| 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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 | 289 |
| 290 static Object* Runtime_RegExpCompile(Arguments args) { | 290 static Object* Runtime_RegExpCompile(Arguments args) { |
| 291 HandleScope scope; // create a new handle scope | 291 HandleScope scope; // create a new handle scope |
| 292 ASSERT(args.length() == 3); | 292 ASSERT(args.length() == 3); |
| 293 CONVERT_CHECKED(JSRegExp, raw_re, args[0]); | 293 CONVERT_CHECKED(JSRegExp, raw_re, args[0]); |
| 294 Handle<JSRegExp> re(raw_re); | 294 Handle<JSRegExp> re(raw_re); |
| 295 CONVERT_CHECKED(String, raw_pattern, args[1]); | 295 CONVERT_CHECKED(String, raw_pattern, args[1]); |
| 296 Handle<String> pattern(raw_pattern); | 296 Handle<String> pattern(raw_pattern); |
| 297 CONVERT_CHECKED(String, raw_flags, args[2]); | 297 CONVERT_CHECKED(String, raw_flags, args[2]); |
| 298 Handle<String> flags(raw_flags); | 298 Handle<String> flags(raw_flags); |
| 299 return *RegExpImpl::Compile(re, pattern, flags); | 299 Handle<Object> result = RegExpImpl::Compile(re, pattern, flags); |
| 300 if (result.is_null()) return Failure::Exception(); |
| 301 return *result; |
| 300 } | 302 } |
| 301 | 303 |
| 302 | 304 |
| 303 static Object* Runtime_CreateApiFunction(Arguments args) { | 305 static Object* Runtime_CreateApiFunction(Arguments args) { |
| 304 HandleScope scope; | 306 HandleScope scope; |
| 305 ASSERT(args.length() == 1); | 307 ASSERT(args.length() == 1); |
| 306 CONVERT_CHECKED(FunctionTemplateInfo, raw_data, args[0]); | 308 CONVERT_CHECKED(FunctionTemplateInfo, raw_data, args[0]); |
| 307 Handle<FunctionTemplateInfo> data(raw_data); | 309 Handle<FunctionTemplateInfo> data(raw_data); |
| 308 return *Factory::CreateApiFunction(data); | 310 return *Factory::CreateApiFunction(data); |
| 309 } | 311 } |
| (...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 return *target; | 964 return *target; |
| 963 } | 965 } |
| 964 | 966 |
| 965 | 967 |
| 966 static Object* CharCodeAt(String* subject, Object* index) { | 968 static Object* CharCodeAt(String* subject, Object* index) { |
| 967 uint32_t i = 0; | 969 uint32_t i = 0; |
| 968 if (!Array::IndexFromObject(index, &i)) return Heap::nan_value(); | 970 if (!Array::IndexFromObject(index, &i)) return Heap::nan_value(); |
| 969 // 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 |
| 970 // 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 |
| 971 // accessed. | 973 // accessed. |
| 974 subject->TryFlatten(StringShape(subject)); |
| 972 StringShape shape(subject); | 975 StringShape shape(subject); |
| 973 subject->TryFlatten(shape); // shape no longer valid! | 976 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(); | 977 return Heap::nan_value(); |
| 976 } | 978 } |
| 977 return Smi::FromInt(subject->Get(StringShape(subject), i)); | 979 return Smi::FromInt(subject->Get(shape, i)); |
| 978 } | 980 } |
| 979 | 981 |
| 980 | 982 |
| 981 static Object* Runtime_StringCharCodeAt(Arguments args) { | 983 static Object* Runtime_StringCharCodeAt(Arguments args) { |
| 982 NoHandleAllocation ha; | 984 NoHandleAllocation ha; |
| 983 ASSERT(args.length() == 2); | 985 ASSERT(args.length() == 2); |
| 984 | 986 |
| 985 CONVERT_CHECKED(String, subject, args[0]); | 987 CONVERT_CHECKED(String, subject, args[0]); |
| 986 Object* index = args[1]; | 988 Object* index = args[1]; |
| 987 return CharCodeAt(subject, index); | 989 return CharCodeAt(subject, index); |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1348 } | 1350 } |
| 1349 | 1351 |
| 1350 // Perform string match of pattern on subject, starting at start index. | 1352 // Perform string match of pattern on subject, starting at start index. |
| 1351 // Caller must ensure that 0 <= start_index <= sub->length(), | 1353 // Caller must ensure that 0 <= start_index <= sub->length(), |
| 1352 // and should check that pat->length() + start_index <= sub->length() | 1354 // and should check that pat->length() + start_index <= sub->length() |
| 1353 int Runtime::StringMatch(Handle<String> sub, | 1355 int Runtime::StringMatch(Handle<String> sub, |
| 1354 Handle<String> pat, | 1356 Handle<String> pat, |
| 1355 int start_index) { | 1357 int start_index) { |
| 1356 ASSERT(0 <= start_index); | 1358 ASSERT(0 <= start_index); |
| 1357 StringShape sub_shape(*sub); | 1359 StringShape sub_shape(*sub); |
| 1358 StringShape pat_shape(*pat); | |
| 1359 ASSERT(start_index <= sub->length(sub_shape)); | 1360 ASSERT(start_index <= sub->length(sub_shape)); |
| 1360 | 1361 |
| 1361 int pattern_length = pat->length(pat_shape); | 1362 int pattern_length = pat->length(); |
| 1362 if (pattern_length == 0) return start_index; | 1363 if (pattern_length == 0) return start_index; |
| 1363 | 1364 |
| 1364 int subject_length = sub->length(sub_shape); | 1365 int subject_length = sub->length(sub_shape); |
| 1365 if (start_index + pattern_length > subject_length) return -1; | 1366 if (start_index + pattern_length > subject_length) return -1; |
| 1366 | 1367 |
| 1367 if (!sub->IsFlat(sub_shape)) { | 1368 if (!sub->IsFlat(sub_shape)) { |
| 1368 FlattenString(sub); | 1369 FlattenString(sub); |
| 1369 sub_shape = StringShape(*sub); | 1370 sub_shape = StringShape(*sub); |
| 1370 } | 1371 } |
| 1372 StringShape pat_shape(*pat); |
| 1371 // Searching for one specific character is common. For one | 1373 // Searching for one specific character is common. For one |
| 1372 // character patterns linear search is necessary, so any smart | 1374 // character patterns linear search is necessary, so any smart |
| 1373 // algorithm is unnecessary overhead. | 1375 // algorithm is unnecessary overhead. |
| 1374 if (pattern_length == 1) { | 1376 if (pattern_length == 1) { |
| 1375 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid | 1377 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid |
| 1376 if (sub_shape.IsAsciiRepresentation()) { | 1378 if (sub_shape.IsAsciiRepresentation()) { |
| 1377 return SingleCharIndexOf(sub->ToAsciiVector(), | 1379 return SingleCharIndexOf(sub->ToAsciiVector(), |
| 1378 pat->Get(pat_shape, 0), | 1380 pat->Get(pat_shape, 0), |
| 1379 start_index); | 1381 start_index); |
| 1380 } | 1382 } |
| 1381 return SingleCharIndexOf(sub->ToUC16Vector(), | 1383 return SingleCharIndexOf(sub->ToUC16Vector(), |
| 1382 pat->Get(pat_shape, 0), | 1384 pat->Get(pat_shape, 0), |
| 1383 start_index); | 1385 start_index); |
| 1384 } | 1386 } |
| 1385 | 1387 |
| 1386 if (!pat->IsFlat(pat_shape)) { | 1388 if (!pat->IsFlat(pat_shape)) { |
| 1387 FlattenString(pat); | 1389 FlattenString(pat); |
| 1388 pat_shape = StringShape(*pat); | 1390 pat_shape = StringShape(*pat); |
| 1391 sub_shape = StringShape(*sub); |
| 1389 } | 1392 } |
| 1390 | 1393 |
| 1391 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid | 1394 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid |
| 1392 // dispatch on type of strings | 1395 // dispatch on type of strings |
| 1393 if (pat_shape.IsAsciiRepresentation()) { | 1396 if (pat_shape.IsAsciiRepresentation()) { |
| 1394 Vector<const char> pat_vector = pat->ToAsciiVector(); | 1397 Vector<const char> pat_vector = pat->ToAsciiVector(); |
| 1395 if (sub_shape.IsAsciiRepresentation()) { | 1398 if (sub_shape.IsAsciiRepresentation()) { |
| 1396 return StringMatchStrategy(sub->ToAsciiVector(), pat_vector, start_index); | 1399 return StringMatchStrategy(sub->ToAsciiVector(), pat_vector, start_index); |
| 1397 } | 1400 } |
| 1398 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... |
| 1513 NoHandleAllocation ha; | 1516 NoHandleAllocation ha; |
| 1514 ASSERT(args.length() == 3); | 1517 ASSERT(args.length() == 3); |
| 1515 | 1518 |
| 1516 CONVERT_CHECKED(String, value, args[0]); | 1519 CONVERT_CHECKED(String, value, args[0]); |
| 1517 CONVERT_DOUBLE_CHECKED(from_number, args[1]); | 1520 CONVERT_DOUBLE_CHECKED(from_number, args[1]); |
| 1518 CONVERT_DOUBLE_CHECKED(to_number, args[2]); | 1521 CONVERT_DOUBLE_CHECKED(to_number, args[2]); |
| 1519 | 1522 |
| 1520 int start = FastD2I(from_number); | 1523 int start = FastD2I(from_number); |
| 1521 int end = FastD2I(to_number); | 1524 int end = FastD2I(to_number); |
| 1522 | 1525 |
| 1523 StringShape shape(value); | |
| 1524 | |
| 1525 RUNTIME_ASSERT(end >= start); | 1526 RUNTIME_ASSERT(end >= start); |
| 1526 RUNTIME_ASSERT(start >= 0); | 1527 RUNTIME_ASSERT(start >= 0); |
| 1527 RUNTIME_ASSERT(end <= value->length(shape)); | 1528 RUNTIME_ASSERT(end <= value->length()); |
| 1528 return value->Slice(shape, start, end); | 1529 return value->Slice(start, end); |
| 1529 } | 1530 } |
| 1530 | 1531 |
| 1531 | 1532 |
| 1532 static Object* Runtime_NumberToRadixString(Arguments args) { | 1533 static Object* Runtime_NumberToRadixString(Arguments args) { |
| 1533 NoHandleAllocation ha; | 1534 NoHandleAllocation ha; |
| 1534 ASSERT(args.length() == 2); | 1535 ASSERT(args.length() == 2); |
| 1535 | 1536 |
| 1536 CONVERT_DOUBLE_CHECKED(value, args[0]); | 1537 CONVERT_DOUBLE_CHECKED(value, args[0]); |
| 1537 if (isnan(value)) { | 1538 if (isnan(value)) { |
| 1538 return Heap::AllocateStringFromAscii(CStrVector("NaN")); | 1539 return Heap::AllocateStringFromAscii(CStrVector("NaN")); |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1901 | 1902 |
| 1902 // Only JS objects can have properties. | 1903 // Only JS objects can have properties. |
| 1903 if (args[0]->IsJSObject()) { | 1904 if (args[0]->IsJSObject()) { |
| 1904 JSObject* object = JSObject::cast(args[0]); | 1905 JSObject* object = JSObject::cast(args[0]); |
| 1905 if (object->HasLocalProperty(key)) return Heap::true_value(); | 1906 if (object->HasLocalProperty(key)) return Heap::true_value(); |
| 1906 } else if (args[0]->IsString()) { | 1907 } else if (args[0]->IsString()) { |
| 1907 // Well, there is one exception: Handle [] on strings. | 1908 // Well, there is one exception: Handle [] on strings. |
| 1908 uint32_t index; | 1909 uint32_t index; |
| 1909 if (key->AsArrayIndex(&index)) { | 1910 if (key->AsArrayIndex(&index)) { |
| 1910 String* string = String::cast(args[0]); | 1911 String* string = String::cast(args[0]); |
| 1911 StringShape shape(string); | 1912 if (index < static_cast<uint32_t>(string->length())) |
| 1912 if (index < static_cast<uint32_t>(string->length(shape))) | |
| 1913 return Heap::true_value(); | 1913 return Heap::true_value(); |
| 1914 } | 1914 } |
| 1915 } | 1915 } |
| 1916 return Heap::false_value(); | 1916 return Heap::false_value(); |
| 1917 } | 1917 } |
| 1918 | 1918 |
| 1919 | 1919 |
| 1920 static Object* Runtime_HasProperty(Arguments args) { | 1920 static Object* Runtime_HasProperty(Arguments args) { |
| 1921 NoHandleAllocation na; | 1921 NoHandleAllocation na; |
| 1922 ASSERT(args.length() == 2); | 1922 ASSERT(args.length() == 2); |
| (...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2675 return Heap::NewNumberFromDouble(x); | 2675 return Heap::NewNumberFromDouble(x); |
| 2676 } | 2676 } |
| 2677 | 2677 |
| 2678 | 2678 |
| 2679 static Object* Runtime_StringAdd(Arguments args) { | 2679 static Object* Runtime_StringAdd(Arguments args) { |
| 2680 NoHandleAllocation ha; | 2680 NoHandleAllocation ha; |
| 2681 ASSERT(args.length() == 2); | 2681 ASSERT(args.length() == 2); |
| 2682 | 2682 |
| 2683 CONVERT_CHECKED(String, str1, args[0]); | 2683 CONVERT_CHECKED(String, str1, args[0]); |
| 2684 CONVERT_CHECKED(String, str2, args[1]); | 2684 CONVERT_CHECKED(String, str2, args[1]); |
| 2685 StringShape shape1(str1); | 2685 int len1 = str1->length(); |
| 2686 StringShape shape2(str2); | 2686 int len2 = str2->length(); |
| 2687 int len1 = str1->length(shape1); | |
| 2688 int len2 = str2->length(shape2); | |
| 2689 if (len1 == 0) return str2; | 2687 if (len1 == 0) return str2; |
| 2690 if (len2 == 0) return str1; | 2688 if (len2 == 0) return str1; |
| 2691 int length_sum = len1 + len2; | 2689 int length_sum = len1 + len2; |
| 2692 // 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 |
| 2693 // 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. |
| 2694 if (length_sum > Smi::kMaxValue || length_sum < 0) { | 2692 if (length_sum > Smi::kMaxValue || length_sum < 0) { |
| 2695 Top::context()->mark_out_of_memory(); | 2693 Top::context()->mark_out_of_memory(); |
| 2696 return Failure::OutOfMemoryException(); | 2694 return Failure::OutOfMemoryException(); |
| 2697 } | 2695 } |
| 2698 return Heap::AllocateConsString(str1, shape1, str2, shape2); | 2696 return Heap::AllocateConsString(str1, str2); |
| 2699 } | 2697 } |
| 2700 | 2698 |
| 2701 | 2699 |
| 2702 template<typename sinkchar> | 2700 template<typename sinkchar> |
| 2703 static inline void StringBuilderConcatHelper(String* special, | 2701 static inline void StringBuilderConcatHelper(String* special, |
| 2704 StringShape special_shape, | 2702 StringShape special_shape, |
| 2705 sinkchar* sink, | 2703 sinkchar* sink, |
| 2706 FixedArray* fixed_array, | 2704 FixedArray* fixed_array, |
| 2707 int array_length) { | 2705 int array_length) { |
| 2708 int position = 0; | 2706 int position = 0; |
| (...skipping 2680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5389 if (boilerplate.is_null()) return Failure::Exception(); | 5387 if (boilerplate.is_null()) return Failure::Exception(); |
| 5390 Handle<JSFunction> compiled_function = | 5388 Handle<JSFunction> compiled_function = |
| 5391 Factory::NewFunctionFromBoilerplate(boilerplate, context); | 5389 Factory::NewFunctionFromBoilerplate(boilerplate, context); |
| 5392 | 5390 |
| 5393 // Invoke the result of the compilation to get the evaluation function. | 5391 // Invoke the result of the compilation to get the evaluation function. |
| 5394 bool has_pending_exception; | 5392 bool has_pending_exception; |
| 5395 Handle<Object> receiver(frame->receiver()); | 5393 Handle<Object> receiver(frame->receiver()); |
| 5396 Handle<Object> evaluation_function = | 5394 Handle<Object> evaluation_function = |
| 5397 Execution::Call(compiled_function, receiver, 0, NULL, | 5395 Execution::Call(compiled_function, receiver, 0, NULL, |
| 5398 &has_pending_exception); | 5396 &has_pending_exception); |
| 5397 if (has_pending_exception) return Failure::Exception(); |
| 5399 | 5398 |
| 5400 Handle<Object> arguments = GetArgumentsObject(frame, function, code, &sinfo, | 5399 Handle<Object> arguments = GetArgumentsObject(frame, function, code, &sinfo, |
| 5401 function_context); | 5400 function_context); |
| 5402 | 5401 |
| 5403 // Invoke the evaluation function and return the result. | 5402 // Invoke the evaluation function and return the result. |
| 5404 const int argc = 2; | 5403 const int argc = 2; |
| 5405 Object** argv[argc] = { arguments.location(), | 5404 Object** argv[argc] = { arguments.location(), |
| 5406 Handle<Object>::cast(source).location() }; | 5405 Handle<Object>::cast(source).location() }; |
| 5407 Handle<Object> result = | 5406 Handle<Object> result = |
| 5408 Execution::Call(Handle<JSFunction>::cast(evaluation_function), receiver, | 5407 Execution::Call(Handle<JSFunction>::cast(evaluation_function), receiver, |
| 5409 argc, argv, &has_pending_exception); | 5408 argc, argv, &has_pending_exception); |
| 5409 if (has_pending_exception) return Failure::Exception(); |
| 5410 return *result; | 5410 return *result; |
| 5411 } | 5411 } |
| 5412 | 5412 |
| 5413 | 5413 |
| 5414 static Object* Runtime_DebugEvaluateGlobal(Arguments args) { | 5414 static Object* Runtime_DebugEvaluateGlobal(Arguments args) { |
| 5415 HandleScope scope; | 5415 HandleScope scope; |
| 5416 | 5416 |
| 5417 // Check the execution state and decode arguments frame and source to be | 5417 // Check the execution state and decode arguments frame and source to be |
| 5418 // evaluated. | 5418 // evaluated. |
| 5419 ASSERT(args.length() == 3); | 5419 ASSERT(args.length() == 3); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 5445 Handle<JSFunction> compiled_function = | 5445 Handle<JSFunction> compiled_function = |
| 5446 Handle<JSFunction>(Factory::NewFunctionFromBoilerplate(boilerplate, | 5446 Handle<JSFunction>(Factory::NewFunctionFromBoilerplate(boilerplate, |
| 5447 context)); | 5447 context)); |
| 5448 | 5448 |
| 5449 // Invoke the result of the compilation to get the evaluation function. | 5449 // Invoke the result of the compilation to get the evaluation function. |
| 5450 bool has_pending_exception; | 5450 bool has_pending_exception; |
| 5451 Handle<Object> receiver = Top::global(); | 5451 Handle<Object> receiver = Top::global(); |
| 5452 Handle<Object> result = | 5452 Handle<Object> result = |
| 5453 Execution::Call(compiled_function, receiver, 0, NULL, | 5453 Execution::Call(compiled_function, receiver, 0, NULL, |
| 5454 &has_pending_exception); | 5454 &has_pending_exception); |
| 5455 if (has_pending_exception) return Failure::Exception(); |
| 5455 return *result; | 5456 return *result; |
| 5456 } | 5457 } |
| 5457 | 5458 |
| 5458 | 5459 |
| 5459 // Helper function used by Runtime_DebugGetLoadedScripts below. | 5460 // Helper function used by Runtime_DebugGetLoadedScripts below. |
| 5460 static int DebugGetLoadedScripts(FixedArray* instances, int instances_size) { | 5461 static int DebugGetLoadedScripts(FixedArray* instances, int instances_size) { |
| 5461 NoHandleAllocation ha; | 5462 NoHandleAllocation ha; |
| 5462 AssertNoAllocation no_alloc; | 5463 AssertNoAllocation no_alloc; |
| 5463 | 5464 |
| 5464 // Get hold of the current empty script. | 5465 // Get hold of the current empty script. |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5871 } else { | 5872 } else { |
| 5872 // Handle last resort GC and make sure to allow future allocations | 5873 // Handle last resort GC and make sure to allow future allocations |
| 5873 // to grow the heap without causing GCs (if possible). | 5874 // to grow the heap without causing GCs (if possible). |
| 5874 Counters::gc_last_resort_from_js.Increment(); | 5875 Counters::gc_last_resort_from_js.Increment(); |
| 5875 Heap::CollectAllGarbage(); | 5876 Heap::CollectAllGarbage(); |
| 5876 } | 5877 } |
| 5877 } | 5878 } |
| 5878 | 5879 |
| 5879 | 5880 |
| 5880 } } // namespace v8::internal | 5881 } } // namespace v8::internal |
| OLD | NEW |