Chromium Code Reviews| Index: src/runtime.cc |
| diff --git a/src/runtime.cc b/src/runtime.cc |
| index 6459aa78d12711dce02b0506b10d957214986eaf..878e474555f88ee822e73d0ab06239788cce4c94 100644 |
| --- a/src/runtime.cc |
| +++ b/src/runtime.cc |
| @@ -4593,6 +4593,24 @@ static Object* Runtime_SmiLexicographicCompare(Arguments args) { |
| } |
| +static Object* StringInputBufferCompare(String* x, String* y) { |
| + static StringInputBuffer bufx; |
| + static StringInputBuffer bufy; |
| + bufx.Reset(x); |
| + bufy.Reset(y); |
| + while (bufx.has_more() && bufy.has_more()) { |
| + int d = bufx.GetNext() - bufy.GetNext(); |
| + if (d < 0) return Smi::FromInt(LESS); |
| + else if (d > 0) return Smi::FromInt(GREATER); |
| + } |
| + |
| + // x is (non-trivial) prefix of y: |
| + if (bufy.has_more()) return Smi::FromInt(LESS); |
| + // y is prefix of x: |
| + return Smi::FromInt(bufx.has_more() ? GREATER : EQUAL); |
| +} |
| + |
| + |
| static Object* Runtime_StringCompare(Arguments args) { |
| NoHandleAllocation ha; |
| ASSERT(args.length() == 2); |
| @@ -4618,20 +4636,46 @@ static Object* Runtime_StringCompare(Arguments args) { |
| x->TryFlattenIfNotFlat(); |
| y->TryFlattenIfNotFlat(); |
| - static StringInputBuffer bufx; |
| - static StringInputBuffer bufy; |
| - bufx.Reset(x); |
| - bufy.Reset(y); |
| - while (bufx.has_more() && bufy.has_more()) { |
| - int d = bufx.GetNext() - bufy.GetNext(); |
| - if (d < 0) return Smi::FromInt(LESS); |
| - else if (d > 0) return Smi::FromInt(GREATER); |
| + if (x->IsFlat() && y->IsFlat()) { |
|
Søren Thygesen Gjesse
2010/02/22 10:14:00
How about moving the body of this if into a functi
Vitaly Repeshko
2010/02/25 12:50:10
Done.
|
| + Object* equal_prefix_result = Smi::FromInt(EQUAL); |
| + int prefix_length = x->length(); |
| + if (y->length() < prefix_length) { |
| + prefix_length = y->length(); |
| + equal_prefix_result = Smi::FromInt(GREATER); |
| + } else if (y->length() > prefix_length) { |
| + equal_prefix_result = Smi::FromInt(LESS); |
| + } |
| + int r; |
| + if (x->IsAsciiRepresentation()) { |
| + Vector<const char> x_chars = x->ToAsciiVector(); |
| + if (y->IsAsciiRepresentation()) { |
| + Vector<const char> y_chars = y->ToAsciiVector(); |
| + r = memcmp(x_chars.start(), y_chars.start(), prefix_length); |
| + } else { |
| + Vector<const uc16> y_chars = y->ToUC16Vector(); |
| + r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); |
| + } |
| + } else { |
| + Vector<const uc16> x_chars = x->ToUC16Vector(); |
| + if (y->IsAsciiRepresentation()) { |
| + Vector<const char> y_chars = y->ToAsciiVector(); |
| + r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); |
| + } else { |
| + Vector<const uc16> y_chars = y->ToUC16Vector(); |
| + r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); |
|
Søren Thygesen Gjesse
2010/02/22 10:14:00
There is a wmemcmp in wchar.h - don't know if it m
Vitaly Repeshko
2010/02/25 12:50:10
I'm worried about variations in wchar_t definition
|
| + } |
| + } |
| + Object* result; |
| + if (r == 0) { |
| + result = equal_prefix_result; |
| + } else { |
| + result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); |
| + } |
| + ASSERT(result == StringInputBufferCompare(x, y)); |
| + return result; |
| } |
| - // x is (non-trivial) prefix of y: |
| - if (bufy.has_more()) return Smi::FromInt(LESS); |
| - // y is prefix of x: |
| - return Smi::FromInt(bufx.has_more() ? GREATER : EQUAL); |
| + return StringInputBufferCompare(x, y); |
| } |