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: e47a9da53b60
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 5e508abf695f
Choose a head ref
  • 2 commits
  • 4 files changed
  • 2 contributors

Commits on Dec 12, 2014

  1. Reintroduce "[Truffle] Raise NameError in #method_missing if it came …

    …from a VCall."
    
    This reintroduces commit 6d424b4.
    
    Conflicts:
    	core/src/main/java/org/jruby/truffle/nodes/core/BasicObjectNodes.java
    
    * It does not touch tags, as no failure is introduced.
    chrisseaton authored and eregon committed Dec 12, 2014
    Copy the full SHA
    1cca07d View commit details
  2. Copy the full SHA
    5e508ab View commit details
11 changes: 11 additions & 0 deletions core/src/main/java/org/jruby/truffle/nodes/RubyCallNode.java
Original file line number Diff line number Diff line change
@@ -37,6 +37,7 @@ public class RubyCallNode extends RubyNode {
@Children protected final RubyNode[] arguments;

private final boolean isSplatted;
private final boolean isVCall;

@Child protected DispatchHeadNode dispatchHead;

@@ -56,7 +57,12 @@ public RubyCallNode(RubyContext context, SourceSection section, String methodNam
this(context, section, methodName, receiver, block, isSplatted, false, false, arguments);
}


public RubyCallNode(RubyContext context, SourceSection section, String methodName, RubyNode receiver, RubyNode block, boolean isSplatted, boolean ignoreVisibility, boolean rubiniusPrimitive, RubyNode... arguments) {
this(context, section, methodName, receiver, block, isSplatted, false, ignoreVisibility, rubiniusPrimitive, arguments);
}

public RubyCallNode(RubyContext context, SourceSection section, String methodName, RubyNode receiver, RubyNode block, boolean isSplatted, boolean isVCall, boolean ignoreVisibility, boolean rubiniusPrimitive, RubyNode... arguments) {
super(context, section);

this.methodName = methodName;
@@ -71,6 +77,7 @@ public RubyCallNode(RubyContext context, SourceSection section, String methodNam

this.arguments = arguments;
this.isSplatted = isSplatted;
this.isVCall = isVCall;

dispatchHead = new DispatchHeadNode(context, ignoreVisibility, false, rubiniusPrimitive, Dispatch.MissingBehavior.CALL_METHOD_MISSING);
respondToMissing = new DispatchHeadNode(context, true, Dispatch.MissingBehavior.RETURN_MISSING);
@@ -209,4 +216,8 @@ public String getName() {
return methodName;
}

public boolean isVCall() {
return isVCall;
}

}
Original file line number Diff line number Diff line change
@@ -11,12 +11,15 @@

import java.util.*;

import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.nodes.NodeUtil;
import com.oracle.truffle.api.source.*;
import com.oracle.truffle.api.dsl.*;
import com.oracle.truffle.api.frame.VirtualFrame;
import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.cast.BooleanCastNodeFactory;
import org.jruby.truffle.nodes.RubyCallNode;
import org.jruby.truffle.nodes.dispatch.Dispatch;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.PredicateDispatchHeadNode;
@@ -273,11 +276,23 @@ public Object methodMissing(RubyBasicObject self, Object[] args, RubyProc block)
}

private Object methodMissing(RubyBasicObject self, RubySymbol name, Object[] args, RubyProc block) {
if (self == getContext().getCoreLibrary().getMainObject()) {
throw new RaiseException(getContext().getCoreLibrary().nameError(String.format("undefined local variable or method `%s' for main:Object", name.toString()), this));
// TODO: should not be a call to Java toString(), but rather sth like name_err_mesg_to_str() in MRI error.c
if (lastCallWasVCall()) {
throw new RaiseException(getContext().getCoreLibrary().nameErrorUndefinedLocalVariableOrMethod(name.toString(), self.toString(), this));
} else {
throw new RaiseException(getContext().getCoreLibrary().noMethodError(name.toString(), self.toString(), this));
}
}

private boolean lastCallWasVCall() {
final RubyCallNode callNode = NodeUtil.findParent(Truffle.getRuntime().getCallerFrame().getCallNode(), RubyCallNode.class);

if (callNode == null) {
return false;
}

throw new RaiseException(getContext().getCoreLibrary().noMethodError(name.toString(), self.toString(), this));
return callNode.isVCall();

}

}
Original file line number Diff line number Diff line change
@@ -532,6 +532,10 @@ public RubyException nameErrorReadOnly(String name, Node currentNode) {
return nameError(String.format("%s is a read-only variable", name), currentNode);
}

public RubyException nameErrorUndefinedLocalVariableOrMethod(String name, String object, Node currentNode) {
return nameError(String.format("undefined local variable or method `%s' for %s", name, object), currentNode);
}

public RubyException noMethodError(String message, Node currentNode) {
CompilerAsserts.neverPartOfCompilation();
return new RubyException(context.getCoreLibrary().getNoMethodErrorClass(), context.makeString(message), RubyCallStack.getBacktrace(currentNode));
Original file line number Diff line number Diff line change
@@ -192,7 +192,7 @@ public RubyNode visitAttrAssignNode(org.jruby.ast.AttrAssignNode node) {
public RubyNode visitAttrAssignNodeExtraArgument(org.jruby.ast.AttrAssignNode node, RubyNode extraArgument) {
final CallNode callNode = new CallNode(node.getPosition(), node.getReceiverNode(), node.getName(), node.getArgsNode(), null);
boolean isAccessorOnSelf = (node.getReceiverNode() instanceof org.jruby.ast.SelfNode);
return visitCallNodeExtraArgument(callNode, extraArgument, isAccessorOnSelf);
return visitCallNodeExtraArgument(callNode, extraArgument, isAccessorOnSelf, false);
}

@Override
@@ -269,13 +269,13 @@ public RubyNode visitBreakNode(org.jruby.ast.BreakNode node) {

@Override
public RubyNode visitCallNode(CallNode node) {
return visitCallNodeExtraArgument(node, null, false);
return visitCallNodeExtraArgument(node, null, false, false);
}

/**
* See translateDummyAssignment to understand what this is for.
*/
public RubyNode visitCallNodeExtraArgument(CallNode node, RubyNode extraArgument, boolean ignoreVisibility) {
public RubyNode visitCallNodeExtraArgument(CallNode node, RubyNode extraArgument, boolean ignoreVisibility, boolean isVCall) {
final SourceSection sourceSection = translate(node.getPosition());

final RubyNode receiverTranslated = node.getReceiverNode().accept(this);
@@ -298,7 +298,7 @@ public RubyNode visitCallNodeExtraArgument(CallNode node, RubyNode extraArgument
new RescueNode[] {new RescueAnyNode(context, sourceSection, new ObjectLiteralNode(context, sourceSection, context.getCoreLibrary().getNilObject()))},
new ObjectLiteralNode(context, sourceSection, context.getCoreLibrary().getNilObject()));
} else {
translated = new RubyCallNode(context, sourceSection, node.getName(), receiverTranslated, argumentsAndBlock.getBlock(), argumentsAndBlock.isSplatted(), ignoreVisibility, false, argumentsAndBlock.getArguments());
translated = new RubyCallNode(context, sourceSection, node.getName(), receiverTranslated, argumentsAndBlock.getBlock(), argumentsAndBlock.isSplatted(), isVCall, ignoreVisibility, false, argumentsAndBlock.getArguments());
}

// return instrumenter.instrumentAsCall(translated, node.getName());
@@ -842,7 +842,7 @@ public RubyNode visitFCallNode(org.jruby.ast.FCallNode node) {
final org.jruby.ast.Node receiver = new org.jruby.ast.SelfNode(node.getPosition());
final CallNode callNode = new CallNode(node.getPosition(), receiver, node.getName(), node.getArgsNode(), node.getIterNode());

return visitCallNodeExtraArgument(callNode, null, true);
return visitCallNodeExtraArgument(callNode, null, true, false);
}

@Override
@@ -2159,7 +2159,7 @@ public RubyNode visitVCallNode(org.jruby.ast.VCallNode node) {
final org.jruby.ast.Node args = null;
final CallNode callNode = new CallNode(node.getPosition(), receiver, node.getName(), args, null);

return visitCallNodeExtraArgument(callNode, null, true);
return visitCallNodeExtraArgument(callNode, null, true, true);
}

@Override