From f98a747e0e6fd669584c2d15b608b1d70e7f1e83 Mon Sep 17 00:00:00 2001 From: Sampson Gao Date: Mon, 21 Aug 2017 15:08:12 -0400 Subject: [PATCH 1/5] Replace napi_is_construct_call with napi_get_new_target --- napi-inl.h | 10 ++++++---- src/node_api.cc | 23 +++++++++++++---------- src/node_api.h | 6 +++--- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/napi-inl.h b/napi-inl.h index 45cb58fb1..18283f78d 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -2016,8 +2016,9 @@ inline CallbackInfo::~CallbackInfo() { } inline bool CallbackInfo::IsConstructCall() const { - bool isConstructCall; - napi_status status = napi_is_construct_call(_env, _info, &isConstructCall); + napi_value new_target; + napi_status status = napi_get_new_target(_env, _info, &new_target); + bool isConstructCall = (new_target != nullptr); NAPI_THROW_IF_FAILED(_env, status, false); return isConstructCall; } @@ -2470,10 +2471,11 @@ template inline napi_value ObjectWrap::ConstructorCallbackWrapper( napi_env env, napi_callback_info info) { - bool isConstructCall; - napi_status status = napi_is_construct_call(env, info, &isConstructCall); + napi_value new_target; + napi_status status = napi_get_new_target(env, info, &new_target); if (status != napi_ok) return nullptr; + bool isConstructCall = (new_target != nullptr); if (!isConstructCall) { napi_throw_type_error(env, nullptr, "Class constructors cannot be invoked without 'new'"); return nullptr; diff --git a/src/node_api.cc b/src/node_api.cc index b84a33e51..b45d148f5 100644 --- a/src/node_api.cc +++ b/src/node_api.cc @@ -438,7 +438,7 @@ class CallbackWrapper { CallbackWrapper(napi_value this_arg, size_t args_length, void* data) : _this(this_arg), _args_length(args_length), _data(data) {} - virtual bool IsConstructCall() = 0; + virtual napi_value NewTarget() = 0; virtual void Args(napi_value* buffer, size_t bufferlength) = 0; virtual void SetReturnValue(napi_value value) = 0; @@ -467,8 +467,7 @@ class CallbackWrapperBase : public CallbackWrapper { ->Value(); } - /*virtual*/ - bool IsConstructCall() override { return false; } + napi_value NewTarget() override { return nullptr; } protected: void InvokeCallback() { @@ -516,8 +515,13 @@ class FunctionCallbackWrapper const v8::FunctionCallbackInfo& cbinfo) : CallbackWrapperBase(cbinfo, cbinfo.Length()) {} - /*virtual*/ - bool IsConstructCall() override { return _cbinfo.IsConstructCall(); } + napi_value NewTarget() override { + if (_cbinfo.IsConstructCall()) { + return v8impl::JsValueFromV8LocalValue(_cbinfo.NewTarget()); + } else { + return nullptr; + } + } /*virtual*/ void Args(napi_value* buffer, size_t buffer_length) override { @@ -1810,10 +1814,9 @@ napi_status napi_get_cb_info( return napi_clear_last_error(env); } -napi_status napi_is_construct_call(napi_env env, - napi_callback_info cbinfo, - bool* result) { - // Omit NAPI_PREAMBLE and GET_RETURN_STATUS because no V8 APIs are called. +napi_status napi_get_new_target(napi_env env, + napi_callback_info cbinfo, + napi_value* result) { CHECK_ENV(env); CHECK_ARG(env, cbinfo); CHECK_ARG(env, result); @@ -1821,7 +1824,7 @@ napi_status napi_is_construct_call(napi_env env, v8impl::CallbackWrapper* info = reinterpret_cast(cbinfo); - *result = info->IsConstructCall(); + *result = info->NewTarget(); return napi_clear_last_error(env); } diff --git a/src/node_api.h b/src/node_api.h index 0cf0ba046..750fcd377 100644 --- a/src/node_api.h +++ b/src/node_api.h @@ -340,9 +340,9 @@ NAPI_EXTERN napi_status napi_get_cb_info( napi_value* this_arg, // [out] Receives the JS 'this' arg for the call void** data); // [out] Receives the data pointer for the callback. -NAPI_EXTERN napi_status napi_is_construct_call(napi_env env, - napi_callback_info cbinfo, - bool* result); +NAPI_EXTERN napi_status napi_get_new_target(napi_env env, + napi_callback_info cbinfo, + napi_value* result); NAPI_EXTERN napi_status napi_define_class(napi_env env, const char* utf8name, From f894a43c00b6b9c5e0fe578c32ea5d59bc8ba878 Mon Sep 17 00:00:00 2001 From: Sampson Gao Date: Mon, 21 Aug 2017 16:14:43 -0400 Subject: [PATCH 2/5] Add NewTarget method to CallbackInfo and change variable name to camel case --- napi-inl.h | 10 ++++++++-- napi.h | 1 + package-lock.json | 5 +++++ 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 package-lock.json diff --git a/napi-inl.h b/napi-inl.h index 18283f78d..77843bed3 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -2015,9 +2015,15 @@ inline CallbackInfo::~CallbackInfo() { } } +inline Value CallbackInfo::NewTarget() const { + napi_value newTarget; + napi_status status = napi_get_new_target(_env, _info, &newTarget); + return Value(_env, newTarget); +} + inline bool CallbackInfo::IsConstructCall() const { - napi_value new_target; - napi_status status = napi_get_new_target(_env, _info, &new_target); + napi_value newTarget; + napi_status status = napi_get_new_target(_env, _info, &newTarget); bool isConstructCall = (new_target != nullptr); NAPI_THROW_IF_FAILED(_env, status, false); return isConstructCall; diff --git a/napi.h b/napi.h index 834141879..efea7abc3 100644 --- a/napi.h +++ b/napi.h @@ -1124,6 +1124,7 @@ namespace Napi { ~CallbackInfo(); Napi::Env Env() const; + Value NewTarget() const; bool IsConstructCall() const; size_t Length() const; const Value operator [](size_t index) const; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..33b8ed07d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,5 @@ +{ + "name": "node-addon-api", + "version": "0.6.2", + "lockfileVersion": 1 +} From 0eda0d60d42a1f470620bc04c448708a37b64888 Mon Sep 17 00:00:00 2001 From: Sampson Gao Date: Tue, 22 Aug 2017 17:03:21 -0400 Subject: [PATCH 3/5] Add missing error handling check in CallbackInfo::NewTarget() --- napi-inl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/napi-inl.h b/napi-inl.h index 77843bed3..246c558c7 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -2018,15 +2018,15 @@ inline CallbackInfo::~CallbackInfo() { inline Value CallbackInfo::NewTarget() const { napi_value newTarget; napi_status status = napi_get_new_target(_env, _info, &newTarget); + NAPI_THROW_IF_FAILED(_env, status, Value()); return Value(_env, newTarget); } inline bool CallbackInfo::IsConstructCall() const { napi_value newTarget; napi_status status = napi_get_new_target(_env, _info, &newTarget); - bool isConstructCall = (new_target != nullptr); NAPI_THROW_IF_FAILED(_env, status, false); - return isConstructCall; + return (new_target != nullptr); } inline Napi::Env CallbackInfo::Env() const { From 739d44e7329539ccdd417e5a2cc0b7d4179f0299 Mon Sep 17 00:00:00 2001 From: Sampson Gao Date: Tue, 22 Aug 2017 18:59:39 -0400 Subject: [PATCH 4/5] Fix typo --- napi-inl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/napi-inl.h b/napi-inl.h index 246c558c7..b3b1feb75 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -2026,7 +2026,7 @@ inline bool CallbackInfo::IsConstructCall() const { napi_value newTarget; napi_status status = napi_get_new_target(_env, _info, &newTarget); NAPI_THROW_IF_FAILED(_env, status, false); - return (new_target != nullptr); + return (newTarget != nullptr); } inline Napi::Env CallbackInfo::Env() const { From 17cd24f4da08f1fde993c8fc974de886a560c592 Mon Sep 17 00:00:00 2001 From: Sampson Gao Date: Tue, 22 Aug 2017 19:01:32 -0400 Subject: [PATCH 5/5] Reduce duplicated code --- napi-inl.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/napi-inl.h b/napi-inl.h index b3b1feb75..610da0c46 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -2023,10 +2023,7 @@ inline Value CallbackInfo::NewTarget() const { } inline bool CallbackInfo::IsConstructCall() const { - napi_value newTarget; - napi_status status = napi_get_new_target(_env, _info, &newTarget); - NAPI_THROW_IF_FAILED(_env, status, false); - return (newTarget != nullptr); + return !NewTarget().IsEmpty(); } inline Napi::Env CallbackInfo::Env() const {