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 |