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); |
} |