Skip to content

Commit

Permalink
[Truffle] Last of hash specs passing.
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisseaton committed Oct 4, 2014
1 parent fb49596 commit b775ac1
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 7 deletions.
Expand Up @@ -831,6 +831,11 @@ public boolean equal(long a, double b) {
public boolean equal(long a, BigInteger b) {
return SlowPathBigInteger.compareTo(BigInteger.valueOf(a), b) == 0;
}

@Fallback
public boolean equal(Object a, Object b) {
return false;
}
}

@CoreMethod(names = "<=>", minArgs = 1, maxArgs = 1)
Expand Down
Expand Up @@ -56,6 +56,15 @@ public boolean equal(RubySymbol a, long b) {
return a.toString().equals(Long.toString(b));
}

@Specialization(guards = "notSymbol")
public boolean equal(RubySymbol a, Object b) {
return false;
}

protected boolean notSymbol(RubySymbol a, Object b) {
return !(b instanceof RubySymbol);
}

}

@CoreMethod(names = "all_symbols", isModuleMethod = true, needsSelf = false, maxArgs = 0)
Expand Down
Expand Up @@ -81,36 +81,53 @@ public RubyHash executeRubyHash(VirtualFrame frame) {

public static class SmallHashLiteralNode extends HashLiteralNode {

@Child protected DispatchHeadNode equalNode;

public SmallHashLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] keyValues) {
super(context, sourceSection, keyValues);
equalNode = new DispatchHeadNode(context);
}

@ExplodeLoop
@Override
public RubyHash executeRubyHash(VirtualFrame frame) {
final Object[] storage = new Object[RubyContext.HASHES_SMALL * 2];

for (int n = 0; n < keyValues.length; n += 2) {
int position = 0;

initializers: for (int n = 0; n < keyValues.length; n += 2) {
Object key = keyValues[n].execute(frame);
final Object value = keyValues[n + 1].execute(frame);

if (key instanceof RubyString) {
key = freezeNode.call(frame, dupNode.call(frame, key, "dup", null), "freeze", null);
}

storage[n] = key;
storage[n + 1] = value;
final Object value = keyValues[n + 1].execute(frame);

for (int i = 0; i < n; i += 2) {
if ((boolean) equalNode.call(frame, key, "==", null, storage[i])) {
storage[i + 1] = value;
continue initializers;
}
}

storage[position] = key;
storage[position + 1] = value;
position += 2;
}

return new RubyHash(getContext().getCoreLibrary().getHashClass(), null, storage, keyValues.length / 2);
return new RubyHash(getContext().getCoreLibrary().getHashClass(), null, storage, position / 2);
}

}

public static class GenericHashLiteralNode extends HashLiteralNode {

@Child protected DispatchHeadNode equalNode;

public GenericHashLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] keyValues) {
super(context, sourceSection, keyValues);
equalNode = new DispatchHeadNode(context);
}

@ExplodeLoop
Expand All @@ -122,12 +139,13 @@ public RubyHash executeRubyHash(VirtualFrame frame) {

for (int n = 0; n < keyValues.length; n += 2) {
Object key = keyValues[n].execute(frame);
final Object value = keyValues[n + 1].execute(frame);

if (key instanceof RubyString) {
key = freezeNode.call(frame, dupNode.call(frame, key, "dup", null), "freeze", null);
}

final Object value = keyValues[n + 1].execute(frame);

storage.put(key, value);
}

Expand Down
1 change: 0 additions & 1 deletion spec/truffle/tags/language/hash_tags.txt

This file was deleted.

0 comments on commit b775ac1

Please sign in to comment.