Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into 9.5-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
headius committed Mar 13, 2024
2 parents acf945c + 4fdce77 commit 8a2f848
Show file tree
Hide file tree
Showing 642 changed files with 9,605 additions and 9,937 deletions.
3 changes: 2 additions & 1 deletion core/src/main/java/org/jruby/RubyBasicObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -2700,8 +2700,9 @@ public IRubyObject instance_variable_set(IRubyObject name, IRubyObject value) {
* d.var #=> nil
*/
public IRubyObject remove_instance_variable(ThreadContext context, IRubyObject name, Block block) {
String id = validateInstanceVariable(name);
ensureInstanceVariablesSettable();
IRubyObject value = (IRubyObject) variableTableRemove(validateInstanceVariable(name));
IRubyObject value = (IRubyObject) variableTableRemove(id);
if (value != null) return value;
throw context.runtime.newNameError("instance variable %1$s not defined", this, name);
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -1062,7 +1062,7 @@ private void concreteSubclasses(Collection<RubyClass> subs) {
Set<RubyClass> keys = subclasses.keySet();
for (RubyClass klass: keys) {
if (klass.isSingleton()) continue;
if (klass.isIncluded()) {
if (klass.isIncluded() || klass.isPrepended()) {
klass.concreteSubclasses(subs);
continue;
}
Expand Down
17 changes: 9 additions & 8 deletions core/src/main/java/org/jruby/RubyFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
import java.util.zip.ZipFile;

import static org.jruby.RubyInteger.singleCharByteList;
import static org.jruby.runtime.ThreadContext.hasKeywords;
import static org.jruby.runtime.Visibility.PRIVATE;
import static org.jruby.util.StringSupport.*;
import static org.jruby.util.io.EncodingUtils.vmode;
Expand Down Expand Up @@ -341,13 +342,14 @@ public IRubyObject flock(ThreadContext context, IRubyObject operation) {
}

// rb_file_initialize
@JRubyMethod(name = "initialize", required = 1, optional = 3, checkArity = false, visibility = PRIVATE)
@JRubyMethod(name = "initialize", required = 1, optional = 3, checkArity = false, visibility = PRIVATE, keywords = true)
public IRubyObject initialize(ThreadContext context, IRubyObject[] args, Block block) {
int argc = Arity.checkArgumentCount(context, args, 1, 4);
boolean keywords = hasKeywords(ThreadContext.resetCallInfo(context));
// Mild hack. We want to arity-mismatch if extra arg is not really a kwarg but not if it is one.
int maxArgs = keywords ? 4 : 3;
int argc = Arity.checkArgumentCount(context, args, 1, maxArgs);

if (openFile != null) {
throw context.runtime.newRuntimeError("reinitializing File");
}
if (openFile != null) throw context.runtime.newRuntimeError("reinitializing File");

if (argc > 0 && argc <= 3) {
IRubyObject fd = TypeConverter.convertToTypeWithCheck(context, args[0], context.runtime.getFixnum(), sites(context).to_int_checked);
Expand Down Expand Up @@ -1307,8 +1309,8 @@ public static IRubyObject lutime(ThreadContext context, IRubyObject recv, IRubyO
long[] mtimeval = null;

if (args[0] != context.nil || args[1] != context.nil) {
atimeval = extractTimespec(context, args[0]);
mtimeval = extractTimespec(context, args[1]);
atimeval = convertTimespecToTimeval(extractTimespec(context, args[0]));
mtimeval = convertTimespecToTimeval(extractTimespec(context, args[1]));
}

for (int i = 2, j = argc; i < j; i++) {
Expand Down Expand Up @@ -1357,7 +1359,6 @@ public static IRubyObject utime(ThreadContext context, IRubyObject recv, IRubyOb
result = runtime.getPosix().utimensat(0, fileToTouch.getAbsolutePath(), atimespec, mtimespec, 0);
} catch (NotImplementedError re) {
// fall back on utimes
result = runtime.getPosix().utimes(fileToTouch.getAbsolutePath(), atimespec, mtimespec);
long[] atimeval = convertTimespecToTimeval(atimespec);
long[] mtimeval = convertTimespecToTimeval(mtimespec);
result = runtime.getPosix().utimes(fileToTouch.getAbsolutePath(), atimeval, mtimeval);
Expand Down
21 changes: 12 additions & 9 deletions core/src/main/java/org/jruby/RubyIO.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
import static com.headius.backport9.buffer.Buffers.limitBuffer;
import static org.jruby.RubyEnumerator.enumeratorize;
import static org.jruby.anno.FrameField.LASTLINE;
import static org.jruby.runtime.ThreadContext.hasKeywords;
import static org.jruby.runtime.Visibility.*;
import static org.jruby.util.RubyStringBuilder.str;
import static org.jruby.util.RubyStringBuilder.types;
Expand Down Expand Up @@ -887,7 +888,7 @@ public static IRubyObject newInstance(ThreadContext context, IRubyObject recv, I
return klass.newInstance(context, args, block);
}

@JRubyMethod(rest = true, meta = true)
@JRubyMethod(rest = true, meta = true, keywords = true)
public static IRubyObject for_fd(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block block) {
RubyClass klass = (RubyClass)recv;

Expand Down Expand Up @@ -1024,18 +1025,17 @@ public IRubyObject initialize(ThreadContext context, IRubyObject fileNumber, IRu
return initializeCommon(context, fileno, vmode, options);
}

@JRubyMethod(name = "initialize", visibility = PRIVATE)
@JRubyMethod(name = "initialize", visibility = PRIVATE, keywords = true)
public IRubyObject initialize(ThreadContext context, IRubyObject fileNumber, IRubyObject modeValue, IRubyObject options, Block unused) {
int callInfo = ThreadContext.resetCallInfo(context);
int fileno = RubyNumeric.fix2int(fileNumber);

// TODO: MRI has a method name in ArgumentError.
// e.g. `for_fd': wrong number of arguments (given 3, expected 1..2)
if (modeValue != null && !modeValue.isNil() && !(modeValue instanceof RubyInteger) && !(modeValue instanceof RubyString)) {
throw context.runtime.newArgumentError(3, 1, 2);
}
if (options == null || options.isNil()) {
throw context.runtime.newArgumentError(3, 1, 2);
}
if (!hasKeywords(callInfo)) throw context.runtime.newArgumentError(3, 1, 2);

return initializeCommon(context, fileno, modeValue, options);
}
Expand Down Expand Up @@ -4217,8 +4217,9 @@ public static IRubyObject binread(ThreadContext context, IRubyObject recv, IRuby
}

// Enebo: annotation processing forced me to do pangea method here...
@JRubyMethod(name = "read", meta = true, required = 1, optional = 3, checkArity = false)
@JRubyMethod(name = "read", meta = true, required = 1, optional = 3, checkArity = false, keywords = true)
public static IRubyObject read(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block unusedBlock) {
boolean keywords = hasKeywords(ThreadContext.resetCallInfo(context));
int argc = Arity.checkArgumentCount(context, args, 1, 4);

Ruby runtime = context.runtime;
Expand All @@ -4228,7 +4229,7 @@ public static IRubyObject read(ThreadContext context, IRubyObject recv, IRubyObj

{ // rb_scan_args logic, basically
if (argc > 3) {
if (!(args[3] instanceof RubyHash)) throw runtime.newTypeError("Must be a hash");
if (!keywords) throw runtime.newArgumentError(args.length, 1, 4);
options = (RubyHash) args[3];
offset = args[2];
length = args[1];
Expand Down Expand Up @@ -4269,25 +4270,27 @@ public static IRubyObject read(ThreadContext context, IRubyObject recv, IRubyObj
}

// rb_io_s_binwrite
@JRubyMethod(meta = true, required = 2, optional = 2, checkArity = false)
@JRubyMethod(meta = true, required = 2, optional = 2, checkArity = false, keywords = true)
public static IRubyObject binwrite(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
return ioStaticWrite(context, recv, args, true);
}

// MRI: rb_io_s_write
@JRubyMethod(name = "write", meta = true, required = 2, optional = 2, checkArity = false)
@JRubyMethod(name = "write", meta = true, required = 2, optional = 2, checkArity = false, keywords = true)
public static IRubyObject write(ThreadContext context, IRubyObject recv, IRubyObject[] argv) {
return (ioStaticWrite(context, recv, argv, false));
}

// MRI: io_s_write
public static IRubyObject ioStaticWrite(ThreadContext context, IRubyObject recv, IRubyObject[] argv, boolean binary) {
boolean keywords = hasKeywords(ThreadContext.resetCallInfo(context));
final Ruby runtime = context.runtime;
IRubyObject string, offset, opt;
string = offset = opt = context.nil;

switch (argv.length) {
case 4:
if (!keywords) throw runtime.newArgumentError(argv.length, 2, 3);
opt = argv[3].convertToHash();
offset = argv[2];
string = argv[1];
Expand Down
33 changes: 24 additions & 9 deletions core/src/main/java/org/jruby/RubyKernel.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@

import static org.jruby.RubyEnumerator.SizeFn;
import static org.jruby.RubyEnumerator.enumeratorizeWithSize;
import static org.jruby.RubyFile.fileResource;
import static org.jruby.anno.FrameField.BACKREF;
import static org.jruby.RubyIO.checkUnsupportedOptions;
import static org.jruby.RubyIO.checkValidSpawnOptions;
Expand Down Expand Up @@ -254,14 +255,12 @@ private static String getMethodMissingFormat(Visibility visibility, CallType cal

@JRubyMethod(name = "open", required = 1, optional = 3, checkArity = false, module = true, visibility = PRIVATE, keywords = true)
public static IRubyObject open(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block block) {
int argc = Arity.checkArgumentCount(context, args, 1, 4);

boolean keywords = hasKeywords(ThreadContext.resetCallInfo(context));
Ruby runtime = context.runtime;
// symbol to_open = 0;
boolean redirect = false;
int callInfo = ThreadContext.resetCallInfo(context);
boolean keywords = hasKeywords(callInfo);

if (argc >= 1) {
if (args.length >= 1) {
// CONST_ID(to_open, "to_open");
if (args[0].respondsTo("to_open")) {
redirect = true;
Expand All @@ -283,13 +282,23 @@ public static IRubyObject open(ThreadContext context, IRubyObject recv, IRubyObj
}
}
}

// Mild hack. We want to arity-mismatch if extra arg is not really a kwarg but not if it is one.
int maxArgs = keywords ? 5 : 4;
Arity.checkArgumentCount(context, args, 1, maxArgs);

// symbol to_open = 0;

if (redirect) {
if (keywords) context.callInfo = ThreadContext.CALL_KEYWORD;
IRubyObject io = args[0].callMethod(context, "to_open", Arrays.copyOfRange(args, 1, args.length));

RubyIO.ensureYieldClose(context, io, block);
return io;
}

// We had to save callInfo from original call because kwargs needs to still pass through to IO#open
context.callInfo = callInfo;
return RubyIO.open(context, runtime.getFile(), args, block);
}

Expand Down Expand Up @@ -1558,7 +1567,13 @@ public static IRubyObject trace_var(ThreadContext context, IRubyObject recv, IRu
if (argc == 1) {
proc = RubyProc.newProc(context.runtime, block, Block.Type.PROC);
} else if (argc == 2) {
proc = (RubyProc)TypeConverter.convertToType(args[1], context.runtime.getProc(), "to_proc", true);
if (args[1] instanceof RubyString) {
RubyString rubyString = context.runtime.newString("proc {");
RubyString s = rubyString.catWithCodeRange(((RubyString) args[1])).cat('}');
proc = (RubyProc) evalCommon(context, recv, new IRubyObject[] { s });
} else {
proc = (RubyProc) TypeConverter.convertToType(args[1], context.runtime.getProc(), "to_proc", true);
}
}

context.runtime.getGlobalVariables().setTraceVar(var, proc);
Expand Down Expand Up @@ -1703,13 +1718,13 @@ private static IRubyObject testCommon(ThreadContext context, IRubyObject recv, i

switch (cmd) {
case 'A': // ?A | Time | Last access time for file1
return context.runtime.newFileStat(arg1.convertToString().toString(), false).atime();
return context.runtime.newFileStat(fileResource(arg1).path(), false).atime();
case 'b': // ?b | boolean | True if file1 is a block device
return RubyFileTest.blockdev_p(recv, arg1);
case 'c': // ?c | boolean | True if file1 is a character device
return RubyFileTest.chardev_p(recv, arg1);
case 'C': // ?C | Time | Last change time for file1
return context.runtime.newFileStat(arg1.convertToString().toString(), false).ctime();
return context.runtime.newFileStat(fileResource(arg1).path(), false).ctime();
case 'd': // ?d | boolean | True if file1 exists and is a directory
return RubyFileTest.directory_p(context, recv, arg1);
case 'e': // ?e | boolean | True if file1 exists
Expand All @@ -1723,7 +1738,7 @@ private static IRubyObject testCommon(ThreadContext context, IRubyObject recv, i
case 'k': // ?k | boolean | True if file1 exists and has the sticky bit set
return RubyFileTest.sticky_p(recv, arg1);
case 'M': // ?M | Time | Last modification time for file1
return context.runtime.newFileStat(arg1.convertToString().toString(), false).mtime();
return context.runtime.newFileStat(fileResource(arg1).path(), false).mtime();
case 'l': // ?l | boolean | True if file1 exists and is a symbolic link
return RubyFileTest.symlink_p(recv, arg1);
case 'o': // ?o | boolean | True if file1 exists and is owned by the caller's effective uid
Expand Down
1 change: 1 addition & 0 deletions core/src/main/java/org/jruby/RubyMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ private long hashCodeImpl() {
public RubyMethod rbClone() {
RubyMethod newMethod = newMethod(implementationModule, methodName, originModule, originName, entry, receiver);
newMethod.setMetaClass(getMetaClass());
if (isFrozen()) newMethod.setFrozen(true);
return newMethod;
}

Expand Down
6 changes: 5 additions & 1 deletion core/src/main/java/org/jruby/RubyModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ public boolean isKindOf(IRubyObject obj, RubyModule type) {
// Not sure how but this happens in test_objects_are_released_by_cache_map
if (cl == null) return false;

return cl.searchAncestor(type.getDelegate().getOrigin()) != null;
return cl.hasAncestor(type);
}
}

Expand All @@ -324,6 +324,10 @@ public boolean isInstance(IRubyObject object) {
return kindOf.isKindOf(object, this);
}

public boolean hasAncestor(RubyModule type) {
return searchAncestor(type.getDelegate().getOrigin()) != null;
}

public Map<String, ConstantEntry> getConstantMap() {
return getOrigin().constants;
}
Expand Down
22 changes: 22 additions & 0 deletions core/src/main/java/org/jruby/RubyString.java
Original file line number Diff line number Diff line change
Expand Up @@ -1394,6 +1394,8 @@ public final RubyString cat(byte[] str, int beg, int len) {
return this;
}

// Needs to remain in place until StringIO has migrated to the new methods
// See https://github.com/ruby/stringio/issues/83
@Deprecated
public final RubyString cat19(RubyString str2) {
return catWithCodeRange(str2);
Expand All @@ -1414,6 +1416,8 @@ public final RubyString cat(ByteList other, int codeRange) {
return this;
}

// Needs to remain in place until StringIO has migrated to the new methods
// See https://github.com/ruby/stringio/issues/83
@Deprecated
public final int cat19(ByteList other, int codeRange) {
return catWithCodeRange(other, codeRange);
Expand Down Expand Up @@ -2630,6 +2634,11 @@ public RubyString append(RubyString other) {
return catWithCodeRange(other);
}

@Deprecated
public RubyString append19(IRubyObject other) {
return append(other);
}

public RubyString appendAsDynamicString(IRubyObject other) {
// fast path for fixnum straight into ascii-compatible bytelist
if (other instanceof RubyFixnum && value.getEncoding().isAsciiCompatible()) {
Expand All @@ -2649,6 +2658,12 @@ public RubyString appendAsDynamicString(IRubyObject other) {
return catWithCodeRange(other.asString());
}

// NOTE: append(RubyString) should pbly just do the encoding aware cat
final RubyString append19(RubyString other) {
modifyCheck();
return catWithCodeRange(other);
}

/** rb_str_concat
*
*/
Expand Down Expand Up @@ -3605,6 +3620,11 @@ private IRubyObject byteARef(Ruby runtime, IRubyObject idx) {
return obj;
}

@Deprecated
public final IRubyObject substr19(Ruby runtime, int beg, int len) {
return substrEnc(runtime, beg, len);
}

public final IRubyObject substrEnc(Ruby runtime, int beg, int len) {
if (len < 0) return runtime.getNil();
int length = value.getRealSize();
Expand Down Expand Up @@ -6465,6 +6485,8 @@ public IRubyObject sumCommon(ThreadContext context, long bits) {
public IRubyObject to_c(ThreadContext context) {
Ruby runtime = context.runtime;

verifyAsciiCompatible();

RubyRegexp underscore_pattern = RubyRegexp.newDummyRegexp(runtime, Numeric.ComplexPatterns.underscores_pat);
RubyString s = gsubFast(context, underscore_pattern, runtime.newString(UNDERSCORE), Block.NULL_BLOCK);

Expand Down
4 changes: 3 additions & 1 deletion core/src/main/java/org/jruby/RubyUnboundMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,9 @@ private CacheEntry convertUnboundMethodToCallableEntry(ThreadContext context, Ru
@JRubyMethod(name = "clone")
@Override
public RubyUnboundMethod rbClone() {
return newUnboundMethod(implementationModule, methodName, originModule, originName, entry);
RubyUnboundMethod unboundMethod = newUnboundMethod(implementationModule, methodName, originModule, originName, entry);
if (isFrozen()) unboundMethod.setFrozen(true);
return unboundMethod;
}

@JRubyMethod(required = 1, rest = true, checkArity = false, keywords = true)
Expand Down
Loading

0 comments on commit 8a2f848

Please sign in to comment.