Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 80f6a365ea03
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 944aaa3d961e
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Aug 19, 2015

  1. Additional cleanup and bug fix in $! save/restore

    * Remove special cases and handle all $! restore in the
      ensure block cloning code.
    subbuss committed Aug 19, 2015
    Copy the full SHA
    60564ba View commit details
  2. Copy the full SHA
    944aaa3 View commit details
21 changes: 9 additions & 12 deletions core/src/main/java/org/jruby/ir/IRBuilder.java
Original file line number Diff line number Diff line change
@@ -229,6 +229,11 @@ public void cloneIntoHostScope(IRBuilder builder) {
if (i instanceof LabelInstr) ii.renameLabel(((LabelInstr)i).getLabel());
}

// $! should be restored before the ensure block is run
if (savedGlobalException != null) {
addInstr(new PutGlobalVarInstr("$!", savedGlobalException));
}

// Clone instructions now
builder.addInstr(new LabelInstr(ii.getRenamedLabel(start)));
builder.addInstr(new ExceptionRegionStartMarkerInstr(bodyRescuer));
@@ -347,11 +352,6 @@ private void emitEnsureBlocks(IRLoop loop) {
// ensure blocks from the loops they are present in.
if (loop != null && ebi.innermostLoop != loop) break;

// $! should be restored before the ensure block is run
if (ebi.savedGlobalException != null) {
addInstr(new PutGlobalVarInstr("$!", ebi.savedGlobalException));
}

// Clone into host scope
ebi.cloneIntoHostScope(this);
}
@@ -2228,9 +2228,6 @@ public Operand buildEnsureInternal(Node ensureBodyNode, Node ensurerNode) {

// Restore $! if we had a non-empty rescue node
if (ensureBodyNode != null && ensureBodyNode instanceof RescueNode) {
if (ensurerNode == null) {
addInstr(new PutGlobalVarInstr("$!", savedGlobalException));
}
ebi.savedGlobalException = savedGlobalException;
}

@@ -3094,12 +3091,12 @@ private Operand buildRescueInternal(RescueNode rescueNode, EnsureBlockInfo ensur
addInstr(new JumpInstr(rEndLabel, true));
} //else {
// If the body had an explicit return, the return instruction IR build takes care of setting
// up execution of all necessary ensure blocks. So, nothing to do here!
// up execution of all necessary ensure blocks. So, nothing to do here!
//
// Additionally, the value in 'rv' will never be used, so need to set it to any specific value.
// So, we can leave it undefined. If on the other hand, there was an exception in that block,
// Additionally, the value in 'rv' will never be used, so no need to set it to any specific value.
// So, we can leave it undefined. If on the other hand, there was an exception in that block,
// 'rv' will get set in the rescue handler -- see the 'rv' being passed into
// buildRescueBodyInternal below. So, in either case, we are good!
// buildRescueBodyInternal below. So, in either case, we are good!
//}

// Start of rescue logic
8 changes: 8 additions & 0 deletions core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java
Original file line number Diff line number Diff line change
@@ -726,6 +726,14 @@ public static IRubyObject mergeKeywordArguments(ThreadContext context, IRubyObje
return ((RubyHash) TypeConverter.checkHashType(context.runtime, restKwarg)).merge(context, explcitKwarg, Block.NULL_BLOCK);
}

@JIT
public static IRubyObject restoryPerlyExc(ThreadContext context, IRubyObject exc, IRubyObject savedExc) {
if (exc instanceof IRReturnJump || exc instanceof IRBreakJump) {
context.runtime.getGlobalVariables().set("$!", savedExc);
}
return null;
}

public static RubyModule findInstanceMethodContainer(ThreadContext context, DynamicScope currDynScope, IRubyObject self) {
boolean inBindingEval = currDynScope.inBindingEval();

7 changes: 7 additions & 0 deletions core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
Original file line number Diff line number Diff line change
@@ -1700,6 +1700,13 @@ public void RuntimeHelperCall(RuntimeHelperCall runtimehelpercall) {
jvmAdapter().invokestatic(p(IRRuntimeHelpers.class), "mergeKeywordArguments", sig(IRubyObject.class, ThreadContext.class, IRubyObject.class, IRubyObject.class));
jvmStoreLocal(runtimehelpercall.getResult());
break;
case RESTORE_PERLY_EXC:
jvmMethod().loadContext();
visit(runtimehelpercall.getArgs()[0]);
visit(runtimehelpercall.getArgs()[1]);
jvmAdapter().invokestatic(p(IRRuntimeHelpers.class), "restorePerlyExc", sig(IRubyObject.class, ThreadContext.class, IRubyObject.class, IRubyObject.class));
jvmStoreLocal(runtimehelpercall.getResult());
break;
default:
throw new NotCompilableException("Unknown IR runtime helper method: " + runtimehelpercall.getHelperMethod() + "; INSTR: " + this);
}