koffi 2.14.0-beta.3 → 2.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -1
- package/README.md +1 -1
- 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/doc/pages/index.md +43 -4
- package/doc/pages/input.md +66 -0
- package/doc/pages/platforms.md +8 -19
- package/doc/pages.ini +0 -7
- package/doc/static/perf_windows.png +0 -0
- package/index.d.ts +0 -1
- package/index.js +10 -9
- package/indirect.js +10 -9
- package/package.json +3 -2
- package/src/cnoke/src/builder.js +1 -2
- package/src/core/base/base.cc +815 -554
- package/src/core/base/base.hh +578 -450
- package/src/core/base/crc.inc +1 -1
- package/src/core/base/crc_gen.py +1 -1
- package/src/core/base/unicode.inc +1 -1
- package/src/core/base/unicode_gen.py +1 -1
- package/src/koffi/src/abi_arm32.cc +24 -24
- package/src/koffi/src/abi_arm64.cc +29 -29
- package/src/koffi/src/abi_riscv64.cc +27 -27
- package/src/koffi/src/abi_x64_sysv.cc +29 -29
- package/src/koffi/src/abi_x64_win.cc +20 -20
- package/src/koffi/src/abi_x86.cc +26 -26
- package/src/koffi/src/call.cc +83 -237
- package/src/koffi/src/call.hh +8 -8
- package/src/koffi/src/ffi.cc +71 -67
- package/src/koffi/src/ffi.hh +9 -9
- package/src/koffi/src/parser.cc +2 -2
- package/src/koffi/src/parser.hh +1 -1
- package/src/koffi/src/trampolines/prototypes.inc +1 -1
- package/src/koffi/src/util.cc +43 -43
- package/src/koffi/src/util.hh +5 -5
- package/src/koffi/src/win32.cc +5 -5
- package/src/koffi/src/win32.hh +1 -1
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
#include <napi.h>
|
|
30
30
|
|
|
31
|
-
namespace
|
|
31
|
+
namespace K {
|
|
32
32
|
|
|
33
33
|
enum class RegisterClass {
|
|
34
34
|
NoClass = 0, // Explicitly 0
|
|
@@ -99,7 +99,7 @@ static inline RegisterClass MergeClasses(RegisterClass cls1, RegisterClass cls2)
|
|
|
99
99
|
|
|
100
100
|
static Size ClassifyType(const TypeInfo *type, Size offset, Span<RegisterClass> classes)
|
|
101
101
|
{
|
|
102
|
-
|
|
102
|
+
K_ASSERT(classes.len > 0);
|
|
103
103
|
|
|
104
104
|
switch (type->primitive) {
|
|
105
105
|
case PrimitiveKind::Void: { return 0; } break;
|
|
@@ -178,10 +178,10 @@ static Size ClassifyType(const TypeInfo *type, Size offset, Span<RegisterClass>
|
|
|
178
178
|
return 1;
|
|
179
179
|
} break;
|
|
180
180
|
|
|
181
|
-
case PrimitiveKind::Prototype: {
|
|
181
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
|
|
184
|
+
K_UNREACHABLE();
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
static void AnalyseParameter(ParameterInfo *param, int gpr_avail, int xmm_avail)
|
|
@@ -200,7 +200,7 @@ static void AnalyseParameter(ParameterInfo *param, int gpr_avail, int xmm_avail)
|
|
|
200
200
|
int xmm_count = 0;
|
|
201
201
|
|
|
202
202
|
for (RegisterClass cls: classes) {
|
|
203
|
-
|
|
203
|
+
K_ASSERT(cls != RegisterClass::NoClass);
|
|
204
204
|
|
|
205
205
|
if (cls == RegisterClass::Memory) {
|
|
206
206
|
param->use_memory = true;
|
|
@@ -283,12 +283,12 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
283
283
|
// Push arguments
|
|
284
284
|
for (Size i = 0; i < func->parameters.len; i++) {
|
|
285
285
|
const ParameterInfo ¶m = func->parameters[i];
|
|
286
|
-
|
|
286
|
+
K_ASSERT(param.directions >= 1 && param.directions <= 3);
|
|
287
287
|
|
|
288
288
|
Napi::Value value = info[param.offset];
|
|
289
289
|
|
|
290
290
|
switch (param.type->primitive) {
|
|
291
|
-
case PrimitiveKind::Void: {
|
|
291
|
+
case PrimitiveKind::Void: { K_UNREACHABLE(); } break;
|
|
292
292
|
|
|
293
293
|
case PrimitiveKind::Bool: {
|
|
294
294
|
if (!value.IsBoolean()) [[unlikely]] {
|
|
@@ -351,7 +351,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
351
351
|
Napi::Object obj = value.As<Napi::Object>();
|
|
352
352
|
|
|
353
353
|
if (param.gpr_count || param.xmm_count) {
|
|
354
|
-
|
|
354
|
+
K_ASSERT(param.type->size <= 16);
|
|
355
355
|
|
|
356
356
|
uint64_t buf[2] = {};
|
|
357
357
|
if (!PushObject(obj, param.type, (uint8_t *)buf))
|
|
@@ -379,7 +379,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
379
379
|
args_ptr += (param.type->size + 7) / 8;
|
|
380
380
|
}
|
|
381
381
|
} break;
|
|
382
|
-
case PrimitiveKind::Array: {
|
|
382
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
383
383
|
case PrimitiveKind::Float32: {
|
|
384
384
|
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
385
385
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
@@ -409,7 +409,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
409
409
|
*(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
|
|
410
410
|
} break;
|
|
411
411
|
|
|
412
|
-
case PrimitiveKind::Prototype: {
|
|
412
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
413
413
|
}
|
|
414
414
|
}
|
|
415
415
|
|
|
@@ -457,23 +457,23 @@ void CallData::Execute(const FunctionInfo *func, void *native)
|
|
|
457
457
|
case PrimitiveKind::Union: {
|
|
458
458
|
if (func->ret.gpr_first && !func->ret.xmm_count) {
|
|
459
459
|
RaxRdxRet ret = PERFORM_CALL(GG);
|
|
460
|
-
memcpy(&result.buf, &ret,
|
|
460
|
+
memcpy(&result.buf, &ret, K_SIZE(ret));
|
|
461
461
|
} else if (func->ret.gpr_first) {
|
|
462
462
|
RaxXmm0Ret ret = PERFORM_CALL(GD);
|
|
463
|
-
memcpy(&result.buf, &ret,
|
|
463
|
+
memcpy(&result.buf, &ret, K_SIZE(ret));
|
|
464
464
|
} else if (func->ret.xmm_count == 2) {
|
|
465
465
|
Xmm0Xmm1Ret ret = PERFORM_CALL(DD);
|
|
466
|
-
memcpy(&result.buf, &ret,
|
|
466
|
+
memcpy(&result.buf, &ret, K_SIZE(ret));
|
|
467
467
|
} else {
|
|
468
468
|
Xmm0RaxRet ret = PERFORM_CALL(DG);
|
|
469
|
-
memcpy(&result.buf, &ret,
|
|
469
|
+
memcpy(&result.buf, &ret, K_SIZE(ret));
|
|
470
470
|
}
|
|
471
471
|
} break;
|
|
472
|
-
case PrimitiveKind::Array: {
|
|
472
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
473
473
|
case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
|
|
474
474
|
case PrimitiveKind::Float64: { result.d = PERFORM_CALL(DG).xmm0; } break;
|
|
475
475
|
|
|
476
|
-
case PrimitiveKind::Prototype: {
|
|
476
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
477
477
|
}
|
|
478
478
|
|
|
479
479
|
#undef PERFORM_CALL
|
|
@@ -481,7 +481,7 @@ void CallData::Execute(const FunctionInfo *func, void *native)
|
|
|
481
481
|
|
|
482
482
|
Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
483
483
|
{
|
|
484
|
-
|
|
484
|
+
K_DEFER {
|
|
485
485
|
PopOutArguments();
|
|
486
486
|
|
|
487
487
|
if (func->ret.type->dispose) {
|
|
@@ -528,14 +528,14 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
528
528
|
Napi::Object obj = DecodeObject(env, ptr, func->ret.type);
|
|
529
529
|
return obj;
|
|
530
530
|
} break;
|
|
531
|
-
case PrimitiveKind::Array: {
|
|
531
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
532
532
|
case PrimitiveKind::Float32: return Napi::Number::New(env, (double)result.f);
|
|
533
533
|
case PrimitiveKind::Float64: return Napi::Number::New(env, result.d);
|
|
534
534
|
|
|
535
|
-
case PrimitiveKind::Prototype: {
|
|
535
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
536
536
|
}
|
|
537
537
|
|
|
538
|
-
|
|
538
|
+
K_UNREACHABLE();
|
|
539
539
|
}
|
|
540
540
|
|
|
541
541
|
void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_stack, BackRegisters *out_reg)
|
|
@@ -555,7 +555,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
555
555
|
uint8_t *return_ptr = proto->ret.use_memory ? (uint8_t *)gpr_ptr[0] : nullptr;
|
|
556
556
|
gpr_ptr += proto->ret.use_memory;
|
|
557
557
|
|
|
558
|
-
|
|
558
|
+
K_DEFER_N(err_guard) { memset(out_reg, 0, K_SIZE(*out_reg)); };
|
|
559
559
|
|
|
560
560
|
if (trampoline.generation >= 0 && trampoline.generation != (int32_t)mem->generation) [[unlikely]] {
|
|
561
561
|
ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
|
|
@@ -569,10 +569,10 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
569
569
|
// Convert to JS arguments
|
|
570
570
|
for (Size i = 0; i < proto->parameters.len; i++) {
|
|
571
571
|
const ParameterInfo ¶m = proto->parameters[i];
|
|
572
|
-
|
|
572
|
+
K_ASSERT(param.directions >= 1 && param.directions <= 3);
|
|
573
573
|
|
|
574
574
|
switch (param.type->primitive) {
|
|
575
|
-
case PrimitiveKind::Void: {
|
|
575
|
+
case PrimitiveKind::Void: { K_UNREACHABLE(); } break;
|
|
576
576
|
|
|
577
577
|
case PrimitiveKind::Bool: {
|
|
578
578
|
bool b = *(bool *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
@@ -714,7 +714,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
714
714
|
case PrimitiveKind::Record:
|
|
715
715
|
case PrimitiveKind::Union: {
|
|
716
716
|
if (param.gpr_count || param.xmm_count) {
|
|
717
|
-
|
|
717
|
+
K_ASSERT(param.type->size <= 16);
|
|
718
718
|
|
|
719
719
|
uint64_t buf[2] = {};
|
|
720
720
|
|
|
@@ -745,7 +745,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
745
745
|
args_ptr += (param.type->size + 7) / 8;
|
|
746
746
|
}
|
|
747
747
|
} break;
|
|
748
|
-
case PrimitiveKind::Array: {
|
|
748
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
749
749
|
case PrimitiveKind::Float32: {
|
|
750
750
|
float f = *(float *)((param.xmm_count ? xmm_ptr : args_ptr)++);
|
|
751
751
|
|
|
@@ -759,7 +759,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
759
759
|
arguments.Append(arg);
|
|
760
760
|
} break;
|
|
761
761
|
|
|
762
|
-
case PrimitiveKind::Prototype: {
|
|
762
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
763
763
|
}
|
|
764
764
|
}
|
|
765
765
|
|
|
@@ -882,7 +882,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
882
882
|
return;
|
|
883
883
|
out_reg->rax = (uint64_t)return_ptr;
|
|
884
884
|
} else {
|
|
885
|
-
|
|
885
|
+
K_ASSERT(type->size <= 16);
|
|
886
886
|
|
|
887
887
|
uint8_t buf[16] = {};
|
|
888
888
|
if (!PushObject(obj, type, buf))
|
|
@@ -903,7 +903,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
903
903
|
}
|
|
904
904
|
}
|
|
905
905
|
} break;
|
|
906
|
-
case PrimitiveKind::Array: {
|
|
906
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
907
907
|
case PrimitiveKind::Float32: {
|
|
908
908
|
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
909
909
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
@@ -945,7 +945,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
945
945
|
out_reg->rax = (uint64_t)ptr;
|
|
946
946
|
} break;
|
|
947
947
|
|
|
948
|
-
case PrimitiveKind::Prototype: {
|
|
948
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
949
949
|
}
|
|
950
950
|
|
|
951
951
|
#undef RETURN_INTEGER_SWAP
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
|
|
30
30
|
#include <napi.h>
|
|
31
31
|
|
|
32
|
-
namespace
|
|
32
|
+
namespace K {
|
|
33
33
|
|
|
34
34
|
struct BackRegisters {
|
|
35
35
|
uint64_t rax;
|
|
@@ -99,12 +99,12 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
99
99
|
// Push arguments
|
|
100
100
|
for (Size i = 0; i < func->parameters.len; i++) {
|
|
101
101
|
const ParameterInfo ¶m = func->parameters[i];
|
|
102
|
-
|
|
102
|
+
K_ASSERT(param.directions >= 1 && param.directions <= 3);
|
|
103
103
|
|
|
104
104
|
Napi::Value value = info[param.offset];
|
|
105
105
|
|
|
106
106
|
switch (param.type->primitive) {
|
|
107
|
-
case PrimitiveKind::Void: {
|
|
107
|
+
case PrimitiveKind::Void: { K_UNREACHABLE(); } break;
|
|
108
108
|
|
|
109
109
|
case PrimitiveKind::Bool: {
|
|
110
110
|
if (!value.IsBoolean()) [[unlikely]] {
|
|
@@ -177,7 +177,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
177
177
|
if (!PushObject(obj, param.type, ptr))
|
|
178
178
|
return false;
|
|
179
179
|
} break;
|
|
180
|
-
case PrimitiveKind::Array: {
|
|
180
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
181
181
|
case PrimitiveKind::Float32: {
|
|
182
182
|
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
183
183
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
@@ -206,7 +206,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
206
206
|
*(void **)(args_ptr++) = ptr;
|
|
207
207
|
} break;
|
|
208
208
|
|
|
209
|
-
case PrimitiveKind::Prototype: {
|
|
209
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
212
|
|
|
@@ -223,7 +223,7 @@ void CallData::Execute(const FunctionInfo *func, void *native)
|
|
|
223
223
|
TEB *teb = GetTEB();
|
|
224
224
|
|
|
225
225
|
// Restore previous stack limits at the end
|
|
226
|
-
|
|
226
|
+
K_DEFER_C(exception_list = teb->ExceptionList,
|
|
227
227
|
base = teb->StackBase,
|
|
228
228
|
limit = teb->StackLimit,
|
|
229
229
|
dealloc = teb->DeallocationStack,
|
|
@@ -280,11 +280,11 @@ void CallData::Execute(const FunctionInfo *func, void *native)
|
|
|
280
280
|
case PrimitiveKind::Record:
|
|
281
281
|
case PrimitiveKind::Union:
|
|
282
282
|
case PrimitiveKind::Callback: { result.u64 = PERFORM_CALL(G); } break;
|
|
283
|
-
case PrimitiveKind::Array: {
|
|
283
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
284
284
|
case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
|
|
285
285
|
case PrimitiveKind::Float64: { result.d = PERFORM_CALL(D); } break;
|
|
286
286
|
|
|
287
|
-
case PrimitiveKind::Prototype: {
|
|
287
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
288
288
|
}
|
|
289
289
|
|
|
290
290
|
#undef PERFORM_CALL
|
|
@@ -292,7 +292,7 @@ void CallData::Execute(const FunctionInfo *func, void *native)
|
|
|
292
292
|
|
|
293
293
|
Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
294
294
|
{
|
|
295
|
-
|
|
295
|
+
K_DEFER {
|
|
296
296
|
PopOutArguments();
|
|
297
297
|
|
|
298
298
|
if (func->ret.type->dispose) {
|
|
@@ -339,14 +339,14 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
339
339
|
Napi::Object obj = DecodeObject(env, ptr, func->ret.type);
|
|
340
340
|
return obj;
|
|
341
341
|
} break;
|
|
342
|
-
case PrimitiveKind::Array: {
|
|
342
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
343
343
|
case PrimitiveKind::Float32: return Napi::Number::New(env, (double)result.f);
|
|
344
344
|
case PrimitiveKind::Float64: return Napi::Number::New(env, result.d);
|
|
345
345
|
|
|
346
|
-
case PrimitiveKind::Prototype: {
|
|
346
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
347
347
|
}
|
|
348
348
|
|
|
349
|
-
|
|
349
|
+
K_UNREACHABLE();
|
|
350
350
|
}
|
|
351
351
|
|
|
352
352
|
void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_stack, BackRegisters *out_reg)
|
|
@@ -357,7 +357,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
357
357
|
TEB *teb = GetTEB();
|
|
358
358
|
|
|
359
359
|
// Restore previous stack limits at the end
|
|
360
|
-
|
|
360
|
+
K_DEFER_C(base = teb->StackBase,
|
|
361
361
|
limit = teb->StackLimit,
|
|
362
362
|
dealloc = teb->DeallocationStack) {
|
|
363
363
|
teb->StackBase = base;
|
|
@@ -381,7 +381,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
381
381
|
|
|
382
382
|
uint8_t *return_ptr = !proto->ret.regular ? (uint8_t *)gpr_ptr[0] : nullptr;
|
|
383
383
|
|
|
384
|
-
|
|
384
|
+
K_DEFER_N(err_guard) { memset(out_reg, 0, K_SIZE(*out_reg)); };
|
|
385
385
|
|
|
386
386
|
if (trampoline.generation >= 0 && trampoline.generation != (int32_t)mem->generation) [[unlikely]] {
|
|
387
387
|
ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
|
|
@@ -395,10 +395,10 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
395
395
|
// Convert to JS arguments
|
|
396
396
|
for (Size i = 0, j = !!return_ptr; i < proto->parameters.len; i++, j++) {
|
|
397
397
|
const ParameterInfo ¶m = proto->parameters[i];
|
|
398
|
-
|
|
398
|
+
K_ASSERT(param.directions >= 1 && param.directions <= 3);
|
|
399
399
|
|
|
400
400
|
switch (param.type->primitive) {
|
|
401
|
-
case PrimitiveKind::Void: {
|
|
401
|
+
case PrimitiveKind::Void: { K_UNREACHABLE(); } break;
|
|
402
402
|
|
|
403
403
|
case PrimitiveKind::Bool: {
|
|
404
404
|
bool b = *(bool *)(j < 4 ? gpr_ptr + j : args_ptr);
|
|
@@ -569,7 +569,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
569
569
|
Napi::Object obj2 = DecodeObject(env, ptr, param.type);
|
|
570
570
|
arguments.Append(obj2);
|
|
571
571
|
} break;
|
|
572
|
-
case PrimitiveKind::Array: {
|
|
572
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
573
573
|
case PrimitiveKind::Float32: {
|
|
574
574
|
float f = *(float *)(j < 4 ? xmm_ptr + j : args_ptr);
|
|
575
575
|
args_ptr += (j >= 4);
|
|
@@ -585,7 +585,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
585
585
|
arguments.Append(arg);
|
|
586
586
|
} break;
|
|
587
587
|
|
|
588
|
-
case PrimitiveKind::Prototype: {
|
|
588
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
589
589
|
}
|
|
590
590
|
}
|
|
591
591
|
|
|
@@ -710,7 +710,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
710
710
|
PushObject(obj, type, (uint8_t *)&out_reg->rax);
|
|
711
711
|
}
|
|
712
712
|
} break;
|
|
713
|
-
case PrimitiveKind::Array: {
|
|
713
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
714
714
|
case PrimitiveKind::Float32: {
|
|
715
715
|
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
716
716
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
@@ -752,7 +752,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
752
752
|
out_reg->rax = (uint64_t)ptr;
|
|
753
753
|
} break;
|
|
754
754
|
|
|
755
|
-
case PrimitiveKind::Prototype: {
|
|
755
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
756
756
|
}
|
|
757
757
|
|
|
758
758
|
#undef RETURN_INTEGER_SWAP
|
package/src/koffi/src/abi_x86.cc
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
|
|
32
32
|
#include <napi.h>
|
|
33
33
|
|
|
34
|
-
namespace
|
|
34
|
+
namespace K {
|
|
35
35
|
|
|
36
36
|
struct BackRegisters {
|
|
37
37
|
uint32_t eax;
|
|
@@ -112,16 +112,16 @@ bool AnalyseFunction(Napi::Env env, InstanceData *instance, FunctionInfo *func)
|
|
|
112
112
|
func->decorated_name = Fmt(&instance->str_alloc, "_%1", func->name).ptr;
|
|
113
113
|
} break;
|
|
114
114
|
case CallConvention::Stdcall: {
|
|
115
|
-
|
|
115
|
+
K_ASSERT(!func->variadic);
|
|
116
116
|
func->decorated_name = Fmt(&instance->str_alloc, "_%1@%2", func->name, params_size).ptr;
|
|
117
117
|
} break;
|
|
118
118
|
case CallConvention::Fastcall: {
|
|
119
|
-
|
|
119
|
+
K_ASSERT(!func->variadic);
|
|
120
120
|
func->decorated_name = Fmt(&instance->str_alloc, "@%1@%2", func->name, params_size).ptr;
|
|
121
121
|
func->args_size += 16;
|
|
122
122
|
} break;
|
|
123
123
|
case CallConvention::Thiscall: {
|
|
124
|
-
|
|
124
|
+
K_ASSERT(!func->variadic);
|
|
125
125
|
func->args_size += 16;
|
|
126
126
|
} break;
|
|
127
127
|
}
|
|
@@ -194,12 +194,12 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
194
194
|
// Push arguments
|
|
195
195
|
for (Size i = 0; i < func->parameters.len; i++) {
|
|
196
196
|
const ParameterInfo ¶m = func->parameters[i];
|
|
197
|
-
|
|
197
|
+
K_ASSERT(param.directions >= 1 && param.directions <= 3);
|
|
198
198
|
|
|
199
199
|
Napi::Value value = info[param.offset];
|
|
200
200
|
|
|
201
201
|
switch (param.type->primitive) {
|
|
202
|
-
case PrimitiveKind::Void: {
|
|
202
|
+
case PrimitiveKind::Void: { K_UNREACHABLE(); } break;
|
|
203
203
|
|
|
204
204
|
case PrimitiveKind::Bool: {
|
|
205
205
|
if (!value.IsBoolean()) [[unlikely]] {
|
|
@@ -272,7 +272,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
272
272
|
args_ptr = (uint32_t *)AlignUp(ptr + param.type->size, 4);
|
|
273
273
|
}
|
|
274
274
|
} break;
|
|
275
|
-
case PrimitiveKind::Array: {
|
|
275
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
276
276
|
case PrimitiveKind::Float32: {
|
|
277
277
|
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
278
278
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
@@ -300,7 +300,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
300
300
|
*(void **)((param.fast ? fast_ptr : args_ptr)++) = ptr;
|
|
301
301
|
} break;
|
|
302
302
|
|
|
303
|
-
case PrimitiveKind::Prototype: {
|
|
303
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
304
304
|
}
|
|
305
305
|
}
|
|
306
306
|
|
|
@@ -320,7 +320,7 @@ void CallData::Execute(const FunctionInfo *func, void *native)
|
|
|
320
320
|
TEB *teb = GetTEB();
|
|
321
321
|
|
|
322
322
|
// Restore previous stack limits at the end
|
|
323
|
-
|
|
323
|
+
K_DEFER_C(exception_list = teb->ExceptionList,
|
|
324
324
|
base = teb->StackBase,
|
|
325
325
|
limit = teb->StackLimit,
|
|
326
326
|
dealloc = teb->DeallocationStack,
|
|
@@ -387,18 +387,18 @@ void CallData::Execute(const FunctionInfo *func, void *native)
|
|
|
387
387
|
} else if (func->ret.fast == 2) {
|
|
388
388
|
result.d = PERFORM_CALL(D);
|
|
389
389
|
} else {
|
|
390
|
-
|
|
390
|
+
K_UNREACHABLE();
|
|
391
391
|
}
|
|
392
392
|
} break;
|
|
393
393
|
#else
|
|
394
394
|
case PrimitiveKind::Record:
|
|
395
395
|
case PrimitiveKind::Union: { result.u64 = PERFORM_CALL(G); } break;
|
|
396
396
|
#endif
|
|
397
|
-
case PrimitiveKind::Array: {
|
|
397
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
398
398
|
case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
|
|
399
399
|
case PrimitiveKind::Float64: { result.d = PERFORM_CALL(D); } break;
|
|
400
400
|
|
|
401
|
-
case PrimitiveKind::Prototype: {
|
|
401
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
402
402
|
}
|
|
403
403
|
|
|
404
404
|
#undef PERFORM_CALL
|
|
@@ -406,7 +406,7 @@ void CallData::Execute(const FunctionInfo *func, void *native)
|
|
|
406
406
|
|
|
407
407
|
Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
408
408
|
{
|
|
409
|
-
|
|
409
|
+
K_DEFER {
|
|
410
410
|
PopOutArguments();
|
|
411
411
|
|
|
412
412
|
if (func->ret.type->dispose) {
|
|
@@ -453,14 +453,14 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
453
453
|
Napi::Object obj = DecodeObject(env, ptr, func->ret.type);
|
|
454
454
|
return obj;
|
|
455
455
|
} break;
|
|
456
|
-
case PrimitiveKind::Array: {
|
|
456
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
457
457
|
case PrimitiveKind::Float32: return Napi::Number::New(env, (double)result.f);
|
|
458
458
|
case PrimitiveKind::Float64: return Napi::Number::New(env, result.d);
|
|
459
459
|
|
|
460
|
-
case PrimitiveKind::Prototype: {
|
|
460
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
461
461
|
}
|
|
462
462
|
|
|
463
|
-
|
|
463
|
+
K_UNREACHABLE();
|
|
464
464
|
}
|
|
465
465
|
|
|
466
466
|
void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack, BackRegisters *out_reg)
|
|
@@ -472,7 +472,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
472
472
|
TEB *teb = GetTEB();
|
|
473
473
|
|
|
474
474
|
// Restore previous stack limits at the end
|
|
475
|
-
|
|
475
|
+
K_DEFER_C(base = teb->StackBase,
|
|
476
476
|
limit = teb->StackLimit,
|
|
477
477
|
dealloc = teb->DeallocationStack) {
|
|
478
478
|
teb->StackBase = base;
|
|
@@ -506,9 +506,9 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
506
506
|
#endif
|
|
507
507
|
}
|
|
508
508
|
|
|
509
|
-
|
|
509
|
+
K_DEFER_N(err_guard) {
|
|
510
510
|
int pop = out_reg->ret_pop;
|
|
511
|
-
memset(out_reg, 0,
|
|
511
|
+
memset(out_reg, 0, K_SIZE(*out_reg));
|
|
512
512
|
out_reg->x87_double = true;
|
|
513
513
|
out_reg->ret_pop = pop;
|
|
514
514
|
};
|
|
@@ -525,10 +525,10 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
525
525
|
// Convert to JS arguments
|
|
526
526
|
for (Size i = 0; i < proto->parameters.len; i++) {
|
|
527
527
|
const ParameterInfo ¶m = proto->parameters[i];
|
|
528
|
-
|
|
528
|
+
K_ASSERT(param.directions >= 1 && param.directions <= 3);
|
|
529
529
|
|
|
530
530
|
switch (param.type->primitive) {
|
|
531
|
-
case PrimitiveKind::Void: {
|
|
531
|
+
case PrimitiveKind::Void: { K_UNREACHABLE(); } break;
|
|
532
532
|
|
|
533
533
|
case PrimitiveKind::Bool: {
|
|
534
534
|
bool b = *(bool *)(args_ptr++);
|
|
@@ -673,7 +673,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
673
673
|
} break;
|
|
674
674
|
case PrimitiveKind::Record:
|
|
675
675
|
case PrimitiveKind::Union: {
|
|
676
|
-
|
|
676
|
+
K_ASSERT(!param.fast);
|
|
677
677
|
|
|
678
678
|
uint8_t *ptr = (uint8_t *)args_ptr;
|
|
679
679
|
|
|
@@ -682,7 +682,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
682
682
|
|
|
683
683
|
args_ptr = (uint32_t *)AlignUp(ptr + param.type->size, 4);
|
|
684
684
|
} break;
|
|
685
|
-
case PrimitiveKind::Array: {
|
|
685
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
686
686
|
case PrimitiveKind::Float32: {
|
|
687
687
|
float f = *(float *)(args_ptr++);
|
|
688
688
|
|
|
@@ -697,7 +697,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
697
697
|
arguments.Append(arg);
|
|
698
698
|
} break;
|
|
699
699
|
|
|
700
|
-
case PrimitiveKind::Prototype: {
|
|
700
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
701
701
|
}
|
|
702
702
|
}
|
|
703
703
|
|
|
@@ -846,7 +846,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
846
846
|
PushObject(obj, type, (uint8_t *)&out_reg->eax);
|
|
847
847
|
}
|
|
848
848
|
} break;
|
|
849
|
-
case PrimitiveKind::Array: {
|
|
849
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
850
850
|
case PrimitiveKind::Float32: {
|
|
851
851
|
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
852
852
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
@@ -886,7 +886,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
886
886
|
out_reg->eax = (uint32_t)ptr;
|
|
887
887
|
} break;
|
|
888
888
|
|
|
889
|
-
case PrimitiveKind::Prototype: {
|
|
889
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
890
890
|
}
|
|
891
891
|
|
|
892
892
|
#undef RETURN_INTEGER_64_SWAP
|