Skip to content

Commit 306c412

Browse files
ajkleinCommit bot
authored andcommitted
[api] Expose FunctionCallbackInfo::NewTarget
This is needed by Blink to implement the Custom Elements spec. BUG=v8:4261 LOG=y Review-Url: https://codereview.chromium.org/1910253005 Cr-Commit-Position: refs/heads/master@{#35833}
1 parent 5a54000 commit 306c412

18 files changed

+168
-160
lines changed

include/v8.h

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3192,12 +3192,13 @@ class FunctionCallbackInfo {
31923192
Local<Function> Callee() const);
31933193
V8_INLINE Local<Object> This() const;
31943194
V8_INLINE Local<Object> Holder() const;
3195+
V8_INLINE Local<Value> NewTarget() const;
31953196
V8_INLINE bool IsConstructCall() const;
31963197
V8_INLINE Local<Value> Data() const;
31973198
V8_INLINE Isolate* GetIsolate() const;
31983199
V8_INLINE ReturnValue<T> GetReturnValue() const;
31993200
// This shouldn't be public, but the arm compiler needs it.
3200-
static const int kArgsLength = 7;
3201+
static const int kArgsLength = 8;
32013202

32023203
protected:
32033204
friend class internal::FunctionCallbackArguments;
@@ -3209,15 +3210,13 @@ class FunctionCallbackInfo {
32093210
static const int kDataIndex = 4;
32103211
static const int kCalleeIndex = 5;
32113212
static const int kContextSaveIndex = 6;
3213+
static const int kNewTargetIndex = 7;
32123214

32133215
V8_INLINE FunctionCallbackInfo(internal::Object** implicit_args,
3214-
internal::Object** values,
3215-
int length,
3216-
bool is_construct_call);
3216+
internal::Object** values, int length);
32173217
internal::Object** implicit_args_;
32183218
internal::Object** values_;
32193219
int length_;
3220-
int is_construct_call_;
32213220
};
32223221

32233222

@@ -7870,17 +7869,11 @@ internal::Object* ReturnValue<T>::GetDefaultValue() {
78707869
return value_[-1];
78717870
}
78727871

7873-
7874-
template<typename T>
7872+
template <typename T>
78757873
FunctionCallbackInfo<T>::FunctionCallbackInfo(internal::Object** implicit_args,
78767874
internal::Object** values,
7877-
int length,
7878-
bool is_construct_call)
7879-
: implicit_args_(implicit_args),
7880-
values_(values),
7881-
length_(length),
7882-
is_construct_call_(is_construct_call) { }
7883-
7875+
int length)
7876+
: implicit_args_(implicit_args), values_(values), length_(length) {}
78847877

78857878
template<typename T>
78867879
Local<Value> FunctionCallbackInfo<T>::operator[](int i) const {
@@ -7908,8 +7901,13 @@ Local<Object> FunctionCallbackInfo<T>::Holder() const {
79087901
&implicit_args_[kHolderIndex]));
79097902
}
79107903

7904+
template <typename T>
7905+
Local<Value> FunctionCallbackInfo<T>::NewTarget() const {
7906+
return Local<Value>(
7907+
reinterpret_cast<Value*>(&implicit_args_[kNewTargetIndex]));
7908+
}
79117909

7912-
template<typename T>
7910+
template <typename T>
79137911
Local<Value> FunctionCallbackInfo<T>::Data() const {
79147912
return Local<Value>(reinterpret_cast<Value*>(&implicit_args_[kDataIndex]));
79157913
}
@@ -7929,7 +7927,7 @@ ReturnValue<T> FunctionCallbackInfo<T>::GetReturnValue() const {
79297927

79307928
template<typename T>
79317929
bool FunctionCallbackInfo<T>::IsConstructCall() const {
7932-
return is_construct_call_ & 0x1;
7930+
return !NewTarget()->IsUndefined();
79337931
}
79347932

79357933

src/api-arguments.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ Handle<Object> FunctionCallbackArguments::Call(FunctionCallback f) {
1111
Isolate* isolate = this->isolate();
1212
VMState<EXTERNAL> state(isolate);
1313
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f));
14-
FunctionCallbackInfo<v8::Value> info(begin(), argv_, argc_,
15-
is_construct_call_);
14+
FunctionCallbackInfo<v8::Value> info(begin(), argv_, argc_);
1615
f(info);
1716
return GetReturnValue<Object>(isolate);
1817
}

src/api-arguments.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -206,19 +206,19 @@ class FunctionCallbackArguments
206206
static const int kIsolateIndex = T::kIsolateIndex;
207207
static const int kCalleeIndex = T::kCalleeIndex;
208208
static const int kContextSaveIndex = T::kContextSaveIndex;
209+
static const int kNewTargetIndex = T::kNewTargetIndex;
209210

