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

Commits on Dec 25, 2014

  1. Copy the full SHA
    e02b9e1 View commit details
  2. Copy the full SHA
    ae1d35e View commit details
Showing with 22 additions and 11 deletions.
  1. +15 −4 core/src/main/java/org/jruby/truffle/nodes/cast/SplatCastNode.java
  2. +7 −7 core/src/main/java/org/jruby/truffle/translator/BodyTranslator.java
19 changes: 15 additions & 4 deletions core/src/main/java/org/jruby/truffle/nodes/cast/SplatCastNode.java
Original file line number Diff line number Diff line change
@@ -38,20 +38,22 @@ public static enum NilBehavior {
}

private final NilBehavior nilBehavior;
private final boolean useToAry;

@Child protected ArrayDupNode dup;
@Child protected DispatchHeadNode respondToToA;
@Child protected BooleanCastNode respondToCast;
@Child protected DispatchHeadNode toA;

public SplatCastNode(RubyContext context, SourceSection sourceSection, NilBehavior nilBehavior) {
public SplatCastNode(RubyContext context, SourceSection sourceSection, NilBehavior nilBehavior, boolean useToAry) {
super(context, sourceSection);
this.nilBehavior = nilBehavior;
// Calling private #to_a is allowed for the *splat operator.
dup = ArrayDupNodeFactory.create(context, sourceSection, null);
respondToToA = new DispatchHeadNode(context, true, Dispatch.MissingBehavior.RETURN_MISSING);
respondToCast = BooleanCastNodeFactory.create(context, sourceSection, null);
toA = new DispatchHeadNode(context, true, Dispatch.MissingBehavior.RETURN_MISSING);
this.useToAry = useToAry;
}

public SplatCastNode(SplatCastNode prev) {
@@ -61,6 +63,7 @@ public SplatCastNode(SplatCastNode prev) {
respondToToA = prev.respondToToA;
respondToCast = prev.respondToCast;
toA = prev.toA;
useToAry = prev.useToAry;
}

protected abstract RubyNode getChild();
@@ -92,9 +95,17 @@ public RubyArray splat(VirtualFrame frame, RubyArray array) {
public RubyArray splat(VirtualFrame frame, Object object) {
notDesignedForCompilation();

final String method;

if (useToAry) {
method = "to_ary";
} else {
method = "to_a";
}

// TODO(CS): why are we directly calling #respond_to? instead of using a respondsTo on a dispatch head node?
if (respondToCast.executeBoolean(frame, respondToToA.call(frame, object, "respond_to?", null, getContext().makeString("to_a"), true))) {
final Object array = toA.call(frame, object, "to_a", null);
if (respondToCast.executeBoolean(frame, respondToToA.call(frame, object, "respond_to?", null, getContext().makeString(method), true))) {
final Object array = toA.call(frame, object, method, null);

if (array instanceof RubyArray) {
return (RubyArray) array;
@@ -104,7 +115,7 @@ public RubyArray splat(VirtualFrame frame, Object object) {
throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertTo(
getContext().getCoreLibrary().getLogicalClass(object).getName(),
"Array",
"to_a",
method,
getContext().getCoreLibrary().getLogicalClass(array).getName(),
this)
);
Original file line number Diff line number Diff line change
@@ -1227,13 +1227,13 @@ public RubyNode visitHashNode(org.jruby.ast.HashNode node) {
}
}

final RubyNode hashLiteralSoFar = HashLiteralNode.create(context, translate(node.getPosition()), keyValues.toArray(new RubyNode[keyValues.size()]));
hashConcats.add(hashLiteralSoFar);

if (hashConcats.size() == 1) {
return hashConcats.get(0);
}

final RubyNode hashLiteralSoFar = HashLiteralNode.create(context, translate(node.getPosition()), keyValues.toArray(new RubyNode[keyValues.size()]));
hashConcats.add(hashLiteralSoFar);

return new ConcatHashLiteralNode(context, sourceSection, hashConcats.toArray(new RubyNode[hashConcats.size()]));
}

@@ -1594,7 +1594,7 @@ public RubyNode visitMultipleAsgnNode(org.jruby.ast.MultipleAsgn19Node node) {
* the temp.
*/

final RubyNode splatCastNode = ArrayCastNodeFactory.create(context, sourceSection, translatingNextExpression ? SplatCastNode.NilBehavior.EMPTY_ARRAY : SplatCastNode.NilBehavior.ARRAY_WITH_NIL, environment.findLocalVarNode(tempRHSName, sourceSection));
final RubyNode splatCastNode = SplatCastNodeFactory.create(context, sourceSection, translatingNextExpression ? SplatCastNode.NilBehavior.EMPTY_ARRAY : SplatCastNode.NilBehavior.ARRAY_WITH_NIL, false, environment.findLocalVarNode(tempRHSName, sourceSection));

final RubyNode writeTemp = ((ReadNode) environment.findLocalVarNode(tempName, sourceSection)).makeWriteNode(splatCastNode);

@@ -1651,7 +1651,7 @@ public RubyNode visitMultipleAsgnNode(org.jruby.ast.MultipleAsgn19Node node) {
throw new RuntimeException("Unknown form of multiple assignment " + node + " at " + node.getPosition());
}

final SplatCastNode rhsSplatCast = SplatCastNodeFactory.create(context, sourceSection, translatingNextExpression ? SplatCastNode.NilBehavior.EMPTY_ARRAY : SplatCastNode.NilBehavior.ARRAY_WITH_NIL, rhsTranslated);
final SplatCastNode rhsSplatCast = SplatCastNodeFactory.create(context, sourceSection, translatingNextExpression ? SplatCastNode.NilBehavior.EMPTY_ARRAY : SplatCastNode.NilBehavior.ARRAY_WITH_NIL, false, rhsTranslated);

result = restRead.makeWriteNode(rhsSplatCast);
} else if (node.getPre() == null
@@ -1707,7 +1707,7 @@ public RubyNode visitMultipleAsgnNode(org.jruby.ast.MultipleAsgn19Node node) {

final List<RubyNode> sequence = new ArrayList<>();

final RubyNode splatCastNode = SplatCastNodeFactory.create(context, sourceSection, translatingNextExpression ? SplatCastNode.NilBehavior.EMPTY_ARRAY : SplatCastNode.NilBehavior.ARRAY_WITH_NIL, rhsTranslated);
final RubyNode splatCastNode = SplatCastNodeFactory.create(context, sourceSection, translatingNextExpression ? SplatCastNode.NilBehavior.EMPTY_ARRAY : SplatCastNode.NilBehavior.ARRAY_WITH_NIL, false, rhsTranslated);

final RubyNode writeTemp = ((ReadNode) environment.findLocalVarNode(tempName, sourceSection)).makeWriteNode(splatCastNode);

@@ -2233,7 +2233,7 @@ public RubyNode visitSplatNode(org.jruby.ast.SplatNode node) {
value = node.getValue().accept(this);
}

return SplatCastNodeFactory.create(context, sourceSection, SplatCastNode.NilBehavior.EMPTY_ARRAY, value);
return SplatCastNodeFactory.create(context, sourceSection, SplatCastNode.NilBehavior.EMPTY_ARRAY, false, value);
}

@Override