Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'master' into pedantic
Conflicts:
	test/pom.rb
	test/pom.xml
  • Loading branch information
chrisseaton committed Oct 16, 2014
2 parents 1618457 + cc5ae83 commit 93db492
Show file tree
Hide file tree
Showing 229 changed files with 5,328 additions and 2,679 deletions.
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/Ruby.java
Expand Up @@ -2824,7 +2824,7 @@ public void loadFile(String scriptName, InputStream in, boolean wrap) {

try {
ThreadContext.pushBacktrace(context, "(root)", file, 0);
context.preNodeEval(objectClass, self, scriptName);
context.preNodeEval(self);
ParseResult parseResult = parseFile(scriptName, in, null);

if (wrap) {
Expand Down
Expand Up @@ -48,15 +48,15 @@ void post(ThreadContext context) {
},
FrameBacktraceScopeFull (Framing.Backtrace, Scoping.Full) {
void pre(ThreadContext context, IRubyObject self, RubyModule implementer, String name, Block block, StaticScope scope) {
context.preMethodBacktraceAndScope(name, implementer, scope);
context.preMethodBacktraceAndScope(name, scope);
}
void post(ThreadContext context) {
context.postMethodBacktraceAndScope();
}
},
FrameBacktraceScopeDummy (Framing.Backtrace, Scoping.Dummy) {
void pre(ThreadContext context, IRubyObject self, RubyModule implementer, String name, Block block, StaticScope scope) {
context.preMethodBacktraceDummyScope(implementer, name, scope);
context.preMethodBacktraceDummyScope(name, scope);
}
void post(ThreadContext context) {
context.postMethodBacktraceDummyScope();
Expand All @@ -72,15 +72,15 @@ void post(ThreadContext context) {
},
FrameNoneScopeFull(Framing.None, Scoping.Full) {
void pre(ThreadContext context, IRubyObject self, RubyModule implementer, String name, Block block, StaticScope scope) {
context.preMethodScopeOnly(implementer, scope);
context.preMethodScopeOnly(scope);
}
void post(ThreadContext context) {
context.postMethodScopeOnly();
}
},
FrameNoneScopeDummy(Framing.None, Scoping.Dummy) {
void pre(ThreadContext context, IRubyObject self, RubyModule implementer, String name, Block block, StaticScope scope) {
context.preMethodNoFrameAndDummyScope(implementer, scope);
context.preMethodNoFrameAndDummyScope(scope);
}
void post(ThreadContext context) {
context.postMethodScopeOnly();
Expand Down
Expand Up @@ -5,6 +5,7 @@

import org.jruby.RubyModule;
import org.jruby.ir.*;
import org.jruby.ir.operands.InterpreterContext;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.Block;
import org.jruby.runtime.DynamicScope;
Expand All @@ -22,22 +23,24 @@ public List<String[]> getParameterList() {
}

@Override
protected void post(ThreadContext context) {
protected void post(InterpreterContext ic, ThreadContext context) {
// update call stacks (pop: ..)
context.popFrame();
context.popScope();
if (ic.popDynScope()) {
context.popScope();
}
}

@Override
protected void pre(ThreadContext context, IRubyObject self, String name, Block block) {
protected void pre(InterpreterContext ic, ThreadContext context, IRubyObject self, String name, Block block) {
// update call stacks (push: frame, class, scope, etc.)

StaticScope ss = method.getStaticScope();
context.preMethodFrameAndClass(getImplementationClass(), name, self, block, ss);
// Add a parent-link to current dynscope to support non-local returns cheaply
// This doesn't affect variable scoping since local variables will all have
// the right scope depth.
context.pushScope(DynamicScope.newDynamicScope(ss, context.getCurrentScope()));
context.preMethodFrameOnly(getImplementationClass(), name, self, block);
if (ic.pushNewDynScope()) {
// Add a parent-link to current dynscope to support non-local returns cheaply
// This doesn't affect variable scoping since local variables will all have
// the right scope depth.
context.pushScope(DynamicScope.newDynamicScope(method.getStaticScope(), context.getCurrentScope()));
}
context.setCurrentVisibility(getVisibility());
}

Expand Down
Expand Up @@ -8,6 +8,7 @@
import org.jruby.RubyClass;
import org.jruby.RubyModule;
import org.jruby.ir.*;
import org.jruby.ir.operands.InterpreterContext;
import org.jruby.ir.representations.CFG;
import org.jruby.ir.interpreter.Interpreter;
import org.jruby.ir.runtime.IRRuntimeHelpers;
Expand All @@ -28,7 +29,6 @@ public class InterpretedIRMethod extends DynamicMethod implements IRMethodArgs,

private Arity arity;
private boolean displayedCFG = false; // FIXME: Remove when we find nicer way of logging CFG
private boolean pushScope;

protected final IRScope method;

Expand All @@ -44,7 +44,6 @@ public InterpretedIRMethod(IRScope method, Visibility visibility, RubyModule imp
this.method = method;
this.method.getStaticScope().determineModule();
this.arity = calculateArity();
this.pushScope = true;
if (!implementationClass.getRuntime().getInstanceConfig().getCompileMode().shouldJIT()) {
this.box.callCount = -1;
}
Expand Down Expand Up @@ -89,18 +88,18 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
DynamicMethod actualMethod = box.actualMethod;
if (actualMethod != null) return actualMethod.call(context, self, clazz, name, args, block);

ensureInstrsReady();
InterpreterContext ic = ensureInstrsReady();

if (IRRuntimeHelpers.isDebug()) doDebug();

if (method.hasExplicitCallProtocol()) return Interpreter.INTERPRET_METHOD(context, this, self, name, args, block);

pre(context, self, name, block);
pre(ic, context, self, name, block);

try {
return Interpreter.INTERPRET_METHOD(context, this, self, name, args, block);
} finally {
post(context);
post(ic, context);
}
}

Expand All @@ -109,39 +108,37 @@ protected void doDebug() {
String realName = name == null || "".equals(name) ? method.getName() : name;
LOG.info("Executing '" + realName + "'");
if (displayedCFG == false) {
// The base IR may not have been processed yet
CFG cfg = method.getCFG();
LOG.info("Graph:\n" + cfg.toStringGraph());
LOG.info("CFG:\n" + cfg.toStringInstrs());
displayedCFG = true;
}
}

protected void post(ThreadContext context) {
protected void post(InterpreterContext ic, ThreadContext context) {
// update call stacks (pop: ..)
context.popFrame();
if (this.pushScope) {
if (ic.popDynScope()) {
context.popScope();
}
}

protected void pre(ThreadContext context, IRubyObject self, String name, Block block) {
protected void pre(InterpreterContext ic, ThreadContext context, IRubyObject self, String name, Block block) {
// update call stacks (push: frame, class, scope, etc.)
StaticScope ss = method.getStaticScope();
context.preMethodFrameAndClass(getImplementationClass(), name, self, block, ss);
if (this.pushScope) {
context.pushScope(DynamicScope.newDynamicScope(ss));
context.preMethodFrameOnly(getImplementationClass(), name, self, block);
if (ic.pushNewDynScope()) {
context.pushScope(DynamicScope.newDynamicScope(method.getStaticScope()));
}
context.setCurrentVisibility(getVisibility());
}

public void ensureInstrsReady() {
// SSS FIXME: Move this out of here to some other place?
// Prepare method if not yet done so we know if the method has an explicit/implicit call protocol
if (method.getInstrsForInterpretation() == null) {
method.prepareForInterpretation(false);
this.pushScope = !method.getFlags().contains(IRFlags.DYNSCOPE_ELIMINATED);
public InterpreterContext ensureInstrsReady() {
InterpreterContext context = method.getInterpreterContext();
if (context == null) {
context = method.prepareForInterpretation();
}
return context;
}

public DynamicMethod getMethodForCaching() {
Expand Down
Expand Up @@ -25,9 +25,7 @@
***** END LICENSE BLOCK *****/
package org.jruby.internal.runtime.methods;

import org.jruby.Ruby;
import org.jruby.RubyModule;
import org.jruby.anno.JRubyMethod;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.Arity;
import org.jruby.runtime.Block;
Expand Down Expand Up @@ -120,23 +118,23 @@ protected final void preFrameOnly(ThreadContext context, IRubyObject self, Strin
}

protected final void preScopeOnly(ThreadContext context) {
context.preMethodScopeOnly(implementationClass, staticScope);
context.preMethodScopeOnly(staticScope);
}

protected final void preNoFrameDummyScope(ThreadContext context) {
context.preMethodNoFrameAndDummyScope(implementationClass, staticScope);
context.preMethodNoFrameAndDummyScope(staticScope);
}

protected final void preBacktraceOnly(ThreadContext context, String name) {
context.preMethodBacktraceOnly(name);
}

protected final void preBacktraceDummyScope(ThreadContext context, String name) {
context.preMethodBacktraceDummyScope(implementationClass, name, staticScope);
context.preMethodBacktraceDummyScope(name, staticScope);
}

protected final void preBacktraceAndScope(ThreadContext context, String name) {
context.preMethodBacktraceAndScope(name, implementationClass, staticScope);
context.preMethodBacktraceAndScope(name, staticScope);
}

protected final void preNoop() {}
Expand Down
44 changes: 29 additions & 15 deletions core/src/main/java/org/jruby/ir/IRBuilder.java
Expand Up @@ -212,6 +212,10 @@ public void addInstr(Instr i) {
instrs.add(i);
}

public void addInstrAtBeginning(Instr i) {
instrs.add(0, i);
}

public void emitBody(IRBuilder b, IRScope s) {
b.addInstr(s, new LabelInstr(start));
for (Instr i: instrs) {
Expand Down Expand Up @@ -293,6 +297,16 @@ public void addInstr(IRScope s, Instr i) {
}
}

public void addInstrAtBeginning(IRScope s, Instr i) {
// If we are building an ensure body, stash the instruction
// in the ensure body's list. If not, add it to the scope directly.
if (ensureBodyBuildStack.empty()) {
s.addInstrAtBeginning(i);
} else {
ensureBodyBuildStack.peek().addInstrAtBeginning(i);
}
}

private Operand getImplicitBlockArg(IRScope s) {
int n = 0;
while (s != null && s instanceof IRClosure) {
Expand Down Expand Up @@ -505,8 +519,7 @@ public Operand buildLambda(LambdaNode node, IRScope s) {
// can be U_NIL if the node is an if node with returns in both branches.
if (closureRetVal != U_NIL) closureBuilder.addInstr(closure, new ReturnInstr(closureRetVal));

// Added as part of 'prepareForInterpretation' code.
// handleBreakAndReturnsInLambdas(closure);
handleBreakAndReturnsInLambdas(closure);

Variable lambda = s.createTemporaryVariable();
// SSS FIXME: Is this the right self here?
Expand Down Expand Up @@ -891,8 +904,8 @@ private void handleNonlocalReturnInMethod(IRScope s) {
//
// Add label and marker instruction in reverse order to the beginning
// so that the label ends up being the first instr.
s.addInstrAtBeginning(new ExceptionRegionStartMarkerInstr(gebLabel));
s.addInstrAtBeginning(new LabelInstr(rBeginLabel));
addInstrAtBeginning(s, new ExceptionRegionStartMarkerInstr(gebLabel));
addInstrAtBeginning(s, new LabelInstr(rBeginLabel));
addInstr(s, new ExceptionRegionEndMarkerInstr());

// Receive exceptions (could be anything, but the handler only processes IRReturnJumps)
Expand Down Expand Up @@ -1970,19 +1983,13 @@ public void buildMultipleAsgn19Assignment(final MultipleAsgn19Node multipleAsgnN
}
}

/* ------------------------------------------------------------------
* This code is added on demand at runtime in the interpreter code.
* For JIT, this may have to be added always!
// These two methods could have been DRY-ed out if we had closures.
// For now, just duplicating code.
private void handleBreakAndReturnsInLambdas(IRClosure s) {
Label rBeginLabel = s.getNewLabel();
Label rEndLabel = s.getNewLabel();
Label rescueLabel = s.getNewLabel();
Label rescueLabel = Label.getGlobalEnsureBlockLabel();

// protect the entire body as it exists now with the global ensure block
s.addInstrAtBeginning(new ExceptionRegionStartMarkerInstr(rescueLabel));
addInstrAtBeginning(s, new ExceptionRegionStartMarkerInstr(rescueLabel));
addInstr(s, new ExceptionRegionEndMarkerInstr());

// Receive exceptions (could be anything, but the handler only processes IRBreakJumps)
Expand All @@ -1992,14 +1999,13 @@ private void handleBreakAndReturnsInLambdas(IRClosure s) {

// Handle break using runtime helper
// --> IRRuntimeHelpers.handleBreakAndReturnsInLambdas(context, scope, bj, blockType)
Variable ret = createTemporaryVariable();
addInstr(s, new RuntimeHelperCall(ret, "handleBreakAndReturnsInLambdas", new Operand[]{exc} ));
Variable ret = s.createTemporaryVariable();
addInstr(s, new RuntimeHelperCall(ret, RuntimeHelperCall.Methods.HANDLE_BREAK_AND_RETURNS_IN_LAMBDA, new Operand[]{exc} ));
addInstr(s, new ReturnInstr(ret));

// End
addInstr(s, new LabelInstr(rEndLabel));
}
* ------------------------------------------------------------------ */

public void receiveMethodArgs(final ArgsNode argsNode, IRScope s) {
receiveArgs(argsNode, s);
Expand Down Expand Up @@ -2524,6 +2530,14 @@ public Operand buildIter(final IterNode iterNode, IRScope s) {
closureBuilder.addInstr(closure, new ReturnInstr(closureRetVal));
}

// Always add break/return handling even though this
// is only required for lambdas, but we don't know at this time,
// if this is a lambda or not.
//
// SSS FIXME: At a later time, see if we can optimize this and
// do this on demand.
closureBuilder.handleBreakAndReturnsInLambdas(closure);

return new WrappedIRClosure(s.getSelf(), closure);
}

Expand Down

0 comments on commit 93db492

Please sign in to comment.