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