Skip to content

Commit

Permalink
Merge branch '9.5-dev' into 10-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
headius committed Nov 11, 2024
2 parents 6c3cdfb + e82d48c commit bf2db33
Show file tree
Hide file tree
Showing 176 changed files with 2,824 additions and 654 deletions.
9 changes: 8 additions & 1 deletion core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
Expand Up @@ -4147,9 +4147,16 @@ public RaiseException newFrozenError(String objectType, IRubyObject receiver) {
ThreadContext context = getCurrentContext();

IRubyObject inspected = context.safeRecurse(Ruby::inspectFrozenObject, this, receiver, "inspect", true);
String message = "can't modify frozen " + objectType + ": " + inspected.convertToString().toString();

return newFrozenError(receiver, message);
}

public RaiseException newFrozenError(IRubyObject receiver, String message) {
ThreadContext context = getCurrentContext();

return RubyFrozenError.newFrozenError(context,
newString("can't modify frozen " + objectType + ": " + inspected.convertToString().toString()),
newString(message),
receiver)
.toThrowable();
}
Expand Down
51 changes: 43 additions & 8 deletions core/src/main/java/org/jruby/RubyBasicObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -1256,11 +1256,17 @@ public boolean eql(IRubyObject other) {
return invokedynamic(metaClass.runtime.getCurrentContext(), this, EQL, other).isTrue();
}

@Deprecated
@Override
public void addFinalizer(IRubyObject f) {
addFinalizer(getRuntime().getCurrentContext(), f);
}

