koffi 3.0.0 → 3.0.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 +9 -1
- package/README.md +5 -4
- package/cnoke.cjs +3 -3
- package/doc/benchmarks.md +23 -46
- package/doc/callbacks.md +4 -13
- package/doc/contribute.md +3 -3
- package/doc/index.md +3 -2
- package/doc/migration.md +100 -0
- package/doc/start.md +7 -5
- package/index.d.ts +308 -308
- package/index.js +2 -1
- package/indirect.d.ts +322 -0
- package/indirect.js +2 -1
- package/package.json +20 -18
- package/src/koffi/CMakeLists.txt +19 -12
- package/src/koffi/index.cjs +65 -16
- package/src/koffi/index.js +105 -16
- package/src/koffi/indirect.cjs +65 -16
- package/src/koffi/indirect.js +105 -16
- package/src/koffi/src/abi/arm64.cc +29 -29
- package/src/koffi/src/abi/riscv64.cc +29 -29
- package/src/koffi/src/abi/x64sysv.cc +25 -25
- package/src/koffi/src/abi/x64win.cc +63 -63
- package/src/koffi/src/abi/x86.cc +66 -65
- package/src/koffi/src/call.cc +2 -2
- package/src/koffi/src/ffi.cc +64 -8
- package/src/koffi/src/ffi.hh +9 -6
- package/src/koffi/src/primitives.inc +1 -4
- package/src/koffi/src/util.cc +175 -121
- package/src/koffi/src/util.hh +13 -14
|
@@ -53,17 +53,17 @@ enum class AbiOpcode {
|
|
|
53
53
|
#define PRIMITIVE(Name) Push ## Name,
|
|
54
54
|
#include "../primitives.inc"
|
|
55
55
|
PushAggregateReg,
|
|
56
|
-
|
|
56
|
+
PushAggregateMem,
|
|
57
57
|
#define PRIMITIVE(Name) Run ## Name,
|
|
58
58
|
#include "../primitives.inc"
|
|
59
59
|
RunAggregateGG,
|
|
60
60
|
RunAggregateDDDD,
|
|
61
|
-
|
|
61
|
+
RunAggregateMem,
|
|
62
62
|
#define PRIMITIVE(Name) Run ## Name ## X,
|
|
63
63
|
#include "../primitives.inc"
|
|
64
64
|
RunAggregateGGX,
|
|
65
65
|
RunAggregateDDDDX,
|
|
66
|
-
|
|
66
|
+
RunAggregateMemX,
|
|
67
67
|
Yield,
|
|
68
68
|
CallGG,
|
|
69
69
|
CallF,
|
|
@@ -76,7 +76,7 @@ enum class AbiOpcode {
|
|
|
76
76
|
#define PRIMITIVE(Name) Return ## Name,
|
|
77
77
|
#include "../primitives.inc"
|
|
78
78
|
ReturnAggregateReg,
|
|
79
|
-
|
|
79
|
+
ReturnAggregateMem,
|
|
80
80
|
#if defined(_M_ARM64EC)
|
|
81
81
|
SetVariadicRegisters
|
|
82
82
|
#endif
|
|
@@ -220,8 +220,8 @@ bool AnalyseFunction(Napi::Env, InstanceData *instance, FunctionInfo *func)
|
|
|
220
220
|
|
|
221
221
|
param.abi.indirect = true;
|
|
222
222
|
|
|
223
|
-
func->sync.Append({ .op = Code2Op(AbiOpcode::
|
|
224
|
-
func->async.Append({ .op = Code2Op(AbiOpcode::
|
|
223
|
+
func->sync.Append({ .op = Code2Op(AbiOpcode::PushAggregateMem), .a = param.offset, .b1 = (int16_t)param.abi.offset, .type = param.type });
|
|
224
|
+
func->async.Append({ .op = Code2Op(AbiOpcode::PushAggregateMem), .a = param.offset, .b1 = (int16_t)param.abi.offset, .type = param.type });
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
break;
|
|
@@ -262,8 +262,8 @@ bool AnalyseFunction(Napi::Env, InstanceData *instance, FunctionInfo *func)
|
|
|
262
262
|
|
|
263
263
|
param.abi.indirect = true;
|
|
264
264
|
|
|
265
|
-
func->sync.Append({ .op = Code2Op(AbiOpcode::
|
|
266
|
-
func->async.Append({ .op = Code2Op(AbiOpcode::
|
|
265
|
+
func->sync.Append({ .op = Code2Op(AbiOpcode::PushAggregateMem), .a = param.offset, .b1 = (int16_t)param.abi.offset, .type = param.type });
|
|
266
|
+
func->async.Append({ .op = Code2Op(AbiOpcode::PushAggregateMem), .a = param.offset, .b1 = (int16_t)param.abi.offset, .type = param.type });
|
|
267
267
|
}
|
|
268
268
|
|
|
269
269
|
break;
|
|
@@ -340,8 +340,8 @@ bool AnalyseFunction(Napi::Env, InstanceData *instance, FunctionInfo *func)
|
|
|
340
340
|
|
|
341
341
|
param.abi.indirect = true;
|
|
342
342
|
|
|
343
|
-
func->sync.Append({ .op = Code2Op(AbiOpcode::
|
|
344
|
-
func->async.Append({ .op = Code2Op(AbiOpcode::
|
|
343
|
+
func->sync.Append({ .op = Code2Op(AbiOpcode::PushAggregateMem), .a = param.offset, .b1 = (int16_t)param.abi.offset, .type = param.type });
|
|
344
|
+
func->async.Append({ .op = Code2Op(AbiOpcode::PushAggregateMem), .a = param.offset, .b1 = (int16_t)param.abi.offset, .type = param.type });
|
|
345
345
|
}
|
|
346
346
|
} break;
|
|
347
347
|
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
@@ -508,12 +508,12 @@ bool AnalyseFunction(Napi::Env, InstanceData *instance, FunctionInfo *func)
|
|
|
508
508
|
func->async.Append({ .op = Code2Op(call) });
|
|
509
509
|
func->async.Append({ .op = Code2Op(AbiOpcode::ReturnAggregateReg), .type = func->ret.type });
|
|
510
510
|
} else {
|
|
511
|
-
AbiOpcode run = func->forward_fp ? AbiOpcode::
|
|
511
|
+
AbiOpcode run = func->forward_fp ? AbiOpcode::RunAggregateMemX : AbiOpcode::RunAggregateMem;
|
|
512
512
|
AbiOpcode call = func->forward_fp ? AbiOpcode::CallStackX : AbiOpcode::CallStack;
|
|
513
513
|
|
|
514
514
|
func->sync.Append({ .op = Code2Op(run), .a = (int32_t)func->ret.type->size, .type = func->ret.type });
|
|
515
515
|
func->async.Append({ .op = Code2Op(call), .a = (int32_t)func->ret.type->size });
|
|
516
|
-
func->async.Append({ .op = Code2Op(AbiOpcode::
|
|
516
|
+
func->async.Append({ .op = Code2Op(AbiOpcode::ReturnAggregateMem), .type = func->ret.type });
|
|
517
517
|
}
|
|
518
518
|
} break;
|
|
519
519
|
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
@@ -716,7 +716,7 @@ namespace {
|
|
|
716
716
|
|
|
717
717
|
NEXT();
|
|
718
718
|
}
|
|
719
|
-
OP(
|
|
719
|
+
OP(PushAggregateMem) {
|
|
720
720
|
napi_value arg = args[inst->a];
|
|
721
721
|
|
|
722
722
|
if (!IsObject(call->env, arg)) [[unlikely]] {
|
|
@@ -817,17 +817,17 @@ namespace {
|
|
|
817
817
|
OP(RunPrototype) { K_UNREACHABLE(); return call->env.Null(); }
|
|
818
818
|
OP(RunAggregateGG) {
|
|
819
819
|
auto ret = WRAP(ForwardCallGG(call->native, base, &call->saved_sp));
|
|
820
|
-
return DecodeObject(call->
|
|
820
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
821
821
|
}
|
|
822
822
|
OP(RunAggregateDDDD) {
|
|
823
823
|
auto ret = WRAP(ForwardCallDDDD(call->native, base, &call->saved_sp));
|
|
824
|
-
return DecodeObject(call->
|
|
824
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
825
825
|
}
|
|
826
|
-
OP(
|
|
826
|
+
OP(RunAggregateMem) {
|
|
827
827
|
uint8_t *ptr = call->AllocHeap(inst->a);
|
|
828
828
|
*(uint8_t **)(base + 8 * 8) = ptr; // x8
|
|
829
829
|
WRAP(ForwardCallGG(call->native, base, &call->saved_sp));
|
|
830
|
-
return DecodeObject(call->
|
|
830
|
+
return DecodeObject(call->instance, ptr, inst->type);
|
|
831
831
|
}
|
|
832
832
|
OP(RunVoidX) {
|
|
833
833
|
WRAP(ForwardCallGGX(call->native, base, &call->saved_sp));
|
|
@@ -893,17 +893,17 @@ namespace {
|
|
|
893
893
|
OP(RunPrototypeX) { K_UNREACHABLE(); return call->env.Null(); }
|
|
894
894
|
OP(RunAggregateGGX) {
|
|
895
895
|
auto ret = WRAP(ForwardCallGGX(call->native, base, &call->saved_sp));
|
|
896
|
-
return DecodeObject(call->
|
|
896
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
897
897
|
}
|
|
898
898
|
OP(RunAggregateDDDDX) {
|
|
899
899
|
auto ret = WRAP(ForwardCallDDDDX(call->native, base, &call->saved_sp));
|
|
900
|
-
return DecodeObject(call->
|
|
900
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
901
901
|
}
|
|
902
|
-
OP(
|
|
902
|
+
OP(RunAggregateMemX) {
|
|
903
903
|
uint8_t *ptr = call->AllocHeap(inst->a);
|
|
904
904
|
*(uint8_t **)(base + 8 * 8) = ptr; // x8
|
|
905
905
|
WRAP(ForwardCallGGX(call->native, base, &call->saved_sp));
|
|
906
|
-
return DecodeObject(call->
|
|
906
|
+
return DecodeObject(call->instance, ptr, inst->type);
|
|
907
907
|
}
|
|
908
908
|
|
|
909
909
|
#undef DISPOSE
|
|
@@ -1026,10 +1026,10 @@ namespace {
|
|
|
1026
1026
|
return Napi::Number::New(call->env, d);
|
|
1027
1027
|
}
|
|
1028
1028
|
OP(ReturnPrototype) { K_UNREACHABLE(); return call->env.Null(); }
|
|
1029
|
-
OP(ReturnAggregateReg) { return DecodeObject(call->
|
|
1030
|
-
OP(
|
|
1029
|
+
OP(ReturnAggregateReg) { return DecodeObject(call->instance, base, inst->type); }
|
|
1030
|
+
OP(ReturnAggregateMem) {
|
|
1031
1031
|
const uint8_t *ptr = *(const uint8_t **)base;
|
|
1032
|
-
return DecodeObject(call->
|
|
1032
|
+
return DecodeObject(call->instance, ptr, inst->type);
|
|
1033
1033
|
}
|
|
1034
1034
|
|
|
1035
1035
|
#if defined(_M_ARM64EC)
|
|
@@ -1053,17 +1053,17 @@ namespace {
|
|
|
1053
1053
|
#define PRIMITIVE(Name) HandlePush ## Name,
|
|
1054
1054
|
#include "../primitives.inc"
|
|
1055
1055
|
HandlePushAggregateReg,
|
|
1056
|
-
|
|
1056
|
+
HandlePushAggregateMem,
|
|
1057
1057
|
#define PRIMITIVE(Name) HandleRun ## Name,
|
|
1058
1058
|
#include "../primitives.inc"
|
|
1059
1059
|
HandleRunAggregateGG,
|
|
1060
1060
|
HandleRunAggregateDDDD,
|
|
1061
|
-
|
|
1061
|
+
HandleRunAggregateMem,
|
|
1062
1062
|
#define PRIMITIVE(Name) HandleRun ## Name ## X,
|
|
1063
1063
|
#include "../primitives.inc"
|
|
1064
1064
|
HandleRunAggregateGGX,
|
|
1065
1065
|
HandleRunAggregateDDDDX,
|
|
1066
|
-
|
|
1066
|
+
HandleRunAggregateMemX,
|
|
1067
1067
|
HandleYield,
|
|
1068
1068
|
HandleCallGG,
|
|
1069
1069
|
HandleCallF,
|
|
@@ -1076,7 +1076,7 @@ namespace {
|
|
|
1076
1076
|
#define PRIMITIVE(Name) HandleReturn ## Name,
|
|
1077
1077
|
#include "../primitives.inc"
|
|
1078
1078
|
HandleReturnAggregateReg,
|
|
1079
|
-
|
|
1079
|
+
HandleReturnAggregateMem,
|
|
1080
1080
|
#if defined(_M_ARM64EC)
|
|
1081
1081
|
HandleSetVariadicRegisters
|
|
1082
1082
|
#endif
|
|
@@ -1242,7 +1242,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
1242
1242
|
uint8_t *ptr = in_ptr + param.abi.offset;
|
|
1243
1243
|
uint8_t *src = param.abi.indirect ? *(uint8_t **)ptr : ptr;
|
|
1244
1244
|
|
|
1245
|
-
arguments[i] = DecodeObject(
|
|
1245
|
+
arguments[i] = DecodeObject(instance, src, param.type);
|
|
1246
1246
|
} break;
|
|
1247
1247
|
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
1248
1248
|
|
|
@@ -52,21 +52,21 @@ enum class AbiOpcode {
|
|
|
52
52
|
#define PRIMITIVE(Name) Push ## Name,
|
|
53
53
|
#include "../primitives.inc"
|
|
54
54
|
PushAggregateReg,
|
|
55
|
-
|
|
55
|
+
PushAggregateMem,
|
|
56
56
|
#define PRIMITIVE(Name) Run ## Name,
|
|
57
57
|
#include "../primitives.inc"
|
|
58
58
|
RunAggregateGG,
|
|
59
59
|
RunAggregateDD,
|
|
60
60
|
RunAggregateGD,
|
|
61
61
|
RunAggregateDG,
|
|
62
|
-
|
|
62
|
+
RunAggregateMem,
|
|
63
63
|
#define PRIMITIVE(Name) Run ## Name ## X,
|
|
64
64
|
#include "../primitives.inc"
|
|
65
65
|
RunAggregateGGX,
|
|
66
66
|
RunAggregateDDX,
|
|
67
67
|
RunAggregateGDX,
|
|
68
68
|
RunAggregateDGX,
|
|
69
|
-
|
|
69
|
+
RunAggregateMemX,
|
|
70
70
|
Yield,
|
|
71
71
|
CallGG,
|
|
72
72
|
CallF,
|
|
@@ -83,7 +83,7 @@ enum class AbiOpcode {
|
|
|
83
83
|
#define PRIMITIVE(Name) Return ## Name,
|
|
84
84
|
#include "../primitives.inc"
|
|
85
85
|
ReturnAggregateReg,
|
|
86
|
-
|
|
86
|
+
ReturnAggregateMem
|
|
87
87
|
};
|
|
88
88
|
|
|
89
89
|
enum class AbiMethod {
|
|
@@ -324,7 +324,7 @@ bool AnalyseFunction(Napi::Env, InstanceData *instance, FunctionInfo *func)
|
|
|
324
324
|
}
|
|
325
325
|
|
|
326
326
|
if (param.type->primitive == PrimitiveKind::Record || param.type->primitive == PrimitiveKind::Union) {
|
|
327
|
-
AbiOpcode code = (param.abi.method != AbiMethod::Memory) ? AbiOpcode::PushAggregateReg : AbiOpcode::
|
|
327
|
+
AbiOpcode code = (param.abi.method != AbiMethod::Memory) ? AbiOpcode::PushAggregateReg : AbiOpcode::PushAggregateMem;
|
|
328
328
|
|
|
329
329
|
func->sync.Append({ .op = Code2Op(code), .a = param.offset, .b1 = (int16_t)param.abi.offsets[0], .b2 = (int16_t)param.abi.offsets[1], .type = param.type });
|
|
330
330
|
func->async.Append({ .op = Code2Op(code), .a = param.offset, .b1 = (int16_t)param.abi.offsets[0], .b2 = (int16_t)param.abi.offsets[1], .type = param.type });
|
|
@@ -407,12 +407,12 @@ bool AnalyseFunction(Napi::Env, InstanceData *instance, FunctionInfo *func)
|
|
|
407
407
|
case PrimitiveKind::Union: {
|
|
408
408
|
switch (func->ret.abi.method) {
|
|
409
409
|
case AbiMethod::Memory: {
|
|
410
|
-
AbiOpcode run = func->forward_fp ? AbiOpcode::
|
|
410
|
+
AbiOpcode run = func->forward_fp ? AbiOpcode::RunAggregateMemX : AbiOpcode::RunAggregateMem;
|
|
411
411
|
AbiOpcode call = func->forward_fp ? AbiOpcode::CallStackX : AbiOpcode::CallStack;
|
|
412
412
|
|
|
413
413
|
func->sync.Append({ .op = Code2Op(run), .a = (int32_t)func->ret.type->size, .type = func->ret.type });
|
|
414
414
|
func->async.Append({ .op = Code2Op(call), .a = (int32_t)func->ret.type->size });
|
|
415
|
-
func->async.Append({ .op = Code2Op(AbiOpcode::
|
|
415
|
+
func->async.Append({ .op = Code2Op(AbiOpcode::ReturnAggregateMem), .type = func->ret.type });
|
|
416
416
|
} break;
|
|
417
417
|
|
|
418
418
|
case AbiMethod::Gpr:
|
|
@@ -643,7 +643,7 @@ namespace {
|
|
|
643
643
|
|
|
644
644
|
NEXT();
|
|
645
645
|
}
|
|
646
|
-
OP(
|
|
646
|
+
OP(PushAggregateMem) {
|
|
647
647
|
napi_value arg = args[inst->a];
|
|
648
648
|
|
|
649
649
|
if (!IsObject(call->env, arg)) [[unlikely]] {
|
|
@@ -746,25 +746,25 @@ namespace {
|
|
|
746
746
|
OP(RunPrototype) { K_UNREACHABLE(); return call->env.Null(); }
|
|
747
747
|
OP(RunAggregateGG) {
|
|
748
748
|
auto ret = WRAP(ForwardCallGG(call->native, base, &call->saved_sp));
|
|
749
|
-
return DecodeObject(call->
|
|
749
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
750
750
|
}
|
|
751
751
|
OP(RunAggregateDD) {
|
|
752
752
|
auto ret = WRAP(ForwardCallDD(call->native, base, &call->saved_sp));
|
|
753
|
-
return DecodeObject(call->
|
|
753
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
754
754
|
}
|
|
755
755
|
OP(RunAggregateGD) {
|
|
756
756
|
auto ret = WRAP(ForwardCallGD(call->native, base, &call->saved_sp));
|
|
757
|
-
return DecodeObject(call->
|
|
757
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
758
758
|
}
|
|
759
759
|
OP(RunAggregateDG) {
|
|
760
760
|
auto ret = WRAP(ForwardCallDG(call->native, base, &call->saved_sp));
|
|
761
|
-
return DecodeObject(call->
|
|
761
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
762
762
|
}
|
|
763
|
-
OP(
|
|
763
|
+
OP(RunAggregateMem) {
|
|
764
764
|
uint8_t *ptr = call->AllocHeap(inst->a);
|
|
765
765
|
*(uint8_t **)base = ptr;
|
|
766
766
|
WRAP(ForwardCallGG(call->native, base, &call->saved_sp));
|
|
767
|
-
return DecodeObject(call->
|
|
767
|
+
return DecodeObject(call->instance, ptr, inst->type);
|
|
768
768
|
}
|
|
769
769
|
OP(RunVoidX) {
|
|
770
770
|
WRAP(ForwardCallGGX(call->native, base, &call->saved_sp));
|
|
@@ -830,25 +830,25 @@ namespace {
|
|
|
830
830
|
OP(RunPrototypeX) { K_UNREACHABLE(); return call->env.Null(); }
|
|
831
831
|
OP(RunAggregateGGX) {
|
|
832
832
|
auto ret = WRAP(ForwardCallGGX(call->native, base, &call->saved_sp));
|
|
833
|
-
return DecodeObject(call->
|
|
833
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
834
834
|
}
|
|
835
835
|
OP(RunAggregateDDX) {
|
|
836
836
|
auto ret = WRAP(ForwardCallDDX(call->native, base, &call->saved_sp));
|
|
837
|
-
return DecodeObject(call->
|
|
837
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
838
838
|
}
|
|
839
839
|
OP(RunAggregateGDX) {
|
|
840
840
|
auto ret = WRAP(ForwardCallGDX(call->native, base, &call->saved_sp));
|
|
841
|
-
return DecodeObject(call->
|
|
841
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
842
842
|
}
|
|
843
843
|
OP(RunAggregateDGX) {
|
|
844
844
|
auto ret = WRAP(ForwardCallDGX(call->native, base, &call->saved_sp));
|
|
845
|
-
return DecodeObject(call->
|
|
845
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
846
846
|
}
|
|
847
|
-
OP(
|
|
847
|
+
OP(RunAggregateMemX) {
|
|
848
848
|
uint8_t *ptr = call->AllocHeap(inst->a);
|
|
849
849
|
*(uint8_t **)base = ptr;
|
|
850
850
|
WRAP(ForwardCallGGX(call->native, base, &call->saved_sp));
|
|
851
|
-
return DecodeObject(call->
|
|
851
|
+
return DecodeObject(call->instance, ptr, inst->type);
|
|
852
852
|
}
|
|
853
853
|
|
|
854
854
|
#undef DISPOSE
|
|
@@ -965,10 +965,10 @@ namespace {
|
|
|
965
965
|
return Napi::Number::New(call->env, d);
|
|
966
966
|
}
|
|
967
967
|
OP(ReturnPrototype) { K_UNREACHABLE(); return call->env.Null(); }
|
|
968
|
-
OP(ReturnAggregateReg) { return DecodeObject(call->
|
|
969
|
-
OP(
|
|
968
|
+
OP(ReturnAggregateReg) { return DecodeObject(call->instance, (const uint8_t *)base, inst->type); }
|
|
969
|
+
OP(ReturnAggregateMem) {
|
|
970
970
|
uint64_t a0 = *(uint64_t *)base;
|
|
971
|
-
return DecodeObject(call->
|
|
971
|
+
return DecodeObject(call->instance, (const uint8_t *)a0, inst->type);
|
|
972
972
|
}
|
|
973
973
|
|
|
974
974
|
#undef INTEGER_SWAP
|
|
@@ -981,21 +981,21 @@ namespace {
|
|
|
981
981
|
#define PRIMITIVE(Name) HandlePush ## Name,
|
|
982
982
|
#include "../primitives.inc"
|
|
983
983
|
HandlePushAggregateReg,
|
|
984
|
-
|
|
984
|
+
HandlePushAggregateMem,
|
|
985
985
|
#define PRIMITIVE(Name) HandleRun ## Name,
|
|
986
986
|
#include "../primitives.inc"
|
|
987
987
|
HandleRunAggregateGG,
|
|
988
988
|
HandleRunAggregateDD,
|
|
989
989
|
HandleRunAggregateGD,
|
|
990
990
|
HandleRunAggregateDG,
|
|
991
|
-
|
|
991
|
+
HandleRunAggregateMem,
|
|
992
992
|
#define PRIMITIVE(Name) HandleRun ## Name ## X,
|
|
993
993
|
#include "../primitives.inc"
|
|
994
994
|
HandleRunAggregateGGX,
|
|
995
995
|
HandleRunAggregateDDX,
|
|
996
996
|
HandleRunAggregateGDX,
|
|
997
997
|
HandleRunAggregateDGX,
|
|
998
|
-
|
|
998
|
+
HandleRunAggregateMemX,
|
|
999
999
|
HandleYield,
|
|
1000
1000
|
HandleCallGG,
|
|
1001
1001
|
HandleCallF,
|
|
@@ -1012,7 +1012,7 @@ namespace {
|
|
|
1012
1012
|
#define PRIMITIVE(Name) HandleReturn ## Name,
|
|
1013
1013
|
#include "../primitives.inc"
|
|
1014
1014
|
HandleReturnAggregateReg,
|
|
1015
|
-
|
|
1015
|
+
HandleReturnAggregateMem
|
|
1016
1016
|
};
|
|
1017
1017
|
|
|
1018
1018
|
FORCE_INLINE napi_value RunLoop(CallData *call, napi_value *args, uint8_t *base, const AbiInstruction *inst)
|
|
@@ -1177,10 +1177,10 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
1177
1177
|
memcpy(buf, in_ptr + param.abi.offsets[0], 8);
|
|
1178
1178
|
memcpy(buf + 8, in_ptr + param.abi.offsets[1], 8);
|
|
1179
1179
|
|
|
1180
|
-
arguments[i] = DecodeObject(
|
|
1180
|
+
arguments[i] = DecodeObject(instance, buf, param.type);
|
|
1181
1181
|
} else {
|
|
1182
1182
|
uint8_t *ptr = *(uint8_t **)(in_ptr + param.abi.offsets[0]);
|
|
1183
|
-
arguments[i] = DecodeObject(
|
|
1183
|
+
arguments[i] = DecodeObject(instance, ptr, param.type);
|
|
1184
1184
|
}
|
|
1185
1185
|
} break;
|
|
1186
1186
|
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
@@ -59,14 +59,14 @@ enum class AbiOpcode {
|
|
|
59
59
|
RunAggregateDD,
|
|
60
60
|
RunAggregateGD,
|
|
61
61
|
RunAggregateDG,
|
|
62
|
-
|
|
62
|
+
RunAggregateMem,
|
|
63
63
|
#define PRIMITIVE(Name) Run ## Name ## X,
|
|
64
64
|
#include "../primitives.inc"
|
|
65
65
|
RunAggregateGGX,
|
|
66
66
|
RunAggregateDDX,
|
|
67
67
|
RunAggregateGDX,
|
|
68
68
|
RunAggregateDGX,
|
|
69
|
-
|
|
69
|
+
RunAggregateMemX,
|
|
70
70
|
Yield,
|
|
71
71
|
CallGG,
|
|
72
72
|
CallF,
|
|
@@ -83,7 +83,7 @@ enum class AbiOpcode {
|
|
|
83
83
|
#define PRIMITIVE(Name) Return ## Name,
|
|
84
84
|
#include "../primitives.inc"
|
|
85
85
|
ReturnAggregateReg,
|
|
86
|
-
|
|
86
|
+
ReturnAggregateMem
|
|
87
87
|
};
|
|
88
88
|
|
|
89
89
|
enum class AbiMethod {
|
|
@@ -452,12 +452,12 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
|
452
452
|
case PrimitiveKind::Union: {
|
|
453
453
|
switch (func->ret.abi.method) {
|
|
454
454
|
case AbiMethod::Stack: {
|
|
455
|
-
AbiOpcode run = func->forward_fp ? AbiOpcode::
|
|
455
|
+
AbiOpcode run = func->forward_fp ? AbiOpcode::RunAggregateMemX : AbiOpcode::RunAggregateMem;
|
|
456
456
|
AbiOpcode call = func->forward_fp ? AbiOpcode::CallStackX : AbiOpcode::CallStack;
|
|
457
457
|
|
|
458
458
|
func->sync.Append({ .op = Code2Op(run), .a = (int32_t)func->ret.type->size, .type = func->ret.type });
|
|
459
459
|
func->async.Append({ .op = Code2Op(call), .a = (int32_t)func->ret.type->size });
|
|
460
|
-
func->async.Append({ .op = Code2Op(AbiOpcode::
|
|
460
|
+
func->async.Append({ .op = Code2Op(AbiOpcode::ReturnAggregateMem), .type = func->ret.type });
|
|
461
461
|
|
|
462
462
|
// Allocate stack space for return value
|
|
463
463
|
func->stk_size += AlignLen(func->ret.type->size, 16);
|
|
@@ -801,25 +801,25 @@ namespace {
|
|
|
801
801
|
OP(RunPrototype) { K_UNREACHABLE(); return call->env.Null(); }
|
|
802
802
|
OP(RunAggregateGG) {
|
|
803
803
|
auto ret = WRAP(ForwardCallGG(call->native, base, &call->saved_sp));
|
|
804
|
-
return DecodeObject(call->
|
|
804
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
805
805
|
}
|
|
806
806
|
OP(RunAggregateDD) {
|
|
807
807
|
auto ret = WRAP(ForwardCallDD(call->native, base, &call->saved_sp));
|
|
808
|
-
return DecodeObject(call->
|
|
808
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
809
809
|
}
|
|
810
810
|
OP(RunAggregateGD) {
|
|
811
811
|
auto ret = WRAP(ForwardCallGD(call->native, base, &call->saved_sp));
|
|
812
|
-
return DecodeObject(call->
|
|
812
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
813
813
|
}
|
|
814
814
|
OP(RunAggregateDG) {
|
|
815
815
|
auto ret = WRAP(ForwardCallDG(call->native, base, &call->saved_sp));
|
|
816
|
-
return DecodeObject(call->
|
|
816
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
817
817
|
}
|
|
818
|
-
OP(
|
|
818
|
+
OP(RunAggregateMem) {
|
|
819
819
|
uint8_t *ptr = call->AllocHeap(inst->a);
|
|
820
820
|
*(uint8_t **)base = ptr;
|
|
821
821
|
WRAP(ForwardCallGG(call->native, base, &call->saved_sp).rax);
|
|
822
|
-
return DecodeObject(call->
|
|
822
|
+
return DecodeObject(call->instance, ptr, inst->type);
|
|
823
823
|
}
|
|
824
824
|
OP(RunVoidX) {
|
|
825
825
|
WRAP(ForwardCallGGX(call->native, base, &call->saved_sp));
|
|
@@ -885,25 +885,25 @@ namespace {
|
|
|
885
885
|
OP(RunPrototypeX) { K_UNREACHABLE(); return call->env.Null(); }
|
|
886
886
|
OP(RunAggregateGGX) {
|
|
887
887
|
auto ret = WRAP(ForwardCallGGX(call->native, base, &call->saved_sp));
|
|
888
|
-
return DecodeObject(call->
|
|
888
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
889
889
|
}
|
|
890
890
|
OP(RunAggregateDDX) {
|
|
891
891
|
auto ret = WRAP(ForwardCallDDX(call->native, base, &call->saved_sp));
|
|
892
|
-
return DecodeObject(call->
|
|
892
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
893
893
|
}
|
|
894
894
|
OP(RunAggregateGDX) {
|
|
895
895
|
auto ret = WRAP(ForwardCallGDX(call->native, base, &call->saved_sp));
|
|
896
|
-
return DecodeObject(call->
|
|
896
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
897
897
|
}
|
|
898
898
|
OP(RunAggregateDGX) {
|
|
899
899
|
auto ret = WRAP(ForwardCallDGX(call->native, base, &call->saved_sp));
|
|
900
|
-
return DecodeObject(call->
|
|
900
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
901
901
|
}
|
|
902
|
-
OP(
|
|
902
|
+
OP(RunAggregateMemX) {
|
|
903
903
|
uint8_t *ptr = call->AllocHeap(inst->a);
|
|
904
904
|
*(uint8_t **)base = ptr;
|
|
905
905
|
WRAP(ForwardCallGGX(call->native, base, &call->saved_sp).rax);
|
|
906
|
-
return DecodeObject(call->
|
|
906
|
+
return DecodeObject(call->instance, ptr, inst->type);
|
|
907
907
|
}
|
|
908
908
|
|
|
909
909
|
#undef DISPOSE
|
|
@@ -1020,10 +1020,10 @@ namespace {
|
|
|
1020
1020
|
return Napi::Number::New(call->env, d);
|
|
1021
1021
|
}
|
|
1022
1022
|
OP(ReturnPrototype) { K_UNREACHABLE(); return call->env.Null(); }
|
|
1023
|
-
OP(ReturnAggregateReg) { return DecodeObject(call->
|
|
1024
|
-
OP(
|
|
1023
|
+
OP(ReturnAggregateReg) { return DecodeObject(call->instance, base, inst->type); }
|
|
1024
|
+
OP(ReturnAggregateMem) {
|
|
1025
1025
|
uint64_t rax = *(uint64_t *)base;
|
|
1026
|
-
return DecodeObject(call->
|
|
1026
|
+
return DecodeObject(call->instance, (const uint8_t *)rax, inst->type);
|
|
1027
1027
|
}
|
|
1028
1028
|
|
|
1029
1029
|
#undef INTEGER_SWAP
|
|
@@ -1043,14 +1043,14 @@ namespace {
|
|
|
1043
1043
|
HandleRunAggregateDD,
|
|
1044
1044
|
HandleRunAggregateGD,
|
|
1045
1045
|
HandleRunAggregateDG,
|
|
1046
|
-
|
|
1046
|
+
HandleRunAggregateMem,
|
|
1047
1047
|
#define PRIMITIVE(Name) HandleRun ## Name ## X,
|
|
1048
1048
|
#include "../primitives.inc"
|
|
1049
1049
|
HandleRunAggregateGGX,
|
|
1050
1050
|
HandleRunAggregateDDX,
|
|
1051
1051
|
HandleRunAggregateGDX,
|
|
1052
1052
|
HandleRunAggregateDGX,
|
|
1053
|
-
|
|
1053
|
+
HandleRunAggregateMemX,
|
|
1054
1054
|
HandleYield,
|
|
1055
1055
|
HandleCallGG,
|
|
1056
1056
|
HandleCallF,
|
|
@@ -1067,7 +1067,7 @@ namespace {
|
|
|
1067
1067
|
#define PRIMITIVE(Name) HandleReturn ## Name,
|
|
1068
1068
|
#include "../primitives.inc"
|
|
1069
1069
|
HandleReturnAggregateReg,
|
|
1070
|
-
|
|
1070
|
+
HandleReturnAggregateMem
|
|
1071
1071
|
};
|
|
1072
1072
|
|
|
1073
1073
|
FORCE_INLINE napi_value RunLoop(CallData *call, napi_value *args, uint8_t *base, const AbiInstruction *inst)
|
|
@@ -1232,9 +1232,9 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
1232
1232
|
buf[0] = *(uint64_t *)(in_ptr + param.abi.offsets[0]);
|
|
1233
1233
|
buf[1] = *(uint64_t *)(in_ptr + param.abi.offsets[1]);
|
|
1234
1234
|
|
|
1235
|
-
arguments[i] = DecodeObject(
|
|
1235
|
+
arguments[i] = DecodeObject(instance, (const uint8_t *)buf, param.type);
|
|
1236
1236
|
} else {
|
|
1237
|
-
arguments[i] = DecodeObject(
|
|
1237
|
+
arguments[i] = DecodeObject(instance, in_ptr + param.abi.offsets[0], param.type);
|
|
1238
1238
|
}
|
|
1239
1239
|
} break;
|
|
1240
1240
|
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|