koffi 2.3.4 → 2.3.5
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/CHANGELOG.md +18 -2
- package/doc/changelog.md +4 -0
- package/doc/index.rst +1 -2
- package/doc/types.md +3 -3
- package/package.json +2 -2
- package/src/core/libcc/libcc.cc +2 -2
- package/src/koffi/build/2.3.5/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.5/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.5/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.5/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.5/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.5/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.3.5/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.5/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.5/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.3.5/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.5/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.5/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.5/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.5/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.5/koffi_win32_x64.tar.gz +0 -0
- package/src/koffi/src/abi_arm32.cc +43 -14
- package/src/koffi/src/abi_arm64.cc +95 -21
- package/src/koffi/src/abi_riscv64.cc +125 -64
- package/src/koffi/src/abi_x64_sysv.cc +38 -20
- package/src/koffi/src/abi_x64_win.cc +11 -5
- package/src/koffi/src/abi_x86.cc +14 -7
- package/src/koffi/src/call.cc +114 -44
- package/src/koffi/src/call.hh +6 -4
- package/src/koffi/src/ffi.cc +172 -147
- package/src/koffi/src/ffi.hh +18 -10
- package/src/koffi/src/index.d.ts +28 -7
- package/src/koffi/src/util.cc +261 -69
- package/src/koffi/src/util.hh +34 -8
- package/vendor/node-addon-api/CHANGELOG.md +122 -9
- package/vendor/node-addon-api/CONTRIBUTING.md +10 -10
- package/vendor/node-addon-api/README.md +36 -12
- package/vendor/node-addon-api/benchmark/function_args.cc +95 -62
- package/vendor/node-addon-api/benchmark/function_args.js +6 -6
- package/vendor/node-addon-api/benchmark/index.js +1 -1
- package/vendor/node-addon-api/benchmark/property_descriptor.cc +27 -34
- package/vendor/node-addon-api/benchmark/property_descriptor.js +5 -4
- package/vendor/node-addon-api/doc/async_operations.md +1 -1
- package/vendor/node-addon-api/doc/async_worker_variants.md +23 -2
- package/vendor/node-addon-api/doc/cmake-js.md +1 -1
- package/vendor/node-addon-api/doc/error_handling.md +3 -3
- package/vendor/node-addon-api/doc/external.md +7 -0
- package/vendor/node-addon-api/doc/handle_scope.md +14 -0
- package/vendor/node-addon-api/doc/hierarchy.md +1 -1
- package/vendor/node-addon-api/doc/object.md +27 -0
- package/vendor/node-addon-api/index.js +3 -3
- package/vendor/node-addon-api/napi-inl.deprecated.h +121 -127
- package/vendor/node-addon-api/napi-inl.h +1178 -1144
- package/vendor/node-addon-api/napi.h +2786 -2675
- package/vendor/node-addon-api/package.json +42 -1
- package/vendor/node-addon-api/test/addon.cc +8 -6
- package/vendor/node-addon-api/test/addon_build/index.js +9 -9
- package/vendor/node-addon-api/test/addon_build/tpl/addon.cc +2 -1
- package/vendor/node-addon-api/test/addon_build/tpl/index.js +4 -4
- package/vendor/node-addon-api/test/addon_data.cc +12 -13
- package/vendor/node-addon-api/test/array_buffer.js +3 -2
- package/vendor/node-addon-api/test/async_progress_queue_worker.cc +13 -3
- package/vendor/node-addon-api/test/async_progress_queue_worker.js +5 -5
- package/vendor/node-addon-api/test/async_progress_worker.cc +65 -9
- package/vendor/node-addon-api/test/async_progress_worker.js +14 -9
- package/vendor/node-addon-api/test/async_worker.cc +236 -3
- package/vendor/node-addon-api/test/async_worker.js +122 -37
- package/vendor/node-addon-api/test/async_worker_nocallback.js +9 -3
- package/vendor/node-addon-api/test/async_worker_persistent.js +2 -2
- package/vendor/node-addon-api/test/basic_types/array.js +3 -4
- package/vendor/node-addon-api/test/basic_types/boolean.cc +4 -2
- package/vendor/node-addon-api/test/basic_types/boolean.js +1 -2
- package/vendor/node-addon-api/test/basic_types/number.cc +12 -6
- package/vendor/node-addon-api/test/basic_types/number.js +19 -18
- package/vendor/node-addon-api/test/basic_types/value.cc +52 -1
- package/vendor/node-addon-api/test/basic_types/value.js +44 -21
- package/vendor/node-addon-api/test/bigint.cc +2 -1
- package/vendor/node-addon-api/test/binding.cc +11 -5
- package/vendor/node-addon-api/test/binding.gyp +3 -1
- package/vendor/node-addon-api/test/buffer.cc +46 -38
- package/vendor/node-addon-api/test/buffer.js +12 -12
- package/vendor/node-addon-api/test/callbackInfo.cc +27 -0
- package/vendor/node-addon-api/test/callbackInfo.js +9 -0
- package/vendor/node-addon-api/test/callbackscope.cc +19 -2
- package/vendor/node-addon-api/test/callbackscope.js +20 -20
- package/vendor/node-addon-api/test/common/index.js +37 -4
- package/vendor/node-addon-api/test/dataview/dataview.js +5 -5
- package/vendor/node-addon-api/test/dataview/dataview_read_write.js +14 -12
- package/vendor/node-addon-api/test/date.cc +2 -1
- package/vendor/node-addon-api/test/date.js +2 -2
- package/vendor/node-addon-api/test/env_cleanup.cc +12 -0
- package/vendor/node-addon-api/test/env_cleanup.js +38 -39
- package/vendor/node-addon-api/test/error.cc +6 -5
- package/vendor/node-addon-api/test/error_terminating_environment.js +64 -60
- package/vendor/node-addon-api/test/external.cc +36 -32
- package/vendor/node-addon-api/test/external.js +43 -46
- package/vendor/node-addon-api/test/function.cc +58 -44
- package/vendor/node-addon-api/test/function.js +4 -0
- package/vendor/node-addon-api/test/function_reference.cc +15 -13
- package/vendor/node-addon-api/test/globalObject/global_object_delete_property.js +50 -53
- package/vendor/node-addon-api/test/globalObject/global_object_get_property.js +33 -34
- package/vendor/node-addon-api/test/globalObject/global_object_has_own_property.js +38 -40
- package/vendor/node-addon-api/test/globalObject/global_object_set_property.js +47 -49
- package/vendor/node-addon-api/test/handlescope.cc +29 -3
- package/vendor/node-addon-api/test/handlescope.js +5 -3
- package/vendor/node-addon-api/test/index.js +1 -5
- package/vendor/node-addon-api/test/maybe/check.cc +49 -3
- package/vendor/node-addon-api/test/maybe/index.js +19 -7
- package/vendor/node-addon-api/test/memory_management.cc +9 -8
- package/vendor/node-addon-api/test/memory_management.js +2 -2
- package/vendor/node-addon-api/test/movable_callbacks.js +2 -2
- package/vendor/node-addon-api/test/name.js +3 -3
- package/vendor/node-addon-api/test/napi_child.js +2 -2
- package/vendor/node-addon-api/test/object/delete_property.js +7 -7
- package/vendor/node-addon-api/test/object/finalizer.cc +13 -12
- package/vendor/node-addon-api/test/object/finalizer.js +2 -2
- package/vendor/node-addon-api/test/object/get_property.js +6 -6
- package/vendor/node-addon-api/test/object/has_own_property.js +3 -3
- package/vendor/node-addon-api/test/object/has_property.js +4 -4
- package/vendor/node-addon-api/test/object/object.cc +191 -111
- package/vendor/node-addon-api/test/object/object.js +53 -52
- package/vendor/node-addon-api/test/object/object_deprecated.cc +24 -20
- package/vendor/node-addon-api/test/object/object_deprecated.js +3 -8
- package/vendor/node-addon-api/test/object/object_freeze_seal.js +54 -54
- package/vendor/node-addon-api/test/object/object_type_tag.cc +39 -0
- package/vendor/node-addon-api/test/object/object_type_tag.js +55 -0
- package/vendor/node-addon-api/test/object/subscript_operator.js +2 -2
- package/vendor/node-addon-api/test/object_reference.js +100 -100
- package/vendor/node-addon-api/test/objectwrap.cc +41 -34
- package/vendor/node-addon-api/test/objectwrap.js +23 -19
- package/vendor/node-addon-api/test/objectwrap_constructor_exception.cc +5 -5
- package/vendor/node-addon-api/test/objectwrap_constructor_exception.js +1 -1
- package/vendor/node-addon-api/test/objectwrap_multiple_inheritance.cc +7 -7
- package/vendor/node-addon-api/test/objectwrap_multiple_inheritance.js +1 -1
- package/vendor/node-addon-api/test/objectwrap_removewrap.js +24 -32
- package/vendor/node-addon-api/test/objectwrap_worker_thread.js +5 -4
- package/vendor/node-addon-api/test/promise.cc +7 -0
- package/vendor/node-addon-api/test/promise.js +3 -1
- package/vendor/node-addon-api/test/reference.cc +1 -1
- package/vendor/node-addon-api/test/reference.js +2 -2
- package/vendor/node-addon-api/test/run_script.cc +1 -1
- package/vendor/node-addon-api/test/symbol.js +59 -66
- package/vendor/node-addon-api/test/testUtil.js +6 -6
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function.cc +64 -29
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function.js +71 -34
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ctx.cc +111 -19
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ctx.js +2 -1
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_existing_tsfn.cc +36 -26
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_existing_tsfn.js +5 -5
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ptr.cc +3 -2
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ptr.js +1 -1
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_sum.cc +47 -32
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_sum.js +3 -3
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_unref.cc +22 -9
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_unref.js +76 -31
- package/vendor/node-addon-api/test/thunking_manual.cc +61 -74
- package/vendor/node-addon-api/test/thunking_manual.js +6 -7
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function.cc +20 -20
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function.js +19 -19
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ctx.cc +57 -5
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ctx.js +2 -0
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_existing_tsfn.js +5 -5
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ptr.cc +5 -1
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ptr.js +4 -3
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_sum.js +3 -3
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_unref.cc +14 -0
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_unref.js +76 -31
- package/vendor/node-addon-api/test/typedarray-bigint.js +2 -2
- package/vendor/node-addon-api/test/typedarray.cc +263 -70
- package/vendor/node-addon-api/test/typedarray.js +44 -10
- package/vendor/node-addon-api/test/version_management.cc +16 -15
- package/vendor/node-addon-api/test/version_management.js +18 -20
- package/vendor/node-addon-api/tools/check-napi.js +13 -14
- package/vendor/node-addon-api/tools/conversion.js +161 -169
- package/vendor/node-addon-api/tools/eslint-format.js +9 -1
- package/vendor/node-addon-api/unit-test/README.md +4 -4
- package/src/koffi/build/2.3.4/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_win32_x64.tar.gz +0 -0
|
@@ -64,11 +64,21 @@ extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_va
|
|
|
64
64
|
|
|
65
65
|
#include "abi_trampolines.inc"
|
|
66
66
|
|
|
67
|
-
static void
|
|
67
|
+
static inline void ExpandPair(const uint8_t raw[16], int size1, int size2, uint64_t out_regs[2])
|
|
68
68
|
{
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
memcpy(out_regs + 0, raw, size1);
|
|
70
|
+
memcpy(out_regs + 1, raw + size1, size2);
|
|
71
|
+
}
|
|
71
72
|
|
|
73
|
+
static inline void CompactPair(const uint64_t regs[2], int size1, int size2, uint8_t out_raw[16])
|
|
74
|
+
{
|
|
75
|
+
memcpy(out_raw, regs + 0, size1);
|
|
76
|
+
memcpy(out_raw + size1, regs + 1, size2);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static void AnalyseParameter(ParameterInfo *param, int gpr_avail, int vec_avail)
|
|
80
|
+
{
|
|
81
|
+
// Too big, pass pointer to struct
|
|
72
82
|
if (param->type->size > 16) {
|
|
73
83
|
param->gpr_count = gpr_avail ? 1 : 0;
|
|
74
84
|
param->use_memory = true;
|
|
@@ -76,36 +86,55 @@ static void AnalyseParameter(ParameterInfo *param, int gpr_avail, int vec_avail)
|
|
|
76
86
|
return;
|
|
77
87
|
}
|
|
78
88
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
bool gpr_first = false;
|
|
89
|
+
gpr_avail = std::min(2, gpr_avail);
|
|
90
|
+
vec_avail = std::min(2, vec_avail);
|
|
82
91
|
|
|
83
|
-
AnalyseFlat(param->type, [&](const TypeInfo *type, int offset, int count) {
|
|
84
92
|
#if defined(__riscv_float_abi_double)
|
|
85
|
-
|
|
93
|
+
if (param->type->primitive != PrimitiveKind::Union) {
|
|
94
|
+
int gpr_count = 0;
|
|
95
|
+
int vec_count = 0;
|
|
96
|
+
bool gpr_first = false;
|
|
97
|
+
|
|
98
|
+
AnalyseFlat(param->type, [&](const TypeInfo *type, int offset, int count) {
|
|
99
|
+
if (IsFloat(type)) {
|
|
100
|
+
vec_count += count;
|
|
101
|
+
} else {
|
|
102
|
+
gpr_count += count;
|
|
103
|
+
gpr_first |= !vec_count;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// We'll reset reg_size if the following conditions don't match,
|
|
107
|
+
// such as having more than two values.
|
|
108
|
+
param->reg_size[offset % 2] = (int8_t)type->size;
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Pass mixed float-integer structs in one GPR and one FP register
|
|
112
|
+
if (gpr_count == 1 && vec_count == 1 && gpr_avail && vec_avail) {
|
|
113
|
+
param->gpr_count = 1;
|
|
114
|
+
param->vec_count = 1;
|
|
115
|
+
param->gpr_first = gpr_first;
|
|
116
|
+
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// HFA rules
|
|
121
|
+
if (vec_count && !gpr_count && vec_count <= vec_avail) {
|
|
122
|
+
param->vec_count = vec_count;
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
86
126
|
#elif defined(__riscv_float_abi_soft)
|
|
87
|
-
|
|
127
|
+
// Use integer conventions
|
|
88
128
|
#else
|
|
89
|
-
|
|
129
|
+
#error The RISC-V single-precision float ABI (LP64F) is not supported
|
|
90
130
|
#endif
|
|
91
131
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
if (gpr_count == 1 && vec_count == 1 && gpr_avail && vec_avail) {
|
|
101
|
-
param->gpr_count = 1;
|
|
102
|
-
param->vec_count = 1;
|
|
103
|
-
param->gpr_first = gpr_first;
|
|
104
|
-
} else if (vec_count && !gpr_count && vec_count <= vec_avail) {
|
|
105
|
-
param->vec_count = vec_count;
|
|
106
|
-
} else if (gpr_avail) {
|
|
107
|
-
param->gpr_count = (param->type->size + 7) / 8;
|
|
108
|
-
param->gpr_first = true;
|
|
132
|
+
param->reg_size[0] = 8;
|
|
133
|
+
param->reg_size[1] = 8;
|
|
134
|
+
|
|
135
|
+
if (gpr_avail) {
|
|
136
|
+
param->gpr_count = std::min(gpr_avail, (param->type->size + 7) / 8);
|
|
137
|
+
param->gpr_first = param->gpr_count;
|
|
109
138
|
}
|
|
110
139
|
}
|
|
111
140
|
|
|
@@ -222,7 +251,8 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
222
251
|
|
|
223
252
|
*(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
|
|
224
253
|
} break;
|
|
225
|
-
case PrimitiveKind::Record:
|
|
254
|
+
case PrimitiveKind::Record:
|
|
255
|
+
case PrimitiveKind::Union: {
|
|
226
256
|
if (RG_UNLIKELY(!IsObject(value))) {
|
|
227
257
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
228
258
|
return false;
|
|
@@ -233,25 +263,34 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
233
263
|
if (!param.use_memory) {
|
|
234
264
|
RG_ASSERT(param.type->size <= 16);
|
|
235
265
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
266
|
+
uint64_t regs[2] = { 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull };
|
|
267
|
+
{
|
|
268
|
+
uint8_t buf[16] = {};
|
|
269
|
+
if (!PushObject(obj, param.type, buf))
|
|
270
|
+
return false;
|
|
271
|
+
ExpandPair(buf, param.reg_size[0], param.reg_size[1], regs);
|
|
272
|
+
}
|
|
243
273
|
|
|
244
274
|
if (param.gpr_first) {
|
|
245
|
-
*(gpr_ptr++) =
|
|
246
|
-
|
|
247
|
-
|
|
275
|
+
*(gpr_ptr++) = regs[0];
|
|
276
|
+
if (param.gpr_count == 2) {
|
|
277
|
+
*(gpr_ptr++) = regs[1];
|
|
278
|
+
} else if (param.vec_count == 1) {
|
|
279
|
+
*(vec_ptr++) = regs[1];
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
args_ptr = std::max(gpr_ptr, args_ptr);
|
|
248
283
|
} else if (param.vec_count) {
|
|
249
|
-
*(vec_ptr++) =
|
|
250
|
-
|
|
284
|
+
*(vec_ptr++) = regs[0];
|
|
285
|
+
if (param.vec_count == 2) {
|
|
286
|
+
*(vec_ptr++) = regs[1];
|
|
287
|
+
} else if (param.gpr_count == 1) {
|
|
288
|
+
*(gpr_ptr++) = regs[1];
|
|
289
|
+
}
|
|
251
290
|
} else {
|
|
252
291
|
RG_ASSERT(param.type->align <= 8);
|
|
253
292
|
|
|
254
|
-
memcpy_safe(args_ptr,
|
|
293
|
+
memcpy_safe(args_ptr, regs, param.type->size);
|
|
255
294
|
args_ptr += (param.type->size + 7) / 8;
|
|
256
295
|
}
|
|
257
296
|
} else {
|
|
@@ -370,7 +409,8 @@ void CallData::Execute(const FunctionInfo *func)
|
|
|
370
409
|
case PrimitiveKind::String16:
|
|
371
410
|
case PrimitiveKind::Pointer:
|
|
372
411
|
case PrimitiveKind::Callback: { result.u64 = PERFORM_CALL(GG).a0; } break;
|
|
373
|
-
case PrimitiveKind::Record:
|
|
412
|
+
case PrimitiveKind::Record:
|
|
413
|
+
case PrimitiveKind::Union: {
|
|
374
414
|
if (func->ret.gpr_first && !func->ret.vec_count) {
|
|
375
415
|
A0A1Ret ret = PERFORM_CALL(GG);
|
|
376
416
|
memcpy(&result.buf, &ret, RG_SIZE(ret));
|
|
@@ -435,15 +475,16 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
435
475
|
return env.Null();
|
|
436
476
|
}
|
|
437
477
|
} break;
|
|
438
|
-
case PrimitiveKind::Record:
|
|
439
|
-
|
|
440
|
-
|
|
478
|
+
case PrimitiveKind::Record:
|
|
479
|
+
case PrimitiveKind::Union: {
|
|
480
|
+
if (return_ptr) {
|
|
481
|
+
Napi::Object obj = DecodeObject(env, return_ptr, func->ret.type);
|
|
441
482
|
return obj;
|
|
442
483
|
} else {
|
|
443
|
-
|
|
444
|
-
|
|
484
|
+
uint8_t buf[16] = {};
|
|
485
|
+
CompactPair(&result.u64, func->ret.reg_size[0], func->ret.reg_size[1], buf);
|
|
445
486
|
|
|
446
|
-
Napi::Object obj = DecodeObject(env,
|
|
487
|
+
Napi::Object obj = DecodeObject(env, buf, func->ret.type);
|
|
447
488
|
return obj;
|
|
448
489
|
}
|
|
449
490
|
} break;
|
|
@@ -624,29 +665,29 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
624
665
|
param.type->dispose(env, param.type, ptr2);
|
|
625
666
|
}
|
|
626
667
|
} break;
|
|
627
|
-
case PrimitiveKind::Record:
|
|
668
|
+
case PrimitiveKind::Record:
|
|
669
|
+
case PrimitiveKind::Union: {
|
|
628
670
|
if (!param.use_memory) {
|
|
629
|
-
uint64_t
|
|
630
|
-
uint64_t *ptr = buf;
|
|
671
|
+
uint64_t regs[2] = {};
|
|
631
672
|
|
|
632
673
|
if (param.gpr_first) {
|
|
633
|
-
|
|
634
|
-
|
|
674
|
+
regs[0] = *(gpr_ptr++);
|
|
675
|
+
regs[1] = *((param.vec_count ? vec_ptr : gpr_ptr)++);
|
|
635
676
|
gpr_ptr -= (param.gpr_count == 1);
|
|
636
677
|
} else if (param.vec_count) {
|
|
637
|
-
|
|
638
|
-
|
|
678
|
+
regs[0] = *(vec_ptr++);
|
|
679
|
+
regs[1] = *((param.gpr_count ? gpr_ptr : vec_ptr)++);
|
|
639
680
|
} else {
|
|
640
681
|
RG_ASSERT(param.type->align <= 8);
|
|
641
682
|
|
|
642
|
-
memcpy_safe(
|
|
683
|
+
memcpy_safe(regs, args_ptr, param.type->size);
|
|
643
684
|
args_ptr += (param.type->size + 7) / 8;
|
|
644
685
|
}
|
|
645
686
|
|
|
646
|
-
|
|
647
|
-
|
|
687
|
+
uint8_t buf[16] = {};
|
|
688
|
+
CompactPair(regs, param.reg_size[0], param.reg_size[1], buf);
|
|
648
689
|
|
|
649
|
-
Napi::Object obj = DecodeObject(env,
|
|
690
|
+
Napi::Object obj = DecodeObject(env, buf, param.type);
|
|
650
691
|
arguments.Append(obj);
|
|
651
692
|
} else {
|
|
652
693
|
uint8_t *ptr = *(uint8_t **)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
@@ -768,7 +809,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
768
809
|
|
|
769
810
|
if (CheckValueTag(instance, value, type->ref.marker)) {
|
|
770
811
|
ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
771
|
-
} else if (IsObject(value) && type->ref.type->primitive == PrimitiveKind::Record
|
|
812
|
+
} else if (IsObject(value) && (type->ref.type->primitive == PrimitiveKind::Record ||
|
|
813
|
+
type->ref.type->primitive == PrimitiveKind::Union)) {
|
|
772
814
|
Napi::Object obj = value.As<Napi::Object>();
|
|
773
815
|
|
|
774
816
|
ptr = AllocHeap(type->ref.type->size, 16);
|
|
@@ -784,7 +826,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
784
826
|
|
|
785
827
|
out_reg->a0 = (uint64_t)ptr;
|
|
786
828
|
} break;
|
|
787
|
-
case PrimitiveKind::Record:
|
|
829
|
+
case PrimitiveKind::Record:
|
|
830
|
+
case PrimitiveKind::Union: {
|
|
788
831
|
if (RG_UNLIKELY(!IsObject(value))) {
|
|
789
832
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
790
833
|
return;
|
|
@@ -796,10 +839,28 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
796
839
|
if (!PushObject(obj, type, return_ptr))
|
|
797
840
|
return;
|
|
798
841
|
out_reg->a0 = (uint64_t)return_ptr;
|
|
799
|
-
} else if (proto->ret.vec_count) { // HFA
|
|
800
|
-
PushObject(obj, type, (uint8_t *)&out_reg->fa0, 8);
|
|
801
842
|
} else {
|
|
802
|
-
|
|
843
|
+
uint64_t regs[2] = { 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull };
|
|
844
|
+
{
|
|
845
|
+
uint8_t buf[16] = {};
|
|
846
|
+
if (!PushObject(obj, type, buf))
|
|
847
|
+
return;
|
|
848
|
+
ExpandPair(buf, proto->ret.reg_size[0], proto->ret.reg_size[1], regs);
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
if (proto->ret.gpr_first && !proto->ret.vec_count) {
|
|
852
|
+
out_reg->a0 = regs[0];
|
|
853
|
+
out_reg->a1 = regs[1];
|
|
854
|
+
} else if (proto->ret.gpr_first) {
|
|
855
|
+
out_reg->a0 = regs[0];
|
|
856
|
+
out_reg->fa0 = *(double *)®s[1];
|
|
857
|
+
} else if (proto->ret.vec_count == 2) {
|
|
858
|
+
out_reg->fa0 = *(double *)®s[0];
|
|
859
|
+
out_reg->fa1 = *(double *)®s[1];
|
|
860
|
+
} else {
|
|
861
|
+
out_reg->fa0 = *(double *)®s[0];
|
|
862
|
+
out_reg->a0 = regs[1];
|
|
863
|
+
}
|
|
803
864
|
}
|
|
804
865
|
} break;
|
|
805
866
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
@@ -132,6 +132,20 @@ static Size ClassifyType(const TypeInfo *type, Size offset, Span<RegisterClass>
|
|
|
132
132
|
|
|
133
133
|
return (offset + 7) / 8;
|
|
134
134
|
} break;
|
|
135
|
+
case PrimitiveKind::Union: {
|
|
136
|
+
if (type->size > 64) {
|
|
137
|
+
classes[0] = MergeClasses(classes[0], RegisterClass::Memory);
|
|
138
|
+
return 1;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
for (const RecordMember &member: type->members) {
|
|
142
|
+
Size start = offset / 8;
|
|
143
|
+
ClassifyType(member.type, offset % 8, classes.Take(start, classes.len - start));
|
|
144
|
+
}
|
|
145
|
+
offset += type->size;
|
|
146
|
+
|
|
147
|
+
return (offset + 7) / 8;
|
|
148
|
+
} break;
|
|
135
149
|
case PrimitiveKind::Array: {
|
|
136
150
|
if (type->size > 64) {
|
|
137
151
|
classes[0] = MergeClasses(classes[0], RegisterClass::Memory);
|
|
@@ -310,7 +324,8 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
310
324
|
|
|
311
325
|
*(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
|
|
312
326
|
} break;
|
|
313
|
-
case PrimitiveKind::Record:
|
|
327
|
+
case PrimitiveKind::Record:
|
|
328
|
+
case PrimitiveKind::Union: {
|
|
314
329
|
if (RG_UNLIKELY(!IsObject(value))) {
|
|
315
330
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
316
331
|
return false;
|
|
@@ -324,21 +339,20 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
324
339
|
uint64_t buf[2] = {};
|
|
325
340
|
if (!PushObject(obj, param.type, (uint8_t *)buf))
|
|
326
341
|
return false;
|
|
327
|
-
uint64_t *ptr = buf;
|
|
328
342
|
|
|
329
343
|
if (param.gpr_first) {
|
|
330
|
-
*(gpr_ptr++) =
|
|
344
|
+
*(gpr_ptr++) = buf[0];
|
|
331
345
|
if (param.gpr_count == 2) {
|
|
332
|
-
*(gpr_ptr++) =
|
|
346
|
+
*(gpr_ptr++) = buf[1];
|
|
333
347
|
} else if (param.xmm_count == 1) {
|
|
334
|
-
*(xmm_ptr++) =
|
|
348
|
+
*(xmm_ptr++) = buf[1];
|
|
335
349
|
}
|
|
336
350
|
} else {
|
|
337
|
-
*(xmm_ptr++) =
|
|
351
|
+
*(xmm_ptr++) = buf[0];
|
|
338
352
|
if (param.xmm_count == 2) {
|
|
339
|
-
*(xmm_ptr++) =
|
|
353
|
+
*(xmm_ptr++) = buf[1];
|
|
340
354
|
} else if (param.gpr_count == 1) {
|
|
341
|
-
*(gpr_ptr++) =
|
|
355
|
+
*(gpr_ptr++) = buf[1];
|
|
342
356
|
}
|
|
343
357
|
}
|
|
344
358
|
} else if (param.use_memory) {
|
|
@@ -434,7 +448,8 @@ void CallData::Execute(const FunctionInfo *func)
|
|
|
434
448
|
case PrimitiveKind::String16:
|
|
435
449
|
case PrimitiveKind::Pointer:
|
|
436
450
|
case PrimitiveKind::Callback: { result.u64 = PERFORM_CALL(GG).rax; } break;
|
|
437
|
-
case PrimitiveKind::Record:
|
|
451
|
+
case PrimitiveKind::Record:
|
|
452
|
+
case PrimitiveKind::Union: {
|
|
438
453
|
if (func->ret.gpr_first && !func->ret.xmm_count) {
|
|
439
454
|
RaxRdxRet ret = PERFORM_CALL(GG);
|
|
440
455
|
memcpy(&result.buf, &ret, RG_SIZE(ret));
|
|
@@ -499,7 +514,8 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
499
514
|
return env.Null();
|
|
500
515
|
}
|
|
501
516
|
} break;
|
|
502
|
-
case PrimitiveKind::Record:
|
|
517
|
+
case PrimitiveKind::Record:
|
|
518
|
+
case PrimitiveKind::Union: {
|
|
503
519
|
const uint8_t *ptr = return_ptr ? (const uint8_t *)return_ptr
|
|
504
520
|
: (const uint8_t *)&result.buf;
|
|
505
521
|
|
|
@@ -683,26 +699,26 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
683
699
|
param.type->dispose(env, param.type, ptr2);
|
|
684
700
|
}
|
|
685
701
|
} break;
|
|
686
|
-
case PrimitiveKind::Record:
|
|
702
|
+
case PrimitiveKind::Record:
|
|
703
|
+
case PrimitiveKind::Union: {
|
|
687
704
|
if (param.gpr_count || param.xmm_count) {
|
|
688
705
|
RG_ASSERT(param.type->size <= 16);
|
|
689
706
|
|
|
690
707
|
uint64_t buf[2] = {};
|
|
691
|
-
uint64_t *ptr = buf;
|
|
692
708
|
|
|
693
709
|
if (param.gpr_first) {
|
|
694
|
-
|
|
710
|
+
buf[0] = *(gpr_ptr++);
|
|
695
711
|
if (param.gpr_count == 2) {
|
|
696
|
-
|
|
712
|
+
buf[1] = *(gpr_ptr++);
|
|
697
713
|
} else if (param.xmm_count == 1) {
|
|
698
|
-
|
|
714
|
+
buf[1] = *(xmm_ptr++);
|
|
699
715
|
}
|
|
700
716
|
} else {
|
|
701
|
-
|
|
717
|
+
buf[0] = *(xmm_ptr++);
|
|
702
718
|
if (param.xmm_count == 2) {
|
|
703
|
-
|
|
719
|
+
buf[1] = *(xmm_ptr++);
|
|
704
720
|
} else if (param.gpr_count == 1) {
|
|
705
|
-
|
|
721
|
+
buf[1] = *(gpr_ptr++);
|
|
706
722
|
}
|
|
707
723
|
}
|
|
708
724
|
|
|
@@ -816,7 +832,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
816
832
|
|
|
817
833
|
if (CheckValueTag(instance, value, type->ref.marker)) {
|
|
818
834
|
ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
819
|
-
} else if (IsObject(value) && type->ref.type->primitive == PrimitiveKind::Record
|
|
835
|
+
} else if (IsObject(value) && (type->ref.type->primitive == PrimitiveKind::Record ||
|
|
836
|
+
type->ref.type->primitive == PrimitiveKind::Union)) {
|
|
820
837
|
Napi::Object obj = value.As<Napi::Object>();
|
|
821
838
|
|
|
822
839
|
ptr = AllocHeap(type->ref.type->size, 16);
|
|
@@ -832,7 +849,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
832
849
|
|
|
833
850
|
out_reg->rax = (uint64_t)ptr;
|
|
834
851
|
} break;
|
|
835
|
-
case PrimitiveKind::Record:
|
|
852
|
+
case PrimitiveKind::Record:
|
|
853
|
+
case PrimitiveKind::Union: {
|
|
836
854
|
if (RG_UNLIKELY(!IsObject(value))) {
|
|
837
855
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
838
856
|
return;
|
|
@@ -143,7 +143,8 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
143
143
|
|
|
144
144
|
*(void **)(args_ptr++) = ptr;
|
|
145
145
|
} break;
|
|
146
|
-
case PrimitiveKind::Record:
|
|
146
|
+
case PrimitiveKind::Record:
|
|
147
|
+
case PrimitiveKind::Union: {
|
|
147
148
|
if (RG_UNLIKELY(!IsObject(value))) {
|
|
148
149
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
149
150
|
return false;
|
|
@@ -261,6 +262,7 @@ void CallData::Execute(const FunctionInfo *func)
|
|
|
261
262
|
case PrimitiveKind::String16:
|
|
262
263
|
case PrimitiveKind::Pointer:
|
|
263
264
|
case PrimitiveKind::Record:
|
|
265
|
+
case PrimitiveKind::Union:
|
|
264
266
|
case PrimitiveKind::Callback: { result.u64 = PERFORM_CALL(G); } break;
|
|
265
267
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
266
268
|
case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
|
|
@@ -312,7 +314,8 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
312
314
|
return env.Null();
|
|
313
315
|
}
|
|
314
316
|
} break;
|
|
315
|
-
case PrimitiveKind::Record:
|
|
317
|
+
case PrimitiveKind::Record:
|
|
318
|
+
case PrimitiveKind::Union: {
|
|
316
319
|
const uint8_t *ptr = return_ptr ? (const uint8_t *)return_ptr
|
|
317
320
|
: (const uint8_t *)&result.buf;
|
|
318
321
|
|
|
@@ -529,7 +532,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
529
532
|
param.type->dispose(env, param.type, ptr2);
|
|
530
533
|
}
|
|
531
534
|
} break;
|
|
532
|
-
case PrimitiveKind::Record:
|
|
535
|
+
case PrimitiveKind::Record:
|
|
536
|
+
case PrimitiveKind::Union: {
|
|
533
537
|
uint8_t *ptr;
|
|
534
538
|
if (param.regular) {
|
|
535
539
|
ptr = (uint8_t *)(j < 4 ? gpr_ptr + j : args_ptr);
|
|
@@ -641,7 +645,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
641
645
|
|
|
642
646
|
if (CheckValueTag(instance, value, type->ref.marker)) {
|
|
643
647
|
ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
644
|
-
} else if (IsObject(value) && type->ref.type->primitive == PrimitiveKind::Record
|
|
648
|
+
} else if (IsObject(value) && (type->ref.type->primitive == PrimitiveKind::Record ||
|
|
649
|
+
type->ref.type->primitive == PrimitiveKind::Union)) {
|
|
645
650
|
Napi::Object obj = value.As<Napi::Object>();
|
|
646
651
|
|
|
647
652
|
ptr = AllocHeap(type->ref.type->size, 16);
|
|
@@ -657,7 +662,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
657
662
|
|
|
658
663
|
out_reg->rax = (uint64_t)ptr;
|
|
659
664
|
} break;
|
|
660
|
-
case PrimitiveKind::Record:
|
|
665
|
+
case PrimitiveKind::Record:
|
|
666
|
+
case PrimitiveKind::Union: {
|
|
661
667
|
if (RG_UNLIKELY(!IsObject(value))) {
|
|
662
668
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
663
669
|
return;
|
package/src/koffi/src/abi_x86.cc
CHANGED
|
@@ -61,7 +61,8 @@ bool AnalyseFunction(Napi::Env env, InstanceData *instance, FunctionInfo *func)
|
|
|
61
61
|
(func->convention == CallConvention::Thiscall) ? 1 : 0;
|
|
62
62
|
func->fast = fast;
|
|
63
63
|
|
|
64
|
-
if (func->ret.type->primitive != PrimitiveKind::Record
|
|
64
|
+
if (func->ret.type->primitive != PrimitiveKind::Record &&
|
|
65
|
+
func->ret.type->primitive != PrimitiveKind::Union) {
|
|
65
66
|
func->ret.trivial = true;
|
|
66
67
|
#if defined(_WIN32) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
|
|
67
68
|
} else {
|
|
@@ -224,7 +225,8 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
224
225
|
|
|
225
226
|
*(void **)((param.fast ? fast_ptr : args_ptr)++) = ptr;
|
|
226
227
|
} break;
|
|
227
|
-
case PrimitiveKind::Record:
|
|
228
|
+
case PrimitiveKind::Record:
|
|
229
|
+
case PrimitiveKind::Union: {
|
|
228
230
|
if (RG_UNLIKELY(!IsObject(value))) {
|
|
229
231
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
230
232
|
return false;
|
|
@@ -346,7 +348,8 @@ void CallData::Execute(const FunctionInfo *func)
|
|
|
346
348
|
case PrimitiveKind::String:
|
|
347
349
|
case PrimitiveKind::String16:
|
|
348
350
|
case PrimitiveKind::Pointer:
|
|
349
|
-
case PrimitiveKind::Record:
|
|
351
|
+
case PrimitiveKind::Record:
|
|
352
|
+
case PrimitiveKind::Union:
|
|
350
353
|
case PrimitiveKind::Callback: { result.u64 = PERFORM_CALL(G); } break;
|
|
351
354
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
352
355
|
case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
|
|
@@ -398,7 +401,8 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
398
401
|
return env.Null();
|
|
399
402
|
}
|
|
400
403
|
} break;
|
|
401
|
-
case PrimitiveKind::Record:
|
|
404
|
+
case PrimitiveKind::Record:
|
|
405
|
+
case PrimitiveKind::Union: {
|
|
402
406
|
const uint8_t *ptr = return_ptr ? (const uint8_t *)return_ptr
|
|
403
407
|
: (const uint8_t *)&result.buf;
|
|
404
408
|
|
|
@@ -617,7 +621,8 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRe
|
|
|
617
621
|
param.type->dispose(env, param.type, ptr2);
|
|
618
622
|
}
|
|
619
623
|
} break;
|
|
620
|
-
case PrimitiveKind::Record:
|
|
624
|
+
case PrimitiveKind::Record:
|
|
625
|
+
case PrimitiveKind::Union: {
|
|
621
626
|
RG_ASSERT(!param.fast);
|
|
622
627
|
|
|
623
628
|
uint8_t *ptr = (uint8_t *)args_ptr;
|
|
@@ -750,7 +755,8 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRe
|
|
|
750
755
|
|
|
751
756
|
if (CheckValueTag(instance, value, type->ref.marker)) {
|
|
752
757
|
ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
753
|
-
} else if (IsObject(value) && type->ref.type->primitive == PrimitiveKind::Record
|
|
758
|
+
} else if (IsObject(value) && (type->ref.type->primitive == PrimitiveKind::Record ||
|
|
759
|
+
type->ref.type->primitive == PrimitiveKind::Union)) {
|
|
754
760
|
Napi::Object obj = value.As<Napi::Object>();
|
|
755
761
|
|
|
756
762
|
ptr = AllocHeap(type->ref.type->size, 16);
|
|
@@ -766,7 +772,8 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRe
|
|
|
766
772
|
|
|
767
773
|
out_reg->eax = (uint32_t)ptr;
|
|
768
774
|
} break;
|
|
769
|
-
case PrimitiveKind::Record:
|
|
775
|
+
case PrimitiveKind::Record:
|
|
776
|
+
case PrimitiveKind::Union: {
|
|
770
777
|
if (RG_UNLIKELY(!IsObject(value))) {
|
|
771
778
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
772
779
|
return;
|