Chromium Code Reviews| 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 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 567 Handle<JSReceiver> hfun(fun); | 567 Handle<JSReceiver> hfun(fun); |
| 568 Handle<Object> hreceiver(receiver, isolate); | 568 Handle<Object> hreceiver(receiver, isolate); |
| 569 Handle<Object> result; | 569 Handle<Object> result; |
| 570 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 570 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 571 isolate, result, | 571 isolate, result, |
| 572 Execution::Call(isolate, hfun, hreceiver, argc, argv, true)); | 572 Execution::Call(isolate, hfun, hreceiver, argc, argv, true)); |
| 573 return *result; | 573 return *result; |
| 574 } | 574 } |
| 575 | 575 |
| 576 | 576 |
| 577 RUNTIME_FUNCTION(Runtime_Apply) { | 577 static Object* ApplyHelper(Isolate* isolate, Handle<JSReceiver> fun, |
| 578 Handle<Object> receiver, Handle<JSObject> arguments, | |
| 579 int32_t offset, int32_t argc, bool is_construct) { | |
| 578 HandleScope scope(isolate); | 580 HandleScope scope(isolate); |
| 579 DCHECK(args.length() == 5); | 581 |
| 580 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0); | |
| 581 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1); | |
| 582 CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2); | |
| 583 CONVERT_INT32_ARG_CHECKED(offset, 3); | |
| 584 CONVERT_INT32_ARG_CHECKED(argc, 4); | |
| 585 RUNTIME_ASSERT(offset >= 0); | 582 RUNTIME_ASSERT(offset >= 0); |
| 586 // Loose upper bound to allow fuzzing. We'll most likely run out of | 583 // Loose upper bound to allow fuzzing. We'll most likely run out of |
| 587 // stack space before hitting this limit. | 584 // stack space before hitting this limit. |
| 588 static int kMaxArgc = 1000000; | 585 static int kMaxArgc = 1000000; |
| 589 RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc); | 586 RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc); |
| 590 | 587 |
| 591 // If there are too many arguments, allocate argv via malloc. | 588 // If there are too many arguments, allocate argv via malloc. |
| 592 const int argv_small_size = 10; | 589 const int argv_small_size = 10; |
| 593 Handle<Object> argv_small_buffer[argv_small_size]; | 590 Handle<Object> argv_small_buffer[argv_small_size]; |
| 594 SmartArrayPointer<Handle<Object> > argv_large_buffer; | 591 SmartArrayPointer<Handle<Object> > argv_large_buffer; |
| 595 Handle<Object>* argv = argv_small_buffer; | 592 Handle<Object>* argv = argv_small_buffer; |
| 596 if (argc > argv_small_size) { | 593 if (argc > argv_small_size) { |
| 597 argv = new Handle<Object>[argc]; | 594 argv = new Handle<Object>[argc]; |
| 598 if (argv == NULL) return isolate->StackOverflow(); | 595 if (argv == NULL) return isolate->StackOverflow(); |
| 599 argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv); | 596 argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv); |
| 600 } | 597 } |
| 601 | 598 |
| 602 for (int i = 0; i < argc; ++i) { | 599 for (int i = 0; i < argc; ++i) { |
| 603 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 600 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 604 isolate, argv[i], Object::GetElement(isolate, arguments, offset + i)); | 601 isolate, argv[i], Object::GetElement(isolate, arguments, offset + i)); |
| 605 } | 602 } |
| 606 | 603 |
| 607 Handle<Object> result; | 604 Handle<Object> result; |
| 608 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 605 if (is_construct) { |
| 609 isolate, result, | 606 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 610 Execution::Call(isolate, fun, receiver, argc, argv, true)); | 607 isolate, result, Execution::New( |
| 608 Handle<JSFunction>::cast(fun), argc, argv)); | |
| 609 } else { | |
| 610 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
| 611 isolate, result, | |
| 612 Execution::Call(isolate, fun, receiver, argc, argv, true)); | |
| 613 } | |
| 611 return *result; | 614 return *result; |
| 612 } | 615 } |
| 613 | 616 |
| 614 | 617 |
| 618 RUNTIME_FUNCTION(Runtime_Apply) { | |
| 619 HandleScope scope(isolate); | |
| 620 DCHECK(args.length() == 5); | |
| 621 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0); | |
| 622 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1); | |
| 623 CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2); | |
| 624 CONVERT_INT32_ARG_CHECKED(offset, 3); | |
| 625 CONVERT_INT32_ARG_CHECKED(argc, 4); | |
| 626 | |
| 627 return ApplyHelper(isolate, fun, receiver, arguments, offset, argc, false); | |
| 628 } | |
| 629 | |
| 630 | |
| 631 static bool GetObjectLength(Isolate* isolate, Handle<JSObject> obj, | |
| 632 int32_t* length) { | |
| 633 HandleScope scope(isolate); | |
| 634 if (obj->IsJSArray()) { | |
| 635 return Handle<JSArray>::cast(obj)->length()->ToInt32(length); | |
| 636 } else { | |
| 637 Handle<Object> val; | |
| 638 Handle<Object> key(isolate->heap()->length_string(), isolate); | |
| 639 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, val, | |
| 640 Runtime::GetObjectProperty(isolate, obj, key), false); | |
| 641 // TODO(caitp): Support larger element indexes (up to 2^53-1). | |
|
rossberg
2015/02/25 14:28:19
Ah, no. We likely won't, ever, at least not for ca
caitp (gmail)
2015/02/25 14:49:08
sorry, that's copy/pasted from similar code I wrot
| |
| 642 if (!val->ToInt32(length)) { | |
| 643 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, val, | |
|
rossberg
2015/02/25 14:28:19
I think it's more adequate to raise an exception h
caitp (gmail)
2015/02/25 14:49:08
The only reason ToLength() would throw is if the v
| |
| 644 Execution::ToLength(isolate, val), false); | |
| 645 return val->ToInt32(length); | |
| 646 } | |
| 647 } | |
| 648 return true; | |
| 649 } | |
| 650 | |
| 651 | |
| 652 RUNTIME_FUNCTION(Runtime_ApplyCall) { | |
| 653 HandleScope scope(isolate); | |
| 654 DCHECK(args.length() == 3); | |
| 655 CONVERT_ARG_HANDLE_CHECKED(Object, fun, 0); | |
| 656 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1); | |
| 657 CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2); | |
| 658 | |
| 659 if (!fun->IsJSFunction()) { | |
|
rossberg
2015/02/25 14:28:19
Why is this needed? Isn't that already taken care
| |
| 660 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
| 661 isolate, fun, Execution::TryGetFunctionDelegate(isolate, fun)); | |
| 662 } | |
| 663 | |
| 664 int32_t length = 0; | |
| 665 if (!GetObjectLength(isolate, arguments, &length)) { | |
| 666 if (isolate->has_pending_exception()) { | |
| 667 return isolate->heap()->exception(); | |
| 668 } | |
| 669 } | |
| 670 | |
| 671 return ApplyHelper(isolate, Handle<JSReceiver>::cast(fun), receiver, | |
| 672 arguments, 0, length, false); | |
| 673 } | |
| 674 | |
| 675 | |
| 676 RUNTIME_FUNCTION(Runtime_ApplyConstruct) { | |
| 677 HandleScope scope(isolate); | |
| 678 DCHECK(args.length() == 2); | |
| 679 CONVERT_ARG_HANDLE_CHECKED(Object, fun, 0); | |
| 680 CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 1); | |
| 681 | |
| 682 if (!fun->IsJSFunction()) { | |
|
rossberg
2015/02/25 14:28:19
In a similar vein, this logic belongs into Executi
caitp (gmail)
2015/02/25 14:49:08
The problem with letting Execution::New() and Exec
| |
| 683 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
| 684 isolate, fun, Execution::TryGetConstructorDelegate(isolate, fun)); | |
| 685 } | |
| 686 | |
| 687 int32_t length = 0; | |
| 688 if (!GetObjectLength(isolate, arguments, &length)) { | |
| 689 if (isolate->has_pending_exception()) { | |
| 690 return isolate->heap()->exception(); | |
| 691 } | |
| 692 } | |
| 693 | |
| 694 return ApplyHelper(isolate, Handle<JSReceiver>::cast(fun), fun, arguments, 0, | |
| 695 length, true); | |
| 696 } | |
| 697 | |
| 698 | |
| 615 RUNTIME_FUNCTION(Runtime_GetFunctionDelegate) { | 699 RUNTIME_FUNCTION(Runtime_GetFunctionDelegate) { |
| 616 HandleScope scope(isolate); | 700 HandleScope scope(isolate); |
| 617 DCHECK(args.length() == 1); | 701 DCHECK(args.length() == 1); |
| 618 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); | 702 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); |
| 619 RUNTIME_ASSERT(!object->IsJSFunction()); | 703 RUNTIME_ASSERT(!object->IsJSFunction()); |
| 620 return *Execution::GetFunctionDelegate(isolate, object); | 704 return *Execution::GetFunctionDelegate(isolate, object); |
| 621 } | 705 } |
| 622 | 706 |
| 623 | 707 |
| 624 RUNTIME_FUNCTION(Runtime_GetConstructorDelegate) { | 708 RUNTIME_FUNCTION(Runtime_GetConstructorDelegate) { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 646 | 730 |
| 647 | 731 |
| 648 RUNTIME_FUNCTION(RuntimeReference_IsFunction) { | 732 RUNTIME_FUNCTION(RuntimeReference_IsFunction) { |
| 649 SealHandleScope shs(isolate); | 733 SealHandleScope shs(isolate); |
| 650 DCHECK(args.length() == 1); | 734 DCHECK(args.length() == 1); |
| 651 CONVERT_ARG_CHECKED(Object, obj, 0); | 735 CONVERT_ARG_CHECKED(Object, obj, 0); |
| 652 return isolate->heap()->ToBoolean(obj->IsJSFunction()); | 736 return isolate->heap()->ToBoolean(obj->IsJSFunction()); |
| 653 } | 737 } |
| 654 } | 738 } |
| 655 } // namespace v8::internal | 739 } // namespace v8::internal |
| OLD | NEW |