/**
* Adds the specified object as a finalizer for this object.
*/
@Override
public void addFinalizer(IRubyObject f) {
public IRubyObject addFinalizer(ThreadContext context, IRubyObject f) {
Finalizer finalizer = (Finalizer) getInternalVariable("__finalizer__");
if (finalizer == null) {
IRubyObject fixnumId = registerWithObjectSpace();
Expand All @@ -1269,7 +1275,7 @@ public void addFinalizer(IRubyObject f) {
setInternalVariable("__finalizer__", finalizer);
getRuntime().addFinalizer(finalizer);
}
finalizer.addFinalizer(f);
return finalizer.addFinalizer(context, f);
}

private IRubyObject registerWithObjectSpace() {
Expand Down Expand Up @@ -1305,6 +1311,7 @@ protected void dupFinalizer() {
*/
@Override
public void removeFinalizers() {
checkFrozen();
Finalizer finalizer = (Finalizer) getInternalVariable("__finalizer__");
if (finalizer != null) {
finalizer.removeFinalizers();
Expand Down Expand Up @@ -1680,15 +1687,15 @@ public static IRubyObject method_missing(ThreadContext context, IRubyObject recv

@JRubyMethod(name = "__send__", omit = true, keywords = true)
public IRubyObject send(ThreadContext context, IRubyObject arg0, Block block) {
String name = RubySymbol.checkID(arg0);
String name = RubySymbol.idStringFromObject(context, arg0);

StaticScope staticScope = context.getCurrentStaticScope();

return getMetaClass().finvokeWithRefinements(context, this, staticScope, name, block);
}
@JRubyMethod(name = "__send__", omit = true, keywords = true)
public IRubyObject send(ThreadContext context, IRubyObject arg0, IRubyObject arg1, Block block) {
String name = RubySymbol.checkID(arg0);
String name = RubySymbol.idStringFromObject(context, arg0);

StaticScope staticScope = context.getCurrentStaticScope();

Expand All @@ -1697,7 +1704,7 @@ public IRubyObject send(ThreadContext context, IRubyObject arg0, IRubyObject arg
}
@JRubyMethod(name = "__send__", omit = true, keywords = true)
public IRubyObject send(ThreadContext context, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2, Block block) {
String name = RubySymbol.checkID(arg0);
String name = RubySymbol.idStringFromObject(context, arg0);

StaticScope staticScope = context.getCurrentStaticScope();

Expand Down Expand Up @@ -1729,7 +1736,7 @@ public IRubyObject send(ThreadContext context, IRubyObject[] args, Block block)
args[argc - 1] = dupIfKeywordRestAtCallsite(context, args[argc - 1]);
}
}
String name = RubySymbol.checkID(args[0]);
String name = RubySymbol.idStringFromObject(context, args[0]);

StaticScope staticScope = context.getCurrentStaticScope();

Expand Down Expand Up @@ -1955,13 +1962,41 @@ public Finalizer(IRubyObject id, Finalizer original) {
this.finalized = new AtomicBoolean(false);
}

@Deprecated
public void addFinalizer(IRubyObject finalizer) {
addFinalizer(finalizer.getRuntime().getCurrentContext(), finalizer);
}

public IRubyObject addFinalizer(ThreadContext context, IRubyObject finalizer) {
if (firstFinalizer == null) {
firstFinalizer = finalizer;

return finalizer;
}

IRubyObject existing = firstFinalizer;

if (existing.op_equal(context, finalizer).isTrue()) {
// do not add equivalent finalizer twice
return existing;
}

if (finalizers == null) {
finalizers = new ArrayList<>(4);
} else {
if (finalizers == null) finalizers = new ArrayList<>(4);
finalizers.add(finalizer);
for (int i = 0; i < finalizers.size(); i++) {
existing = finalizers.get(i);

if (existing.op_equal(context, finalizer).isTrue()) {
// do not add equivalent finalizer twice
return existing;
}
}
}

finalizers.add(finalizer);

return finalizer;
}

public void removeFinalizers() {
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyBinding.java
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public IRubyObject local_variable_set(ThreadContext context, IRubyObject symbol,

// MRI: check_local_id
private String checkLocalId(ThreadContext context, IRubyObject obj) {
String id = RubySymbol.checkID(obj);
String id = RubySymbol.idStringFromObject(context, obj);

if (!RubyLexer.isIdentifierChar(id.charAt(0))) {
throw context.runtime.newNameError(str(context.runtime, "wrong local variable name '", obj, "' for ", this), id);
Expand Down
31 changes: 11 additions & 20 deletions core/src/main/java/org/jruby/RubyGlobal.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,47 +134,38 @@ public static RubyHash createGlobalsAndENV(Ruby runtime) {
// Version information:
IRubyObject version;
IRubyObject patchlevel;
IRubyObject release = runtime.newString(Constants.COMPILE_DATE);
release.setFrozen(true);
IRubyObject platform = runtime.newString(Constants.PLATFORM);
release.setFrozen(true);
IRubyObject engine = runtime.newString(Constants.ENGINE);
release.setFrozen(true);

version = runtime.newString(Constants.RUBY_VERSION);
release.setFrozen(true);
IRubyObject release = RubyString.newFString(runtime, Constants.COMPILE_DATE);
IRubyObject platform = RubyString.newFString(runtime, Constants.PLATFORM);
IRubyObject engine = RubyString.newFString(runtime, Constants.ENGINE);

version = RubyString.newFString(runtime, Constants.RUBY_VERSION);
patchlevel = runtime.newFixnum(0);
runtime.defineGlobalConstant("RUBY_VERSION", version);
runtime.defineGlobalConstant("RUBY_PATCHLEVEL", patchlevel);
runtime.defineGlobalConstant("RUBY_RELEASE_DATE", release);
runtime.defineGlobalConstant("RUBY_PLATFORM", platform);

IRubyObject description = runtime.newString(OutputStrings.getVersionString());
release.setFrozen(true);
IRubyObject description = RubyString.newFString(runtime, OutputStrings.getVersionString());
runtime.defineGlobalConstant("RUBY_DESCRIPTION", description);

IRubyObject copyright = runtime.newString(OutputStrings.getCopyrightString());
release.setFrozen(true);
IRubyObject copyright = RubyString.newFString(runtime, OutputStrings.getCopyrightString());
runtime.defineGlobalConstant("RUBY_COPYRIGHT", copyright);

runtime.defineGlobalConstant("RELEASE_DATE", release);
runtime.defineGlobalConstant("PLATFORM", platform);

IRubyObject jrubyVersion = runtime.newString(Constants.VERSION);
release.setFrozen(true);
IRubyObject jrubyRevision = runtime.newString(Constants.REVISION);
release.setFrozen(true);
IRubyObject jrubyVersion = RubyString.newFString(runtime, Constants.VERSION);
IRubyObject jrubyRevision = RubyString.newFString(runtime, Constants.REVISION);
runtime.defineGlobalConstant("JRUBY_VERSION", jrubyVersion);
runtime.defineGlobalConstant("JRUBY_REVISION", jrubyRevision);
runtime.defineGlobalConstant("RUBY_REVISION", runtime.newString(Constants.REVISION));
runtime.defineGlobalConstant("RUBY_REVISION", RubyString.newFString(runtime, Constants.REVISION));
runtime.defineGlobalConstant("RUBY_ENGINE", engine);
runtime.defineGlobalConstant("RUBY_ENGINE_VERSION", jrubyVersion);

RubyInstanceConfig.Verbosity verbosity = runtime.getInstanceConfig().getVerbosity();
runtime.defineVariable(new WarningGlobalVariable(runtime, "$-W", verbosity), GLOBAL);

IRubyObject defaultRS = runtime.newString(runtime.getInstanceConfig().getRecordSeparator());
release.setFrozen(true);
IRubyObject defaultRS = RubyString.newFString(runtime, runtime.getInstanceConfig().getRecordSeparator());
GlobalVariable rs = new StringGlobalVariable(runtime, "$/", defaultRS);
runtime.defineVariable(rs, GLOBAL);
runtime.setRecordSeparatorVar(rs);
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyKernel.java
Original file line number Diff line number Diff line change
Expand Up @@ -2182,7 +2182,7 @@ public static IRubyObject public_send(ThreadContext context, IRubyObject recv, I
throw context.runtime.newArgumentError("no method name given");
}

String name = RubySymbol.checkID(args[0]);
String name = RubySymbol.idStringFromObject(context, args[0]);

if (args.length > 1) {
args[args.length - 1] = dupIfKeywordRestAtCallsite(context, args[args.length - 1]);
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -3050,7 +3050,7 @@ public IRubyObject ruby2_keywords(ThreadContext context, IRubyObject[] args) {
checkFrozen();

for (IRubyObject name: args) {
String id = RubySymbol.checkID(name);
String id = RubySymbol.idStringFromObject(context, name);

// FIXME: id == null or bad symbol error missing

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyObjectSpace.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public static IRubyObject define_finalizer(ThreadContext context, IRubyObject re
if (blockReferencesObject(obj, block)) referenceWarning(runtime);
finalizer = runtime.newProc(Block.Type.PROC, block);
}
runtime.getObjectSpace().addFinalizer(obj, finalizer);
finalizer = runtime.getObjectSpace().addFinalizer(context, obj, finalizer);
return runtime.newArray(RubyFixnum.zero(runtime), finalizer);
}

Expand Down
11 changes: 11 additions & 0 deletions core/src/main/java/org/jruby/RubyString.java
Original file line number Diff line number Diff line change
Expand Up @@ -1080,6 +1080,17 @@ public void setReadLength(int length) {
}
}

/**
* Create anew or deduplicate a RubyString based on the given Java String content.
*
* @param runtime the JRuby runtime
* @param content the Java String content
* @return a frozen, deduplicated RubyString hosting the given content
*/
public static RubyString newFString(Ruby runtime, String content) {
return runtime.freezeAndDedupString(newString(runtime, content));
}

// MRI: rb_str_new_frozen, at least in spirit
// also aliased to rb_str_new4
public RubyString newFrozen() {
Expand Down
48 changes: 41 additions & 7 deletions core/src/main/java/org/jruby/RubySymbol.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.ContextAwareBlockBody;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.JavaSites;
import org.jruby.runtime.MethodIndex;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.Signature;
Expand Down Expand Up @@ -1554,19 +1555,48 @@ public static String objectToSymbolString(IRubyObject object) {
return object.convertToString().getByteList().toString();
}

// MRI: rb_check_id
@Deprecated
public static String checkID(IRubyObject object) {
if (object instanceof RubySymbol) return ((RubySymbol) object).idString();
return idStringFromObject(object.getRuntime().getCurrentContext(), object);
}

// MRI: rb_check_id but producing a Java String
public static String idStringFromObject(ThreadContext context, IRubyObject object) {
IRubyObject symOrStr = prepareID(object.getRuntime().getCurrentContext(), object);

if (symOrStr instanceof RubySymbol) return ((RubySymbol) symOrStr).idString();

if (!(object instanceof RubyString)) {
IRubyObject tmp = TypeConverter.checkStringType(object.getRuntime(), object);
return ((RubyString) symOrStr).getByteList().toString();
}

// MRI: rb_check_id
public static RubySymbol idSymbolFromObject(ThreadContext context, IRubyObject object) {
IRubyObject symOrStr = prepareID(context, object);

if (tmp.isNil()) throw typeError(object.getRuntime().getCurrentContext(), "", object, " is not a symbol nor a string");
if (symOrStr instanceof RubySymbol) return (RubySymbol) symOrStr;

return newSymbol(context.runtime, ((RubyString) symOrStr).getByteList());
}

object = tmp;
/**
* Return the given object if it is a Symbol or String, or convert it to a String.
*
* @param context the current context
* @param object the object
* @return the object, if it is a Symbol or String, or a String produced by calling #to_str on the object.
*/
public static IRubyObject prepareID(ThreadContext context, IRubyObject object) {
if (object instanceof RubySymbol || object instanceof RubyString) return object;

Ruby runtime = context.runtime;

IRubyObject tmp = TypeConverter.checkStringType(context, sites(context).to_str_checked, object);

if (tmp.isNil()) {
throw runtime.newTypeError(str(runtime, "", object, " is not a symbol nor a string"));
}

return ((RubyString) object).getByteList().toString();
return tmp;
}

@Override
Expand Down Expand Up @@ -1660,6 +1690,10 @@ public ArgumentDescriptor[] getArgumentDescriptors() {
}
}

private static JavaSites.SymbolSites sites(ThreadContext context) {
return context.sites.Symbol;
}

@Deprecated
@Override
public IRubyObject taint(ThreadContext context) {
Expand Down
23 changes: 15 additions & 8 deletions core/src/main/java/org/jruby/RubyThread.java
Original file line number Diff line number Diff line change
Expand Up @@ -1102,7 +1102,7 @@ public IRubyObject fetch(ThreadContext context, IRubyObject key, IRubyObject _de

@JRubyMethod(name = "[]")
public IRubyObject op_aref(ThreadContext context, IRubyObject key) {
key = getSymbolKey(key);
key = RubySymbol.idSymbolFromObject(context, key);
final Map<IRubyObject, IRubyObject> locals = getFiberLocals();
synchronized (locals) {
IRubyObject value;
Expand All @@ -1111,10 +1111,12 @@ public IRubyObject op_aref(ThreadContext context, IRubyObject key) {
}

@JRubyMethod(name = "[]=")
public IRubyObject op_aset(IRubyObject key, IRubyObject value) {
checkFrozen();
public IRubyObject op_aset(ThreadContext context, IRubyObject key, IRubyObject value) {
if (isFrozen()) {
throw getRuntime().newFrozenError(this, "can't modify frozen thread locals");
}

key = getSymbolKey(key);
key = RubySymbol.idSymbolFromObject(context, key);
final Map<IRubyObject, IRubyObject> locals = getFiberLocals();
synchronized (locals) {
locals.put(key, value);
Expand All @@ -1124,7 +1126,7 @@ public IRubyObject op_aset(IRubyObject key, IRubyObject value) {

@JRubyMethod(name = "key?")
public RubyBoolean key_p(ThreadContext context, IRubyObject key) {
key = getSymbolKey(key);
key = RubySymbol.idSymbolFromObject(context, key);
final Map<IRubyObject, IRubyObject> locals = getFiberLocals();
synchronized (locals) {
return asBoolean(context, locals.containsKey(key));
Expand All @@ -1147,7 +1149,7 @@ public RubyArray keys() {

@JRubyMethod(name = "thread_variable?")
public IRubyObject thread_variable_p(ThreadContext context, IRubyObject key) {
key = getSymbolKey(key);
key = RubySymbol.idSymbolFromObject(context, key);
final Map<IRubyObject, IRubyObject> locals = getThreadLocals();
synchronized (locals) {
return asBoolean(context, locals.containsKey(key));
Expand All @@ -1156,7 +1158,7 @@ public IRubyObject thread_variable_p(ThreadContext context, IRubyObject key) {

@JRubyMethod(name = "thread_variable_get")
public IRubyObject thread_variable_get(ThreadContext context, IRubyObject key) {
key = getSymbolKey(key);
key = RubySymbol.idSymbolFromObject(context, key);
final Map<IRubyObject, IRubyObject> locals = getThreadLocals();
synchronized (locals) {
IRubyObject value;
Expand All @@ -1167,7 +1169,7 @@ public IRubyObject thread_variable_get(ThreadContext context, IRubyObject key) {
@JRubyMethod(name = "thread_variable_set")
public IRubyObject thread_variable_set(ThreadContext context, IRubyObject key, IRubyObject value) {
checkFrozen();
key = getSymbolKey(key);
key = RubySymbol.idSymbolFromObject(context, key);
final Map<IRubyObject, IRubyObject> locals = getThreadLocals();
synchronized (locals) {
locals.put(key, value);
Expand Down Expand Up @@ -2690,4 +2692,9 @@ public IRubyObject join(ThreadContext context, IRubyObject[] args) {
throw context.runtime.newArgumentError(args.length, 0, 1);
}
}

@Deprecated
public IRubyObject op_aset(IRubyObject key, IRubyObject value) {
return op_aset(getRuntime().getCurrentContext(), key, value);
}
}
Loading

0 comments on commit bf2db33

Please sign in to comment.