OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
9 #include "src/ast/scopeinfo.h" | 9 #include "src/ast/scopeinfo.h" |
10 #include "src/ast/scopes.h" | 10 #include "src/ast/scopes.h" |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 isolate, JSObject::SetOwnPropertyIgnoreAttributes( | 407 isolate, JSObject::SetOwnPropertyIgnoreAttributes( |
408 Handle<JSObject>::cast(holder), name, value, attr)); | 408 Handle<JSObject>::cast(holder), name, value, attr)); |
409 | 409 |
410 return *value; | 410 return *value; |
411 } | 411 } |
412 | 412 |
413 | 413 |
414 namespace { | 414 namespace { |
415 | 415 |
416 // Find the arguments of the JavaScript function invocation that called | 416 // Find the arguments of the JavaScript function invocation that called |
417 // into C++ code. Collect these in a newly allocated array of handles (possibly | 417 // into C++ code. Collect these in a newly allocated array of handles. |
418 // prefixed by a number of empty handles). | |
419 base::SmartArrayPointer<Handle<Object>> GetCallerArguments(Isolate* isolate, | 418 base::SmartArrayPointer<Handle<Object>> GetCallerArguments(Isolate* isolate, |
420 int prefix_argc, | |
421 int* total_argc) { | 419 int* total_argc) { |
422 // Find frame containing arguments passed to the caller. | 420 // Find frame containing arguments passed to the caller. |
423 JavaScriptFrameIterator it(isolate); | 421 JavaScriptFrameIterator it(isolate); |
424 JavaScriptFrame* frame = it.frame(); | 422 JavaScriptFrame* frame = it.frame(); |
425 List<JSFunction*> functions(2); | 423 List<JSFunction*> functions(2); |
426 frame->GetFunctions(&functions); | 424 frame->GetFunctions(&functions); |
427 if (functions.length() > 1) { | 425 if (functions.length() > 1) { |
428 int inlined_jsframe_index = functions.length() - 1; | 426 int inlined_jsframe_index = functions.length() - 1; |
429 TranslatedState translated_values(frame); | 427 TranslatedState translated_values(frame); |
430 translated_values.Prepare(false, frame->fp()); | 428 translated_values.Prepare(false, frame->fp()); |
431 | 429 |
432 int argument_count = 0; | 430 int argument_count = 0; |
433 TranslatedFrame* translated_frame = | 431 TranslatedFrame* translated_frame = |
434 translated_values.GetArgumentsInfoFromJSFrameIndex( | 432 translated_values.GetArgumentsInfoFromJSFrameIndex( |
435 inlined_jsframe_index, &argument_count); | 433 inlined_jsframe_index, &argument_count); |
436 TranslatedFrame::iterator iter = translated_frame->begin(); | 434 TranslatedFrame::iterator iter = translated_frame->begin(); |
437 | 435 |
438 // Skip the function. | 436 // Skip the function. |
439 iter++; | 437 iter++; |
440 | 438 |
441 // Skip the receiver. | 439 // Skip the receiver. |
442 iter++; | 440 iter++; |
443 argument_count--; | 441 argument_count--; |
444 | 442 |
445 *total_argc = prefix_argc + argument_count; | 443 *total_argc = argument_count; |
446 base::SmartArrayPointer<Handle<Object>> param_data( | 444 base::SmartArrayPointer<Handle<Object>> param_data( |
447 NewArray<Handle<Object>>(*total_argc)); | 445 NewArray<Handle<Object>>(*total_argc)); |
448 bool should_deoptimize = false; | 446 bool should_deoptimize = false; |
449 for (int i = 0; i < argument_count; i++) { | 447 for (int i = 0; i < argument_count; i++) { |
450 should_deoptimize = should_deoptimize || iter->IsMaterializedObject(); | 448 should_deoptimize = should_deoptimize || iter->IsMaterializedObject(); |
451 Handle<Object> value = iter->GetValue(); | 449 Handle<Object> value = iter->GetValue(); |
452 param_data[prefix_argc + i] = value; | 450 param_data[i] = value; |
453 iter++; | 451 iter++; |
454 } | 452 } |
455 | 453 |
456 if (should_deoptimize) { | 454 if (should_deoptimize) { |
457 translated_values.StoreMaterializedValuesAndDeopt(); | 455 translated_values.StoreMaterializedValuesAndDeopt(); |
458 } | 456 } |
459 | 457 |
460 return param_data; | 458 return param_data; |
461 } else { | 459 } else { |
462 it.AdvanceToArgumentsFrame(); | 460 it.AdvanceToArgumentsFrame(); |
463 frame = it.frame(); | 461 frame = it.frame(); |
464 int args_count = frame->ComputeParametersCount(); | 462 int args_count = frame->ComputeParametersCount(); |
465 | 463 |
466 *total_argc = prefix_argc + args_count; | 464 *total_argc = args_count; |
467 base::SmartArrayPointer<Handle<Object>> param_data( | 465 base::SmartArrayPointer<Handle<Object>> param_data( |
468 NewArray<Handle<Object>>(*total_argc)); | 466 NewArray<Handle<Object>>(*total_argc)); |
469 for (int i = 0; i < args_count; i++) { | 467 for (int i = 0; i < args_count; i++) { |
470 Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate); | 468 Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate); |
471 param_data[prefix_argc + i] = val; | 469 param_data[i] = val; |
472 } | 470 } |
473 return param_data; | 471 return param_data; |
474 } | 472 } |
475 } | 473 } |
476 | 474 |
477 | 475 |
478 template <typename T> | 476 template <typename T> |
479 Handle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee, | 477 Handle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee, |
480 T parameters, int argument_count) { | 478 T parameters, int argument_count) { |
481 CHECK(!IsSubclassConstructor(callee->shared()->kind())); | 479 CHECK(!IsSubclassConstructor(callee->shared()->kind())); |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 | 625 |
628 | 626 |
629 RUNTIME_FUNCTION(Runtime_NewSloppyArguments_Generic) { | 627 RUNTIME_FUNCTION(Runtime_NewSloppyArguments_Generic) { |
630 HandleScope scope(isolate); | 628 HandleScope scope(isolate); |
631 DCHECK(args.length() == 1); | 629 DCHECK(args.length() == 1); |
632 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); | 630 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); |
633 // This generic runtime function can also be used when the caller has been | 631 // This generic runtime function can also be used when the caller has been |
634 // inlined, we use the slow but accurate {GetCallerArguments}. | 632 // inlined, we use the slow but accurate {GetCallerArguments}. |
635 int argument_count = 0; | 633 int argument_count = 0; |
636 base::SmartArrayPointer<Handle<Object>> arguments = | 634 base::SmartArrayPointer<Handle<Object>> arguments = |
637 GetCallerArguments(isolate, 0, &argument_count); | 635 GetCallerArguments(isolate, &argument_count); |
638 HandleArguments argument_getter(arguments.get()); | 636 HandleArguments argument_getter(arguments.get()); |
639 return *NewSloppyArguments(isolate, callee, argument_getter, argument_count); | 637 return *NewSloppyArguments(isolate, callee, argument_getter, argument_count); |
640 } | 638 } |
641 | 639 |
642 | 640 |
643 RUNTIME_FUNCTION(Runtime_NewStrictArguments_Generic) { | 641 RUNTIME_FUNCTION(Runtime_NewStrictArguments_Generic) { |
644 HandleScope scope(isolate); | 642 HandleScope scope(isolate); |
645 DCHECK(args.length() == 1); | 643 DCHECK(args.length() == 1); |
646 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); | 644 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); |
647 // This generic runtime function can also be used when the caller has been | 645 // This generic runtime function can also be used when the caller has been |
648 // inlined, we use the slow but accurate {GetCallerArguments}. | 646 // inlined, we use the slow but accurate {GetCallerArguments}. |
649 int argument_count = 0; | 647 int argument_count = 0; |
650 base::SmartArrayPointer<Handle<Object>> arguments = | 648 base::SmartArrayPointer<Handle<Object>> arguments = |
651 GetCallerArguments(isolate, 0, &argument_count); | 649 GetCallerArguments(isolate, &argument_count); |
652 HandleArguments argument_getter(arguments.get()); | 650 HandleArguments argument_getter(arguments.get()); |
653 return *NewStrictArguments(isolate, callee, argument_getter, argument_count); | 651 return *NewStrictArguments(isolate, callee, argument_getter, argument_count); |
654 } | 652 } |
655 | 653 |
656 | 654 |
657 RUNTIME_FUNCTION(Runtime_NewRestArguments_Generic) { | 655 RUNTIME_FUNCTION(Runtime_NewRestArguments_Generic) { |
658 HandleScope scope(isolate); | 656 HandleScope scope(isolate); |
659 DCHECK(args.length() == 2); | 657 DCHECK(args.length() == 2); |
660 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0) | 658 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0) |
661 CONVERT_SMI_ARG_CHECKED(start_index, 1); | 659 CONVERT_SMI_ARG_CHECKED(start_index, 1); |
662 // This generic runtime function can also be used when the caller has been | 660 // This generic runtime function can also be used when the caller has been |
663 // inlined, we use the slow but accurate {GetCallerArguments}. | 661 // inlined, we use the slow but accurate {GetCallerArguments}. |
664 int argument_count = 0; | 662 int argument_count = 0; |
665 base::SmartArrayPointer<Handle<Object>> arguments = | 663 base::SmartArrayPointer<Handle<Object>> arguments = |
666 GetCallerArguments(isolate, 0, &argument_count); | 664 GetCallerArguments(isolate, &argument_count); |
667 HandleArguments argument_getter(arguments.get()); | 665 HandleArguments argument_getter(arguments.get()); |
668 return *NewRestArguments(isolate, callee, argument_getter, argument_count, | 666 return *NewRestArguments(isolate, callee, argument_getter, argument_count, |
669 start_index); | 667 start_index); |
670 } | 668 } |
671 | 669 |
672 | 670 |
673 RUNTIME_FUNCTION(Runtime_NewSloppyArguments) { | 671 RUNTIME_FUNCTION(Runtime_NewSloppyArguments) { |
674 HandleScope scope(isolate); | 672 HandleScope scope(isolate); |
675 DCHECK(args.length() == 3); | 673 DCHECK(args.length() == 3); |
676 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); | 674 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); |
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1168 isolate, Object::SetProperty(object, name, value, language_mode)); | 1166 isolate, Object::SetProperty(object, name, value, language_mode)); |
1169 | 1167 |
1170 return *value; | 1168 return *value; |
1171 } | 1169 } |
1172 | 1170 |
1173 | 1171 |
1174 RUNTIME_FUNCTION(Runtime_ArgumentsLength) { | 1172 RUNTIME_FUNCTION(Runtime_ArgumentsLength) { |
1175 HandleScope scope(isolate); | 1173 HandleScope scope(isolate); |
1176 DCHECK(args.length() == 0); | 1174 DCHECK(args.length() == 0); |
1177 int argument_count = 0; | 1175 int argument_count = 0; |
1178 GetCallerArguments(isolate, 0, &argument_count); | 1176 GetCallerArguments(isolate, &argument_count); |
1179 return Smi::FromInt(argument_count); | 1177 return Smi::FromInt(argument_count); |
1180 } | 1178 } |
1181 | 1179 |
1182 | 1180 |
1183 RUNTIME_FUNCTION(Runtime_Arguments) { | 1181 RUNTIME_FUNCTION(Runtime_Arguments) { |
1184 HandleScope scope(isolate); | 1182 HandleScope scope(isolate); |
1185 DCHECK(args.length() == 1); | 1183 DCHECK(args.length() == 1); |
1186 CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0); | 1184 CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0); |
1187 | 1185 |
1188 // Determine the actual arguments passed to the function. | 1186 // Determine the actual arguments passed to the function. |
1189 int argument_count_signed = 0; | 1187 int argument_count_signed = 0; |
1190 base::SmartArrayPointer<Handle<Object>> arguments = | 1188 base::SmartArrayPointer<Handle<Object>> arguments = |
1191 GetCallerArguments(isolate, 0, &argument_count_signed); | 1189 GetCallerArguments(isolate, &argument_count_signed); |
1192 const uint32_t argument_count = argument_count_signed; | 1190 const uint32_t argument_count = argument_count_signed; |
1193 | 1191 |
1194 // Try to convert the key to an index. If successful and within | 1192 // Try to convert the key to an index. If successful and within |
1195 // index return the the argument from the frame. | 1193 // index return the the argument from the frame. |
1196 uint32_t index = 0; | 1194 uint32_t index = 0; |
1197 if (raw_key->ToArrayIndex(&index) && index < argument_count) { | 1195 if (raw_key->ToArrayIndex(&index) && index < argument_count) { |
1198 return *arguments[index]; | 1196 return *arguments[index]; |
1199 } | 1197 } |
1200 | 1198 |
1201 if (raw_key->IsSymbol()) { | 1199 if (raw_key->IsSymbol()) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1248 | 1246 |
1249 // Lookup in the initial Object.prototype object. | 1247 // Lookup in the initial Object.prototype object. |
1250 Handle<Object> result; | 1248 Handle<Object> result; |
1251 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1249 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1252 isolate, result, | 1250 isolate, result, |
1253 Object::GetProperty(isolate->initial_object_prototype(), key)); | 1251 Object::GetProperty(isolate->initial_object_prototype(), key)); |
1254 return *result; | 1252 return *result; |
1255 } | 1253 } |
1256 } // namespace internal | 1254 } // namespace internal |
1257 } // namespace v8 | 1255 } // namespace v8 |
OLD | NEW |