Skip to content

Commit

Permalink
Showing 3 changed files with 33 additions and 6 deletions.
3 changes: 3 additions & 0 deletions test/truffle/compiler/pe/core/string_pe.rb
Original file line number Diff line number Diff line change
@@ -35,3 +35,6 @@
example "''.empty?", true
example "'abc'.empty?", false
example "'こにちわ'.empty?", false

example "'A' == String.from_codepoint(65, Encoding::US_ASCII)", true
example "'A' == 65.chr", true
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@

package org.jruby.truffle.core.rope;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import org.jcodings.Encoding;

import java.lang.ref.WeakReference;
@@ -24,7 +24,7 @@ public class RopeTable {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final WeakHashMap<Key, WeakReference<Rope>> ropesTable = new WeakHashMap<>();

@CompilerDirectives.TruffleBoundary
@TruffleBoundary
public Rope getRope(byte[] bytes, Encoding encoding, CodeRange codeRange) {
final Key key = new Key(bytes, encoding);

Original file line number Diff line number Diff line change
@@ -505,14 +505,24 @@ public StringEqualPrimitiveNode(RubyContext context, SourceSection sourceSection

public abstract boolean executeStringEqual(DynamicObject string, DynamicObject other);

@Specialization(guards = "ropeEqual(string, other)")
@Specialization(guards = "ropeReferenceEqual(string, other)")
public boolean stringEqualsRopeEquals(DynamicObject string, DynamicObject other) {
return true;
}

@Specialization(guards = {
"isRubyString(other)",
"!ropeEqual(string, other)",
"!ropeReferenceEqual(string, other)",
"bytesReferenceEqual(string, other)"
})
public boolean stringEqualsBytesEquals(DynamicObject string, DynamicObject other) {
return true;
}

@Specialization(guards = {
"isRubyString(other)",
"!ropeReferenceEqual(string, other)",
"!bytesReferenceEqual(string, other)",
"!areComparable(string, other, sameEncodingProfile, firstStringEmptyProfile, secondStringEmptyProfile, firstStringCR7BitProfile, secondStringCR7BitProfile, firstStringAsciiCompatible, secondStringAsciiCompatible)"
})
public boolean stringEqualNotComparable(DynamicObject string, DynamicObject other,
@@ -528,7 +538,8 @@ public boolean stringEqualNotComparable(DynamicObject string, DynamicObject othe

@Specialization(guards = {
"isRubyString(other)",
"!ropeEqual(string, other)",
"!ropeReferenceEqual(string, other)",
"!bytesReferenceEqual(string, other)",
"areComparable(string, other, sameEncodingProfile, firstStringEmptyProfile, secondStringEmptyProfile, firstStringCR7BitProfile, secondStringCR7BitProfile, firstStringAsciiCompatible, secondStringAsciiCompatible)"
})
public boolean equal(DynamicObject string, DynamicObject other,
@@ -599,12 +610,25 @@ protected boolean areComparable(DynamicObject first, DynamicObject second,
return false;
}

protected static boolean ropeEqual(DynamicObject first, DynamicObject second) {
protected static boolean ropeReferenceEqual(DynamicObject first, DynamicObject second) {
assert RubyGuards.isRubyString(first);
assert RubyGuards.isRubyString(second);

return rope(first) == rope(second);
}

protected static boolean bytesReferenceEqual(DynamicObject first, DynamicObject second) {
assert RubyGuards.isRubyString(first);
assert RubyGuards.isRubyString(second);

final Rope firstRope = rope(first);
final Rope secondRope = rope(second);

return firstRope.getCodeRange() == CodeRange.CR_7BIT &&
secondRope.getCodeRange() == CodeRange.CR_7BIT &&
firstRope.getRawBytes() != null &&
firstRope.getRawBytes() == secondRope.getRawBytes();
}
}

@RubiniusPrimitive(name = "string_find_character")

2 comments on commit 07cee75

@nirvdrum
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chrisseaton I don't recall exactly what comparison you were trying to compile previously, but I think it involved ropes with the same bytes but different encodings. This change might have fixed that case for you.

Sorry, something went wrong.

@chrisseaton
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was these

tagged_example "defined?(true) == 'true'", true
tagged_example "defined?(false) == 'false'", true
tagged_example "defined?(self) == 'self'", true
tagged_example "defined?(14) == 'expression'", true
tagged_example "defined?(14 + 2) == 'expression'", true
. The string literals are UTF-8 by default, but the value from defined? is always ASCII. The bytes are always the same.

Can you experiment with untagging those?

Sorry, something went wrong.

Please sign in to comment.