Skip to content

Commit a15af3e

Browse files
committed
JIT support for BEGIN and END.
1 parent 58ca80d commit a15af3e

File tree

6 files changed

+27
-6
lines changed

6 files changed

+27
-6
lines changed

core/src/main/java/org/jruby/ir/IRBuilder.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2917,6 +2917,9 @@ public Operand buildPostExe(PostExeNode postExeNode, IRScope s) {
29172917
closureBuilder.addInstr(endClosure, new CopyInstr(endClosure.getCurrentModuleVariable(), new ScopeModule(0)));
29182918
closureBuilder.build(postExeNode.getBodyNode(), endClosure);
29192919

2920+
// END does not have either explicit or implicit return, so we add one
2921+
closureBuilder.addInstr(endClosure, new ReturnInstr(new Nil()));
2922+
29202923
// Add an instruction in 's' to record the end block in the 'topLevel' scope.
29212924
// SSS FIXME: IR support for end-blocks that access vars in non-toplevel-scopes
29222925
// might be broken currently. We could either fix it or consider dropping support
@@ -2936,6 +2939,9 @@ public Operand buildPreExe(PreExeNode preExeNode, IRScope s) {
29362939
closureBuilder.addInstr(beginClosure, new CopyInstr(beginClosure.getCurrentModuleVariable(), new ScopeModule(0)));
29372940
closureBuilder.build(preExeNode.getBodyNode(), beginClosure);
29382941

2942+
// BEGIN does not have either explicit or implicit return, so we add one
2943+
closureBuilder.addInstr(beginClosure, new ReturnInstr(new Nil()));
2944+
29392945
// Record the begin block at IR build time
29402946
s.getTopLevelScope().recordBeginBlock(beginClosure);
29412947
return manager.getNil();

core/src/main/java/org/jruby/ir/instructions/RecordEndBlockInstr.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package org.jruby.ir.instructions;
22

33
import org.jruby.ir.*;
4-
import org.jruby.ir.interpreter.BeginEndInterpreterContext;
54
import org.jruby.ir.operands.Operand;
65
import org.jruby.ir.operands.WrappedIRClosure;
6+
import org.jruby.ir.runtime.IRRuntimeHelpers;
77
import org.jruby.ir.transformations.inlining.CloneInfo;
88
import org.jruby.parser.StaticScope;
99
import org.jruby.runtime.Block;
@@ -55,7 +55,7 @@ public Instr clone(CloneInfo ii) {
5555
@Override
5656
public Object interpret(ThreadContext context, StaticScope currScope, DynamicScope currDynScope, IRubyObject self, Object[] temp) {
5757
Block blk = (Block) endBlockClosure.retrieve(context, self, currScope, context.getCurrentScope(), temp);
58-
context.runtime.pushExitBlock(context.runtime.newProc(Block.Type.LAMBDA, blk));
58+
IRRuntimeHelpers.pushExitBlock(context, blk);
5959
return null;
6060
}
6161

core/src/main/java/org/jruby/ir/interpreter/Interpreter.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,8 +572,7 @@ private static IRubyObject interpret(ThreadContext context, IRubyObject self,
572572
}
573573

574574
// Control should never get here!
575-
// SSS FIXME: But looks like BEGIN/END blocks get here -- needs fixing
576-
return null;
575+
throw context.runtime.newRuntimeError("BUG: interpreter fell through to end unexpectedly");
577576
}
578577

579578
/*

core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,4 +1287,9 @@ public static IRubyObject irNot(ThreadContext context, IRubyObject obj) {
12871287
public static RaiseException newRequiredKeywordArgumentError(ThreadContext context, String name) {
12881288
return context.runtime.newArgumentError("missing keyword: " + name);
12891289
}
1290+
1291+
@JIT
1292+
public static void pushExitBlock(ThreadContext context, Block blk) {
1293+
context.runtime.pushExitBlock(context.runtime.newProc(Block.Type.LAMBDA, blk));
1294+
}
12901295
}

core/src/main/java/org/jruby/ir/targets/JVMVisitor.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,6 +1494,17 @@ public void ReceiveSelfInstr(ReceiveSelfInstr receiveselfinstr) {
14941494
jvmStoreLocal(receiveselfinstr.getResult());
14951495
}
14961496

1497+
@Override
1498+
public void RecordEndBlockInstr(RecordEndBlockInstr recordEndBlockInstr) {
1499+
jvmMethod().loadContext();
1500+
1501+
jvmMethod().loadContext();
1502+
visit(recordEndBlockInstr.getEndBlockClosure());
1503+
jvmMethod().invokeIRHelper("getBlockFromObject", sig(Block.class, ThreadContext.class, Object.class));
1504+
1505+
jvmMethod().invokeIRHelper("pushExitBlock", sig(void.class, ThreadContext.class, Block.class));
1506+
}
1507+
14971508
@Override
14981509
public void ReqdArgMultipleAsgnInstr(ReqdArgMultipleAsgnInstr reqdargmultipleasgninstr) {
14991510
jvmMethod().loadContext();

spec/compiler/general_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -670,12 +670,12 @@ def self.remove; remove_method :gh1239; end
670670
run("def foo; yield; end; x = false; foo { break 5 if x; begin; ensure; x = true; redo; end; break 6}") {|result| expect(result).to eq 5 }
671671
end
672672

673-
it "compiles END BLocks", pending: "JIT support" do
673+
it "compiles END Blocks" do
674674
# END block
675675
expect { run("END {}"){} }.to_not raise_error
676676
end
677677

678-
it "compiles BEGIN blocks", pending: "JIT support" do
678+
it "compiles BEGIN blocks" do
679679
# BEGIN block
680680
run("BEGIN { $begin = 5 }; $begin") {|result| expect(result).to eq 5 }
681681
end

0 commit comments

Comments
 (0)