OLD | NEW |
---|---|
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 4460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4471 | 4471 |
4472 | 4472 |
4473 // ----------------------------------------------------------------------------- | 4473 // ----------------------------------------------------------------------------- |
4474 // | 4474 // |
4475 | 4475 |
4476 | 4476 |
4477 namespace { | 4477 namespace { |
4478 | 4478 |
4479 template <bool is_construct> | 4479 template <bool is_construct> |
4480 MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper( | 4480 MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper( |
4481 Isolate* isolate, BuiltinArguments<BuiltinExtraArguments::kTarget> args) { | 4481 Isolate* isolate, BuiltinArguments<BuiltinExtraArguments::kTarget> args) { |
Benedikt Meurer
2016/04/23 11:57:47
You could change this to generally accept kTargetA
Benedikt Meurer
2016/04/23 18:21:45
Ignore the part about builtins-x64.cc, I just noti
adamk
2016/04/25 18:53:40
Can you point me at where we load undefined for th
Benedikt Meurer
2016/04/25 19:02:00
Sure, it's part of the invoke function sequence, s
adamk
2016/04/25 22:59:55
Done.
| |
4482 HandleScope scope(isolate); | 4482 HandleScope scope(isolate); |
4483 Handle<HeapObject> function = args.target<HeapObject>(); | 4483 Handle<HeapObject> function = args.target<HeapObject>(); |
4484 Handle<JSReceiver> receiver; | 4484 Handle<JSReceiver> receiver; |
4485 | 4485 |
4486 DCHECK(function->IsFunctionTemplateInfo() || | 4486 DCHECK(function->IsFunctionTemplateInfo() || |
4487 Handle<JSFunction>::cast(function)->shared()->IsApiFunction()); | 4487 Handle<JSFunction>::cast(function)->shared()->IsApiFunction()); |
4488 | 4488 |
4489 Handle<FunctionTemplateInfo> fun_data = | 4489 Handle<FunctionTemplateInfo> fun_data = |
4490 function->IsFunctionTemplateInfo() | 4490 function->IsFunctionTemplateInfo() |
4491 ? Handle<FunctionTemplateInfo>::cast(function) | 4491 ? Handle<FunctionTemplateInfo>::cast(function) |
4492 : handle(JSFunction::cast(*function)->shared()->get_api_func_data()); | 4492 : handle(JSFunction::cast(*function)->shared()->get_api_func_data()); |
4493 if (is_construct) { | 4493 if (is_construct) { |
4494 DCHECK(args.receiver()->IsTheHole()); | 4494 DCHECK(args.receiver()->IsTheHole()); |
Benedikt Meurer
2016/04/23 11:57:47
I wonder if we could unify this with the general i
| |
4495 if (fun_data->instance_template()->IsUndefined()) { | 4495 if (fun_data->instance_template()->IsUndefined()) { |
4496 v8::Local<ObjectTemplate> templ = | 4496 v8::Local<ObjectTemplate> templ = |
4497 ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate), | 4497 ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate), |
4498 ToApiHandle<v8::FunctionTemplate>(fun_data)); | 4498 ToApiHandle<v8::FunctionTemplate>(fun_data)); |
4499 fun_data->set_instance_template(*Utils::OpenHandle(*templ)); | 4499 fun_data->set_instance_template(*Utils::OpenHandle(*templ)); |
4500 } | 4500 } |
4501 Handle<ObjectTemplateInfo> instance_template( | 4501 Handle<ObjectTemplateInfo> instance_template( |
4502 ObjectTemplateInfo::cast(fun_data->instance_template()), isolate); | 4502 ObjectTemplateInfo::cast(fun_data->instance_template()), isolate); |
4503 ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver, | 4503 ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver, |
4504 ApiNatives::InstantiateObject(instance_template), | 4504 ApiNatives::InstantiateObject(instance_template), |
(...skipping 28 matching lines...) Expand all Loading... | |
4533 DCHECK(raw_call_data->IsCallHandlerInfo()); | 4533 DCHECK(raw_call_data->IsCallHandlerInfo()); |
4534 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); | 4534 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); |
4535 Object* callback_obj = call_data->callback(); | 4535 Object* callback_obj = call_data->callback(); |
4536 v8::FunctionCallback callback = | 4536 v8::FunctionCallback callback = |
4537 v8::ToCData<v8::FunctionCallback>(callback_obj); | 4537 v8::ToCData<v8::FunctionCallback>(callback_obj); |
4538 Object* data_obj = call_data->data(); | 4538 Object* data_obj = call_data->data(); |
4539 | 4539 |
4540 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); | 4540 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); |
4541 DCHECK(raw_holder->IsJSObject()); | 4541 DCHECK(raw_holder->IsJSObject()); |
4542 | 4542 |
4543 FunctionCallbackArguments custom(isolate, | 4543 FunctionCallbackArguments custom(isolate, data_obj, *function, raw_holder, |
4544 data_obj, | 4544 isolate->heap()->undefined_value(), |
4545 *function, | 4545 &args[0] - 1, args.length() - 1, |
4546 raw_holder, | |
4547 &args[0] - 1, | |
4548 args.length() - 1, | |
4549 is_construct); | 4546 is_construct); |
4550 | 4547 |
4551 Handle<Object> result = custom.Call(callback); | 4548 Handle<Object> result = custom.Call(callback); |
4552 if (result.is_null()) result = isolate->factory()->undefined_value(); | 4549 if (result.is_null()) result = isolate->factory()->undefined_value(); |
4553 | 4550 |
4554 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 4551 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
4555 if (!is_construct || result->IsJSObject()) { | 4552 if (!is_construct || result->IsJSObject()) { |
4556 return scope.CloseAndEscape(result); | 4553 return scope.CloseAndEscape(result); |
4557 } | 4554 } |
4558 } | 4555 } |
4559 | 4556 |
4560 return scope.CloseAndEscape(receiver); | 4557 return scope.CloseAndEscape(receiver); |
4561 } | 4558 } |
4562 | 4559 |
4563 } // namespace | 4560 } // namespace |
4564 | 4561 |
4565 | 4562 |
4566 BUILTIN(HandleApiCall) { | 4563 BUILTIN(HandleApiCall) { |
4567 HandleScope scope(isolate); | 4564 HandleScope scope(isolate); |
4568 Handle<Object> result; | 4565 Handle<Object> result; |
4569 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 4566 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
4570 HandleApiCallHelper<false>(isolate, args)); | 4567 HandleApiCallHelper<false>(isolate, args)); |
4571 return *result; | 4568 return *result; |
4572 } | 4569 } |
4573 | 4570 |
4574 | 4571 |
4575 BUILTIN(HandleApiCallConstruct) { | 4572 BUILTIN(HandleApiCallConstruct) { |
4576 HandleScope scope(isolate); | 4573 HandleScope scope(isolate); |
4577 Handle<Object> result; | 4574 Handle<HeapObject> function = args.target<HeapObject>(); |
4578 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 4575 Handle<HeapObject> new_target = args.new_target(); |
4579 HandleApiCallHelper<true>(isolate, args)); | 4576 Handle<JSReceiver> receiver; |
4580 return *result; | 4577 |
4578 DCHECK(function->IsFunctionTemplateInfo() || | |
4579 Handle<JSFunction>::cast(function)->shared()->IsApiFunction()); | |
4580 | |
4581 Handle<FunctionTemplateInfo> fun_data = | |
4582 function->IsFunctionTemplateInfo() | |
4583 ? Handle<FunctionTemplateInfo>::cast(function) | |
4584 : handle(JSFunction::cast(*function)->shared()->get_api_func_data()); | |
4585 DCHECK(args.receiver()->IsTheHole()); | |
4586 if (fun_data->instance_template()->IsUndefined()) { | |
4587 v8::Local<ObjectTemplate> templ = | |
4588 ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate), | |
4589 ToApiHandle<v8::FunctionTemplate>(fun_data)); | |
4590 fun_data->set_instance_template(*Utils::OpenHandle(*templ)); | |
4591 } | |
4592 Handle<ObjectTemplateInfo> instance_template( | |
4593 ObjectTemplateInfo::cast(fun_data->instance_template()), isolate); | |
4594 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
4595 isolate, receiver, ApiNatives::InstantiateObject(instance_template)); | |
4596 args[0] = *receiver; | |
4597 DCHECK_EQ(*receiver, *args.receiver()); | |
4598 | |
4599 Object* raw_holder = fun_data->GetCompatibleReceiver(isolate, *receiver); | |
4600 | |
4601 if (raw_holder->IsNull()) { | |
4602 // This function cannot be called with the given receiver. Abort! | |
4603 THROW_NEW_ERROR_RETURN_FAILURE( | |
4604 isolate, NewTypeError(MessageTemplate::kIllegalInvocation)); | |
4605 } | |
4606 | |
4607 Object* raw_call_data = fun_data->call_code(); | |
4608 if (!raw_call_data->IsUndefined()) { | |
4609 DCHECK(raw_call_data->IsCallHandlerInfo()); | |
4610 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); | |
4611 Object* callback_obj = call_data->callback(); | |
4612 v8::FunctionCallback callback = | |
4613 v8::ToCData<v8::FunctionCallback>(callback_obj); | |
4614 Object* data_obj = call_data->data(); | |
4615 | |
4616 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); | |
4617 DCHECK(raw_holder->IsJSObject()); | |
4618 | |
4619 FunctionCallbackArguments custom(isolate, data_obj, *function, raw_holder, | |
4620 *new_target, &args[0] - 1, | |
4621 args.length() - 1, true); | |
4622 | |
4623 Handle<Object> result = custom.Call(callback); | |
4624 if (result.is_null()) result = isolate->factory()->undefined_value(); | |
4625 | |
4626 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | |
4627 if (result->IsJSObject()) { | |
4628 return *result; | |
4629 } | |
4630 } | |
4631 | |
4632 return *receiver; | |
4581 } | 4633 } |
4582 | 4634 |
4583 Handle<Code> Builtins::CallFunction(ConvertReceiverMode mode, | 4635 Handle<Code> Builtins::CallFunction(ConvertReceiverMode mode, |
4584 TailCallMode tail_call_mode) { | 4636 TailCallMode tail_call_mode) { |
4585 switch (tail_call_mode) { | 4637 switch (tail_call_mode) { |
4586 case TailCallMode::kDisallow: | 4638 case TailCallMode::kDisallow: |
4587 switch (mode) { | 4639 switch (mode) { |
4588 case ConvertReceiverMode::kNullOrUndefined: | 4640 case ConvertReceiverMode::kNullOrUndefined: |
4589 return CallFunction_ReceiverIsNullOrUndefined(); | 4641 return CallFunction_ReceiverIsNullOrUndefined(); |
4590 case ConvertReceiverMode::kNotNullOrUndefined: | 4642 case ConvertReceiverMode::kNotNullOrUndefined: |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4749 Object* callback_obj = call_data->callback(); | 4801 Object* callback_obj = call_data->callback(); |
4750 v8::FunctionCallback callback = | 4802 v8::FunctionCallback callback = |
4751 v8::ToCData<v8::FunctionCallback>(callback_obj); | 4803 v8::ToCData<v8::FunctionCallback>(callback_obj); |
4752 | 4804 |
4753 // Get the data for the call and perform the callback. | 4805 // Get the data for the call and perform the callback. |
4754 Object* result; | 4806 Object* result; |
4755 { | 4807 { |
4756 HandleScope scope(isolate); | 4808 HandleScope scope(isolate); |
4757 LOG(isolate, ApiObjectAccess("call non-function", obj)); | 4809 LOG(isolate, ApiObjectAccess("call non-function", obj)); |
4758 | 4810 |
4759 FunctionCallbackArguments custom(isolate, | 4811 FunctionCallbackArguments custom(isolate, call_data->data(), constructor, |
4760 call_data->data(), | 4812 obj, isolate->heap()->undefined_value(), |
4761 constructor, | 4813 &args[0] - 1, args.length() - 1, |
4762 obj, | |
4763 &args[0] - 1, | |
4764 args.length() - 1, | |
4765 is_construct_call); | 4814 is_construct_call); |
4766 Handle<Object> result_handle = custom.Call(callback); | 4815 Handle<Object> result_handle = custom.Call(callback); |
4767 if (result_handle.is_null()) { | 4816 if (result_handle.is_null()) { |
4768 result = isolate->heap()->undefined_value(); | 4817 result = isolate->heap()->undefined_value(); |
4769 } else { | 4818 } else { |
4770 result = *result_handle; | 4819 result = *result_handle; |
4771 } | 4820 } |
4772 } | 4821 } |
4773 // Check for exceptions and return result. | 4822 // Check for exceptions and return result. |
4774 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 4823 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5346 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) | 5395 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) |
5347 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 5396 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
5348 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 5397 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
5349 #undef DEFINE_BUILTIN_ACCESSOR_C | 5398 #undef DEFINE_BUILTIN_ACCESSOR_C |
5350 #undef DEFINE_BUILTIN_ACCESSOR_A | 5399 #undef DEFINE_BUILTIN_ACCESSOR_A |
5351 #undef DEFINE_BUILTIN_ACCESSOR_T | 5400 #undef DEFINE_BUILTIN_ACCESSOR_T |
5352 #undef DEFINE_BUILTIN_ACCESSOR_H | 5401 #undef DEFINE_BUILTIN_ACCESSOR_H |
5353 | 5402 |
5354 } // namespace internal | 5403 } // namespace internal |
5355 } // namespace v8 | 5404 } // namespace v8 |
OLD | NEW |