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 |