Skip to content

Commit

Permalink
Showing 4 changed files with 27 additions and 9 deletions.
19 changes: 18 additions & 1 deletion core/src/main/java/org/jruby/ir/targets/Bootstrap.java
Original file line number Diff line number Diff line change
@@ -878,7 +878,7 @@ public static CallSite globalBootstrap(Lookup lookup, String name, MethodType ty
if (operation.equals("get")) {
handle = lookup.findStatic(Bootstrap.class, "getGlobalFallback", methodType(IRubyObject.class, GlobalSite.class, ThreadContext.class));
} else {
throw new RuntimeException("invalid variable access type");
handle = lookup.findStatic(Bootstrap.class, "setGlobalFallback", methodType(void.class, GlobalSite.class, IRubyObject.class, ThreadContext.class));
}

handle = handle.bindTo(site);
@@ -926,6 +926,23 @@ public static IRubyObject getGlobalUncached(GlobalVariable variable) throws Thro
return variable.getAccessor().getValue();
}

public static void setGlobalFallback(GlobalSite site, IRubyObject value, ThreadContext context) throws Throwable {
Ruby runtime = context.runtime;
GlobalVariable variable = runtime.getGlobalVariables().getVariable(site.name());
MethodHandle uncached = lookup().findStatic(Bootstrap.class, "setGlobalUncached", methodType(void.class, GlobalVariable.class, IRubyObject.class));
uncached = uncached.bindTo(variable);
uncached = dropArguments(uncached, 1, ThreadContext.class);
site.setTarget(uncached);
uncached.invokeWithArguments(value, context);
}

public static void setGlobalUncached(GlobalVariable variable, IRubyObject value) throws Throwable {
// FIXME: duplicated logic from GlobalVariables.set
variable.getAccessor().setValue(value);
variable.trace(value);
variable.invalidate();
}

public static Handle prepareBlock() {
return new Handle(Opcodes.H_INVOKESTATIC, p(Bootstrap.class), "prepareBlock", sig(CallSite.class, Lookup.class, String.class, MethodType.class, MethodHandle.class, MethodHandle.class, long.class));
}
Original file line number Diff line number Diff line change
@@ -597,7 +597,7 @@ public org.objectweb.asm.Label newLabel() {
*
* Stack required: the new value
*/
public abstract void setGlobalVariable(String name);
public abstract void setGlobalVariable(String name, String file, int line);

/**
* Yield argument list to a block.
11 changes: 7 additions & 4 deletions core/src/main/java/org/jruby/ir/targets/IRBytecodeAdapter6.java
Original file line number Diff line number Diff line change
@@ -968,10 +968,13 @@ public void getGlobalVariable(String name, String file, int line) {
}

@Override
public void setGlobalVariable(String name) {
loadRuntime();
adapter.ldc(name);
invokeHelper("setGlobalVariable", sig(IRubyObject.class, IRubyObject.class, Ruby.class, String.class));
public void setGlobalVariable(String name, String file, int line) {
loadContext();
adapter.invokedynamic(
"set:" + JavaNameMangler.mangleMethodName(name),
sig(void.class, IRubyObject.class, ThreadContext.class),
Bootstrap.global(),
file, line);
}

@Override
4 changes: 1 addition & 3 deletions core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
Original file line number Diff line number Diff line change
@@ -1743,9 +1743,7 @@ public void PutFieldInstr(PutFieldInstr putfieldinstr) {
@Override
public void PutGlobalVarInstr(PutGlobalVarInstr putglobalvarinstr) {
visit(putglobalvarinstr.getValue());
jvmMethod().setGlobalVariable(putglobalvarinstr.getTarget().getName());
// leaves copy of value on stack
jvmAdapter().pop();
jvmMethod().setGlobalVariable(putglobalvarinstr.getTarget().getName(), file, lastLine);
}

@Override

0 comments on commit b77ee98

Please sign in to comment.