koffi 2.3.17 → 2.3.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/build/2.3.19/koffi_darwin_arm64/koffi.node +0 -0
  3. package/build/{2.3.17 → 2.3.19}/koffi_darwin_x64/koffi.node +0 -0
  4. package/build/2.3.19/koffi_freebsd_arm64/koffi.node +0 -0
  5. package/build/{2.3.17 → 2.3.19}/koffi_freebsd_ia32/koffi.node +0 -0
  6. package/build/{2.3.17 → 2.3.19}/koffi_freebsd_x64/koffi.node +0 -0
  7. package/build/{2.3.17 → 2.3.19}/koffi_linux_arm32hf/koffi.node +0 -0
  8. package/build/{2.3.17 → 2.3.19}/koffi_linux_arm64/koffi.node +0 -0
  9. package/build/{2.3.17 → 2.3.19}/koffi_linux_ia32/koffi.node +0 -0
  10. package/build/{2.3.17 → 2.3.19}/koffi_linux_riscv64hf64/koffi.node +0 -0
  11. package/build/{2.3.17 → 2.3.19}/koffi_linux_x64/koffi.node +0 -0
  12. package/build/{2.3.17 → 2.3.19}/koffi_openbsd_ia32/koffi.node +0 -0
  13. package/build/{2.3.17 → 2.3.19}/koffi_openbsd_x64/koffi.node +0 -0
  14. package/build/2.3.19/koffi_win32_arm64/koffi.node +0 -0
  15. package/build/{2.3.17 → 2.3.19}/koffi_win32_ia32/koffi.node +0 -0
  16. package/build/2.3.19/koffi_win32_x64/koffi.node +0 -0
  17. package/package.json +2 -2
  18. package/src/koffi/src/call.cc +16 -8
  19. package/src/koffi/src/ffi.cc +3 -4
  20. package/src/koffi/src/ffi.hh +2 -0
  21. package/vendor/node-addon-api/CHANGELOG.md +41 -0
  22. package/vendor/node-addon-api/README.md +1 -1
  23. package/vendor/node-addon-api/doc/array_buffer.md +10 -0
  24. package/vendor/node-addon-api/doc/buffer.md +97 -0
  25. package/vendor/node-addon-api/doc/env.md +2 -2
  26. package/vendor/node-addon-api/doc/external.md +2 -2
  27. package/vendor/node-addon-api/doc/external_buffer.md +18 -0
  28. package/vendor/node-addon-api/doc/hierarchy.md +4 -2
  29. package/vendor/node-addon-api/doc/object.md +2 -29
  30. package/vendor/node-addon-api/doc/type_taggable.md +40 -0
  31. package/vendor/node-addon-api/doc/value.md +7 -1
  32. package/vendor/node-addon-api/napi-inl.h +317 -22
  33. package/vendor/node-addon-api/napi.h +84 -7
  34. package/vendor/node-addon-api/package.json +9 -1
  35. package/vendor/node-addon-api/test/async_progress_worker.cc +15 -3
  36. package/vendor/node-addon-api/test/binding.cc +4 -2
  37. package/vendor/node-addon-api/test/binding.gyp +11 -1
  38. package/vendor/node-addon-api/test/buffer.cc +13 -19
  39. package/vendor/node-addon-api/test/buffer.h +26 -0
  40. package/vendor/node-addon-api/test/buffer.js +82 -0
  41. package/vendor/node-addon-api/test/buffer_new_or_copy-inl.h +68 -0
  42. package/vendor/node-addon-api/test/buffer_no_external.cc +24 -0
  43. package/vendor/node-addon-api/test/error.cc +101 -0
  44. package/vendor/node-addon-api/test/error.js +15 -1
  45. package/vendor/node-addon-api/test/index.js +1 -1
  46. package/vendor/node-addon-api/test/object_reference.cc +220 -22
  47. package/vendor/node-addon-api/test/object_reference.js +83 -80
  48. package/vendor/node-addon-api/test/objectwrap.cc +23 -3
  49. package/vendor/node-addon-api/test/objectwrap.js +14 -2
  50. package/vendor/node-addon-api/test/reference.cc +55 -1
  51. package/vendor/node-addon-api/test/reference.js +7 -1
  52. package/vendor/node-addon-api/test/type_taggable.cc +66 -0
  53. package/vendor/node-addon-api/test/type_taggable.js +60 -0
  54. package/vendor/node-addon-api/test/value_type_cast.cc +60 -0
  55. package/vendor/node-addon-api/test/value_type_cast.js +106 -0
  56. package/vendor/node-addon-api/tools/eslint-format.js +2 -2
  57. package/build/2.3.17/koffi_darwin_arm64/koffi.node +0 -0
  58. package/build/2.3.17/koffi_freebsd_arm64/koffi.node +0 -0
  59. package/build/2.3.17/koffi_win32_arm64/koffi.node +0 -0
  60. package/build/2.3.17/koffi_win32_x64/koffi.node +0 -0
  61. package/vendor/node-addon-api/test/object/object_type_tag.cc +0 -39
  62. package/vendor/node-addon-api/test/object/object_type_tag.js +0 -55
  63. /package/build/{2.3.17 → 2.3.19}/koffi_win32_arm64/koffi.exp +0 -0
  64. /package/build/{2.3.17 → 2.3.19}/koffi_win32_arm64/koffi.lib +0 -0
  65. /package/build/{2.3.17 → 2.3.19}/koffi_win32_ia32/koffi.exp +0 -0
  66. /package/build/{2.3.17 → 2.3.19}/koffi_win32_ia32/koffi.lib +0 -0
  67. /package/build/{2.3.17 → 2.3.19}/koffi_win32_x64/koffi.exp +0 -0
  68. /package/build/{2.3.17 → 2.3.19}/koffi_win32_x64/koffi.lib +0 -0
