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 |