OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |