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

Commits on Dec 24, 2014

  1. Copy the full SHA
    0137e98 View commit details
  2. Copy the full SHA
    430efff View commit details
101 changes: 101 additions & 0 deletions core/src/main/java/org/jruby/truffle/nodes/cast/HashCastNode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright (c) 2014 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.cast;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
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.dispatch.Dispatch;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.*;

// TODO(CS): copy and paste of ArrayCastNode

@NodeChild("child")
public abstract class HashCastNode extends RubyNode {

@Child protected DispatchHeadNode toHashNode;

public HashCastNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
toHashNode = new DispatchHeadNode(context, Dispatch.MissingBehavior.RETURN_MISSING);
}

public HashCastNode(HashCastNode prev) {
super(prev);
toHashNode = prev.toHashNode;
}

protected abstract RubyNode getChild();

@Specialization
public RubyNilClass cast(boolean value) {
return getContext().getCoreLibrary().getNilObject();
}

@Specialization
public RubyNilClass cast(int value) {
return getContext().getCoreLibrary().getNilObject();
}

@Specialization
public RubyNilClass cast(long value) {
return getContext().getCoreLibrary().getNilObject();
}

@Specialization
public RubyNilClass cast(double value) {
return getContext().getCoreLibrary().getNilObject();
}

@Specialization
public RubyNilClass cast(RubyBignum value) {
return getContext().getCoreLibrary().getNilObject();
}

@Specialization
public RubyHash cast(RubyHash hash) {
return hash;
}

@Specialization
public RubyNilClass cast(RubyNilClass nil) {
return nil;
}

@Specialization(guards = {"!isRubyNilClass", "!isRubyHash"})
public Object cast(VirtualFrame frame, RubyBasicObject object) {
notDesignedForCompilation();

final Object result = toHashNode.call(frame, object, "to_hash", null, new Object[]{});

if (result == Dispatch.MISSING) {
return getContext().getCoreLibrary().getNilObject();
}

if (!(result instanceof RubyHash)) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().typeErrorShouldReturn(object.toString(), "to_hash", "HAsh", this));
}

return result;
}

@Override
public void executeVoid(VirtualFrame frame) {
getChild().executeVoid(frame);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2014 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.literal;

import com.oracle.truffle.api.frame.VirtualFrame;
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.RubyContext;
import org.jruby.truffle.runtime.core.RubyHash;
import org.jruby.truffle.runtime.hash.HashOperations;
import org.jruby.truffle.runtime.hash.KeyValue;

import java.util.ArrayList;
import java.util.List;

public class ConcatHashLiteralNode extends RubyNode {

@Children protected final RubyNode[] children;

public ConcatHashLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] children) {
super(context, sourceSection);
this.children = children;
}

@Override
public RubyHash executeRubyHash(VirtualFrame frame) {
notDesignedForCompilation();

final List<KeyValue> keyValues = new ArrayList<>();

for (RubyNode child : children) {
try {
keyValues.addAll(HashOperations.verySlowToKeyValues(child.executeRubyHash(frame)));
} catch (UnexpectedResultException e) {
throw new UnsupportedOperationException();
}
}

return HashOperations.verySlowFromEntries(getContext(), keyValues);
}

@Override
public Object execute(VirtualFrame frame) {
return executeRubyHash(frame);
}

}
Original file line number Diff line number Diff line change
@@ -1206,23 +1206,35 @@ public RubyNode visitGlobalVarNode(org.jruby.ast.GlobalVarNode node) {
public RubyNode visitHashNode(org.jruby.ast.HashNode node) {
final SourceSection sourceSection = translate(node.getPosition());

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

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

for (KeyValuePair<Node, Node> pair: node.getPairs()) {
if (pair.getKey() == null) {
keyValues.add(new ObjectLiteralNode(context, sourceSection, context.getCoreLibrary().getNilObject()));
final RubyNode hashLiteralSoFar = HashLiteralNode.create(context, translate(node.getPosition()), keyValues.toArray(new RubyNode[keyValues.size()]));
hashConcats.add(hashLiteralSoFar);
hashConcats.add(HashCastNodeFactory.create(context, sourceSection, pair.getValue().accept(this)));
keyValues.clear();
} else {
keyValues.add(pair.getKey().accept(this));
}

if (pair.getValue() == null) {
keyValues.add(new ObjectLiteralNode(context, sourceSection, context.getCoreLibrary().getNilObject()));
} else {
keyValues.add(pair.getValue().accept(this));
if (pair.getValue() == null) {
keyValues.add(new ObjectLiteralNode(context, sourceSection, context.getCoreLibrary().getNilObject()));
} else {
keyValues.add(pair.getValue().accept(this));
}
}
}

return HashLiteralNode.create(context, translate(node.getPosition()), keyValues.toArray(new RubyNode[keyValues.size()]));
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()]));
}

@Override
1 change: 0 additions & 1 deletion spec/truffle/tags/language/block_tags.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
fails:Block-local variables override shadowed variables from the outer scope
fails:Post-args with pattern matching extracts matched blocks with post arguments
fails:A block yielded a single Array assigns nil to unassigned required arguments
fails:A block yielded a single Array assigns elements to optional arguments
fails:A block yielded a single Array assgins elements to post arguments
2 changes: 0 additions & 2 deletions spec/truffle/tags/language/hash_tags.txt

This file was deleted.

2 changes: 1 addition & 1 deletion spec/truffle/tags/language/send_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
fails:Invoking a method with optional argument(s), expands an array to arguments grouped in parentheses
fails:Invoking a method expands an array to arguments grouped in parentheses which in turn takes rest arguments
fails:Invoking a method converts a final splatted explicit Hash to an Array
1 change: 0 additions & 1 deletion spec/truffle/tags/language/variables_tags.txt
Original file line number Diff line number Diff line change
@@ -30,7 +30,6 @@ fails:Multiple assignment with a single RHS value assigns indexed elements
fails:Multiple assignment with a single splatted RHS value calls #to_a to convert nil to an empty Array
fails:Multiple assignment with a single splatted RHS value returns an Array when the splatted object is an Array subclass
fails:Multiple assignment with a single splatted RHS value does not call #to_a if #respond_to? returns false
fails:Multiple assignment with a single splatted RHS value raises a TypeError if #to_a does not return an Array
fails:Multiple assignment with a single splatted RHS value assigns a MLHS with leading splat
fails:Multiple assignment with a single splatted RHS value calls #to_a to convert an Object splat RHS when assigned to a simple MLHS
fails:Multiple assignment with a single splatted RHS value does not call #to_ary to convert an Object splat RHS when assigned to a simple MLHS