Skip to content

Commit abfafe6

Browse files
authored
Ensure use of correct env in JSReference (microsoft#120)
1 parent d0a4d09 commit abfafe6

File tree

3 files changed

+57
-15
lines changed

3 files changed

+57
-15
lines changed

.vscode/tasks.json

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@
4646
"-c",
4747
"Release",
4848
"-f",
49-
"net7.0"
49+
"net7.0",
50+
"--",
51+
"--filter",
52+
"*.NonAot.*"
5053
],
5154
"options": {
5255
"cwd": "${workspaceFolder}/bench"
@@ -55,6 +58,28 @@
5558
"reveal": "always"
5659
},
5760
"problemMatcher": "$msCompile"
58-
}
59-
]
61+
},
62+
{
63+
"label": "bench AOT",
64+
"command": "dotnet",
65+
"type": "shell",
66+
"args": [
67+
"run",
68+
"-c",
69+
"Release",
70+
"-f",
71+
"net7.0",
72+
"--",
73+
"--filter",
74+
"*.Aot.*"
75+
],
76+
"options": {
77+
"cwd": "${workspaceFolder}/bench"
78+
},
79+
"presentation": {
80+
"reveal": "always"
81+
},
82+
"problemMatcher": "$msCompile"
83+
}
84+
]
6085
}

bench/Benchmarks.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.IO;
66
using BenchmarkDotNet.Attributes;
7+
using BenchmarkDotNet.Configs;
78
using BenchmarkDotNet.Jobs;
89
using BenchmarkDotNet.Running;
910
using Microsoft.JavaScript.NodeApi.Runtimes;
@@ -18,7 +19,8 @@ public static void Main(string[] args)
1819
{
1920
// Example: dotnet run -c Release --filter aot
2021
// If no filter is specified, the switcher will prompt.
21-
BenchmarkSwitcher.FromAssembly(typeof(Benchmarks).Assembly).Run(args);
22+
BenchmarkSwitcher.FromAssembly(typeof(Benchmarks).Assembly).Run(args,
23+
ManualConfig.Create(DefaultConfig.Instance).WithOptions(ConfigOptions.JoinSummary));
2224
}
2325

2426
public class NonAot : Benchmarks
@@ -41,6 +43,7 @@ public class Aot : Benchmarks
4143
private napi_env _env;
4244
private JSValue _function;
4345
private JSValue _callback;
46+
private JSReference _reference = null!;
4447

4548
[GlobalSetup]
4649
public void Setup()
@@ -56,14 +59,28 @@ public void Setup()
5659
JSValueScope scope = new(JSValueScopeType.Root, _env);
5760

5861
// Create some JS values that will be used by the benchmarks.
62+
5963
_function = JSNativeApi.RunScript("function callMeBack(cb) { cb(); }; callMeBack");
6064
_callback = JSValue.CreateFunction("callback", (args) => JSValue.Undefined);
65+
66+
_reference = new JSReference(_function);
6167
}
6268

6369
[Benchmark]
6470
public void CallJS()
6571
{
6672
_function.Call(thisArg: default, _callback);
6773
}
68-
}
6974

75+
[Benchmark]
76+
public void GetReference()
77+
{
78+
_ = _reference.GetValue()!.Value;
79+
}
80+
81+
[Benchmark]
82+
public void CreateAndDiposeReference()
83+
{
84+
using JSReference reference = new(_function);
85+
}
86+
}

src/NodeApi/JSReference.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ namespace Microsoft.JavaScript.NodeApi;
2323
/// </remarks>
2424
public class JSReference : IDisposable
2525
{
26-
private readonly JSRuntimeContext? _context;
2726
private readonly napi_ref _handle;
27+
private readonly napi_env _env;
28+
private readonly JSRuntimeContext? _context;
2829

2930
public bool IsWeak { get; private set; }
3031

@@ -40,8 +41,9 @@ public JSReference(JSValue value, bool isWeak = false)
4041

4142
public JSReference(napi_ref handle, bool isWeak = false)
4243
{
43-
_context = JSRuntimeContext.Current;
4444
_handle = handle;
45+
_env = (napi_env)JSValueScope.Current;
46+
_context = JSRuntimeContext.Current;
4547
IsWeak = isWeak;
4648
}
4749

@@ -68,7 +70,7 @@ public void MakeWeak()
6870
ThrowIfDisposed();
6971
if (!IsWeak)
7072
{
71-
napi_reference_unref((napi_env)JSValueScope.Current, _handle, default).ThrowIfFailed();
73+
napi_reference_unref(_env, _handle, default).ThrowIfFailed();
7274
IsWeak = true;
7375
}
7476
}
@@ -77,16 +79,15 @@ public void MakeStrong()
7779
ThrowIfDisposed();
7880
if (IsWeak)
7981
{
80-
napi_reference_ref((napi_env)JSValueScope.Current, _handle, default).ThrowIfFailed();
82+
napi_reference_ref(_env, _handle, default).ThrowIfFailed();
8183
IsWeak = true;
8284
}
8385
}
8486

8587
public JSValue? GetValue()
8688
{
8789
ThrowIfDisposed();
88-
napi_get_reference_value(
89-
(napi_env)JSValueScope.Current, _handle, out napi_value result).ThrowIfFailed();
90+
napi_get_reference_value(_env, _handle, out napi_value result).ThrowIfFailed();
9091
return result;
9192
}
9293

@@ -123,13 +124,12 @@ protected virtual void Dispose(bool disposing)
123124
// as the native host. In that case the reference must be disposed from the JS thread.
124125
if (_context == null)
125126
{
126-
napi_delete_reference((napi_env)JSValueScope.Current, handle).ThrowIfFailed();
127+
napi_delete_reference(_env, handle).ThrowIfFailed();
127128
}
128129
else
129130
{
130-
_context?.SynchronizationContext.Post(
131-
() => napi_delete_reference((napi_env)_context, handle).ThrowIfFailed(),
132-
allowSync: true);
131+
_context.SynchronizationContext.Post(
132+
() => napi_delete_reference(_env, handle).ThrowIfFailed(), allowSync: true);
133133
}
134134
}
135135
}

0 commit comments

Comments
 (0)