koffi 2.16.1 → 3.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -2
- package/README.md +8 -8
- package/build/koffi/darwin_arm64/koffi.node +0 -0
- package/build/koffi/darwin_x64/koffi.node +0 -0
- package/build/koffi/freebsd_arm64/koffi.node +0 -0
- package/build/koffi/freebsd_ia32/koffi.node +0 -0
- package/build/koffi/freebsd_x64/koffi.node +0 -0
- package/build/koffi/linux_arm64/koffi.node +0 -0
- package/build/koffi/linux_ia32/koffi.node +0 -0
- package/build/koffi/linux_x64/koffi.node +0 -0
- package/build/koffi/musl_arm64/koffi.node +0 -0
- package/build/koffi/musl_x64/koffi.node +0 -0
- package/build/koffi/openbsd_ia32/koffi.node +0 -0
- package/build/koffi/openbsd_x64/koffi.node +0 -0
- package/build/koffi/win32_ia32/koffi.node +0 -0
- package/build/koffi/win32_x64/koffi.node +0 -0
- package/doc/benchmarks.md +33 -33
- package/doc/benchmarks.xlsx +0 -0
- package/doc/contribute.md +37 -25
- package/doc/index.md +8 -8
- package/doc/variables.md +1 -1
- package/index.d.ts +11 -9
- package/index.js +1 -634
- package/indirect.js +1 -533
- package/lib/native/base/base.cc +63 -85
- package/lib/native/base/base.hh +178 -151
- package/package.json +3 -4
- package/src/build.js +1178 -0
- package/src/koffi/CMakeLists.txt +97 -34
- package/src/koffi/index.js +359 -0
- package/src/koffi/indirect.js +216 -0
- package/src/koffi/src/{abi_arm32.cc → abi/arm32.cc} +279 -275
- package/src/koffi/src/{abi_arm32_asm.S → abi/arm32_asm.S} +2 -5
- package/src/koffi/src/abi/arm64.cc +1511 -0
- package/src/koffi/src/{abi_arm64_asm.S → abi/arm64_asm.S} +44 -23
- package/src/koffi/src/{abi_arm64_asm.asm → abi/arm64_asm.asm} +32 -25
- package/src/koffi/src/{abi_loong64_asm.S → abi/loong64_asm.S} +1 -5
- package/src/koffi/src/{abi_riscv64.cc → abi/riscv64.cc} +279 -273
- package/src/koffi/src/{abi_riscv64_asm.S → abi/riscv64_asm.S} +1 -4
- package/src/koffi/src/abi/x64sysv.cc +1456 -0
- package/src/koffi/src/{abi_x64_sysv_asm.S → abi/x64sysv_asm.S} +30 -33
- package/src/koffi/src/abi/x64win.cc +1121 -0
- package/src/koffi/src/{abi_x64_win_asm.S → abi/x64win_asm.S} +8 -12
- package/src/koffi/src/{abi_x64_win_asm.asm → abi/x64win_asm.asm} +11 -14
- package/src/koffi/src/abi/x86.cc +1233 -0
- package/src/koffi/src/{abi_x86_asm.S → abi/x86_asm.S} +49 -25
- package/src/koffi/src/{abi_x86_asm.asm → abi/x86_asm.asm} +11 -14
- package/src/koffi/src/call.cc +458 -598
- package/src/koffi/src/call.hh +61 -82
- package/src/koffi/src/ffi.cc +595 -309
- package/src/koffi/src/ffi.hh +103 -89
- package/src/koffi/src/parser.cc +0 -4
- package/src/koffi/src/primitives.inc +39 -0
- package/src/koffi/{tools/write_trampolines.js → src/trampolines.js} +1 -1
- package/src/koffi/src/util.cc +503 -446
- package/src/koffi/src/util.hh +269 -57
- package/src/koffi/src/uv.cc +2 -2
- package/src/koffi/src/uv.def +3 -0
- package/src/koffi/src/win32.hh +30 -1
- package/vendor/node-addon-api/napi-inl.h +4 -0
- package/vendor/node-addon-api/napi.h +1 -0
- package/build/koffi/linux_armhf/koffi.node +0 -0
- package/build/koffi/linux_loong64/koffi.node +0 -0
- package/build/koffi/linux_riscv64d/koffi.node +0 -0
- package/build/koffi/win32_arm64/koffi.exp +0 -0
- package/build/koffi/win32_arm64/koffi.lib +0 -0
- package/build/koffi/win32_arm64/koffi.node +0 -0
- package/doc/platforms.md +0 -36
- package/src/cnoke/LICENSE.txt +0 -22
- package/src/cnoke/README.md +0 -99
- package/src/cnoke/assets/FindCNoke.cmake +0 -127
- package/src/cnoke/assets/toolchains.json +0 -126
- package/src/cnoke/assets/win_delay_hook.c +0 -36
- package/src/cnoke/cnoke.js +0 -170
- package/src/cnoke/package.json +0 -24
- package/src/cnoke/src/builder.js +0 -511
- package/src/cnoke/src/index.js +0 -10
- package/src/cnoke/src/tools.js +0 -407
- package/src/koffi/src/abi_arm64.cc +0 -1295
- package/src/koffi/src/abi_x64_sysv.cc +0 -939
- package/src/koffi/src/abi_x64_win.cc +0 -715
- package/src/koffi/src/abi_x86.cc +0 -860
- package/src/koffi/src/init.js +0 -105
- /package/src/koffi/src/{abi_loong64.cc → abi/loong64.cc} +0 -0
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
#if __riscv_xlen == 64 || defined(__loongarch64)
|
|
5
5
|
|
|
6
6
|
#include "lib/native/base/base.hh"
|
|
7
|
-
#include "ffi.hh"
|
|
8
|
-
#include "call.hh"
|
|
9
|
-
#include "util.hh"
|
|
7
|
+
#include "../ffi.hh"
|
|
8
|
+
#include "../call.hh"
|
|
9
|
+
#include "../util.hh"
|
|
10
10
|
|
|
11
11
|
#include <napi.h>
|
|
12
12
|
|
|
@@ -48,10 +48,11 @@ extern "C" Fa0A0Ret ForwardCallXDG(const void *func, uint8_t *sp, uint8_t **out_
|
|
|
48
48
|
extern "C" A0Fa0Ret ForwardCallXGD(const void *func, uint8_t *sp, uint8_t **out_old_sp);
|
|
49
49
|
extern "C" Fa0Fa1Ret ForwardCallXDD(const void *func, uint8_t *sp, uint8_t **out_old_sp);
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
enum class AbiOpcode : int8_t {
|
|
52
|
+
#define PRIMITIVE(Name) Name,
|
|
53
|
+
#include "../primitives.inc"
|
|
54
|
+
End
|
|
55
|
+
};
|
|
55
56
|
|
|
56
57
|
static inline void ExpandPair(const uint8_t raw[16], int size1, int size2, uint64_t out_regs[2])
|
|
57
58
|
{
|
|
@@ -65,7 +66,8 @@ static inline void CompactPair(const uint64_t regs[2], int size1, int size2, uin
|
|
|
65
66
|
memcpy(out_raw + size1, regs + 1, size2);
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
|
|
69
|
+
template <typename T>
|
|
70
|
+
void AnalyseParameter(T *param, int gpr_avail, int vec_avail)
|
|
69
71
|
{
|
|
70
72
|
// Too big, pass pointer to struct
|
|
71
73
|
if (param->type->size > 16) {
|
|
@@ -139,8 +141,11 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
|
139
141
|
|
|
140
142
|
gpr_avail = std::max(0, gpr_avail - param.gpr_count);
|
|
141
143
|
vec_avail = std::max(0, vec_avail - param.vec_count);
|
|
144
|
+
|
|
145
|
+
func->instructions.Append((AbiOpcode)param.type->primitive);
|
|
142
146
|
}
|
|
143
147
|
|
|
148
|
+
func->instructions.Append(AbiOpcode::End);
|
|
144
149
|
func->args_size = 8 * func->parameters.len;
|
|
145
150
|
func->forward_fp = (vec_avail < 8);
|
|
146
151
|
|
|
@@ -149,213 +154,261 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
|
149
154
|
|
|
150
155
|
bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
151
156
|
{
|
|
152
|
-
uint64_t *
|
|
153
|
-
uint64_t *gpr_ptr =
|
|
154
|
-
uint64_t *
|
|
157
|
+
uint64_t *vec_ptr = AllocStack<uint64_t>(16 * 8 + func->args_size);
|
|
158
|
+
uint64_t *gpr_ptr = vec_ptr + 8;
|
|
159
|
+
uint64_t *args_ptr = vec_ptr + 16;
|
|
155
160
|
|
|
156
|
-
|
|
157
|
-
if (!AllocStack(func->args_size, 16, &args_ptr)) [[unlikely]]
|
|
158
|
-
return false;
|
|
159
|
-
if (!AllocStack(8 * 8, 8, &gpr_ptr)) [[unlikely]]
|
|
160
|
-
return false;
|
|
161
|
-
if (!AllocStack(8 * 8, 8, &vec_ptr)) [[unlikely]]
|
|
161
|
+
if (!vec_ptr) [[unlikely]]
|
|
162
162
|
return false;
|
|
163
163
|
if (func->ret.use_memory) {
|
|
164
|
-
return_ptr = AllocHeap(func->ret.type->size
|
|
164
|
+
return_ptr = AllocHeap(func->ret.type->size);
|
|
165
165
|
*(uint8_t **)(gpr_ptr++) = return_ptr;
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
Size i = -1;
|
|
169
|
+
|
|
170
|
+
static const void *const DispatchTable[] = {
|
|
171
|
+
#define PRIMITIVE(Name) && Name,
|
|
172
|
+
#include "../primitives.inc"
|
|
173
|
+
&& End
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
#define LOOP
|
|
177
|
+
#define CASE(Primitive) \
|
|
178
|
+
do { \
|
|
179
|
+
AbiOpcode next = func->instructions[++i]; \
|
|
180
|
+
goto *DispatchTable[(int)next]; \
|
|
181
|
+
} while (false); \
|
|
182
|
+
Primitive:
|
|
183
|
+
#define OR(Primitive) \
|
|
184
|
+
Primitive:
|
|
185
|
+
|
|
168
186
|
#define PUSH_INTEGER(CType) \
|
|
169
187
|
do { \
|
|
170
|
-
|
|
188
|
+
const ParameterInfo ¶m = func->parameters[i]; \
|
|
189
|
+
Napi::Value value = info[param.offset]; \
|
|
190
|
+
\
|
|
191
|
+
CType v; \
|
|
192
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
171
193
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
172
194
|
return false; \
|
|
173
195
|
} \
|
|
174
196
|
\
|
|
175
|
-
CType v = GetNumber<CType>(value); \
|
|
176
197
|
*((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint64_t)v; \
|
|
177
198
|
} while (false)
|
|
178
199
|
#define PUSH_INTEGER_SWAP(CType) \
|
|
179
200
|
do { \
|
|
180
|
-
|
|
201
|
+
const ParameterInfo ¶m = func->parameters[i]; \
|
|
202
|
+
Napi::Value value = info[param.offset]; \
|
|
203
|
+
\
|
|
204
|
+
CType v; \
|
|
205
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
181
206
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
182
207
|
return false; \
|
|
183
208
|
} \
|
|
184
209
|
\
|
|
185
|
-
CType v = GetNumber<CType>(value); \
|
|
186
210
|
*((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint64_t)ReverseBytes(v); \
|
|
187
211
|
} while (false)
|
|
188
212
|
|
|
189
213
|
// Push arguments
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
K_ASSERT(param.directions >= 1 && param.directions <= 3);
|
|
214
|
+
LOOP {
|
|
215
|
+
CASE(Void) { K_UNREACHABLE(); };
|
|
193
216
|
|
|
194
|
-
|
|
217
|
+
CASE(Bool) {
|
|
218
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
219
|
+
Napi::Value value = info[param.offset];
|
|
195
220
|
|
|
196
|
-
|
|
197
|
-
|
|
221
|
+
bool b;
|
|
222
|
+
if (napi_get_value_bool(env, value, &b) != napi_ok) [[unlikely]] {
|
|
223
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
198
226
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
227
|
+
*((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint64_t)b;
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
CASE(Int8) { PUSH_INTEGER(int8_t); };
|
|
231
|
+
CASE(UInt8) { PUSH_INTEGER(uint8_t); };
|
|
232
|
+
CASE(Int16) { PUSH_INTEGER(int16_t); };
|
|
233
|
+
CASE(Int16S) { PUSH_INTEGER_SWAP(int16_t); };
|
|
234
|
+
CASE(UInt16) { PUSH_INTEGER(uint16_t); };
|
|
235
|
+
CASE(UInt16S) { PUSH_INTEGER_SWAP(uint16_t); };
|
|
236
|
+
CASE(Int32) { PUSH_INTEGER(int32_t); };
|
|
237
|
+
CASE(Int32S) { PUSH_INTEGER_SWAP(int32_t); };
|
|
238
|
+
CASE(UInt32) { PUSH_INTEGER(uint32_t); };
|
|
239
|
+
CASE(UInt32S) { PUSH_INTEGER_SWAP(uint32_t); };
|
|
240
|
+
CASE(Int64) { PUSH_INTEGER(int64_t); };
|
|
241
|
+
CASE(Int64S) { PUSH_INTEGER_SWAP(int64_t); };
|
|
242
|
+
CASE(UInt64) { PUSH_INTEGER(uint64_t); };
|
|
243
|
+
CASE(UInt64S) { PUSH_INTEGER_SWAP(uint64_t); };
|
|
244
|
+
|
|
245
|
+
CASE(String) {
|
|
246
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
247
|
+
Napi::Value value = info[param.offset];
|
|
204
248
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
case PrimitiveKind::Int8: { PUSH_INTEGER(int8_t); } break;
|
|
209
|
-
case PrimitiveKind::UInt8: { PUSH_INTEGER(uint8_t); } break;
|
|
210
|
-
case PrimitiveKind::Int16: { PUSH_INTEGER(int16_t); } break;
|
|
211
|
-
case PrimitiveKind::Int16S: { PUSH_INTEGER_SWAP(int16_t); } break;
|
|
212
|
-
case PrimitiveKind::UInt16: { PUSH_INTEGER(uint16_t); } break;
|
|
213
|
-
case PrimitiveKind::UInt16S: { PUSH_INTEGER_SWAP(uint16_t); } break;
|
|
214
|
-
case PrimitiveKind::Int32: { PUSH_INTEGER(int32_t); } break;
|
|
215
|
-
case PrimitiveKind::Int32S: { PUSH_INTEGER_SWAP(int32_t); } break;
|
|
216
|
-
case PrimitiveKind::UInt32: { PUSH_INTEGER(uint32_t); } break;
|
|
217
|
-
case PrimitiveKind::UInt32S: { PUSH_INTEGER_SWAP(uint32_t); } break;
|
|
218
|
-
case PrimitiveKind::Int64: { PUSH_INTEGER(int64_t); } break;
|
|
219
|
-
case PrimitiveKind::Int64S: { PUSH_INTEGER_SWAP(int64_t); } break;
|
|
220
|
-
case PrimitiveKind::UInt64: { PUSH_INTEGER(uint64_t); } break;
|
|
221
|
-
case PrimitiveKind::UInt64S: { PUSH_INTEGER_SWAP(uint64_t); } break;
|
|
222
|
-
case PrimitiveKind::String: {
|
|
223
|
-
const char *str;
|
|
224
|
-
if (!PushString(value, param.directions, &str)) [[unlikely]]
|
|
225
|
-
return false;
|
|
249
|
+
const char *str;
|
|
250
|
+
if (!PushString(value, param.directions, &str)) [[unlikely]]
|
|
251
|
+
return false;
|
|
226
252
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
return false;
|
|
253
|
+
*(const char **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str;
|
|
254
|
+
};
|
|
255
|
+
CASE(String16) {
|
|
256
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
257
|
+
Napi::Value value = info[param.offset];
|
|
233
258
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
const char32_t *str32;
|
|
238
|
-
if (!PushString32(value, param.directions, &str32)) [[unlikely]]
|
|
239
|
-
return false;
|
|
259
|
+
const char16_t *str16;
|
|
260
|
+
if (!PushString16(value, param.directions, &str16)) [[unlikely]]
|
|
261
|
+
return false;
|
|
240
262
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
return false;
|
|
263
|
+
*(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str16;
|
|
264
|
+
};
|
|
265
|
+
CASE(String32) {
|
|
266
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
267
|
+
Napi::Value value = info[param.offset];
|
|
247
268
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
case PrimitiveKind::Union: {
|
|
252
|
-
if (!IsObject(value)) [[unlikely]] {
|
|
253
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
254
|
-
return false;
|
|
255
|
-
}
|
|
269
|
+
const char32_t *str32;
|
|
270
|
+
if (!PushString32(value, param.directions, &str32)) [[unlikely]]
|
|
271
|
+
return false;
|
|
256
272
|
|
|
257
|
-
|
|
273
|
+
*(const char32_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str32;
|
|
274
|
+
};
|
|
258
275
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
uint64_t regs[2] = { 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull };
|
|
263
|
-
{
|
|
264
|
-
uint8_t buf[16] = {};
|
|
265
|
-
if (!PushObject(obj, param.type, buf))
|
|
266
|
-
return false;
|
|
267
|
-
ExpandPair(buf, param.reg_size[0], param.reg_size[1], regs);
|
|
268
|
-
}
|
|
276
|
+
CASE(Pointer) {
|
|
277
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
278
|
+
Napi::Value value = info[param.offset];
|
|
269
279
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
*(gpr_ptr++) = regs[1];
|
|
274
|
-
} else if (param.vec_count == 1) {
|
|
275
|
-
*(vec_ptr++) = regs[1];
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
args_ptr = std::max(gpr_ptr, args_ptr);
|
|
279
|
-
} else if (param.vec_count) {
|
|
280
|
-
*(vec_ptr++) = regs[0];
|
|
281
|
-
if (param.vec_count == 2) {
|
|
282
|
-
*(vec_ptr++) = regs[1];
|
|
283
|
-
} else if (param.gpr_count == 1) {
|
|
284
|
-
*(gpr_ptr++) = regs[1];
|
|
285
|
-
}
|
|
286
|
-
} else {
|
|
287
|
-
K_ASSERT(param.type->align <= 8);
|
|
280
|
+
void *ptr;
|
|
281
|
+
if (!PushPointer(value, param.type, param.directions, &ptr)) [[unlikely]]
|
|
282
|
+
return false;
|
|
288
283
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
}
|
|
292
|
-
} else {
|
|
293
|
-
uint8_t *ptr = AllocHeap(param.type->size, 16);
|
|
284
|
+
*(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
|
|
285
|
+
};
|
|
294
286
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
287
|
+
CASE(Record) OR(Union) {
|
|
288
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
289
|
+
Napi::Value value = info[param.offset];
|
|
298
290
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
291
|
+
if (!IsObject(value)) [[unlikely]] {
|
|
292
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
Napi::Object obj = value.As<Napi::Object>();
|
|
297
|
+
|
|
298
|
+
if (!param.use_memory) {
|
|
299
|
+
K_ASSERT(param.type->size <= 16);
|
|
303
300
|
|
|
304
|
-
|
|
301
|
+
uint64_t regs[2] = { 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull };
|
|
302
|
+
{
|
|
303
|
+
uint8_t buf[16] = {};
|
|
304
|
+
if (!PushObject(obj, param.type, buf))
|
|
305
305
|
return false;
|
|
306
|
-
|
|
307
|
-
} break;
|
|
308
|
-
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
309
|
-
case PrimitiveKind::Float32: {
|
|
310
|
-
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
311
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
312
|
-
return false;
|
|
306
|
+
ExpandPair(buf, param.reg_size[0], param.reg_size[1], regs);
|
|
313
307
|
}
|
|
314
308
|
|
|
315
|
-
|
|
309
|
+
if (param.gpr_first) {
|
|
310
|
+
*(gpr_ptr++) = regs[0];
|
|
311
|
+
if (param.gpr_count == 2) {
|
|
312
|
+
*(gpr_ptr++) = regs[1];
|
|
313
|
+
} else if (param.vec_count == 1) {
|
|
314
|
+
*(vec_ptr++) = regs[1];
|
|
315
|
+
}
|
|
316
316
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
*(
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
317
|
+
args_ptr = std::max(gpr_ptr, args_ptr);
|
|
318
|
+
} else if (param.vec_count) {
|
|
319
|
+
*(vec_ptr++) = regs[0];
|
|
320
|
+
if (param.vec_count == 2) {
|
|
321
|
+
*(vec_ptr++) = regs[1];
|
|
322
|
+
} else if (param.gpr_count == 1) {
|
|
323
|
+
*(gpr_ptr++) = regs[1];
|
|
324
|
+
}
|
|
323
325
|
} else {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
case PrimitiveKind::Float64: {
|
|
329
|
-
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
330
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
331
|
-
return false;
|
|
326
|
+
K_ASSERT(param.type->align <= 8);
|
|
327
|
+
|
|
328
|
+
MemCpy(args_ptr, regs, param.type->size);
|
|
329
|
+
args_ptr += (param.type->size + 7) / 8;
|
|
332
330
|
}
|
|
331
|
+
} else {
|
|
332
|
+
uint8_t *ptr = AllocHeap(param.type->size);
|
|
333
333
|
|
|
334
|
-
|
|
334
|
+
if (param.gpr_count) {
|
|
335
|
+
K_ASSERT(param.gpr_count == 1);
|
|
336
|
+
K_ASSERT(param.vec_count == 0);
|
|
335
337
|
|
|
336
|
-
|
|
337
|
-
*(double *)(vec_ptr++) = d;
|
|
338
|
-
} else if (param.gpr_count) {
|
|
339
|
-
*(double *)(gpr_ptr++) = d;
|
|
338
|
+
*(uint8_t **)(gpr_ptr++) = ptr;
|
|
340
339
|
} else {
|
|
341
|
-
*(
|
|
340
|
+
*(uint8_t **)(args_ptr++) = ptr;
|
|
342
341
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
void *ptr;
|
|
346
|
-
if (!PushCallback(value, param.type, &ptr)) [[unlikely]]
|
|
342
|
+
|
|
343
|
+
if (!PushObject(obj, param.type, ptr))
|
|
347
344
|
return false;
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
CASE(Array) { K_UNREACHABLE(); };
|
|
348
348
|
|
|
349
|
-
|
|
350
|
-
|
|
349
|
+
CASE(Float32) {
|
|
350
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
351
|
+
Napi::Value value = info[param.offset];
|
|
351
352
|
|
|
352
|
-
|
|
353
|
-
|
|
353
|
+
float f;
|
|
354
|
+
if (!TryNumber(value, &f)) [[unlikely]] {
|
|
355
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (param.vec_count) [[likely]] {
|
|
360
|
+
memset((uint8_t *)vec_ptr + 4, 0xFF, 4);
|
|
361
|
+
*(float *)(vec_ptr++) = f;
|
|
362
|
+
} else if (param.gpr_count) {
|
|
363
|
+
memset((uint8_t *)gpr_ptr + 4, 0xFF, 4);
|
|
364
|
+
*(float *)(gpr_ptr++) = f;
|
|
365
|
+
} else {
|
|
366
|
+
memset(args_ptr, 0xFF, 8);
|
|
367
|
+
*(float *)(args_ptr++) = f;
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
CASE(Float64) {
|
|
371
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
372
|
+
Napi::Value value = info[param.offset];
|
|
373
|
+
|
|
374
|
+
double d;
|
|
375
|
+
if (!TryNumber(value, &d)) [[unlikely]] {
|
|
376
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
if (param.vec_count) [[likely]] {
|
|
381
|
+
*(double *)(vec_ptr++) = d;
|
|
382
|
+
} else if (param.gpr_count) {
|
|
383
|
+
*(double *)(gpr_ptr++) = d;
|
|
384
|
+
} else {
|
|
385
|
+
*(double *)(args_ptr++) = d;
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
CASE(Callback) {
|
|
390
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
391
|
+
Napi::Value value = info[param.offset];
|
|
392
|
+
|
|
393
|
+
void *ptr;
|
|
394
|
+
if (!PushCallback(value, param.type, &ptr)) [[unlikely]]
|
|
395
|
+
return false;
|
|
396
|
+
|
|
397
|
+
*(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
CASE(Prototype) { K_UNREACHABLE(); };
|
|
401
|
+
|
|
402
|
+
CASE(End) { /* End loop */ };
|
|
354
403
|
}
|
|
355
404
|
|
|
356
405
|
#undef PUSH_INTEGER_SWAP
|
|
357
406
|
#undef PUSH_INTEGER
|
|
358
407
|
|
|
408
|
+
#undef OR
|
|
409
|
+
#undef CASE
|
|
410
|
+
#undef LOOP
|
|
411
|
+
|
|
359
412
|
new_sp = mem->stack.end();
|
|
360
413
|
|
|
361
414
|
return true;
|
|
@@ -422,8 +475,6 @@ void CallData::Execute(const FunctionInfo *func, void *native)
|
|
|
422
475
|
Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
423
476
|
{
|
|
424
477
|
K_DEFER {
|
|
425
|
-
PopOutArguments();
|
|
426
|
-
|
|
427
478
|
if (func->ret.type->dispose) {
|
|
428
479
|
func->ret.type->dispose(env, func->ret.type, result.ptr);
|
|
429
480
|
}
|
|
@@ -432,34 +483,25 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
432
483
|
switch (func->ret.type->primitive) {
|
|
433
484
|
case PrimitiveKind::Void: return env.Undefined();
|
|
434
485
|
case PrimitiveKind::Bool: return Napi::Boolean::New(env, result.u8 & 0x1);
|
|
435
|
-
case PrimitiveKind::Int8: return
|
|
436
|
-
case PrimitiveKind::UInt8: return
|
|
437
|
-
case PrimitiveKind::Int16: return
|
|
438
|
-
case PrimitiveKind::Int16S: return
|
|
439
|
-
case PrimitiveKind::UInt16: return
|
|
440
|
-
case PrimitiveKind::UInt16S: return
|
|
441
|
-
case PrimitiveKind::Int32: return
|
|
442
|
-
case PrimitiveKind::Int32S: return
|
|
443
|
-
case PrimitiveKind::UInt32: return
|
|
444
|
-
case PrimitiveKind::UInt32S: return
|
|
445
|
-
case PrimitiveKind::Int64: return
|
|
446
|
-
case PrimitiveKind::Int64S: return
|
|
447
|
-
case PrimitiveKind::UInt64: return
|
|
448
|
-
case PrimitiveKind::UInt64S: return
|
|
486
|
+
case PrimitiveKind::Int8: return NewInt(env, result.i8);
|
|
487
|
+
case PrimitiveKind::UInt8: return NewInt(env, result.u8);
|
|
488
|
+
case PrimitiveKind::Int16: return NewInt(env, result.i16);
|
|
489
|
+
case PrimitiveKind::Int16S: return NewInt(env, ReverseBytes(result.i16));
|
|
490
|
+
case PrimitiveKind::UInt16: return NewInt(env, result.u16);
|
|
491
|
+
case PrimitiveKind::UInt16S: return NewInt(env, ReverseBytes(result.u16));
|
|
492
|
+
case PrimitiveKind::Int32: return NewInt(env, result.i32);
|
|
493
|
+
case PrimitiveKind::Int32S: return NewInt(env, ReverseBytes(result.i32));
|
|
494
|
+
case PrimitiveKind::UInt32: return NewInt(env, result.u32);
|
|
495
|
+
case PrimitiveKind::UInt32S: return NewInt(env, ReverseBytes(result.u32));
|
|
496
|
+
case PrimitiveKind::Int64: return NewInt(env, result.i64);
|
|
497
|
+
case PrimitiveKind::Int64S: return NewInt(env, ReverseBytes(result.i64));
|
|
498
|
+
case PrimitiveKind::UInt64: return NewInt(env, result.u64);
|
|
499
|
+
case PrimitiveKind::UInt64S: return NewInt(env, ReverseBytes(result.u64));
|
|
449
500
|
case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
|
|
450
501
|
case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
|
|
451
502
|
case PrimitiveKind::String32: return result.ptr ? MakeStringFromUTF32(env, (const char32_t *)result.ptr) : env.Null();
|
|
452
|
-
case PrimitiveKind::Pointer:
|
|
453
|
-
case PrimitiveKind::Callback:
|
|
454
|
-
if (result.ptr) {
|
|
455
|
-
Napi::External<void> external = Napi::External<void>::New(env, result.ptr);
|
|
456
|
-
SetValueTag(external, func->ret.type->ref.marker);
|
|
457
|
-
|
|
458
|
-
return external;
|
|
459
|
-
} else {
|
|
460
|
-
return env.Null();
|
|
461
|
-
}
|
|
462
|
-
} break;
|
|
503
|
+
case PrimitiveKind::Pointer: return result.ptr ? WrapPointer(env, func->ret.type->ref.type, result.ptr) : env.Null();
|
|
504
|
+
case PrimitiveKind::Callback: return result.ptr ? WrapCallback(env, func->ret.type->ref.type, result.ptr) : env.Null();
|
|
463
505
|
case PrimitiveKind::Record:
|
|
464
506
|
case PrimitiveKind::Union: {
|
|
465
507
|
if (return_ptr) {
|
|
@@ -485,14 +527,14 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
485
527
|
|
|
486
528
|
void CallData::Relay(Size idx, uint8_t *sp)
|
|
487
529
|
{
|
|
488
|
-
|
|
530
|
+
TrampolineInfo *trampoline = &shared.trampolines[idx];
|
|
489
531
|
|
|
490
532
|
uint8_t *own_sp = sp;
|
|
491
533
|
uint8_t *caller_sp = sp + 168;
|
|
492
534
|
BackRegisters *out_reg = (BackRegisters *)(sp + 128);
|
|
493
535
|
|
|
494
|
-
const FunctionInfo *proto = trampoline
|
|
495
|
-
Napi::Function func = trampoline
|
|
536
|
+
const FunctionInfo *proto = trampoline->proto;
|
|
537
|
+
Napi::Function func = trampoline->func.Value();
|
|
496
538
|
|
|
497
539
|
uint64_t *gpr_ptr = (uint64_t *)own_sp;
|
|
498
540
|
uint64_t *vec_ptr = gpr_ptr + 8;
|
|
@@ -501,11 +543,14 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
501
543
|
uint8_t *return_ptr = proto->ret.use_memory ? (uint8_t *)gpr_ptr[0] : nullptr;
|
|
502
544
|
gpr_ptr += proto->ret.use_memory;
|
|
503
545
|
|
|
504
|
-
K_DEFER_N(err_guard) {
|
|
546
|
+
K_DEFER_N(err_guard) {
|
|
547
|
+
trampoline->state = -1;
|
|
548
|
+
memset(out_reg, 0, K_SIZE(*out_reg));
|
|
549
|
+
};
|
|
505
550
|
|
|
506
551
|
LocalArray<napi_value, MaxParameters + 1> arguments;
|
|
507
552
|
|
|
508
|
-
arguments.Append(!trampoline
|
|
553
|
+
arguments.Append(!trampoline->recv.IsEmpty() ? trampoline->recv.Value() : env.Undefined());
|
|
509
554
|
|
|
510
555
|
// Convert to JS arguments
|
|
511
556
|
for (Size i = 0; i < proto->parameters.len; i++) {
|
|
@@ -522,91 +567,87 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
522
567
|
arguments.Append(arg);
|
|
523
568
|
} break;
|
|
524
569
|
case PrimitiveKind::Int8: {
|
|
525
|
-
|
|
570
|
+
int8_t v = *(int8_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
526
571
|
|
|
527
|
-
Napi::Value arg =
|
|
572
|
+
Napi::Value arg = NewInt(env, v);
|
|
528
573
|
arguments.Append(arg);
|
|
529
574
|
} break;
|
|
530
575
|
case PrimitiveKind::UInt8: {
|
|
531
|
-
|
|
576
|
+
uint8_t v = *(uint8_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
532
577
|
|
|
533
|
-
Napi::Value arg =
|
|
578
|
+
Napi::Value arg = NewInt(env, v);
|
|
534
579
|
arguments.Append(arg);
|
|
535
580
|
} break;
|
|
536
581
|
case PrimitiveKind::Int16: {
|
|
537
|
-
|
|
582
|
+
int16_t v = *(int16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
538
583
|
|
|
539
|
-
Napi::Value arg =
|
|
584
|
+
Napi::Value arg = NewInt(env, v);
|
|
540
585
|
arguments.Append(arg);
|
|
541
586
|
} break;
|
|
542
587
|
case PrimitiveKind::Int16S: {
|
|
543
588
|
int16_t v = *(int16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
544
|
-
double d = (double)ReverseBytes(v);
|
|
545
589
|
|
|
546
|
-
Napi::Value arg =
|
|
590
|
+
Napi::Value arg = NewInt(env, ReverseBytes(v));
|
|
547
591
|
arguments.Append(arg);
|
|
548
592
|
} break;
|
|
549
593
|
case PrimitiveKind::UInt16: {
|
|
550
|
-
|
|
594
|
+
uint16_t v = *(uint16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
551
595
|
|
|
552
|
-
Napi::Value arg =
|
|
596
|
+
Napi::Value arg = NewInt(env, v);
|
|
553
597
|
arguments.Append(arg);
|
|
554
598
|
} break;
|
|
555
599
|
case PrimitiveKind::UInt16S: {
|
|
556
600
|
uint16_t v = *(uint16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
557
|
-
double d = (double)ReverseBytes(v);
|
|
558
601
|
|
|
559
|
-
Napi::Value arg =
|
|
602
|
+
Napi::Value arg = NewInt(env, ReverseBytes(v));
|
|
560
603
|
arguments.Append(arg);
|
|
561
604
|
} break;
|
|
562
605
|
case PrimitiveKind::Int32: {
|
|
563
|
-
|
|
606
|
+
int32_t v = *(int32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
564
607
|
|
|
565
|
-
Napi::Value arg =
|
|
608
|
+
Napi::Value arg = NewInt(env, v);
|
|
566
609
|
arguments.Append(arg);
|
|
567
610
|
} break;
|
|
568
611
|
case PrimitiveKind::Int32S: {
|
|
569
612
|
int32_t v = *(int32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
570
|
-
double d = (double)ReverseBytes(v);
|
|
571
613
|
|
|
572
|
-
Napi::Value arg =
|
|
614
|
+
Napi::Value arg = NewInt(env, ReverseBytes(v));
|
|
573
615
|
arguments.Append(arg);
|
|
574
616
|
} break;
|
|
575
617
|
case PrimitiveKind::UInt32: {
|
|
576
|
-
|
|
618
|
+
uint32_t v = *(uint32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
577
619
|
|
|
578
|
-
Napi::Value arg =
|
|
620
|
+
Napi::Value arg = NewInt(env, v);
|
|
579
621
|
arguments.Append(arg);
|
|
580
622
|
} break;
|
|
581
623
|
case PrimitiveKind::UInt32S: {
|
|
582
624
|
uint32_t v = *(uint32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
583
|
-
double d = (double)ReverseBytes(v);
|
|
584
625
|
|
|
585
|
-
Napi::Value arg =
|
|
626
|
+
Napi::Value arg = NewInt(env, ReverseBytes(v));
|
|
586
627
|
arguments.Append(arg);
|
|
587
628
|
} break;
|
|
588
629
|
case PrimitiveKind::Int64: {
|
|
589
630
|
int64_t v = *(int64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
590
631
|
|
|
591
|
-
Napi::Value arg =
|
|
632
|
+
Napi::Value arg = NewInt(env, v);
|
|
592
633
|
arguments.Append(arg);
|
|
593
634
|
} break;
|
|
594
635
|
case PrimitiveKind::Int64S: {
|
|
595
636
|
int64_t v = *(int64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
596
637
|
|
|
597
|
-
Napi::Value arg =
|
|
638
|
+
Napi::Value arg = NewInt(env, ReverseBytes(v));
|
|
598
639
|
arguments.Append(arg);
|
|
599
640
|
} break;
|
|
600
641
|
case PrimitiveKind::UInt64: {
|
|
601
642
|
uint64_t v = *(uint64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
602
643
|
|
|
603
|
-
Napi::Value arg =
|
|
644
|
+
Napi::Value arg = NewInt(env, v);
|
|
604
645
|
arguments.Append(arg);
|
|
605
646
|
} break;
|
|
606
647
|
case PrimitiveKind::UInt64S: {
|
|
607
648
|
uint64_t v = *(uint64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
608
649
|
|
|
609
|
-
Napi::Value arg =
|
|
650
|
+
Napi::Value arg = NewInt(env, ReverseBytes(v));
|
|
610
651
|
arguments.Append(arg);
|
|
611
652
|
} break;
|
|
612
653
|
case PrimitiveKind::String: {
|
|
@@ -635,18 +676,21 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
635
676
|
Napi::Value arg = str32 ? MakeStringFromUTF32(env, str32) : env.Null();
|
|
636
677
|
arguments.Append(arg);
|
|
637
678
|
} break;
|
|
638
|
-
case PrimitiveKind::Pointer:
|
|
639
|
-
case PrimitiveKind::Callback: {
|
|
679
|
+
case PrimitiveKind::Pointer: {
|
|
640
680
|
void *ptr2 = *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
641
681
|
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
SetValueTag(external, param.type->ref.marker);
|
|
682
|
+
Napi::Value p = ptr2 ? WrapPointer(env, param.type->ref.type, ptr2) : env.Null();
|
|
683
|
+
arguments.Append(p);
|
|
645
684
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
arguments.Append(env.Null());
|
|
685
|
+
if (param.type->dispose) {
|
|
686
|
+
param.type->dispose(env, param.type, ptr2);
|
|
649
687
|
}
|
|
688
|
+
} break;
|
|
689
|
+
case PrimitiveKind::Callback: {
|
|
690
|
+
void *ptr2 = *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
691
|
+
|
|
692
|
+
Napi::Value p = ptr2 ? WrapCallback(env, param.type->ref.type, ptr2) : env.Null();
|
|
693
|
+
arguments.Append(p);
|
|
650
694
|
|
|
651
695
|
if (param.type->dispose) {
|
|
652
696
|
param.type->dispose(env, param.type, ptr2);
|
|
@@ -725,22 +769,22 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
725
769
|
|
|
726
770
|
#define RETURN_INTEGER(CType) \
|
|
727
771
|
do { \
|
|
728
|
-
|
|
772
|
+
CType v; \
|
|
773
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
729
774
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
730
775
|
return; \
|
|
731
776
|
} \
|
|
732
777
|
\
|
|
733
|
-
CType v = GetNumber<CType>(value); \
|
|
734
778
|
out_reg->a0 = (uint64_t)v; \
|
|
735
779
|
} while (false)
|
|
736
780
|
#define RETURN_INTEGER_SWAP(CType) \
|
|
737
781
|
do { \
|
|
738
|
-
|
|
782
|
+
CType v; \
|
|
783
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
739
784
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
740
785
|
return; \
|
|
741
786
|
} \
|
|
742
787
|
\
|
|
743
|
-
CType v = GetNumber<CType>(value); \
|
|
744
788
|
out_reg->a0 = (uint64_t)ReverseBytes(v); \
|
|
745
789
|
} while (false)
|
|
746
790
|
|
|
@@ -748,12 +792,12 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
748
792
|
switch (type->primitive) {
|
|
749
793
|
case PrimitiveKind::Void: {} break;
|
|
750
794
|
case PrimitiveKind::Bool: {
|
|
751
|
-
|
|
795
|
+
bool b;
|
|
796
|
+
if (napi_get_value_bool(env, value, &b) != napi_ok) [[unlikely]] {
|
|
752
797
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
|
|
753
798
|
return;
|
|
754
799
|
}
|
|
755
800
|
|
|
756
|
-
bool b = value.As<Napi::Boolean>();
|
|
757
801
|
out_reg->a0 = (uint64_t)b;
|
|
758
802
|
} break;
|
|
759
803
|
case PrimitiveKind::Int8: { RETURN_INTEGER(int8_t); } break;
|
|
@@ -792,24 +836,9 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
792
836
|
out_reg->a0 = (uint64_t)str32;
|
|
793
837
|
} break;
|
|
794
838
|
case PrimitiveKind::Pointer: {
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
if (CheckValueTag(value, type->ref.marker)) {
|
|
798
|
-
ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
799
|
-
} else if (IsObject(value) && (type->ref.type->primitive == PrimitiveKind::Record ||
|
|
800
|
-
type->ref.type->primitive == PrimitiveKind::Union)) {
|
|
801
|
-
Napi::Object obj = value.As<Napi::Object>();
|
|
802
|
-
|
|
803
|
-
ptr = AllocHeap(type->ref.type->size, 16);
|
|
804
|
-
|
|
805
|
-
if (!PushObject(obj, type->ref.type, ptr))
|
|
806
|
-
return;
|
|
807
|
-
} else if (IsNullOrUndefined(value)) {
|
|
808
|
-
ptr = nullptr;
|
|
809
|
-
} else {
|
|
810
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected %2", GetValueType(instance, value), type->name);
|
|
839
|
+
void *ptr;
|
|
840
|
+
if (!PushPointer(value, type, 1, &ptr)) [[unlikely]]
|
|
811
841
|
return;
|
|
812
|
-
}
|
|
813
842
|
|
|
814
843
|
out_reg->a0 = (uint64_t)ptr;
|
|
815
844
|
} break;
|
|
@@ -852,41 +881,28 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
852
881
|
} break;
|
|
853
882
|
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
854
883
|
case PrimitiveKind::Float32: {
|
|
855
|
-
|
|
884
|
+
float f;
|
|
885
|
+
if (!TryNumber(value, &f)) [[unlikely]] {
|
|
856
886
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
857
887
|
return;
|
|
858
888
|
}
|
|
859
889
|
|
|
860
|
-
float f = GetNumber<float>(value);
|
|
861
890
|
memset((uint8_t *)&out_reg->fa0 + 4, 0xFF, 4);
|
|
862
891
|
memcpy(&out_reg->fa0, &f, 4);
|
|
863
892
|
} break;
|
|
864
893
|
case PrimitiveKind::Float64: {
|
|
865
|
-
|
|
894
|
+
double d;
|
|
895
|
+
if (!TryNumber(value, &d)) [[unlikely]] {
|
|
866
896
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
867
897
|
return;
|
|
868
898
|
}
|
|
869
899
|
|
|
870
|
-
double d = GetNumber<double>(value);
|
|
871
900
|
out_reg->fa0 = d;
|
|
872
901
|
} break;
|
|
873
902
|
case PrimitiveKind::Callback: {
|
|
874
903
|
void *ptr;
|
|
875
|
-
|
|
876
|
-
if (value.IsFunction()) {
|
|
877
|
-
Napi::Function func2 = value.As<Napi::Function>();
|
|
878
|
-
|
|
879
|
-
ptr = ReserveTrampoline(type->ref.proto, func2);
|
|
880
|
-
if (!ptr) [[unlikely]]
|
|
881
|
-
return;
|
|
882
|
-
} else if (CheckValueTag(value, type->ref.marker)) {
|
|
883
|
-
ptr = value.As<Napi::External<void>>().Data();
|
|
884
|
-
} else if (IsNullOrUndefined(value)) {
|
|
885
|
-
ptr = nullptr;
|
|
886
|
-
} else {
|
|
887
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected %2", GetValueType(instance, value), type->name);
|
|
904
|
+
if (!PushCallback(value, type, &ptr)) [[unlikely]]
|
|
888
905
|
return;
|
|
889
|
-
}
|
|
890
906
|
|
|
891
907
|
out_reg->a0 = (uint64_t)ptr;
|
|
892
908
|
} break;
|
|
@@ -900,16 +916,6 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
900
916
|
err_guard.Disable();
|
|
901
917
|
}
|
|
902
918
|
|
|
903
|
-
void *FindTrampolineStart()
|
|
904
|
-
{
|
|
905
|
-
return &Trampoline0;
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
void *FindTrampolineEnd()
|
|
909
|
-
{
|
|
910
|
-
return &TrampolineEnd;
|
|
911
|
-
}
|
|
912
|
-
|
|
913
919
|
}
|
|
914
920
|
|
|
915
921
|
#endif
|