From 44273cd1a977c5492ed38a08ce231c6938b17342 Mon Sep 17 00:00:00 2001 From: Vladimir Morozov Date: Fri, 3 May 2024 21:26:55 -0700 Subject: [PATCH 1/2] fix compilation for Visual Studio 2022 --- .gitignore | 11 +++++++++++ napi-inl.h | 33 ++++++++++++++++++++------------- napi.h | 36 ++++++++++++++++++------------------ test/async_worker.cc | 22 ++++++++++++---------- 4 files changed, 61 insertions(+), 41 deletions(-) diff --git a/.gitignore b/.gitignore index bcded4821..f6b80ae92 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,14 @@ # ignore node-gyp generated files outside its build directory /test/*.Makefile /test/*.mk + +# ignore node-gyp generated Visual Studio files +*.vcxproj +*.vcxproj.filters +*.vcxproj.user +*.vsidx +*.sln +*.suo +/test/.vs/ +/test/Release/ +/test/Debug/ diff --git a/napi-inl.h b/napi-inl.h index a5ae7af72..39c725c7d 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -2988,9 +2988,10 @@ inline Object Error::Value() const { return Object(_env, refValue); } -inline Error::Error(Error&& other) : ObjectReference(std::move(other)) {} +inline Error::Error(Error&& other) NAPI_NOEXCEPT + : ObjectReference(std::move(other)) {} -inline Error& Error::operator=(Error&& other) { +inline Error& Error::operator=(Error&& other) NAPI_NOEXCEPT { static_cast*>(this)->operator=(std::move(other)); return *this; } @@ -3199,7 +3200,7 @@ inline Reference::~Reference() { } template -inline Reference::Reference(Reference&& other) +inline Reference::Reference(Reference&& other) NAPI_NOEXCEPT : _env(other._env), _ref(other._ref), _suppressDestruct(other._suppressDestruct) { @@ -3209,7 +3210,8 @@ inline Reference::Reference(Reference&& other) } template -inline Reference& Reference::operator=(Reference&& other) { +inline Reference& Reference::operator=(Reference&& other) + NAPI_NOEXCEPT { Reset(); _env = other._env; _ref = other._ref; @@ -3359,10 +3361,11 @@ inline ObjectReference& ObjectReference::operator=(Reference&& other) { return *this; } -inline ObjectReference::ObjectReference(ObjectReference&& other) +inline ObjectReference::ObjectReference(ObjectReference&& other) NAPI_NOEXCEPT : Reference(std::move(other)) {} -inline ObjectReference& ObjectReference::operator=(ObjectReference&& other) { +inline ObjectReference& ObjectReference::operator=(ObjectReference&& other) + NAPI_NOEXCEPT { static_cast*>(this)->operator=(std::move(other)); return *this; } @@ -3526,19 +3529,19 @@ inline FunctionReference::FunctionReference(napi_env env, napi_ref ref) : Reference(env, ref) {} inline FunctionReference::FunctionReference(Reference&& other) - : Reference(std::move(other)) {} + NAPI_NOEXCEPT : Reference(std::move(other)) {} inline FunctionReference& FunctionReference::operator=( - Reference&& other) { + Reference&& other) NAPI_NOEXCEPT { static_cast*>(this)->operator=(std::move(other)); return *this; } inline FunctionReference::FunctionReference(FunctionReference&& other) - : Reference(std::move(other)) {} + NAPI_NOEXCEPT : Reference(std::move(other)) {} inline FunctionReference& FunctionReference::operator=( - FunctionReference&& other) { + FunctionReference&& other) NAPI_NOEXCEPT { static_cast*>(this)->operator=(std::move(other)); return *this; } @@ -4891,7 +4894,10 @@ inline napi_value ObjectWrap::WrappedMethod( napi_env env, napi_callback_info info) NAPI_NOEXCEPT { return details::WrapCallback([&] { const CallbackInfo cbInfo(env, info); - method(cbInfo, cbInfo[0]); + // MSVC requires to copy 'method' function pointer to a local variable + // before invoking it. + auto m = method; + m(cbInfo, cbInfo[0]); return nullptr; }); } @@ -5014,14 +5020,15 @@ inline AsyncContext::~AsyncContext() { } } -inline AsyncContext::AsyncContext(AsyncContext&& other) { +inline AsyncContext::AsyncContext(AsyncContext&& other) NAPI_NOEXCEPT { _env = other._env; other._env = nullptr; _context = other._context; other._context = nullptr; } -inline AsyncContext& AsyncContext::operator=(AsyncContext&& other) { +inline AsyncContext& AsyncContext::operator=(AsyncContext&& other) + NAPI_NOEXCEPT { _env = other._env; other._env = nullptr; _context = other._context; diff --git a/napi.h b/napi.h index 9f20cb884..a52df75c1 100644 --- a/napi.h +++ b/napi.h @@ -1268,7 +1268,7 @@ class TypedArrayOf : public TypedArray { napi_typedarray_type type = TypedArray::TypedArrayTypeForPrimitiveType() #else - napi_typedarray_type type + napi_typedarray_type type #endif ///< Type of array, if different from the default array type for the ///< template parameter T. @@ -1291,7 +1291,7 @@ class TypedArrayOf : public TypedArray { napi_typedarray_type type = TypedArray::TypedArrayTypeForPrimitiveType() #else - napi_typedarray_type type + napi_typedarray_type type #endif ///< Type of array, if different from the default array type for the ///< template parameter T. @@ -1381,8 +1381,8 @@ class DataView : public Object { template void WriteData(size_t byteOffset, T value) const; - void* _data; - size_t _length; + void* _data{}; + size_t _length{}; }; class Function : public Object { @@ -1554,8 +1554,8 @@ class Reference { ~Reference(); // A reference can be moved but cannot be copied. - Reference(Reference&& other); - Reference& operator=(Reference&& other); + Reference(Reference&& other) NAPI_NOEXCEPT; + Reference& operator=(Reference&& other) NAPI_NOEXCEPT; NAPI_DISALLOW_ASSIGN(Reference) operator napi_ref() const; @@ -1601,8 +1601,8 @@ class ObjectReference : public Reference { // A reference can be moved but cannot be copied. ObjectReference(Reference&& other); ObjectReference& operator=(Reference&& other); - ObjectReference(ObjectReference&& other); - ObjectReference& operator=(ObjectReference&& other); + ObjectReference(ObjectReference&& other) NAPI_NOEXCEPT; + ObjectReference& operator=(ObjectReference&& other) NAPI_NOEXCEPT; NAPI_DISALLOW_ASSIGN(ObjectReference) MaybeOrValue Get(const char* utf8name) const; @@ -1637,10 +1637,10 @@ class FunctionReference : public Reference { FunctionReference(napi_env env, napi_ref ref); // A reference can be moved but cannot be copied. - FunctionReference(Reference&& other); - FunctionReference& operator=(Reference&& other); - FunctionReference(FunctionReference&& other); - FunctionReference& operator=(FunctionReference&& other); + FunctionReference(Reference&& other) NAPI_NOEXCEPT; + FunctionReference& operator=(Reference&& other) NAPI_NOEXCEPT; + FunctionReference(FunctionReference&& other) NAPI_NOEXCEPT; + FunctionReference& operator=(FunctionReference&& other) NAPI_NOEXCEPT; NAPI_DISALLOW_ASSIGN_COPY(FunctionReference) MaybeOrValue operator()( @@ -1715,7 +1715,7 @@ FunctionReference Persistent(Function value); /// /// Following C++ statements will not be executed. The exception will bubble /// up as a C++ exception of type `Napi::Error`, until it is either caught -/// while still in C++, or else automatically propataged as a JavaScript +/// while still in C++, or else automatically propagated as a JavaScript /// exception when the callback returns to JavaScript. /// /// #### Example 2A - Propagating a Node-API C++ exception: @@ -1801,8 +1801,8 @@ class Error : public ObjectReference Error(napi_env env, napi_value value); // An error can be moved or copied. - Error(Error&& other); - Error& operator=(Error&& other); + Error(Error&& other) NAPI_NOEXCEPT; + Error& operator=(Error&& other) NAPI_NOEXCEPT; Error(const Error&); Error& operator=(const Error&); @@ -1888,7 +1888,7 @@ class CallbackInfo { napi_value _this; size_t _argc; napi_value* _argv; - napi_value _staticArgs[6]; + napi_value _staticArgs[6]{}; napi_value* _dynamicArgs; void* _data; }; @@ -2507,8 +2507,8 @@ class AsyncContext { const Object& resource); virtual ~AsyncContext(); - AsyncContext(AsyncContext&& other); - AsyncContext& operator=(AsyncContext&& other); + AsyncContext(AsyncContext&& other) NAPI_NOEXCEPT; + AsyncContext& operator=(AsyncContext&& other) NAPI_NOEXCEPT; NAPI_DISALLOW_ASSIGN_COPY(AsyncContext) operator napi_async_context() const; diff --git a/test/async_worker.cc b/test/async_worker.cc index 972b7b2eb..c0a20cb5c 100644 --- a/test/async_worker.cc +++ b/test/async_worker.cc @@ -51,15 +51,17 @@ class TestWorkerWithUserDefRecv : public AsyncWorker { }; // Using default std::allocator impl, but assuming user can define their own -// alloc/dealloc methods +// allocate/deallocate methods class CustomAllocWorker : public AsyncWorker { + using Allocator = std::allocator; + public: CustomAllocWorker(Function& cb) : AsyncWorker(cb){}; static void DoWork(const CallbackInfo& info) { Function cb = info[0].As(); - std::allocator create_alloc; - CustomAllocWorker* newWorker = create_alloc.allocate(1); - create_alloc.construct(newWorker, cb); + Allocator allocator; + CustomAllocWorker* newWorker = allocator.allocate(1); + std::allocator_traits::construct(allocator, newWorker, cb); newWorker->Queue(); } @@ -67,9 +69,9 @@ class CustomAllocWorker : public AsyncWorker { void Execute() override {} void Destroy() override { assert(this->_secretVal == 24); - std::allocator deallocer; - deallocer.destroy(this); - deallocer.deallocate(this, 1); + Allocator allocator; + std::allocator_traits::destroy(allocator, this); + allocator.deallocate(this, 1); } private: @@ -108,7 +110,7 @@ class TestWorker : public AsyncWorker { : AsyncWorker(cb, resource_name, resource) {} TestWorker(Function cb, const char* resource_name) : AsyncWorker(cb, resource_name) {} - bool _succeed; + bool _succeed{}; }; class TestWorkerWithResult : public AsyncWorker { @@ -143,7 +145,7 @@ class TestWorkerWithResult : public AsyncWorker { const char* resource_name, const Object& resource) : AsyncWorker(cb, resource_name, resource) {} - bool _succeed; + bool _succeed{}; }; class TestWorkerNoCallback : public AsyncWorker { @@ -194,7 +196,7 @@ class TestWorkerNoCallback : public AsyncWorker { : AsyncWorker(env, resource_name, resource), _deferred(Napi::Promise::Deferred::New(env)) {} Promise::Deferred _deferred; - bool _succeed; + bool _succeed{}; }; class EchoWorker : public AsyncWorker { From 2b528565c3df81dd8865c77a2db53396f0848c50 Mon Sep 17 00:00:00 2001 From: Vladimir Morozov Date: Mon, 6 May 2024 12:15:16 -0700 Subject: [PATCH 2/2] remove newly added NAPI_NOEXCEPT --- napi-inl.h | 28 ++++++++++++---------------- napi.h | 24 ++++++++++++------------ 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/napi-inl.h b/napi-inl.h index 39c725c7d..40e7d4208 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -2988,10 +2988,9 @@ inline Object Error::Value() const { return Object(_env, refValue); } -inline Error::Error(Error&& other) NAPI_NOEXCEPT - : ObjectReference(std::move(other)) {} +inline Error::Error(Error&& other) : ObjectReference(std::move(other)) {} -inline Error& Error::operator=(Error&& other) NAPI_NOEXCEPT { +inline Error& Error::operator=(Error&& other) { static_cast*>(this)->operator=(std::move(other)); return *this; } @@ -3200,7 +3199,7 @@ inline Reference::~Reference() { } template -inline Reference::Reference(Reference&& other) NAPI_NOEXCEPT +inline Reference::Reference(Reference&& other) : _env(other._env), _ref(other._ref), _suppressDestruct(other._suppressDestruct) { @@ -3210,8 +3209,7 @@ inline Reference::Reference(Reference&& other) NAPI_NOEXCEPT } template -inline Reference& Reference::operator=(Reference&& other) - NAPI_NOEXCEPT { +inline Reference& Reference::operator=(Reference&& other) { Reset(); _env = other._env; _ref = other._ref; @@ -3361,11 +3359,10 @@ inline ObjectReference& ObjectReference::operator=(Reference&& other) { return *this; } -inline ObjectReference::ObjectReference(ObjectReference&& other) NAPI_NOEXCEPT +inline ObjectReference::ObjectReference(ObjectReference&& other) : Reference(std::move(other)) {} -inline ObjectReference& ObjectReference::operator=(ObjectReference&& other) - NAPI_NOEXCEPT { +inline ObjectReference& ObjectReference::operator=(ObjectReference&& other) { static_cast*>(this)->operator=(std::move(other)); return *this; } @@ -3529,19 +3526,19 @@ inline FunctionReference::FunctionReference(napi_env env, napi_ref ref) : Reference(env, ref) {} inline FunctionReference::FunctionReference(Reference&& other) - NAPI_NOEXCEPT : Reference(std::move(other)) {} + : Reference(std::move(other)) {} inline FunctionReference& FunctionReference::operator=( - Reference&& other) NAPI_NOEXCEPT { + Reference&& other) { static_cast*>(this)->operator=(std::move(other)); return *this; } inline FunctionReference::FunctionReference(FunctionReference&& other) - NAPI_NOEXCEPT : Reference(std::move(other)) {} + : Reference(std::move(other)) {} inline FunctionReference& FunctionReference::operator=( - FunctionReference&& other) NAPI_NOEXCEPT { + FunctionReference&& other) { static_cast*>(this)->operator=(std::move(other)); return *this; } @@ -5020,15 +5017,14 @@ inline AsyncContext::~AsyncContext() { } } -inline AsyncContext::AsyncContext(AsyncContext&& other) NAPI_NOEXCEPT { +inline AsyncContext::AsyncContext(AsyncContext&& other) { _env = other._env; other._env = nullptr; _context = other._context; other._context = nullptr; } -inline AsyncContext& AsyncContext::operator=(AsyncContext&& other) - NAPI_NOEXCEPT { +inline AsyncContext& AsyncContext::operator=(AsyncContext&& other) { _env = other._env; other._env = nullptr; _context = other._context; diff --git a/napi.h b/napi.h index a52df75c1..0b1fe170a 100644 --- a/napi.h +++ b/napi.h @@ -1554,8 +1554,8 @@ class Reference { ~Reference(); // A reference can be moved but cannot be copied. - Reference(Reference&& other) NAPI_NOEXCEPT; - Reference& operator=(Reference&& other) NAPI_NOEXCEPT; + Reference(Reference&& other); + Reference& operator=(Reference&& other); NAPI_DISALLOW_ASSIGN(Reference) operator napi_ref() const; @@ -1601,8 +1601,8 @@ class ObjectReference : public Reference { // A reference can be moved but cannot be copied. ObjectReference(Reference&& other); ObjectReference& operator=(Reference&& other); - ObjectReference(ObjectReference&& other) NAPI_NOEXCEPT; - ObjectReference& operator=(ObjectReference&& other) NAPI_NOEXCEPT; + ObjectReference(ObjectReference&& other); + ObjectReference& operator=(ObjectReference&& other); NAPI_DISALLOW_ASSIGN(ObjectReference) MaybeOrValue Get(const char* utf8name) const; @@ -1637,10 +1637,10 @@ class FunctionReference : public Reference { FunctionReference(napi_env env, napi_ref ref); // A reference can be moved but cannot be copied. - FunctionReference(Reference&& other) NAPI_NOEXCEPT; - FunctionReference& operator=(Reference&& other) NAPI_NOEXCEPT; - FunctionReference(FunctionReference&& other) NAPI_NOEXCEPT; - FunctionReference& operator=(FunctionReference&& other) NAPI_NOEXCEPT; + FunctionReference(Reference&& other); + FunctionReference& operator=(Reference&& other); + FunctionReference(FunctionReference&& other); + FunctionReference& operator=(FunctionReference&& other); NAPI_DISALLOW_ASSIGN_COPY(FunctionReference) MaybeOrValue operator()( @@ -1801,8 +1801,8 @@ class Error : public ObjectReference Error(napi_env env, napi_value value); // An error can be moved or copied. - Error(Error&& other) NAPI_NOEXCEPT; - Error& operator=(Error&& other) NAPI_NOEXCEPT; + Error(Error&& other); + Error& operator=(Error&& other); Error(const Error&); Error& operator=(const Error&); @@ -2507,8 +2507,8 @@ class AsyncContext { const Object& resource); virtual ~AsyncContext(); - AsyncContext(AsyncContext&& other) NAPI_NOEXCEPT; - AsyncContext& operator=(AsyncContext&& other) NAPI_NOEXCEPT; + AsyncContext(AsyncContext&& other); + AsyncContext& operator=(AsyncContext&& other); NAPI_DISALLOW_ASSIGN_COPY(AsyncContext) operator napi_async_context() const;