Skip to content

Commit

Permalink
Merge branch 'truffle-break'
Browse files Browse the repository at this point in the history
  • Loading branch information
nirvdrum committed Jan 12, 2015
2 parents 4e4a5f5 + 3eab260 commit 6428162
Show file tree
Hide file tree
Showing 17 changed files with 226 additions and 76 deletions.
Expand Up @@ -37,7 +37,7 @@ public Object execute(VirtualFrame frame) {
// TODO(CS): not sure we're closing over the correct state here

return new RubyProc(getContext().getCoreLibrary().getProcClass(), RubyProc.Type.LAMBDA,
method.getSharedMethodInfo(), method.getCallTarget(), method.getCallTarget(),
method.getSharedMethodInfo(), method.getCallTarget(), method.getCallTarget(), method.getCallTarget(),
method.getDeclarationFrame(), method.getDeclaringModule(), method, RubyArguments.getSelf(frame.getArguments()), null);
}

Expand Down
Expand Up @@ -13,15 +13,12 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.instrument.KillException;
import com.oracle.truffle.api.nodes.DirectCallNode;
import com.oracle.truffle.api.nodes.InvalidAssumptionException;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.UndefinedPlaceholder;
import org.jruby.truffle.runtime.core.*;

public class TraceNode extends RubyNode {
Expand Down Expand Up @@ -70,7 +67,7 @@ public void trace(VirtualFrame frame) {
traceFunc = context.getTraceManager().getTraceFunc();

if (traceFunc != null) {
callNode = insert(Truffle.getRuntime().createDirectCallNode(traceFunc.getCallTarget()));
callNode = insert(Truffle.getRuntime().createDirectCallNode(traceFunc.getCallTargetForBlocks()));
} else {
callNode = null;
}
Expand Down
Expand Up @@ -2510,7 +2510,7 @@ public Object max(VirtualFrame frame, RubyArray array) {

final RubyProc block = new RubyProc(getContext().getCoreLibrary().getProcClass(), RubyProc.Type.PROC,
maxBlock.getSharedMethodInfo(), maxBlock.getCallTarget(), maxBlock.getCallTarget(),
maximumClosureFrame.materialize(), null, null, array, null);
maxBlock.getCallTarget(), maximumClosureFrame.materialize(), null, null, array, null);

eachNode.call(frame, array, "each", block);

Expand Down Expand Up @@ -2629,7 +2629,7 @@ public Object min(VirtualFrame frame, RubyArray array) {

final RubyProc block = new RubyProc(getContext().getCoreLibrary().getProcClass(), RubyProc.Type.PROC,
minBlock.getSharedMethodInfo(), minBlock.getCallTarget(), minBlock.getCallTarget(),
minimumClosureFrame.materialize(), null, null, array, null);
minBlock.getCallTarget(), minimumClosureFrame.materialize(), null, null, array, null);

eachNode.call(frame, array, "each", block);

Expand Down
Expand Up @@ -1240,7 +1240,8 @@ public RubyProc proc(RubyProc block) {

return new RubyProc(getContext().getCoreLibrary().getProcClass(), RubyProc.Type.LAMBDA,
block.getSharedMethodInfo(), block.getCallTargetForMethods(), block.getCallTargetForMethods(),
block.getDeclarationFrame(), block.getDeclaringModule(), block.getMethod(), block.getSelfCapturedInScope(), block.getBlockCapturedInScope());
block.getCallTargetForMethods(), block.getDeclarationFrame(), block.getDeclaringModule(),
block.getMethod(), block.getSelfCapturedInScope(), block.getBlockCapturedInScope());
}
}

Expand Down Expand Up @@ -1513,8 +1514,9 @@ public RubyProc proc(RubyProc block) {
notDesignedForCompilation();

return new RubyProc(getContext().getCoreLibrary().getProcClass(), RubyProc.Type.PROC,
block.getSharedMethodInfo(), block.getCallTarget(), block.getCallTargetForMethods(), block.getDeclarationFrame(),
block.getDeclaringModule(), block.getMethod(), block.getSelfCapturedInScope(), block.getBlockCapturedInScope());
block.getSharedMethodInfo(), block.getCallTargetForProcs(), block.getCallTargetForProcs(),
block.getCallTargetForMethods(), block.getDeclarationFrame(), block.getDeclaringModule(),
block.getMethod(), block.getSelfCapturedInScope(), block.getBlockCapturedInScope());
}
}

