emnapi 0.31.0 → 0.32.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.
- package/CMakeLists.txt +22 -1
- package/README.md +19 -16
- package/dist/library_napi.js +217 -9
- package/index.js +6 -0
- package/lib/wasm32/libemnapi-basic.a +0 -0
- package/lib/wasm32/libemnapi.a +0 -0
- package/lib/wasm32-emscripten/libemnapi-basic.a +0 -0
- package/lib/wasm32-emscripten/libemnapi-mt.a +0 -0
- package/lib/wasm32-emscripten/libemnapi.a +0 -0
- package/lib/wasm32-emscripten.txt +2 -2
- package/lib/wasm32-wasi/libemnapi-basic.a +0 -0
- package/lib/wasm32-wasi/libemnapi.a +0 -0
- package/package.json +1 -1
- package/src/async_cleanup_hook.c +126 -0
- package/src/async_context.c +53 -0
- package/src/async_work.c +236 -0
- package/src/emnapi.c +1 -1324
- package/src/emnapi_common.h +171 -0
- package/src/js_native_api.c +106 -0
- package/src/node_api.c +73 -0
- package/src/threadsafe_function.c +617 -0
package/CMakeLists.txt
CHANGED
|
@@ -26,7 +26,19 @@ set(UV_SRC
|
|
|
26
26
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/uv/unix/core.c"
|
|
27
27
|
)
|
|
28
28
|
|
|
29
|
-
set(
|
|
29
|
+
set(ENAPI_BASIC_SRC
|
|
30
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/js_native_api.c"
|
|
31
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/node_api.c"
|
|
32
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/emnapi.c"
|
|
33
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/async_cleanup_hook.c"
|
|
34
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/async_context.c"
|
|
35
|
+
)
|
|
36
|
+
set(EMNAPI_THREADS_SRC
|
|
37
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/async_work.c"
|
|
38
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/threadsafe_function.c"
|
|
39
|
+
)
|
|
40
|
+
set(EMNAPI_SRC ${ENAPI_BASIC_SRC} ${EMNAPI_THREADS_SRC})
|
|
41
|
+
|
|
30
42
|
set(EMNAPI_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
|
31
43
|
|
|
32
44
|
set(EMNAPI_JS_LIB "${CMAKE_CURRENT_SOURCE_DIR}/dist/library_napi.js")
|
|
@@ -37,6 +49,7 @@ else()
|
|
|
37
49
|
set(EMNAPI_MT_CFLAGS "-pthread")
|
|
38
50
|
endif()
|
|
39
51
|
|
|
52
|
+
set(EMNAPI_BASIC_TARGET_NAME "emnapi-basic")
|
|
40
53
|
set(EMNAPI_TARGET_NAME "emnapi")
|
|
41
54
|
set(EMNAPI_MT_TARGET_NAME "emnapi-mt")
|
|
42
55
|
set(DLMALLOC_TARGET_NAME "dlmalloc")
|
|
@@ -82,6 +95,12 @@ if(IS_EMSCRIPTEN)
|
|
|
82
95
|
target_link_options(${EMNAPI_TARGET_NAME} INTERFACE "--js-library=${EMNAPI_JS_LIB}")
|
|
83
96
|
endif()
|
|
84
97
|
|
|
98
|
+
add_library(${EMNAPI_BASIC_TARGET_NAME} STATIC ${ENAPI_BASIC_SRC})
|
|
99
|
+
target_include_directories(${EMNAPI_BASIC_TARGET_NAME} PUBLIC ${EMNAPI_INCLUDE})
|
|
100
|
+
if(IS_EMSCRIPTEN)
|
|
101
|
+
target_link_options(${EMNAPI_BASIC_TARGET_NAME} INTERFACE "--js-library=${EMNAPI_JS_LIB}")
|
|
102
|
+
endif()
|
|
103
|
+
|
|
85
104
|
if(IS_EMSCRIPTEN OR (CMAKE_C_COMPILER_TARGET STREQUAL "wasm32-wasi-threads"))
|
|
86
105
|
set(EMNAPI_BUILD_MT ON)
|
|
87
106
|
else()
|
|
@@ -118,6 +137,7 @@ endif()
|
|
|
118
137
|
# endif()
|
|
119
138
|
if(LIB_ARCH)
|
|
120
139
|
install(TARGETS ${EMNAPI_TARGET_NAME} DESTINATION "lib/${LIB_ARCH}")
|
|
140
|
+
install(TARGETS ${EMNAPI_BASIC_TARGET_NAME} DESTINATION "lib/${LIB_ARCH}")
|
|
121
141
|
if(EMNAPI_BUILD_MT)
|
|
122
142
|
install(TARGETS ${EMNAPI_MT_TARGET_NAME} DESTINATION "lib/${LIB_ARCH}")
|
|
123
143
|
endif()
|
|
@@ -150,6 +170,7 @@ install(FILES
|
|
|
150
170
|
if(EMNAPI_INSTALL_SRC)
|
|
151
171
|
install(FILES
|
|
152
172
|
${EMNAPI_SRC}
|
|
173
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/emnapi_common.h"
|
|
153
174
|
DESTINATION "src/${PROJECT_NAME}")
|
|
154
175
|
install(DIRECTORY
|
|
155
176
|
${CMAKE_CURRENT_SOURCE_DIR}/src/uv
|
package/README.md
CHANGED
|
@@ -348,12 +348,13 @@ fetch('./hello.wasm').then(res => res.arrayBuffer()).then(wasmBuffer => {
|
|
|
348
348
|
napi: napiModule.imports.napi,
|
|
349
349
|
emnapi: napiModule.imports.emnapi
|
|
350
350
|
})
|
|
351
|
-
}).then(({ instance }) => {
|
|
352
|
-
const binding = napiModule.init(
|
|
351
|
+
}).then(({ instance, module }) => {
|
|
352
|
+
const binding = napiModule.init({
|
|
353
353
|
instance, // WebAssembly.Instance
|
|
354
|
-
|
|
355
|
-
instance.exports.
|
|
356
|
-
|
|
354
|
+
module, // WebAssembly.Module
|
|
355
|
+
memory: instance.exports.memory, // WebAssembly.Memory
|
|
356
|
+
table: instance.exports.__indirect_function_table // WebAssembly.Table
|
|
357
|
+
})
|
|
357
358
|
// binding === napiModule.exports
|
|
358
359
|
})
|
|
359
360
|
</script>
|
|
@@ -383,13 +384,14 @@ WebAssembly.instantiate(require('fs').readFileSync('./hello.wasm'), {
|
|
|
383
384
|
// clang
|
|
384
385
|
napi: napiModule.imports.napi,
|
|
385
386
|
emnapi: napiModule.imports.emnapi
|
|
386
|
-
}).then(({ instance }) => {
|
|
387
|
+
}).then(({ instance, module }) => {
|
|
387
388
|
wasi.initialize(instance)
|
|
388
|
-
const binding = napiModule.init(
|
|
389
|
+
const binding = napiModule.init({
|
|
389
390
|
instance,
|
|
390
|
-
|
|
391
|
-
instance.exports.
|
|
392
|
-
|
|
391
|
+
module,
|
|
392
|
+
memory: instance.exports.memory,
|
|
393
|
+
table: instance.exports.__indirect_function_table
|
|
394
|
+
})
|
|
393
395
|
// binding === napiModule.exports
|
|
394
396
|
})
|
|
395
397
|
```
|
|
@@ -408,7 +410,7 @@ const napiModule = createNapiModule({
|
|
|
408
410
|
})
|
|
409
411
|
|
|
410
412
|
const fs = createFsFromVolume(Volume.from({ /* ... */ }))
|
|
411
|
-
const wasi = WASI
|
|
413
|
+
const wasi = new WASI({ fs, /* ... */ })
|
|
412
414
|
|
|
413
415
|
WebAssembly.instantiate(wasmBuffer, {
|
|
414
416
|
wasi_snapshot_preview1: wasi.wasiImport,
|
|
@@ -421,13 +423,14 @@ WebAssembly.instantiate(wasmBuffer, {
|
|
|
421
423
|
// clang
|
|
422
424
|
napi: napiModule.imports.napi,
|
|
423
425
|
emnapi: napiModule.imports.emnapi
|
|
424
|
-
}).then(({ instance }) => {
|
|
426
|
+
}).then(({ instance, module }) => {
|
|
425
427
|
wasi.initialize(instance)
|
|
426
|
-
const binding = napiModule.init(
|
|
428
|
+
const binding = napiModule.init({
|
|
427
429
|
instance,
|
|
428
|
-
|
|
429
|
-
instance.exports.
|
|
430
|
-
|
|
430
|
+
module,
|
|
431
|
+
memory: instance.exports.memory,
|
|
432
|
+
table: instance.exports.__indirect_function_table
|
|
433
|
+
})
|
|
431
434
|
// binding === napiModule.exports
|
|
432
435
|
})
|
|
433
436
|
```
|
package/dist/library_napi.js
CHANGED
|
@@ -1,5 +1,205 @@
|
|
|
1
1
|
{{{ ((DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.indexOf("$emnapiInit") === -1 ? DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.push("$emnapiInit") : undefined), "") }}}
|
|
2
2
|
{{{ ((EXPORTED_RUNTIME_METHODS.indexOf("emnapiInit") === -1 ? EXPORTED_RUNTIME_METHODS.push("emnapiInit") : undefined), "") }}}
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
4
|
+
function emnapiCreateIdGenerator() {
|
|
5
|
+
var obj = {
|
|
6
|
+
nextId: 1,
|
|
7
|
+
list: [],
|
|
8
|
+
generate: function () {
|
|
9
|
+
var id;
|
|
10
|
+
if (obj.list.length) {
|
|
11
|
+
id = obj.list.shift();
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
id = obj.nextId;
|
|
15
|
+
obj.nextId++;
|
|
16
|
+
}
|
|
17
|
+
return id;
|
|
18
|
+
},
|
|
19
|
+
reuse: function (id) {
|
|
20
|
+
obj.list.push(id);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
return obj;
|
|
24
|
+
}
|
|
25
|
+
var emnapiAsyncWork = {
|
|
26
|
+
idGen: {},
|
|
27
|
+
values: [undefined],
|
|
28
|
+
queued: new Set(),
|
|
29
|
+
pending: [],
|
|
30
|
+
init: function () {
|
|
31
|
+
emnapiAsyncWork.idGen = emnapiCreateIdGenerator();
|
|
32
|
+
emnapiAsyncWork.values = [undefined];
|
|
33
|
+
emnapiAsyncWork.queued = new Set();
|
|
34
|
+
emnapiAsyncWork.pending = [];
|
|
35
|
+
},
|
|
36
|
+
create: function (env, resource, resourceName, execute, complete, data) {
|
|
37
|
+
var asyncId = 0;
|
|
38
|
+
var triggerAsyncId = 0;
|
|
39
|
+
if (emnapiNodeBinding) {
|
|
40
|
+
var asyncContext = emnapiNodeBinding.node.emitAsyncInit(resource, resourceName, -1);
|
|
41
|
+
asyncId = asyncContext.asyncId;
|
|
42
|
+
triggerAsyncId = asyncContext.triggerAsyncId;
|
|
43
|
+
}
|
|
44
|
+
var id = emnapiAsyncWork.idGen.generate();
|
|
45
|
+
emnapiAsyncWork.values[id] = {
|
|
46
|
+
env: env,
|
|
47
|
+
id: id,
|
|
48
|
+
resource: resource,
|
|
49
|
+
resourceName: resourceName,
|
|
50
|
+
asyncId: asyncId,
|
|
51
|
+
triggerAsyncId: triggerAsyncId,
|
|
52
|
+
status: 0,
|
|
53
|
+
execute: execute,
|
|
54
|
+
complete: complete,
|
|
55
|
+
data: data
|
|
56
|
+
};
|
|
57
|
+
return id;
|
|
58
|
+
},
|
|
59
|
+
callComplete: function (work, status) {
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
61
|
+
var complete = work.complete;
|
|
62
|
+
var env = work.env;
|
|
63
|
+
var data = work.data;
|
|
64
|
+
var callback = function () {
|
|
65
|
+
var envObject = emnapiCtx.envStore.get(env);
|
|
66
|
+
var scope = emnapiCtx.openScope(envObject);
|
|
67
|
+
try {
|
|
68
|
+
envObject.callIntoModule(function () {
|
|
69
|
+
{{{ makeDynCall('vpip', 'complete') }}}(env, status, data);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
emnapiCtx.closeScope(envObject, scope);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
if (emnapiNodeBinding) {
|
|
77
|
+
emnapiNodeBinding.node.makeCallback(work.resource, callback, [], {
|
|
78
|
+
asyncId: work.asyncId,
|
|
79
|
+
triggerAsyncId: work.triggerAsyncId
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
callback();
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
queue: function (id) {
|
|
87
|
+
var work = emnapiAsyncWork.values[id];
|
|
88
|
+
if (!work)
|
|
89
|
+
return;
|
|
90
|
+
if (work.status === 0) {
|
|
91
|
+
work.status = 1;
|
|
92
|
+
if (emnapiAsyncWork.queued.size >= 4) {
|
|
93
|
+
emnapiAsyncWork.pending.push(id);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
emnapiAsyncWork.queued.add(id);
|
|
97
|
+
var env_1 = work.env;
|
|
98
|
+
var data_1 = work.data;
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
100
|
+
var execute = work.execute;
|
|
101
|
+
work.status = 2;
|
|
102
|
+
emnapiCtx.feature.setImmediate(function () {
|
|
103
|
+
{{{ makeDynCall('vpp', 'execute') }}}(env_1, data_1);
|
|
104
|
+
emnapiAsyncWork.queued.delete(id);
|
|
105
|
+
work.status = 3;
|
|
106
|
+
emnapiAsyncWork.callComplete(work, 0 /* napi_status.napi_ok */);
|
|
107
|
+
if (emnapiAsyncWork.pending.length > 0) {
|
|
108
|
+
var nextWorkId = emnapiAsyncWork.pending.shift();
|
|
109
|
+
emnapiAsyncWork.values[nextWorkId].status = 0;
|
|
110
|
+
emnapiAsyncWork.queue(nextWorkId);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
cancel: function (id) {
|
|
116
|
+
var index = emnapiAsyncWork.pending.indexOf(id);
|
|
117
|
+
if (index !== -1) {
|
|
118
|
+
var work = emnapiAsyncWork.values[id];
|
|
119
|
+
if (work && (work.status === 1)) {
|
|
120
|
+
work.status = 4;
|
|
121
|
+
emnapiAsyncWork.pending.splice(index, 1);
|
|
122
|
+
emnapiAsyncWork.callComplete(work, 11 /* napi_status.napi_cancelled */);
|
|
123
|
+
return 0 /* napi_status.napi_ok */;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
return 9 /* napi_status.napi_generic_failure */;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return 9 /* napi_status.napi_generic_failure */;
|
|
130
|
+
},
|
|
131
|
+
remove: function (id) {
|
|
132
|
+
var work = emnapiAsyncWork.values[id];
|
|
133
|
+
if (!work)
|
|
134
|
+
return;
|
|
135
|
+
if (emnapiNodeBinding) {
|
|
136
|
+
emnapiNodeBinding.node.emitAsyncDestroy({
|
|
137
|
+
asyncId: work.asyncId,
|
|
138
|
+
triggerAsyncId: work.triggerAsyncId
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
emnapiAsyncWork.values[id] = undefined;
|
|
142
|
+
emnapiAsyncWork.idGen.reuse(id);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
function _napi_create_async_work(env, resource, resource_name, execute, complete, data, result) {
|
|
146
|
+
if (env == 0)
|
|
147
|
+
return 1 /* napi_status.napi_invalid_arg */;
|
|
148
|
+
var envObject = emnapiCtx.envStore.get(env);
|
|
149
|
+
if (execute == 0)
|
|
150
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
151
|
+
if (result == 0)
|
|
152
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
153
|
+
var resourceObject;
|
|
154
|
+
if (resource) {
|
|
155
|
+
resourceObject = Object(emnapiCtx.handleStore.get(resource).value);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
resourceObject = {};
|
|
159
|
+
}
|
|
160
|
+
if (resource_name == 0)
|
|
161
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
162
|
+
var resourceName = String(emnapiCtx.handleStore.get(resource_name).value);
|
|
163
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
164
|
+
var id = emnapiAsyncWork.create(env, resourceObject, resourceName, execute, complete, data);
|
|
165
|
+
{{{ makeSetValue('result', 0, 'id', '*') }}};
|
|
166
|
+
return envObject.clearLastError();
|
|
167
|
+
}
|
|
168
|
+
function _napi_delete_async_work(env, work) {
|
|
169
|
+
if (env == 0)
|
|
170
|
+
return 1 /* napi_status.napi_invalid_arg */;
|
|
171
|
+
var envObject = emnapiCtx.envStore.get(env);
|
|
172
|
+
if (work == 0)
|
|
173
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
174
|
+
emnapiAsyncWork.remove(work);
|
|
175
|
+
return envObject.clearLastError();
|
|
176
|
+
}
|
|
177
|
+
function _napi_queue_async_work(env, work) {
|
|
178
|
+
if (env == 0)
|
|
179
|
+
return 1 /* napi_status.napi_invalid_arg */;
|
|
180
|
+
var envObject = emnapiCtx.envStore.get(env);
|
|
181
|
+
if (work == 0)
|
|
182
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
183
|
+
emnapiAsyncWork.queue(work);
|
|
184
|
+
return envObject.clearLastError();
|
|
185
|
+
}
|
|
186
|
+
function _napi_cancel_async_work(env, work) {
|
|
187
|
+
if (env == 0)
|
|
188
|
+
return 1 /* napi_status.napi_invalid_arg */;
|
|
189
|
+
var envObject = emnapiCtx.envStore.get(env);
|
|
190
|
+
if (work == 0)
|
|
191
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
192
|
+
var status = emnapiAsyncWork.cancel(work);
|
|
193
|
+
if (status === 0 /* napi_status.napi_ok */)
|
|
194
|
+
return envObject.clearLastError();
|
|
195
|
+
return envObject.setLastError(status);
|
|
196
|
+
}
|
|
197
|
+
emnapiImplementHelper('$emnapiCreateIdGenerator', undefined, emnapiCreateIdGenerator, []);
|
|
198
|
+
emnapiDefineVar('$emnapiAsyncWork', emnapiAsyncWork, ['$emnapiCreateIdGenerator'], 'emnapiAsyncWork.init();');
|
|
199
|
+
emnapiImplement('napi_create_async_work', 'ippppppp', _napi_create_async_work, ['$emnapiAsyncWork']);
|
|
200
|
+
emnapiImplement('napi_delete_async_work', 'ipp', _napi_delete_async_work, ['$emnapiAsyncWork']);
|
|
201
|
+
emnapiImplement('napi_queue_async_work', 'ipp', _napi_queue_async_work, ['$emnapiAsyncWork']);
|
|
202
|
+
emnapiImplement('napi_cancel_async_work', 'ipp', _napi_cancel_async_work, ['$emnapiAsyncWork']);
|
|
3
203
|
function _emnapi_create_memory_view(env, typedarray_type, external_data, byte_length, finalize_cb, finalize_hint, result
|
|
4
204
|
// @ts-expect-error
|
|
5
205
|
) {
|
|
@@ -826,10 +1026,18 @@ function emnapiCreateFunction(envObject, utf8name, length, cb, data) {
|
|
|
826
1026
|
}
|
|
827
1027
|
#if DYNAMIC_EXECUTION
|
|
828
1028
|
if (emnapiCtx.feature.supportNewFunction) {
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
'return
|
|
832
|
-
|
|
1029
|
+
var _ = makeFunction();
|
|
1030
|
+
try {
|
|
1031
|
+
f = (new Function('_', 'return function ' + functionName + '(){' +
|
|
1032
|
+
'"use strict";' +
|
|
1033
|
+
'return _.apply(this,arguments);' +
|
|
1034
|
+
'};'))(_);
|
|
1035
|
+
}
|
|
1036
|
+
catch (_err) {
|
|
1037
|
+
f = makeFunction();
|
|
1038
|
+
if (emnapiCtx.feature.canSetFunctionName)
|
|
1039
|
+
Object.defineProperty(f, 'name', { value: functionName });
|
|
1040
|
+
}
|
|
833
1041
|
}
|
|
834
1042
|
else {
|
|
835
1043
|
f = makeFunction();
|
|
@@ -2180,7 +2388,7 @@ function napi_define_properties(env, object, property_count, properties
|
|
|
2180
2388
|
var value_2 = {{{ makeGetValue("propPtr", POINTER_SIZE * 5, "*") }}};
|
|
2181
2389
|
attributes = {{{ makeGetValue("propPtr", POINTER_SIZE * 6, POINTER_WASM_TYPE) }}};
|
|
2182
2390
|
{{{ from64("attributes") }}};
|
|
2183
|
-
var
|
|
2391
|
+
var data_2 = {{{ makeGetValue("propPtr", POINTER_SIZE * 7, "*") }}};
|
|
2184
2392
|
if (utf8Name_1) {
|
|
2185
2393
|
propertyName_1 = UTF8ToString(utf8Name_1);
|
|
2186
2394
|
}
|
|
@@ -2193,7 +2401,7 @@ function napi_define_properties(env, object, property_count, properties
|
|
|
2193
2401
|
return envObject_32.setLastError(4 /* napi_status.napi_name_expected */);
|
|
2194
2402
|
}
|
|
2195
2403
|
}
|
|
2196
|
-
emnapiDefineProperty(envObject_32, maybeObject_1, propertyName_1, method_1, getter_1, setter_1, value_2, attributes,
|
|
2404
|
+
emnapiDefineProperty(envObject_32, maybeObject_1, propertyName_1, method_1, getter_1, setter_1, value_2, attributes, data_2);
|
|
2197
2405
|
}
|
|
2198
2406
|
return 0 /* napi_status.napi_ok */;
|
|
2199
2407
|
}
|
|
@@ -2840,7 +3048,7 @@ function napi_define_class(env, utf8name, length, constructor, callback_data, pr
|
|
|
2840
3048
|
var value_3 = {{{ makeGetValue("propPtr", POINTER_SIZE * 5, "*") }}};
|
|
2841
3049
|
attributes = {{{ makeGetValue("propPtr", POINTER_SIZE * 6, POINTER_WASM_TYPE) }}};
|
|
2842
3050
|
{{{ from64("attributes") }}};
|
|
2843
|
-
var
|
|
3051
|
+
var data_3 = {{{ makeGetValue("propPtr", POINTER_SIZE * 7, "*") }}};
|
|
2844
3052
|
if (utf8Name_2) {
|
|
2845
3053
|
propertyName_2 = UTF8ToString(utf8Name_2);
|
|
2846
3054
|
}
|
|
@@ -2854,10 +3062,10 @@ function napi_define_class(env, utf8name, length, constructor, callback_data, pr
|
|
|
2854
3062
|
}
|
|
2855
3063
|
}
|
|
2856
3064
|
if ((attributes & 1024 /* napi_property_attributes.napi_static */) !== 0) {
|
|
2857
|
-
emnapiDefineProperty(envObject_43, F_1, propertyName_2, method_2, getter_2, setter_2, value_3, attributes,
|
|
3065
|
+
emnapiDefineProperty(envObject_43, F_1, propertyName_2, method_2, getter_2, setter_2, value_3, attributes, data_3);
|
|
2858
3066
|
continue;
|
|
2859
3067
|
}
|
|
2860
|
-
emnapiDefineProperty(envObject_43, F_1.prototype, propertyName_2, method_2, getter_2, setter_2, value_3, attributes,
|
|
3068
|
+
emnapiDefineProperty(envObject_43, F_1.prototype, propertyName_2, method_2, getter_2, setter_2, value_3, attributes, data_3);
|
|
2861
3069
|
}
|
|
2862
3070
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2863
3071
|
var valueHandle_2 = emnapiCtx.addToCurrentScope(F_1);
|
package/index.js
CHANGED
|
@@ -7,7 +7,13 @@ const include = path.join(__dirname, 'include')
|
|
|
7
7
|
const includeDir = path.relative(process.cwd(), include)
|
|
8
8
|
const jsLibrary = path.join(__dirname, './dist/library_napi.js')
|
|
9
9
|
const sources = [
|
|
10
|
+
path.join(__dirname, './src/js_native_api.c'),
|
|
11
|
+
path.join(__dirname, './src/node_api.c'),
|
|
10
12
|
path.join(__dirname, './src/emnapi.c'),
|
|
13
|
+
path.join(__dirname, './src/async_cleanup_hook.c'),
|
|
14
|
+
path.join(__dirname, './src/async_context.c'),
|
|
15
|
+
path.join(__dirname, './src/async_work.c'),
|
|
16
|
+
path.join(__dirname, './src/threadsafe_function.c'),
|
|
11
17
|
path.join(__dirname, './src/uv/uv-common.c'),
|
|
12
18
|
path.join(__dirname, './src/uv/threadpool.c'),
|
|
13
19
|
path.join(__dirname, './src/uv/unix/loop.c'),
|
|
Binary file
|
package/lib/wasm32/libemnapi.a
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.
|
|
2
|
-
clang version
|
|
1
|
+
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.32 (eab98adf462c39f3c31d348331c4830bcaa36949)
|
|
2
|
+
clang version 17.0.0 (https://github.com/llvm/llvm-project df82394e7a2d06506718cafa347bf7827c79fc4f)
|
|
3
3
|
Target: wasm32-unknown-emscripten
|
|
4
4
|
Thread model: posix
|
|
5
5
|
InstalledDir: /home/runner/work/emnapi/emnapi/emsdk-cache/emsdk-main/upstream/bin
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#include "emnapi_common.h"
|
|
2
|
+
#include "node_api.h"
|
|
3
|
+
|
|
4
|
+
EXTERN_C_START
|
|
5
|
+
|
|
6
|
+
typedef void (*async_cleanup_hook)(void* arg, void(*)(void*), void*);
|
|
7
|
+
|
|
8
|
+
struct async_cleanup_hook_info {
|
|
9
|
+
napi_env env;
|
|
10
|
+
async_cleanup_hook fun;
|
|
11
|
+
void* arg;
|
|
12
|
+
bool started;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
struct napi_async_cleanup_hook_handle__ {
|
|
16
|
+
struct async_cleanup_hook_info* handle_;
|
|
17
|
+
napi_env env_;
|
|
18
|
+
napi_async_cleanup_hook user_hook_;
|
|
19
|
+
void* user_data_;
|
|
20
|
+
void (*done_cb_)(void*);
|
|
21
|
+
void* done_data_;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
static void _emnapi_ach_handle_hook(void* data, void (*done_cb)(void*), void* done_data) {
|
|
25
|
+
napi_async_cleanup_hook_handle handle =
|
|
26
|
+
(napi_async_cleanup_hook_handle) (data);
|
|
27
|
+
handle->done_cb_ = done_cb;
|
|
28
|
+
handle->done_data_ = done_data;
|
|
29
|
+
handle->user_hook_(handle, handle->user_data_);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static void _emnapi_finish_async_cleanup_hook(void* arg) {
|
|
33
|
+
// struct async_cleanup_hook_info* info = (struct async_cleanup_hook_info*) (arg);
|
|
34
|
+
EMNAPI_KEEPALIVE_POP();
|
|
35
|
+
_emnapi_ctx_decrease_waiting_request_counter();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static void _emnapi_run_async_cleanup_hook(void* arg) {
|
|
39
|
+
struct async_cleanup_hook_info* info = (struct async_cleanup_hook_info*) (arg);
|
|
40
|
+
EMNAPI_KEEPALIVE_PUSH();
|
|
41
|
+
_emnapi_ctx_increase_waiting_request_counter();
|
|
42
|
+
info->started = true;
|
|
43
|
+
info->fun(info->arg, _emnapi_finish_async_cleanup_hook, info);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static struct async_cleanup_hook_info*
|
|
47
|
+
_emnapi_add_async_environment_cleanup_hook(napi_env env,
|
|
48
|
+
async_cleanup_hook fun,
|
|
49
|
+
void* arg) {
|
|
50
|
+
struct async_cleanup_hook_info* info =
|
|
51
|
+
(struct async_cleanup_hook_info*) malloc(sizeof(struct async_cleanup_hook_info));
|
|
52
|
+
info->env = env;
|
|
53
|
+
info->fun = fun;
|
|
54
|
+
info->arg = arg;
|
|
55
|
+
info->started = false;
|
|
56
|
+
|
|
57
|
+
EMNAPI_ASSERT_CALL(napi_add_env_cleanup_hook(env, _emnapi_run_async_cleanup_hook, info));
|
|
58
|
+
|
|
59
|
+
return info;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static void _emnapi_remove_async_environment_cleanup_hook(
|
|
63
|
+
struct async_cleanup_hook_info* info) {
|
|
64
|
+
if (info->started) return;
|
|
65
|
+
EMNAPI_ASSERT_CALL(napi_remove_env_cleanup_hook(info->env, _emnapi_run_async_cleanup_hook, info));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static napi_async_cleanup_hook_handle
|
|
69
|
+
_emnapi_ach_handle_create(napi_env env,
|
|
70
|
+
napi_async_cleanup_hook user_hook,
|
|
71
|
+
void* user_data) {
|
|
72
|
+
napi_async_cleanup_hook_handle handle =
|
|
73
|
+
(napi_async_cleanup_hook_handle) calloc(1, sizeof(struct napi_async_cleanup_hook_handle__));
|
|
74
|
+
handle->env_ = env;
|
|
75
|
+
handle->user_hook_ = user_hook;
|
|
76
|
+
handle->user_data_ = user_data;
|
|
77
|
+
handle->handle_ = _emnapi_add_async_environment_cleanup_hook(env, _emnapi_ach_handle_hook, handle);
|
|
78
|
+
_emnapi_env_ref(env);
|
|
79
|
+
|
|
80
|
+
return handle;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
EMNAPI_INTERNAL_EXTERN void _emnapi_set_immediate(void (*callback)(void*), void* data);
|
|
84
|
+
|
|
85
|
+
static void _emnapi_ach_handle_env_unref(void* arg) {
|
|
86
|
+
napi_env env = (napi_env) arg;
|
|
87
|
+
_emnapi_env_unref(env);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
static void
|
|
91
|
+
_emnapi_ach_handle_delete(napi_async_cleanup_hook_handle handle) {
|
|
92
|
+
_emnapi_remove_async_environment_cleanup_hook(handle->handle_);
|
|
93
|
+
if (handle->done_cb_ != NULL) handle->done_cb_(handle->done_data_);
|
|
94
|
+
|
|
95
|
+
_emnapi_set_immediate(_emnapi_ach_handle_env_unref, handle->env_);
|
|
96
|
+
|
|
97
|
+
free(handle->handle_);
|
|
98
|
+
free(handle);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
napi_status
|
|
102
|
+
napi_add_async_cleanup_hook(napi_env env,
|
|
103
|
+
napi_async_cleanup_hook hook,
|
|
104
|
+
void* arg,
|
|
105
|
+
napi_async_cleanup_hook_handle* remove_handle) {
|
|
106
|
+
CHECK_ENV(env);
|
|
107
|
+
CHECK_ARG(env, hook);
|
|
108
|
+
|
|
109
|
+
napi_async_cleanup_hook_handle handle =
|
|
110
|
+
_emnapi_ach_handle_create(env, hook, arg);
|
|
111
|
+
|
|
112
|
+
if (remove_handle != NULL) *remove_handle = handle;
|
|
113
|
+
|
|
114
|
+
return napi_clear_last_error(env);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
napi_status
|
|
118
|
+
napi_remove_async_cleanup_hook(napi_async_cleanup_hook_handle remove_handle) {
|
|
119
|
+
if (remove_handle == NULL) return napi_invalid_arg;
|
|
120
|
+
|
|
121
|
+
_emnapi_ach_handle_delete(remove_handle);
|
|
122
|
+
|
|
123
|
+
return napi_ok;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
EXTERN_C_END
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#include <node_api.h>
|
|
2
|
+
#include "emnapi_common.h"
|
|
3
|
+
|
|
4
|
+
EXTERN_C_START
|
|
5
|
+
|
|
6
|
+
struct napi_async_context__ {
|
|
7
|
+
int32_t low;
|
|
8
|
+
int32_t high;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
EMNAPI_INTERNAL_EXTERN napi_status
|
|
12
|
+
_emnapi_async_init_js(napi_value async_resource,
|
|
13
|
+
napi_value async_resource_name,
|
|
14
|
+
napi_async_context result);
|
|
15
|
+
EMNAPI_INTERNAL_EXTERN napi_status
|
|
16
|
+
_emnapi_async_destroy_js(napi_async_context async_context);
|
|
17
|
+
|
|
18
|
+
napi_status
|
|
19
|
+
napi_async_init(napi_env env,
|
|
20
|
+
napi_value async_resource,
|
|
21
|
+
napi_value async_resource_name,
|
|
22
|
+
napi_async_context* result) {
|
|
23
|
+
CHECK_ENV(env);
|
|
24
|
+
CHECK_ARG(env, async_resource_name);
|
|
25
|
+
CHECK_ARG(env, result);
|
|
26
|
+
|
|
27
|
+
napi_async_context ret = (napi_async_context) malloc(sizeof(struct napi_async_context__));
|
|
28
|
+
|
|
29
|
+
napi_status status = _emnapi_async_init_js(async_resource, async_resource_name, ret);
|
|
30
|
+
if (status != napi_ok) {
|
|
31
|
+
free(ret);
|
|
32
|
+
return napi_set_last_error(env, status, 0, NULL);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
*result = ret;
|
|
36
|
+
return napi_clear_last_error(env);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
napi_status napi_async_destroy(napi_env env,
|
|
40
|
+
napi_async_context async_context) {
|
|
41
|
+
CHECK_ENV(env);
|
|
42
|
+
CHECK_ARG(env, async_context);
|
|
43
|
+
|
|
44
|
+
napi_status status = _emnapi_async_destroy_js(async_context);
|
|
45
|
+
if (status != napi_ok) {
|
|
46
|
+
return napi_set_last_error(env, status, 0, NULL);
|
|
47
|
+
}
|
|
48
|
+
free(async_context);
|
|
49
|
+
|
|
50
|
+
return napi_clear_last_error(env);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
EXTERN_C_END
|