Chromium Code Reviews| 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 |