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