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

Commits on May 24, 2016

  1. Copy the full SHA
    071b5b4 View commit details
  2. [Truffle] Fixed character length calculation.

    The length calculation needs to be for the character at the given offset and based on the max character length, not the start and end of the byte array.
    nirvdrum committed May 24, 2016
    Copy the full SHA
    4f2db25 View commit details
  3. [Truffle] Extended the single-byte optimization for String#find_chara…

    …cter to all CR_7BIT strings.
    
    When porting from Rubinius, we followed their logic directly, which only shortcuts for encodings with a max character length of 1. But we know a priori whether a rope consists of only byte-wide characters, so we can broaden the guard.
    nirvdrum committed May 24, 2016
    Copy the full SHA
    cf97225 View commit details
  4. Copy the full SHA
    d9b8814 View commit details
  5. Copy the full SHA
    dd623ed View commit details
Original file line number Diff line number Diff line change
@@ -44,8 +44,7 @@
exclude_tests.rb: |
failures = { KernelTest: [:test_silence_stream,
:test_quietly],
InflectorTest: [:test_titleize_mixture_to_title_case_13,
:test_titleize_mixture_to_title_case_14],
InflectorTest: [:test_titleize_mixture_to_title_case_14],
LoadPathsTest: [:test_uniq_load_paths],
LoggerTest: [:test_buffer_multibyte],
MultibyteCharsExtrasTest: [:test_titleize_should_be_unicode_aware,
@@ -55,8 +54,7 @@
:test_transliterate_should_work_with_custom_i18n_rules_and_uncomposed_utf8],
StringInflectionsTest: [:test_string_parameterized_no_separator,
:test_string_parameterized_normal,
:test_string_parameterized_underscore,
:test_titleize],
:test_string_parameterized_underscore],
TimeZoneTest: :test_map_srednekolymsk_to_tzinfo }
Original file line number Diff line number Diff line change
@@ -34,11 +34,6 @@ public static boolean isAsciiCompatible(DynamicObject string) {
return Layouts.STRING.getRope(string).getEncoding().isAsciiCompatible();
}

public static boolean isSingleByte(DynamicObject string) {
assert RubyGuards.isRubyString(string);
return Layouts.STRING.getRope(string).getEncoding().isSingleByte();
}

public static boolean isValidOr7BitEncoding(DynamicObject string) {
assert RubyGuards.isRubyString(string);
final Rope rope = StringOperations.rope(string);
Original file line number Diff line number Diff line change
@@ -3112,33 +3112,30 @@ public Object stringFindCharacterNegativeOffset(DynamicObject string, int offset
return nil();
}

@Specialization(guards = { "offset >= 0", "isSingleByte(string)" })
public Object stringFindCharacterSingleByte(DynamicObject string, int offset,
@Cached("createBinaryProfile()") ConditionProfile offsetTooLargeProfile) {
@Specialization(guards = "offsetTooLarge(string, offset)")
public Object stringFindCharacterOffsetTooLarge(DynamicObject string, int offset) {
return nil();
}

@Specialization(guards = { "offset >= 0", "!offsetTooLarge(string, offset)", "isSingleByteOptimizable(string)" })
public Object stringFindCharacterSingleByte(DynamicObject string, int offset) {
// Taken from Rubinius's String::find_character.

final Rope rope = rope(string);
if (offsetTooLargeProfile.profile(offset >= rope.byteLength())) {
return nil();
}

final DynamicObject ret = allocateObjectNode.allocate(Layouts.BASIC_OBJECT.getLogicalClass(string), makeSubstringNode.executeMake(rope, offset, 1), null);

return propagate(string, ret);
}

@Specialization(guards = { "offset >= 0", "!isSingleByte(string)" })
public Object stringFindCharacter(DynamicObject string, int offset,
@Cached("createBinaryProfile()") ConditionProfile offsetTooLargeProfile) {
@Specialization(guards = { "offset >= 0", "!offsetTooLarge(string, offset)", "!isSingleByteOptimizable(string)" })
public Object stringFindCharacter(DynamicObject string, int offset) {
// Taken from Rubinius's String::find_character.

final Rope rope = rope(string);
if (offsetTooLargeProfile.profile(offset >= rope.byteLength())) {
return nil();
}

final Encoding enc = rope.getEncoding();
final int clen = StringSupport.preciseLength(enc, rope.getBytes(), 0, rope.byteLength());
final int clen = StringSupport.preciseLength(enc, rope.getBytes(), offset, offset + enc.maxLength());

final DynamicObject ret;
if (StringSupport.MBCLEN_CHARFOUND_P(clen)) {
@@ -3164,6 +3161,12 @@ private Object maybeTaint(DynamicObject source, DynamicObject value) {
return taintResultNode.maybeTaint(source, value);
}

protected static boolean offsetTooLarge(DynamicObject string, int offset) {
assert RubyGuards.isRubyString(string);

return offset >= rope(string).byteLength();
}

}

@Primitive(name = "string_from_codepoint", needsSelf = false)