diff --git a/test/binding.cc b/test/binding.cc index c2bd101f3..e374ac124 100644 --- a/test/binding.cc +++ b/test/binding.cc @@ -28,6 +28,7 @@ Object InitTypedArray(Env env); Object InitObjectWrap(Env env); Object InitObjectReference(Env env); Object InitVersionManagement(Env env); +Object InitThunkingManual(Env env); Object Init(Env env, Object exports) { exports.Set("arraybuffer", InitArrayBuffer(env)); @@ -56,6 +57,7 @@ Object Init(Env env, Object exports) { exports.Set("objectwrap", InitObjectWrap(env)); exports.Set("objectreference", InitObjectReference(env)); exports.Set("version_management", InitVersionManagement(env)); + exports.Set("thunking_manual", InitThunkingManual(env)); return exports; } diff --git a/test/binding.gyp b/test/binding.gyp index 7bff35e8a..c4ab467a7 100644 --- a/test/binding.gyp +++ b/test/binding.gyp @@ -30,7 +30,8 @@ 'typedarray.cc', 'objectwrap.cc', 'objectreference.cc', - 'version_management.cc' + 'version_management.cc', + 'thunking_manual.cc', ], 'conditions': [ ['NAPI_VERSION!=""', { 'defines': ['NAPI_VERSION=<@(NAPI_VERSION)'] } ] diff --git a/test/thunking_manual.cc b/test/thunking_manual.cc new file mode 100644 index 000000000..ead638748 --- /dev/null +++ b/test/thunking_manual.cc @@ -0,0 +1,112 @@ +#include + +static Napi::Value TestMethod(const Napi::CallbackInfo& /*info*/) { + return Napi::Value(); +} + +static Napi::Value TestGetter(const Napi::CallbackInfo& /*info*/) { + return Napi::Value(); +} + +static void TestSetter(const Napi::CallbackInfo& /*info*/) { +} + +class TestClass : public Napi::ObjectWrap { + public: + TestClass(const Napi::CallbackInfo& info): + ObjectWrap(info) { + } + static Napi::Value TestClassStaticMethod(const Napi::CallbackInfo& info) { + return Napi::Number::New(info.Env(), 42); + } + + static void TestClassStaticVoidMethod(const Napi::CallbackInfo& /*info*/) { + } + + Napi::Value TestClassInstanceMethod(const Napi::CallbackInfo& info) { + return Napi::Number::New(info.Env(), 42); + } + + void TestClassInstanceVoidMethod(const Napi::CallbackInfo& /*info*/) { + } + + Napi::Value TestClassInstanceGetter(const Napi::CallbackInfo& info) { + return Napi::Number::New(info.Env(), 42); + } + + void TestClassInstanceSetter(const Napi::CallbackInfo& /*info*/, + const Napi::Value& /*new_value*/) { + } + + static Napi::Function NewClass(Napi::Env env) { + return DefineClass(env, "TestClass", { + StaticMethod(env, "staticMethod", TestClassStaticMethod), + StaticMethod(env, "staticVoidMethod", TestClassStaticVoidMethod), + StaticMethod(env, + Napi::Symbol::New(env, "staticMethod"), + TestClassStaticMethod), + StaticMethod(env, + Napi::Symbol::New(env, "staticVoidMethod"), + TestClassStaticVoidMethod), + InstanceMethod("instanceMethod", &TestClass::TestClassInstanceMethod), + InstanceMethod("instanceVoidMethod", + &TestClass::TestClassInstanceVoidMethod), + InstanceMethod(Napi::Symbol::New(env, "instanceMethod"), + &TestClass::TestClassInstanceMethod), + InstanceMethod(Napi::Symbol::New(env, "instanceVoidMethod"), + &TestClass::TestClassInstanceVoidMethod), + InstanceAccessor("instanceAccessor", + &TestClass::TestClassInstanceGetter, + &TestClass::TestClassInstanceSetter) + }); + } +}; + +static Napi::Value CreateTestObject(const Napi::CallbackInfo& info) { + Napi::Object item = Napi::Object::New(info.Env()); + item["testMethod"] = + Napi::Function::New(info.Env(), TestMethod, "testMethod"); + + item.DefineProperties({ + Napi::PropertyDescriptor::Accessor(info.Env(), + item, + "accessor_1", + TestGetter), + Napi::PropertyDescriptor::Accessor(info.Env(), + item, + std::string("accessor_1_std_string"), + TestGetter), + Napi::PropertyDescriptor::Accessor(info.Env(), + item, + Napi::String::New(info.Env(), + "accessor_1_js_string"), + TestGetter), + Napi::PropertyDescriptor::Accessor(info.Env(), + item, + "accessor_2", + TestGetter, + TestSetter), + Napi::PropertyDescriptor::Accessor(info.Env(), + item, + std::string("accessor_2_std_string"), + TestGetter, + TestSetter), + Napi::PropertyDescriptor::Accessor(info.Env(), + item, + Napi::String::New(info.Env(), + "accessor_2_js_string"), + TestGetter, + TestSetter), + Napi::PropertyDescriptor::Value("TestClass", + TestClass::NewClass(info.Env())), + }); + + return item; +} + +Napi::Object InitThunkingManual(Napi::Env env) { + Napi::Object exports = Napi::Object::New(env); + exports["createTestObject"] = + Napi::Function::New(env, CreateTestObject, "createTestObject"); + return exports; +} diff --git a/test/thunking_manual.js b/test/thunking_manual.js new file mode 100644 index 000000000..22fb8877d --- /dev/null +++ b/test/thunking_manual.js @@ -0,0 +1,18 @@ +// Flags: --expose-gc +'use strict'; +const buildType = 'Debug'; +const assert = require('assert'); + +test(require(`./build/${buildType}/binding.node`)); +test(require(`./build/${buildType}/binding_noexcept.node`)); + +function test(binding) { + console.log("Thunking: Performing initial GC"); + global.gc(); + console.log("Thunking: Creating test object"); + let object = binding.thunking_manual.createTestObject(); + object = null; + console.log("Thunking: About to GC\n--------"); + global.gc(); + console.log("--------\nThunking: GC complete"); +}