Skip to content
This repository was archived by the owner on Oct 15, 2020. It is now read-only.

Commit d4795cd

Browse files
authored
chakrashim: implement new.target support native callbacks (#450)
Using the release/1.9 new Jsrt API to support callbacks which can receive new.target.
1 parent 7206694 commit d4795cd

File tree

4 files changed

+36
-44
lines changed

4 files changed

+36
-44
lines changed

Diff for: deps/chakrashim/include/v8.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -1756,8 +1756,7 @@ class FunctionCallbackInfo {
17561756
V8_INLINE Local<Value> operator[](int i) const;
17571757
Local<Function> Callee() const { return _callee; }
17581758
Local<Object> This() const { return _thisPointer; }
1759-
// TODO(jahorto): Implement this once JSRT gains new.target support
1760-
Local<Value> NewTarget() const { return nullptr; }
1759+
Local<Value> NewTarget() const { return _newTargetPointer; }
17611760
Local<Object> Holder() const { return _holder; }
17621761
bool IsConstructCall() const { return _isConstructorCall; }
17631762
Local<Value> Data() const { return _data; }
@@ -1771,13 +1770,15 @@ class FunctionCallbackInfo {
17711770
Value** args,
17721771
int length,
17731772
Local<Object> _this,
1773+
Local<Object> _newTarget,
17741774
Local<Object> holder,
17751775
bool isConstructorCall,
17761776
Local<Value> data,
17771777
Local<Function> callee)
17781778
: _args(args),
17791779
_length(length),
17801780
_thisPointer(_this),
1781+
_newTargetPointer(_newTarget),
17811782
_holder(holder),
17821783
_isConstructorCall(isConstructorCall),
17831784
_data(data),
@@ -1789,6 +1790,7 @@ class FunctionCallbackInfo {
17891790
Value** _args;
17901791
int _length;
17911792
Local<Object> _thisPointer;
1793+
Local<Object> _newTargetPointer;
17921794
Local<Object> _holder;
17931795
bool _isConstructorCall;
17941796
Local<Value> _data;
@@ -2439,7 +2441,7 @@ class V8_EXPORT ObjectTemplate : public Template {
24392441
friend class FunctionTemplateData;
24402442
friend class Utils;
24412443

2442-
Local<Object> NewInstance(Handle<Object> prototype);
2444+
Local<Object> NewInstance(Handle<Function> constructor);
24432445
void SetConstructor(Handle<FunctionTemplate> constructor);
24442446
};
24452447

Diff for: deps/chakrashim/src/v8functiontemplate.cc

+16-17
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,10 @@ class FunctionCallbackData : public ExternalData {
7070
this->prototype.Reset(nullptr, prototype);
7171
}
7272

73-
Local<Object> NewInstance() {
73+
Local<Object> NewInstance(Handle<Function> newTarget) {
7474
Utils::EnsureObjectTemplate(&instanceTemplate);
7575
return !instanceTemplate.IsEmpty() ?
76-
instanceTemplate->NewInstance(prototype) : Local<Object>();
76+
instanceTemplate->NewInstance(newTarget) : Local<Object>();
7777
}
7878

7979
bool CheckSignature(Local<Object> thisPointer,
@@ -91,9 +91,9 @@ class FunctionCallbackData : public ExternalData {
9191

9292
static JsValueRef CHAKRA_CALLBACK FunctionInvoked(
9393
JsValueRef callee,
94-
bool isConstructCall,
9594
JsValueRef *arguments,
9695
unsigned short argumentCount, // NOLINT(runtime/int)
96+
JsNativeFunctionInfo *info,
9797
void *callbackState) {
9898
CHAKRA_VERIFY(argumentCount >= 1);
9999

@@ -110,15 +110,16 @@ class FunctionCallbackData : public ExternalData {
110110
}
111111

112112
Local<Object> thisPointer;
113-
++arguments; // skip the this argument
113+
Local<Function> newTargetPointer = info->newTargetArg;
114+
++arguments; // skip arguments[0]
114115

115-
if (isConstructCall) {
116-
thisPointer = callbackData->NewInstance();
116+
if (info->isConstructCall) {
117+
thisPointer = callbackData->NewInstance(newTargetPointer);
117118
if (thisPointer.IsEmpty()) {
118119
return JS_INVALID_REFERENCE;
119120
}
120121
} else {
121-
thisPointer = static_cast<Object*>(arguments[-1]);
122+
thisPointer = info->thisArg;
122123
}
123124

124125
if (callbackData->callback != nullptr) {
@@ -132,8 +133,9 @@ class FunctionCallbackData : public ExternalData {
132133
reinterpret_cast<Value**>(arguments),
133134
argumentCount - 1,
134135
thisPointer,
136+
newTargetPointer,
135137
holder,
136-
isConstructCall,
138+
info->isConstructCall,
137139
callbackData->data,
138140
static_cast<Function*>(callee));
139141

@@ -142,7 +144,7 @@ class FunctionCallbackData : public ExternalData {
142144

143145
// if this is a regualr function call return the result, otherwise this is
144146
// a constructor call return the new instance
145-
if (!isConstructCall) {
147+
if (!info->isConstructCall) {
146148
return *result;
147149
} else if (!result.IsEmpty()) {
148150
if (!result->IsUndefined() && !result->IsNull()) {
@@ -245,14 +247,11 @@ class FunctionTemplateData : public TemplateData {
245247

246248
JsValueRef function = nullptr;
247249
{
248-
if (!this->className.IsEmpty()) {
249-
error = JsCreateNamedFunction(*this->className,
250-
FunctionCallbackData::FunctionInvoked,
251-
funcCallbackObjectRef, &function);
252-
} else {
253-
error = JsCreateFunction(FunctionCallbackData::FunctionInvoked,
254-
funcCallbackObjectRef, &function);
255-
}
250+
error = JsCreateEnhancedFunction(
251+
FunctionCallbackData::FunctionInvoked,
252+
this->className.IsEmpty() ? JS_INVALID_REFERENCE : *this->className,
253+
funcCallbackObjectRef,
254+
&function);
256255

257256
if (error != JsNoError) {
258257
return nullptr;

Diff for: deps/chakrashim/src/v8objecttemplate.cc

+15-23
Original file line numberDiff line numberDiff line change
@@ -847,14 +847,14 @@ JsValueRef CHAKRA_CALLBACK GetSelf(
847847
}
848848

849849
MaybeLocal<Object> ObjectTemplate::NewInstance(Local<Context> context) {
850-
return NewInstance(Local<Object>());
850+
return NewInstance(Local<Function>());
851851
}
852852

853853
Local<Object> ObjectTemplate::NewInstance() {
854854
return FromMaybe(NewInstance(Local<Context>()));
855855
}
856856

857-
Local<Object> ObjectTemplate::NewInstance(Handle<Object> prototype) {
857+
Local<Object> ObjectTemplate::NewInstance(Handle<Function> constructor) {
858858
ObjectTemplateData* objectTemplateData = nullptr;
859859
if (!ExternalData::TryGet(this, &objectTemplateData)) {
860860
return Local<Object>();
@@ -869,31 +869,23 @@ Local<Object> ObjectTemplate::NewInstance(Handle<Object> prototype) {
869869
return Local<Object>();
870870
}
871871

872-
// If there was no prototype specifically provided, then try to get one from
873-
// the constructor, if it exists. It's possible that the constructor
874-
// function doesn't have a prototype to provide.
875-
if (prototype.IsEmpty()) {
872+
if (constructor.IsEmpty()) {
876873
if (!objectTemplateData->constructor.IsEmpty()) {
877-
Local<Function> function = objectTemplateData->constructor->GetFunction();
878-
879-
if (!function.IsEmpty()) {
880-
jsrt::IsolateShim* iso = jsrt::IsolateShim::GetCurrent();
881-
JsValueRef prototypeValue = nullptr;
882-
883-
if (JsGetProperty(*function,
884-
iso->GetCachedPropertyIdRef(
885-
jsrt::CachedPropertyIdRef::prototype),
886-
&prototypeValue) == JsNoError) {
887-
prototype = Local<Object>::New(prototypeValue);
888-
}
889-
}
874+
constructor = objectTemplateData->constructor->GetFunction();
890875
}
891876
}
892877

893-
if (!prototype.IsEmpty()) {
894-
if (JsSetPrototype(newInstanceRef,
895-
reinterpret_cast<JsValueRef>(*prototype)) != JsNoError) {
896-
return Local<Object>();
878+
if (!constructor.IsEmpty()) {
879+
jsrt::IsolateShim* iso = jsrt::IsolateShim::GetCurrent();
880+
JsValueRef prototypeValue = nullptr;
881+
882+
if (JsGetProperty(*constructor,
883+
iso->GetCachedPropertyIdRef(
884+
jsrt::CachedPropertyIdRef::prototype),
885+
&prototypeValue) == JsNoError) {
886+
if (JsSetPrototype(newInstanceRef, prototypeValue) != JsNoError) {
887+
return Local<Object>();
888+
}
897889
}
898890
}
899891

Diff for: test/addons/addon.status

-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ prefix addons
2222
# These tests are failing for Node-Chakracore and should eventually be fixed
2323
async-hooks-promise/test : SKIP
2424
hello-world-esm/test : SKIP
25-
new-target/test : SKIP
2625
callback-scope/test : SKIP
2726
callback-scope/test-resolve-async : SKIP
2827

0 commit comments

Comments
 (0)