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

Commits on Dec 4, 2016

  1. [Truffle] Simplify logic.

    eregon committed Dec 4, 2016
    Copy the full SHA
    8dc3927 View commit details
  2. [Truffle] Pass the last 3 language specs!

    * Handle keyword arguments in ReloadArgumentsTranslator
      and clean up support for the *rest argument.
    eregon committed Dec 4, 2016
    Copy the full SHA
    d35c8a5 View commit details
3 changes: 0 additions & 3 deletions spec/truffle/tags/language/super_tags.txt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -30,11 +30,11 @@ public class ReadZSuperArgumentsNode extends RubyNode {
@Children private final RubyNode[] reloadNodes;
@Child private ArrayToObjectArrayNode unsplatNode;

private final boolean hasRestParameter;
private final int restArgIndex;

public ReadZSuperArgumentsNode(RubyContext context, SourceSection sourceSection, boolean hasRestParameter, RubyNode[] reloadNodes) {
public ReadZSuperArgumentsNode(RubyContext context, SourceSection sourceSection, int restArgIndex, RubyNode[] reloadNodes) {
super(context, sourceSection);
this.hasRestParameter = hasRestParameter;
this.restArgIndex = restArgIndex;
this.reloadNodes = reloadNodes;

}
@@ -50,14 +50,15 @@ public final Object execute(VirtualFrame frame) {
superArguments[n] = reloadNodes[n].execute(frame);
}

if (hasRestParameter) {
// TODO (eregon, 22 July 2015): Assumes rest arg is last, not true if post or keyword args.
final int restArgIndex = reloadNodes.length - 1;
if (restArgIndex != -1) {
final Object restArg = superArguments[restArgIndex];
assert RubyGuards.isRubyArray(restArg);
final Object[] restArgs = unsplat((DynamicObject) restArg);
superArguments = ArrayUtils.copyOf(superArguments, restArgIndex + restArgs.length);
ArrayUtils.arraycopy(restArgs, 0, superArguments, restArgIndex, restArgs.length);
final int after = superArguments.length - (restArgIndex + 1);
Object[] splattedArguments = ArrayUtils.copyOf(superArguments, superArguments.length + restArgs.length - 1);
ArrayUtils.arraycopy(superArguments, restArgIndex + 1, splattedArguments, restArgIndex + restArgs.length, after);
ArrayUtils.arraycopy(restArgs, 0, splattedArguments, restArgIndex, restArgs.length);
superArguments = splattedArguments;
}

return superArguments;
Original file line number Diff line number Diff line change
@@ -288,19 +288,8 @@ public RubyNode visitKeywordArgNode(KeywordArgParseNode node) {
final RubySourceSection sourceSection = translate(node.getPosition());
final SourceSection fullSourceSection = sourceSection.toSourceSection(source);

final ParseNode firstChild = node.childNodes().get(0);
final AssignableParseNode asgnNode;
final String name;

if (firstChild instanceof LocalAsgnParseNode) {
asgnNode = (LocalAsgnParseNode) firstChild;
name = ((LocalAsgnParseNode) firstChild).getName();
} else if (firstChild instanceof DAsgnParseNode) {
asgnNode = (DAsgnParseNode) firstChild;
name = ((DAsgnParseNode) firstChild).getName();
} else {
throw new UnsupportedOperationException("unsupported keyword arg " + node);
}
final AssignableParseNode asgnNode = node.getAssignable();
final String name = ((INameNode) asgnNode).getName();

final FrameSlot slot = methodBodyTranslator.getEnvironment().getFrameDescriptor().findOrAddFrameSlot(name);

Original file line number Diff line number Diff line change
@@ -377,7 +377,7 @@ public RubyNode visitZSuperNode(ZSuperParseNode node) {
final SequenceNode reloadSequence = (SequenceNode) reloadTranslator.visitArgsNode(argsNode);

final RubyNode arguments = new ReadZSuperArgumentsNode(context, fullSourceSection,
reloadTranslator.isSplatted(),
reloadTranslator.getRestParameterIndex(),
reloadSequence.getSequence());
final RubyNode block = executeOrInheritBlock(blockNode);
return new SuperCallNode(context, fullSourceSection, arguments, block);
Original file line number Diff line number Diff line change
@@ -13,18 +13,25 @@
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.hash.ConcatHashLiteralNode;
import org.jruby.truffle.core.hash.HashLiteralNode;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.RubySourceSection;
import org.jruby.truffle.language.arguments.MissingArgumentBehavior;
import org.jruby.truffle.language.arguments.ProfileArgumentNode;
import org.jruby.truffle.language.arguments.ReadPreArgumentNode;
import org.jruby.truffle.language.control.SequenceNode;
import org.jruby.truffle.language.literal.ObjectLiteralNode;
import org.jruby.truffle.parser.ast.ArgsParseNode;
import org.jruby.truffle.parser.ast.ArgumentParseNode;
import org.jruby.truffle.parser.ast.AssignableParseNode;
import org.jruby.truffle.parser.ast.KeywordArgParseNode;
import org.jruby.truffle.parser.ast.KeywordRestArgParseNode;
import org.jruby.truffle.parser.ast.MultipleAsgnParseNode;
import org.jruby.truffle.parser.ast.OptArgParseNode;
import org.jruby.truffle.parser.ast.ParseNode;
import org.jruby.truffle.parser.ast.RestArgParseNode;
import org.jruby.truffle.parser.ast.types.INameNode;

import java.util.ArrayList;
import java.util.List;
@@ -40,13 +47,17 @@ public class ReloadArgumentsTranslator extends Translator {
private final BodyTranslator methodBodyTranslator;

private int index = 0;
private boolean hasRestParameter = false;
private int restParameterIndex = -1;

public ReloadArgumentsTranslator(Node currentNode, RubyContext context, Source source, BodyTranslator methodBodyTranslator) {
super(currentNode, context, source);
this.methodBodyTranslator = methodBodyTranslator;
}

public int getRestParameterIndex() {
return restParameterIndex;
}

@Override
public RubyNode visitArgsNode(ArgsParseNode node) {
final RubySourceSection sourceSection = translate(node.getPosition());
@@ -72,7 +83,7 @@ public RubyNode visitArgsNode(ArgsParseNode node) {
}

if (node.hasRestArg()) {
hasRestParameter = true;
restParameterIndex = node.getPostIndex();
sequence.add(node.getRestArgNode().accept(this));
}

@@ -82,8 +93,36 @@ public RubyNode visitArgsNode(ArgsParseNode node) {
System.err.printf("WARNING: post args in zsuper not yet implemented at %s:%d%n", sourceSectionX.getSource().getName(), sourceSectionX.getStartLine());
}

if (node.hasKwargs() && !source.getName().endsWith("/language/fixtures/super.rb")) {
System.err.printf("WARNING: kwargs in zsuper not yet implemented at %s:%d%n", sourceSectionX.getSource().getName(), sourceSectionX.getStartLine());
RubyNode kwArgsNode = null;

if (node.hasKwargs()) {
final int keywordIndex = node.getKeywordsIndex();
final int keywordCount = node.getKeywordCount();
RubyNode[] keyValues = new RubyNode[keywordCount * 2];

for (int i = 0; i < keywordCount; i++) {
final KeywordArgParseNode kwArg = (KeywordArgParseNode) args[keywordIndex + i];
final RubyNode value = kwArg.accept(this);
final String name = ((INameNode) kwArg.getAssignable()).getName();
RubyNode key = new ObjectLiteralNode(context, sourceSectionX, context.getSymbolTable().getSymbol(name));
keyValues[2 * i] = key;
keyValues[2 * i + 1] = value;
}
kwArgsNode = HashLiteralNode.create(context, sourceSectionX, keyValues);
}

if (node.hasKeyRest()) {
final RubyNode keyRest = node.getKeyRest().accept(this);
if (kwArgsNode == null) {
kwArgsNode = keyRest;
} else {
kwArgsNode = new ConcatHashLiteralNode(context, sourceSectionX, new RubyNode[]{kwArgsNode, keyRest});
}

}

if (kwArgsNode != null) {
sequence.add(kwArgsNode);
}

return new SequenceNode(sourceSection.toSourceSection(source), sequence.toArray(new RubyNode[sequence.size()]));
@@ -113,13 +152,23 @@ public RubyNode visitRestArgNode(RestArgParseNode node) {
}

@Override
protected RubyNode defaultVisit(ParseNode node) {
public RubyNode visitKeywordArgNode(KeywordArgParseNode node) {
final RubySourceSection sourceSection = translate(node.getPosition());
return nilNode(source, sourceSection);
final AssignableParseNode asgnNode = node.getAssignable();
final String name = ((INameNode) asgnNode).getName();
return methodBodyTranslator.getEnvironment().findLocalVarNode(name, source, sourceSection);
}

public boolean isSplatted() {
return hasRestParameter;
@Override
public RubyNode visitKeywordRestArgNode(KeywordRestArgParseNode node) {
final RubySourceSection sourceSection = translate(node.getPosition());
return methodBodyTranslator.getEnvironment().findLocalVarNode(node.getName(), source, sourceSection);
}

@Override
protected RubyNode defaultVisit(ParseNode node) {
final RubySourceSection sourceSection = translate(node.getPosition());
return nilNode(source, sourceSection);
}

}