koffi 2.3.4 → 2.3.6-beta.1
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 +25 -2
- package/doc/changelog.md +4 -0
- package/doc/index.rst +1 -2
- package/doc/types.md +3 -3
- package/package.json +5 -5
- package/src/cnoke/cnoke.js +40 -834
- package/src/cnoke/package.json +1 -0
- package/src/cnoke/src/builder.js +447 -0
- package/src/cnoke/src/index.js +20 -0
- package/src/cnoke/src/tools.js +401 -0
- package/src/core/libcc/libcc.cc +2 -2
- package/src/koffi/build/2.3.6-beta.1/koffi_darwin_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_darwin_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_freebsd_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_freebsd_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_freebsd_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_linux_arm32hf/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_linux_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_linux_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_linux_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_openbsd_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_openbsd_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_arm64/koffi.exp +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_arm64/koffi.lib +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_arm64/koffi.pdb +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_ia32/koffi.exp +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_ia32/koffi.lib +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_ia32/koffi.pdb +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_x64/koffi.exp +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_x64/koffi.lib +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_x64/koffi.pdb +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/index.js +23 -4
- 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
|
@@ -25,6 +25,11 @@
|
|
|
25
25
|
|
|
26
26
|
namespace RG {
|
|
27
27
|
|
|
28
|
+
struct HfaInfo {
|
|
29
|
+
int count;
|
|
30
|
+
bool float32;
|
|
31
|
+
};
|
|
32
|
+
|
|
28
33
|
struct X0X1Ret {
|
|
29
34
|
uint64_t x0;
|
|
30
35
|
uint64_t x1;
|
|
@@ -59,15 +64,61 @@ extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_va
|
|
|
59
64
|
|
|
60
65
|
#include "abi_trampolines.inc"
|
|
61
66
|
|
|
62
|
-
static
|
|
67
|
+
static HfaInfo IsHFA(const TypeInfo *type)
|
|
68
|
+
{
|
|
69
|
+
bool float32 = false;
|
|
70
|
+
bool float64 = false;
|
|
71
|
+
int count = 0;
|
|
72
|
+
|
|
73
|
+
count = AnalyseFlat(type, [&](const TypeInfo *type, int, int) {
|
|
74
|
+
if (type->primitive == PrimitiveKind::Float32) {
|
|
75
|
+
float32 = true;
|
|
76
|
+
} else if (type->primitive == PrimitiveKind::Float64) {
|
|
77
|
+
float64 = true;
|
|
78
|
+
} else {
|
|
79
|
+
float32 = true;
|
|
80
|
+
float64 = true;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
HfaInfo info = {};
|
|
85
|
+
|
|
86
|
+
if (count < 1 || count > 4)
|
|
87
|
+
return info;
|
|
88
|
+
if (float32 && float64)
|
|
89
|
+
return info;
|
|
90
|
+
|
|
91
|
+
info.count = count;
|
|
92
|
+
info.float32 = float32;
|
|
93
|
+
|
|
94
|
+
return info;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
static inline void ExpandFloats(uint8_t *ptr, Size len, Size bytes)
|
|
98
|
+
{
|
|
99
|
+
for (Size i = len - 1; i >= 0; i--) {
|
|
100
|
+
const uint8_t *src = ptr + i * bytes;
|
|
101
|
+
uint8_t *dest = ptr + i * 8;
|
|
102
|
+
|
|
103
|
+
memmove(dest, src, bytes);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
static inline void CompactFloats(uint8_t *ptr, Size len, Size bytes)
|
|
63
108
|
{
|
|
64
|
-
|
|
109
|
+
for (Size i = 0; i < len; i++) {
|
|
110
|
+
const uint8_t *src = ptr + i * 8;
|
|
111
|
+
uint8_t *dest = ptr + i * bytes;
|
|
112
|
+
|
|
113
|
+
memmove(dest, src, bytes);
|
|
114
|
+
}
|
|
65
115
|
}
|
|
66
116
|
|
|
67
117
|
bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
68
118
|
{
|
|
69
|
-
if (
|
|
70
|
-
func->ret.vec_count = (int8_t)hfa;
|
|
119
|
+
if (HfaInfo hfa = IsHFA(func->ret.type); hfa.count) {
|
|
120
|
+
func->ret.vec_count = (int8_t)hfa.count;
|
|
121
|
+
func->ret.vec_bytes = hfa.float32 ? 4 : 8;
|
|
71
122
|
} else if (func->ret.type->size <= 16) {
|
|
72
123
|
func->ret.gpr_count = (int8_t)((func->ret.type->size + 7) / 8);
|
|
73
124
|
} else {
|
|
@@ -115,8 +166,9 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
|
115
166
|
gpr_avail--;
|
|
116
167
|
}
|
|
117
168
|
} break;
|
|
118
|
-
case PrimitiveKind::Record:
|
|
119
|
-
|
|
169
|
+
case PrimitiveKind::Record:
|
|
170
|
+
case PrimitiveKind::Union: {
|
|
171
|
+
HfaInfo hfa = IsHFA(param.type);
|
|
120
172
|
|
|
121
173
|
#ifdef _M_ARM64EC
|
|
122
174
|
if (func->variadic) {
|
|
@@ -137,7 +189,7 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
|
137
189
|
|
|
138
190
|
#if defined(_WIN32)
|
|
139
191
|
if (param.variadic) {
|
|
140
|
-
hfa = 0;
|
|
192
|
+
hfa.count = 0;
|
|
141
193
|
}
|
|
142
194
|
#elif defined(__APPLE__)
|
|
143
195
|
if (param.variadic) {
|
|
@@ -146,10 +198,11 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
|
146
198
|
}
|
|
147
199
|
#endif
|
|
148
200
|
|
|
149
|
-
if (hfa) {
|
|
150
|
-
if (hfa <= vec_avail) {
|
|
151
|
-
param.vec_count = (int8_t)hfa;
|
|
152
|
-
|
|
201
|
+
if (hfa.count) {
|
|
202
|
+
if (hfa.count <= vec_avail) {
|
|
203
|
+
param.vec_count = (int8_t)hfa.count;
|
|
204
|
+
param.vec_bytes = hfa.float32 ? 4 : 8;
|
|
205
|
+
vec_avail -= hfa.count;
|
|
153
206
|
} else {
|
|
154
207
|
vec_avail = 0;
|
|
155
208
|
}
|
|
@@ -364,7 +417,8 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
364
417
|
#endif
|
|
365
418
|
*(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
|
|
366
419
|
} break;
|
|
367
|
-
case PrimitiveKind::Record:
|
|
420
|
+
case PrimitiveKind::Record:
|
|
421
|
+
case PrimitiveKind::Union: {
|
|
368
422
|
if (RG_UNLIKELY(!IsObject(value))) {
|
|
369
423
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
370
424
|
return false;
|
|
@@ -373,8 +427,12 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
373
427
|
Napi::Object obj = value.As<Napi::Object>();
|
|
374
428
|
|
|
375
429
|
if (param.vec_count) { // HFA
|
|
376
|
-
|
|
430
|
+
uint8_t *ptr = (uint8_t *)vec_ptr;
|
|
431
|
+
|
|
432
|
+
if (!PushObject(obj, param.type, ptr))
|
|
377
433
|
return false;
|
|
434
|
+
ExpandFloats(ptr, param.vec_count, param.vec_bytes);
|
|
435
|
+
|
|
378
436
|
vec_ptr += param.vec_count;
|
|
379
437
|
} else if (!param.use_memory) {
|
|
380
438
|
if (param.gpr_count) {
|
|
@@ -544,7 +602,8 @@ void CallData::Execute(const FunctionInfo *func)
|
|
|
544
602
|
case PrimitiveKind::String16:
|
|
545
603
|
case PrimitiveKind::Pointer:
|
|
546
604
|
case PrimitiveKind::Callback: { result.u64 = PERFORM_CALL(GG).x0; } break;
|
|
547
|
-
case PrimitiveKind::Record:
|
|
605
|
+
case PrimitiveKind::Record:
|
|
606
|
+
case PrimitiveKind::Union: {
|
|
548
607
|
if (func->ret.gpr_count) {
|
|
549
608
|
X0X1Ret ret = PERFORM_CALL(GG);
|
|
550
609
|
memcpy(&result.buf, &ret, RG_SIZE(ret));
|
|
@@ -605,9 +664,14 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
605
664
|
return env.Null();
|
|
606
665
|
}
|
|
607
666
|
} break;
|
|
608
|
-
case PrimitiveKind::Record:
|
|
667
|
+
case PrimitiveKind::Record:
|
|
668
|
+
case PrimitiveKind::Union: {
|
|
609
669
|
if (func->ret.vec_count) { // HFA
|
|
610
|
-
|
|
670
|
+
uint8_t *ptr = (uint8_t *)&result.buf;
|
|
671
|
+
|
|
672
|
+
CompactFloats(ptr, func->ret.vec_count, func->ret.vec_bytes);
|
|
673
|
+
|
|
674
|
+
Napi::Object obj = DecodeObject(env, ptr, func->ret.type);
|
|
611
675
|
return obj;
|
|
612
676
|
} else {
|
|
613
677
|
const uint8_t *ptr = return_ptr ? (const uint8_t *)return_ptr
|
|
@@ -973,9 +1037,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
973
1037
|
param.type->dispose(env, param.type, ptr2);
|
|
974
1038
|
}
|
|
975
1039
|
} break;
|
|
976
|
-
case PrimitiveKind::Record:
|
|
1040
|
+
case PrimitiveKind::Record:
|
|
1041
|
+
case PrimitiveKind::Union: {
|
|
977
1042
|
if (param.vec_count) { // HFA
|
|
978
|
-
|
|
1043
|
+
uint8_t *ptr = (uint8_t *)vec_ptr;
|
|
1044
|
+
|
|
1045
|
+
CompactFloats(ptr, param.vec_count, param.vec_bytes);
|
|
1046
|
+
|
|
1047
|
+
Napi::Object obj = DecodeObject(env, ptr, param.type);
|
|
979
1048
|
arguments.Append(obj);
|
|
980
1049
|
|
|
981
1050
|
vec_ptr += param.vec_count;
|
|
@@ -1133,7 +1202,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
1133
1202
|
|
|
1134
1203
|
if (CheckValueTag(instance, value, type->ref.marker)) {
|
|
1135
1204
|
ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
1136
|
-
} else if (IsObject(value) && type->ref.type->primitive == PrimitiveKind::Record
|
|
1205
|
+
} else if (IsObject(value) && (type->ref.type->primitive == PrimitiveKind::Record ||
|
|
1206
|
+
type->ref.type->primitive == PrimitiveKind::Union)) {
|
|
1137
1207
|
Napi::Object obj = value.As<Napi::Object>();
|
|
1138
1208
|
|
|
1139
1209
|
ptr = AllocHeap(type->ref.type->size, 16);
|
|
@@ -1149,7 +1219,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
1149
1219
|
|
|
1150
1220
|
out_reg->x0 = (uint64_t)ptr;
|
|
1151
1221
|
} break;
|
|
1152
|
-
case PrimitiveKind::Record:
|
|
1222
|
+
case PrimitiveKind::Record:
|
|
1223
|
+
case PrimitiveKind::Union: {
|
|
1153
1224
|
if (RG_UNLIKELY(!IsObject(value))) {
|
|
1154
1225
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
1155
1226
|
return;
|
|
@@ -1162,7 +1233,10 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
1162
1233
|
return;
|
|
1163
1234
|
out_reg->x0 = (uint64_t)return_ptr;
|
|
1164
1235
|
} else if (proto->ret.vec_count) { // HFA
|
|
1165
|
-
|
|
1236
|
+
uint8_t *ptr = (uint8_t *)&out_reg->d0;
|
|
1237
|
+
|
|
1238
|
+
ExpandFloats(ptr, proto->ret.vec_count, proto->ret.vec_bytes);
|
|
1239
|
+
PushObject(obj, type, ptr);
|
|
1166
1240
|
} else {
|
|
1167
1241
|
PushObject(obj, type, (uint8_t *)&out_reg->x0);
|
|
1168
1242
|
}
|
|
@@ -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;
|