@@ -16,7 +16,37 @@ const testUtil = require('./testUtil');
16
16
 
17
17
  module.exports = require('./common').runTest(test);
18
18
 
19
+ const enumType = {
20
+ JS: 0, // Napi::Value
21
+ C_STR: 1, // const char *
22
+ CPP_STR: 2, // std::string
23
+ BOOL: 3, // bool
24
+ INT: 4, // uint32_t
25
+ DOUBLE: 5, // double
26
+ JS_CAST: 6 // napi_value
27
+ };
28
+
29
+ const configObjects = [
30
+ { keyType: enumType.C_STR, valType: enumType.JS, key: 'hello', val: 'worlds' },
31
+ { keyType: enumType.C_STR, valType: enumType.C_STR, key: 'hello', val: 'worldd' },
32
+ { keyType: enumType.C_STR, valType: enumType.BOOL, key: 'hello', val: false },
33
+ { keyType: enumType.C_STR, valType: enumType.DOUBLE, key: 'hello', val: 3.56 },
34
+ { keyType: enumType.C_STR, valType: enumType.JS_CAST, key: 'hello_cast', val: 'world' },
35
+ { keyType: enumType.CPP_STR, valType: enumType.JS, key: 'hello_cpp', val: 'world_js' },
36
+ { keyType: enumType.CPP_STR, valType: enumType.JS_CAST, key: 'hello_cpp', val: 'world_js_cast' },
37
+ { keyType: enumType.CPP_STR, valType: enumType.CPP_STR, key: 'hello_cpp', val: 'world_cpp_str' },
38
+ { keyType: enumType.CPP_STR, valType: enumType.BOOL, key: 'hello_cpp', val: true },
39
+ { keyType: enumType.CPP_STR, valType: enumType.DOUBLE, key: 'hello_cpp', val: 3.58 },
40
+ { keyType: enumType.INT, valType: enumType.JS, key: 1, val: 'hello world' },
41
+ { keyType: enumType.INT, valType: enumType.JS_CAST, key: 2, val: 'hello world' },
42
+ { keyType: enumType.INT, valType: enumType.C_STR, key: 3, val: 'hello world' },
43
+ { keyType: enumType.INT, valType: enumType.CPP_STR, key: 8, val: 'hello world' },
44
+ { keyType: enumType.INT, valType: enumType.BOOL, key: 3, val: false },
45
+ { keyType: enumType.INT, valType: enumType.DOUBLE, key: 4, val: 3.14159 }
46
+ ];
47
+
19
48
  function test (binding) {
49
+ binding.objectreference.moveOpTest();
20
50
  function testCastedEqual (testToCompare) {
21
51
  const compareTest = ['hello', 'world', '!'];
22
52
  if (testToCompare instanceof Array) {
@@ -74,45 +104,32 @@ function test (binding) {
74
104
 
75
105
  'Weak',
76
106
  () => {
77
- binding.objectreference.setObjects('hello', 'world');
78
- const test = binding.objectreference.getFromValue('weak');
79
- const test2 = binding.objectreference.getFromGetter('weak', 'hello');
107
+ for (const configObject of configObjects) {
108
+ binding.objectreference.setObject(configObject);
109
+ const test = binding.objectreference.getFromValue('weak');
110
+ const test2 = binding.objectreference.getFromGetters('weak', configObject);
80
111
 
81
- assert.deepEqual({ hello: 'world' }, test);
82
- assert.equal('world', test2);
83
- assert.equal(test.hello, test2);
84
- },
85
- () => {
86
- binding.objectreference.setObjects('hello', 'world', 'javascript');
87
- const test = binding.objectreference.getFromValue('weak');
88
- const test2 = binding.objectreference.getFromValue('weak', 'hello');
112
+ const assertObject = {
113
+ [configObject.key]: configObject.val
114
+ };
115
+ assert.deepEqual(assertObject, test);
116
+ assert.equal(configObject.val, test2);
117
+ }
118
+ }, () => {
119
+ const configObjA = { keyType: enumType.INT, valType: enumType.JS, key: 0, val: 'hello' };
120
+ const configObjB = { keyType: enumType.INT, valType: enumType.JS, key: 1, val: 'world' };
121
+ binding.objectreference.setObject(configObjA);
122
+ binding.objectreference.setObject(configObjB);
89
123
 
90
- assert.deepEqual({ hello: 'world' }, test);
91
- assert.deepEqual({ hello: 'world' }, test2);
92
- assert.equal(test, test2);
93
- },
94
- () => {
95
- binding.objectreference.setObjects(1, 'hello world');
96
- const test = binding.objectreference.getFromValue('weak');
97
- const test2 = binding.objectreference.getFromGetter('weak', 1);
98
-
99
- assert.deepEqual({ 1: 'hello world' }, test);
100
- assert.equal('hello world', test2);
101
- assert.equal(test[1], test2);
102
- },
103
- () => {
104
- binding.objectreference.setObjects(0, 'hello');
105
- binding.objectreference.setObjects(1, 'world');
106
124
  const test = binding.objectreference.getFromValue('weak');
107
- const test2 = binding.objectreference.getFromGetter('weak', 0);
108
- const test3 = binding.objectreference.getFromGetter('weak', 1);
109
-
125
+ const test2 = binding.objectreference.getFromGetters('weak', configObjA);
126
+ const test3 = binding.objectreference.getFromGetters('weak', configObjB);
110
127
  assert.deepEqual({ 1: 'world' }, test);
111
128
  assert.equal(undefined, test2);
112
129
  assert.equal('world', test3);
113
130
  },
114
131
  () => {
115
- binding.objectreference.setObjects('hello', 'world');
132
+ binding.objectreference.setObject({ keyType: enumType.JS, valType: enumType.JS, key: 'hello', val: 'world' });
116
133
  assert.doesNotThrow(
117
134
  () => {
118
135
  let rcount = binding.objectreference.refObjects('weak');
@@ -132,16 +149,20 @@ function test (binding) {
132
149
 
133
150
  'Persistent',
134
151
  () => {
135
- binding.objectreference.setObjects('hello', 'world');
136
- const test = binding.objectreference.getFromValue('persistent');
137
- const test2 = binding.objectreference.getFromGetter('persistent', 'hello');
152
+ for (const configObject of configObjects) {
153
+ binding.objectreference.setObject(configObject);
154
+ const test = binding.objectreference.getFromValue('persistent');
155
+ const test2 = binding.objectreference.getFromGetters('persistent', configObject);
156
+ const assertObject = {
157
+ [configObject.key]: configObject.val
158
+ };
138
159
 
139
- assert.deepEqual({ hello: 'world' }, test);
140
- assert.equal('world', test2);
141
- assert.equal(test.hello, test2);
160
+ assert.deepEqual(assertObject, test);
161
+ assert.equal(configObject.val, test2);
162
+ }
142
163
  },
143
164
  () => {
144
- binding.objectreference.setObjects('hello', 'world', 'javascript');
165
+ binding.objectreference.setObject({ keyType: enumType.CPP_STR, valType: enumType.JS, key: 'hello', val: 'world' });
145
166
  const test = binding.objectreference.getFromValue('persistent');
146
167
  const test2 = binding.objectreference.getFromValue('persistent', 'hello');
147
168
 
@@ -150,27 +171,21 @@ function test (binding) {
150
171
  assert.deepEqual(test, test2);
151
172
  },
152
173
  () => {
153
- binding.objectreference.setObjects(1, 'hello world');
154
- const test = binding.objectreference.getFromValue('persistent');
155
- const test2 = binding.objectreference.getFromGetter('persistent', 1);
174
+ const configObjA = { keyType: enumType.INT, valType: enumType.JS, key: 0, val: 'hello' };
175
+ const configObjB = { keyType: enumType.INT, valType: enumType.JS, key: 1, val: 'world' };
176
+ binding.objectreference.setObject(configObjA);
177
+ binding.objectreference.setObject(configObjB);
156
178
 
157
- assert.deepEqual({ 1: 'hello world' }, test);
158
- assert.equal('hello world', test2);
159
- assert.equal(test[1], test2);
160
- },
161
- () => {
162
- binding.objectreference.setObjects(0, 'hello');
163
- binding.objectreference.setObjects(1, 'world');
164
179
  const test = binding.objectreference.getFromValue('persistent');
165
- const test2 = binding.objectreference.getFromGetter('persistent', 0);
166
- const test3 = binding.objectreference.getFromGetter('persistent', 1);
180
+ const test2 = binding.objectreference.getFromGetters('persistent', configObjA);
181
+ const test3 = binding.objectreference.getFromGetters('persistent', configObjB);
167
182
 
168
183
  assert.deepEqual({ 1: 'world' }, test);
169
184
  assert.equal(undefined, test2);
170
185
  assert.equal('world', test3);
171
186
  },
172
187
  () => {
173
- binding.objectreference.setObjects('hello', 'world');
188
+ binding.objectreference.setObject({ keyType: enumType.CPP_STR, valType: enumType.JS, key: 'hello', val: 'world' });
174
189
  assert.doesNotThrow(
175
190
  () => {
176
191
  let rcount = binding.objectreference.unrefObjects('persistent');
@@ -196,45 +211,33 @@ function test (binding) {
196
211
 
197
212
  'References',
198
213
  () => {
199
- binding.objectreference.setObjects('hello', 'world');
200
- const test = binding.objectreference.getFromValue();
201
- const test2 = binding.objectreference.getFromGetter('hello');
202
-
203
- assert.deepEqual({ hello: 'world' }, test);
204
- assert.equal('world', test2);
205
- assert.equal(test.hello, test2);
214
+ for (const configObject of configObjects) {
215
+ binding.objectreference.setObject(configObject);
216
+ const test = binding.objectreference.getFromValue();
217
+ const test2 = binding.objectreference.getFromGetters('reference', configObject);
218
+ const assertObject = {
219
+ [configObject.key]: configObject.val
220
+ };
221
+ assert.deepEqual(assertObject, test);
222
+ assert.equal(configObject.val, test2);
223
+ }
206
224
  },
207
225
  () => {
208
- binding.objectreference.setObjects('hello', 'world', 'javascript');
226
+ const configObjA = { keyType: enumType.INT, valType: enumType.JS, key: 0, val: 'hello' };
227
+ const configObjB = { keyType: enumType.INT, valType: enumType.JS, key: 1, val: 'world' };
228
+ binding.objectreference.setObject(configObjA);
229
+ binding.objectreference.setObject(configObjB);
209
230
  const test = binding.objectreference.getFromValue();
210
- const test2 = binding.objectreference.getFromValue('hello');
211
231
 
212
- assert.deepEqual({ hello: 'world' }, test);
213
- assert.deepEqual({ hello: 'world' }, test2);
214
- assert.deepEqual(test, test2);
215
- },
216
- () => {
217
- binding.objectreference.setObjects(1, 'hello world');
218
- const test = binding.objectreference.getFromValue();
219
- const test2 = binding.objectreference.getFromGetter(1);
220
-
221
- assert.deepEqual({ 1: 'hello world' }, test);
222
- assert.equal('hello world', test2);
223
- assert.equal(test[1], test2);
224
- },
225
- () => {
226
- binding.objectreference.setObjects(0, 'hello');
227
- binding.objectreference.setObjects(1, 'world');
228
- const test = binding.objectreference.getFromValue();
229
- const test2 = binding.objectreference.getFromGetter(0);
230
- const test3 = binding.objectreference.getFromGetter(1);
232
+ const test2 = binding.objectreference.getFromGetters('reference', configObjA);
233
+ const test3 = binding.objectreference.getFromGetters('reference', configObjB);
231
234
 
232
235
  assert.deepEqual({ 1: 'world' }, test);
233
236
  assert.equal(undefined, test2);
234
237
  assert.equal('world', test3);
235
238
  },
236
239
  () => {
237
- binding.objectreference.setObjects('hello', 'world');
240
+ binding.objectreference.setObject({ keyType: enumType.CPP_STR, valType: enumType.JS, key: 'hello', val: 'world' });
238
241
  assert.doesNotThrow(
239
242
  () => {
240
243
  let rcount = binding.objectreference.unrefObjects('references');
@@ -12,6 +12,10 @@ void StaticSetter(const Napi::CallbackInfo& /*info*/,
12
12
  testStaticContextRef.Value().Set("value", value);
13
13
  }
14
14
 
15
+ void StaticMethodVoidCb(const Napi::CallbackInfo& info) {
16
+ StaticSetter(info, info[0].As<Napi::Number>());
17
+ }
18
+
15
19
  Napi::Value TestStaticMethod(const Napi::CallbackInfo& info) {
16
20
  std::string str = MaybeUnwrap(info[0].ToString());
17
21
  return Napi::String::New(info.Env(), str + " static");
@@ -53,6 +57,15 @@ class Test : public Napi::ObjectWrap<Test> {
53
57
  return static_cast<Test*>(info.Data())->Getter(info);
54
58
  }
55
59
 
60
+ static Napi::Value CanUnWrap(const Napi::CallbackInfo& info) {
61
+ Napi::Object wrappedObject = info[0].As<Napi::Object>();
62
+ std::string expectedString = info[1].As<Napi::String>();
63
+ Test* nativeObject = Test::Unwrap(wrappedObject);
64
+ std::string strVal = MaybeUnwrap(nativeObject->Getter(info).ToString());
65
+
66
+ return Napi::Boolean::New(info.Env(), strVal == expectedString);
67
+ }
68
+
56
69
  void Setter(const Napi::CallbackInfo& /*info*/, const Napi::Value& value) {
57
70
  value_ = MaybeUnwrap(value.ToString());
58
71
  }
@@ -115,7 +128,8 @@ class Test : public Napi::ObjectWrap<Test> {
115
128
  Napi::Symbol::New(env, "kTestStaticMethodTInternal");
116
129
  Napi::Symbol kTestStaticVoidMethodTInternal =
117
130
  Napi::Symbol::New(env, "kTestStaticVoidMethodTInternal");
118
-
131
+ Napi::Symbol kTestStaticVoidMethodInternal =
132
+ Napi::Symbol::New(env, "kTestStaticVoidMethodInternal");
119
133
  Napi::Symbol kTestValueInternal =
120
134
  Napi::Symbol::New(env, "kTestValueInternal");
121
135
  Napi::Symbol kTestAccessorInternal =
@@ -147,6 +161,8 @@ class Test : public Napi::ObjectWrap<Test> {
147
161
  kTestStaticMethodInternal),
148
162
  StaticValue("kTestStaticMethodTInternal",
149
163
  kTestStaticMethodTInternal),
164
+ StaticValue("kTestStaticVoidMethodInternal",
165
+ kTestStaticVoidMethodInternal),
150
166
  StaticValue("kTestStaticVoidMethodTInternal",
151
167
  kTestStaticVoidMethodTInternal),
152
168
  StaticValue("kTestValueInternal", kTestValueInternal),
@@ -184,7 +200,11 @@ class Test : public Napi::ObjectWrap<Test> {
184
200
  "testStaticGetSetT"),
185
201
  StaticAccessor<&StaticGetter, &StaticSetter>(
186
202
  kTestStaticAccessorTInternal),
187
-
203
+ StaticMethod(
204
+ "testStaticVoidMethod", &StaticMethodVoidCb, napi_default),
205
+ StaticMethod(kTestStaticVoidMethodInternal,
206
+ &StaticMethodVoidCb,
207
+ napi_default),
188
208
  StaticMethod(
189
209
  "testStaticMethod", &TestStaticMethod, napi_enumerable),
190
210
  StaticMethod(kTestStaticMethodInternal,
@@ -195,7 +215,7 @@ class Test : public Napi::ObjectWrap<Test> {
195
215
  StaticMethod<&TestStaticVoidMethodT>(
196
216
  kTestStaticVoidMethodTInternal),
197
217
  StaticMethod<&TestStaticMethodT>(kTestStaticMethodTInternal),
198
-
218
+ StaticMethod("canUnWrap", &CanUnWrap, napi_enumerable),
199
219
  InstanceValue("testValue",
200
220
  Napi::Boolean::New(env, true),
201
221
  napi_enumerable),
@@ -210,6 +210,10 @@ async function test (binding) {
210
210
  };
211
211
 
212
212
  const testStaticMethod = (clazz) => {
213
+ clazz.testStaticVoidMethod(52);
214
+ assert.strictEqual(clazz.testStaticGetter, 52);
215
+ clazz[clazz.kTestStaticVoidMethodInternal](94);
216
+ assert.strictEqual(clazz.testStaticGetter, 94);
213
217
  assert.strictEqual(clazz.testStaticMethod('method'), 'method static');
214
218
  assert.strictEqual(clazz[clazz.kTestStaticMethodInternal]('method'), 'method static internal');
215
219
  clazz.testStaticVoidMethodT('static method<>(const char*)');
@@ -224,7 +228,8 @@ async function test (binding) {
224
228
  'testStaticValue',
225
229
  'testStaticGetter',
226
230
  'testStaticGetSet',
227
- 'testStaticMethod'
231
+ 'testStaticMethod',
232
+ 'canUnWrap'
228
233
  ]);
229
234
 
230
235
  // for..in
@@ -238,7 +243,8 @@ async function test (binding) {
238
243
  'testStaticValue',
239
244
  'testStaticGetter',
240
245
  'testStaticGetSet',
241
- 'testStaticMethod'
246
+ 'testStaticMethod',
247
+ 'canUnWrap'
242
248
  ]);
243
249
  }
244
250
  };
@@ -260,6 +266,11 @@ async function test (binding) {
260
266
  ]);
261
267
  }
262
268
 
269
+ const testUnwrap = (obj, clazz) => {
270
+ obj.testSetter = 'unwrapTest';
271
+ assert(clazz.canUnWrap(obj, 'unwrapTest'));
272
+ };
273
+
263
274
  const testObj = (obj, clazz) => {
264
275
  testValue(obj, clazz);
265
276
  testAccessor(obj, clazz);
@@ -268,6 +279,7 @@ async function test (binding) {
268
279
  testEnumerables(obj, clazz);
269
280
 
270
281
  testConventions(obj, clazz);
282
+ testUnwrap(obj, clazz);
271
283
  };
272
284
 
273
285
  async function testClass (clazz) {
@@ -1,9 +1,60 @@
1
+ #include "assert.h"
1
2
  #include "napi.h"
2
-
3
+ #include "test_helper.h"
3
4
  using namespace Napi;
4
5
 
5
6
  static Reference<Buffer<uint8_t>> weak;
6
7
 
8
+ static void RefMoveAssignTests(const Napi::CallbackInfo& info) {
9
+ Napi::Object obj = Napi::Object::New(info.Env());
10
+ obj.Set("tPro", "tTEST");
11
+ Napi::Reference<Napi::Object> ref = Napi::Reference<Napi::Object>::New(obj);
12
+ ref.SuppressDestruct();
13
+
14
+ napi_ref obj_ref = static_cast<napi_ref>(ref);
15
+ Napi::Reference<Napi::Object> existingRef =
16
+ Napi::Reference<Napi::Object>(info.Env(), obj_ref);
17
+ assert(ref == existingRef);
18
+ assert(!(ref != existingRef));
19
+
20
+ std::string val =
21
+ MaybeUnwrap(existingRef.Value().Get("tPro")).As<Napi::String>();
22
+ assert(val == "tTEST");
23
+ // ------------------------------------------------------------ //
24
+ Napi::Reference<Napi::Object> copyMoveRef = std::move(existingRef);
25
+ assert(copyMoveRef == ref);
26
+
27
+ Napi::Reference<Napi::Object> copyAssignRef;
28
+ copyAssignRef = std::move(copyMoveRef);
29
+ assert(copyAssignRef == ref);
30
+ }
31
+
32
+ static void ReferenceRefTests(const Napi::CallbackInfo& info) {
33
+ Napi::Object obj = Napi::Object::New(info.Env());
34
+ Napi::Reference<Napi::Object> ref = Napi::Reference<Napi::Object>::New(obj);
35
+
36
+ assert(ref.Ref() == 1);
37
+ assert(ref.Unref() == 0);
38
+ }
39
+
40
+ static void ReferenceResetTests(const Napi::CallbackInfo& info) {
41
+ Napi::Object obj = Napi::Object::New(info.Env());
42
+ Napi::Reference<Napi::Object> ref = Napi::Reference<Napi::Object>::New(obj);
43
+ assert(!ref.IsEmpty());
44
+
45
+ ref.Reset();
46
+ assert(ref.IsEmpty());
47
+
48
+ Napi::Object newObject = Napi::Object::New(info.Env());
49
+ newObject.Set("n-api", "node");
50
+
51
+ ref.Reset(newObject, 1);
52
+ assert(!ref.IsEmpty());
53
+
54
+ std::string val = MaybeUnwrap(ref.Value().Get("n-api")).As<Napi::String>();
55
+ assert(val == "node");
56
+ }
57
+
7
58
  void CreateWeakArray(const CallbackInfo& info) {
8
59
  weak = Weak(Buffer<uint8_t>::New(info.Env(), 1));
9
60
  weak.SuppressDestruct();
@@ -20,5 +71,8 @@ Object InitReference(Env env) {
20
71
  exports["createWeakArray"] = Function::New(env, CreateWeakArray);
21
72
  exports["accessWeakArrayEmpty"] = Function::New(env, AccessWeakArrayEmpty);
22
73
 
74
+ exports["refMoveAssignTest"] = Function::New(env, RefMoveAssignTests);
75
+ exports["referenceRefTest"] = Function::New(env, ReferenceRefTests);
76
+ exports["refResetTest"] = Function::New(env, ReferenceResetTests);
23
77
  return exports;
24
78
  }
@@ -9,6 +9,12 @@ function test (binding) {
9
9
  return testUtil.runGCTests([
10
10
  'test reference',
11
11
  () => binding.reference.createWeakArray(),
12
- () => assert.strictEqual(true, binding.reference.accessWeakArrayEmpty())
12
+ () => assert.strictEqual(true, binding.reference.accessWeakArrayEmpty()),
13
+ 'test reference move op',
14
+ () => binding.reference.refMoveAssignTest(),
15
+ 'test reference ref',
16
+ () => binding.reference.referenceRefTest(),
17
+ 'test reference reset',
18
+ () => binding.reference.refResetTest()
13
19
  ]);
14
20
  }
@@ -0,0 +1,66 @@
1
+ #include "napi.h"
2
+
3
+ #if (NAPI_VERSION > 7)
4
+
5
+ using namespace Napi;
6
+
7
+ static const napi_type_tag type_tags[5] = {
8
+ {0xdaf987b3cc62481a, 0xb745b0497f299531},
9
+ {0xbb7936c374084d9b, 0xa9548d0762eeedb9},
10
+ {0xa5ed9ce2e4c00c38, 0},
11
+ {0, 0},
12
+ {0xa5ed9ce2e4c00c38, 0xdaf987b3cc62481a},
13
+ };
14
+
15
+ template <TypeTaggable Factory(Env), typename NodeApiClass>
16
+ class TestTypeTaggable {
17
+ public:
18
+ static Value TypeTaggedInstance(const CallbackInfo& info) {
19
+ TypeTaggable instance = Factory(info.Env());
20
+ uint32_t type_index = info[0].As<Number>().Int32Value();
21
+
22
+ instance.TypeTag(&type_tags[type_index]);
23
+
24
+ return instance;
25
+ }
26
+
27
+ static Value CheckTypeTag(const CallbackInfo& info) {
28
+ uint32_t type_index = info[0].As<Number>().Int32Value();
29
+ TypeTaggable instance = info[1].As<NodeApiClass>();
30
+
31
+ return Boolean::New(info.Env(),
32
+ instance.CheckTypeTag(&type_tags[type_index]));
33
+ }
34
+ };
35
+
36
+ TypeTaggable ObjectFactory(Env env) {
37
+ return Object::New(env);
38
+ }
39
+
40
+ TypeTaggable ExternalFactory(Env env) {
41
+ // External does not accept a nullptr for its data.
42
+ return External<void>::New(env, reinterpret_cast<void*>(0x1));
43
+ }
44
+
45
+ using TestObject = TestTypeTaggable<ObjectFactory, Object>;
46
+ using TestExternal = TestTypeTaggable<ExternalFactory, External<void>>;
47
+
48
+ Object InitTypeTaggable(Env env) {
49
+ Object exports = Object::New(env);
50
+
51
+ Object external = Object::New(env);
52
+ exports["external"] = external;
53
+ external["checkTypeTag"] = Function::New(env, &TestExternal::CheckTypeTag);
54
+ external["typeTaggedInstance"] =
55
+ Function::New(env, &TestExternal::TypeTaggedInstance);
56
+
57
+ Object object = Object::New(env);
58
+ exports["object"] = object;
59
+ object["checkTypeTag"] = Function::New(env, &TestObject::CheckTypeTag);
60
+ object["typeTaggedInstance"] =
61
+ Function::New(env, &TestObject::TypeTaggedInstance);
62
+
63
+ return exports;
64
+ }
65
+
66
+ #endif
@@ -0,0 +1,60 @@
1
+ 'use strict';
2
+
3
+ const assert = require('assert');
4
+
5
+ module.exports = require('./common').runTest(test);
6
+
7
+ function testTypeTaggable ({ typeTaggedInstance, checkTypeTag }) {
8
+ const obj1 = typeTaggedInstance(0);
9
+ const obj2 = typeTaggedInstance(1);
10
+
11
+ // Verify that type tags are correctly accepted.
12
+ assert.strictEqual(checkTypeTag(0, obj1), true);
13
+ assert.strictEqual(checkTypeTag(1, obj2), true);
14
+
15
+ // Verify that wrongly tagged objects are rejected.
16
+ assert.strictEqual(checkTypeTag(0, obj2), false);
17
+ assert.strictEqual(checkTypeTag(1, obj1), false);
18
+
19
+ // Verify that untagged objects are rejected.
20
+ assert.strictEqual(checkTypeTag(0, {}), false);
21
+ assert.strictEqual(checkTypeTag(1, {}), false);
22
+
23
+ // Node v14 and v16 have an issue checking type tags if the `upper` in
24
+ // `napi_type_tag` is 0, so these tests can only be performed on Node version
25
+ // >=18. See:
26
+ // - https://github.com/nodejs/node/issues/43786
27
+ // - https://github.com/nodejs/node/pull/43788
28
+ const nodeVersion = parseInt(process.versions.node.split('.')[0]);
29
+ if (nodeVersion < 18) {
30
+ return;
31
+ }
32
+
33
+ const obj3 = typeTaggedInstance(2);
34
+ const obj4 = typeTaggedInstance(3);
35
+
36
+ // Verify that untagged objects are rejected.
37
+ assert.strictEqual(checkTypeTag(0, {}), false);
38
+ assert.strictEqual(checkTypeTag(1, {}), false);
39
+
40
+ // Verify that type tags are correctly accepted.
41
+ assert.strictEqual(checkTypeTag(0, obj1), true);
42
+ assert.strictEqual(checkTypeTag(1, obj2), true);
43
+ assert.strictEqual(checkTypeTag(2, obj3), true);
44
+ assert.strictEqual(checkTypeTag(3, obj4), true);
45
+
46
+ // Verify that wrongly tagged objects are rejected.
47
+ assert.strictEqual(checkTypeTag(0, obj2), false);
48
+ assert.strictEqual(checkTypeTag(1, obj1), false);
49
+ assert.strictEqual(checkTypeTag(0, obj3), false);
50
+ assert.strictEqual(checkTypeTag(1, obj4), false);
51
+ assert.strictEqual(checkTypeTag(2, obj4), false);
52
+ assert.strictEqual(checkTypeTag(3, obj3), false);
53
+ assert.strictEqual(checkTypeTag(4, obj3), false);
54
+ }
55
+
56
+ // eslint-disable-next-line camelcase
57
+ function test ({ type_taggable }) {
58
+ testTypeTaggable(type_taggable.external);
59
+ testTypeTaggable(type_taggable.object);
60
+ }
@@ -0,0 +1,60 @@
1
+ #include "common/test_helper.h"
2
+ #include "napi.h"
3
+
4
+ using namespace Napi;
5
+
6
+ #define TYPE_CAST_TYPES(V) \
7
+ V(Boolean) \
8
+ V(Number) \
9
+ V(BigInt) \
10
+ V(Date) \
11
+ V(String) \
12
+ V(Symbol) \
13
+ V(Object) \
14
+ V(Array) \
15
+ V(ArrayBuffer) \
16
+ V(TypedArray) \
17
+ V(DataView) \
18
+ V(Function) \
19
+ V(Promise)
20
+
21
+ // The following types are tested individually.
22
+ // External
23
+ // TypedArrayOf
24
+ // Buffer
25
+
26
+ namespace {
27
+ #define V(Type) \
28
+ void TypeCast##Type(const CallbackInfo& info) { USE(info[0].As<Type>()); }
29
+ TYPE_CAST_TYPES(V)
30
+ #undef V
31
+
32
+ void TypeCastBuffer(const CallbackInfo& info) {
33
+ USE(info[0].As<Buffer<uint8_t>>());
34
+ }
35
+
36
+ void TypeCastExternal(const CallbackInfo& info) {
37
+ USE(info[0].As<External<void>>());
38
+ }
39
+
40
+ void TypeCastTypeArrayOfUint8(const CallbackInfo& info) {
41
+ USE(info[0].As<TypedArrayOf<uint8_t>>());
42
+ }
43
+ } // namespace
44
+
45
+ Object InitValueTypeCast(Env env, Object exports) {
46
+ exports["external"] = External<void>::New(env, nullptr);
47
+
48
+ #define V(Type) exports["typeCast" #Type] = Function::New(env, TypeCast##Type);
49
+ TYPE_CAST_TYPES(V)
50
+ #undef V
51
+
52
+ exports["typeCastBuffer"] = Function::New(env, TypeCastBuffer);
53
+ exports["typeCastExternal"] = Function::New(env, TypeCastExternal);
54
+ exports["typeCastTypeArrayOfUint8"] =
55
+ Function::New(env, TypeCastTypeArrayOfUint8);
56
+
57
+ return exports;
58
+ }
59
+
60
+ NODE_API_MODULE(addon, InitValueTypeCast)