Skip to content

Commit

Permalink
Fix weak reference handling in runtime object map (#334)
Browse files Browse the repository at this point in the history
  • Loading branch information
jasongin authored Jul 24, 2024
1 parent baaafdc commit 9af64a6
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
5 changes: 2 additions & 3 deletions src/NodeApi/Interop/JSRuntimeContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -371,11 +371,10 @@ private JSValue GetOrCreateObjectWrapper<T>(T obj, Func<JSValue> createWrapper)
if (_objectMap.TryGetValue(obj, out JSReference? wrapperWeakRef) &&
!wrapperWeakRef.IsDisposed)
{
JSValue? existingWrapper = wrapperWeakRef.GetValue();
if (existingWrapper.HasValue)
if (wrapperWeakRef.TryGetValue(out JSValue existingWrapper))
{
// Return the JS wrapper that was found in the map.
return existingWrapper.Value;
return existingWrapper;
}
else
{
Expand Down
28 changes: 28 additions & 0 deletions test/TestCases/napi-dotnet/object_map.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// Test the JSRuntimeContext "object map" which keeps track of JS wrapper objects
// for corresponding .NET objects.

const assert = require('assert');

/** @type {import('./napi-dotnet')} */
const binding = require('../common').binding;

const ComplexTypes = binding.ComplexTypes;
assert.strictEqual(typeof ComplexTypes, 'object');

let obj1 = ComplexTypes.classObject;
assert(obj1);

// The same JS wrapper instance should be returned every time.
let obj2 = ComplexTypes.classObject;
assert.strictEqual(obj1, obj2);

// Force the JS wrapper object to be collected.
obj1 = obj2 = undefined;
global.gc();

// A new JS wrapper object should be created.
let obj3 = ComplexTypes.classObject;
assert(obj3);

0 comments on commit 9af64a6

Please sign in to comment.