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: 4754c09f209a
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 8e5f3e9d8977
Choose a head ref
  • 3 commits
  • 6 files changed
  • 1 contributor

Commits on Nov 28, 2015

  1. Copy the full SHA
    5515feb View commit details
  2. Copy the full SHA
    dd5c418 View commit details
  3. Add Save/RestoreBindingVisibilityInstr required for block execution

    * Execution plugged into InterpreterEngine.
    * No IR generated yet.
    subbuss committed Nov 28, 2015
    Copy the full SHA
    8e5f3e9 View commit details
2 changes: 2 additions & 0 deletions core/src/main/java/org/jruby/ir/IRVisitor.java
Original file line number Diff line number Diff line change
@@ -112,8 +112,10 @@ private void error(Object object) {
public void ReqdArgMultipleAsgnInstr(ReqdArgMultipleAsgnInstr reqdargmultipleasgninstr) { error(reqdargmultipleasgninstr); }
public void RescueEQQInstr(RescueEQQInstr rescueeqqinstr) { error(rescueeqqinstr); }
public void RestArgMultipleAsgnInstr(RestArgMultipleAsgnInstr restargmultipleasgninstr) { error(restargmultipleasgninstr); }
public void RestoreBindingVisibilityInstr(RestoreBindingVisibilityInstr instr) { error(instr); }
public void ReturnInstr(ReturnInstr returninstr) { error(returninstr); }
public void RuntimeHelperCall(RuntimeHelperCall runtimehelpercall) { error(runtimehelpercall); }
public void SaveBindingVisibilityInstr(SaveBindingVisibilityInstr instr) { error(instr); }
public void SearchConstInstr(SearchConstInstr searchconstinstr) { error(searchconstinstr); }
public void SetCapturedVarInstr(SetCapturedVarInstr instr) { error(instr); }
public void StoreLocalVarInstr(StoreLocalVarInstr storelocalvarinstr) { error(storelocalvarinstr); }
2 changes: 2 additions & 0 deletions core/src/main/java/org/jruby/ir/Operation.java
Original file line number Diff line number Diff line change
@@ -211,6 +211,8 @@ public enum Operation {
PUSH_BLOCK_BINDING(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
POP_BLOCK_FRAME(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
POP_BINDING(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
SAVE_BINDING_VIZ(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
RESTORE_BINDING_VIZ(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
TOGGLE_BACKTRACE(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect);

public final OpClass opClass;
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.jruby.ir.instructions;

import org.jruby.ir.IRVisitor;
import org.jruby.ir.Operation;
import org.jruby.ir.operands.Operand;
import org.jruby.ir.persistence.IRReaderDecoder;
import org.jruby.ir.persistence.IRWriterEncoder;
import org.jruby.ir.transformations.inlining.CloneInfo;
import org.jruby.ir.transformations.inlining.SimpleCloneInfo;

public class RestoreBindingVisibilityInstr extends OneOperandInstr implements FixedArityInstr {
public RestoreBindingVisibilityInstr(Operand viz) {
super(Operation.RESTORE_BINDING_VIZ, viz);
}

public Operand getVisibility() {
return getOperand1();
}

@Override
public Instr clone(CloneInfo ii) {
return ii instanceof SimpleCloneInfo ? this : NopInstr.NOP; // FIXME: Is this correct?
}

public static RestoreBindingVisibilityInstr decode(IRReaderDecoder d) {
return new RestoreBindingVisibilityInstr(d.decodeVariable());
}

@Override
public void encode(IRWriterEncoder e) {
super.encode(e);
e.encode(getVisibility());
}

@Override
public void visit(IRVisitor visitor) {
visitor.RestoreBindingVisibilityInstr(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.jruby.ir.instructions;

import org.jruby.ir.IRVisitor;
import org.jruby.ir.Operation;
import org.jruby.ir.operands.Variable;
import org.jruby.ir.persistence.IRReaderDecoder;
import org.jruby.ir.transformations.inlining.CloneInfo;
import org.jruby.ir.transformations.inlining.SimpleCloneInfo;

public class SaveBindingVisibilityInstr extends NoOperandResultBaseInstr implements FixedArityInstr {
public SaveBindingVisibilityInstr(Variable result) {
super(Operation.SAVE_BINDING_VIZ, result);
}

@Override
public Instr clone(CloneInfo ii) {
return ii instanceof SimpleCloneInfo ? this : NopInstr.NOP; // FIXME: Is this correct?
}

public static SaveBindingVisibilityInstr decode(IRReaderDecoder d) {
return new SaveBindingVisibilityInstr(d.decodeVariable());
}

@Override
public void visit(IRVisitor visitor) {
visitor.SaveBindingVisibilityInstr(this);
}
}
33 changes: 25 additions & 8 deletions core/src/main/java/org/jruby/ir/interpreter/InterpreterEngine.java
Original file line number Diff line number Diff line change
@@ -21,9 +21,11 @@
import org.jruby.ir.instructions.ReceiveArgBase;
import org.jruby.ir.instructions.ReceivePostReqdArgInstr;
import org.jruby.ir.instructions.ReceivePreReqdArgInstr;
import org.jruby.ir.instructions.RestoreBindingVisibilityInstr;
import org.jruby.ir.instructions.ResultInstr;
import org.jruby.ir.instructions.ReturnBase;
import org.jruby.ir.instructions.RuntimeHelperCall;
import org.jruby.ir.instructions.SaveBindingVisibilityInstr;
import org.jruby.ir.instructions.SearchConstInstr;
import org.jruby.ir.instructions.ToggleBacktraceInstr;
import org.jruby.ir.instructions.TraceInstr;
@@ -57,8 +59,8 @@
import org.jruby.parser.StaticScope;
import org.jruby.EvalType;
import org.jruby.runtime.Block;
import org.jruby.runtime.Frame;
import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.Frame;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
@@ -102,6 +104,18 @@ public IRubyObject interpret(ThreadContext context, Block block, IRubyObject sel
return interpret(context, block, self, interpreterContext, implClass, name, new IRubyObject[] {arg1, arg2, arg3, arg4}, blockArg);
}

private DynamicScope getBlockScope(ThreadContext context, Block block, InterpreterContext interpreterContext) {
DynamicScope newScope = block.getBinding().getDynamicScope();
if (interpreterContext.pushNewDynScope()) {
context.pushScope(block.allocScope(newScope));
} else if (interpreterContext.reuseParentDynScope()) {
// Reuse! We can avoid the push only if surrounding vars aren't referenced!
context.pushScope(newScope);
}

return newScope;
}

public IRubyObject interpret(ThreadContext context, Block block, IRubyObject self,
InterpreterContext interpreterContext, RubyModule implClass,
String name, IRubyObject[] args, Block blockArg) {
@@ -171,13 +185,7 @@ public IRubyObject interpret(ThreadContext context, Block block, IRubyObject sel
currDynScope = interpreterContext.newDynamicScope(context);
context.pushScope(currDynScope);
} else if (operation == Operation.PUSH_BLOCK_BINDING) {
DynamicScope newScope = block.getBinding().getDynamicScope();
if (interpreterContext.pushNewDynScope()) {
context.pushScope(block.allocScope(newScope));
} else if (interpreterContext.reuseParentDynScope()) {
// Reuse! We can avoid the push only if surrounding vars aren't referenced!
context.pushScope(newScope);
}
currDynScope = getBlockScope(context, block, interpreterContext);
} else {
processBookKeepingOp(context, block, instr, operation, name, args, self, blockArg, implClass, currDynScope, temp, currScope);
}
@@ -339,9 +347,18 @@ protected static void processBookKeepingOp(ThreadContext context, Block block, I
DynamicScope currDynScope, Object[] temp, StaticScope currScope) {
Block.Type blockType = block == null ? null : block.type;
Frame f;
Visibility viz;
switch(operation) {
case LABEL:
break;
case SAVE_BINDING_VIZ:
viz = block.getBinding().getVisibility();
setResult(temp, currDynScope, ((SaveBindingVisibilityInstr)instr).getResult(), viz);
break;
case RESTORE_BINDING_VIZ:
viz = (Visibility)retrieveOp(((RestoreBindingVisibilityInstr)instr).getVisibility(), context, self, currDynScope, currScope, temp);
block.getBinding().setVisibility(viz);
break;
case PUSH_BLOCK_FRAME:
f = context.preYieldNoScope(block.getBinding());
setResult(temp, currDynScope, ((PushBlockFrameInstr)instr).getResult(), f);
39 changes: 4 additions & 35 deletions core/src/main/java/org/jruby/runtime/ThreadContext.java
Original file line number Diff line number Diff line change
@@ -207,14 +207,6 @@ public IRubyObject setErrorInfo(IRubyObject errorInfo) {
return errorInfo;
}

/**
* Returns the lastCallStatus.
* @return LastCallStatus
*/
public void setLastCallStatus(CallType callType) {
lastCallType = callType;
}

public CallType getLastCallType() {
return lastCallType;
}
@@ -758,16 +750,11 @@ public static String createRawBacktraceStringFromThrowable(final Throwable ex, f

private Frame pushFrameForBlock(Binding binding) {
Frame lastFrame = getNextFrame();
Frame f = pushFrame(binding.getFrame());
f.setVisibility(binding.getVisibility());

return lastFrame;
}
Frame bindingFrame = binding.getFrame();
bindingFrame.setVisibility(binding.getVisibility());
pushFrame(bindingFrame);

private Frame pushFrameForEval(Binding binding) {
Frame lastFrame = getNextFrame();
Frame f = pushFrame(binding.getFrame());
f.setVisibility(binding.getVisibility());
return lastFrame;
}

@@ -895,26 +882,13 @@ public void postTrace() {
setWithinTrace(false);
}

public Frame preForBlock(Binding binding) {
Frame lastFrame = preYieldNoScope(binding);
pushScope(binding.getDynamicScope());
return lastFrame;
}

public Frame preYieldSpecificBlock(Binding binding, StaticScope scope) {
Frame lastFrame = preYieldNoScope(binding);
// new scope for this invocation of the block, based on parent scope
pushScope(DynamicScope.newDynamicScope(scope, binding.getDynamicScope()));
return lastFrame;
}

public Frame preYieldLightBlock(Binding binding, DynamicScope emptyScope) {
Frame lastFrame = preYieldNoScope(binding);
// just push the same empty scope, since we won't use one
pushScope(emptyScope);
return lastFrame;
}

public Frame preYieldNoScope(Binding binding) {
return pushFrameForBlock(binding);
}
@@ -928,7 +902,7 @@ public void postEvalScriptlet() {
}

public Frame preEvalWithBinding(Binding binding) {
return pushFrameForEval(binding);
return pushFrameForBlock(binding);
}

public void postEvalWithBinding(Binding binding, Frame lastFrame) {
@@ -940,11 +914,6 @@ public void postYield(Binding binding, Frame lastFrame) {
popFrameReal(lastFrame);
}

public void postYieldLight(Binding binding, Frame lastFrame) {
popScope();
popFrameReal(lastFrame);
}

public void postYieldNoScope(Frame lastFrame) {
popFrameReal(lastFrame);
}