Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
toyobayashi committed Dec 13, 2024
1 parent c2c7206 commit 3c126e3
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 10 deletions.
30 changes: 30 additions & 0 deletions packages/test/objwrap/myobject.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ void operator delete(void* p) noexcept {
}
#endif

typedef int32_t FinalizerData;

napi_ref MyObject::constructor;

MyObject::MyObject(double value)
Expand All @@ -29,6 +31,11 @@ void MyObject::Destructor(node_api_basic_env env,
void* /*finalize_hint*/) {
MyObject* obj = static_cast<MyObject*>(nativeObject);
delete obj;

FinalizerData* data;
NODE_API_BASIC_CALL_RETURN_VOID(
env, napi_get_instance_data(env, reinterpret_cast<void**>(&data)));
*data += 1;
}

void MyObject::Init(napi_env env, napi_value exports) {
Expand Down Expand Up @@ -215,15 +222,38 @@ napi_value ObjectWrapDanglingReferenceTest(napi_env env,
return ret;
}

static napi_value GetFinalizerCallCount(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value argv[1];
FinalizerData* data;
napi_value result;

NODE_API_CALL(env,
napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
NODE_API_CALL(env,
napi_get_instance_data(env, reinterpret_cast<void**>(&data)));
NODE_API_CALL(env, napi_create_int32(env, *data, &result));
return result;
}

static void finalizeData(napi_env env, void* data, void* hint) {
delete reinterpret_cast<FinalizerData*>(data);
}

EXTERN_C_START
napi_value Init(napi_env env, napi_value exports) {
FinalizerData* data = new FinalizerData;
*data = 0;
NODE_API_CALL(env, napi_set_instance_data(env, data, finalizeData, nullptr));

MyObject::Init(env, exports);

napi_property_descriptor descriptors[] = {
DECLARE_NODE_API_PROPERTY("objectWrapDanglingReference",
ObjectWrapDanglingReference),
DECLARE_NODE_API_PROPERTY("objectWrapDanglingReferenceTest",
ObjectWrapDanglingReferenceTest),
DECLARE_NODE_API_PROPERTY("getFinalizerCallCount", GetFinalizerCallCount),
};

NODE_API_CALL(
Expand Down
25 changes: 15 additions & 10 deletions packages/test/objwrap/objwrapbasicfinalizer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,23 @@
/* eslint-disable camelcase */
'use strict'
const { load } = require('../util')
const common = require('../common')
const { onGC, gcUntil } = require('../gc')
const assert = require('assert')
const { gcUntil } = require('../gc')

const p = load('objwrapbasicfinalizer')
module.exports = p.then(async addon => {
let obj = new addon.MyObject(9)
let called = false
onGC(obj, {
ongc: common.mustCall(() => {
called = true
})
// This test verifies that ObjectWrap can be correctly finalized with a node_api_basic_finalizer
// in the current JS loop tick
(() => {
let obj = new addon.MyObject(9)
obj = null
// Silent eslint about unused variables.
assert.strictEqual(obj, null)
})()

await gcUntil(() => {
return addon.getFinalizerCallCount() === 1
})
obj = null
await gcUntil(() => called)

assert.strictEqual(addon.getFinalizerCallCount(), 1)
})

0 comments on commit 3c126e3

Please sign in to comment.