| 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 953 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 964 return *target; | 964 return *target; |
| 965 } | 965 } |
| 966 | 966 |
| 967 | 967 |
| 968 static Object* CharCodeAt(String* subject, Object* index) { | 968 static Object* CharCodeAt(String* subject, Object* index) { |
| 969 uint32_t i = 0; | 969 uint32_t i = 0; |
| 970 if (!Array::IndexFromObject(index, &i)) return Heap::nan_value(); | 970 if (!Array::IndexFromObject(index, &i)) return Heap::nan_value(); |
| 971 // Flatten the string. If someone wants to get a char at an index | 971 // Flatten the string. If someone wants to get a char at an index |
| 972 // in a cons string, it is likely that more indices will be | 972 // in a cons string, it is likely that more indices will be |
| 973 // accessed. | 973 // accessed. |
| 974 subject->TryFlatten(StringShape(subject)); |
| 974 StringShape shape(subject); | 975 StringShape shape(subject); |
| 975 subject->TryFlatten(shape); // shape no longer valid! | 976 if (i >= static_cast<uint32_t>(subject->length(shape))) { |
| 976 if (i >= static_cast<uint32_t>(subject->length(StringShape(subject)))) { | |
| 977 return Heap::nan_value(); | 977 return Heap::nan_value(); |
| 978 } | 978 } |
| 979 return Smi::FromInt(subject->Get(StringShape(subject), i)); | 979 return Smi::FromInt(subject->Get(shape, i)); |
| 980 } | 980 } |
| 981 | 981 |
| 982 | 982 |
| 983 static Object* Runtime_StringCharCodeAt(Arguments args) { | 983 static Object* Runtime_StringCharCodeAt(Arguments args) { |
| 984 NoHandleAllocation ha; | 984 NoHandleAllocation ha; |
| 985 ASSERT(args.length() == 2); | 985 ASSERT(args.length() == 2); |
| 986 | 986 |
| 987 CONVERT_CHECKED(String, subject, args[0]); | 987 CONVERT_CHECKED(String, subject, args[0]); |
| 988 Object* index = args[1]; | 988 Object* index = args[1]; |
| 989 return CharCodeAt(subject, index); | 989 return CharCodeAt(subject, index); |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1350 } | 1350 } |
| 1351 | 1351 |
| 1352 // Perform string match of pattern on subject, starting at start index. | 1352 // Perform string match of pattern on subject, starting at start index. |
| 1353 // Caller must ensure that 0 <= start_index <= sub->length(), | 1353 // Caller must ensure that 0 <= start_index <= sub->length(), |
| 1354 // and should check that pat->length() + start_index <= sub->length() | 1354 // and should check that pat->length() + start_index <= sub->length() |
| 1355 int Runtime::StringMatch(Handle<String> sub, | 1355 int Runtime::StringMatch(Handle<String> sub, |
| 1356 Handle<String> pat, | 1356 Handle<String> pat, |
| 1357 int start_index) { | 1357 int start_index) { |
| 1358 ASSERT(0 <= start_index); | 1358 ASSERT(0 <= start_index); |
| 1359 StringShape sub_shape(*sub); | 1359 StringShape sub_shape(*sub); |
| 1360 StringShape pat_shape(*pat); | |
| 1361 ASSERT(start_index <= sub->length(sub_shape)); | 1360 ASSERT(start_index <= sub->length(sub_shape)); |
| 1362 | 1361 |
| 1363 int pattern_length = pat->length(pat_shape); | 1362 int pattern_length = pat->length(); |
| 1364 if (pattern_length == 0) return start_index; | 1363 if (pattern_length == 0) return start_index; |
| 1365 | 1364 |
| 1366 int subject_length = sub->length(sub_shape); | 1365 int subject_length = sub->length(sub_shape); |
| 1367 if (start_index + pattern_length > subject_length) return -1; | 1366 if (start_index + pattern_length > subject_length) return -1; |
| 1368 | 1367 |
| 1369 if (!sub->IsFlat(sub_shape)) { | 1368 if (!sub->IsFlat(sub_shape)) { |
| 1370 FlattenString(sub); | 1369 FlattenString(sub); |
| 1371 sub_shape = StringShape(*sub); | 1370 sub_shape = StringShape(*sub); |
| 1372 } | 1371 } |
| 1372 StringShape pat_shape(*pat); |
| 1373 // Searching for one specific character is common. For one | 1373 // Searching for one specific character is common. For one |
| 1374 // character patterns linear search is necessary, so any smart | 1374 // character patterns linear search is necessary, so any smart |
| 1375 // algorithm is unnecessary overhead. | 1375 // algorithm is unnecessary overhead. |
| 1376 if (pattern_length == 1) { | 1376 if (pattern_length == 1) { |
| 1377 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid | 1377 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid |
| 1378 if (sub_shape.IsAsciiRepresentation()) { | 1378 if (sub_shape.IsAsciiRepresentation()) { |
| 1379 return SingleCharIndexOf(sub->ToAsciiVector(), | 1379 return SingleCharIndexOf(sub->ToAsciiVector(), |
| 1380 pat->Get(pat_shape, 0), | 1380 pat->Get(pat_shape, 0), |
| 1381 start_index); | 1381 start_index); |
| 1382 } | 1382 } |
| 1383 return SingleCharIndexOf(sub->ToUC16Vector(), | 1383 return SingleCharIndexOf(sub->ToUC16Vector(), |
| 1384 pat->Get(pat_shape, 0), | 1384 pat->Get(pat_shape, 0), |
| 1385 start_index); | 1385 start_index); |
| 1386 } | 1386 } |
| 1387 | 1387 |
| 1388 if (!pat->IsFlat(pat_shape)) { | 1388 if (!pat->IsFlat(pat_shape)) { |
| 1389 FlattenString(pat); | 1389 FlattenString(pat); |
| 1390 pat_shape = StringShape(*pat); | 1390 pat_shape = StringShape(*pat); |
| 1391 sub_shape = StringShape(*sub); |
| 1391 } | 1392 } |
| 1392 | 1393 |
| 1393 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid | 1394 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid |
| 1394 // dispatch on type of strings | 1395 // dispatch on type of strings |
| 1395 if (pat_shape.IsAsciiRepresentation()) { | 1396 if (pat_shape.IsAsciiRepresentation()) { |
| 1396 Vector<const char> pat_vector = pat->ToAsciiVector(); | 1397 Vector<const char> pat_vector = pat->ToAsciiVector(); |
| 1397 if (sub_shape.IsAsciiRepresentation()) { | 1398 if (sub_shape.IsAsciiRepresentation()) { |
| 1398 return StringMatchStrategy(sub->ToAsciiVector(), pat_vector, start_index); | 1399 return StringMatchStrategy(sub->ToAsciiVector(), pat_vector, start_index); |
| 1399 } | 1400 } |
| 1400 return StringMatchStrategy(sub->ToUC16Vector(), pat_vector, start_index); | 1401 return StringMatchStrategy(sub->ToUC16Vector(), pat_vector, start_index); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1515 NoHandleAllocation ha; | 1516 NoHandleAllocation ha; |
| 1516 ASSERT(args.length() == 3); | 1517 ASSERT(args.length() == 3); |
| 1517 | 1518 |
| 1518 CONVERT_CHECKED(String, value, args[0]); | 1519 CONVERT_CHECKED(String, value, args[0]); |
| 1519 CONVERT_DOUBLE_CHECKED(from_number, args[1]); | 1520 CONVERT_DOUBLE_CHECKED(from_number, args[1]); |
| 1520 CONVERT_DOUBLE_CHECKED(to_number, args[2]); | 1521 CONVERT_DOUBLE_CHECKED(to_number, args[2]); |
| 1521 | 1522 |
| 1522 int start = FastD2I(from_number); | 1523 int start = FastD2I(from_number); |
| 1523 int end = FastD2I(to_number); | 1524 int end = FastD2I(to_number); |
| 1524 | 1525 |
| 1525 StringShape shape(value); | |
| 1526 | |
| 1527 RUNTIME_ASSERT(end >= start); | 1526 RUNTIME_ASSERT(end >= start); |
| 1528 RUNTIME_ASSERT(start >= 0); | 1527 RUNTIME_ASSERT(start >= 0); |
| 1529 RUNTIME_ASSERT(end <= value->length(shape)); | 1528 RUNTIME_ASSERT(end <= value->length()); |
| 1530 return value->Slice(shape, start, end); | 1529 return value->Slice(start, end); |
| 1531 } | 1530 } |
| 1532 | 1531 |
| 1533 | 1532 |
| 1534 static Object* Runtime_NumberToRadixString(Arguments args) { | 1533 static Object* Runtime_NumberToRadixString(Arguments args) { |
| 1535 NoHandleAllocation ha; | 1534 NoHandleAllocation ha; |
| 1536 ASSERT(args.length() == 2); | 1535 ASSERT(args.length() == 2); |
| 1537 | 1536 |
| 1538 CONVERT_DOUBLE_CHECKED(value, args[0]); | 1537 CONVERT_DOUBLE_CHECKED(value, args[0]); |
| 1539 if (isnan(value)) { | 1538 if (isnan(value)) { |
| 1540 return Heap::AllocateStringFromAscii(CStrVector("NaN")); | 1539 return Heap::AllocateStringFromAscii(CStrVector("NaN")); |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1903 | 1902 |
| 1904 // Only JS objects can have properties. | 1903 // Only JS objects can have properties. |
| 1905 if (args[0]->IsJSObject()) { | 1904 if (args[0]->IsJSObject()) { |
| 1906 JSObject* object = JSObject::cast(args[0]); | 1905 JSObject* object = JSObject::cast(args[0]); |
| 1907 if (object->HasLocalProperty(key)) return Heap::true_value(); | 1906 if (object->HasLocalProperty(key)) return Heap::true_value(); |
| 1908 } else if (args[0]->IsString()) { | 1907 } else if (args[0]->IsString()) { |
| 1909 // Well, there is one exception: Handle [] on strings. | 1908 // Well, there is one exception: Handle [] on strings. |
| 1910 uint32_t index; | 1909 uint32_t index; |
| 1911 if (key->AsArrayIndex(&index)) { | 1910 if (key->AsArrayIndex(&index)) { |
| 1912 String* string = String::cast(args[0]); | 1911 String* string = String::cast(args[0]); |
| 1913 StringShape shape(string); | 1912 if (index < static_cast<uint32_t>(string->length())) |
| 1914 if (index < static_cast<uint32_t>(string->length(shape))) | |
| 1915 return Heap::true_value(); | 1913 return Heap::true_value(); |
| 1916 } | 1914 } |
| 1917 } | 1915 } |
| 1918 return Heap::false_value(); | 1916 return Heap::false_value(); |
| 1919 } | 1917 } |
| 1920 | 1918 |
| 1921 | 1919 |
| 1922 static Object* Runtime_HasProperty(Arguments args) { | 1920 static Object* Runtime_HasProperty(Arguments args) { |
| 1923 NoHandleAllocation na; | 1921 NoHandleAllocation na; |
| 1924 ASSERT(args.length() == 2); | 1922 ASSERT(args.length() == 2); |
| (...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2677 return Heap::NewNumberFromDouble(x); | 2675 return Heap::NewNumberFromDouble(x); |
| 2678 } | 2676 } |
| 2679 | 2677 |
| 2680 | 2678 |
| 2681 static Object* Runtime_StringAdd(Arguments args) { | 2679 static Object* Runtime_StringAdd(Arguments args) { |
| 2682 NoHandleAllocation ha; | 2680 NoHandleAllocation ha; |
| 2683 ASSERT(args.length() == 2); | 2681 ASSERT(args.length() == 2); |
| 2684 | 2682 |
| 2685 CONVERT_CHECKED(String, str1, args[0]); | 2683 CONVERT_CHECKED(String, str1, args[0]); |
| 2686 CONVERT_CHECKED(String, str2, args[1]); | 2684 CONVERT_CHECKED(String, str2, args[1]); |
| 2687 StringShape shape1(str1); | 2685 int len1 = str1->length(); |
| 2688 StringShape shape2(str2); | 2686 int len2 = str2->length(); |
| 2689 int len1 = str1->length(shape1); | |
| 2690 int len2 = str2->length(shape2); | |
| 2691 if (len1 == 0) return str2; | 2687 if (len1 == 0) return str2; |
| 2692 if (len2 == 0) return str1; | 2688 if (len2 == 0) return str1; |
| 2693 int length_sum = len1 + len2; | 2689 int length_sum = len1 + len2; |
| 2694 // Make sure that an out of memory exception is thrown if the length | 2690 // Make sure that an out of memory exception is thrown if the length |
| 2695 // of the new cons string is too large to fit in a Smi. | 2691 // of the new cons string is too large to fit in a Smi. |
| 2696 if (length_sum > Smi::kMaxValue || length_sum < 0) { | 2692 if (length_sum > Smi::kMaxValue || length_sum < 0) { |
| 2697 Top::context()->mark_out_of_memory(); | 2693 Top::context()->mark_out_of_memory(); |
| 2698 return Failure::OutOfMemoryException(); | 2694 return Failure::OutOfMemoryException(); |
| 2699 } | 2695 } |
| 2700 return Heap::AllocateConsString(str1, shape1, str2, shape2); | 2696 return Heap::AllocateConsString(str1, str2); |
| 2701 } | 2697 } |
| 2702 | 2698 |
| 2703 | 2699 |
| 2704 template<typename sinkchar> | 2700 template<typename sinkchar> |
| 2705 static inline void StringBuilderConcatHelper(String* special, | 2701 static inline void StringBuilderConcatHelper(String* special, |
| 2706 StringShape special_shape, | 2702 StringShape special_shape, |
| 2707 sinkchar* sink, | 2703 sinkchar* sink, |
| 2708 FixedArray* fixed_array, | 2704 FixedArray* fixed_array, |
| 2709 int array_length) { | 2705 int array_length) { |
| 2710 int position = 0; | 2706 int position = 0; |
| (...skipping 3165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5876 } else { | 5872 } else { |
| 5877 // Handle last resort GC and make sure to allow future allocations | 5873 // Handle last resort GC and make sure to allow future allocations |
| 5878 // to grow the heap without causing GCs (if possible). | 5874 // to grow the heap without causing GCs (if possible). |
| 5879 Counters::gc_last_resort_from_js.Increment(); | 5875 Counters::gc_last_resort_from_js.Increment(); |
| 5880 Heap::CollectAllGarbage(); | 5876 Heap::CollectAllGarbage(); |
| 5881 } | 5877 } |
| 5882 } | 5878 } |
| 5883 | 5879 |
| 5884 | 5880 |
| 5885 } } // namespace v8::internal | 5881 } } // namespace v8::internal |
| OLD | NEW |