| 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 |