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 defined(__arm__) || (defined(__M_ARM) && !defined(_M_ARM64))
|
|
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
|
#include <signal.h>
|
|
@@ -38,10 +38,11 @@ extern "C" uint64_t ForwardCallXGG(const void *func, uint8_t *sp, uint8_t **out_
|
|
|
38
38
|
extern "C" float ForwardCallXF(const void *func, uint8_t *sp, uint8_t **out_old_sp);
|
|
39
39
|
extern "C" HfaRet ForwardCallXDDDD(const void *func, uint8_t *sp, uint8_t **out_old_sp);
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
enum class AbiOpcode : int8_t {
|
|
42
|
+
#define PRIMITIVE(Name) Name,
|
|
43
|
+
#include "../primitives.inc"
|
|
44
|
+
End
|
|
45
|
+
};
|
|
45
46
|
|
|
46
47
|
static int IsHFA(const TypeInfo *type)
|
|
47
48
|
{
|
|
@@ -190,9 +191,11 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
|
190
191
|
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
191
192
|
}
|
|
192
193
|
|
|
194
|
+
func->instructions.Append((AbiOpcode)param.type->primitive);
|
|
193
195
|
func->args_size += AlignLen(param.type->size, 16);
|
|
194
196
|
}
|
|
195
197
|
|
|
198
|
+
func->instructions.Append(AbiOpcode::End);
|
|
196
199
|
func->forward_fp = (vec_avail < 16);
|
|
197
200
|
|
|
198
201
|
return true;
|
|
@@ -200,54 +203,74 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
|
200
203
|
|
|
201
204
|
bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
202
205
|
{
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
uint32_t *vec_ptr =
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
// partially in GPR, partially in the stack.
|
|
211
|
-
if (!AllocStack(func->args_size, 16, &args_ptr)) [[unlikely]]
|
|
212
|
-
return false;
|
|
213
|
-
if (!AllocStack(4 * 4, 8, &gpr_ptr)) [[unlikely]]
|
|
214
|
-
return false;
|
|
215
|
-
if (!AllocStack(8 * 8, 8, &vec_ptr)) [[unlikely]]
|
|
206
|
+
// Unlike other call conventions, here we put the general-purpose registers before the stack, behind the vector ones).
|
|
207
|
+
// In the armv7hf calling convention, some arguments can end up partially in GPR, partially in the stack.
|
|
208
|
+
uint32_t *vec_ptr = AllocStack<uint32_t>(20 * 4 + func->args_size);
|
|
209
|
+
uint32_t *gpr_ptr = vec_ptr + 16;
|
|
210
|
+
uint32_t *args_ptr = vec_ptr + 20;
|
|
211
|
+
|
|
212
|
+
if (!vec_ptr) [[unlikely]]
|
|
216
213
|
return false;
|
|
217
214
|
if (func->ret.use_memory) {
|
|
218
|
-
return_ptr = AllocHeap(func->ret.type->size
|
|
215
|
+
return_ptr = AllocHeap(func->ret.type->size);
|
|
219
216
|
*(uint8_t **)(gpr_ptr++) = return_ptr;
|
|
220
217
|
}
|
|
221
218
|
|
|
219
|
+
Size i = -1;
|
|
220
|
+
|
|
221
|
+
static const void *const DispatchTable[] = {
|
|
222
|
+
#define PRIMITIVE(Name) && Name,
|
|
223
|
+
#include "../primitives.inc"
|
|
224
|
+
&& End
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
#define LOOP
|
|
228
|
+
#define CASE(Primitive) \
|
|
229
|
+
do { \
|
|
230
|
+
AbiOpcode next = func->instructions[++i]; \
|
|
231
|
+
goto *DispatchTable[(int)next]; \
|
|
232
|
+
} while (false); \
|
|
233
|
+
Primitive:
|
|
234
|
+
#define OR(Primitive) \
|
|
235
|
+
Primitive:
|
|
236
|
+
|
|
222
237
|
#define PUSH_INTEGER_32(CType) \
|
|
223
238
|
do { \
|
|
224
|
-
|
|
239
|
+
const ParameterInfo ¶m = func->parameters[i]; \
|
|
240
|
+
Napi::Value value = info[param.offset]; \
|
|
241
|
+
\
|
|
242
|
+
CType v; \
|
|
243
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
225
244
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
226
245
|
return false; \
|
|
227
246
|
} \
|
|
228
247
|
\
|
|
229
|
-
CType v = GetNumber<CType>(value); \
|
|
230
248
|
*((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint32_t)v; \
|
|
231
249
|
} while (false)
|
|
232
250
|
#define PUSH_INTEGER_32_SWAP(CType) \
|
|
233
251
|
do { \
|
|
234
|
-
|
|
252
|
+
const ParameterInfo ¶m = func->parameters[i]; \
|
|
253
|
+
Napi::Value value = info[param.offset]; \
|
|
254
|
+
\
|
|
255
|
+
CType v; \
|
|
256
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
235
257
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
236
258
|
return false; \
|
|
237
259
|
} \
|
|
238
260
|
\
|
|
239
|
-
CType v = GetNumber<CType>(value); \
|
|
240
261
|
*((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint32_t)ReverseBytes(v); \
|
|
241
262
|
} while (false)
|
|
242
263
|
#define PUSH_INTEGER_64(CType) \
|
|
243
264
|
do { \
|
|
244
|
-
|
|
265
|
+
const ParameterInfo ¶m = func->parameters[i]; \
|
|
266
|
+
Napi::Value value = info[param.offset]; \
|
|
267
|
+
\
|
|
268
|
+
CType v; \
|
|
269
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
245
270
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
246
271
|
return false; \
|
|
247
272
|
} \
|
|
248
273
|
\
|
|
249
|
-
CType v = GetNumber<CType>(value); \
|
|
250
|
-
\
|
|
251
274
|
if (param.gpr_count) [[likely]] { \
|
|
252
275
|
gpr_ptr = AlignUp(gpr_ptr, 8); \
|
|
253
276
|
*(uint64_t *)gpr_ptr = (uint64_t)v; \
|
|
@@ -260,13 +283,15 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
260
283
|
} while (false)
|
|
261
284
|
#define PUSH_INTEGER_64_SWAP(CType) \
|
|
262
285
|
do { \
|
|
263
|
-
|
|
286
|
+
const ParameterInfo ¶m = func->parameters[i]; \
|
|
287
|
+
Napi::Value value = info[param.offset]; \
|
|
288
|
+
\
|
|
289
|
+
CType v; \
|
|
290
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
264
291
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
265
292
|
return false; \
|
|
266
293
|
} \
|
|
267
294
|
\
|
|
268
|
-
CType v = GetNumber<CType>(value); \
|
|
269
|
-
\
|
|
270
295
|
if (param.gpr_count) [[likely]] { \
|
|
271
296
|
gpr_ptr = AlignUp(gpr_ptr, 8); \
|
|
272
297
|
*(uint64_t *)gpr_ptr = (uint64_t)ReverseBytes(v); \
|
|
@@ -278,148 +303,172 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
278
303
|
} \
|
|
279
304
|
} while (false)
|
|
280
305
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
const ParameterInfo ¶m = func->parameters[i];
|
|
284
|
-
K_ASSERT(param.directions >= 1 && param.directions <= 3);
|
|
306
|
+
LOOP {
|
|
307
|
+
CASE(Void) { K_UNREACHABLE(); };
|
|
285
308
|
|
|
286
|
-
|
|
309
|
+
CASE(Bool) {
|
|
310
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
311
|
+
Napi::Value value = info[param.offset];
|
|
287
312
|
|
|
288
|
-
|
|
289
|
-
|
|
313
|
+
bool b;
|
|
314
|
+
if (napi_get_value_bool(env, value, &b) != napi_ok) [[unlikely]] {
|
|
315
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
290
318
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
319
|
+
*((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint32_t)b;
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
CASE(Int8) { PUSH_INTEGER_32(int8_t); };
|
|
323
|
+
CASE(UInt8) { PUSH_INTEGER_32(uint8_t); };
|
|
324
|
+
CASE(Int16) { PUSH_INTEGER_32(int16_t); };
|
|
325
|
+
CASE(Int16S) { PUSH_INTEGER_32_SWAP(int16_t); };
|
|
326
|
+
CASE(UInt16) { PUSH_INTEGER_32(uint16_t); };
|
|
327
|
+
CASE(UInt16S) { PUSH_INTEGER_32_SWAP(uint16_t); };
|
|
328
|
+
CASE(Int32) { PUSH_INTEGER_32(int32_t); };
|
|
329
|
+
CASE(Int32S) { PUSH_INTEGER_32_SWAP(int32_t); };
|
|
330
|
+
CASE(UInt32) { PUSH_INTEGER_32(uint32_t); };
|
|
331
|
+
CASE(UInt32S) { PUSH_INTEGER_32_SWAP(uint32_t); };
|
|
332
|
+
CASE(Int64) { PUSH_INTEGER_64(int64_t); };
|
|
333
|
+
CASE(Int64S) { PUSH_INTEGER_64_SWAP(int64_t); };
|
|
334
|
+
CASE(UInt64) { PUSH_INTEGER_64(uint64_t); };
|
|
335
|
+
CASE(UInt64S) { PUSH_INTEGER_64_SWAP(uint64_t); };
|
|
336
|
+
|
|
337
|
+
CASE(String) {
|
|
338
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
339
|
+
Napi::Value value = info[param.offset];
|
|
296
340
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
case PrimitiveKind::Int8: { PUSH_INTEGER_32(int8_t); } break;
|
|
301
|
-
case PrimitiveKind::UInt8: { PUSH_INTEGER_32(uint8_t); } break;
|
|
302
|
-
case PrimitiveKind::Int16: { PUSH_INTEGER_32(int16_t); } break;
|
|
303
|
-
case PrimitiveKind::Int16S: { PUSH_INTEGER_32_SWAP(int16_t); } break;
|
|
304
|
-
case PrimitiveKind::UInt16: { PUSH_INTEGER_32(uint16_t); } break;
|
|
305
|
-
case PrimitiveKind::UInt16S: { PUSH_INTEGER_32_SWAP(uint16_t); } break;
|
|
306
|
-
case PrimitiveKind::Int32: { PUSH_INTEGER_32(int32_t); } break;
|
|
307
|
-
case PrimitiveKind::Int32S: { PUSH_INTEGER_32_SWAP(int32_t); } break;
|
|
308
|
-
case PrimitiveKind::UInt32: { PUSH_INTEGER_32(uint32_t); } break;
|
|
309
|
-
case PrimitiveKind::UInt32S: { PUSH_INTEGER_32_SWAP(uint32_t); } break;
|
|
310
|
-
case PrimitiveKind::Int64: { PUSH_INTEGER_64(int64_t); } break;
|
|
311
|
-
case PrimitiveKind::Int64S: { PUSH_INTEGER_64_SWAP(int64_t); } break;
|
|
312
|
-
case PrimitiveKind::UInt64: { PUSH_INTEGER_64(uint64_t); } break;
|
|
313
|
-
case PrimitiveKind::UInt64S: { PUSH_INTEGER_64_SWAP(uint64_t); } break;
|
|
314
|
-
case PrimitiveKind::String: {
|
|
315
|
-
const char *str;
|
|
316
|
-
if (!PushString(value, param.directions, &str)) [[unlikely]]
|
|
317
|
-
return false;
|
|
341
|
+
const char *str;
|
|
342
|
+
if (!PushString(value, param.directions, &str)) [[unlikely]]
|
|
343
|
+
return false;
|
|
318
344
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
return false;
|
|
345
|
+
*(const char **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str;
|
|
346
|
+
};
|
|
347
|
+
CASE(String16) {
|
|
348
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
349
|
+
Napi::Value value = info[param.offset];
|
|
325
350
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
const char32_t *str32;
|
|
330
|
-
if (!PushString32(value, param.directions, &str32)) [[unlikely]]
|
|
331
|
-
return false;
|
|
351
|
+
const char16_t *str16;
|
|
352
|
+
if (!PushString16(value, param.directions, &str16)) [[unlikely]]
|
|
353
|
+
return false;
|
|
332
354
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
return false;
|
|
355
|
+
*(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str16;
|
|
356
|
+
};
|
|
357
|
+
CASE(String32) {
|
|
358
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
359
|
+
Napi::Value value = info[param.offset];
|
|
339
360
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
case PrimitiveKind::Union: {
|
|
344
|
-
if (!IsObject(value)) [[unlikely]] {
|
|
345
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
346
|
-
return false;
|
|
347
|
-
}
|
|
361
|
+
const char32_t *str32;
|
|
362
|
+
if (!PushString32(value, param.directions, &str32)) [[unlikely]]
|
|
363
|
+
return false;
|
|
348
364
|
|
|
349
|
-
|
|
365
|
+
*(const char32_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str32;
|
|
366
|
+
};
|
|
350
367
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
vec_ptr += param.vec_count;
|
|
355
|
-
} else if (param.gpr_count) {
|
|
356
|
-
K_ASSERT(param.type->align <= 8);
|
|
368
|
+
CASE(Pointer) {
|
|
369
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
370
|
+
Napi::Value value = info[param.offset];
|
|
357
371
|
|
|
358
|
-
|
|
359
|
-
|
|
372
|
+
void *ptr;
|
|
373
|
+
if (!PushPointer(value, param.type, param.directions, &ptr)) [[unlikely]]
|
|
374
|
+
return false;
|
|
360
375
|
|
|
361
|
-
|
|
362
|
-
|
|
376
|
+
*(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
|
|
377
|
+
};
|
|
363
378
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
int16_t align = (param.type->align <= 4) ? 4 : 8;
|
|
368
|
-
args_ptr = AlignUp(args_ptr, align);
|
|
379
|
+
CASE(Record) OR(Union) {
|
|
380
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
381
|
+
Napi::Value value = info[param.offset];
|
|
369
382
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
383
|
+
if (!IsObject(value)) [[unlikely]] {
|
|
384
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
Napi::Object obj = value.As<Napi::Object>();
|
|
389
|
+
|
|
390
|
+
if (param.vec_count) {
|
|
391
|
+
if (!PushObject(obj, param.type, (uint8_t *)vec_ptr))
|
|
379
392
|
return false;
|
|
380
|
-
|
|
393
|
+
vec_ptr += param.vec_count;
|
|
394
|
+
} else if (param.gpr_count) {
|
|
395
|
+
K_ASSERT(param.type->align <= 8);
|
|
381
396
|
|
|
382
|
-
|
|
397
|
+
int16_t align = (param.type->align <= 4) ? 4 : 8;
|
|
398
|
+
gpr_ptr = AlignUp(gpr_ptr, align);
|
|
383
399
|
|
|
384
|
-
if (param.
|
|
385
|
-
*(float *)(vec_ptr++) = f;
|
|
386
|
-
} else if (param.gpr_count) {
|
|
387
|
-
*(float *)(gpr_ptr++) = f;
|
|
388
|
-
} else {
|
|
389
|
-
*(float *)(args_ptr++) = f;
|
|
390
|
-
}
|
|
391
|
-
} break;
|
|
392
|
-
case PrimitiveKind::Float64: {
|
|
393
|
-
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
394
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
400
|
+
if (!PushObject(obj, param.type, (uint8_t *)gpr_ptr))
|
|
395
401
|
return false;
|
|
396
|
-
}
|
|
397
402
|
|
|
398
|
-
|
|
403
|
+
gpr_ptr += param.gpr_count;
|
|
404
|
+
args_ptr += (param.type->size - param.gpr_count * 4 + 3) / 4;
|
|
405
|
+
} else if (param.type->size) {
|
|
406
|
+
int16_t align = (param.type->align <= 4) ? 4 : 8;
|
|
407
|
+
args_ptr = AlignUp(args_ptr, align);
|
|
399
408
|
|
|
400
|
-
if (param.
|
|
401
|
-
*(double *)vec_ptr = d;
|
|
402
|
-
vec_ptr += 2;
|
|
403
|
-
} else if (param.gpr_count) {
|
|
404
|
-
gpr_ptr = AlignUp(gpr_ptr, 8);
|
|
405
|
-
*(double *)gpr_ptr = d;
|
|
406
|
-
gpr_ptr += 2;
|
|
407
|
-
} else {
|
|
408
|
-
args_ptr = AlignUp(args_ptr, 8);
|
|
409
|
-
*(double *)args_ptr = d;
|
|
410
|
-
args_ptr += 2;
|
|
411
|
-
}
|
|
412
|
-
} break;
|
|
413
|
-
case PrimitiveKind::Callback: {
|
|
414
|
-
void *ptr;
|
|
415
|
-
if (!PushCallback(value, param.type, &ptr)) [[unlikely]]
|
|
409
|
+
if (!PushObject(obj, param.type, (uint8_t *)args_ptr))
|
|
416
410
|
return false;
|
|
411
|
+
args_ptr += (param.type->size + 3) / 4;
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
CASE(Array) { K_UNREACHABLE(); };
|
|
417
415
|
|
|
418
|
-
|
|
419
|
-
|
|
416
|
+
CASE(Float32) {
|
|
417
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
418
|
+
Napi::Value value = info[param.offset];
|
|
420
419
|
|
|
421
|
-
|
|
422
|
-
|
|
420
|
+
float f;
|
|
421
|
+
if (!TryNumber(value, &f)) [[unlikely]] {
|
|
422
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
423
|
+
return false;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if (param.vec_count) [[likely]] {
|
|
427
|
+
*(float *)(vec_ptr++) = f;
|
|
428
|
+
} else if (param.gpr_count) {
|
|
429
|
+
*(float *)(gpr_ptr++) = f;
|
|
430
|
+
} else {
|
|
431
|
+
*(float *)(args_ptr++) = f;
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
CASE(Float64) {
|
|
435
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
436
|
+
Napi::Value value = info[param.offset];
|
|
437
|
+
|
|
438
|
+
double d;
|
|
439
|
+
if (!TryNumber(value, &d)) [[unlikely]] {
|
|
440
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (param.vec_count) [[likely]] {
|
|
445
|
+
*(double *)vec_ptr = d;
|
|
446
|
+
vec_ptr += 2;
|
|
447
|
+
} else if (param.gpr_count) {
|
|
448
|
+
gpr_ptr = AlignUp(gpr_ptr, 8);
|
|
449
|
+
*(double *)gpr_ptr = d;
|
|
450
|
+
gpr_ptr += 2;
|
|
451
|
+
} else {
|
|
452
|
+
args_ptr = AlignUp(args_ptr, 8);
|
|
453
|
+
*(double *)args_ptr = d;
|
|
454
|
+
args_ptr += 2;
|
|
455
|
+
}
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
CASE(Callback) {
|
|
459
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
460
|
+
Napi::Value value = info[param.offset];
|
|
461
|
+
|
|
462
|
+
void *ptr;
|
|
463
|
+
if (!PushCallback(value, param.type, &ptr)) [[unlikely]]
|
|
464
|
+
return false;
|
|
465
|
+
|
|
466
|
+
*(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
CASE(Prototype) { K_UNREACHABLE(); };
|
|
470
|
+
|
|
471
|
+
CASE(End) { /* End loop */ };
|
|
423
472
|
}
|
|
424
473
|
|
|
425
474
|
#undef PUSH_INTEGER_64_SWAP
|
|
@@ -427,6 +476,10 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
427
476
|
#undef PUSH_INTEGER_32_SWAP
|
|
428
477
|
#undef PUSH_INTEGER_32
|
|
429
478
|
|
|
479
|
+
#undef OR
|
|
480
|
+
#undef CASE
|
|
481
|
+
#undef LOOP
|
|
482
|
+
|
|
430
483
|
new_sp = mem->stack.end();
|
|
431
484
|
|
|
432
485
|
return true;
|
|
@@ -486,8 +539,6 @@ void CallData::Execute(const FunctionInfo *func, void *native)
|
|
|
486
539
|
Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
487
540
|
{
|
|
488
541
|
K_DEFER {
|
|
489
|
-
PopOutArguments();
|
|
490
|
-
|
|
491
542
|
if (func->ret.type->dispose) {
|
|
492
543
|
func->ret.type->dispose(env, func->ret.type, result.ptr);
|
|
493
544
|
}
|
|
@@ -496,34 +547,25 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
496
547
|
switch (func->ret.type->primitive) {
|
|
497
548
|
case PrimitiveKind::Void: return env.Undefined();
|
|
498
549
|
case PrimitiveKind::Bool: return Napi::Boolean::New(env, result.u8 & 0x1);
|
|
499
|
-
case PrimitiveKind::Int8: return
|
|
500
|
-
case PrimitiveKind::UInt8: return
|
|
501
|
-
case PrimitiveKind::Int16: return
|
|
502
|
-
case PrimitiveKind::Int16S: return
|
|
503
|
-
case PrimitiveKind::UInt16: return
|
|
504
|
-
case PrimitiveKind::UInt16S: return
|
|
505
|
-
case PrimitiveKind::Int32: return
|
|
506
|
-
case PrimitiveKind::Int32S: return
|
|
507
|
-
case PrimitiveKind::UInt32: return
|
|
508
|
-
case PrimitiveKind::UInt32S: return
|
|
509
|
-
case PrimitiveKind::Int64: return
|
|
510
|
-
case PrimitiveKind::Int64S: return
|
|
511
|
-
case PrimitiveKind::UInt64: return
|
|
512
|
-
case PrimitiveKind::UInt64S: return
|
|
550
|
+
case PrimitiveKind::Int8: return NewInt(env, result.i8);
|
|
551
|
+
case PrimitiveKind::UInt8: return NewInt(env, result.u8);
|
|
552
|
+
case PrimitiveKind::Int16: return NewInt(env, result.i16);
|
|
553
|
+
case PrimitiveKind::Int16S: return NewInt(env, ReverseBytes(result.i16));
|
|
554
|
+
case PrimitiveKind::UInt16: return NewInt(env, result.u16);
|
|
555
|
+
case PrimitiveKind::UInt16S: return NewInt(env, ReverseBytes(result.u16));
|
|
556
|
+
case PrimitiveKind::Int32: return NewInt(env, result.i32);
|
|
557
|
+
case PrimitiveKind::Int32S: return NewInt(env, ReverseBytes(result.i32));
|
|
558
|
+
case PrimitiveKind::UInt32: return NewInt(env, result.u32);
|
|
559
|
+
case PrimitiveKind::UInt32S: return NewInt(env, ReverseBytes(result.u32));
|
|
560
|
+
case PrimitiveKind::Int64: return NewInt(env, result.i64);
|
|
561
|
+
case PrimitiveKind::Int64S: return NewInt(env, ReverseBytes(result.i64));
|
|
562
|
+
case PrimitiveKind::UInt64: return NewInt(env, result.u64);
|
|
563
|
+
case PrimitiveKind::UInt64S: return NewInt(env, ReverseBytes(result.u64));
|
|
513
564
|
case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
|
|
514
565
|
case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
|
|
515
566
|
case PrimitiveKind::String32: return result.ptr ? MakeStringFromUTF32(env, (const char32_t *)result.ptr) : env.Null();
|
|
516
|
-
case PrimitiveKind::Pointer:
|
|
517
|
-
case PrimitiveKind::Callback:
|
|
518
|
-
if (result.ptr) {
|
|
519
|
-
Napi::External<void> external = Napi::External<void>::New(env, result.ptr);
|
|
520
|
-
SetValueTag(external, func->ret.type->ref.marker);
|
|
521
|
-
|
|
522
|
-
return external;
|
|
523
|
-
} else {
|
|
524
|
-
return env.Null();
|
|
525
|
-
}
|
|
526
|
-
} break;
|
|
567
|
+
case PrimitiveKind::Pointer: return result.ptr ? WrapPointer(env, func->ret.type->ref.type, result.ptr) : env.Null();
|
|
568
|
+
case PrimitiveKind::Callback: return result.ptr ? WrapCallback(env, func->ret.type->ref.type, result.ptr) : env.Null();
|
|
527
569
|
case PrimitiveKind::Record:
|
|
528
570
|
case PrimitiveKind::Union: {
|
|
529
571
|
const uint8_t *ptr = return_ptr ? (const uint8_t *)return_ptr
|
|
@@ -544,14 +586,14 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
544
586
|
|
|
545
587
|
void CallData::Relay(Size idx, uint8_t *sp)
|
|
546
588
|
{
|
|
547
|
-
|
|
589
|
+
TrampolineInfo *trampoline = &shared.trampolines[idx];
|
|
548
590
|
|
|
549
591
|
uint8_t *own_sp = sp;
|
|
550
592
|
uint8_t *caller_sp = sp + 128;
|
|
551
593
|
BackRegisters *out_reg = (BackRegisters *)(sp + 80);
|
|
552
594
|
|
|
553
|
-
const FunctionInfo *proto = trampoline
|
|
554
|
-
Napi::Function func = trampoline
|
|
595
|
+
const FunctionInfo *proto = trampoline->proto;
|
|
596
|
+
Napi::Function func = trampoline->func.Value();
|
|
555
597
|
|
|
556
598
|
uint32_t *vec_ptr = (uint32_t *)own_sp;
|
|
557
599
|
uint32_t *gpr_ptr = vec_ptr + 16;
|
|
@@ -560,11 +602,14 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
560
602
|
uint8_t *return_ptr = proto->ret.use_memory ? (uint8_t *)gpr_ptr[0] : nullptr;
|
|
561
603
|
gpr_ptr += proto->ret.use_memory;
|
|
562
604
|
|
|
563
|
-
K_DEFER_N(err_guard) {
|
|
605
|
+
K_DEFER_N(err_guard) {
|
|
606
|
+
trampoline->state = -1;
|
|
607
|
+
memset(out_reg, 0, K_SIZE(*out_reg));
|
|
608
|
+
};
|
|
564
609
|
|
|
565
610
|
LocalArray<napi_value, MaxParameters + 1> arguments;
|
|
566
611
|
|
|
567
|
-
arguments.Append(!trampoline
|
|
612
|
+
arguments.Append(!trampoline->recv.IsEmpty() ? trampoline->recv.Value() : env.Undefined());
|
|
568
613
|
|
|
569
614
|
// Convert to JS arguments
|
|
570
615
|
for (Size i = 0; i < proto->parameters.len; i++) {
|
|
@@ -581,67 +626,63 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
581
626
|
arguments.Append(arg);
|
|
582
627
|
} break;
|
|
583
628
|
case PrimitiveKind::Int8: {
|
|
584
|
-
|
|
629
|
+
int8_t v = *(int8_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
585
630
|
|
|
586
|
-
Napi::Value arg =
|
|
631
|
+
Napi::Value arg = NewInt(env, v);
|
|
587
632
|
arguments.Append(arg);
|
|
588
633
|
} break;
|
|
589
634
|
case PrimitiveKind::UInt8: {
|
|
590
|
-
|
|
635
|
+
uint8_t v = *(uint8_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
591
636
|
|
|
592
|
-
Napi::Value arg =
|
|
637
|
+
Napi::Value arg = NewInt(env, v);
|
|
593
638
|
arguments.Append(arg);
|
|
594
639
|
} break;
|
|
595
640
|
case PrimitiveKind::Int16: {
|
|
596
|
-
|
|
641
|
+
int16_t v = *(int16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
597
642
|
|
|
598
|
-
Napi::Value arg =
|
|
643
|
+
Napi::Value arg = NewInt(env, v);
|
|
599
644
|
arguments.Append(arg);
|
|
600
645
|
} break;
|
|
601
646
|
case PrimitiveKind::Int16S: {
|
|
602
647
|
int16_t v = *(int16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
603
|
-
double d = (double)ReverseBytes(v);
|
|
604
648
|
|
|
605
|
-
Napi::Value arg =
|
|
649
|
+
Napi::Value arg = NewInt(env, ReverseBytes(v));
|
|
606
650
|
arguments.Append(arg);
|
|
607
651
|
} break;
|
|
608
652
|
case PrimitiveKind::UInt16: {
|
|
609
|
-
|
|
653
|
+
uint16_t v = *(uint16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
610
654
|
|
|
611
|
-
Napi::Value arg =
|
|
655
|
+
Napi::Value arg = NewInt(env, v);
|
|
612
656
|
arguments.Append(arg);
|
|
613
657
|
} break;
|
|
614
658
|
case PrimitiveKind::UInt16S: {
|
|
615
659
|
uint16_t v = *(uint16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
616
|
-
double d = (double)ReverseBytes(v);
|
|
617
660
|
|
|
618
|
-
Napi::Value arg =
|
|
661
|
+
Napi::Value arg = NewInt(env, ReverseBytes(v));
|
|
619
662
|
arguments.Append(arg);
|
|
620
663
|
} break;
|
|
621
664
|
case PrimitiveKind::Int32: {
|
|
622
|
-
|
|
665
|
+
int32_t v = *(int32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
623
666
|
|
|
624
|
-
Napi::Value arg =
|
|
667
|
+
Napi::Value arg = NewInt(env, v);
|
|
625
668
|
arguments.Append(arg);
|
|
626
669
|
} break;
|
|
627
670
|
case PrimitiveKind::Int32S: {
|
|
628
671
|
int32_t v = *(int32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
629
|
-
double d = (double)ReverseBytes(v);
|
|
630
672
|
|
|
631
|
-
Napi::Value arg =
|
|
673
|
+
Napi::Value arg = NewInt(env, ReverseBytes(v));
|
|
632
674
|
arguments.Append(arg);
|
|
633
675
|
} break;
|
|
634
676
|
case PrimitiveKind::UInt32: {
|
|
635
|
-
|
|
677
|
+
uint32_t v = *(uint32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
636
678
|
|
|
637
|
-
Napi::Value arg =
|
|
679
|
+
Napi::Value arg = NewInt(env, v);
|
|
638
680
|
arguments.Append(arg);
|
|
639
681
|
} break;
|
|
640
682
|
case PrimitiveKind::UInt32S: {
|
|
641
683
|
uint32_t v = *(uint32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
642
|
-
double d = (double)ReverseBytes(v);
|
|
643
684
|
|
|
644
|
-
Napi::Value arg =
|
|
685
|
+
Napi::Value arg = NewInt(env, ReverseBytes(v));
|
|
645
686
|
arguments.Append(arg);
|
|
646
687
|
} break;
|
|
647
688
|
case PrimitiveKind::Int64: {
|
|
@@ -650,7 +691,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
650
691
|
int64_t v = *(int64_t *)(param.gpr_count ? gpr_ptr : args_ptr);
|
|
651
692
|
(param.gpr_count ? gpr_ptr : args_ptr) += 2;
|
|
652
693
|
|
|
653
|
-
Napi::Value arg =
|
|
694
|
+
Napi::Value arg = NewInt(env, v);
|
|
654
695
|
arguments.Append(arg);
|
|
655
696
|
} break;
|
|
656
697
|
case PrimitiveKind::Int64S: {
|
|
@@ -659,7 +700,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
659
700
|
int64_t v = *(int64_t *)(param.gpr_count ? gpr_ptr : args_ptr);
|
|
660
701
|
(param.gpr_count ? gpr_ptr : args_ptr) += 2;
|
|
661
702
|
|
|
662
|
-
Napi::Value arg =
|
|
703
|
+
Napi::Value arg = NewInt(env, ReverseBytes(v));
|
|
663
704
|
arguments.Append(arg);
|
|
664
705
|
} break;
|
|
665
706
|
case PrimitiveKind::UInt64: {
|
|
@@ -668,7 +709,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
668
709
|
uint64_t v = *(uint64_t *)(param.gpr_count ? gpr_ptr : args_ptr);
|
|
669
710
|
(param.gpr_count ? gpr_ptr : args_ptr) += 2;
|
|
670
711
|
|
|
671
|
-
Napi::Value arg =
|
|
712
|
+
Napi::Value arg = NewInt(env, v);
|
|
672
713
|
arguments.Append(arg);
|
|
673
714
|
} break;
|
|
674
715
|
case PrimitiveKind::UInt64S: {
|
|
@@ -677,7 +718,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
677
718
|
uint64_t v = *(uint64_t *)(param.gpr_count ? gpr_ptr : args_ptr);
|
|
678
719
|
(param.gpr_count ? gpr_ptr : args_ptr) += 2;
|
|
679
720
|
|
|
680
|
-
Napi::Value arg =
|
|
721
|
+
Napi::Value arg = NewInt(env, ReverseBytes(v));
|
|
681
722
|
arguments.Append(arg);
|
|
682
723
|
} break;
|
|
683
724
|
case PrimitiveKind::String: {
|
|
@@ -706,18 +747,21 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
706
747
|
Napi::Value arg = str32 ? MakeStringFromUTF32(env, str32) : env.Null();
|
|
707
748
|
arguments.Append(arg);
|
|
708
749
|
} break;
|
|
709
|
-
case PrimitiveKind::Pointer:
|
|
710
|
-
case PrimitiveKind::Callback: {
|
|
750
|
+
case PrimitiveKind::Pointer: {
|
|
711
751
|
void *ptr2 = *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
712
752
|
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
SetValueTag(external, param.type->ref.marker);
|
|
753
|
+
Napi::Value p = ptr2 ? WrapPointer(env, param.type->ref.type, ptr2) : env.Null();
|
|
754
|
+
arguments.Append(p);
|
|
716
755
|
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
arguments.Append(env.Null());
|
|
756
|
+
if (param.type->dispose) {
|
|
757
|
+
param.type->dispose(env, param.type, ptr2);
|
|
720
758
|
}
|
|
759
|
+
} break;
|
|
760
|
+
case PrimitiveKind::Callback: {
|
|
761
|
+
void *ptr2 = *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
762
|
+
|
|
763
|
+
Napi::Value p = ptr2 ? WrapCallback(env, param.type->ref.type, ptr2) : env.Null();
|
|
764
|
+
arguments.Append(p);
|
|
721
765
|
|
|
722
766
|
if (param.type->dispose) {
|
|
723
767
|
param.type->dispose(env, param.type, ptr2);
|
|
@@ -740,7 +784,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
740
784
|
if (param.type->size > gpr_size) {
|
|
741
785
|
// XXX: Expensive, can we do better?
|
|
742
786
|
// The problem is that the object is split between the GPRs and the caller stack.
|
|
743
|
-
uint8_t *ptr = AllocHeap(param.type->size
|
|
787
|
+
uint8_t *ptr = AllocHeap(param.type->size);
|
|
744
788
|
|
|
745
789
|
memcpy(ptr, gpr_ptr, gpr_size);
|
|
746
790
|
memcpy(ptr + gpr_size, args_ptr, param.type->size - gpr_size);
|
|
@@ -813,45 +857,43 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
813
857
|
|
|
814
858
|
#define RETURN_INTEGER_32(CType) \
|
|
815
859
|
do { \
|
|
816
|
-
|
|
860
|
+
CType v; \
|
|
861
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
817
862
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
|
|
818
863
|
return; \
|
|
819
864
|
} \
|
|
820
865
|
\
|
|
821
|
-
CType v = GetNumber<CType>(value); \
|
|
822
866
|
out_reg->r0 = (uint32_t)v; \
|
|
823
867
|
} while (false)
|
|
824
868
|
#define RETURN_INTEGER_32_SWAP(CType) \
|
|
825
869
|
do { \
|
|
826
|
-
|
|
827
|
-
|
|
870
|
+
CType v; \
|
|
871
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
872
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
|
|
828
873
|
return; \
|
|
829
874
|
} \
|
|
830
875
|
\
|
|
831
|
-
CType v = GetNumber<CType>(value); \
|
|
832
876
|
out_reg->r0 = (uint32_t)ReverseBytes(v); \
|
|
833
877
|
} while (false)
|
|
834
878
|
#define RETURN_INTEGER_64(CType) \
|
|
835
879
|
do { \
|
|
836
|
-
|
|
837
|
-
|
|
880
|
+
CType v; \
|
|
881
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
882
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
|
|
838
883
|
return; \
|
|
839
884
|
} \
|
|
840
885
|
\
|
|
841
|
-
CType v = GetNumber<CType>(value); \
|
|
842
|
-
\
|
|
843
886
|
out_reg->r0 = (uint32_t)((uint64_t)v >> 32); \
|
|
844
887
|
out_reg->r1 = (uint32_t)((uint64_t)v & 0xFFFFFFFFu); \
|
|
845
888
|
} while (false)
|
|
846
889
|
#define RETURN_INTEGER_64_SWAP(CType) \
|
|
847
890
|
do { \
|
|
848
|
-
|
|
849
|
-
|
|
891
|
+
CType v; \
|
|
892
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
893
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
|
|
850
894
|
return; \
|
|
851
895
|
} \
|
|
852
896
|
\
|
|
853
|
-
CType v = ReverseBytes(GetNumber<CType>(value)); \
|
|
854
|
-
\
|
|
855
897
|
out_reg->r0 = (uint32_t)((uint64_t)v >> 32); \
|
|
856
898
|
out_reg->r1 = (uint32_t)((uint64_t)v & 0xFFFFFFFFu); \
|
|
857
899
|
} while (false)
|
|
@@ -860,12 +902,12 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
860
902
|
switch (type->primitive) {
|
|
861
903
|
case PrimitiveKind::Void: {} break;
|
|
862
904
|
case PrimitiveKind::Bool: {
|
|
863
|
-
|
|
905
|
+
bool b;
|
|
906
|
+
if (napi_get_value_bool(env, value, &b) != napi_ok) [[unlikely]] {
|
|
864
907
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
|
|
865
908
|
return;
|
|
866
909
|
}
|
|
867
910
|
|
|
868
|
-
bool b = value.As<Napi::Boolean>();
|
|
869
911
|
out_reg->r0 = (uint32_t)b;
|
|
870
912
|
} break;
|
|
871
913
|
case PrimitiveKind::Int8: { RETURN_INTEGER_32(int8_t); } break;
|
|
@@ -904,24 +946,9 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
904
946
|
out_reg->r0 = (uint32_t)str32;
|
|
905
947
|
} break;
|
|
906
948
|
case PrimitiveKind::Pointer: {
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
if (CheckValueTag(value, type->ref.marker)) {
|
|
910
|
-
ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
911
|
-
} else if (IsObject(value) && (type->ref.type->primitive == PrimitiveKind::Record ||
|
|
912
|
-
type->ref.type->primitive == PrimitiveKind::Union)) {
|
|
913
|
-
Napi::Object obj = value.As<Napi::Object>();
|
|
914
|
-
|
|
915
|
-
ptr = AllocHeap(type->ref.type->size, 16);
|
|
916
|
-
|
|
917
|
-
if (!PushObject(obj, type->ref.type, ptr))
|
|
918
|
-
return;
|
|
919
|
-
} else if (IsNullOrUndefined(value)) {
|
|
920
|
-
ptr = nullptr;
|
|
921
|
-
} else {
|
|
922
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected %2", GetValueType(instance, value), type->name);
|
|
949
|
+
void *ptr;
|
|
950
|
+
if (!PushPointer(value, type, 1, &ptr)) [[unlikely]]
|
|
923
951
|
return;
|
|
924
|
-
}
|
|
925
952
|
|
|
926
953
|
out_reg->r0 = (uint32_t)ptr;
|
|
927
954
|
} break;
|
|
@@ -946,12 +973,12 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
946
973
|
} break;
|
|
947
974
|
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
948
975
|
case PrimitiveKind::Float32: {
|
|
949
|
-
|
|
976
|
+
float f;
|
|
977
|
+
if (!TryNumber(value, &f)) [[unlikely]] {
|
|
950
978
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
951
979
|
return;
|
|
952
980
|
}
|
|
953
981
|
|
|
954
|
-
float f = GetNumber<float>(value);
|
|
955
982
|
#if defined(__ARM_PCS_VFP)
|
|
956
983
|
memcpy(&out_reg->d0, &f, 4);
|
|
957
984
|
#else
|
|
@@ -959,12 +986,12 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
959
986
|
#endif
|
|
960
987
|
} break;
|
|
961
988
|
case PrimitiveKind::Float64: {
|
|
962
|
-
|
|
989
|
+
double d;
|
|
990
|
+
if (!TryNumber(value, &d)) [[unlikely]] {
|
|
963
991
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
964
992
|
return;
|
|
965
993
|
}
|
|
966
994
|
|
|
967
|
-
double d = GetNumber<double>(value);
|
|
968
995
|
#if defined(__ARM_PCS_VFP)
|
|
969
996
|
out_reg->d0 = d;
|
|
970
997
|
#else
|
|
@@ -973,21 +1000,8 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
973
1000
|
} break;
|
|
974
1001
|
case PrimitiveKind::Callback: {
|
|
975
1002
|
void *ptr;
|
|
976
|
-
|
|
977
|
-
if (value.IsFunction()) {
|
|
978
|
-
Napi::Function func2 = value.As<Napi::Function>();
|
|
979
|
-
|
|
980
|
-
ptr = ReserveTrampoline(type->ref.proto, func2);
|
|
981
|
-
if (!ptr) [[unlikely]]
|
|
982
|
-
return;
|
|
983
|
-
} else if (CheckValueTag(value, type->ref.marker)) {
|
|
984
|
-
ptr = value.As<Napi::External<void>>().Data();
|
|
985
|
-
} else if (IsNullOrUndefined(value)) {
|
|
986
|
-
ptr = nullptr;
|
|
987
|
-
} else {
|
|
988
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected %2", GetValueType(instance, value), type->name);
|
|
1003
|
+
if (!PushCallback(value, type, &ptr)) [[unlikely]]
|
|
989
1004
|
return;
|
|
990
|
-
}
|
|
991
1005
|
|
|
992
1006
|
out_reg->r0 = (uint32_t)ptr;
|
|
993
1007
|
} break;
|
|
@@ -1003,16 +1017,6 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
1003
1017
|
err_guard.Disable();
|
|
1004
1018
|
}
|
|
1005
1019
|
|
|
1006
|
-
void *FindTrampolineStart()
|
|
1007
|
-
{
|
|
1008
|
-
return &Trampoline0;
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
void *FindTrampolineEnd()
|
|
1012
|
-
{
|
|
1013
|
-
return &TrampolineEnd;
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
1020
|
}
|
|
1017
1021
|
|
|
1018
1022
|
#endif
|