210211
FunctionCallbackArguments(internal::Isolate* isolate, internal::Object* data,
211212
internal::HeapObject* callee,
212-
internal::Object* holder, internal::Object** argv,
213-
int argc, bool is_construct_call)
214-
: Super(isolate),
215-
argv_(argv),
216-
argc_(argc),
217-
is_construct_call_(is_construct_call) {
213+
internal::Object* holder,
214+
internal::HeapObject* new_target,
215+
internal::Object** argv, int argc)
216+
: Super(isolate), argv_(argv), argc_(argc) {
218217
Object** values = begin();
219218
values[T::kDataIndex] = data;
220219
values[T::kCalleeIndex] = callee;
221220
values[T::kHolderIndex] = holder;
221+
values[T::kNewTargetIndex] = new_target;
222222
values[T::kContextSaveIndex] = isolate->heap()->the_hole_value();
223223
values[T::kIsolateIndex] = reinterpret_cast<internal::Object*>(isolate);
224224
// Here the hole is set as default value.
@@ -245,7 +245,6 @@ class FunctionCallbackArguments
245245
private:
246246
internal::Object** argv_;
247247
int argc_;
248-
bool is_construct_call_;
249248
};
250249

251250
} // namespace internal

src/arm/builtins-arm.cc

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -604,16 +604,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
604604
// r0: number of arguments
605605
// r1: constructor function
606606
// r3: new target
607-
if (is_api_function) {
608-
__ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
609-
Handle<Code> code =
610-
masm->isolate()->builtins()->HandleApiCallConstruct();
611-
__ Call(code, RelocInfo::CODE_TARGET);
612-
} else {
613-
ParameterCount actual(r0);
614-
__ InvokeFunction(r1, r3, actual, CALL_FUNCTION,
615-
CheckDebugStepCallWrapper());
616-
}
607+
ParameterCount actual(r0);
608+
__ InvokeFunction(r1, r3, actual, CALL_FUNCTION,
609+
CheckDebugStepCallWrapper());
617610

618611
// Store offset of return address for deoptimizer.
619612
if (create_implicit_receiver && !is_api_function) {

src/arm/code-stubs-arm.cc

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5428,7 +5428,11 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
54285428
STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
54295429
STATIC_ASSERT(FCA::kIsolateIndex == 1);
54305430
STATIC_ASSERT(FCA::kHolderIndex == 0);
5431-
STATIC_ASSERT(FCA::kArgsLength == 7);
5431+
STATIC_ASSERT(FCA::kNewTargetIndex == 7);
5432+
STATIC_ASSERT(FCA::kArgsLength == 8);
5433+
5434+
// new target
5435+
__ PushRoot(Heap::kUndefinedValueRootIndex);
54325436

54335437
// context save
54345438
__ push(context);
@@ -5462,7 +5466,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
54625466

54635467
// Allocate the v8::Arguments structure in the arguments' space since
54645468
// it's not controlled by GC.
5465-
const int kApiStackSpace = 4;
5469+
const int kApiStackSpace = 3;
54665470

54675471
FrameScope frame_scope(masm, StackFrame::MANUAL);
54685472
__ EnterExitFrame(false, kApiStackSpace);
@@ -5479,9 +5483,6 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
54795483
// FunctionCallbackInfo::length_ = argc
54805484
__ mov(ip, Operand(argc()));
54815485
__ str(ip, MemOperand(r0, 2 * kPointerSize));
5482-
// FunctionCallbackInfo::is_construct_call_ = 0
5483-
__ mov(ip, Operand::Zero());
5484-
__ str(ip, MemOperand(r0, 3 * kPointerSize));
54855486

54865487
ExternalReference thunk_ref =
54875488
ExternalReference::invoke_function_callback(masm->isolate());
@@ -5498,8 +5499,8 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
54985499
}
54995500
MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
55005501
int stack_space = 0;
5501-
MemOperand is_construct_call_operand = MemOperand(sp, 4 * kPointerSize);
5502-
MemOperand* stack_space_operand = &is_construct_call_operand;
5502+
MemOperand length_operand = MemOperand(sp, 3 * kPointerSize);
5503+
MemOperand* stack_space_operand = &length_operand;
55035504
stack_space = argc() + FCA::kArgsLength + 1;
55045505
stack_space_operand = NULL;
55055506

