| 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/v8.h" | 5 #include "src/v8.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/compiler.h" | 9 #include "src/compiler.h" |
| 10 #include "src/cpu-profiler.h" | 10 #include "src/cpu-profiler.h" |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 JSFunction* func = JSFunction::cast(*object); | 321 JSFunction* func = JSFunction::cast(*object); |
| 322 func->shared()->set_force_inline(true); | 322 func->shared()->set_force_inline(true); |
| 323 } | 323 } |
| 324 return isolate->heap()->undefined_value(); | 324 return isolate->heap()->undefined_value(); |
| 325 } | 325 } |
| 326 | 326 |
| 327 | 327 |
| 328 // Find the arguments of the JavaScript function invocation that called | 328 // Find the arguments of the JavaScript function invocation that called |
| 329 // into C++ code. Collect these in a newly allocated array of handles (possibly | 329 // into C++ code. Collect these in a newly allocated array of handles (possibly |
| 330 // prefixed by a number of empty handles). | 330 // prefixed by a number of empty handles). |
| 331 static SmartArrayPointer<Handle<Object> > GetCallerArguments(Isolate* isolate, | 331 static base::SmartArrayPointer<Handle<Object> > GetCallerArguments( |
| 332 int prefix_argc, | 332 Isolate* isolate, int prefix_argc, int* total_argc) { |
| 333 int* total_argc) { | |
| 334 // Find frame containing arguments passed to the caller. | 333 // Find frame containing arguments passed to the caller. |
| 335 JavaScriptFrameIterator it(isolate); | 334 JavaScriptFrameIterator it(isolate); |
| 336 JavaScriptFrame* frame = it.frame(); | 335 JavaScriptFrame* frame = it.frame(); |
| 337 List<JSFunction*> functions(2); | 336 List<JSFunction*> functions(2); |
| 338 frame->GetFunctions(&functions); | 337 frame->GetFunctions(&functions); |
| 339 if (functions.length() > 1) { | 338 if (functions.length() > 1) { |
| 340 int inlined_jsframe_index = functions.length() - 1; | 339 int inlined_jsframe_index = functions.length() - 1; |
| 341 TranslatedState translated_values(frame); | 340 TranslatedState translated_values(frame); |
| 342 translated_values.Prepare(false, frame->fp()); | 341 translated_values.Prepare(false, frame->fp()); |
| 343 | 342 |
| 344 int argument_count = 0; | 343 int argument_count = 0; |
| 345 TranslatedFrame* translated_frame = | 344 TranslatedFrame* translated_frame = |
| 346 translated_values.GetArgumentsInfoFromJSFrameIndex( | 345 translated_values.GetArgumentsInfoFromJSFrameIndex( |
| 347 inlined_jsframe_index, &argument_count); | 346 inlined_jsframe_index, &argument_count); |
| 348 TranslatedFrame::iterator iter = translated_frame->begin(); | 347 TranslatedFrame::iterator iter = translated_frame->begin(); |
| 349 | 348 |
| 350 // Skip the function. | 349 // Skip the function. |
| 351 iter++; | 350 iter++; |
| 352 | 351 |
| 353 // Skip the receiver. | 352 // Skip the receiver. |
| 354 iter++; | 353 iter++; |
| 355 argument_count--; | 354 argument_count--; |
| 356 | 355 |
| 357 *total_argc = prefix_argc + argument_count; | 356 *total_argc = prefix_argc + argument_count; |
| 358 SmartArrayPointer<Handle<Object> > param_data( | 357 base::SmartArrayPointer<Handle<Object> > param_data( |
| 359 NewArray<Handle<Object> >(*total_argc)); | 358 NewArray<Handle<Object> >(*total_argc)); |
| 360 bool should_deoptimize = false; | 359 bool should_deoptimize = false; |
| 361 for (int i = 0; i < argument_count; i++) { | 360 for (int i = 0; i < argument_count; i++) { |
| 362 should_deoptimize = should_deoptimize || iter->IsMaterializedObject(); | 361 should_deoptimize = should_deoptimize || iter->IsMaterializedObject(); |
| 363 Handle<Object> value = iter->GetValue(); | 362 Handle<Object> value = iter->GetValue(); |
| 364 param_data[prefix_argc + i] = value; | 363 param_data[prefix_argc + i] = value; |
| 365 iter++; | 364 iter++; |
| 366 } | 365 } |
| 367 | 366 |
| 368 if (should_deoptimize) { | 367 if (should_deoptimize) { |
| 369 translated_values.StoreMaterializedValuesAndDeopt(); | 368 translated_values.StoreMaterializedValuesAndDeopt(); |
| 370 } | 369 } |
| 371 | 370 |
| 372 return param_data; | 371 return param_data; |
| 373 } else { | 372 } else { |
| 374 it.AdvanceToArgumentsFrame(); | 373 it.AdvanceToArgumentsFrame(); |
| 375 frame = it.frame(); | 374 frame = it.frame(); |
| 376 int args_count = frame->ComputeParametersCount(); | 375 int args_count = frame->ComputeParametersCount(); |
| 377 | 376 |
| 378 *total_argc = prefix_argc + args_count; | 377 *total_argc = prefix_argc + args_count; |
| 379 SmartArrayPointer<Handle<Object> > param_data( | 378 base::SmartArrayPointer<Handle<Object> > param_data( |
| 380 NewArray<Handle<Object> >(*total_argc)); | 379 NewArray<Handle<Object> >(*total_argc)); |
| 381 for (int i = 0; i < args_count; i++) { | 380 for (int i = 0; i < args_count; i++) { |
| 382 Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate); | 381 Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate); |
| 383 param_data[prefix_argc + i] = val; | 382 param_data[prefix_argc + i] = val; |
| 384 } | 383 } |
| 385 return param_data; | 384 return param_data; |
| 386 } | 385 } |
| 387 } | 386 } |
| 388 | 387 |
| 389 | 388 |
| 390 RUNTIME_FUNCTION(Runtime_FunctionBindArguments) { | 389 RUNTIME_FUNCTION(Runtime_FunctionBindArguments) { |
| 391 HandleScope scope(isolate); | 390 HandleScope scope(isolate); |
| 392 DCHECK(args.length() == 4); | 391 DCHECK(args.length() == 4); |
| 393 CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0); | 392 CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0); |
| 394 CONVERT_ARG_HANDLE_CHECKED(Object, bindee, 1); | 393 CONVERT_ARG_HANDLE_CHECKED(Object, bindee, 1); |
| 395 CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2); | 394 CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2); |
| 396 CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3); | 395 CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3); |
| 397 | 396 |
| 398 // TODO(lrn): Create bound function in C++ code from premade shared info. | 397 // TODO(lrn): Create bound function in C++ code from premade shared info. |
| 399 bound_function->shared()->set_bound(true); | 398 bound_function->shared()->set_bound(true); |
| 400 bound_function->shared()->set_optimized_code_map(Smi::FromInt(0)); | 399 bound_function->shared()->set_optimized_code_map(Smi::FromInt(0)); |
| 401 bound_function->shared()->set_inferred_name(isolate->heap()->empty_string()); | 400 bound_function->shared()->set_inferred_name(isolate->heap()->empty_string()); |
| 402 // Get all arguments of calling function (Function.prototype.bind). | 401 // Get all arguments of calling function (Function.prototype.bind). |
| 403 int argc = 0; | 402 int argc = 0; |
| 404 SmartArrayPointer<Handle<Object> > arguments = | 403 base::SmartArrayPointer<Handle<Object> > arguments = |
| 405 GetCallerArguments(isolate, 0, &argc); | 404 GetCallerArguments(isolate, 0, &argc); |
| 406 // Don't count the this-arg. | 405 // Don't count the this-arg. |
| 407 if (argc > 0) { | 406 if (argc > 0) { |
| 408 RUNTIME_ASSERT(arguments[0].is_identical_to(this_object)); | 407 RUNTIME_ASSERT(arguments[0].is_identical_to(this_object)); |
| 409 argc--; | 408 argc--; |
| 410 } else { | 409 } else { |
| 411 RUNTIME_ASSERT(this_object->IsUndefined()); | 410 RUNTIME_ASSERT(this_object->IsUndefined()); |
| 412 } | 411 } |
| 413 // Initialize array of bindings (function, this, and any existing arguments | 412 // Initialize array of bindings (function, this, and any existing arguments |
| 414 // if the function was already bound). | 413 // if the function was already bound). |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 Handle<FixedArray> bound_args = | 495 Handle<FixedArray> bound_args = |
| 497 Handle<FixedArray>(FixedArray::cast(function->function_bindings())); | 496 Handle<FixedArray>(FixedArray::cast(function->function_bindings())); |
| 498 int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex; | 497 int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex; |
| 499 Handle<Object> bound_function( | 498 Handle<Object> bound_function( |
| 500 JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)), | 499 JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)), |
| 501 isolate); | 500 isolate); |
| 502 DCHECK(!bound_function->IsJSFunction() || | 501 DCHECK(!bound_function->IsJSFunction() || |
| 503 !Handle<JSFunction>::cast(bound_function)->shared()->bound()); | 502 !Handle<JSFunction>::cast(bound_function)->shared()->bound()); |
| 504 | 503 |
| 505 int total_argc = 0; | 504 int total_argc = 0; |
| 506 SmartArrayPointer<Handle<Object> > param_data = | 505 base::SmartArrayPointer<Handle<Object> > param_data = |
| 507 GetCallerArguments(isolate, bound_argc, &total_argc); | 506 GetCallerArguments(isolate, bound_argc, &total_argc); |
| 508 for (int i = 0; i < bound_argc; i++) { | 507 for (int i = 0; i < bound_argc; i++) { |
| 509 param_data[i] = Handle<Object>( | 508 param_data[i] = Handle<Object>( |
| 510 bound_args->get(JSFunction::kBoundArgumentsStartIndex + i), isolate); | 509 bound_args->get(JSFunction::kBoundArgumentsStartIndex + i), isolate); |
| 511 } | 510 } |
| 512 | 511 |
| 513 if (!bound_function->IsJSFunction()) { | 512 if (!bound_function->IsJSFunction()) { |
| 514 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 513 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 515 isolate, bound_function, | 514 isolate, bound_function, |
| 516 Execution::TryGetConstructorDelegate(isolate, bound_function)); | 515 Execution::TryGetConstructorDelegate(isolate, bound_function)); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 528 RUNTIME_FUNCTION(Runtime_Call) { | 527 RUNTIME_FUNCTION(Runtime_Call) { |
| 529 HandleScope scope(isolate); | 528 HandleScope scope(isolate); |
| 530 DCHECK(args.length() >= 2); | 529 DCHECK(args.length() >= 2); |
| 531 int argc = args.length() - 2; | 530 int argc = args.length() - 2; |
| 532 CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1); | 531 CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1); |
| 533 Object* receiver = args[0]; | 532 Object* receiver = args[0]; |
| 534 | 533 |
| 535 // If there are too many arguments, allocate argv via malloc. | 534 // If there are too many arguments, allocate argv via malloc. |
| 536 const int argv_small_size = 10; | 535 const int argv_small_size = 10; |
| 537 Handle<Object> argv_small_buffer[argv_small_size]; | 536 Handle<Object> argv_small_buffer[argv_small_size]; |
| 538 SmartArrayPointer<Handle<Object> > argv_large_buffer; | 537 base::SmartArrayPointer<Handle<Object> > argv_large_buffer; |
| 539 Handle<Object>* argv = argv_small_buffer; | 538 Handle<Object>* argv = argv_small_buffer; |
| 540 if (argc > argv_small_size) { | 539 if (argc > argv_small_size) { |
| 541 argv = new Handle<Object>[argc]; | 540 argv = new Handle<Object>[argc]; |
| 542 if (argv == NULL) return isolate->StackOverflow(); | 541 if (argv == NULL) return isolate->StackOverflow(); |
| 543 argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv); | 542 argv_large_buffer = base::SmartArrayPointer<Handle<Object> >(argv); |
| 544 } | 543 } |
| 545 | 544 |
| 546 for (int i = 0; i < argc; ++i) { | 545 for (int i = 0; i < argc; ++i) { |
| 547 argv[i] = Handle<Object>(args[1 + i], isolate); | 546 argv[i] = Handle<Object>(args[1 + i], isolate); |
| 548 } | 547 } |
| 549 | 548 |
| 550 Handle<JSReceiver> hfun(fun); | 549 Handle<JSReceiver> hfun(fun); |
| 551 Handle<Object> hreceiver(receiver, isolate); | 550 Handle<Object> hreceiver(receiver, isolate); |
| 552 Handle<Object> result; | 551 Handle<Object> result; |
| 553 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 552 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 567 CONVERT_INT32_ARG_CHECKED(argc, 4); | 566 CONVERT_INT32_ARG_CHECKED(argc, 4); |
| 568 RUNTIME_ASSERT(offset >= 0); | 567 RUNTIME_ASSERT(offset >= 0); |
| 569 // Loose upper bound to allow fuzzing. We'll most likely run out of | 568 // Loose upper bound to allow fuzzing. We'll most likely run out of |
| 570 // stack space before hitting this limit. | 569 // stack space before hitting this limit. |
| 571 static int kMaxArgc = 1000000; | 570 static int kMaxArgc = 1000000; |
| 572 RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc); | 571 RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc); |
| 573 | 572 |
| 574 // If there are too many arguments, allocate argv via malloc. | 573 // If there are too many arguments, allocate argv via malloc. |
| 575 const int argv_small_size = 10; | 574 const int argv_small_size = 10; |
| 576 Handle<Object> argv_small_buffer[argv_small_size]; | 575 Handle<Object> argv_small_buffer[argv_small_size]; |
| 577 SmartArrayPointer<Handle<Object> > argv_large_buffer; | 576 base::SmartArrayPointer<Handle<Object> > argv_large_buffer; |
| 578 Handle<Object>* argv = argv_small_buffer; | 577 Handle<Object>* argv = argv_small_buffer; |
| 579 if (argc > argv_small_size) { | 578 if (argc > argv_small_size) { |
| 580 argv = new Handle<Object>[argc]; | 579 argv = new Handle<Object>[argc]; |
| 581 if (argv == NULL) return isolate->StackOverflow(); | 580 if (argv == NULL) return isolate->StackOverflow(); |
| 582 argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv); | 581 argv_large_buffer = base::SmartArrayPointer<Handle<Object> >(argv); |
| 583 } | 582 } |
| 584 | 583 |
| 585 for (int i = 0; i < argc; ++i) { | 584 for (int i = 0; i < argc; ++i) { |
| 586 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 585 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 587 isolate, argv[i], Object::GetElement(isolate, arguments, offset + i)); | 586 isolate, argv[i], Object::GetElement(isolate, arguments, offset + i)); |
| 588 } | 587 } |
| 589 | 588 |
| 590 Handle<Object> result; | 589 Handle<Object> result; |
| 591 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 590 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 592 isolate, result, | 591 isolate, result, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 | 646 |
| 648 | 647 |
| 649 RUNTIME_FUNCTION(Runtime_ThrowStrongModeTooFewArguments) { | 648 RUNTIME_FUNCTION(Runtime_ThrowStrongModeTooFewArguments) { |
| 650 HandleScope scope(isolate); | 649 HandleScope scope(isolate); |
| 651 DCHECK(args.length() == 0); | 650 DCHECK(args.length() == 0); |
| 652 THROW_NEW_ERROR_RETURN_FAILURE(isolate, | 651 THROW_NEW_ERROR_RETURN_FAILURE(isolate, |
| 653 NewTypeError(MessageTemplate::kStrongArity)); | 652 NewTypeError(MessageTemplate::kStrongArity)); |
| 654 } | 653 } |
| 655 } // namespace internal | 654 } // namespace internal |
| 656 } // namespace v8 | 655 } // namespace v8 |
| OLD | NEW |