diff --git a/napi-inl.h b/napi-inl.h index 45cb58fb1..610da0c46 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -2015,11 +2015,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 { - bool isConstructCall; - napi_status status = napi_is_construct_call(_env, _info, &isConstructCall); - NAPI_THROW_IF_FAILED(_env, status, false); - return isConstructCall; + return !NewTarget().IsEmpty(); } inline Napi::Env CallbackInfo::Env() const { @@ -2470,10 +2474,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/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 +} 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,