Skip to content

Commit ba7ad37

Browse files
davedoesdevmhdawson
authored andcommitted
src: fix ObjectWrap inheritance
- fix wrap/unwrap of objects inheriting from non-ObjectWrap PR-URL: #732 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Nicola Del Gobbo <nicoladelgobbo@gmail.com>
1 parent 31504c8 commit ba7ad37

File tree

6 files changed

+53
-3
lines changed

6 files changed

+53
-3
lines changed

napi-inl.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3146,10 +3146,11 @@ inline ObjectWrap<T>::ObjectWrap(const Napi::CallbackInfo& callbackInfo) {
31463146
napi_value wrapper = callbackInfo.This();
31473147
napi_status status;
31483148
napi_ref ref;
3149-
status = napi_wrap(env, wrapper, this, FinalizeCallback, nullptr, &ref);
3149+
T* instance = static_cast<T*>(this);
3150+
status = napi_wrap(env, wrapper, instance, FinalizeCallback, nullptr, &ref);
31503151
NAPI_THROW_IF_FAILED_VOID(env, status);
31513152

3152-
Reference<Object>* instanceRef = this;
3153+
Reference<Object>* instanceRef = instance;
31533154
*instanceRef = Reference<Object>(env, ref);
31543155
}
31553156

@@ -3872,7 +3873,7 @@ inline napi_value ObjectWrap<T>::InstanceSetterCallbackWrapper(
38723873

38733874
template <typename T>
38743875
inline void ObjectWrap<T>::FinalizeCallback(napi_env env, void* data, void* /*hint*/) {
3875-
ObjectWrap<T>* instance = static_cast<ObjectWrap<T>*>(data);
3876+
T* instance = static_cast<T*>(data);
38763877
instance->Finalize(Napi::Env(env));
38773878
delete instance;
38783879
}

test/binding.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ Object InitTypedArray(Env env);
5353
Object InitObjectWrap(Env env);
5454
Object InitObjectWrapConstructorException(Env env);
5555
Object InitObjectWrapRemoveWrap(Env env);
56+
Object InitObjectWrapMultipleInheritance(Env env);
5657
Object InitObjectReference(Env env);
5758
Object InitVersionManagement(Env env);
5859
Object InitThunkingManual(Env env);
@@ -111,6 +112,7 @@ Object Init(Env env, Object exports) {
111112
exports.Set("objectwrapConstructorException",
112113
InitObjectWrapConstructorException(env));
113114
exports.Set("objectwrap_removewrap", InitObjectWrapRemoveWrap(env));
115+
exports.Set("objectwrap_multiple_inheritance", InitObjectWrapMultipleInheritance(env));
114116
exports.Set("objectreference", InitObjectReference(env));
115117
exports.Set("version_management", InitVersionManagement(env));
116118
exports.Set("thunking_manual", InitThunkingManual(env));

test/binding.gyp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
'objectwrap.cc',
4646
'objectwrap_constructor_exception.cc',
4747
'objectwrap-removewrap.cc',
48+
'objectwrap_multiple_inheritance.cc',
4849
'objectreference.cc',
4950
'version_management.cc',
5051
'thunking_manual.cc',

test/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ let testModules = [
5353
'objectwrap',
5454
'objectwrap_constructor_exception',
5555
'objectwrap-removewrap',
56+
'objectwrap_multiple_inheritance',
5657
'objectreference',
5758
'version_management'
5859
];
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#include <napi.h>
2+
3+
class TestMIBase {
4+
public:
5+
TestMIBase() : test(0) {}
6+
virtual void dummy() {}
7+
uint32_t test;
8+
};
9+
10+
class TestMI : public TestMIBase, public Napi::ObjectWrap<TestMI> {
11+
public:
12+
TestMI(const Napi::CallbackInfo& info) :
13+
Napi::ObjectWrap<TestMI>(info) {}
14+
15+
Napi::Value GetTest(const Napi::CallbackInfo& info) {
16+
return Napi::Number::New(info.Env(), test);
17+
}
18+
19+
static void Initialize(Napi::Env env, Napi::Object exports) {
20+
exports.Set("TestMI", DefineClass(env, "TestMI", {
21+
InstanceAccessor<&TestMI::GetTest>("test")
22+
}));
23+
}
24+
};
25+
26+
Napi::Object InitObjectWrapMultipleInheritance(Napi::Env env) {
27+
Napi::Object exports = Napi::Object::New(env);
28+
TestMI::Initialize(env, exports);
29+
return exports;
30+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
'use strict';
2+
3+
const buildType = process.config.target_defaults.default_configuration;
4+
const assert = require('assert');
5+
6+
const test = bindingName => {
7+
const binding = require(bindingName);
8+
const TestMI = binding.objectwrap_multiple_inheritance.TestMI;
9+
const testmi = new TestMI();
10+
11+
assert.strictEqual(testmi.test, 0);
12+
}
13+
14+
test(`./build/${buildType}/binding.node`);
15+
test(`./build/${buildType}/binding_noexcept.node`);

0 commit comments

Comments
 (0)