microsoft / node-api-dotnet

Advanced interoperability between .NET and JavaScript in the same process.
MIT License
495 stars 53 forks source link

Fix unintentional destruction of object wrapper reference #297

Closed vmoroz closed 4 months ago

vmoroz commented 4 months ago

Fixes: #296

When we create a new object wrapper in the JsRuntimeContext.InitializeObjectWrapper we add a reference to it to the _objectMap: https://github.com/microsoft/node-api-dotnet/blob/25b3b6c9452a855a7062e9c58160afd2e276ad36/src/NodeApi/Interop/JSRuntimeContext.cs#L328

Then, the calling method in the JsRuntimeContext.GetOrCreateObjectWrapper creates another JSReference to the same wrapper and replaces it in the _objectMap: https://github.com/microsoft/node-api-dotnet/blob/25b3b6c9452a855a7062e9c58160afd2e276ad36/src/NodeApi/Interop/JSRuntimeContext.cs#L398

As a result the originally created JSReference is collected by .Net GC and destroys the wrapper napi_ref stored as a private property in the JS object. When try to unwrap it later we observe a crash because the underlying napi_ref is deleted.

To work around this issue this PR adds a condition after calling createWrapper() to check if the _objectMap already has an entry and do nothing in such case.