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

Commits on Dec 30, 2015

  1. Copy the full SHA
    4ff8a48 View commit details
  2. [Truffle] Fix last super spec.

    eregon committed Dec 30, 2015
    Copy the full SHA
    33d388a View commit details
5 changes: 0 additions & 5 deletions spec/truffle/tags/language/predefined_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
fails:The predefined global constant ARGV contains Strings encoded in locale Encoding
slow:The predefined global constant STDERR has the encodings set by #set_encoding
slow:The predefined global constant STDIN retains the encoding set by #set_encoding when Encoding.default_external is changed
slow:The predefined global constant STDIN has the encodings set by #set_encoding
@@ -10,7 +9,3 @@ windows:The predefined global constant STDERR has the encodings set by #set_enco
fails:Predefined global $_ is set to the last line read by e.g. StringIO#gets
fails:Predefined global $_ is set at the method-scoped level rather than block-scoped
fails:Global variable $0 actually sets the program name
fails:The predefined global constant STDIN has the encodings set by #set_encoding
fails:The predefined global constant STDIN retains the encoding set by #set_encoding when Encoding.default_external is changed
fails:The predefined global constant STDOUT has the encodings set by #set_encoding
fails:The predefined global constant STDERR has the encodings set by #set_encoding
1 change: 0 additions & 1 deletion spec/truffle/tags/language/super_tags.txt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
import com.oracle.truffle.api.nodes.NodeUtil;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.cast.BooleanCastNodeGen;
@@ -29,6 +30,7 @@
import org.jruby.truffle.nodes.methods.UnsupportedOperationBehavior;
import org.jruby.truffle.nodes.objects.AllocateObjectNode;
import org.jruby.truffle.nodes.objects.AllocateObjectNodeGen;
import org.jruby.truffle.nodes.supercall.GeneralSuperReCallNode;
import org.jruby.truffle.nodes.yield.YieldDispatchHeadNode;
import org.jruby.truffle.runtime.ModuleOperations;
import org.jruby.truffle.runtime.NotProvided;
@@ -208,7 +210,9 @@ public Object methodMissingBlock(Object self, DynamicObject name, Object[] args,
private Object methodMissing(Object self, DynamicObject nameObject, Object[] args, DynamicObject block) {
final String name = nameObject.toString();

if (lastCallWasCallingPrivateMethod(self, name)) {
if (lastCallWasSuper()) {
throw new RaiseException(getContext().getCoreLibrary().noSuperMethodError(name, this));
} else if (lastCallWasCallingPrivateMethod(self, name)) {
throw new RaiseException(getContext().getCoreLibrary().privateMethodError(name, self, this));
} else if (lastCallWasVCall()) {
throw new RaiseException(getContext().getCoreLibrary().nameErrorUndefinedLocalVariableOrMethod(name, self, this));
@@ -217,6 +221,11 @@ private Object methodMissing(Object self, DynamicObject nameObject, Object[] arg
}
}

private boolean lastCallWasSuper() {
final GeneralSuperReCallNode callNode = NodeUtil.findParent(Truffle.getRuntime().getCallerFrame().getCallNode(), GeneralSuperReCallNode.class);
return callNode != null;
}

/**
* See {@link org.jruby.truffle.nodes.dispatch.DispatchNode#lookup}.
* The only way to fail if method is not null and not undefined is visibility.
Original file line number Diff line number Diff line change
@@ -15,18 +15,20 @@
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;

import org.jcodings.specific.UTF8Encoding;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.cast.ProcOrNullNode;
import org.jruby.truffle.nodes.cast.ProcOrNullNodeGen;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.nodes.methods.CallMethodNode;
import org.jruby.truffle.nodes.methods.CallMethodNodeGen;
import org.jruby.truffle.nodes.methods.DeclarationContext;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.array.ArrayUtils;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.ArrayOperations;
import org.jruby.truffle.runtime.core.StringOperations;
import org.jruby.truffle.runtime.methods.InternalMethod;
@@ -46,6 +48,8 @@ public class GeneralSuperReCallNode extends RubyNode {
@Child LookupSuperMethodNode lookupSuperMethodNode;
@Child CallMethodNode callMethodNode;

@Child CallDispatchHeadNode callMethodMissingNode;

public GeneralSuperReCallNode(RubyContext context, SourceSection sourceSection, boolean hasRestParameter, RubyNode[] reloadNodes, RubyNode block) {
super(context, sourceSection);
this.hasRestParameter = hasRestParameter;
@@ -96,14 +100,17 @@ public final Object execute(VirtualFrame frame) {
if (superMethod == null) {
CompilerDirectives.transferToInterpreter();
final String name = RubyArguments.getMethod(frame.getArguments()).getSharedMethodInfo().getName(); // use the original name
throw new RaiseException(getContext().getCoreLibrary().noMethodError(String.format("super: no superclass method `%s'", name), name, this));
final Object[] methodMissingArguments = new Object[1 + superArguments.length];
methodMissingArguments[0] = getContext().getSymbol(name);
ArrayUtils.arraycopy(superArguments, 0, methodMissingArguments, 1, superArguments.length);
return callMethodMissing(frame, self, blockObject, methodMissingArguments);
}

final Object[] frameArguments = RubyArguments.pack(
superMethod,
RubyArguments.getDeclarationFrame(originalArguments),
null,
RubyArguments.getSelf(originalArguments),
self,
blockObject,
DeclarationContext.METHOD,
superArguments);
@@ -123,4 +130,12 @@ public Object isDefined(VirtualFrame frame) {
}
}

private Object callMethodMissing(VirtualFrame frame, Object receiver, DynamicObject block, Object[] arguments) {
if (callMethodMissingNode == null) {
CompilerDirectives.transferToInterpreter();
callMethodMissingNode = insert(DispatchHeadNodeFactory.createMethodCallOnSelf(getContext()));
}
return callMethodMissingNode.call(frame, receiver, "method_missing", block, arguments);
}

}
Original file line number Diff line number Diff line change
@@ -43,7 +43,7 @@ public final Object execute(VirtualFrame frame) {
"implicit argument passing of super from method defined by define_method() is not supported." +
" Specify all arguments explicitly.", this));
} else {
throw new RaiseException(getContext().getCoreLibrary().noSuperMethodError(this));
throw new RaiseException(getContext().getCoreLibrary().noSuperMethodOutsideMethodError(this));
}
}

Original file line number Diff line number Diff line change
@@ -1167,13 +1167,18 @@ public DynamicObject noMethodError(String message, String name, Node currentNode
return noMethodError;
}

public DynamicObject noSuperMethodError(Node currentNode) {
public DynamicObject noSuperMethodOutsideMethodError(Node currentNode) {
CompilerAsserts.neverPartOfCompilation();
DynamicObject noMethodError = noMethodError("super called outside of method", "<unknown>", currentNode);
noMethodError.define("@name", nilObject, 0); // FIXME: the name of the method is not known in this case currently
return noMethodError;
}

public DynamicObject noSuperMethodError(String name, Node currentNode) {
CompilerAsserts.neverPartOfCompilation();
return noMethodError(String.format("super: no superclass method `%s'", name), name, currentNode);
}

public DynamicObject noMethodErrorOnReceiver(String name, Object receiver, Node currentNode) {
CompilerAsserts.neverPartOfCompilation();
DynamicObject logicalClass = getLogicalClass(receiver);