koffi 2.15.1 → 2.16.0-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/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_armhf/koffi.node +0 -0
- package/build/koffi/linux_ia32/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/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_arm64/koffi.node +0 -0
- package/build/koffi/win32_ia32/koffi.node +0 -0
- package/build/koffi/win32_x64/koffi.node +0 -0
- package/index.d.ts +11 -9
- package/index.js +8 -8
- package/indirect.js +8 -8
- package/package.json +1 -1
- package/src/koffi/src/abi_arm32.cc +222 -219
- package/src/koffi/src/abi_arm32_asm.S +1 -29
- package/src/koffi/src/abi_arm64.cc +257 -235
- package/src/koffi/src/abi_arm64_asm.S +1 -32
- package/src/koffi/src/abi_arm64_asm.asm +1 -23
- package/src/koffi/src/abi_loong64_asm.S +1 -25
- package/src/koffi/src/abi_riscv64.cc +220 -217
- package/src/koffi/src/abi_riscv64_asm.S +1 -25
- package/src/koffi/src/abi_x64_sysv.cc +196 -192
- package/src/koffi/src/abi_x64_sysv_asm.S +1 -31
- package/src/koffi/src/abi_x64_win.cc +188 -172
- package/src/koffi/src/abi_x64_win_asm.S +1 -19
- package/src/koffi/src/abi_x64_win_asm.asm +1 -21
- package/src/koffi/src/abi_x86.cc +224 -189
- package/src/koffi/src/abi_x86_asm.S +6 -25
- package/src/koffi/src/abi_x86_asm.asm +9 -22
- package/src/koffi/src/call.cc +246 -428
- package/src/koffi/src/call.hh +9 -8
- package/src/koffi/src/ffi.cc +140 -87
- package/src/koffi/src/ffi.hh +12 -58
- package/src/koffi/src/primitives.inc +39 -0
- package/src/koffi/src/trampolines/armasm.inc +0 -32770
- package/src/koffi/src/trampolines/gnu.inc +0 -24578
- package/src/koffi/src/trampolines/masm32.inc +0 -32770
- package/src/koffi/src/trampolines/masm64.inc +0 -32770
- package/src/koffi/src/trampolines/prototypes.inc +16385 -16385
- package/src/koffi/src/util.cc +149 -107
- package/src/koffi/src/util.hh +76 -40
|
@@ -52,8 +52,6 @@ extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_va
|
|
|
52
52
|
uint8_t *old_sp, Span<uint8_t> *new_stack,
|
|
53
53
|
napi_value (*call)(Napi::Function *func, size_t argc, napi_value *argv));
|
|
54
54
|
|
|
55
|
-
#include "trampolines/prototypes.inc"
|
|
56
|
-
|
|
57
55
|
static HfaInfo IsHFA(const TypeInfo *type)
|
|
58
56
|
{
|
|
59
57
|
bool float32 = false;
|
|
@@ -249,22 +247,45 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
|
249
247
|
|
|
250
248
|
bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
251
249
|
{
|
|
252
|
-
uint64_t *
|
|
253
|
-
uint64_t *
|
|
254
|
-
uint64_t *
|
|
250
|
+
uint64_t *gpr_ptr = AllocStack<uint64_t>(17 * 8 + func->args_size);
|
|
251
|
+
uint64_t *vec_ptr = gpr_ptr + 9;
|
|
252
|
+
uint64_t *args_ptr = gpr_ptr + 17;
|
|
255
253
|
|
|
256
|
-
|
|
257
|
-
if (!AllocStack(func->args_size, 16, &args_ptr)) [[unlikely]]
|
|
258
|
-
return false;
|
|
259
|
-
if (!AllocStack(8 * 8, 8, &vec_ptr)) [[unlikely]]
|
|
260
|
-
return false;
|
|
261
|
-
if (!AllocStack(9 * 8, 8, &gpr_ptr)) [[unlikely]]
|
|
254
|
+
if (!gpr_ptr) [[unlikely]]
|
|
262
255
|
return false;
|
|
263
256
|
if (func->ret.use_memory) {
|
|
264
257
|
return_ptr = AllocHeap(func->ret.type->size, 16);
|
|
265
258
|
gpr_ptr[8] = (uint64_t)return_ptr;
|
|
266
259
|
}
|
|
267
260
|
|
|
261
|
+
Size i = -1;
|
|
262
|
+
|
|
263
|
+
#if defined(__GNUC__) || defined(__clang__)
|
|
264
|
+
static const void *const DispatchTable[] = {
|
|
265
|
+
#define PRIMITIVE(Name) && Name,
|
|
266
|
+
#include "primitives.inc"
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
#define LOOP
|
|
270
|
+
#define CASE(Primitive) \
|
|
271
|
+
do { \
|
|
272
|
+
PrimitiveKind next = func->primitives[++i]; \
|
|
273
|
+
goto *DispatchTable[(int)next]; \
|
|
274
|
+
} while (false); \
|
|
275
|
+
Primitive:
|
|
276
|
+
#define OR(Primitive) \
|
|
277
|
+
Primitive:
|
|
278
|
+
#else
|
|
279
|
+
#define LOOP \
|
|
280
|
+
while (++i < func->parameters.len) \
|
|
281
|
+
switch (func->primitives[i])
|
|
282
|
+
#define CASE(Primitive) \
|
|
283
|
+
break; \
|
|
284
|
+
case PrimitiveKind::Primitive:
|
|
285
|
+
#define OR(Primitive) \
|
|
286
|
+
case PrimitiveKind::Primitive:
|
|
287
|
+
#endif
|
|
288
|
+
|
|
268
289
|
#if defined(_M_ARM64EC)
|
|
269
290
|
if (func->variadic) {
|
|
270
291
|
gpr_ptr[4] = (uint64_t)args_ptr;
|
|
@@ -280,13 +301,15 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
280
301
|
#if defined(__APPLE__)
|
|
281
302
|
#define PUSH_INTEGER(CType) \
|
|
282
303
|
do { \
|
|
283
|
-
|
|
304
|
+
const ParameterInfo ¶m = func->parameters[i]; \
|
|
305
|
+
Napi::Value value = info[param.offset]; \
|
|
306
|
+
\
|
|
307
|
+
CType v; \
|
|
308
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
284
309
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
285
310
|
return false; \
|
|
286
311
|
} \
|
|
287
312
|
\
|
|
288
|
-
CType v = GetNumber<CType>(value); \
|
|
289
|
-
\
|
|
290
313
|
if (param.gpr_count) [[likely]] { \
|
|
291
314
|
*(gpr_ptr++) = (uint64_t)v; \
|
|
292
315
|
} else { \
|
|
@@ -297,13 +320,15 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
297
320
|
} while (false)
|
|
298
321
|
#define PUSH_INTEGER_SWAP(CType) \
|
|
299
322
|
do { \
|
|
300
|
-
|
|
323
|
+
const ParameterInfo ¶m = func->parameters[i]; \
|
|
324
|
+
Napi::Value value = info[param.offset]; \
|
|
325
|
+
\
|
|
326
|
+
CType v; \
|
|
327
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
301
328
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
302
329
|
return false; \
|
|
303
330
|
} \
|
|
304
331
|
\
|
|
305
|
-
CType v = GetNumber<CType>(value); \
|
|
306
|
-
\
|
|
307
332
|
if (param.gpr_count) [[likely]] { \
|
|
308
333
|
*(gpr_ptr++) = (uint64_t)ReverseBytes(v); \
|
|
309
334
|
} else { \
|
|
@@ -315,227 +340,259 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
315
340
|
#else
|
|
316
341
|
#define PUSH_INTEGER(CType) \
|
|
317
342
|
do { \
|
|
318
|
-
|
|
343
|
+
const ParameterInfo ¶m = func->parameters[i]; \
|
|
344
|
+
Napi::Value value = info[param.offset]; \
|
|
345
|
+
\
|
|
346
|
+
CType v; \
|
|
347
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
319
348
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
320
349
|
return false; \
|
|
321
350
|
} \
|
|
322
351
|
\
|
|
323
|
-
CType v = GetNumber<CType>(value); \
|
|
324
352
|
*((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint64_t)v; \
|
|
325
353
|
} while (false)
|
|
326
354
|
#define PUSH_INTEGER_SWAP(CType) \
|
|
327
355
|
do { \
|
|
328
|
-
|
|
356
|
+
const ParameterInfo ¶m = func->parameters[i]; \
|
|
357
|
+
Napi::Value value = info[param.offset]; \
|
|
358
|
+
\
|
|
359
|
+
CType v; \
|
|
360
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
329
361
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
330
362
|
return false; \
|
|
331
363
|
} \
|
|
332
364
|
\
|
|
333
|
-
CType v = GetNumber<CType>(value); \
|
|
334
365
|
*((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint64_t)ReverseBytes(v); \
|
|
335
366
|
} while (false)
|
|
336
367
|
#endif
|
|
337
368
|
|
|
338
369
|
// Push arguments
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
K_ASSERT(param.directions >= 1 && param.directions <= 3);
|
|
370
|
+
LOOP {
|
|
371
|
+
CASE(Void) { K_UNREACHABLE(); };
|
|
342
372
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
case PrimitiveKind::Void: { K_UNREACHABLE(); } break;
|
|
347
|
-
|
|
348
|
-
case PrimitiveKind::Bool: {
|
|
349
|
-
if (!value.IsBoolean()) [[unlikely]] {
|
|
350
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
|
|
351
|
-
return false;
|
|
352
|
-
}
|
|
373
|
+
CASE(Bool) {
|
|
374
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
375
|
+
Napi::Value value = info[param.offset];
|
|
353
376
|
|
|
354
|
-
|
|
377
|
+
bool b;
|
|
378
|
+
if (napi_get_value_bool(env, value, &b) != napi_ok) [[unlikely]] {
|
|
379
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
|
|
380
|
+
return false;
|
|
381
|
+
}
|
|
355
382
|
|
|
356
383
|
#if defined(__APPLE__)
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
384
|
+
if (param.gpr_count) [[likely]] {
|
|
385
|
+
*(gpr_ptr++) = (uint64_t)b;
|
|
386
|
+
} else {
|
|
387
|
+
*(uint8_t *)args_ptr = b;
|
|
388
|
+
args_ptr = (uint64_t *)((uint8_t *)args_ptr + 1);
|
|
389
|
+
}
|
|
363
390
|
#else
|
|
364
|
-
|
|
391
|
+
*((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint64_t)b;
|
|
365
392
|
#endif
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
CASE(Int8) { PUSH_INTEGER(int8_t); };
|
|
396
|
+
CASE(UInt8) { PUSH_INTEGER(uint8_t); };
|
|
397
|
+
CASE(Int16) { PUSH_INTEGER(int16_t); };
|
|
398
|
+
CASE(Int16S) { PUSH_INTEGER_SWAP(int16_t); };
|
|
399
|
+
CASE(UInt16) { PUSH_INTEGER(uint16_t); };
|
|
400
|
+
CASE(UInt16S) { PUSH_INTEGER_SWAP(uint16_t); };
|
|
401
|
+
CASE(Int32) { PUSH_INTEGER(int32_t); };
|
|
402
|
+
CASE(Int32S) { PUSH_INTEGER_SWAP(int32_t); };
|
|
403
|
+
CASE(UInt32) { PUSH_INTEGER(uint32_t); };
|
|
404
|
+
CASE(UInt32S) { PUSH_INTEGER_SWAP(uint32_t); };
|
|
405
|
+
CASE(Int64) { PUSH_INTEGER(int64_t); };
|
|
406
|
+
CASE(Int64S) { PUSH_INTEGER_SWAP(int64_t); };
|
|
407
|
+
CASE(UInt64) { PUSH_INTEGER(uint64_t); };
|
|
408
|
+
CASE(UInt64S) { PUSH_INTEGER_SWAP(uint64_t); };
|
|
409
|
+
|
|
410
|
+
CASE(String) {
|
|
411
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
412
|
+
Napi::Value value = info[param.offset];
|
|
413
|
+
|
|
414
|
+
const char *str;
|
|
415
|
+
if (!PushString(value, param.directions, &str)) [[unlikely]]
|
|
416
|
+
return false;
|
|
385
417
|
|
|
386
418
|
#if defined(__APPLE__)
|
|
387
|
-
|
|
419
|
+
args_ptr = param.gpr_count ? args_ptr : AlignUp(args_ptr, 8);
|
|
388
420
|
#endif
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
421
|
+
*(const char **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str;
|
|
422
|
+
};
|
|
423
|
+
CASE(String16) {
|
|
424
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
425
|
+
Napi::Value value = info[param.offset];
|
|
426
|
+
|
|
427
|
+
const char16_t *str16;
|
|
428
|
+
if (!PushString16(value, param.directions, &str16)) [[unlikely]]
|
|
429
|
+
return false;
|
|
395
430
|
|
|
396
431
|
#if defined(__APPLE__)
|
|
397
|
-
|
|
432
|
+
args_ptr = param.gpr_count ? args_ptr : AlignUp(args_ptr, 8);
|
|
398
433
|
#endif
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
434
|
+
*(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str16;
|
|
435
|
+
};
|
|
436
|
+
CASE(String32) {
|
|
437
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
438
|
+
Napi::Value value = info[param.offset];
|
|
439
|
+
|
|
440
|
+
const char32_t *str32;
|
|
441
|
+
if (!PushString32(value, param.directions, &str32)) [[unlikely]]
|
|
442
|
+
return false;
|
|
405
443
|
|
|
406
444
|
#if defined(__APPLE__)
|
|
407
|
-
|
|
445
|
+
args_ptr = param.gpr_count ? args_ptr : AlignUp(args_ptr, 8);
|
|
408
446
|
#endif
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
447
|
+
*(const char32_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str32;
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
CASE(Pointer) {
|
|
451
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
452
|
+
Napi::Value value = info[param.offset];
|
|
453
|
+
|
|
454
|
+
void *ptr;
|
|
455
|
+
if (!PushPointer(value, param.type, param.directions, &ptr)) [[unlikely]]
|
|
456
|
+
return false;
|
|
415
457
|
|
|
416
458
|
#if defined(__APPLE__)
|
|
417
|
-
|
|
459
|
+
args_ptr = param.gpr_count ? args_ptr : AlignUp(args_ptr, 8);
|
|
418
460
|
#endif
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
case PrimitiveKind::Record:
|
|
422
|
-
case PrimitiveKind::Union: {
|
|
423
|
-
if (!IsObject(value)) [[unlikely]] {
|
|
424
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
425
|
-
return false;
|
|
426
|
-
}
|
|
461
|
+
*(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
|
|
462
|
+
};
|
|
427
463
|
|
|
428
|
-
|
|
464
|
+
CASE(Record) OR(Union) {
|
|
465
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
466
|
+
Napi::Value value = info[param.offset];
|
|
429
467
|
|
|
430
|
-
|
|
431
|
-
|
|
468
|
+
if (!IsObject(value)) [[unlikely]] {
|
|
469
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
470
|
+
return false;
|
|
471
|
+
}
|
|
432
472
|
|
|
433
|
-
|
|
434
|
-
return false;
|
|
435
|
-
ExpandFloats(ptr, param.vec_count, param.vec_bytes);
|
|
473
|
+
Napi::Object obj = value.As<Napi::Object>();
|
|
436
474
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
if (param.gpr_count) {
|
|
440
|
-
K_ASSERT(param.type->align <= 8);
|
|
475
|
+
if (param.vec_count) { // HFA
|
|
476
|
+
uint8_t *ptr = (uint8_t *)vec_ptr;
|
|
441
477
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
478
|
+
if (!PushObject(obj, param.type, ptr))
|
|
479
|
+
return false;
|
|
480
|
+
ExpandFloats(ptr, param.vec_count, param.vec_bytes);
|
|
481
|
+
|
|
482
|
+
vec_ptr += param.vec_count;
|
|
483
|
+
} else if (!param.use_memory) {
|
|
484
|
+
if (param.gpr_count) {
|
|
485
|
+
K_ASSERT(param.type->align <= 8);
|
|
486
|
+
|
|
487
|
+
if (!PushObject(obj, param.type, (uint8_t *)gpr_ptr))
|
|
488
|
+
return false;
|
|
489
|
+
gpr_ptr += param.gpr_count;
|
|
490
|
+
} else if (param.type->size) {
|
|
446
491
|
#if defined(__APPLE__)
|
|
447
|
-
|
|
492
|
+
args_ptr = AlignUp(args_ptr, 8);
|
|
448
493
|
#endif
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
494
|
+
if (!PushObject(obj, param.type, (uint8_t *)args_ptr))
|
|
495
|
+
return false;
|
|
496
|
+
args_ptr += (param.type->size + 7) / 8;
|
|
497
|
+
}
|
|
498
|
+
} else {
|
|
499
|
+
uint8_t *ptr = AllocHeap(param.type->size, 16);
|
|
455
500
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
501
|
+
if (param.gpr_count) {
|
|
502
|
+
K_ASSERT(param.gpr_count == 1);
|
|
503
|
+
K_ASSERT(param.vec_count == 0);
|
|
459
504
|
|
|
460
|
-
|
|
461
|
-
|
|
505
|
+
*(uint8_t **)(gpr_ptr++) = ptr;
|
|
506
|
+
} else {
|
|
462
507
|
#if defined(__APPLE__)
|
|
463
|
-
|
|
508
|
+
args_ptr = AlignUp(args_ptr, 8);
|
|
464
509
|
#endif
|
|
465
|
-
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
if (!PushObject(obj, param.type, ptr))
|
|
469
|
-
return false;
|
|
510
|
+
*(uint8_t **)(args_ptr++) = ptr;
|
|
470
511
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
case PrimitiveKind::Float32: {
|
|
474
|
-
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
475
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
512
|
+
|
|
513
|
+
if (!PushObject(obj, param.type, ptr))
|
|
476
514
|
return false;
|
|
477
|
-
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
CASE(Array) { K_UNREACHABLE(); };
|
|
478
518
|
|
|
479
|
-
|
|
519
|
+
CASE(Float32) {
|
|
520
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
521
|
+
Napi::Value value = info[param.offset];
|
|
480
522
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
523
|
+
float f;
|
|
524
|
+
if (!TryNumber(value, &f)) [[unlikely]] {
|
|
525
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
526
|
+
return false;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
if (param.vec_count) [[likely]] {
|
|
530
|
+
memset((uint8_t *)vec_ptr + 4, 0, 4);
|
|
531
|
+
*(float *)(vec_ptr++) = f;
|
|
484
532
|
#if defined(_WIN32)
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
533
|
+
} else if (param.gpr_count) {
|
|
534
|
+
memset((uint8_t *)gpr_ptr + 4, 0, 4);
|
|
535
|
+
*(float *)(gpr_ptr++) = f;
|
|
488
536
|
#endif
|
|
489
|
-
|
|
537
|
+
} else {
|
|
490
538
|
#if defined(__APPLE__)
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
539
|
+
args_ptr = AlignUp(args_ptr, 4);
|
|
540
|
+
*(float *)args_ptr = f;
|
|
541
|
+
args_ptr = (uint64_t *)((uint8_t *)args_ptr + 4);
|
|
494
542
|
#else
|
|
495
|
-
|
|
496
|
-
|
|
543
|
+
memset((uint8_t *)args_ptr + 4, 0, 4);
|
|
544
|
+
*(float *)(args_ptr++) = f;
|
|
497
545
|
#endif
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
return false;
|
|
504
|
-
}
|
|
546
|
+
}
|
|
547
|
+
};
|
|
548
|
+
CASE(Float64) {
|
|
549
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
550
|
+
Napi::Value value = info[param.offset];
|
|
505
551
|
|
|
506
|
-
|
|
552
|
+
double d;
|
|
553
|
+
if (!TryNumber(value, &d)) [[unlikely]] {
|
|
554
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
555
|
+
return false;
|
|
556
|
+
}
|
|
507
557
|
|
|
508
|
-
|
|
509
|
-
|
|
558
|
+
if (param.vec_count) [[likely]] {
|
|
559
|
+
*(double *)(vec_ptr++) = d;
|
|
510
560
|
#if defined(_WIN32)
|
|
511
|
-
|
|
512
|
-
|
|
561
|
+
} else if (param.gpr_count) {
|
|
562
|
+
*(double *)(gpr_ptr++) = d;
|
|
513
563
|
#endif
|
|
514
|
-
|
|
564
|
+
} else {
|
|
515
565
|
#if defined(__APPLE__)
|
|
516
|
-
|
|
566
|
+
args_ptr = AlignUp(args_ptr, 8);
|
|
517
567
|
#endif
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
568
|
+
*(double *)(args_ptr++) = d;
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
CASE(Callback) {
|
|
573
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
574
|
+
Napi::Value value = info[param.offset];
|
|
575
|
+
|
|
576
|
+
void *ptr;
|
|
577
|
+
if (!PushCallback(value, param.type, &ptr)) [[unlikely]]
|
|
578
|
+
return false;
|
|
525
579
|
|
|
526
580
|
#if defined(__APPLE__)
|
|
527
|
-
|
|
581
|
+
args_ptr = param.gpr_count ? args_ptr : AlignUp(args_ptr, 8);
|
|
528
582
|
#endif
|
|
529
|
-
|
|
530
|
-
|
|
583
|
+
*(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
|
|
584
|
+
};
|
|
531
585
|
|
|
532
|
-
|
|
533
|
-
}
|
|
586
|
+
CASE(Prototype) { /* End loop */ };
|
|
534
587
|
}
|
|
535
588
|
|
|
536
589
|
#undef PUSH_INTEGER_SWAP
|
|
537
590
|
#undef PUSH_INTEGER
|
|
538
591
|
|
|
592
|
+
#undef OR
|
|
593
|
+
#undef CASE
|
|
594
|
+
#undef LOOP
|
|
595
|
+
|
|
539
596
|
new_sp = mem->stack.end();
|
|
540
597
|
|
|
541
598
|
return true;
|
|
@@ -653,17 +710,8 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
653
710
|
case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
|
|
654
711
|
case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
|
|
655
712
|
case PrimitiveKind::String32: return result.ptr ? MakeStringFromUTF32(env, (const char32_t *)result.ptr) : env.Null();
|
|
656
|
-
case PrimitiveKind::Pointer:
|
|
657
|
-
case PrimitiveKind::Callback:
|
|
658
|
-
if (result.ptr) {
|
|
659
|
-
Napi::External<void> external = Napi::External<void>::New(env, result.ptr);
|
|
660
|
-
SetValueTag(external, func->ret.type->ref.marker);
|
|
661
|
-
|
|
662
|
-
return external;
|
|
663
|
-
} else {
|
|
664
|
-
return env.Null();
|
|
665
|
-
}
|
|
666
|
-
} break;
|
|
713
|
+
case PrimitiveKind::Pointer: return result.ptr ? WrapPointer(env, func->ret.type->ref.type, result.ptr) : env.Null();
|
|
714
|
+
case PrimitiveKind::Callback: return result.ptr ? WrapCallback(env, func->ret.type->ref.type, result.ptr) : env.Null();
|
|
667
715
|
case PrimitiveKind::Record:
|
|
668
716
|
case PrimitiveKind::Union: {
|
|
669
717
|
if (func->ret.vec_count) { // HFA
|
|
@@ -1026,22 +1074,29 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
1026
1074
|
Napi::Value arg = str32 ? MakeStringFromUTF32(env, str32) : env.Null();
|
|
1027
1075
|
arguments.Append(arg);
|
|
1028
1076
|
} break;
|
|
1029
|
-
case PrimitiveKind::Pointer:
|
|
1030
|
-
case PrimitiveKind::Callback: {
|
|
1077
|
+
case PrimitiveKind::Pointer: {
|
|
1031
1078
|
#if defined(__APPLE__)
|
|
1032
1079
|
args_ptr = AlignUp(args_ptr, 8);
|
|
1033
1080
|
#endif
|
|
1034
1081
|
|
|
1035
1082
|
void *ptr2 = *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
1036
1083
|
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
SetValueTag(external, param.type->ref.marker);
|
|
1084
|
+
Napi::Value p = ptr2 ? WrapPointer(env, param.type->ref.type, ptr2) : env.Null();
|
|
1085
|
+
arguments.Append(p);
|
|
1040
1086
|
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
arguments.Append(env.Null());
|
|
1087
|
+
if (param.type->dispose) {
|
|
1088
|
+
param.type->dispose(env, param.type, ptr2);
|
|
1044
1089
|
}
|
|
1090
|
+
} break;
|
|
1091
|
+
case PrimitiveKind::Callback: {
|
|
1092
|
+
#if defined(__APPLE__)
|
|
1093
|
+
args_ptr = AlignUp(args_ptr, 8);
|
|
1094
|
+
#endif
|
|
1095
|
+
|
|
1096
|
+
void *ptr2 = *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
1097
|
+
|
|
1098
|
+
Napi::Value p = ptr2 ? WrapCallback(env, param.type->ref.type, ptr2) : env.Null();
|
|
1099
|
+
arguments.Append(p);
|
|
1045
1100
|
|
|
1046
1101
|
if (param.type->dispose) {
|
|
1047
1102
|
param.type->dispose(env, param.type, ptr2);
|
|
@@ -1148,22 +1203,22 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
1148
1203
|
|
|
1149
1204
|
#define RETURN_INTEGER(CType) \
|
|
1150
1205
|
do { \
|
|
1151
|
-
|
|
1206
|
+
CType v; \
|
|
1207
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
1152
1208
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
1153
1209
|
return; \
|
|
1154
1210
|
} \
|
|
1155
1211
|
\
|
|
1156
|
-
CType v = GetNumber<CType>(value); \
|
|
1157
1212
|
out_reg->x0 = (uint64_t)v; \
|
|
1158
1213
|
} while (false)
|
|
1159
1214
|
#define RETURN_INTEGER_SWAP(CType) \
|
|
1160
1215
|
do { \
|
|
1161
|
-
|
|
1216
|
+
CType v; \
|
|
1217
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
1162
1218
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
1163
1219
|
return; \
|
|
1164
1220
|
} \
|
|
1165
1221
|
\
|
|
1166
|
-
CType v = GetNumber<CType>(value); \
|
|
1167
1222
|
out_reg->x0 = (uint64_t)ReverseBytes(v); \
|
|
1168
1223
|
} while (false)
|
|
1169
1224
|
|
|
@@ -1171,12 +1226,12 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
1171
1226
|
switch (type->primitive) {
|
|
1172
1227
|
case PrimitiveKind::Void: {} break;
|
|
1173
1228
|
case PrimitiveKind::Bool: {
|
|
1174
|
-
|
|
1229
|
+
bool b;
|
|
1230
|
+
if (napi_get_value_bool(env, value, &b) != napi_ok) [[unlikely]] {
|
|
1175
1231
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
|
|
1176
1232
|
return;
|
|
1177
1233
|
}
|
|
1178
1234
|
|
|
1179
|
-
bool b = value.As<Napi::Boolean>();
|
|
1180
1235
|
out_reg->x0 = (uint64_t)b;
|
|
1181
1236
|
} break;
|
|
1182
1237
|
case PrimitiveKind::Int8: { RETURN_INTEGER(int8_t); } break;
|
|
@@ -1215,24 +1270,9 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
1215
1270
|
out_reg->x0 = (uint64_t)str32;
|
|
1216
1271
|
} break;
|
|
1217
1272
|
case PrimitiveKind::Pointer: {
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
if (CheckValueTag(value, type->ref.marker)) {
|
|
1221
|
-
ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
1222
|
-
} else if (IsObject(value) && (type->ref.type->primitive == PrimitiveKind::Record ||
|
|
1223
|
-
type->ref.type->primitive == PrimitiveKind::Union)) {
|
|
1224
|
-
Napi::Object obj = value.As<Napi::Object>();
|
|
1225
|
-
|
|
1226
|
-
ptr = AllocHeap(type->ref.type->size, 16);
|
|
1227
|
-
|
|
1228
|
-
if (!PushObject(obj, type->ref.type, ptr))
|
|
1229
|
-
return;
|
|
1230
|
-
} else if (IsNullOrUndefined(value)) {
|
|
1231
|
-
ptr = nullptr;
|
|
1232
|
-
} else {
|
|
1233
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected %2", GetValueType(instance, value), type->name);
|
|
1273
|
+
void *ptr;
|
|
1274
|
+
if (!PushPointer(value, type, 1, &ptr)) [[unlikely]]
|
|
1234
1275
|
return;
|
|
1235
|
-
}
|
|
1236
1276
|
|
|
1237
1277
|
out_reg->x0 = (uint64_t)ptr;
|
|
1238
1278
|
} break;
|
|
@@ -1260,42 +1300,30 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
1260
1300
|
} break;
|
|
1261
1301
|
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
1262
1302
|
case PrimitiveKind::Float32: {
|
|
1263
|
-
|
|
1303
|
+
float f;
|
|
1304
|
+
|
|
1305
|
+
if (!TryNumber(value, &f)) [[unlikely]] {
|
|
1264
1306
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
1265
1307
|
return;
|
|
1266
1308
|
}
|
|
1267
1309
|
|
|
1268
|
-
float f = GetNumber<float>(value);
|
|
1269
|
-
|
|
1270
1310
|
memset((uint8_t *)&out_reg->d0 + 4, 0, 4);
|
|
1271
1311
|
memcpy(&out_reg->d0, &f, 4);
|
|
1272
1312
|
} break;
|
|
1273
1313
|
case PrimitiveKind::Float64: {
|
|
1274
|
-
|
|
1314
|
+
double d;
|
|
1315
|
+
|
|
1316
|
+
if (!TryNumber(value, &d)) [[unlikely]] {
|
|
1275
1317
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
1276
1318
|
return;
|
|
1277
1319
|
}
|
|
1278
1320
|
|
|
1279
|
-
double d = GetNumber<double>(value);
|
|
1280
1321
|
out_reg->d0 = d;
|
|
1281
1322
|
} break;
|
|
1282
1323
|
case PrimitiveKind::Callback: {
|
|
1283
1324
|
void *ptr;
|
|
1284
|
-
|
|
1285
|
-
if (value.IsFunction()) {
|
|
1286
|
-
Napi::Function func2 = value.As<Napi::Function>();
|
|
1287
|
-
|
|
1288
|
-
ptr = ReserveTrampoline(type->ref.proto, func2);
|
|
1289
|
-
if (!ptr) [[unlikely]]
|
|
1290
|
-
return;
|
|
1291
|
-
} else if (CheckValueTag(value, type->ref.marker)) {
|
|
1292
|
-
ptr = value.As<Napi::External<void>>().Data();
|
|
1293
|
-
} else if (IsNullOrUndefined(value)) {
|
|
1294
|
-
ptr = nullptr;
|
|
1295
|
-
} else {
|
|
1296
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected %2", GetValueType(instance, value), type->name);
|
|
1325
|
+
if (!PushCallback(value, type, &ptr)) [[unlikely]]
|
|
1297
1326
|
return;
|
|
1298
|
-
}
|
|
1299
1327
|
|
|
1300
1328
|
out_reg->x0 = (uint64_t)ptr;
|
|
1301
1329
|
} break;
|
|
@@ -1309,12 +1337,6 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
1309
1337
|
err_guard.Disable();
|
|
1310
1338
|
}
|
|
1311
1339
|
|
|
1312
|
-
void *GetTrampoline(int16_t idx, const FunctionInfo *proto)
|
|
1313
|
-
{
|
|
1314
|
-
bool vec = proto->forward_fp || IsFloat(proto->ret.type);
|
|
1315
|
-
return Trampolines[idx][vec];
|
|
1316
|
-
}
|
|
1317
|
-
|
|
1318
1340
|
}
|
|
1319
1341
|
|
|
1320
1342
|
#endif
|