Skip to content

Commit

Permalink
[Truffle] Add a Hash check that keys are symbols when splatted
Browse files Browse the repository at this point in the history
  • Loading branch information
Brandon Fish committed Nov 30, 2016
1 parent 2eab42d commit ad2bfbc
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 2 deletions.
1 change: 0 additions & 1 deletion spec/truffle/tags/language/hash_tags.txt

This file was deleted.

@@ -0,0 +1,34 @@
package org.jruby.truffle.core.hash;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.control.RaiseException;

public class EnsureSymbolKeysNode extends RubyNode {

@Child private RubyNode child;

private final BranchProfile errorProfile = BranchProfile.create();

public EnsureSymbolKeysNode(RubyContext context, SourceSection sourceSection, RubyNode child) {
super(context, sourceSection);
this.child = child;
}

@Override
public Object execute(VirtualFrame frame) {
final Object hash = child.execute(frame);
for (KeyValue keyValue : HashOperations.iterableKeyValues((DynamicObject) hash)) {
if (!RubyGuards.isRubySymbol(keyValue.getKey())) {
errorProfile.enter();
throw new RaiseException(coreExceptions().typeErrorWrongArgumentType(keyValue.getKey(), "Symbol", this));
}
}
return hash;
}
}
Expand Up @@ -44,6 +44,7 @@
import org.jruby.truffle.core.cast.ToSNode;
import org.jruby.truffle.core.cast.ToSNodeGen;
import org.jruby.truffle.core.hash.ConcatHashLiteralNode;
import org.jruby.truffle.core.hash.EnsureSymbolKeysNode;
import org.jruby.truffle.core.hash.HashLiteralNode;
import org.jruby.truffle.core.hash.HashNodesFactory;
import org.jruby.truffle.core.kernel.KernelNodesFactory;
Expand Down Expand Up @@ -1831,9 +1832,11 @@ public RubyNode visitHashNode(HashParseNode node) {

for (KeyValuePair<ParseNode, ParseNode> pair: node.getPairs()) {
if (pair.getKey() == null) {
// This null case is for splats {a: 1, **{b: 2}, c: 3}
final RubyNode hashLiteralSoFar = HashLiteralNode.create(context, fullSourceSection, keyValues.toArray(new RubyNode[keyValues.size()]));
hashConcats.add(hashLiteralSoFar);
hashConcats.add(HashCastNodeGen.create(context, fullSourceSection, pair.getValue().accept(this)));
hashConcats.add(new EnsureSymbolKeysNode(context, fullSourceSection,
HashCastNodeGen.create(context, fullSourceSection, pair.getValue().accept(this))));
keyValues.clear();
} else {
keyValues.add(pair.getKey().accept(this));
Expand Down

0 comments on commit ad2bfbc

Please sign in to comment.