Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(112)

Side by Side Diff: src/builtins.cc

Issue 1910253005: [api] Expose FunctionCallbackInfo::NewTarget (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Added a TODO Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/builtins.h ('k') | src/ia32/builtins-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/builtins.h" 5 #include "src/builtins.h"
6 6
7 #include "src/api-arguments.h" 7 #include "src/api-arguments.h"
8 #include "src/api-natives.h" 8 #include "src/api-natives.h"
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/base/once.h" 10 #include "src/base/once.h"
(...skipping 4458 matching lines...) Expand 10 before | Expand all | Expand 10 after
4469 isolate, NewTypeError(MessageTemplate::kStrictPoisonPill)); 4469 isolate, NewTypeError(MessageTemplate::kStrictPoisonPill));
4470 } 4470 }
4471 4471
4472 4472
4473 // ----------------------------------------------------------------------------- 4473 // -----------------------------------------------------------------------------
4474 // 4474 //
4475 4475
4476 4476
4477 namespace { 4477 namespace {
4478 4478
4479 template <bool is_construct>
4480 MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper( 4479 MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper(
4481 Isolate* isolate, BuiltinArguments<BuiltinExtraArguments::kTarget> args) { 4480 Isolate* isolate,
4481 BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget> args) {
4482 HandleScope scope(isolate); 4482 HandleScope scope(isolate);
4483 Handle<HeapObject> function = args.target<HeapObject>(); 4483 Handle<HeapObject> function = args.target<HeapObject>();
4484 Handle<HeapObject> new_target = args.new_target();
4485 bool is_construct = !new_target->IsUndefined();
4484 Handle<JSReceiver> receiver; 4486 Handle<JSReceiver> receiver;
4485 4487
4486 DCHECK(function->IsFunctionTemplateInfo() || 4488 DCHECK(function->IsFunctionTemplateInfo() ||
4487 Handle<JSFunction>::cast(function)->shared()->IsApiFunction()); 4489 Handle<JSFunction>::cast(function)->shared()->IsApiFunction());
4488 4490
4489 Handle<FunctionTemplateInfo> fun_data = 4491 Handle<FunctionTemplateInfo> fun_data =
4490 function->IsFunctionTemplateInfo() 4492 function->IsFunctionTemplateInfo()
4491 ? Handle<FunctionTemplateInfo>::cast(function) 4493 ? Handle<FunctionTemplateInfo>::cast(function)
4492 : handle(JSFunction::cast(*function)->shared()->get_api_func_data()); 4494 : handle(JSFunction::cast(*function)->shared()->get_api_func_data());
4493 if (is_construct) { 4495 if (is_construct) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4533 DCHECK(raw_call_data->IsCallHandlerInfo()); 4535 DCHECK(raw_call_data->IsCallHandlerInfo());
4534 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); 4536 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
4535 Object* callback_obj = call_data->callback(); 4537 Object* callback_obj = call_data->callback();
4536 v8::FunctionCallback callback = 4538 v8::FunctionCallback callback =
4537 v8::ToCData<v8::FunctionCallback>(callback_obj); 4539 v8::ToCData<v8::FunctionCallback>(callback_obj);
4538 Object* data_obj = call_data->data(); 4540 Object* data_obj = call_data->data();
4539 4541
4540 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); 4542 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver())));
4541 DCHECK(raw_holder->IsJSObject()); 4543 DCHECK(raw_holder->IsJSObject());
4542 4544
4543 FunctionCallbackArguments custom(isolate, 4545 FunctionCallbackArguments custom(isolate, data_obj, *function, raw_holder,
4544 data_obj, 4546 *new_target, &args[0] - 1,
4545 *function, 4547 args.length() - 1);
4546 raw_holder,
4547 &args[0] - 1,
4548 args.length() - 1,
4549 is_construct);
4550 4548
4551 Handle<Object> result = custom.Call(callback); 4549 Handle<Object> result = custom.Call(callback);
4552 if (result.is_null()) result = isolate->factory()->undefined_value(); 4550 if (result.is_null()) result = isolate->factory()->undefined_value();
4553 4551
4554 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 4552 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
4555 if (!is_construct || result->IsJSObject()) { 4553 if (!is_construct || result->IsJSObject()) {
4556 return scope.CloseAndEscape(result); 4554 return scope.CloseAndEscape(result);
4557 } 4555 }
4558 } 4556 }
4559 4557
4560 return scope.CloseAndEscape(receiver); 4558 return scope.CloseAndEscape(receiver);
4561 } 4559 }
4562 4560
4563 } // namespace 4561 } // namespace
4564 4562
4565 4563
4566 BUILTIN(HandleApiCall) { 4564 BUILTIN(HandleApiCall) {
4567 HandleScope scope(isolate); 4565 HandleScope scope(isolate);
4568 Handle<Object> result; 4566 Handle<Object> result;
4569 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, 4567 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
4570 HandleApiCallHelper<false>(isolate, args)); 4568 HandleApiCallHelper(isolate, args));
4571 return *result; 4569 return *result;
4572 } 4570 }
4573 4571
4574 4572
4575 BUILTIN(HandleApiCallConstruct) {
4576 HandleScope scope(isolate);
4577 Handle<Object> result;
4578 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
4579 HandleApiCallHelper<true>(isolate, args));
4580 return *result;
4581 }
4582
4583 Handle<Code> Builtins::CallFunction(ConvertReceiverMode mode, 4573 Handle<Code> Builtins::CallFunction(ConvertReceiverMode mode,
4584 TailCallMode tail_call_mode) { 4574 TailCallMode tail_call_mode) {
4585 switch (tail_call_mode) { 4575 switch (tail_call_mode) {
4586 case TailCallMode::kDisallow: 4576 case TailCallMode::kDisallow:
4587 switch (mode) { 4577 switch (mode) {
4588 case ConvertReceiverMode::kNullOrUndefined: 4578 case ConvertReceiverMode::kNullOrUndefined:
4589 return CallFunction_ReceiverIsNullOrUndefined(); 4579 return CallFunction_ReceiverIsNullOrUndefined();
4590 case ConvertReceiverMode::kNotNullOrUndefined: 4580 case ConvertReceiverMode::kNotNullOrUndefined:
4591 return CallFunction_ReceiverIsNotNullOrUndefined(); 4581 return CallFunction_ReceiverIsNotNullOrUndefined();
4592 case ConvertReceiverMode::kAny: 4582 case ConvertReceiverMode::kAny:
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
4654 case TailCallMode::kAllow: 4644 case TailCallMode::kAllow:
4655 return InterpreterPushArgsAndTailCall(); 4645 return InterpreterPushArgsAndTailCall();
4656 } 4646 }
4657 UNREACHABLE(); 4647 UNREACHABLE();
4658 return Handle<Code>::null(); 4648 return Handle<Code>::null();
4659 } 4649 }
4660 4650
4661 namespace { 4651 namespace {
4662 4652
4663 class RelocatableArguments 4653 class RelocatableArguments
4664 : public BuiltinArguments<BuiltinExtraArguments::kTarget>, 4654 : public BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget>,
4665 public Relocatable { 4655 public Relocatable {
4666 public: 4656 public:
4667 RelocatableArguments(Isolate* isolate, int length, Object** arguments) 4657 RelocatableArguments(Isolate* isolate, int length, Object** arguments)
4668 : BuiltinArguments<BuiltinExtraArguments::kTarget>(length, arguments), 4658 : BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget>(length,
4659 arguments),
4669 Relocatable(isolate) {} 4660 Relocatable(isolate) {}
4670 4661
4671 virtual inline void IterateInstance(ObjectVisitor* v) { 4662 virtual inline void IterateInstance(ObjectVisitor* v) {
4672 if (length() == 0) return; 4663 if (length() == 0) return;
4673 v->VisitPointers(lowest_address(), highest_address() + 1); 4664 v->VisitPointers(lowest_address(), highest_address() + 1);
4674 } 4665 }
4675 4666
4676 private: 4667 private:
4677 DISALLOW_COPY_AND_ASSIGN(RelocatableArguments); 4668 DISALLOW_COPY_AND_ASSIGN(RelocatableArguments);
4678 }; 4669 };
(...skipping 11 matching lines...) Expand all
4690 if (function->IsFunctionTemplateInfo() || 4681 if (function->IsFunctionTemplateInfo() ||
4691 is_sloppy(JSFunction::cast(*function)->shared()->language_mode())) { 4682 is_sloppy(JSFunction::cast(*function)->shared()->language_mode())) {
4692 if (receiver->IsUndefined() || receiver->IsNull()) { 4683 if (receiver->IsUndefined() || receiver->IsNull()) {
4693 receiver = handle(isolate->global_proxy(), isolate); 4684 receiver = handle(isolate->global_proxy(), isolate);
4694 } else { 4685 } else {
4695 ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver, 4686 ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
4696 Object::ToObject(isolate, receiver), Object); 4687 Object::ToObject(isolate, receiver), Object);
4697 } 4688 }
4698 } 4689 }
4699 } 4690 }
4700 // Construct BuiltinArguments object: function, arguments reversed, receiver. 4691 // Construct BuiltinArguments object:
4692 // new target, function, arguments reversed, receiver.
4701 const int kBufferSize = 32; 4693 const int kBufferSize = 32;
4702 Object* small_argv[kBufferSize]; 4694 Object* small_argv[kBufferSize];
4703 Object** argv; 4695 Object** argv;
4704 if (argc + 2 <= kBufferSize) { 4696 if (argc + 3 <= kBufferSize) {
4705 argv = small_argv; 4697 argv = small_argv;
4706 } else { 4698 } else {
4707 argv = new Object* [argc + 2]; 4699 argv = new Object*[argc + 3];
4708 } 4700 }
4709 argv[argc + 1] = *receiver; 4701 argv[argc + 2] = *receiver;
4710 for (int i = 0; i < argc; ++i) { 4702 for (int i = 0; i < argc; ++i) {
4711 argv[argc - i] = *args[i]; 4703 argv[argc - i + 1] = *args[i];
4712 } 4704 }
4713 argv[0] = *function; 4705 argv[1] = *function;
4706 argv[0] = isolate->heap()->undefined_value(); // new target
4714 MaybeHandle<Object> result; 4707 MaybeHandle<Object> result;
4715 { 4708 {
4716 RelocatableArguments arguments(isolate, argc + 2, &argv[argc + 1]); 4709 RelocatableArguments arguments(isolate, argc + 3, &argv[argc] + 2);
4717 result = HandleApiCallHelper<false>(isolate, arguments); 4710 result = HandleApiCallHelper(isolate, arguments);
4718 } 4711 }
4719 if (argv != small_argv) { 4712 if (argv != small_argv) {
4720 delete[] argv; 4713 delete[] argv;
4721 } 4714 }
4722 return result; 4715 return result;
4723 } 4716 }
4724 4717
4725 4718
4726 // Helper function to handle calls to non-function objects created through the 4719 // Helper function to handle calls to non-function objects created through the
4727 // API. The object can be called as either a constructor (using new) or just as 4720 // API. The object can be called as either a constructor (using new) or just as
4728 // a function (without new). 4721 // a function (without new).
4729 MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( 4722 MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor(
4730 Isolate* isolate, bool is_construct_call, 4723 Isolate* isolate, bool is_construct_call,
4731 BuiltinArguments<BuiltinExtraArguments::kNone> args) { 4724 BuiltinArguments<BuiltinExtraArguments::kNone> args) {
4732 Handle<Object> receiver = args.receiver(); 4725 Handle<Object> receiver = args.receiver();
4733 4726
4734 // Get the object called. 4727 // Get the object called.
4735 JSObject* obj = JSObject::cast(*receiver); 4728 JSObject* obj = JSObject::cast(*receiver);
4736 4729
4730 // Set the new target.
4731 HeapObject* new_target;
4732 if (is_construct_call) {
4733 // TODO(adamk): This should be passed through in args instead of
4734 // being patched in here. We need to set a non-undefined value
4735 // for v8::FunctionCallbackInfo::IsConstructCall() to get the
4736 // right answer.
4737 new_target = obj;
4738 } else {
4739 new_target = isolate->heap()->undefined_value();
4740 }
4741
4737 // Get the invocation callback from the function descriptor that was 4742 // Get the invocation callback from the function descriptor that was
4738 // used to create the called object. 4743 // used to create the called object.
4739 DCHECK(obj->map()->is_callable()); 4744 DCHECK(obj->map()->is_callable());
4740 JSFunction* constructor = JSFunction::cast(obj->map()->GetConstructor()); 4745 JSFunction* constructor = JSFunction::cast(obj->map()->GetConstructor());
4741 // TODO(ishell): turn this back to a DCHECK. 4746 // TODO(ishell): turn this back to a DCHECK.
4742 CHECK(constructor->shared()->IsApiFunction()); 4747 CHECK(constructor->shared()->IsApiFunction());
4743 Object* handler = 4748 Object* handler =
4744 constructor->shared()->get_api_func_data()->instance_call_handler(); 4749 constructor->shared()->get_api_func_data()->instance_call_handler();
4745 DCHECK(!handler->IsUndefined()); 4750 DCHECK(!handler->IsUndefined());
4746 // TODO(ishell): remove this debugging code. 4751 // TODO(ishell): remove this debugging code.
4747 CHECK(handler->IsCallHandlerInfo()); 4752 CHECK(handler->IsCallHandlerInfo());
4748 CallHandlerInfo* call_data = CallHandlerInfo::cast(handler); 4753 CallHandlerInfo* call_data = CallHandlerInfo::cast(handler);
4749 Object* callback_obj = call_data->callback(); 4754 Object* callback_obj = call_data->callback();
4750 v8::FunctionCallback callback = 4755 v8::FunctionCallback callback =
4751 v8::ToCData<v8::FunctionCallback>(callback_obj); 4756 v8::ToCData<v8::FunctionCallback>(callback_obj);
4752 4757
4753 // Get the data for the call and perform the callback. 4758 // Get the data for the call and perform the callback.
4754 Object* result; 4759 Object* result;
4755 { 4760 {
4756 HandleScope scope(isolate); 4761 HandleScope scope(isolate);
4757 LOG(isolate, ApiObjectAccess("call non-function", obj)); 4762 LOG(isolate, ApiObjectAccess("call non-function", obj));
4758 4763
4759 FunctionCallbackArguments custom(isolate, 4764 FunctionCallbackArguments custom(isolate, call_data->data(), constructor,
4760 call_data->data(), 4765 obj, new_target, &args[0] - 1,
4761 constructor, 4766 args.length() - 1);
4762 obj,
4763 &args[0] - 1,
4764 args.length() - 1,
4765 is_construct_call);
4766 Handle<Object> result_handle = custom.Call(callback); 4767 Handle<Object> result_handle = custom.Call(callback);
4767 if (result_handle.is_null()) { 4768 if (result_handle.is_null()) {
4768 result = isolate->heap()->undefined_value(); 4769 result = isolate->heap()->undefined_value();
4769 } else { 4770 } else {
4770 result = *result_handle; 4771 result = *result_handle;
4771 } 4772 }
4772 } 4773 }
4773 // Check for exceptions and return result. 4774 // Check for exceptions and return result.
4774 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); 4775 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
4775 return result; 4776 return result;
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after
5346 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) 5347 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T)
5347 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 5348 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
5348 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 5349 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
5349 #undef DEFINE_BUILTIN_ACCESSOR_C 5350 #undef DEFINE_BUILTIN_ACCESSOR_C
5350 #undef DEFINE_BUILTIN_ACCESSOR_A 5351 #undef DEFINE_BUILTIN_ACCESSOR_A
5351 #undef DEFINE_BUILTIN_ACCESSOR_T 5352 #undef DEFINE_BUILTIN_ACCESSOR_T
5352 #undef DEFINE_BUILTIN_ACCESSOR_H 5353 #undef DEFINE_BUILTIN_ACCESSOR_H
5353 5354
5354 } // namespace internal 5355 } // namespace internal
5355 } // namespace v8 5356 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins.h ('k') | src/ia32/builtins-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698