koffi 2.4.2 → 2.5.0-beta.2

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 (63) hide show
  1. package/build/2.5.0-beta.2/koffi_darwin_arm64/koffi.node +0 -0
  2. package/build/2.5.0-beta.2/koffi_darwin_x64/koffi.node +0 -0
  3. package/build/2.5.0-beta.2/koffi_freebsd_arm64/koffi.node +0 -0
  4. package/build/2.5.0-beta.2/koffi_freebsd_ia32/koffi.node +0 -0
  5. package/build/2.5.0-beta.2/koffi_freebsd_x64/koffi.node +0 -0
  6. package/build/2.5.0-beta.2/koffi_linux_arm32hf/koffi.node +0 -0
  7. package/build/2.5.0-beta.2/koffi_linux_arm64/koffi.node +0 -0
  8. package/build/2.5.0-beta.2/koffi_linux_ia32/koffi.node +0 -0
  9. package/build/2.5.0-beta.2/koffi_linux_riscv64hf64/koffi.node +0 -0
  10. package/build/2.5.0-beta.2/koffi_linux_x64/koffi.node +0 -0
  11. package/build/2.5.0-beta.2/koffi_openbsd_ia32/koffi.node +0 -0
  12. package/build/{2.4.2 → 2.5.0-beta.2}/koffi_openbsd_x64/koffi.node +0 -0
  13. package/build/2.5.0-beta.2/koffi_win32_arm64/koffi.node +0 -0
  14. package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_ia32/koffi.node +0 -0
  15. package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_x64/koffi.node +0 -0
  16. package/build/2.5.0-beta.2/koffi_win32_x64/koffi.pdb +0 -0
  17. package/doc/callbacks.md +1 -1
  18. package/doc/conf.py +1 -1
  19. package/doc/functions.md +1 -1
  20. package/doc/index.rst +1 -0
  21. package/doc/parameters.md +1 -1
  22. package/doc/pointers.md +1 -1
  23. package/doc/unions.md +187 -0
  24. package/package.json +1 -1
  25. package/src/core/libcc/libcc.cc +58 -54
  26. package/src/core/libcc/libcc.hh +33 -19
  27. package/src/koffi/src/abi_x86.cc +31 -4
  28. package/src/koffi/src/call.cc +42 -22
  29. package/src/koffi/src/ffi.cc +259 -311
  30. package/src/koffi/src/ffi.hh +3 -1
  31. package/src/koffi/src/util.cc +20 -13
  32. package/src/koffi/src/util.hh +5 -2
  33. package/vendor/node-addon-api/CHANGELOG.md +31 -0
  34. package/vendor/node-addon-api/README.md +3 -2
  35. package/vendor/node-addon-api/doc/async_worker.md +1 -0
  36. package/vendor/node-addon-api/doc/creating_a_release.md +21 -0
  37. package/vendor/node-addon-api/doc/value.md +7 -0
  38. package/vendor/node-addon-api/napi-inl.h +23 -7
  39. package/vendor/node-addon-api/package.json +9 -1
  40. package/vendor/node-addon-api/test/async_progress_queue_worker.cc +155 -0
  41. package/vendor/node-addon-api/test/async_progress_queue_worker.js +134 -0
  42. package/vendor/node-addon-api/test/async_progress_worker.cc +155 -0
  43. package/vendor/node-addon-api/test/async_progress_worker.js +134 -0
  44. package/vendor/node-addon-api/test/common/index.js +45 -0
  45. package/vendor/node-addon-api/test/objectwrap.js +9 -0
  46. package/build/2.4.2/koffi_darwin_arm64/koffi.node +0 -0
  47. package/build/2.4.2/koffi_darwin_x64/koffi.node +0 -0
  48. package/build/2.4.2/koffi_freebsd_arm64/koffi.node +0 -0
  49. package/build/2.4.2/koffi_freebsd_ia32/koffi.node +0 -0
  50. package/build/2.4.2/koffi_freebsd_x64/koffi.node +0 -0
  51. package/build/2.4.2/koffi_linux_arm32hf/koffi.node +0 -0
  52. package/build/2.4.2/koffi_linux_arm64/koffi.node +0 -0
  53. package/build/2.4.2/koffi_linux_ia32/koffi.node +0 -0
  54. package/build/2.4.2/koffi_linux_riscv64hf64/koffi.node +0 -0
  55. package/build/2.4.2/koffi_linux_x64/koffi.node +0 -0
  56. package/build/2.4.2/koffi_openbsd_ia32/koffi.node +0 -0
  57. package/build/2.4.2/koffi_win32_arm64/koffi.node +0 -0
  58. /package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_arm64/koffi.exp +0 -0
  59. /package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_arm64/koffi.lib +0 -0
  60. /package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_ia32/koffi.exp +0 -0
  61. /package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_ia32/koffi.lib +0 -0
  62. /package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_x64/koffi.exp +0 -0
  63. /package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_x64/koffi.lib +0 -0
