koffi 1.0.3 → 1.1.0-beta.0
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/README.md +48 -22
- package/build/qemu/1.1.0-beta.0/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.0/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.0/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.0/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.0/koffi_linux_arm.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.0/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.0/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.0/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.0/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.0/koffi_win32_x64.tar.gz +0 -0
- package/package.json +1 -1
- package/qemu/qemu.js +11 -5
- package/qemu/registry/machines.json +20 -10
- package/src/abi_arm32.cc +130 -215
- package/src/abi_arm64.cc +103 -117
- package/src/abi_x64_sysv.cc +117 -135
- package/src/abi_x64_win.cc +89 -98
- package/src/abi_x86.cc +91 -99
- package/src/call.cc +164 -40
- package/src/call.hh +53 -31
- package/src/ffi.cc +163 -19
- package/src/ffi.hh +30 -22
- package/src/util.cc +0 -127
- package/src/util.hh +0 -16
- package/test/misc.c +68 -2
- package/vendor/libcc/libcc.hh +1 -1
- package/build/qemu/1.0.3/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.0.3/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.0.3/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.0.3/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.0.3/koffi_linux_arm.tar.gz +0 -0
- package/build/qemu/1.0.3/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.0.3/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.0.3/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.0.3/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.0.3/koffi_win32_x64.tar.gz +0 -0
- package/test/misc.js +0 -180
- package/vendor/node-addon-api/CODE_OF_CONDUCT.md +0 -4
- package/vendor/node-addon-api/CONTRIBUTING.md +0 -93
- package/vendor/node-addon-api/appveyor.yml +0 -37
- package/vendor/node-addon-api/benchmark/README.md +0 -47
- package/vendor/node-addon-api/benchmark/binding.gyp +0 -25
- package/vendor/node-addon-api/benchmark/function_args.cc +0 -217
- package/vendor/node-addon-api/benchmark/function_args.js +0 -60
- package/vendor/node-addon-api/benchmark/index.js +0 -34
- package/vendor/node-addon-api/benchmark/property_descriptor.cc +0 -91
- package/vendor/node-addon-api/benchmark/property_descriptor.js +0 -37
- package/vendor/node-addon-api/doc/addon.md +0 -163
- package/vendor/node-addon-api/doc/array.md +0 -81
- package/vendor/node-addon-api/doc/array_buffer.md +0 -155
- package/vendor/node-addon-api/doc/async_context.md +0 -86
- package/vendor/node-addon-api/doc/async_operations.md +0 -31
- package/vendor/node-addon-api/doc/async_worker.md +0 -427
- package/vendor/node-addon-api/doc/async_worker_variants.md +0 -557
- package/vendor/node-addon-api/doc/bigint.md +0 -97
- package/vendor/node-addon-api/doc/boolean.md +0 -68
- package/vendor/node-addon-api/doc/buffer.md +0 -150
- package/vendor/node-addon-api/doc/callback_scope.md +0 -54
- package/vendor/node-addon-api/doc/callbackinfo.md +0 -97
- package/vendor/node-addon-api/doc/checker-tool.md +0 -32
- package/vendor/node-addon-api/doc/class_property_descriptor.md +0 -123
- package/vendor/node-addon-api/doc/cmake-js.md +0 -68
- package/vendor/node-addon-api/doc/conversion-tool.md +0 -28
- package/vendor/node-addon-api/doc/creating_a_release.md +0 -62
- package/vendor/node-addon-api/doc/dataview.md +0 -248
- package/vendor/node-addon-api/doc/date.md +0 -68
- package/vendor/node-addon-api/doc/env.md +0 -196
- package/vendor/node-addon-api/doc/error.md +0 -120
- package/vendor/node-addon-api/doc/error_handling.md +0 -254
- package/vendor/node-addon-api/doc/escapable_handle_scope.md +0 -80
- package/vendor/node-addon-api/doc/external.md +0 -63
- package/vendor/node-addon-api/doc/function.md +0 -402
- package/vendor/node-addon-api/doc/function_reference.md +0 -238
- package/vendor/node-addon-api/doc/generator.md +0 -13
- package/vendor/node-addon-api/doc/handle_scope.md +0 -63
- package/vendor/node-addon-api/doc/hierarchy.md +0 -91
- package/vendor/node-addon-api/doc/instance_wrap.md +0 -408
- package/vendor/node-addon-api/doc/maybe.md +0 -76
- package/vendor/node-addon-api/doc/memory_management.md +0 -27
- package/vendor/node-addon-api/doc/name.md +0 -29
- package/vendor/node-addon-api/doc/node-gyp.md +0 -82
- package/vendor/node-addon-api/doc/number.md +0 -163
- package/vendor/node-addon-api/doc/object.md +0 -411
- package/vendor/node-addon-api/doc/object_lifetime_management.md +0 -83
- package/vendor/node-addon-api/doc/object_reference.md +0 -117
- package/vendor/node-addon-api/doc/object_wrap.md +0 -588
- package/vendor/node-addon-api/doc/prebuild_tools.md +0 -16
- package/vendor/node-addon-api/doc/promises.md +0 -79
- package/vendor/node-addon-api/doc/property_descriptor.md +0 -286
- package/vendor/node-addon-api/doc/propertylvalue.md +0 -50
- package/vendor/node-addon-api/doc/range_error.md +0 -59
- package/vendor/node-addon-api/doc/reference.md +0 -113
- package/vendor/node-addon-api/doc/setup.md +0 -110
- package/vendor/node-addon-api/doc/string.md +0 -93
- package/vendor/node-addon-api/doc/symbol.md +0 -61
- package/vendor/node-addon-api/doc/threadsafe.md +0 -121
- package/vendor/node-addon-api/doc/threadsafe_function.md +0 -290
- package/vendor/node-addon-api/doc/type_error.md +0 -59
- package/vendor/node-addon-api/doc/typed_array.md +0 -78
- package/vendor/node-addon-api/doc/typed_array_of.md +0 -137
- package/vendor/node-addon-api/doc/typed_threadsafe_function.md +0 -306
- package/vendor/node-addon-api/doc/value.md +0 -340
- package/vendor/node-addon-api/doc/version_management.md +0 -43
- package/vendor/node-addon-api/package.json +0 -415
- package/vendor/node-addon-api/test/README.md +0 -91
- package/vendor/node-addon-api/test/addon.cc +0 -36
- package/vendor/node-addon-api/test/addon.js +0 -11
- package/vendor/node-addon-api/test/addon_build/index.js +0 -49
- package/vendor/node-addon-api/test/addon_build/tpl/addon.cc +0 -17
- package/vendor/node-addon-api/test/addon_build/tpl/binding.gyp +0 -62
- package/vendor/node-addon-api/test/addon_build/tpl/index.js +0 -9
- package/vendor/node-addon-api/test/addon_build/tpl/package.json +0 -11
- package/vendor/node-addon-api/test/addon_data.cc +0 -99
- package/vendor/node-addon-api/test/addon_data.js +0 -46
- package/vendor/node-addon-api/test/array_buffer.cc +0 -243
- package/vendor/node-addon-api/test/array_buffer.js +0 -69
- package/vendor/node-addon-api/test/async_context.cc +0 -36
- package/vendor/node-addon-api/test/async_context.js +0 -122
- package/vendor/node-addon-api/test/async_progress_queue_worker.cc +0 -83
- package/vendor/node-addon-api/test/async_progress_queue_worker.js +0 -46
- package/vendor/node-addon-api/test/async_progress_worker.cc +0 -134
- package/vendor/node-addon-api/test/async_progress_worker.js +0 -61
- package/vendor/node-addon-api/test/async_worker.cc +0 -106
- package/vendor/node-addon-api/test/async_worker.js +0 -179
- package/vendor/node-addon-api/test/async_worker_nocallback.js +0 -13
- package/vendor/node-addon-api/test/async_worker_persistent.cc +0 -63
- package/vendor/node-addon-api/test/async_worker_persistent.js +0 -24
- package/vendor/node-addon-api/test/basic_types/array.cc +0 -40
- package/vendor/node-addon-api/test/basic_types/array.js +0 -35
- package/vendor/node-addon-api/test/basic_types/boolean.cc +0 -38
- package/vendor/node-addon-api/test/basic_types/boolean.js +0 -35
- package/vendor/node-addon-api/test/basic_types/number.cc +0 -99
- package/vendor/node-addon-api/test/basic_types/number.js +0 -114
- package/vendor/node-addon-api/test/basic_types/value.cc +0 -120
- package/vendor/node-addon-api/test/basic_types/value.js +0 -133
- package/vendor/node-addon-api/test/bigint.cc +0 -91
- package/vendor/node-addon-api/test/bigint.js +0 -53
- package/vendor/node-addon-api/test/binding-swallowexcept.cc +0 -12
- package/vendor/node-addon-api/test/binding.cc +0 -173
- package/vendor/node-addon-api/test/binding.gyp +0 -124
- package/vendor/node-addon-api/test/buffer.cc +0 -183
- package/vendor/node-addon-api/test/buffer.js +0 -69
- package/vendor/node-addon-api/test/callbackscope.cc +0 -22
- package/vendor/node-addon-api/test/callbackscope.js +0 -49
- package/vendor/node-addon-api/test/common/index.js +0 -114
- package/vendor/node-addon-api/test/common/test_helper.h +0 -71
- package/vendor/node-addon-api/test/dataview/dataview.cc +0 -48
- package/vendor/node-addon-api/test/dataview/dataview.js +0 -35
- package/vendor/node-addon-api/test/dataview/dataview_read_write.cc +0 -115
- package/vendor/node-addon-api/test/dataview/dataview_read_write.js +0 -90
- package/vendor/node-addon-api/test/date.cc +0 -44
- package/vendor/node-addon-api/test/date.js +0 -18
- package/vendor/node-addon-api/test/env_cleanup.cc +0 -88
- package/vendor/node-addon-api/test/env_cleanup.js +0 -56
- package/vendor/node-addon-api/test/error.cc +0 -287
- package/vendor/node-addon-api/test/error.js +0 -81
- package/vendor/node-addon-api/test/error_handling_for_primitives.cc +0 -13
- package/vendor/node-addon-api/test/error_handling_for_primitives.js +0 -29
- package/vendor/node-addon-api/test/error_terminating_environment.js +0 -95
- package/vendor/node-addon-api/test/external.cc +0 -81
- package/vendor/node-addon-api/test/external.js +0 -88
- package/vendor/node-addon-api/test/function.cc +0 -324
- package/vendor/node-addon-api/test/function.js +0 -133
- package/vendor/node-addon-api/test/function_reference.cc +0 -202
- package/vendor/node-addon-api/test/function_reference.js +0 -157
- package/vendor/node-addon-api/test/globalObject/global_object.cc +0 -61
- package/vendor/node-addon-api/test/globalObject/global_object_delete_property.cc +0 -31
- package/vendor/node-addon-api/test/globalObject/global_object_delete_property.js +0 -61
- package/vendor/node-addon-api/test/globalObject/global_object_get_property.cc +0 -40
- package/vendor/node-addon-api/test/globalObject/global_object_get_property.js +0 -57
- package/vendor/node-addon-api/test/globalObject/global_object_has_own_property.cc +0 -28
- package/vendor/node-addon-api/test/globalObject/global_object_has_own_property.js +0 -48
- package/vendor/node-addon-api/test/globalObject/global_object_set_property.cc +0 -31
- package/vendor/node-addon-api/test/globalObject/global_object_set_property.js +0 -58
- package/vendor/node-addon-api/test/handlescope.cc +0 -60
- package/vendor/node-addon-api/test/handlescope.js +0 -14
- package/vendor/node-addon-api/test/index.js +0 -159
- package/vendor/node-addon-api/test/maybe/check.cc +0 -23
- package/vendor/node-addon-api/test/maybe/index.js +0 -38
- package/vendor/node-addon-api/test/memory_management.cc +0 -17
- package/vendor/node-addon-api/test/memory_management.js +0 -9
- package/vendor/node-addon-api/test/movable_callbacks.cc +0 -23
- package/vendor/node-addon-api/test/movable_callbacks.js +0 -21
- package/vendor/node-addon-api/test/name.cc +0 -108
- package/vendor/node-addon-api/test/name.js +0 -59
- package/vendor/node-addon-api/test/napi_child.js +0 -14
- package/vendor/node-addon-api/test/object/delete_property.cc +0 -38
- package/vendor/node-addon-api/test/object/delete_property.js +0 -41
- package/vendor/node-addon-api/test/object/finalizer.cc +0 -29
- package/vendor/node-addon-api/test/object/finalizer.js +0 -28
- package/vendor/node-addon-api/test/object/get_property.cc +0 -34
- package/vendor/node-addon-api/test/object/get_property.js +0 -40
- package/vendor/node-addon-api/test/object/has_own_property.cc +0 -34
- package/vendor/node-addon-api/test/object/has_own_property.js +0 -34
- package/vendor/node-addon-api/test/object/has_property.cc +0 -38
- package/vendor/node-addon-api/test/object/has_property.js +0 -37
- package/vendor/node-addon-api/test/object/object.cc +0 -350
- package/vendor/node-addon-api/test/object/object.js +0 -217
- package/vendor/node-addon-api/test/object/object_deprecated.cc +0 -66
- package/vendor/node-addon-api/test/object/object_deprecated.js +0 -47
- package/vendor/node-addon-api/test/object/object_freeze_seal.cc +0 -25
- package/vendor/node-addon-api/test/object/object_freeze_seal.js +0 -61
- package/vendor/node-addon-api/test/object/set_property.cc +0 -45
- package/vendor/node-addon-api/test/object/set_property.js +0 -30
- package/vendor/node-addon-api/test/object/subscript_operator.cc +0 -58
- package/vendor/node-addon-api/test/object/subscript_operator.js +0 -17
- package/vendor/node-addon-api/test/object_reference.cc +0 -219
- package/vendor/node-addon-api/test/object_reference.js +0 -259
- package/vendor/node-addon-api/test/objectwrap.cc +0 -268
- package/vendor/node-addon-api/test/objectwrap.js +0 -284
- package/vendor/node-addon-api/test/objectwrap_constructor_exception.cc +0 -26
- package/vendor/node-addon-api/test/objectwrap_constructor_exception.js +0 -18
- package/vendor/node-addon-api/test/objectwrap_function.cc +0 -45
- package/vendor/node-addon-api/test/objectwrap_function.js +0 -22
- package/vendor/node-addon-api/test/objectwrap_multiple_inheritance.cc +0 -30
- package/vendor/node-addon-api/test/objectwrap_multiple_inheritance.js +0 -13
- package/vendor/node-addon-api/test/objectwrap_removewrap.cc +0 -45
- package/vendor/node-addon-api/test/objectwrap_removewrap.js +0 -40
- package/vendor/node-addon-api/test/objectwrap_worker_thread.js +0 -19
- package/vendor/node-addon-api/test/promise.cc +0 -29
- package/vendor/node-addon-api/test/promise.js +0 -18
- package/vendor/node-addon-api/test/reference.cc +0 -24
- package/vendor/node-addon-api/test/reference.js +0 -14
- package/vendor/node-addon-api/test/run_script.cc +0 -56
- package/vendor/node-addon-api/test/run_script.js +0 -45
- package/vendor/node-addon-api/test/symbol.cc +0 -79
- package/vendor/node-addon-api/test/symbol.js +0 -73
- package/vendor/node-addon-api/test/testUtil.js +0 -54
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function.cc +0 -195
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function.js +0 -188
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ctx.cc +0 -63
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ctx.js +0 -12
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_existing_tsfn.cc +0 -115
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_existing_tsfn.js +0 -14
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ptr.cc +0 -26
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ptr.js +0 -7
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_sum.cc +0 -225
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_sum.js +0 -59
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_unref.cc +0 -42
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_unref.js +0 -53
- package/vendor/node-addon-api/test/thunking_manual.cc +0 -140
- package/vendor/node-addon-api/test/thunking_manual.js +0 -17
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function.cc +0 -215
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function.js +0 -188
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ctx.cc +0 -68
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ctx.js +0 -12
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_existing_tsfn.cc +0 -127
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_existing_tsfn.js +0 -14
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ptr.cc +0 -28
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ptr.js +0 -7
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_sum.cc +0 -237
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_sum.js +0 -59
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_unref.cc +0 -53
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_unref.js +0 -53
- package/vendor/node-addon-api/test/typedarray-bigint.js +0 -58
- package/vendor/node-addon-api/test/typedarray.cc +0 -216
- package/vendor/node-addon-api/test/typedarray.js +0 -69
- package/vendor/node-addon-api/test/version_management.cc +0 -27
- package/vendor/node-addon-api/test/version_management.js +0 -31
- package/vendor/node-addon-api/unit-test/README.md +0 -28
- package/vendor/node-addon-api/unit-test/binding-file-template.js +0 -39
- package/vendor/node-addon-api/unit-test/binding.gyp +0 -72
- package/vendor/node-addon-api/unit-test/exceptions.js +0 -32
- package/vendor/node-addon-api/unit-test/generate-binding-cc.js +0 -61
- package/vendor/node-addon-api/unit-test/injectTestParams.js +0 -101
- package/vendor/node-addon-api/unit-test/listOfTestModules.js +0 -88
- package/vendor/node-addon-api/unit-test/matchModules.js +0 -65
- package/vendor/node-addon-api/unit-test/setup.js +0 -13
- package/vendor/node-addon-api/unit-test/spawnTask.js +0 -26
- package/vendor/node-addon-api/unit-test/test.js +0 -30
package/src/call.cc
CHANGED
|
@@ -20,19 +20,24 @@
|
|
|
20
20
|
|
|
21
21
|
namespace RG {
|
|
22
22
|
|
|
23
|
-
CallData::CallData(Napi::Env env,
|
|
24
|
-
: env(env), instance(
|
|
25
|
-
|
|
26
|
-
old_stack_mem(instance->stack_mem), old_heap_mem(instance->heap_mem)
|
|
23
|
+
CallData::CallData(Napi::Env env, const FunctionInfo *func, InstanceMemory *mem, bool debug)
|
|
24
|
+
: env(env), instance(env.GetInstanceData<InstanceData>()), func(func), debug(debug),
|
|
25
|
+
mem(mem), old_stack_mem(mem->stack), old_heap_mem(mem->heap)
|
|
27
26
|
{
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
mem->depth++;
|
|
28
|
+
|
|
29
|
+
RG_ASSERT(AlignUp(mem->stack.ptr, 16) == mem->stack.ptr);
|
|
30
|
+
RG_ASSERT(AlignUp(mem->stack.end(), 16) == mem->stack.end());
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
CallData::~CallData()
|
|
33
34
|
{
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
mem->stack = old_stack_mem;
|
|
36
|
+
mem->heap = old_heap_mem;
|
|
37
|
+
|
|
38
|
+
if (!--mem->depth && mem->temporary) {
|
|
39
|
+
delete mem;
|
|
40
|
+
}
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
const char *CallData::PushString(const Napi::Value &value)
|
|
@@ -45,8 +50,8 @@ const char *CallData::PushString(const Napi::Value &value)
|
|
|
45
50
|
size_t len = 0;
|
|
46
51
|
napi_status status;
|
|
47
52
|
|
|
48
|
-
buf.ptr = (char *)
|
|
49
|
-
buf.len = std::max((Size)0,
|
|
53
|
+
buf.ptr = (char *)mem->heap.ptr;
|
|
54
|
+
buf.len = std::max((Size)0, mem->heap.len - Kibibytes(32));
|
|
50
55
|
|
|
51
56
|
status = napi_get_value_string_utf8(env, value, buf.ptr, (size_t)buf.len, &len);
|
|
52
57
|
RG_ASSERT(status == napi_ok);
|
|
@@ -54,15 +59,15 @@ const char *CallData::PushString(const Napi::Value &value)
|
|
|
54
59
|
len++;
|
|
55
60
|
|
|
56
61
|
if (RG_LIKELY(len < (size_t)buf.len)) {
|
|
57
|
-
|
|
58
|
-
|
|
62
|
+
mem->heap.ptr += (Size)len;
|
|
63
|
+
mem->heap.len -= (Size)len;
|
|
59
64
|
} else {
|
|
60
65
|
status = napi_get_value_string_utf8(env, value, nullptr, 0, &len);
|
|
61
66
|
RG_ASSERT(status == napi_ok);
|
|
62
67
|
|
|
63
68
|
len++;
|
|
64
69
|
|
|
65
|
-
buf.ptr = (char *)Allocator::Allocate(&big_alloc, (Size)len);
|
|
70
|
+
buf.ptr = (char *)Allocator::Allocate(&mem->big_alloc, (Size)len);
|
|
66
71
|
buf.len = (Size)len;
|
|
67
72
|
|
|
68
73
|
status = napi_get_value_string_utf8(env, value, buf.ptr, (size_t)buf.len, &len);
|
|
@@ -82,8 +87,8 @@ const char16_t *CallData::PushString16(const Napi::Value &value)
|
|
|
82
87
|
size_t len = 0;
|
|
83
88
|
napi_status status;
|
|
84
89
|
|
|
85
|
-
buf.ptr = (char16_t *)
|
|
86
|
-
buf.len = std::max((Size)0,
|
|
90
|
+
buf.ptr = (char16_t *)mem->heap.ptr;
|
|
91
|
+
buf.len = std::max((Size)0, mem->heap.len - Kibibytes(32)) / 2;
|
|
87
92
|
|
|
88
93
|
status = napi_get_value_string_utf16(env, value, buf.ptr, (size_t)buf.len, &len);
|
|
89
94
|
RG_ASSERT(status == napi_ok);
|
|
@@ -91,15 +96,15 @@ const char16_t *CallData::PushString16(const Napi::Value &value)
|
|
|
91
96
|
len++;
|
|
92
97
|
|
|
93
98
|
if (RG_LIKELY(len < (size_t)buf.len)) {
|
|
94
|
-
|
|
95
|
-
|
|
99
|
+
mem->heap.ptr += (Size)len * 2;
|
|
100
|
+
mem->heap.len -= (Size)len * 2;
|
|
96
101
|
} else {
|
|
97
102
|
status = napi_get_value_string_utf16(env, value, nullptr, 0, &len);
|
|
98
103
|
RG_ASSERT(status == napi_ok);
|
|
99
104
|
|
|
100
105
|
len++;
|
|
101
106
|
|
|
102
|
-
buf.ptr = (char16_t *)Allocator::Allocate(&big_alloc, (Size)len * 2);
|
|
107
|
+
buf.ptr = (char16_t *)Allocator::Allocate(&mem->big_alloc, (Size)len * 2);
|
|
103
108
|
buf.len = (Size)len;
|
|
104
109
|
|
|
105
110
|
status = napi_get_value_string_utf16(env, value, buf.ptr, (size_t)buf.len, &len);
|
|
@@ -111,9 +116,6 @@ const char16_t *CallData::PushString16(const Napi::Value &value)
|
|
|
111
116
|
|
|
112
117
|
bool CallData::PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t *dest)
|
|
113
118
|
{
|
|
114
|
-
Napi::Env env = obj.Env();
|
|
115
|
-
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
116
|
-
|
|
117
119
|
RG_ASSERT(IsObject(obj));
|
|
118
120
|
RG_ASSERT(type->primitive == PrimitiveKind::Record);
|
|
119
121
|
|
|
@@ -156,24 +158,6 @@ bool CallData::PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t
|
|
|
156
158
|
int64_t v = CopyNumber<int64_t>(value);
|
|
157
159
|
memcpy(dest, &v, member.type->size); // Little Endian
|
|
158
160
|
} break;
|
|
159
|
-
case PrimitiveKind::Float32: {
|
|
160
|
-
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
161
|
-
ThrowError<Napi::TypeError>(env, "Unexpected value %1 for member '%2', expected number", GetValueType(instance, value), member.name);
|
|
162
|
-
return false;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
float f = CopyNumber<float>(value);
|
|
166
|
-
memcpy(dest, &f, 4);
|
|
167
|
-
} break;
|
|
168
|
-
case PrimitiveKind::Float64: {
|
|
169
|
-
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
170
|
-
ThrowError<Napi::TypeError>(env, "Unexpected value %1 for member '%2', expected number", GetValueType(instance, value), member.name);
|
|
171
|
-
return false;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
double d = CopyNumber<double>(value);
|
|
175
|
-
memcpy(dest, &d, 8);
|
|
176
|
-
} break;
|
|
177
161
|
case PrimitiveKind::String: {
|
|
178
162
|
if (RG_UNLIKELY(!value.IsString())) {
|
|
179
163
|
ThrowError<Napi::TypeError>(env, "Unexpected value %1 for member '%2', expected string", GetValueType(instance, value), member.name);
|
|
@@ -206,7 +190,6 @@ bool CallData::PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t
|
|
|
206
190
|
void *ptr = external.Data();
|
|
207
191
|
*(void **)dest = ptr;
|
|
208
192
|
} break;
|
|
209
|
-
|
|
210
193
|
case PrimitiveKind::Record: {
|
|
211
194
|
if (RG_UNLIKELY(!IsObject(value))) {
|
|
212
195
|
ThrowError<Napi::TypeError>(env, "Unexpected value %1 for member '%2', expected object", GetValueType(instance, value), member.name);
|
|
@@ -217,6 +200,24 @@ bool CallData::PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t
|
|
|
217
200
|
if (!PushObject(obj, member.type, dest))
|
|
218
201
|
return false;
|
|
219
202
|
} break;
|
|
203
|
+
case PrimitiveKind::Float32: {
|
|
204
|
+
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
205
|
+
ThrowError<Napi::TypeError>(env, "Unexpected value %1 for member '%2', expected number", GetValueType(instance, value), member.name);
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
float f = CopyNumber<float>(value);
|
|
210
|
+
memcpy(dest, &f, 4);
|
|
211
|
+
} break;
|
|
212
|
+
case PrimitiveKind::Float64: {
|
|
213
|
+
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
214
|
+
ThrowError<Napi::TypeError>(env, "Unexpected value %1 for member '%2', expected number", GetValueType(instance, value), member.name);
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
double d = CopyNumber<double>(value);
|
|
219
|
+
memcpy(dest, &d, 8);
|
|
220
|
+
} break;
|
|
220
221
|
}
|
|
221
222
|
|
|
222
223
|
dest += member.type->size;
|
|
@@ -225,4 +226,127 @@ bool CallData::PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t
|
|
|
225
226
|
return true;
|
|
226
227
|
}
|
|
227
228
|
|
|
229
|
+
void CallData::PopObject(Napi::Object obj, const uint8_t *ptr, const TypeInfo *type)
|
|
230
|
+
{
|
|
231
|
+
RG_ASSERT(type->primitive == PrimitiveKind::Record);
|
|
232
|
+
|
|
233
|
+
for (const RecordMember &member: type->members) {
|
|
234
|
+
ptr = AlignUp(ptr, member.align);
|
|
235
|
+
|
|
236
|
+
switch (member.type->primitive) {
|
|
237
|
+
case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
|
|
238
|
+
|
|
239
|
+
case PrimitiveKind::Bool: {
|
|
240
|
+
bool b = *(bool *)ptr;
|
|
241
|
+
obj.Set(member.name, Napi::Boolean::New(env, b));
|
|
242
|
+
} break;
|
|
243
|
+
case PrimitiveKind::Int8: {
|
|
244
|
+
double d = (double)*(int8_t *)ptr;
|
|
245
|
+
obj.Set(member.name, Napi::Number::New(env, d));
|
|
246
|
+
} break;
|
|
247
|
+
case PrimitiveKind::UInt8: {
|
|
248
|
+
double d = (double)*(uint8_t *)ptr;
|
|
249
|
+
obj.Set(member.name, Napi::Number::New(env, d));
|
|
250
|
+
} break;
|
|
251
|
+
case PrimitiveKind::Int16: {
|
|
252
|
+
double d = (double)*(int16_t *)ptr;
|
|
253
|
+
obj.Set(member.name, Napi::Number::New(env, d));
|
|
254
|
+
} break;
|
|
255
|
+
case PrimitiveKind::UInt16: {
|
|
256
|
+
double d = (double)*(uint16_t *)ptr;
|
|
257
|
+
obj.Set(member.name, Napi::Number::New(env, d));
|
|
258
|
+
} break;
|
|
259
|
+
case PrimitiveKind::Int32: {
|
|
260
|
+
double d = (double)*(int32_t *)ptr;
|
|
261
|
+
obj.Set(member.name, Napi::Number::New(env, d));
|
|
262
|
+
} break;
|
|
263
|
+
case PrimitiveKind::UInt32: {
|
|
264
|
+
double d = (double)*(uint32_t *)ptr;
|
|
265
|
+
obj.Set(member.name, Napi::Number::New(env, d));
|
|
266
|
+
} break;
|
|
267
|
+
case PrimitiveKind::Int64: {
|
|
268
|
+
int64_t v = *(int64_t *)ptr;
|
|
269
|
+
obj.Set(member.name, Napi::BigInt::New(env, v));
|
|
270
|
+
} break;
|
|
271
|
+
case PrimitiveKind::UInt64: {
|
|
272
|
+
uint64_t v = *(uint64_t *)ptr;
|
|
273
|
+
obj.Set(member.name, Napi::BigInt::New(env, v));
|
|
274
|
+
} break;
|
|
275
|
+
case PrimitiveKind::String: {
|
|
276
|
+
const char *str = *(const char **)ptr;
|
|
277
|
+
obj.Set(member.name, Napi::String::New(env, str));
|
|
278
|
+
} break;
|
|
279
|
+
case PrimitiveKind::String16: {
|
|
280
|
+
const char16_t *str16 = *(const char16_t **)ptr;
|
|
281
|
+
obj.Set(member.name, Napi::String::New(env, str16));
|
|
282
|
+
} break;
|
|
283
|
+
case PrimitiveKind::Pointer: {
|
|
284
|
+
void *ptr2 = *(void **)ptr;
|
|
285
|
+
|
|
286
|
+
Napi::External<void> external = Napi::External<void>::New(env, ptr2);
|
|
287
|
+
SetValueTag(instance, external, member.type);
|
|
288
|
+
|
|
289
|
+
obj.Set(member.name, external);
|
|
290
|
+
} break;
|
|
291
|
+
case PrimitiveKind::Record: {
|
|
292
|
+
Napi::Object obj2 = PopObject(ptr, member.type);
|
|
293
|
+
obj.Set(member.name, obj2);
|
|
294
|
+
} break;
|
|
295
|
+
case PrimitiveKind::Float32: {
|
|
296
|
+
float f;
|
|
297
|
+
memcpy(&f, ptr, 4);
|
|
298
|
+
obj.Set(member.name, Napi::Number::New(env, (double)f));
|
|
299
|
+
} break;
|
|
300
|
+
case PrimitiveKind::Float64: {
|
|
301
|
+
double d;
|
|
302
|
+
memcpy(&d, ptr, 8);
|
|
303
|
+
obj.Set(member.name, Napi::Number::New(env, d));
|
|
304
|
+
} break;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
ptr += member.type->size;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
Napi::Object CallData::PopObject(const uint8_t *ptr, const TypeInfo *type)
|
|
312
|
+
{
|
|
313
|
+
Napi::Object obj = Napi::Object::New(env);
|
|
314
|
+
PopObject(obj, ptr, type);
|
|
315
|
+
return obj;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
static void DumpMemory(const char *type, Span<const uint8_t> bytes)
|
|
319
|
+
{
|
|
320
|
+
if (bytes.len) {
|
|
321
|
+
PrintLn(stderr, "%1 at 0x%2 (%3):", type, bytes.ptr, FmtMemSize(bytes.len));
|
|
322
|
+
|
|
323
|
+
for (const uint8_t *ptr = bytes.begin(); ptr < bytes.end();) {
|
|
324
|
+
Print(stderr, " [0x%1 %2 %3] ", FmtArg(ptr).Pad0(-16),
|
|
325
|
+
FmtArg((ptr - bytes.begin()) / sizeof(void *)).Pad(-4),
|
|
326
|
+
FmtArg(ptr - bytes.begin()).Pad(-4));
|
|
327
|
+
for (int i = 0; ptr < bytes.end() && i < (int)sizeof(void *); i++, ptr++) {
|
|
328
|
+
Print(stderr, " %1", FmtHex(*ptr).Pad0(-2));
|
|
329
|
+
}
|
|
330
|
+
PrintLn(stderr);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
void CallData::DumpDebug() const
|
|
336
|
+
{
|
|
337
|
+
PrintLn(stderr, "%!..+---- %1 (%2) ----%!0", func->name, CallConventionNames[(int)func->convention]);
|
|
338
|
+
|
|
339
|
+
if (func->parameters.len) {
|
|
340
|
+
PrintLn(stderr, "Parameters:");
|
|
341
|
+
for (Size i = 0; i < func->parameters.len; i++) {
|
|
342
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
343
|
+
PrintLn(stderr, " %1 = %2 (%3)", i, param.type->name, FmtMemSize(param.type->size));
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
PrintLn(stderr, "Return: %1 (%2)", func->ret.type->name, FmtMemSize(func->ret.type->size));
|
|
347
|
+
|
|
348
|
+
DumpMemory("Stack", stack);
|
|
349
|
+
DumpMemory("Heap", heap);
|
|
350
|
+
}
|
|
351
|
+
|
|
228
352
|
}
|
package/src/call.hh
CHANGED
|
@@ -24,38 +24,61 @@ namespace RG {
|
|
|
24
24
|
bool AnalyseFunction(InstanceData *instance, FunctionInfo *func);
|
|
25
25
|
|
|
26
26
|
class CallData {
|
|
27
|
+
struct OutObject {
|
|
28
|
+
Napi::ObjectReference ref;
|
|
29
|
+
const uint8_t *ptr;
|
|
30
|
+
const TypeInfo *type;
|
|
31
|
+
};
|
|
32
|
+
|
|
27
33
|
Napi::Env env;
|
|
28
34
|
InstanceData *instance;
|
|
29
35
|
const FunctionInfo *func;
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
Span<uint8_t> *heap_mem;
|
|
33
|
-
BlockAllocator big_alloc;
|
|
37
|
+
bool debug;
|
|
34
38
|
|
|
39
|
+
InstanceMemory *mem;
|
|
35
40
|
Span<uint8_t> old_stack_mem;
|
|
36
41
|
Span<uint8_t> old_heap_mem;
|
|
37
42
|
|
|
43
|
+
LocalArray<OutObject, MaxOutParameters> out_objects;
|
|
44
|
+
|
|
45
|
+
Span<uint8_t> heap;
|
|
46
|
+
Span<uint8_t> stack;
|
|
47
|
+
|
|
48
|
+
union {
|
|
49
|
+
uint32_t u32;
|
|
50
|
+
uint64_t u64;
|
|
51
|
+
float f;
|
|
52
|
+
double d;
|
|
53
|
+
void *ptr;
|
|
54
|
+
uint8_t buf[32];
|
|
55
|
+
} result;
|
|
56
|
+
uint8_t *return_ptr = nullptr;
|
|
57
|
+
|
|
38
58
|
public:
|
|
39
|
-
CallData(Napi::Env env,
|
|
59
|
+
CallData(Napi::Env env, const FunctionInfo *func, InstanceMemory *mem, bool debug);
|
|
40
60
|
~CallData();
|
|
41
61
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
Size len = old_stack_mem.end() - sp;
|
|
46
|
-
|
|
47
|
-
return MakeSpan(sp, len);
|
|
48
|
-
}
|
|
49
|
-
uint8_t *GetSP() const { return stack_mem->end(); };
|
|
62
|
+
bool Prepare(const Napi::CallbackInfo &info);
|
|
63
|
+
void Execute();
|
|
64
|
+
Napi::Value Complete();
|
|
50
65
|
|
|
51
|
-
|
|
66
|
+
Napi::Value Run(const Napi::CallbackInfo &info)
|
|
52
67
|
{
|
|
53
|
-
|
|
54
|
-
|
|
68
|
+
if (!RG_UNLIKELY(Prepare(info)))
|
|
69
|
+
return env.Null();
|
|
70
|
+
|
|
71
|
+
if (debug) {
|
|
72
|
+
DumpDebug();
|
|
73
|
+
}
|
|
74
|
+
Execute();
|
|
55
75
|
|
|
56
|
-
return
|
|
76
|
+
return Complete();
|
|
57
77
|
}
|
|
58
78
|
|
|
79
|
+
void DumpDebug() const;
|
|
80
|
+
|
|
81
|
+
private:
|
|
59
82
|
template <typename T = void>
|
|
60
83
|
bool AllocStack(Size size, Size align, T **out_ptr = nullptr);
|
|
61
84
|
template <typename T = void>
|
|
@@ -65,27 +88,26 @@ public:
|
|
|
65
88
|
const char16_t *PushString16(const Napi::Value &value);
|
|
66
89
|
bool PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t *dest);
|
|
67
90
|
|
|
68
|
-
void
|
|
69
|
-
|
|
70
|
-
Napi::Value Execute(const Napi::CallbackInfo &info);
|
|
91
|
+
void PopObject(Napi::Object obj, const uint8_t *ptr, const TypeInfo *type);
|
|
92
|
+
Napi::Object PopObject(const uint8_t *ptr, const TypeInfo *type);
|
|
71
93
|
};
|
|
72
94
|
|
|
73
95
|
template <typename T>
|
|
74
96
|
bool CallData::AllocStack(Size size, Size align, T **out_ptr)
|
|
75
97
|
{
|
|
76
|
-
uint8_t *ptr = AlignDown(
|
|
77
|
-
Size delta =
|
|
98
|
+
uint8_t *ptr = AlignDown(mem->stack.end() - size, align);
|
|
99
|
+
Size delta = mem->stack.end() - ptr;
|
|
78
100
|
|
|
79
|
-
if (RG_UNLIKELY(
|
|
101
|
+
if (RG_UNLIKELY(mem->stack.len < delta)) {
|
|
80
102
|
ThrowError<Napi::Error>(env, "FFI call is taking up too much memory");
|
|
81
103
|
return false;
|
|
82
104
|
}
|
|
83
105
|
|
|
84
|
-
if (
|
|
106
|
+
if (debug) {
|
|
85
107
|
memset(ptr, 0, delta);
|
|
86
108
|
}
|
|
87
109
|
|
|
88
|
-
|
|
110
|
+
mem->stack.len -= delta;
|
|
89
111
|
|
|
90
112
|
if (out_ptr) {
|
|
91
113
|
*out_ptr = (T *)ptr;
|
|
@@ -96,20 +118,20 @@ bool CallData::AllocStack(Size size, Size align, T **out_ptr)
|
|
|
96
118
|
template <typename T>
|
|
97
119
|
bool CallData::AllocHeap(Size size, Size align, T **out_ptr)
|
|
98
120
|
{
|
|
99
|
-
uint8_t *ptr = AlignUp(
|
|
100
|
-
Size delta = size + (ptr -
|
|
121
|
+
uint8_t *ptr = AlignUp(mem->heap.ptr, align);
|
|
122
|
+
Size delta = size + (ptr - mem->heap.ptr);
|
|
101
123
|
|
|
102
|
-
if (RG_UNLIKELY(delta >
|
|
124
|
+
if (RG_UNLIKELY(delta > mem->heap.len)) {
|
|
103
125
|
ThrowError<Napi::Error>(env, "FFI call is taking up too much memory");
|
|
104
126
|
return false;
|
|
105
127
|
}
|
|
106
128
|
|
|
107
|
-
if (
|
|
108
|
-
memset(
|
|
129
|
+
if (debug) {
|
|
130
|
+
memset(mem->heap.ptr, 0, (size_t)delta);
|
|
109
131
|
}
|
|
110
132
|
|
|
111
|
-
|
|
112
|
-
|
|
133
|
+
mem->heap.ptr += delta;
|
|
134
|
+
mem->heap.len -= delta;
|
|
113
135
|
|
|
114
136
|
if (out_ptr) {
|
|
115
137
|
*out_ptr = (T *)ptr;
|
package/src/ffi.cc
CHANGED
|
@@ -241,14 +241,57 @@ static Napi::Value MarkInOut(const Napi::CallbackInfo &info)
|
|
|
241
241
|
return EncodePointerDirection(info, 3);
|
|
242
242
|
}
|
|
243
243
|
|
|
244
|
+
static Span<uint8_t> AllocateAndAlign16(Allocator *alloc, Size size)
|
|
245
|
+
{
|
|
246
|
+
RG_ASSERT(AlignLen(size, 16) == size);
|
|
247
|
+
RG_ASSERT(size >= Kibibytes(1));
|
|
248
|
+
|
|
249
|
+
// Account for allocator overhead
|
|
250
|
+
size -= 256;
|
|
251
|
+
|
|
252
|
+
uint8_t *ptr = (uint8_t *)Allocator::Allocate(alloc, size);
|
|
253
|
+
uint8_t *aligned = AlignUp(ptr, 16);
|
|
254
|
+
Size delta = AlignLen(aligned - ptr, 16);
|
|
255
|
+
|
|
256
|
+
return MakeSpan(aligned, size - delta);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
static InstanceMemory *AllocateCallMemory(InstanceData *instance)
|
|
260
|
+
{
|
|
261
|
+
for (InstanceMemory *mem: instance->memories) {
|
|
262
|
+
if (!mem->depth)
|
|
263
|
+
return mem;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
InstanceMemory *mem = new InstanceMemory();
|
|
267
|
+
|
|
268
|
+
mem->stack = AllocateAndAlign16(&mem->mem_alloc, Mebibytes(1));
|
|
269
|
+
mem->heap = AllocateAndAlign16(&mem->mem_alloc, Mebibytes(2));
|
|
270
|
+
|
|
271
|
+
if (instance->memories.Available()) {
|
|
272
|
+
instance->memories.Append(mem);
|
|
273
|
+
} else {
|
|
274
|
+
mem->temporary = true;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return mem;
|
|
278
|
+
}
|
|
279
|
+
|
|
244
280
|
static Napi::Value TranslateNormalCall(const Napi::CallbackInfo &info)
|
|
245
281
|
{
|
|
246
282
|
Napi::Env env = info.Env();
|
|
247
283
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
248
284
|
FunctionInfo *func = (FunctionInfo *)info.Data();
|
|
249
285
|
|
|
250
|
-
|
|
251
|
-
|
|
286
|
+
if (info.Length() < (uint32_t)func->parameters.len) {
|
|
287
|
+
ThrowError<Napi::TypeError>(env, "Expected %1 arguments, got %2", func->parameters.len, info.Length());
|
|
288
|
+
return env.Null();
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
InstanceMemory *mem = AllocateCallMemory(instance);
|
|
292
|
+
CallData call(env, func, mem, instance->debug);
|
|
293
|
+
|
|
294
|
+
return call.Run(info);
|
|
252
295
|
}
|
|
253
296
|
|
|
254
297
|
static Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info)
|
|
@@ -266,6 +309,10 @@ static Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info)
|
|
|
266
309
|
func.parameters.Leak();
|
|
267
310
|
};
|
|
268
311
|
|
|
312
|
+
if (info.Length() < (uint32_t)func.parameters.len) {
|
|
313
|
+
ThrowError<Napi::TypeError>(env, "Expected %1 arguments or more, got %2", func.parameters.len, info.Length());
|
|
314
|
+
return env.Null();
|
|
315
|
+
}
|
|
269
316
|
if ((info.Length() - func.parameters.len) % 2) {
|
|
270
317
|
ThrowError<Napi::Error>(env, "Missing value argument for variadic call");
|
|
271
318
|
return env.Null();
|
|
@@ -300,8 +347,91 @@ static Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info)
|
|
|
300
347
|
if (!AnalyseFunction(instance, &func))
|
|
301
348
|
return env.Null();
|
|
302
349
|
|
|
303
|
-
|
|
304
|
-
|
|
350
|
+
InstanceMemory *mem = AllocateCallMemory(instance);
|
|
351
|
+
CallData call(env, &func, mem, instance->debug);
|
|
352
|
+
|
|
353
|
+
return call.Run(info);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
class AsyncCall: public Napi::AsyncWorker {
|
|
357
|
+
Napi::Env env;
|
|
358
|
+
const FunctionInfo *func;
|
|
359
|
+
|
|
360
|
+
CallData call;
|
|
361
|
+
bool prepared = false;
|
|
362
|
+
|
|
363
|
+
public:
|
|
364
|
+
AsyncCall(Napi::Env env, InstanceMemory *mem, FunctionInfo *func, bool debug,
|
|
365
|
+
Napi::Function &callback)
|
|
366
|
+
: Napi::AsyncWorker(callback), env(env), func(func->Ref()),
|
|
367
|
+
call(env, func, mem, debug) {}
|
|
368
|
+
~AsyncCall() { func->Unref(); }
|
|
369
|
+
|
|
370
|
+
bool Prepare(const Napi::CallbackInfo &info) {
|
|
371
|
+
prepared = call.Prepare(info);
|
|
372
|
+
|
|
373
|
+
if (!prepared) {
|
|
374
|
+
Napi::Error err = env.GetAndClearPendingException();
|
|
375
|
+
SetError(err.Message());
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return prepared;
|
|
379
|
+
}
|
|
380
|
+
void DumpDebug() { call.DumpDebug(); }
|
|
381
|
+
|
|
382
|
+
void Execute() override;
|
|
383
|
+
void OnOK() override;
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
void AsyncCall::Execute()
|
|
387
|
+
{
|
|
388
|
+
if (prepared) {
|
|
389
|
+
call.Execute();
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
void AsyncCall::OnOK()
|
|
394
|
+
{
|
|
395
|
+
RG_ASSERT(prepared);
|
|
396
|
+
|
|
397
|
+
Napi::FunctionReference &callback = Callback();
|
|
398
|
+
|
|
399
|
+
Napi::Value self = env.Null();
|
|
400
|
+
napi_value args[] = {
|
|
401
|
+
env.Null(),
|
|
402
|
+
call.Complete()
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
callback.Call(self, RG_LEN(args), args);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
static Napi::Value TranslateAsyncCall(const Napi::CallbackInfo &info)
|
|
409
|
+
{
|
|
410
|
+
Napi::Env env = info.Env();
|
|
411
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
412
|
+
FunctionInfo *func = (FunctionInfo *)info.Data();
|
|
413
|
+
|
|
414
|
+
if (info.Length() <= (uint32_t)func->parameters.len) {
|
|
415
|
+
ThrowError<Napi::TypeError>(env, "Expected %1 arguments, got %2", func->parameters.len + 1, info.Length());
|
|
416
|
+
return env.Null();
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
Napi::Function callback = info[(uint32_t)func->parameters.len].As<Napi::Function>();
|
|
420
|
+
|
|
421
|
+
if (!callback.IsFunction()) {
|
|
422
|
+
ThrowError<Napi::TypeError>(env, "Expected callback function as last arguments, got %1", GetValueType(instance, callback));
|
|
423
|
+
return env.Null();
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
InstanceMemory *mem = AllocateCallMemory(instance);
|
|
427
|
+
AsyncCall *async = new AsyncCall(env, mem, func, instance->debug, callback);
|
|
428
|
+
|
|
429
|
+
if (async->Prepare(info) && instance->debug) {
|
|
430
|
+
async->DumpDebug();
|
|
431
|
+
}
|
|
432
|
+
async->Queue();
|
|
433
|
+
|
|
434
|
+
return env.Null();
|
|
305
435
|
}
|
|
306
436
|
|
|
307
437
|
static bool ParseClassicFunction(Napi::Env env, Napi::String name, Napi::Value ret,
|
|
@@ -377,7 +507,7 @@ static Napi::Value FindLibraryFunction(const Napi::CallbackInfo &info, CallConve
|
|
|
377
507
|
LibraryHolder *lib = (LibraryHolder *)info.Data();
|
|
378
508
|
|
|
379
509
|
FunctionInfo *func = new FunctionInfo();
|
|
380
|
-
|
|
510
|
+
RG_DEFER { func->Unref(); };
|
|
381
511
|
|
|
382
512
|
func->lib = lib->Ref();
|
|
383
513
|
func->convention = convention;
|
|
@@ -436,9 +566,14 @@ static Napi::Value FindLibraryFunction(const Napi::CallbackInfo &info, CallConve
|
|
|
436
566
|
}
|
|
437
567
|
|
|
438
568
|
Napi::Function::Callback call = func->variadic ? TranslateVariadicCall : TranslateNormalCall;
|
|
439
|
-
Napi::Function wrapper = Napi::Function::New(env, call, func->name, (void *)func);
|
|
440
|
-
wrapper.AddFinalizer([](Napi::Env, FunctionInfo *func) {
|
|
441
|
-
|
|
569
|
+
Napi::Function wrapper = Napi::Function::New(env, call, func->name, (void *)func->Ref());
|
|
570
|
+
wrapper.AddFinalizer([](Napi::Env, FunctionInfo *func) { func->Unref(); }, func);
|
|
571
|
+
|
|
572
|
+
if (!func->variadic) {
|
|
573
|
+
Napi::Function async = Napi::Function::New(env, TranslateAsyncCall, func->name, (void *)func->Ref());
|
|
574
|
+
async.AddFinalizer([](Napi::Env, FunctionInfo *func) { func->Unref(); }, func);
|
|
575
|
+
wrapper.Set("async", async);
|
|
576
|
+
}
|
|
442
577
|
|
|
443
578
|
return wrapper;
|
|
444
579
|
}
|
|
@@ -531,13 +666,13 @@ LibraryHolder::~LibraryHolder()
|
|
|
531
666
|
#endif
|
|
532
667
|
}
|
|
533
668
|
|
|
534
|
-
LibraryHolder *LibraryHolder::Ref()
|
|
669
|
+
const LibraryHolder *LibraryHolder::Ref() const
|
|
535
670
|
{
|
|
536
671
|
refcount++;
|
|
537
672
|
return this;
|
|
538
673
|
}
|
|
539
674
|
|
|
540
|
-
void LibraryHolder::Unref()
|
|
675
|
+
void LibraryHolder::Unref() const
|
|
541
676
|
{
|
|
542
677
|
if (!--refcount) {
|
|
543
678
|
delete this;
|
|
@@ -637,21 +772,30 @@ FunctionInfo::~FunctionInfo()
|
|
|
637
772
|
}
|
|
638
773
|
}
|
|
639
774
|
|
|
640
|
-
|
|
775
|
+
const FunctionInfo *FunctionInfo::Ref() const
|
|
641
776
|
{
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
uint8_t *aligned = AlignUp(ptr, 16);
|
|
646
|
-
Size delta = AlignLen(aligned - ptr, 16);
|
|
777
|
+
refcount++;
|
|
778
|
+
return this;
|
|
779
|
+
}
|
|
647
780
|
|
|
648
|
-
|
|
781
|
+
void FunctionInfo::Unref() const
|
|
782
|
+
{
|
|
783
|
+
if (!--refcount) {
|
|
784
|
+
delete this;
|
|
785
|
+
}
|
|
649
786
|
}
|
|
650
787
|
|
|
651
788
|
InstanceData::InstanceData()
|
|
652
789
|
{
|
|
653
|
-
|
|
654
|
-
|
|
790
|
+
AllocateCallMemory(this);
|
|
791
|
+
RG_ASSERT(memories.len == 1);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
InstanceData::~InstanceData()
|
|
795
|
+
{
|
|
796
|
+
for (InstanceMemory *mem: memories) {
|
|
797
|
+
delete mem;
|
|
798
|
+
}
|
|
655
799
|
}
|
|
656
800
|
|
|
657
801
|
template <typename Func>
|