src/arm64/builtins-arm64.cc

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -605,16 +605,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
605605
// x0: number of arguments
606606
// x1: constructor function
607607
// x3: new target
608-
if (is_api_function) {
609-
__ Ldr(cp, FieldMemOperand(constructor, JSFunction::kContextOffset));
610-
Handle<Code> code =
611-
masm->isolate()->builtins()->HandleApiCallConstruct();
612-
__ Call(code, RelocInfo::CODE_TARGET);
613-
} else {
614-
ParameterCount actual(argc);
615-
__ InvokeFunction(constructor, new_target, actual, CALL_FUNCTION,
616-
CheckDebugStepCallWrapper());
617-
}
608+
ParameterCount actual(argc);
609+
__ InvokeFunction(constructor, new_target, actual, CALL_FUNCTION,
610+
CheckDebugStepCallWrapper());
618611

619612
// Store offset of return address for deoptimizer.
620613
if (create_implicit_receiver && !is_api_function) {

src/arm64/code-stubs-arm64.cc

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5812,9 +5812,15 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
58125812
STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
58135813
STATIC_ASSERT(FCA::kIsolateIndex == 1);
58145814
STATIC_ASSERT(FCA::kHolderIndex == 0);
5815-
STATIC_ASSERT(FCA::kArgsLength == 7);
5815+
STATIC_ASSERT(FCA::kNewTargetIndex == 7);
5816+
STATIC_ASSERT(FCA::kArgsLength == 8);
58165817

5817-
// FunctionCallbackArguments: context, callee and call data.
5818+
// FunctionCallbackArguments
5819+
5820+
// new target
5821+
__ PushRoot(Heap::kUndefinedValueRootIndex);
5822+
5823+
// context, callee and call data.
58185824
__ Push(context, callee, call_data);
58195825

58205826
if (!is_lazy()) {
@@ -5838,7 +5844,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
58385844

58395845
// Allocate the v8::Arguments structure in the arguments' space, since it's
58405846
// not controlled by GC.
5841-
const int kApiStackSpace = 4;
5847+
const int kApiStackSpace = 3;
58425848

58435849
// Allocate space for CallApiFunctionAndReturn can store some scratch
58445850
// registeres on the stack.
@@ -5854,10 +5860,9 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
58545860
// FunctionCallbackInfo::implicit_args_ and FunctionCallbackInfo::values_
58555861
__ Add(x10, args, Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize));
58565862
__ Stp(args, x10, MemOperand(x0, 0 * kPointerSize));
5857-
// FunctionCallbackInfo::length_ = argc and
5858-
// FunctionCallbackInfo::is_construct_call = 0
5863+
// FunctionCallbackInfo::length_ = argc
58595864
__ Mov(x10, argc());
5860-
__ Stp(x10, xzr, MemOperand(x0, 2 * kPointerSize));
5865+
__ Str(x10, MemOperand(x0, 2 * kPointerSize));
58615866

58625867
ExternalReference thunk_ref =
58635868
ExternalReference::invoke_function_callback(masm->isolate());
@@ -5874,9 +5879,9 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
58745879
}
58755880
MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
58765881
int stack_space = 0;
5877-
MemOperand is_construct_call_operand =
5878-
MemOperand(masm->StackPointer(), 4 * kPointerSize);
5879-
MemOperand* stack_space_operand = &is_construct_call_operand;
5882+
MemOperand length_operand =
5883+
MemOperand(masm->StackPointer(), 3 * kPointerSize);
5884+
MemOperand* stack_space_operand = &length_operand;
58805885
stack_space = argc() + FCA::kArgsLength + 1;
58815886
stack_space_operand = NULL;
58825887

src/builtins.cc

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4525,11 +4525,13 @@ BUILTIN(RestrictedStrictArgumentsPropertiesThrower) {
45254525

45264526
namespace {
45274527

4528-
template <bool is_construct>
45294528
MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper(
4530-
Isolate* isolate, BuiltinArguments<BuiltinExtraArguments::kTarget> args) {
4529+
Isolate* isolate,
4530+
BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget> args) {
45314531
HandleScope scope(isolate);
45324532
Handle<HeapObject> function = args.target<HeapObject>();
4533+
Handle<HeapObject> new_target = args.new_target();
4534+
bool is_construct = !new_target->IsUndefined();
45334535
Handle<JSReceiver> receiver;
45344536

45354537
DCHECK(function->IsFunctionTemplateInfo() ||
@@ -4589,13 +4591,9 @@ MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper(
45894591
LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver())));
45904592
DCHECK(raw_holder->IsJSObject());
45914593

4592-
FunctionCallbackArguments custom(isolate,
4593-
data_obj,
4594-
*function,
4595-
raw_holder,
4596-
&args[0] - 1,
4597-
args.length() - 1,
4598-
is_construct);
4594+
FunctionCallbackArguments custom(isolate, data_obj, *function, raw_holder,
4595+
*new_target, &args[0] - 1,
4596+
args.length() - 1);
45994597

46004598
Handle<Object> result = custom.Call(callback);
46014599
if (result.is_null()) result = isolate->factory()->undefined_value();
@@ -4616,19 +4614,11 @@ BUILTIN(HandleApiCall) {
46164614
HandleScope scope(isolate);
46174615
Handle<Object> result;
46184616
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
4619-
HandleApiCallHelper<false>(isolate, args));
4617+
HandleApiCallHelper(isolate, args));
46204618
return *result;
46214619
}
46224620