@@ -2,6 +2,7 @@
2
2
 
3
3
  #include <chrono>
4
4
  #include <condition_variable>
5
+ #include <iostream>
5
6
  #include <mutex>
6
7
  #include <thread>
7
8
 
@@ -15,6 +16,157 @@ struct ProgressData {
15
16
  size_t progress;
16
17
  };
17
18
 
19
+ class TestWorkerWithNoCb : public AsyncProgressWorker<ProgressData> {
20
+ public:
21
+ static void DoWork(const CallbackInfo& info) {
22
+ switch (info.Length()) {
23
+ case 1: {
24
+ Function cb = info[0].As<Function>();
25
+ TestWorkerWithNoCb* worker = new TestWorkerWithNoCb(info.Env(), cb);
26
+ worker->Queue();
27
+ } break;
28
+
29
+ case 2: {
30
+ std::string resName = info[0].As<String>();
31
+ Function cb = info[1].As<Function>();
32
+ TestWorkerWithNoCb* worker =
33
+ new TestWorkerWithNoCb(info.Env(), resName.c_str(), cb);
34
+ worker->Queue();
35
+ } break;
36
+
37
+ case 3: {
38
+ std::string resName = info[0].As<String>();
39
+ Object resObject = info[1].As<Object>();
40
+ Function cb = info[2].As<Function>();
41
+ TestWorkerWithNoCb* worker =
42
+ new TestWorkerWithNoCb(info.Env(), resName.c_str(), resObject, cb);
43
+ worker->Queue();
44
+ } break;
45
+
46
+ default:
47
+
48
+ break;
49
+ }
50
+ }
51
+
52
+ protected:
53
+ void Execute(const ExecutionProgress& progress) override {
54
+ ProgressData data{1};
55
+ progress.Send(&data, 1);
56
+ }
57
+
58
+ void OnProgress(const ProgressData*, size_t /* count */) override {
59
+ _cb.Call({});
60
+ }
61
+
62
+ private:
63
+ TestWorkerWithNoCb(Napi::Env env, Function cb) : AsyncProgressWorker(env) {
64
+ _cb.Reset(cb, 1);
65
+ }
66
+ TestWorkerWithNoCb(Napi::Env env, const char* resourceName, Function cb)
67
+ : AsyncProgressWorker(env, resourceName) {
68
+ _cb.Reset(cb, 1);
69
+ }
70
+ TestWorkerWithNoCb(Napi::Env env,
71
+ const char* resourceName,
72
+ const Object& resourceObject,
73
+ Function cb)
74
+ : AsyncProgressWorker(env, resourceName, resourceObject) {
75
+ _cb.Reset(cb, 1);
76
+ }
77
+ FunctionReference _cb;
78
+ };
79
+
80
+ class TestWorkerWithRecv : public AsyncProgressWorker<ProgressData> {
81
+ public:
82
+ static void DoWork(const CallbackInfo& info) {
83
+ switch (info.Length()) {
84
+ case 2: {
85
+ Object recv = info[0].As<Object>();
86
+ Function cb = info[1].As<Function>();
87
+ TestWorkerWithRecv* worker = new TestWorkerWithRecv(recv, cb);
88
+ worker->Queue();
89
+ } break;
90
+
91
+ case 3: {
92
+ Object recv = info[0].As<Object>();
93
+ Function cb = info[1].As<Function>();
94
+ std::string resName = info[2].As<String>();
95
+ TestWorkerWithRecv* worker =
96
+ new TestWorkerWithRecv(recv, cb, resName.c_str());
97
+ worker->Queue();
98
+ } break;
99
+
100
+ case 4: {
101
+ Object recv = info[0].As<Object>();
102
+ Function cb = info[1].As<Function>();
103
+ std::string resName = info[2].As<String>();
104
+ Object resObject = info[3].As<Object>();
105
+ TestWorkerWithRecv* worker =
106
+ new TestWorkerWithRecv(recv, cb, resName.c_str(), resObject);
107
+ worker->Queue();
108
+ } break;
109
+
110
+ default:
111
+
112
+ break;
113
+ }
114
+ }
115
+
116
+ protected:
117
+ void Execute(const ExecutionProgress&) override {}
118
+
119
+ void OnProgress(const ProgressData*, size_t /* count */) override {}
120
+
121
+ private:
122
+ TestWorkerWithRecv(const Object& recv, const Function& cb)
123
+ : AsyncProgressWorker(recv, cb) {}
124
+ TestWorkerWithRecv(const Object& recv,
125
+ const Function& cb,
126
+ const char* resourceName)
127
+ : AsyncProgressWorker(recv, cb, resourceName) {}
128
+ TestWorkerWithRecv(const Object& recv,
129
+ const Function& cb,
130
+ const char* resourceName,
131
+ const Object& resourceObject)
132
+ : AsyncProgressWorker(recv, cb, resourceName, resourceObject) {}
133
+ };
134
+
135
+ class TestWorkerWithCb : public AsyncProgressWorker<ProgressData> {
136
+ public:
137
+ static void DoWork(const CallbackInfo& info) {
138
+ switch (info.Length()) {
139
+ case 1: {
140
+ Function cb = info[0].As<Function>();
141
+ TestWorkerWithCb* worker = new TestWorkerWithCb(cb);
142
+ worker->Queue();
143
+ } break;
144
+
145
+ case 2: {
146
+ Function cb = info[0].As<Function>();
147
+ std::string asyncResName = info[1].As<String>();
148
+ TestWorkerWithCb* worker =
149
+ new TestWorkerWithCb(cb, asyncResName.c_str());
150
+ worker->Queue();
151
+ } break;
152
+
153
+ default:
154
+
155
+ break;
156
+ }
157
+ }
158
+
159
+ protected:
160
+ void Execute(const ExecutionProgress&) override {}
161
+
162
+ void OnProgress(const ProgressData*, size_t /* count */) override {}
163
+
164
+ private:
165
+ TestWorkerWithCb(Function cb) : AsyncProgressWorker(cb) {}
166
+ TestWorkerWithCb(Function cb, const char* res_name)
167
+ : AsyncProgressWorker(cb, res_name) {}
168
+ };
169
+
18
170
  class TestWorker : public AsyncProgressWorker<ProgressData> {
19
171
  public:
20
172
  static void DoWork(const CallbackInfo& info) {
@@ -196,6 +348,9 @@ Object InitAsyncProgressWorker(Env env) {
196
348
  exports["doMalignTest"] = Function::New(env, MalignWorker::DoWork);
197
349
  exports["doSignalAfterProgressTest"] =
198
350
  Function::New(env, SignalAfterProgressTestWorker::DoWork);
351
+ exports["runWorkerNoCb"] = Function::New(env, TestWorkerWithNoCb::DoWork);
352
+ exports["runWorkerWithRecv"] = Function::New(env, TestWorkerWithRecv::DoWork);
353
+ exports["runWorkerWithCb"] = Function::New(env, TestWorkerWithCb::DoWork);
199
354
  return exports;
200
355
  }
201
356
 
@@ -4,12 +4,146 @@ const common = require('./common');
4
4
  const assert = require('assert');
5
5
 
6
6
  module.exports = common.runTest(test);
7
+ const nodeVersion = process.versions.node.split('.')[0];
8
+
9
+ let asyncHooks;
10
+ function checkAsyncHooks () {
11
+ if (nodeVersion >= 8) {
12
+ if (asyncHooks === undefined) {
13
+ asyncHooks = require('async_hooks');
14
+ }
15
+ return true;
16
+ }
17
+ return false;
18
+ }
7
19
 
8
20
  async function test ({ asyncprogressworker }) {
9
21
  await success(asyncprogressworker);
10
22
  await fail(asyncprogressworker);
11
23
  await signalTest(asyncprogressworker.doMalignTest);
12
24
  await signalTest(asyncprogressworker.doSignalAfterProgressTest);
25
+
26
+ await asyncProgressWorkerCallbackOverloads(asyncprogressworker.runWorkerWithCb);
27
+ await asyncProgressWorkerRecvOverloads(asyncprogressworker.runWorkerWithRecv);
28
+ await asyncProgressWorkerNoCbOverloads(asyncprogressworker.runWorkerNoCb);
29
+ }
30
+
31
+ async function asyncProgressWorkerCallbackOverloads (bindingFunction) {
32
+ bindingFunction(common.mustCall());
33
+ if (!checkAsyncHooks()) {
34
+ return;
35
+ }
36
+
37
+ const hooks = common.installAysncHooks('cbResources');
38
+
39
+ const triggerAsyncId = asyncHooks.executionAsyncId();
40
+ await new Promise((resolve, reject) => {
41
+ bindingFunction(common.mustCall(), 'cbResources');
42
+ hooks.then(actual => {
43
+ assert.deepStrictEqual(actual, [
44
+ {
45
+ eventName: 'init',
46
+ type: 'cbResources',
47
+ triggerAsyncId: triggerAsyncId,
48
+ resource: {}
49
+ },
50
+ { eventName: 'before' },
51
+ { eventName: 'after' },
52
+ { eventName: 'destroy' }
53
+ ]);
54
+ }).catch(common.mustNotCall());
55
+ resolve();
56
+ });
57
+ }
58
+
59
+ async function asyncProgressWorkerRecvOverloads (bindingFunction) {
60
+ const recvObject = {
61
+ a: 4
62
+ };
63
+
64
+ function cb () {
65
+ assert.strictEqual(this.a, recvObject.a);
66
+ }
67
+
68
+ bindingFunction(recvObject, common.mustCall(cb));
69
+ if (!checkAsyncHooks()) {
70
+ return;
71
+ }
72
+ const asyncResources = [
73
+ { resName: 'cbRecvResources', resObject: {} },
74
+ { resName: 'cbRecvResourcesObject', resObject: { foo: 'bar' } }
75
+ ];
76
+
77
+ for (const asyncResource of asyncResources) {
78
+ const asyncResName = asyncResource.resName;
79
+ const asyncResObject = asyncResource.resObject;
80
+
81
+ const hooks = common.installAysncHooks(asyncResource.resName);
82
+ const triggerAsyncId = asyncHooks.executionAsyncId();
83
+ await new Promise((resolve, reject) => {
84
+ if (Object.keys(asyncResObject).length === 0) {
85
+ bindingFunction(recvObject, common.mustCall(cb), asyncResName);
86
+ } else {
87
+ bindingFunction(recvObject, common.mustCall(cb), asyncResName, asyncResObject);
88
+ }
89
+
90
+ hooks.then(actual => {
91
+ assert.deepStrictEqual(actual, [
92
+ {
93
+ eventName: 'init',
94
+ type: asyncResName,
95
+ triggerAsyncId: triggerAsyncId,
96
+ resource: asyncResObject
97
+ },
98
+ { eventName: 'before' },
99
+ { eventName: 'after' },
100
+ { eventName: 'destroy' }
101
+ ]);
102
+ }).catch(common.mustNotCall());
103
+ resolve();
104
+ });
105
+ }
106
+ }
107
+
108
+ async function asyncProgressWorkerNoCbOverloads (bindingFunction) {
109
+ bindingFunction(common.mustCall(() => {}));
110
+ if (!checkAsyncHooks()) {
111
+ return;
112
+ }
113
+ const asyncResources = [
114
+ { resName: 'noCbResources', resObject: {} },
115
+ { resName: 'noCbResourcesObject', resObject: { foo: 'bar' } }
116
+ ];
117
+
118
+ for (const asyncResource of asyncResources) {
119
+ const asyncResName = asyncResource.resName;
120
+ const asyncResObject = asyncResource.resObject;
121
+
122
+ const hooks = common.installAysncHooks(asyncResource.resName);
123
+ const triggerAsyncId = asyncHooks.executionAsyncId();
124
+ await new Promise((resolve, reject) => {
125
+ if (Object.keys(asyncResObject).length === 0) {
126
+ bindingFunction(asyncResName, common.mustCall(() => {}));
127
+ } else {
128
+ bindingFunction(asyncResName, asyncResObject, common.mustCall(() => {}));
129
+ }
130
+
131
+ hooks.then(actual => {
132
+ assert.deepStrictEqual(actual, [
133
+ {
134
+ eventName: 'init',
135
+ type: asyncResName,
136
+ triggerAsyncId: triggerAsyncId,
137
+ resource: asyncResObject
138
+ },
139
+ { eventName: 'before' },
140
+ { eventName: 'after' },
141
+ { eventName: 'destroy' }
142
+ ]);
143
+ }).catch(common.mustNotCall());
144
+ resolve();
145
+ });
146
+ }
13
147
  }
14
148
 
15
149
  function success (binding) {
@@ -32,6 +32,51 @@ function runCallChecks (exitCode) {
32
32
  if (failed.length) process.exit(1);
33
33
  }
34
34
 
35
+ exports.installAysncHooks = function (asyncResName) {
36
+ const asyncHooks = require('async_hooks');
37
+ return new Promise((resolve, reject) => {
38
+ let id;
39
+ const events = [];
40
+ /**
41
+ * TODO(legendecas): investigate why resolving & disabling hooks in
42
+ * destroy callback causing crash with case 'callbackscope.js'.
43
+ */
44
+ let destroyed = false;
45
+ const hook = asyncHooks.createHook({
46
+ init (asyncId, type, triggerAsyncId, resource) {
47
+ if (id === undefined && type === asyncResName) {
48
+ id = asyncId;
49
+ events.push({ eventName: 'init', type, triggerAsyncId, resource });
50
+ }
51
+ },
52
+ before (asyncId) {
53
+ if (asyncId === id) {
54
+ events.push({ eventName: 'before' });
55
+ }
56
+ },
57
+ after (asyncId) {
58
+ if (asyncId === id) {
59
+ events.push({ eventName: 'after' });
60
+ }
61
+ },
62
+ destroy (asyncId) {
63
+ if (asyncId === id) {
64
+ events.push({ eventName: 'destroy' });
65
+ destroyed = true;
66
+ }
67
+ }
68
+ }).enable();
69
+
70
+ const interval = setInterval(() => {
71
+ if (destroyed) {
72
+ hook.disable();
73
+ clearInterval(interval);
74
+ resolve(events);
75
+ }
76
+ }, 10);
77
+ });
78
+ };
79
+
35
80
  exports.mustCall = function (fn, exact) {
36
81
  return _mustCallInner(fn, exact, 'exact');
37
82
  };
@@ -24,6 +24,9 @@ async function test (binding) {
24
24
  obj.testSetter = 'instance getter 2';
25
25
  assert.strictEqual(obj.testGetter, 'instance getter 2');
26
26
  assert.strictEqual(obj.testGetterT, 'instance getter 2');
27
+
28
+ assert.throws(() => clazz.prototype.testGetter, /Invalid argument/);
29
+ assert.throws(() => clazz.prototype.testGetterT, /Invalid argument/);
27
30
  }
28
31
 
29
32
  // read write-only
@@ -61,6 +64,9 @@ async function test (binding) {
61
64
 
62
65
  obj.testGetSetT = 'instance getset 4';
63
66
  assert.strictEqual(obj.testGetSetT, 'instance getset 4');
67
+
68
+ assert.throws(() => { clazz.prototype.testGetSet = 'instance getset'; }, /Invalid argument/);
69
+ assert.throws(() => { clazz.prototype.testGetSetT = 'instance getset'; }, /Invalid argument/);
64
70
  }
65
71
 
66
72
  // rw symbol
@@ -98,6 +104,9 @@ async function test (binding) {
98
104
  assert.strictEqual(obj.testMethodT(), 'method<>(const char*)');
99
105
  obj[clazz.kTestVoidMethodTInternal]('method<>(Symbol)');
100
106
  assert.strictEqual(obj[clazz.kTestMethodTInternal](), 'method<>(Symbol)');
107
+ assert.throws(() => clazz.prototype.testMethod('method'));
108
+ assert.throws(() => clazz.prototype.testMethodT());
109
+ assert.throws(() => clazz.prototype.testVoidMethodT('method<>(const char*)'));
101
110
  };
102
111
 
103
112
  const testEnumerables = (obj, clazz) => {