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 <memory> |
| 8 |
7 #include "src/accessors.h" | 9 #include "src/accessors.h" |
8 #include "src/arguments.h" | 10 #include "src/arguments.h" |
9 #include "src/ast/scopeinfo.h" | 11 #include "src/ast/scopeinfo.h" |
10 #include "src/ast/scopes.h" | 12 #include "src/ast/scopes.h" |
11 #include "src/deoptimizer.h" | 13 #include "src/deoptimizer.h" |
12 #include "src/frames-inl.h" | 14 #include "src/frames-inl.h" |
13 #include "src/isolate-inl.h" | 15 #include "src/isolate-inl.h" |
14 #include "src/messages.h" | 16 #include "src/messages.h" |
15 | 17 |
16 namespace v8 { | 18 namespace v8 { |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 DCHECK_EQ(1, args.length()); | 365 DCHECK_EQ(1, args.length()); |
364 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | 366 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |
365 return DeclareEvalHelper(isolate, name, | 367 return DeclareEvalHelper(isolate, name, |
366 isolate->factory()->undefined_value()); | 368 isolate->factory()->undefined_value()); |
367 } | 369 } |
368 | 370 |
369 namespace { | 371 namespace { |
370 | 372 |
371 // Find the arguments of the JavaScript function invocation that called | 373 // Find the arguments of the JavaScript function invocation that called |
372 // into C++ code. Collect these in a newly allocated array of handles. | 374 // into C++ code. Collect these in a newly allocated array of handles. |
373 base::SmartArrayPointer<Handle<Object>> GetCallerArguments(Isolate* isolate, | 375 std::unique_ptr<Handle<Object>[]> GetCallerArguments(Isolate* isolate, |
374 int* total_argc) { | 376 int* total_argc) { |
375 // Find frame containing arguments passed to the caller. | 377 // Find frame containing arguments passed to the caller. |
376 JavaScriptFrameIterator it(isolate); | 378 JavaScriptFrameIterator it(isolate); |
377 JavaScriptFrame* frame = it.frame(); | 379 JavaScriptFrame* frame = it.frame(); |
378 List<JSFunction*> functions(2); | 380 List<JSFunction*> functions(2); |
379 frame->GetFunctions(&functions); | 381 frame->GetFunctions(&functions); |
380 if (functions.length() > 1) { | 382 if (functions.length() > 1) { |
381 int inlined_jsframe_index = functions.length() - 1; | 383 int inlined_jsframe_index = functions.length() - 1; |
382 TranslatedState translated_values(frame); | 384 TranslatedState translated_values(frame); |
383 translated_values.Prepare(false, frame->fp()); | 385 translated_values.Prepare(false, frame->fp()); |
384 | 386 |
385 int argument_count = 0; | 387 int argument_count = 0; |
386 TranslatedFrame* translated_frame = | 388 TranslatedFrame* translated_frame = |
387 translated_values.GetArgumentsInfoFromJSFrameIndex( | 389 translated_values.GetArgumentsInfoFromJSFrameIndex( |
388 inlined_jsframe_index, &argument_count); | 390 inlined_jsframe_index, &argument_count); |
389 TranslatedFrame::iterator iter = translated_frame->begin(); | 391 TranslatedFrame::iterator iter = translated_frame->begin(); |
390 | 392 |
391 // Skip the function. | 393 // Skip the function. |
392 iter++; | 394 iter++; |
393 | 395 |
394 // Skip the receiver. | 396 // Skip the receiver. |
395 iter++; | 397 iter++; |
396 argument_count--; | 398 argument_count--; |
397 | 399 |
398 *total_argc = argument_count; | 400 *total_argc = argument_count; |
399 base::SmartArrayPointer<Handle<Object>> param_data( | 401 std::unique_ptr<Handle<Object>[]> param_data( |
400 NewArray<Handle<Object>>(*total_argc)); | 402 NewArray<Handle<Object>>(*total_argc)); |
401 bool should_deoptimize = false; | 403 bool should_deoptimize = false; |
402 for (int i = 0; i < argument_count; i++) { | 404 for (int i = 0; i < argument_count; i++) { |
403 should_deoptimize = should_deoptimize || iter->IsMaterializedObject(); | 405 should_deoptimize = should_deoptimize || iter->IsMaterializedObject(); |
404 Handle<Object> value = iter->GetValue(); | 406 Handle<Object> value = iter->GetValue(); |
405 param_data[i] = value; | 407 param_data[i] = value; |
406 iter++; | 408 iter++; |
407 } | 409 } |
408 | 410 |
409 if (should_deoptimize) { | 411 if (should_deoptimize) { |
410 translated_values.StoreMaterializedValuesAndDeopt(); | 412 translated_values.StoreMaterializedValuesAndDeopt(); |
411 } | 413 } |
412 | 414 |
413 return param_data; | 415 return param_data; |
414 } else { | 416 } else { |
415 it.AdvanceToArgumentsFrame(); | 417 it.AdvanceToArgumentsFrame(); |
416 frame = it.frame(); | 418 frame = it.frame(); |
417 int args_count = frame->ComputeParametersCount(); | 419 int args_count = frame->ComputeParametersCount(); |
418 | 420 |
419 *total_argc = args_count; | 421 *total_argc = args_count; |
420 base::SmartArrayPointer<Handle<Object>> param_data( | 422 std::unique_ptr<Handle<Object>[]> param_data( |
421 NewArray<Handle<Object>>(*total_argc)); | 423 NewArray<Handle<Object>>(*total_argc)); |
422 for (int i = 0; i < args_count; i++) { | 424 for (int i = 0; i < args_count; i++) { |
423 Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate); | 425 Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate); |
424 param_data[i] = val; | 426 param_data[i] = val; |
425 } | 427 } |
426 return param_data; | 428 return param_data; |
427 } | 429 } |
428 } | 430 } |
429 | 431 |
430 | |
431 template <typename T> | 432 template <typename T> |
432 Handle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee, | 433 Handle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee, |
433 T parameters, int argument_count) { | 434 T parameters, int argument_count) { |
434 CHECK(!IsSubclassConstructor(callee->shared()->kind())); | 435 CHECK(!IsSubclassConstructor(callee->shared()->kind())); |
435 DCHECK(callee->shared()->has_simple_parameters()); | 436 DCHECK(callee->shared()->has_simple_parameters()); |
436 Handle<JSObject> result = | 437 Handle<JSObject> result = |
437 isolate->factory()->NewArgumentsObject(callee, argument_count); | 438 isolate->factory()->NewArgumentsObject(callee, argument_count); |
438 | 439 |
439 // Allocate the elements if needed. | 440 // Allocate the elements if needed. |
440 int parameter_count = callee->shared()->internal_formal_parameter_count(); | 441 int parameter_count = callee->shared()->internal_formal_parameter_count(); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 } // namespace | 540 } // namespace |
540 | 541 |
541 | 542 |
542 RUNTIME_FUNCTION(Runtime_NewSloppyArguments_Generic) { | 543 RUNTIME_FUNCTION(Runtime_NewSloppyArguments_Generic) { |
543 HandleScope scope(isolate); | 544 HandleScope scope(isolate); |
544 DCHECK(args.length() == 1); | 545 DCHECK(args.length() == 1); |
545 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); | 546 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); |
546 // This generic runtime function can also be used when the caller has been | 547 // This generic runtime function can also be used when the caller has been |
547 // inlined, we use the slow but accurate {GetCallerArguments}. | 548 // inlined, we use the slow but accurate {GetCallerArguments}. |
548 int argument_count = 0; | 549 int argument_count = 0; |
549 base::SmartArrayPointer<Handle<Object>> arguments = | 550 std::unique_ptr<Handle<Object>[]> arguments = |
550 GetCallerArguments(isolate, &argument_count); | 551 GetCallerArguments(isolate, &argument_count); |
551 HandleArguments argument_getter(arguments.get()); | 552 HandleArguments argument_getter(arguments.get()); |
552 return *NewSloppyArguments(isolate, callee, argument_getter, argument_count); | 553 return *NewSloppyArguments(isolate, callee, argument_getter, argument_count); |
553 } | 554 } |
554 | 555 |
555 | 556 |
556 RUNTIME_FUNCTION(Runtime_NewStrictArguments) { | 557 RUNTIME_FUNCTION(Runtime_NewStrictArguments) { |
557 HandleScope scope(isolate); | 558 HandleScope scope(isolate); |
558 DCHECK_EQ(1, args.length()); | 559 DCHECK_EQ(1, args.length()); |
559 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); | 560 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); |
560 // This generic runtime function can also be used when the caller has been | 561 // This generic runtime function can also be used when the caller has been |
561 // inlined, we use the slow but accurate {GetCallerArguments}. | 562 // inlined, we use the slow but accurate {GetCallerArguments}. |
562 int argument_count = 0; | 563 int argument_count = 0; |
563 base::SmartArrayPointer<Handle<Object>> arguments = | 564 std::unique_ptr<Handle<Object>[]> arguments = |
564 GetCallerArguments(isolate, &argument_count); | 565 GetCallerArguments(isolate, &argument_count); |
565 Handle<JSObject> result = | 566 Handle<JSObject> result = |
566 isolate->factory()->NewArgumentsObject(callee, argument_count); | 567 isolate->factory()->NewArgumentsObject(callee, argument_count); |
567 if (argument_count) { | 568 if (argument_count) { |
568 Handle<FixedArray> array = | 569 Handle<FixedArray> array = |
569 isolate->factory()->NewUninitializedFixedArray(argument_count); | 570 isolate->factory()->NewUninitializedFixedArray(argument_count); |
570 DisallowHeapAllocation no_gc; | 571 DisallowHeapAllocation no_gc; |
571 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); | 572 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); |
572 for (int i = 0; i < argument_count; i++) { | 573 for (int i = 0; i < argument_count; i++) { |
573 array->set(i, *arguments[i], mode); | 574 array->set(i, *arguments[i], mode); |
574 } | 575 } |
575 result->set_elements(*array); | 576 result->set_elements(*array); |
576 } | 577 } |
577 return *result; | 578 return *result; |
578 } | 579 } |
579 | 580 |
580 | 581 |
581 RUNTIME_FUNCTION(Runtime_NewRestParameter) { | 582 RUNTIME_FUNCTION(Runtime_NewRestParameter) { |
582 HandleScope scope(isolate); | 583 HandleScope scope(isolate); |
583 DCHECK_EQ(1, args.length()); | 584 DCHECK_EQ(1, args.length()); |
584 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0) | 585 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0) |
585 int start_index = callee->shared()->internal_formal_parameter_count(); | 586 int start_index = callee->shared()->internal_formal_parameter_count(); |
586 // This generic runtime function can also be used when the caller has been | 587 // This generic runtime function can also be used when the caller has been |
587 // inlined, we use the slow but accurate {GetCallerArguments}. | 588 // inlined, we use the slow but accurate {GetCallerArguments}. |
588 int argument_count = 0; | 589 int argument_count = 0; |
589 base::SmartArrayPointer<Handle<Object>> arguments = | 590 std::unique_ptr<Handle<Object>[]> arguments = |
590 GetCallerArguments(isolate, &argument_count); | 591 GetCallerArguments(isolate, &argument_count); |
591 int num_elements = std::max(0, argument_count - start_index); | 592 int num_elements = std::max(0, argument_count - start_index); |
592 Handle<JSObject> result = | 593 Handle<JSObject> result = |
593 isolate->factory()->NewJSArray(FAST_ELEMENTS, num_elements, num_elements, | 594 isolate->factory()->NewJSArray(FAST_ELEMENTS, num_elements, num_elements, |
594 DONT_INITIALIZE_ARRAY_ELEMENTS); | 595 DONT_INITIALIZE_ARRAY_ELEMENTS); |
595 { | 596 { |
596 DisallowHeapAllocation no_gc; | 597 DisallowHeapAllocation no_gc; |
597 FixedArray* elements = FixedArray::cast(result->elements()); | 598 FixedArray* elements = FixedArray::cast(result->elements()); |
598 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); | 599 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); |
599 for (int i = 0; i < num_elements; i++) { | 600 for (int i = 0; i < num_elements; i++) { |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
972 RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { | 973 RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { |
973 HandleScope scope(isolate); | 974 HandleScope scope(isolate); |
974 DCHECK_EQ(2, args.length()); | 975 DCHECK_EQ(2, args.length()); |
975 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | 976 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |
976 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); | 977 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); |
977 RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, STRICT)); | 978 RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, STRICT)); |
978 } | 979 } |
979 | 980 |
980 } // namespace internal | 981 } // namespace internal |
981 } // namespace v8 | 982 } // namespace v8 |
OLD | NEW |