test: checks on napi factory wrap’s finalization
Fixes: https://github.com/nodejs/node/issues/22396 PR-URL: https://github.com/nodejs/node/pull/22612 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com>
This commit is contained in:
parent
cf0e881b33
commit
1cee085367
@ -15,9 +15,14 @@ napi_value CreateObject(napi_env env, napi_callback_info info) {
|
|||||||
napi_value Init(napi_env env, napi_value exports) {
|
napi_value Init(napi_env env, napi_value exports) {
|
||||||
NAPI_CALL(env, MyObject::Init(env));
|
NAPI_CALL(env, MyObject::Init(env));
|
||||||
|
|
||||||
NAPI_CALL(env,
|
napi_property_descriptor descriptors[] = {
|
||||||
// NOLINTNEXTLINE (readability/null_usage)
|
DECLARE_NAPI_GETTER("finalizeCount", MyObject::GetFinalizeCount),
|
||||||
napi_create_function(env, "exports", -1, CreateObject, NULL, &exports));
|
DECLARE_NAPI_PROPERTY("createObject", CreateObject),
|
||||||
|
};
|
||||||
|
|
||||||
|
NAPI_CALL(env, napi_define_properties(
|
||||||
|
env, exports, sizeof(descriptors) / sizeof(*descriptors), descriptors));
|
||||||
|
|
||||||
return exports;
|
return exports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include "myobject.h"
|
#include "myobject.h"
|
||||||
#include "../common.h"
|
#include "../common.h"
|
||||||
|
|
||||||
|
static int finalize_count = 0;
|
||||||
|
|
||||||
MyObject::MyObject() : env_(nullptr), wrapper_(nullptr) {}
|
MyObject::MyObject() : env_(nullptr), wrapper_(nullptr) {}
|
||||||
|
|
||||||
MyObject::~MyObject() { napi_delete_reference(env_, wrapper_); }
|
MyObject::~MyObject() { napi_delete_reference(env_, wrapper_); }
|
||||||
@ -8,10 +10,17 @@ MyObject::~MyObject() { napi_delete_reference(env_, wrapper_); }
|
|||||||
void MyObject::Destructor(napi_env env,
|
void MyObject::Destructor(napi_env env,
|
||||||
void* nativeObject,
|
void* nativeObject,
|
||||||
void* /*finalize_hint*/) {
|
void* /*finalize_hint*/) {
|
||||||
|
++finalize_count;
|
||||||
MyObject* obj = static_cast<MyObject*>(nativeObject);
|
MyObject* obj = static_cast<MyObject*>(nativeObject);
|
||||||
delete obj;
|
delete obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
napi_value MyObject::GetFinalizeCount(napi_env env, napi_callback_info info) {
|
||||||
|
napi_value result;
|
||||||
|
NAPI_CALL(env, napi_create_int32(env, finalize_count, &result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
napi_ref MyObject::constructor;
|
napi_ref MyObject::constructor;
|
||||||
|
|
||||||
napi_status MyObject::Init(napi_env env) {
|
napi_status MyObject::Init(napi_env env) {
|
||||||
|
@ -7,6 +7,7 @@ class MyObject {
|
|||||||
public:
|
public:
|
||||||
static napi_status Init(napi_env env);
|
static napi_status Init(napi_env env);
|
||||||
static void Destructor(napi_env env, void* nativeObject, void* finalize_hint);
|
static void Destructor(napi_env env, void* nativeObject, void* finalize_hint);
|
||||||
|
static napi_value GetFinalizeCount(napi_env env, napi_callback_info info);
|
||||||
static napi_status NewInstance(napi_env env,
|
static napi_status NewInstance(napi_env env,
|
||||||
napi_value arg,
|
napi_value arg,
|
||||||
napi_value* instance);
|
napi_value* instance);
|
||||||
|
@ -1,14 +1,25 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
// Flags: --expose-gc
|
||||||
|
|
||||||
const common = require('../../common');
|
const common = require('../../common');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const createObject = require(`./build/${common.buildType}/binding`);
|
const test = require(`./build/${common.buildType}/binding`);
|
||||||
|
|
||||||
const obj = createObject(10);
|
assert.strictEqual(test.finalizeCount, 0);
|
||||||
assert.strictEqual(obj.plusOne(), 11);
|
(() => {
|
||||||
assert.strictEqual(obj.plusOne(), 12);
|
const obj = test.createObject(10);
|
||||||
assert.strictEqual(obj.plusOne(), 13);
|
assert.strictEqual(obj.plusOne(), 11);
|
||||||
|
assert.strictEqual(obj.plusOne(), 12);
|
||||||
|
assert.strictEqual(obj.plusOne(), 13);
|
||||||
|
})();
|
||||||
|
global.gc();
|
||||||
|
assert.strictEqual(test.finalizeCount, 1);
|
||||||
|
|
||||||
const obj2 = createObject(20);
|
(() => {
|
||||||
assert.strictEqual(obj2.plusOne(), 21);
|
const obj2 = test.createObject(20);
|
||||||
assert.strictEqual(obj2.plusOne(), 22);
|
assert.strictEqual(obj2.plusOne(), 21);
|
||||||
assert.strictEqual(obj2.plusOne(), 23);
|
assert.strictEqual(obj2.plusOne(), 22);
|
||||||
|
assert.strictEqual(obj2.plusOne(), 23);
|
||||||
|
})();
|
||||||
|
global.gc();
|
||||||
|
assert.strictEqual(test.finalizeCount, 2);
|
||||||
|
@ -6,11 +6,12 @@ const assert = require('assert');
|
|||||||
const addon = require(`./build/${common.buildType}/binding`);
|
const addon = require(`./build/${common.buildType}/binding`);
|
||||||
|
|
||||||
let obj1 = addon.createObject(10);
|
let obj1 = addon.createObject(10);
|
||||||
const obj2 = addon.createObject(20);
|
let obj2 = addon.createObject(20);
|
||||||
const result = addon.add(obj1, obj2);
|
const result = addon.add(obj1, obj2);
|
||||||
assert.strictEqual(result, 30);
|
assert.strictEqual(result, 30);
|
||||||
|
|
||||||
// Make sure the native destructor gets called.
|
// Make sure the native destructor gets called.
|
||||||
obj1 = null;
|
obj1 = null;
|
||||||
|
obj2 = null;
|
||||||
global.gc();
|
global.gc();
|
||||||
assert.strictEqual(addon.finalizeCount(), 1);
|
assert.strictEqual(addon.finalizeCount(), 2);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user