Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(338)

Side by Side Diff: src/runtime.cc

Issue 18552: Fix bug where strings were not flattened before regexp. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1042 matching lines...) Expand 10 before | Expand all | Expand 10 after
1053 return *target; 1053 return *target;
1054 } 1054 }
1055 1055
1056 1056
1057 static Object* CharCodeAt(String* subject, Object* index) { 1057 static Object* CharCodeAt(String* subject, Object* index) {
1058 uint32_t i = 0; 1058 uint32_t i = 0;
1059 if (!Array::IndexFromObject(index, &i)) return Heap::nan_value(); 1059 if (!Array::IndexFromObject(index, &i)) return Heap::nan_value();
1060 // Flatten the string. If someone wants to get a char at an index 1060 // Flatten the string. If someone wants to get a char at an index
1061 // in a cons string, it is likely that more indices will be 1061 // in a cons string, it is likely that more indices will be
1062 // accessed. 1062 // accessed.
1063 subject->TryFlatten(StringShape(subject)); 1063 subject->TryFlattenIfNotFlat(StringShape(subject));
1064 StringShape shape(subject); 1064 StringShape shape(subject);
1065 if (i >= static_cast<uint32_t>(subject->length(shape))) { 1065 if (i >= static_cast<uint32_t>(subject->length(shape))) {
1066 return Heap::nan_value(); 1066 return Heap::nan_value();
1067 } 1067 }
1068 return Smi::FromInt(subject->Get(shape, i)); 1068 return Smi::FromInt(subject->Get(shape, i));
1069 } 1069 }
1070 1070
1071 1071
1072 static Object* Runtime_StringCharCodeAt(Arguments args) { 1072 static Object* Runtime_StringCharCodeAt(Arguments args) {
1073 NoHandleAllocation ha; 1073 NoHandleAllocation ha;
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
1524 1524
1525 1525
1526 static Object* Runtime_StringLastIndexOf(Arguments args) { 1526 static Object* Runtime_StringLastIndexOf(Arguments args) {
1527 NoHandleAllocation ha; 1527 NoHandleAllocation ha;
1528 ASSERT(args.length() == 3); 1528 ASSERT(args.length() == 3);
1529 1529
1530 CONVERT_CHECKED(String, sub, args[0]); 1530 CONVERT_CHECKED(String, sub, args[0]);
1531 CONVERT_CHECKED(String, pat, args[1]); 1531 CONVERT_CHECKED(String, pat, args[1]);
1532 Object* index = args[2]; 1532 Object* index = args[2];
1533 1533
1534 sub->TryFlatten(StringShape(sub)); 1534 sub->TryFlattenIfNotFlat(StringShape(sub));
1535 pat->TryFlatten(StringShape(pat)); 1535 pat->TryFlattenIfNotFlat(StringShape(pat));
1536 1536
1537 StringShape sub_shape(sub); 1537 StringShape sub_shape(sub);
1538 StringShape pat_shape(pat); 1538 StringShape pat_shape(pat);
1539 1539
1540 uint32_t start_index; 1540 uint32_t start_index;
1541 if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1); 1541 if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1);
1542 1542
1543 uint32_t pattern_length = pat->length(pat_shape); 1543 uint32_t pattern_length = pat->length(pat_shape);
1544 uint32_t sub_length = sub->length(sub_shape); 1544 uint32_t sub_length = sub->length(sub_shape);
1545 1545
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1584 } 1584 }
1585 1585
1586 int end = str1_length < str2_length ? str1_length : str2_length; 1586 int end = str1_length < str2_length ? str1_length : str2_length;
1587 1587
1588 // No need to flatten if we are going to find the answer on the first 1588 // No need to flatten if we are going to find the answer on the first
1589 // character. At this point we know there is at least one character 1589 // character. At this point we know there is at least one character
1590 // in each string, due to the trivial case handling above. 1590 // in each string, due to the trivial case handling above.
1591 int d = str1->Get(shape1, 0) - str2->Get(shape2, 0); 1591 int d = str1->Get(shape1, 0) - str2->Get(shape2, 0);
1592 if (d != 0) return Smi::FromInt(d); 1592 if (d != 0) return Smi::FromInt(d);
1593 1593
1594 str1->TryFlatten(shape1); // Shapes are no longer valid now! 1594 str1->TryFlattenIfNotFlat(shape1); // Shapes are no longer valid now!
1595 str2->TryFlatten(shape2); 1595 str2->TryFlattenIfNotFlat(shape2);
1596 1596
1597 static StringInputBuffer buf1; 1597 static StringInputBuffer buf1;
1598 static StringInputBuffer buf2; 1598 static StringInputBuffer buf2;
1599 1599
1600 buf1.Reset(str1); 1600 buf1.Reset(str1);
1601 buf2.Reset(str2); 1601 buf2.Reset(str2);
1602 1602
1603 for (int i = 0; i < end; i++) { 1603 for (int i = 0; i < end; i++) {
1604 uint16_t char1 = buf1.GetNext(); 1604 uint16_t char1 = buf1.GetNext();
1605 uint16_t char2 = buf2.GetNext(); 1605 uint16_t char2 = buf2.GetNext();
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1722 DeleteArray(str); 1722 DeleteArray(str);
1723 return res; 1723 return res;
1724 } 1724 }
1725 1725
1726 1726
1727 // Returns a single character string where first character equals 1727 // Returns a single character string where first character equals
1728 // string->Get(index). 1728 // string->Get(index).
1729 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) { 1729 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
1730 StringShape shape(*string); 1730 StringShape shape(*string);
1731 if (index < static_cast<uint32_t>(string->length(shape))) { 1731 if (index < static_cast<uint32_t>(string->length(shape))) {
1732 string->TryFlatten(shape); // Invalidates shape! 1732 string->TryFlattenIfNotFlat(shape); // Invalidates shape!
1733 return LookupSingleCharacterStringFromCode( 1733 return LookupSingleCharacterStringFromCode(
1734 string->Get(StringShape(*string), index)); 1734 string->Get(StringShape(*string), index));
1735 } 1735 }
1736 return Execution::CharAt(string, index); 1736 return Execution::CharAt(string, index);
1737 } 1737 }
1738 1738
1739 1739
1740 Object* Runtime::GetElementOrCharAt(Handle<Object> object, uint32_t index) { 1740 Object* Runtime::GetElementOrCharAt(Handle<Object> object, uint32_t index) {
1741 // Handle [] indexing on Strings 1741 // Handle [] indexing on Strings
1742 if (object->IsString()) { 1742 if (object->IsString()) {
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
1915 return *value; 1915 return *value;
1916 } 1916 }
1917 1917
1918 if (key->IsString()) { 1918 if (key->IsString()) {
1919 Handle<Object> result; 1919 Handle<Object> result;
1920 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { 1920 if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
1921 ASSERT(attr == NONE); 1921 ASSERT(attr == NONE);
1922 result = SetElement(js_object, index, value); 1922 result = SetElement(js_object, index, value);
1923 } else { 1923 } else {
1924 Handle<String> key_string = Handle<String>::cast(key); 1924 Handle<String> key_string = Handle<String>::cast(key);
1925 key_string->TryFlatten(StringShape(*key_string)); 1925 key_string->TryFlattenIfNotFlat(StringShape(*key_string));
1926 result = SetProperty(js_object, key_string, value, attr); 1926 result = SetProperty(js_object, key_string, value, attr);
1927 } 1927 }
1928 if (result.is_null()) return Failure::Exception(); 1928 if (result.is_null()) return Failure::Exception();
1929 return *value; 1929 return *value;
1930 } 1930 }
1931 1931
1932 // Call-back into JavaScript to convert the key to a string. 1932 // Call-back into JavaScript to convert the key to a string.
1933 bool has_pending_exception = false; 1933 bool has_pending_exception = false;
1934 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); 1934 Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
1935 if (has_pending_exception) return Failure::Exception(); 1935 if (has_pending_exception) return Failure::Exception();
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
2187 // host objects gives that it is okay to return "object" 2187 // host objects gives that it is okay to return "object"
2188 return Heap::object_symbol(); 2188 return Heap::object_symbol();
2189 } 2189 }
2190 } 2190 }
2191 2191
2192 2192
2193 static Object* Runtime_StringToNumber(Arguments args) { 2193 static Object* Runtime_StringToNumber(Arguments args) {
2194 NoHandleAllocation ha; 2194 NoHandleAllocation ha;
2195 ASSERT(args.length() == 1); 2195 ASSERT(args.length() == 1);
2196 CONVERT_CHECKED(String, subject, args[0]); 2196 CONVERT_CHECKED(String, subject, args[0]);
2197 subject->TryFlatten(StringShape(subject)); 2197 subject->TryFlattenIfNotFlat(StringShape(subject));
2198 return Heap::NumberFromDouble(StringToDouble(subject, ALLOW_HEX)); 2198 return Heap::NumberFromDouble(StringToDouble(subject, ALLOW_HEX));
2199 } 2199 }
2200 2200
2201 2201
2202 static Object* Runtime_StringFromCharCodeArray(Arguments args) { 2202 static Object* Runtime_StringFromCharCodeArray(Arguments args) {
2203 NoHandleAllocation ha; 2203 NoHandleAllocation ha;
2204 ASSERT(args.length() == 1); 2204 ASSERT(args.length() == 1);
2205 2205
2206 CONVERT_CHECKED(JSArray, codes, args[0]); 2206 CONVERT_CHECKED(JSArray, codes, args[0]);
2207 int length = Smi::cast(codes->length())->value(); 2207 int length = Smi::cast(codes->length())->value();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2270 return kNotEscaped[character] != 0; 2270 return kNotEscaped[character] != 0;
2271 } 2271 }
2272 2272
2273 2273
2274 static Object* Runtime_URIEscape(Arguments args) { 2274 static Object* Runtime_URIEscape(Arguments args) {
2275 const char hex_chars[] = "0123456789ABCDEF"; 2275 const char hex_chars[] = "0123456789ABCDEF";
2276 NoHandleAllocation ha; 2276 NoHandleAllocation ha;
2277 ASSERT(args.length() == 1); 2277 ASSERT(args.length() == 1);
2278 CONVERT_CHECKED(String, source, args[0]); 2278 CONVERT_CHECKED(String, source, args[0]);
2279 2279
2280 source->TryFlatten(StringShape(source)); 2280 source->TryFlattenIfNotFlat(StringShape(source));
2281 2281
2282 int escaped_length = 0; 2282 int escaped_length = 0;
2283 int length = source->length(); 2283 int length = source->length();
2284 { 2284 {
2285 Access<StringInputBuffer> buffer(&string_input_buffer); 2285 Access<StringInputBuffer> buffer(&string_input_buffer);
2286 buffer->Reset(source); 2286 buffer->Reset(source);
2287 while (buffer->has_more()) { 2287 while (buffer->has_more()) {
2288 uint16_t character = buffer->GetNext(); 2288 uint16_t character = buffer->GetNext();
2289 if (character >= 256) { 2289 if (character >= 256) {
2290 escaped_length += 6; 2290 escaped_length += 6;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
2384 return character; 2384 return character;
2385 } 2385 }
2386 } 2386 }
2387 2387
2388 2388
2389 static Object* Runtime_URIUnescape(Arguments args) { 2389 static Object* Runtime_URIUnescape(Arguments args) {
2390 NoHandleAllocation ha; 2390 NoHandleAllocation ha;
2391 ASSERT(args.length() == 1); 2391 ASSERT(args.length() == 1);
2392 CONVERT_CHECKED(String, source, args[0]); 2392 CONVERT_CHECKED(String, source, args[0]);
2393 2393
2394 source->TryFlatten(StringShape(source)); 2394 source->TryFlattenIfNotFlat(StringShape(source));
2395 StringShape source_shape(source); 2395 StringShape source_shape(source);
2396 2396
2397 bool ascii = true; 2397 bool ascii = true;
2398 int length = source->length(source_shape); 2398 int length = source->length(source_shape);
2399 2399
2400 int unescaped_length = 0; 2400 int unescaped_length = 0;
2401 for (int i = 0; i < length; unescaped_length++) { 2401 for (int i = 0; i < length; unescaped_length++) {
2402 int step; 2402 int step;
2403 if (Unescape(source, 2403 if (Unescape(source,
2404 source_shape, 2404 source_shape,
(...skipping 28 matching lines...) Expand all
2433 } 2433 }
2434 2434
2435 2435
2436 static Object* Runtime_StringParseInt(Arguments args) { 2436 static Object* Runtime_StringParseInt(Arguments args) {
2437 NoHandleAllocation ha; 2437 NoHandleAllocation ha;
2438 2438
2439 CONVERT_CHECKED(String, s, args[0]); 2439 CONVERT_CHECKED(String, s, args[0]);
2440 CONVERT_DOUBLE_CHECKED(n, args[1]); 2440 CONVERT_DOUBLE_CHECKED(n, args[1]);
2441 int radix = FastD2I(n); 2441 int radix = FastD2I(n);
2442 2442
2443 s->TryFlatten(StringShape(s)); 2443 s->TryFlattenIfNotFlat(StringShape(s));
2444 2444
2445 StringShape shape(s); 2445 StringShape shape(s);
2446 2446
2447 int len = s->length(shape); 2447 int len = s->length(shape);
2448 int i; 2448 int i;
2449 2449
2450 // Skip leading white space. 2450 // Skip leading white space.
2451 for (i = 0; i < len && Scanner::kIsWhiteSpace.get(s->Get(shape, i)); i++) ; 2451 for (i = 0; i < len && Scanner::kIsWhiteSpace.get(s->Get(shape, i)); i++) ;
2452 if (i == len) return Heap::nan_value(); 2452 if (i == len) return Heap::nan_value();
2453 2453
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2506 static unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping; 2506 static unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping;
2507 static unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping; 2507 static unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping;
2508 2508
2509 2509
2510 template <class Converter> 2510 template <class Converter>
2511 static Object* ConvertCase(Arguments args, 2511 static Object* ConvertCase(Arguments args,
2512 unibrow::Mapping<Converter, 128>* mapping) { 2512 unibrow::Mapping<Converter, 128>* mapping) {
2513 NoHandleAllocation ha; 2513 NoHandleAllocation ha;
2514 2514
2515 CONVERT_CHECKED(String, s, args[0]); 2515 CONVERT_CHECKED(String, s, args[0]);
2516 s->TryFlatten(StringShape(s)); 2516 s->TryFlattenIfNotFlat(StringShape(s));
2517 StringShape shape(s); 2517 StringShape shape(s);
2518 2518
2519 int raw_string_length = s->length(shape); 2519 int raw_string_length = s->length(shape);
2520 // Assume that the string is not empty; we need this assumption later 2520 // Assume that the string is not empty; we need this assumption later
2521 if (raw_string_length == 0) return s; 2521 if (raw_string_length == 0) return s;
2522 int length = raw_string_length; 2522 int length = raw_string_length;
2523 2523
2524 2524
2525 // We try this twice, once with the assumption that the result is 2525 // We try this twice, once with the assumption that the result is
2526 // no longer than the input and, if that assumption breaks, again 2526 // no longer than the input and, if that assumption breaks, again
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after
3110 if (x->length(x_shape) == 0) return Smi::FromInt(EQUAL); 3110 if (x->length(x_shape) == 0) return Smi::FromInt(EQUAL);
3111 return Smi::FromInt(GREATER); 3111 return Smi::FromInt(GREATER);
3112 } else if (x->length(x_shape) == 0) { 3112 } else if (x->length(x_shape) == 0) {
3113 return Smi::FromInt(LESS); 3113 return Smi::FromInt(LESS);
3114 } 3114 }
3115 3115
3116 int d = x->Get(x_shape, 0) - y->Get(y_shape, 0); 3116 int d = x->Get(x_shape, 0) - y->Get(y_shape, 0);
3117 if (d < 0) return Smi::FromInt(LESS); 3117 if (d < 0) return Smi::FromInt(LESS);
3118 else if (d > 0) return Smi::FromInt(GREATER); 3118 else if (d > 0) return Smi::FromInt(GREATER);
3119 3119
3120 x->TryFlatten(x_shape); // Shapes are no longer valid! 3120 x->TryFlattenIfNotFlat(x_shape); // Shapes are no longer valid!
3121 y->TryFlatten(y_shape); 3121 y->TryFlattenIfNotFlat(y_shape);
3122 3122
3123 static StringInputBuffer bufx; 3123 static StringInputBuffer bufx;
3124 static StringInputBuffer bufy; 3124 static StringInputBuffer bufy;
3125 bufx.Reset(x); 3125 bufx.Reset(x);
3126 bufy.Reset(y); 3126 bufy.Reset(y);
3127 while (bufx.has_more() && bufy.has_more()) { 3127 while (bufx.has_more() && bufy.has_more()) {
3128 int d = bufx.GetNext() - bufy.GetNext(); 3128 int d = bufx.GetNext() - bufy.GetNext();
3129 if (d < 0) return Smi::FromInt(LESS); 3129 if (d < 0) return Smi::FromInt(LESS);
3130 else if (d > 0) return Smi::FromInt(GREATER); 3130 else if (d > 0) return Smi::FromInt(GREATER);
3131 } 3131 }
(...skipping 2956 matching lines...) Expand 10 before | Expand all | Expand 10 after
6088 } else { 6088 } else {
6089 // Handle last resort GC and make sure to allow future allocations 6089 // Handle last resort GC and make sure to allow future allocations
6090 // to grow the heap without causing GCs (if possible). 6090 // to grow the heap without causing GCs (if possible).
6091 Counters::gc_last_resort_from_js.Increment(); 6091 Counters::gc_last_resort_from_js.Increment();
6092 Heap::CollectAllGarbage(); 6092 Heap::CollectAllGarbage();
6093 } 6093 }
6094 } 6094 }
6095 6095
6096 6096
6097 } } // namespace v8::internal 6097 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698