46234621

4624-
BUILTIN(HandleApiCallConstruct) {
4625-
HandleScope scope(isolate);
4626-
Handle<Object> result;
4627-
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
4628-
HandleApiCallHelper<true>(isolate, args));
4629-
return *result;
4630-
}
4631-
46324622
Handle<Code> Builtins::CallFunction(ConvertReceiverMode mode,
46334623
TailCallMode tail_call_mode) {
46344624
switch (tail_call_mode) {
@@ -4710,11 +4700,12 @@ Handle<Code> Builtins::InterpreterPushArgsAndCall(TailCallMode tail_call_mode) {
47104700
namespace {
47114701

47124702
class RelocatableArguments
4713-
: public BuiltinArguments<BuiltinExtraArguments::kTarget>,
4703+
: public BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget>,
47144704
public Relocatable {
47154705
public:
47164706
RelocatableArguments(Isolate* isolate, int length, Object** arguments)
4717-
: BuiltinArguments<BuiltinExtraArguments::kTarget>(length, arguments),
4707+
: BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget>(length,
4708+
arguments),
47184709
Relocatable(isolate) {}
47194710

47204711
virtual inline void IterateInstance(ObjectVisitor* v) {
@@ -4746,24 +4737,26 @@ MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<HeapObject> function,
47464737
}
47474738
}
47484739
}
4749-
// Construct BuiltinArguments object: function, arguments reversed, receiver.
4740+
// Construct BuiltinArguments object:
4741+
// new target, function, arguments reversed, receiver.
47504742
const int kBufferSize = 32;
47514743
Object* small_argv[kBufferSize];
47524744
Object** argv;
4753-
if (argc + 2 <= kBufferSize) {
4745+
if (argc + 3 <= kBufferSize) {
47544746
argv = small_argv;
47554747
} else {
4756-
argv = new Object* [argc + 2];
4748+
argv = new Object*[argc + 3];
47574749
}
4758-
argv[argc + 1] = *receiver;
4750+
argv[argc + 2] = *receiver;
47594751
for (int i = 0; i < argc; ++i) {
4760-
argv[argc - i] = *args[i];
4752+
argv[argc - i + 1] = *args[i];
47614753
}
4762-
argv[0] = *function;
4754+
argv[1] = *function;
4755+
argv[0] = isolate->heap()->undefined_value(); // new target
47634756
MaybeHandle<Object> result;
47644757
{
4765-
RelocatableArguments arguments(isolate, argc + 2, &argv[argc + 1]);
4766-
result = HandleApiCallHelper<false>(isolate, arguments);
4758+
RelocatableArguments arguments(isolate, argc + 3, &argv[argc] + 2);
4759+
result = HandleApiCallHelper(isolate, arguments);
47674760
}
47684761
if (argv != small_argv) {
47694762
delete[] argv;
@@ -4783,6 +4776,18 @@ MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor(
47834776
// Get the object called.
47844777
JSObject* obj = JSObject::cast(*receiver);
47854778

4779+
// Set the new target.
4780+
HeapObject* new_target;
4781+
if (is_construct_call) {
4782+
// TODO(adamk): This should be passed through in args instead of
4783+
// being patched in here. We need to set a non-undefined value
4784+
// for v8::FunctionCallbackInfo::IsConstructCall() to get the
4785+
// right answer.
4786+
new_target = obj;
4787+
} else {
4788+
new_target = isolate->heap()->undefined_value();
4789+
}
4790+
47864791
// Get the invocation callback from the function descriptor that was
47874792
// used to create the called object.
47884793
DCHECK(obj->map()->is_callable());
@@ -4805,13 +4810,9 @@ MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor(
48054810
HandleScope scope(isolate);
48064811
LOG(isolate, ApiObjectAccess("call non-function", obj));
48074812

4808-
FunctionCallbackArguments custom(isolate,
4809-
call_data->data(),
4810-
constructor,
4811-
obj,
4812-
&args[0] - 1,
4813-
args.length() - 1,
4814-
is_construct_call);
4813+
FunctionCallbackArguments custom(isolate, call_data->data(), constructor,
4814+
obj, new_target, &args[0] - 1,
4815+
args.length() - 1);
48154816
Handle<Object> result_handle = custom.Call(callback);
48164817
if (result_handle.is_null()) {
48174818
result = isolate->heap()->undefined_value();

0 commit comments

Comments
 (0)