Expand Down
Expand Up @@ -113,8 +113,10 @@ public InitializeNode(InitializeNode prev) {

@Specialization
public RubyNilClass initialize(RubyProc proc, RubyProc block) {
proc.initialize(block.getSharedMethodInfo(), block.getCallTargetForMethods(), block.getCallTargetForMethods(),
block.getDeclarationFrame(), block.getDeclaringModule(), block.getMethod(), block.getSelfCapturedInScope(), block.getBlockCapturedInScope());
proc.initialize(block.getSharedMethodInfo(), block.getCallTargetForProcs(),
block.getCallTargetForProcs(), block.getCallTargetForMethods(), block.getDeclarationFrame(),
block.getDeclaringModule(), block.getMethod(), block.getSelfCapturedInScope(),
block.getBlockCapturedInScope());

return getContext().getCoreLibrary().getNilObject();
}
Expand Down
Expand Up @@ -14,7 +14,6 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.RubyRootNode;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyModule;
Expand All @@ -30,17 +29,23 @@ public class BlockDefinitionNode extends RubyNode {

private final SharedMethodInfo sharedMethodInfo;

private final CallTarget callTarget;
// TODO(CS, 10-Jan-15) having three call targets isn't ideal, but they all have different semantics, and we don't
// want to move logic into the call site

private final CallTarget callTargetForBlocks;
private final CallTarget callTargetForProcs;
private final CallTarget callTargetForMethods;

private final boolean requiresDeclarationFrame;

public BlockDefinitionNode(RubyContext context, SourceSection sourceSection, SharedMethodInfo sharedMethodInfo,
boolean requiresDeclarationFrame, CallTarget callTarget, CallTarget callTargetForMethods) {
boolean requiresDeclarationFrame, CallTarget callTargetForBlocks,
CallTarget callTargetForProcs, CallTarget callTargetForMethods) {
super(context, sourceSection);
this.sharedMethodInfo = sharedMethodInfo;

this.callTarget = callTarget;
this.callTargetForBlocks = callTargetForBlocks;
this.callTargetForProcs = callTargetForProcs;
this.callTargetForMethods = callTargetForMethods;

this.requiresDeclarationFrame = requiresDeclarationFrame;
Expand Down Expand Up @@ -68,7 +73,8 @@ public Object execute(VirtualFrame frame) {
}

return new RubyProc(getContext().getCoreLibrary().getProcClass(), RubyProc.Type.PROC, sharedMethodInfo,
callTarget, callTargetForMethods, declarationFrame, declaringModule, RubyArguments.getMethod(frame.getArguments()), RubyArguments.getSelf(frame.getArguments()),
callTargetForBlocks, callTargetForProcs, callTargetForMethods, declarationFrame, declaringModule,
RubyArguments.getMethod(frame.getArguments()), RubyArguments.getSelf(frame.getArguments()),
RubyArguments.getBlock(frame.getArguments()));
}

Expand Down
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.nodes.methods;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.BranchProfile;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.BreakException;
import org.jruby.truffle.runtime.control.RaiseException;

public class CatchBreakAsProcErrorNode extends RubyNode {

@Child private RubyNode body;

public CatchBreakAsProcErrorNode(RubyContext context, SourceSection sourceSection, RubyNode body) {
super(context, sourceSection);
this.body = body;
}

@Override
public Object execute(VirtualFrame frame) {
try {
return body.execute(frame);
} catch (BreakException e) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().loadError("break from proc-closure", this));
}
}

}
Expand Up @@ -28,7 +28,7 @@ public class CachedYieldDispatchNode extends YieldDispatchNode {
public CachedYieldDispatchNode(RubyContext context, RubyProc block, YieldDispatchNode next) {
super(context);

callNode = Truffle.getRuntime().createDirectCallNode(block.getCallTarget());
callNode = Truffle.getRuntime().createDirectCallNode(block.getCallTargetForBlocks());
insert(callNode);

if (Options.TRUFFLE_INLINER_ALWAYS_CLONE_YIELD.load() && callNode.isCallTargetCloningAllowed()) {
Expand All @@ -44,7 +44,7 @@ public CachedYieldDispatchNode(RubyContext context, RubyProc block, YieldDispatc

@Override
public Object dispatch(VirtualFrame frame, RubyProc block, Object[] argumentsObjects) {
if (block.getCallTarget() != callNode.getCallTarget()) {
if (block.getCallTargetForBlocks() != callNode.getCallTarget()) {
return next.dispatch(frame, block, argumentsObjects);
}

Expand All @@ -53,7 +53,7 @@ public Object dispatch(VirtualFrame frame, RubyProc block, Object[] argumentsObj

@Override
public Object dispatchWithModifiedBlock(VirtualFrame frame, RubyProc block, RubyProc modifiedBlock, Object[] argumentsObjects) {
if (block.getCallTarget() != callNode.getCallTarget()) {
if (block.getCallTargetForBlocks() != callNode.getCallTarget()) {
return next.dispatch(frame, block, argumentsObjects);
}

Expand All @@ -62,7 +62,7 @@ public Object dispatchWithModifiedBlock(VirtualFrame frame, RubyProc block, Ruby

@Override
public Object dispatchWithModifiedSelf(VirtualFrame frame, RubyProc block, Object self, Object... argumentsObjects) {
if (block.getCallTarget() != callNode.getCallTarget()) {
if (block.getCallTargetForBlocks() != callNode.getCallTarget()) {
return next.dispatchWithModifiedSelf(frame, block, self, argumentsObjects);
}

Expand Down
Expand Up @@ -30,17 +30,17 @@ public GeneralYieldDispatchNode(RubyContext context) {

@Override
public Object dispatch(VirtualFrame frame, RubyProc block, Object[] argumentsObjects) {
return callNode.call(frame, block.getCallTarget(), RubyArguments.pack(block, block.getDeclarationFrame(), block.getSelfCapturedInScope(), block.getBlockCapturedInScope(), argumentsObjects));
return callNode.call(frame, block.getCallTargetForBlocks(), RubyArguments.pack(block, block.getDeclarationFrame(), block.getSelfCapturedInScope(), block.getBlockCapturedInScope(), argumentsObjects));
}

@Override
public Object dispatchWithModifiedBlock(VirtualFrame frame, RubyProc block, RubyProc modifiedBlock, Object[] argumentsObjects) {
return callNode.call(frame, block.getCallTarget(), RubyArguments.pack(block, block.getDeclarationFrame(), block.getSelfCapturedInScope(), modifiedBlock, argumentsObjects));
return callNode.call(frame, block.getCallTargetForBlocks(), RubyArguments.pack(block, block.getDeclarationFrame(), block.getSelfCapturedInScope(), modifiedBlock, argumentsObjects));
}

@Override
public Object dispatchWithModifiedSelf(VirtualFrame frame, RubyProc block, Object self, Object... argumentsObjects) {
return callNode.call(frame, block.getCallTarget(), RubyArguments.pack(block, block.getDeclarationFrame(), self, block.getBlockCapturedInScope(), argumentsObjects));
return callNode.call(frame, block.getCallTargetForBlocks(), RubyArguments.pack(block, block.getDeclarationFrame(), self, block.getBlockCapturedInScope(), argumentsObjects));
}

}
36 changes: 24 additions & 12 deletions core/src/main/java/org/jruby/truffle/runtime/core/RubyProc.java
Expand Up @@ -29,13 +29,15 @@ public class RubyProc extends RubyBasicObject implements MethodLike {
public static final boolean PROC_BINDING = Options.TRUFFLE_PROC_BINDING.load();

public static enum Type {
PROC, LAMBDA
BLOCK, PROC, LAMBDA
}

private final Type type;
@CompilationFinal private SharedMethodInfo sharedMethodInfo;
/** Call target for procs, which have special arguments destructuring */
@CompilationFinal private CallTarget callTarget;
/** Call target for blocks, which have special arguments destructuring */
@CompilationFinal private CallTarget callTargetForBlocks;
/** Call target for actual Proc arguments, which handle break differently */
@CompilationFinal private CallTarget callTargetForProcs;
/** Call target for lambdas and methods, which have strict arguments destructuring */
@CompilationFinal private CallTarget callTargetForMethods;
@CompilationFinal private MaterializedFrame declarationFrame;
Expand All @@ -49,16 +51,20 @@ public RubyProc(RubyClass procClass, Type type) {
this.type = type;
}

public RubyProc(RubyClass procClass, Type type, SharedMethodInfo sharedMethodInfo, CallTarget callTarget,
CallTarget callTargetForMethods, MaterializedFrame declarationFrame, RubyModule declaringModule, MethodLike method, Object self, RubyProc block) {
public RubyProc(RubyClass procClass, Type type, SharedMethodInfo sharedMethodInfo, CallTarget callTargetForBlocks,
CallTarget callTargetForProcs, CallTarget callTargetForMethods, MaterializedFrame declarationFrame,
RubyModule declaringModule, MethodLike method, Object self, RubyProc block) {
this(procClass, type);
initialize(sharedMethodInfo, callTarget, callTargetForMethods, declarationFrame, declaringModule, method, self, block);
initialize(sharedMethodInfo, callTargetForBlocks, callTargetForProcs, callTargetForMethods, declarationFrame,
declaringModule, method, self, block);
}

public void initialize(SharedMethodInfo sharedMethodInfo, CallTarget callTarget, CallTarget callTargetForMethods,
MaterializedFrame declarationFrame, RubyModule declaringModule, MethodLike method, Object self, RubyProc block) {
public void initialize(SharedMethodInfo sharedMethodInfo, CallTarget callTargetForBlocks, CallTarget callTargetForProcs,
CallTarget callTargetForMethods, MaterializedFrame declarationFrame, RubyModule declaringModule,
MethodLike method, Object self, RubyProc block) {
this.sharedMethodInfo = sharedMethodInfo;
this.callTarget = callTarget;
this.callTargetForBlocks = callTargetForBlocks;
this.callTargetForProcs = callTargetForProcs;
this.callTargetForMethods = callTargetForMethods;
this.declarationFrame = declarationFrame;
this.declaringModule = declaringModule;
Expand All @@ -69,8 +75,10 @@ public void initialize(SharedMethodInfo sharedMethodInfo, CallTarget callTarget,

public CallTarget getCallTargetForType() {
switch (type) {
case BLOCK:
return callTargetForBlocks;
case PROC:
return callTarget;
return callTargetForProcs;
case LAMBDA:
return callTargetForMethods;
}
Expand All @@ -94,8 +102,12 @@ public SharedMethodInfo getSharedMethodInfo() {
return sharedMethodInfo;
}

public CallTarget getCallTarget() {
return callTarget;
public CallTarget getCallTargetForBlocks() {
return callTargetForBlocks;
}

public CallTarget getCallTargetForProcs() {
return callTargetForProcs;
}

public CallTarget getCallTargetForMethods() {
Expand Down
Expand Up @@ -55,7 +55,7 @@ public RubyProc toProc(SourceSection sourceSection, final RubyNode currentNode)
final CallTarget callTarget = Truffle.getRuntime().createCallTarget(rootNode);

return new RubyProc(context.getCoreLibrary().getProcClass(), RubyProc.Type.PROC, sharedMethodInfo, callTarget,
callTarget, null, null, null, getContext().getCoreLibrary().getNilObject(), null);
callTarget, callTarget, null, null, null, getContext().getCoreLibrary().getNilObject(), null);
}

public org.jruby.RubySymbol getJRubySymbol() {
Expand Down
Expand Up @@ -19,26 +19,26 @@
@NodeInfo(cost = NodeCost.NONE)
public class BehaveAsBlockNode extends RubyNode {

@Child private RubyNode asBlockNode;
@Child private RubyNode asMethodNode;
@Child private RubyNode asBlock;
@Child private RubyNode notAsBlock;

public BehaveAsBlockNode(RubyContext context, SourceSection sourceSection, RubyNode asBlockNode, RubyNode asMethodNode) {
public BehaveAsBlockNode(RubyContext context, SourceSection sourceSection, RubyNode asBlock, RubyNode notAsBlock) {
super(context, sourceSection);
this.asBlockNode = asBlockNode;
this.asMethodNode = asMethodNode;
this.asBlock = asBlock;
this.notAsBlock = notAsBlock;
}

@Override
public Object execute(VirtualFrame frame) {
throw new UnsupportedOperationException();
}

public RubyNode getAsBlockNode() {
return asBlockNode;
public RubyNode getAsBlock() {
return asBlock;
}

public RubyNode getAsMethodNode() {
return asMethodNode;
public RubyNode getNotAsBlock() {
return notAsBlock;
}

}
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2014, 2015 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.translator;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.NodeCost;
import com.oracle.truffle.api.nodes.NodeInfo;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;

@NodeInfo(cost = NodeCost.NONE)
public class BehaveAsProcNode extends RubyNode {

@Child private RubyNode asProc;
@Child private RubyNode notAsProc;

public BehaveAsProcNode(RubyContext context, SourceSection sourceSection, RubyNode asProc, RubyNode notAsProc) {
super(context, sourceSection);
this.asProc = asProc;
this.notAsProc = notAsProc;
}

@Override
public Object execute(VirtualFrame frame) {
throw new UnsupportedOperationException();
}

public RubyNode getAsProc() {
return asProc;
}

public RubyNode getNotAsProc() {
return notAsProc;
}

}

0 comments on commit 6428162

Please sign in to comment.