Chromium Code Reviews| Index: src/builtins.cc |
| diff --git a/src/builtins.cc b/src/builtins.cc |
| index d910c01101d3879a015f211492d66a4dc1e8af3f..c69c588bfd4e4af4e7e6174a67456e8ca78c1f69 100644 |
| --- a/src/builtins.cc |
| +++ b/src/builtins.cc |
| @@ -4476,11 +4476,13 @@ BUILTIN(RestrictedStrictArgumentsPropertiesThrower) { |
| namespace { |
| -template <bool is_construct> |
| MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper( |
| - Isolate* isolate, BuiltinArguments<BuiltinExtraArguments::kTarget> args) { |
| + Isolate* isolate, |
| + BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget> args) { |
| HandleScope scope(isolate); |
| Handle<HeapObject> function = args.target<HeapObject>(); |
| + Handle<HeapObject> new_target = args.new_target(); |
| + bool is_construct = !new_target->IsUndefined(); |
| Handle<JSReceiver> receiver; |
| DCHECK(function->IsFunctionTemplateInfo() || |
| @@ -4540,13 +4542,9 @@ MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper( |
| LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); |
| DCHECK(raw_holder->IsJSObject()); |
| - FunctionCallbackArguments custom(isolate, |
| - data_obj, |
| - *function, |
| - raw_holder, |
| - &args[0] - 1, |
| - args.length() - 1, |
| - is_construct); |
| + FunctionCallbackArguments custom(isolate, data_obj, *function, raw_holder, |
| + *new_target, &args[0] - 1, |
| + args.length() - 1); |
| Handle<Object> result = custom.Call(callback); |
| if (result.is_null()) result = isolate->factory()->undefined_value(); |
| @@ -4567,19 +4565,11 @@ BUILTIN(HandleApiCall) { |
| HandleScope scope(isolate); |
| Handle<Object> result; |
| ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| - HandleApiCallHelper<false>(isolate, args)); |
| + HandleApiCallHelper(isolate, args)); |
| return *result; |
| } |
| -BUILTIN(HandleApiCallConstruct) { |
| - HandleScope scope(isolate); |
| - Handle<Object> result; |
| - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| - HandleApiCallHelper<true>(isolate, args)); |
| - return *result; |
| -} |
| - |
| Handle<Code> Builtins::CallFunction(ConvertReceiverMode mode, |
| TailCallMode tail_call_mode) { |
| switch (tail_call_mode) { |
| @@ -4661,11 +4651,12 @@ Handle<Code> Builtins::InterpreterPushArgsAndCall(TailCallMode tail_call_mode) { |
| namespace { |
| class RelocatableArguments |
| - : public BuiltinArguments<BuiltinExtraArguments::kTarget>, |
| + : public BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget>, |
| public Relocatable { |
| public: |
| RelocatableArguments(Isolate* isolate, int length, Object** arguments) |
| - : BuiltinArguments<BuiltinExtraArguments::kTarget>(length, arguments), |
| + : BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget>(length, |
| + arguments), |
| Relocatable(isolate) {} |
| virtual inline void IterateInstance(ObjectVisitor* v) { |
| @@ -4697,24 +4688,26 @@ MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<HeapObject> function, |
| } |
| } |
| } |
| - // Construct BuiltinArguments object: function, arguments reversed, receiver. |
| + // Construct BuiltinArguments object: |
| + // new target, function, arguments reversed, receiver. |
| const int kBufferSize = 32; |
| Object* small_argv[kBufferSize]; |
| Object** argv; |
| - if (argc + 2 <= kBufferSize) { |
| + if (argc + 3 <= kBufferSize) { |
| argv = small_argv; |
| } else { |
| - argv = new Object* [argc + 2]; |
| + argv = new Object*[argc + 3]; |
| } |
| - argv[argc + 1] = *receiver; |
| + argv[argc + 2] = *receiver; |
| for (int i = 0; i < argc; ++i) { |
| - argv[argc - i] = *args[i]; |
| + argv[argc - i + 1] = *args[i]; |
| } |
| - argv[0] = *function; |
| + argv[1] = *function; |
| + argv[0] = isolate->heap()->undefined_value(); // new target |
| MaybeHandle<Object> result; |
| { |
| - RelocatableArguments arguments(isolate, argc + 2, &argv[argc + 1]); |
| - result = HandleApiCallHelper<false>(isolate, arguments); |
| + RelocatableArguments arguments(isolate, argc + 3, &argv[argc] + 2); |
| + result = HandleApiCallHelper(isolate, arguments); |
| } |
| if (argv != small_argv) { |
| delete[] argv; |
| @@ -4734,6 +4727,15 @@ MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( |
| // Get the object called. |
| JSObject* obj = JSObject::cast(*receiver); |
| + // Set the new target. |
| + HeapObject* new_target; |
|
Benedikt Meurer
2016/04/26 04:21:34
You don't need to make up a new.target here. Just
adamk
2016/04/26 18:17:14
Simply adding kNewTarget in builtins.h doesn't see
Benedikt Meurer
2016/04/26 18:28:40
Ah you're right. It's because we call... Meh, can
adamk
2016/04/26 18:34:35
Added a TODO.
|
| + if (is_construct_call) { |
| + new_target = obj; |
| + } else { |
| + new_target = isolate->heap()->undefined_value(); |
| + } |
| + // DCHECK(is_construct_call && new_target->map()->is_constructor()); |
| + |
| // Get the invocation callback from the function descriptor that was |
| // used to create the called object. |
| DCHECK(obj->map()->is_callable()); |
| @@ -4756,13 +4758,9 @@ MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( |
| HandleScope scope(isolate); |
| LOG(isolate, ApiObjectAccess("call non-function", obj)); |
| - FunctionCallbackArguments custom(isolate, |
| - call_data->data(), |
| - constructor, |
| - obj, |
| - &args[0] - 1, |
| - args.length() - 1, |
| - is_construct_call); |
| + FunctionCallbackArguments custom(isolate, call_data->data(), constructor, |
| + obj, new_target, &args[0] - 1, |
| + args.length() - 1); |
| Handle<Object> result_handle = custom.Call(callback); |
| if (result_handle.is_null()) { |
| result = isolate->heap()->undefined_value(); |