koffi 3.0.1 → 3.1.0
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 +32 -3
- package/cnoke.cjs +2 -2
- package/doc/benchmarks.md +1 -1
- package/doc/callbacks.md +7 -26
- package/doc/{input.md → composites.md} +161 -147
- package/doc/contribute.md +3 -2
- package/doc/index.md +0 -14
- package/doc/{functions.md → load.md} +54 -113
- package/doc/migration.md +4 -7
- package/doc/misc.md +0 -103
- package/doc/output.md +5 -11
- package/doc/pointers.md +76 -17
- package/doc/primitives.md +151 -0
- package/doc/start.md +3 -13
- package/doc/types.md +88 -0
- package/doc/unions.md +0 -186
- package/doc/values.md +134 -0
- package/index.d.ts +375 -308
- package/lib/native/base/base.cc +66 -24
- package/lib/native/base/base.hh +55 -153
- package/package.json +16 -16
- package/src/koffi/CMakeLists.txt +20 -17
- package/src/koffi/index.cjs +30 -111
- package/src/koffi/index.js +22 -96
- package/src/koffi/indirect.cjs +30 -111
- package/src/koffi/indirect.js +24 -24
- package/src/koffi/src/abi/arm64.cc +48 -62
- package/src/koffi/src/abi/riscv64.cc +39 -57
- package/src/koffi/src/abi/x64sysv.cc +39 -57
- package/src/koffi/src/abi/x64win.cc +48 -65
- package/src/koffi/src/abi/x86.cc +47 -59
- package/src/koffi/src/call.cc +426 -209
- package/src/koffi/src/call.hh +7 -11
- package/src/koffi/src/ffi.cc +534 -303
- package/src/koffi/src/ffi.hh +71 -15
- package/src/koffi/src/parser.cc +5 -3
- package/src/koffi/src/parser.hh +2 -2
- package/src/koffi/src/static.cjs +122 -0
- package/src/koffi/src/static.js +125 -0
- package/src/koffi/src/type.cc +725 -0
- package/src/koffi/src/type.hh +71 -0
- package/src/koffi/src/util.cc +117 -1202
- package/src/koffi/src/util.hh +158 -156
- package/src/koffi/src/uv.cc +17 -11
- package/src/koffi/src/uv.hh +2 -1
- package/vendor/node-addon-api/README.md +1 -1
- package/vendor/node-addon-api/napi-inl.h +213 -35
- package/vendor/node-addon-api/napi.h +118 -7
- package/doc/variables.md +0 -102
- package/indirect.d.ts +0 -322
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
#include "lib/native/base/base.hh"
|
|
7
7
|
#include "../ffi.hh"
|
|
8
8
|
#include "../call.hh"
|
|
9
|
+
#include "../type.hh"
|
|
9
10
|
#include "../util.hh"
|
|
10
11
|
|
|
11
12
|
#include <napi.h>
|
|
@@ -683,13 +684,8 @@ namespace {
|
|
|
683
684
|
OP(PushAggregateReg) {
|
|
684
685
|
napi_value arg = args[inst->a];
|
|
685
686
|
|
|
686
|
-
if (!IsObject(call->env, arg)) [[unlikely]] {
|
|
687
|
-
ThrowError<Napi::TypeError>(call->env, "Unexpected %1 value, expected object", GetValueType(call->instance, args[inst->a]));
|
|
688
|
-
return call->env.Null();
|
|
689
|
-
}
|
|
690
|
-
|
|
691
687
|
uint64_t buf[2];
|
|
692
|
-
if (!call->PushObject(arg, inst->type, (uint8_t *)buf))
|
|
688
|
+
if (!call->PushObject(arg, inst->type, (uint8_t *)buf)) [[unlikely]]
|
|
693
689
|
return call->env.Null();
|
|
694
690
|
|
|
695
691
|
// The second part might be useless (if object fits in one register), in
|
|
@@ -704,12 +700,7 @@ namespace {
|
|
|
704
700
|
OP(PushAggregateStack) {
|
|
705
701
|
napi_value arg = args[inst->a];
|
|
706
702
|
|
|
707
|
-
if (!
|
|
708
|
-
ThrowError<Napi::TypeError>(call->env, "Unexpected %1 value, expected object", GetValueType(call->instance, arg));
|
|
709
|
-
return call->env.Null();
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
if (!call->PushObject(arg, inst->type, base + inst->b1))
|
|
703
|
+
if (!call->PushObject(arg, inst->type, base + inst->b1)) [[unlikely]]
|
|
713
704
|
return call->env.Null();
|
|
714
705
|
|
|
715
706
|
NEXT();
|
|
@@ -733,7 +724,7 @@ namespace {
|
|
|
733
724
|
#define DISPOSE(Ptr) \
|
|
734
725
|
do { \
|
|
735
726
|
if (inst->type->dispose) { \
|
|
736
|
-
inst->type->dispose(call->
|
|
727
|
+
inst->type->dispose(call->instance, inst->type, (Ptr)); \
|
|
737
728
|
} \
|
|
738
729
|
} while (false)
|
|
739
730
|
|
|
@@ -761,42 +752,42 @@ namespace {
|
|
|
761
752
|
OP(RunUInt64S) { INTEGER_SWAP(GG, uint64_t); }
|
|
762
753
|
OP(RunString) {
|
|
763
754
|
uint64_t rax = WRAP(ForwardCallGG(call->native, base, &call->saved_sp).rax);
|
|
764
|
-
napi_value value =
|
|
755
|
+
napi_value value = NewString(call->env, (const char *)rax);
|
|
765
756
|
DISPOSE((void *)rax);
|
|
766
757
|
return value;
|
|
767
758
|
}
|
|
768
759
|
OP(RunString16) {
|
|
769
760
|
uint64_t rax = WRAP(ForwardCallGG(call->native, base, &call->saved_sp).rax);
|
|
770
|
-
napi_value value =
|
|
761
|
+
napi_value value = NewString(call->env, (const char16_t *)rax);
|
|
771
762
|
DISPOSE((void *)rax);
|
|
772
763
|
return value;
|
|
773
764
|
}
|
|
774
765
|
OP(RunString32) {
|
|
775
766
|
uint64_t rax = WRAP(ForwardCallGG(call->native, base, &call->saved_sp).rax);
|
|
776
|
-
napi_value value =
|
|
767
|
+
napi_value value = NewString(call->env, (const char32_t *)rax);
|
|
777
768
|
DISPOSE((void *)rax);
|
|
778
769
|
return value;
|
|
779
770
|
}
|
|
780
771
|
OP(RunPointer) {
|
|
781
772
|
uint64_t rax = WRAP(ForwardCallGG(call->native, base, &call->saved_sp).rax);
|
|
782
|
-
napi_value value =
|
|
773
|
+
napi_value value = WrapPointer(call->env, inst->type, (void *)rax);
|
|
783
774
|
DISPOSE((void *)rax);
|
|
784
775
|
return value;
|
|
785
776
|
}
|
|
786
777
|
OP(RunCallback) {
|
|
787
778
|
uint64_t rax = WRAP(ForwardCallGG(call->native, base, &call->saved_sp).rax);
|
|
788
|
-
return
|
|
779
|
+
return WrapPointer(call->env, inst->type, (void *)rax);
|
|
789
780
|
}
|
|
790
781
|
OP(RunRecord) { K_UNREACHABLE(); return call->env.Null(); }
|
|
791
782
|
OP(RunUnion) { K_UNREACHABLE(); return call->env.Null(); }
|
|
792
783
|
OP(RunArray) { K_UNREACHABLE(); return call->env.Null(); }
|
|
793
784
|
OP(RunFloat32) {
|
|
794
785
|
float f = WRAP(ForwardCallF(call->native, base, &call->saved_sp));
|
|
795
|
-
return
|
|
786
|
+
return NewFloat(call->env, f);
|
|
796
787
|
}
|
|
797
788
|
OP(RunFloat64) {
|
|
798
789
|
double d = WRAP(ForwardCallDD(call->native, base, &call->saved_sp).xmm0);
|
|
799
|
-
return
|
|
790
|
+
return NewFloat(call->env, d);
|
|
800
791
|
}
|
|
801
792
|
OP(RunPrototype) { K_UNREACHABLE(); return call->env.Null(); }
|
|
802
793
|
OP(RunAggregateGG) {
|
|
@@ -845,42 +836,42 @@ namespace {
|
|
|
845
836
|
OP(RunUInt64SX) { INTEGER_SWAP(GGX, uint64_t); }
|
|
846
837
|
OP(RunStringX) {
|
|
847
838
|
uint64_t rax = WRAP(ForwardCallGGX(call->native, base, &call->saved_sp).rax);
|
|
848
|
-
napi_value value =
|
|
839
|
+
napi_value value = NewString(call->env, (const char *)rax);
|
|
849
840
|
DISPOSE((void *)rax);
|
|
850
841
|
return value;
|
|
851
842
|
}
|
|
852
843
|
OP(RunString16X) {
|
|
853
844
|
uint64_t rax = WRAP(ForwardCallGGX(call->native, base, &call->saved_sp).rax);
|
|
854
|
-
napi_value value =
|
|
845
|
+
napi_value value = NewString(call->env, (const char16_t *)rax);
|
|
855
846
|
DISPOSE((void *)rax);
|
|
856
847
|
return value;
|
|
857
848
|
}
|
|
858
849
|
OP(RunString32X) {
|
|
859
850
|
uint64_t rax = WRAP(ForwardCallGGX(call->native, base, &call->saved_sp).rax);
|
|
860
|
-
napi_value value =
|
|
851
|
+
napi_value value = NewString(call->env, (const char32_t *)rax);
|
|
861
852
|
DISPOSE((void *)rax);
|
|
862
853
|
return value;
|
|
863
854
|
}
|
|
864
855
|
OP(RunPointerX) {
|
|
865
856
|
uint64_t rax = WRAP(ForwardCallGGX(call->native, base, &call->saved_sp).rax);
|
|
866
|
-
napi_value value =
|
|
857
|
+
napi_value value = WrapPointer(call->env, inst->type, (void *)rax);
|
|
867
858
|
DISPOSE((void *)rax);
|
|
868
859
|
return value;
|
|
869
860
|
}
|
|
870
861
|
OP(RunCallbackX) {
|
|
871
862
|
uint64_t rax = WRAP(ForwardCallGGX(call->native, base, &call->saved_sp).rax);
|
|
872
|
-
return
|
|
863
|
+
return WrapPointer(call->env, inst->type, (void *)rax);
|
|
873
864
|
}
|
|
874
865
|
OP(RunRecordX) { K_UNREACHABLE(); return call->env.Null(); }
|
|
875
866
|
OP(RunUnionX) { K_UNREACHABLE(); return call->env.Null(); }
|
|
876
867
|
OP(RunArrayX) { K_UNREACHABLE(); return call->env.Null(); }
|
|
877
868
|
OP(RunFloat32X) {
|
|
878
869
|
float f = WRAP(ForwardCallFX(call->native, base, &call->saved_sp));
|
|
879
|
-
return
|
|
870
|
+
return NewFloat(call->env, f);
|
|
880
871
|
}
|
|
881
872
|
OP(RunFloat64X) {
|
|
882
873
|
double d = WRAP(ForwardCallDDX(call->native, base, &call->saved_sp).xmm0);
|
|
883
|
-
return
|
|
874
|
+
return NewFloat(call->env, d);
|
|
884
875
|
}
|
|
885
876
|
OP(RunPrototypeX) { K_UNREACHABLE(); return call->env.Null(); }
|
|
886
877
|
OP(RunAggregateGGX) {
|
|
@@ -919,7 +910,7 @@ namespace {
|
|
|
919
910
|
do { \
|
|
920
911
|
if (inst->type->dispose) { \
|
|
921
912
|
void *ptr = *(void **)base; \
|
|
922
|
-
inst->type->dispose(call->
|
|
913
|
+
inst->type->dispose(call->instance, inst->type, ptr); \
|
|
923
914
|
} \
|
|
924
915
|
} while (false)
|
|
925
916
|
#define INTEGER(CType) \
|
|
@@ -982,42 +973,42 @@ namespace {
|
|
|
982
973
|
OP(ReturnUInt64S) { INTEGER_SWAP(uint64_t); }
|
|
983
974
|
OP(ReturnString) {
|
|
984
975
|
uint64_t rax = *(uint64_t *)base;
|
|
985
|
-
napi_value value =
|
|
976
|
+
napi_value value = NewString(call->env, (const char *)rax);
|
|
986
977
|
DISPOSE();
|
|
987
978
|
return value;
|
|
988
979
|
}
|
|
989
980
|
OP(ReturnString16) {
|
|
990
981
|
uint64_t rax = *(uint64_t *)base;
|
|
991
|
-
napi_value value =
|
|
982
|
+
napi_value value = NewString(call->env, (const char16_t *)rax);
|
|
992
983
|
DISPOSE();
|
|
993
984
|
return value;
|
|
994
985
|
}
|
|
995
986
|
OP(ReturnString32) {
|
|
996
987
|
uint64_t rax = *(uint64_t *)base;
|
|
997
|
-
napi_value value =
|
|
988
|
+
napi_value value = NewString(call->env, (const char32_t *)rax);
|
|
998
989
|
DISPOSE();
|
|
999
990
|
return value;
|
|
1000
991
|
}
|
|
1001
992
|
OP(ReturnPointer) {
|
|
1002
993
|
uint64_t rax = *(uint64_t *)base;
|
|
1003
|
-
napi_value value =
|
|
994
|
+
napi_value value = WrapPointer(call->env, inst->type, (void *)rax);
|
|
1004
995
|
DISPOSE();
|
|
1005
996
|
return value;
|
|
1006
997
|
}
|
|
1007
998
|
OP(ReturnCallback) {
|
|
1008
999
|
uint64_t rax = *(uint64_t *)base;
|
|
1009
|
-
return
|
|
1000
|
+
return WrapPointer(call->env, inst->type, (void *)rax);
|
|
1010
1001
|
}
|
|
1011
1002
|
OP(ReturnRecord) { K_UNREACHABLE(); return call->env.Null(); }
|
|
1012
1003
|
OP(ReturnUnion) { K_UNREACHABLE(); return call->env.Null(); }
|
|
1013
1004
|
OP(ReturnArray) { K_UNREACHABLE(); return call->env.Null(); }
|
|
1014
1005
|
OP(ReturnFloat32) {
|
|
1015
1006
|
float f = *(float *)base;
|
|
1016
|
-
return
|
|
1007
|
+
return NewFloat(call->env, f);
|
|
1017
1008
|
}
|
|
1018
1009
|
OP(ReturnFloat64) {
|
|
1019
1010
|
double d = *(double *)base;
|
|
1020
|
-
return
|
|
1011
|
+
return NewFloat(call->env, d);
|
|
1021
1012
|
}
|
|
1022
1013
|
OP(ReturnPrototype) { K_UNREACHABLE(); return call->env.Null(); }
|
|
1023
1014
|
OP(ReturnAggregateReg) { return DecodeObject(call->instance, base, inst->type); }
|
|
@@ -1187,30 +1178,30 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
1187
1178
|
const uint8_t *src = in_ptr + param.abi.offsets[0];
|
|
1188
1179
|
const char *str = *(const char **)src;
|
|
1189
1180
|
|
|
1190
|
-
arguments[i] =
|
|
1181
|
+
arguments[i] = NewString(env, str);
|
|
1191
1182
|
|
|
1192
1183
|
if (param.type->dispose) {
|
|
1193
|
-
param.type->dispose(
|
|
1184
|
+
param.type->dispose(instance, param.type, str);
|
|
1194
1185
|
}
|
|
1195
1186
|
} break;
|
|
1196
1187
|
case PrimitiveKind::String16: {
|
|
1197
1188
|
const uint8_t *src = in_ptr + param.abi.offsets[0];
|
|
1198
1189
|
const char16_t *str16 = *(const char16_t **)src;
|
|
1199
1190
|
|
|
1200
|
-
arguments[i] =
|
|
1191
|
+
arguments[i] = NewString(env, str16);
|
|
1201
1192
|
|
|
1202
1193
|
if (param.type->dispose) {
|
|
1203
|
-
param.type->dispose(
|
|
1194
|
+
param.type->dispose(instance, param.type, str16);
|
|
1204
1195
|
}
|
|
1205
1196
|
} break;
|
|
1206
1197
|
case PrimitiveKind::String32: {
|
|
1207
1198
|
const uint8_t *src = in_ptr + param.abi.offsets[0];
|
|
1208
1199
|
const char32_t *str32 = *(const char32_t **)src;
|
|
1209
1200
|
|
|
1210
|
-
arguments[i] =
|
|
1201
|
+
arguments[i] = NewString(env, str32);
|
|
1211
1202
|
|
|
1212
1203
|
if (param.type->dispose) {
|
|
1213
|
-
param.type->dispose(
|
|
1204
|
+
param.type->dispose(instance, param.type, str32);
|
|
1214
1205
|
}
|
|
1215
1206
|
} break;
|
|
1216
1207
|
|
|
@@ -1218,10 +1209,10 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
1218
1209
|
const uint8_t *src = in_ptr + param.abi.offsets[0];
|
|
1219
1210
|
void *ptr2 = *(void **)src;
|
|
1220
1211
|
|
|
1221
|
-
arguments[i] =
|
|
1212
|
+
arguments[i] = WrapPointer(env, param.type->ref.type, ptr2);
|
|
1222
1213
|
|
|
1223
1214
|
if (param.type->dispose) {
|
|
1224
|
-
param.type->dispose(
|
|
1215
|
+
param.type->dispose(instance, param.type, ptr2);
|
|
1225
1216
|
}
|
|
1226
1217
|
} break;
|
|
1227
1218
|
|
|
@@ -1243,24 +1234,20 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
1243
1234
|
const uint8_t *src = in_ptr + param.abi.offsets[0];
|
|
1244
1235
|
float f = *(float *)src;
|
|
1245
1236
|
|
|
1246
|
-
arguments[i] =
|
|
1237
|
+
arguments[i] = NewFloat(env, f);
|
|
1247
1238
|
} break;
|
|
1248
1239
|
case PrimitiveKind::Float64: {
|
|
1249
1240
|
const uint8_t *src = in_ptr + param.abi.offsets[0];
|
|
1250
1241
|
double d = *(double *)src;
|
|
1251
1242
|
|
|
1252
|
-
arguments[i] =
|
|
1243
|
+
arguments[i] = NewFloat(env, d);
|
|
1253
1244
|
} break;
|
|
1254
1245
|
|
|
1255
1246
|
case PrimitiveKind::Callback: {
|
|
1256
1247
|
const uint8_t *src = in_ptr + param.abi.offsets[0];
|
|
1257
1248
|
void *ptr2 = *(void **)src;
|
|
1258
1249
|
|
|
1259
|
-
arguments[i] =
|
|
1260
|
-
|
|
1261
|
-
if (param.type->dispose) {
|
|
1262
|
-
param.type->dispose(env, param.type, ptr2);
|
|
1263
|
-
}
|
|
1250
|
+
arguments[i] = WrapPointer(env, param.type->ref.type, ptr2);
|
|
1264
1251
|
} break;
|
|
1265
1252
|
|
|
1266
1253
|
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
@@ -1360,16 +1347,11 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
1360
1347
|
|
|
1361
1348
|
case PrimitiveKind::Record:
|
|
1362
1349
|
case PrimitiveKind::Union: {
|
|
1363
|
-
if (!IsObject(env, value)) [[unlikely]] {
|
|
1364
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
1365
|
-
return;
|
|
1366
|
-
}
|
|
1367
|
-
|
|
1368
1350
|
if (proto->ret.abi.method == AbiMethod::Stack) {
|
|
1369
1351
|
uint64_t *gpr_ptr = (uint64_t *)in_ptr;
|
|
1370
1352
|
uint8_t *dest = (uint8_t *)gpr_ptr[0];
|
|
1371
1353
|
|
|
1372
|
-
if (!PushObject(value, type, dest))
|
|
1354
|
+
if (!PushObject(value, type, dest)) [[unlikely]]
|
|
1373
1355
|
return;
|
|
1374
1356
|
|
|
1375
1357
|
out_reg->rax = (uint64_t)dest;
|
|
@@ -1377,7 +1359,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
1377
1359
|
K_ASSERT(type->size <= 16);
|
|
1378
1360
|
|
|
1379
1361
|
uint8_t buf[16] = {};
|
|
1380
|
-
if (!PushObject(value, type, buf))
|
|
1362
|
+
if (!PushObject(value, type, buf)) [[unlikely]]
|
|
1381
1363
|
return;
|
|
1382
1364
|
|
|
1383
1365
|
switch (proto->ret.abi.method) {
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
#include "lib/native/base/base.hh"
|
|
7
7
|
#include "../ffi.hh"
|
|
8
8
|
#include "../call.hh"
|
|
9
|
+
#include "../type.hh"
|
|
9
10
|
#include "../util.hh"
|
|
10
11
|
#include "../win32.hh"
|
|
11
12
|
|
|
@@ -73,16 +74,16 @@ inline void *Code2Op(AbiOpcode code)
|
|
|
73
74
|
|
|
74
75
|
bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
75
76
|
{
|
|
76
|
-
func->ret.regular = IsRegularSize(func->ret.type->size, 8);
|
|
77
|
+
func->ret.abi.regular = IsRegularSize(func->ret.type->size, 8);
|
|
77
78
|
|
|
78
79
|
for (Size i = 0; i < func->parameters.len; i++) {
|
|
79
|
-
int16_t arg = (int16_t)(!func->ret.regular + i);
|
|
80
|
+
int16_t arg = (int16_t)(!func->ret.abi.regular + i);
|
|
80
81
|
ParameterInfo ¶m = func->parameters[i];
|
|
81
82
|
|
|
82
|
-
param.regular = IsRegularSize(param.type->size, 8);
|
|
83
|
+
param.abi.regular = IsRegularSize(param.type->size, 8);
|
|
83
84
|
|
|
84
85
|
if (param.type->primitive == PrimitiveKind::Record || param.type->primitive == PrimitiveKind::Union) {
|
|
85
|
-
AbiOpcode code = param.regular ? AbiOpcode::PushAggregateReg : AbiOpcode::PushAggregateMem;
|
|
86
|
+
AbiOpcode code = param.abi.regular ? AbiOpcode::PushAggregateReg : AbiOpcode::PushAggregateMem;
|
|
86
87
|
|
|
87
88
|
func->sync.Append({ .op = Code2Op(code), .a = param.offset, .b1 = (int16_t)(arg * 8), .b2 = (int16_t)param.directions, .type = param.type });
|
|
88
89
|
func->async.Append({ .op = Code2Op(code), .a = param.offset, .b1 = (int16_t)(arg * 8), .b2 = (int16_t)param.directions, .type = param.type });
|
|
@@ -99,7 +100,7 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
|
99
100
|
|
|
100
101
|
// At least 4 parameter registers
|
|
101
102
|
{
|
|
102
|
-
Size count = std::max((Size)4, func->parameters.len + !func->ret.regular);
|
|
103
|
+
Size count = std::max((Size)4, func->parameters.len + !func->ret.abi.regular);
|
|
103
104
|
func->stk_size = AlignLen(8 * count, 16);
|
|
104
105
|
}
|
|
105
106
|
|
|
@@ -167,7 +168,7 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
|
167
168
|
|
|
168
169
|
case PrimitiveKind::Record:
|
|
169
170
|
case PrimitiveKind::Union: {
|
|
170
|
-
if (func->ret.regular) {
|
|
171
|
+
if (func->ret.abi.regular) {
|
|
171
172
|
AbiOpcode run = func->forward_fp ? AbiOpcode::RunAggregateRegX : AbiOpcode::RunAggregateReg;
|
|
172
173
|
AbiOpcode call = func->forward_fp ? AbiOpcode::CallGX : AbiOpcode::CallG;
|
|
173
174
|
|
|
@@ -369,14 +370,9 @@ namespace {
|
|
|
369
370
|
OP(PushAggregateReg) {
|
|
370
371
|
napi_value arg = args[inst->a];
|
|
371
372
|
|
|
372
|
-
if (!IsObject(call->env, arg)) [[unlikely]] {
|
|
373
|
-
ThrowError<Napi::TypeError>(call->env, "Unexpected %1 value, expected object", GetValueType(call->instance, arg));
|
|
374
|
-
return call->env.Null();
|
|
375
|
-
}
|
|
376
|
-
|
|
377
373
|
uint8_t *ptr = (uint8_t *)(base + inst->b1);
|
|
378
374
|
|
|
379
|
-
if (!call->PushObject(arg, inst->type, ptr))
|
|
375
|
+
if (!call->PushObject(arg, inst->type, ptr)) [[unlikely]]
|
|
380
376
|
return call->env.Null();
|
|
381
377
|
|
|
382
378
|
NEXT();
|
|
@@ -384,15 +380,10 @@ namespace {
|
|
|
384
380
|
OP(PushAggregateMem) {
|
|
385
381
|
napi_value arg = args[inst->a];
|
|
386
382
|
|
|
387
|
-
if (!IsObject(call->env, arg)) [[unlikely]] {
|
|
388
|
-
ThrowError<Napi::TypeError>(call->env, "Unexpected %1 value, expected object", GetValueType(call->instance, arg));
|
|
389
|
-
return call->env.Null();
|
|
390
|
-
}
|
|
391
|
-
|
|
392
383
|
uint8_t *ptr = call->AllocHeap(inst->type->size);
|
|
393
384
|
*(uint8_t **)(base + inst->b1) = ptr;
|
|
394
385
|
|
|
395
|
-
if (!call->PushObject(arg, inst->type, ptr))
|
|
386
|
+
if (!call->PushObject(arg, inst->type, ptr)) [[unlikely]]
|
|
396
387
|
return call->env.Null();
|
|
397
388
|
|
|
398
389
|
NEXT();
|
|
@@ -414,7 +405,7 @@ namespace {
|
|
|
414
405
|
#define DISPOSE(Ptr) \
|
|
415
406
|
do { \
|
|
416
407
|
if (inst->type->dispose) { \
|
|
417
|
-
inst->type->dispose(call->
|
|
408
|
+
inst->type->dispose(call->instance, inst->type, (Ptr)); \
|
|
418
409
|
} \
|
|
419
410
|
} while (false)
|
|
420
411
|
|
|
@@ -442,42 +433,42 @@ namespace {
|
|
|
442
433
|
OP(RunUInt64S) { INTEGER_SWAP(G, uint64_t); }
|
|
443
434
|
OP(RunString) {
|
|
444
435
|
uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
|
|
445
|
-
napi_value value =
|
|
436
|
+
napi_value value = NewString(call->env, (const char *)rax);
|
|
446
437
|
DISPOSE((void *)rax);
|
|
447
438
|
return value;
|
|
448
439
|
}
|
|
449
440
|
OP(RunString16) {
|
|
450
441
|
uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
|
|
451
|
-
napi_value value =
|
|
442
|
+
napi_value value = NewString(call->env, (const char16_t *)rax);
|
|
452
443
|
DISPOSE((void *)rax);
|
|
453
444
|
return value;
|
|
454
445
|
}
|
|
455
446
|
OP(RunString32) {
|
|
456
447
|
uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
|
|
457
|
-
napi_value value =
|
|
448
|
+
napi_value value = NewString(call->env, (const char32_t *)rax);
|
|
458
449
|
DISPOSE((void *)rax);
|
|
459
450
|
return value;
|
|
460
451
|
}
|
|
461
452
|
OP(RunPointer) {
|
|
462
453
|
uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
|
|
463
|
-
napi_value value =
|
|
454
|
+
napi_value value = WrapPointer(call->env, inst->type, (void *)rax);
|
|
464
455
|
DISPOSE((void *)rax);
|
|
465
456
|
return value;
|
|
466
457
|
}
|
|
467
458
|
OP(RunCallback) {
|
|
468
459
|
uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
|
|
469
|
-
return
|
|
460
|
+
return WrapPointer(call->env, inst->type, (void *)rax);
|
|
470
461
|
}
|
|
471
462
|
OP(RunRecord) { K_UNREACHABLE(); return call->env.Null(); }
|
|
472
463
|
OP(RunUnion) { K_UNREACHABLE(); return call->env.Null(); }
|
|
473
464
|
OP(RunArray) { K_UNREACHABLE(); return call->env.Null(); }
|
|
474
465
|
OP(RunFloat32) {
|
|
475
466
|
float f = WRAP(ForwardCallF(call->native, base, &call->saved_sp));
|
|
476
|
-
return
|
|
467
|
+
return NewFloat(call->env, f);
|
|
477
468
|
}
|
|
478
469
|
OP(RunFloat64) {
|
|
479
470
|
double d = WRAP(ForwardCallD(call->native, base, &call->saved_sp));
|
|
480
|
-
return
|
|
471
|
+
return NewFloat(call->env, d);
|
|
481
472
|
}
|
|
482
473
|
OP(RunPrototype) { K_UNREACHABLE(); return call->env.Null(); }
|
|
483
474
|
OP(RunAggregateReg) {
|
|
@@ -513,42 +504,42 @@ namespace {
|
|
|
513
504
|
OP(RunUInt64SX) { INTEGER_SWAP(GX, uint64_t); }
|
|
514
505
|
OP(RunStringX) {
|
|
515
506
|
uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
|
|
516
|
-
napi_value value =
|
|
507
|
+
napi_value value = NewString(call->env, (const char *)rax);
|
|
517
508
|
DISPOSE((void *)rax);
|
|
518
509
|
return value;
|
|
519
510
|
}
|
|
520
511
|
OP(RunString16X) {
|
|
521
512
|
uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
|
|
522
|
-
napi_value value =
|
|
513
|
+
napi_value value = NewString(call->env, (const char16_t *)rax);
|
|
523
514
|
DISPOSE((void *)rax);
|
|
524
515
|
return value;
|
|
525
516
|
}
|
|
526
517
|
OP(RunString32X) {
|
|
527
518
|
uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
|
|
528
|
-
napi_value value =
|
|
519
|
+
napi_value value = NewString(call->env, (const char32_t *)rax);
|
|
529
520
|
DISPOSE((void *)rax);
|
|
530
521
|
return value;
|
|
531
522
|
}
|
|
532
523
|
OP(RunPointerX) {
|
|
533
524
|
uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
|
|
534
|
-
napi_value value =
|
|
525
|
+
napi_value value = WrapPointer(call->env, inst->type, (void *)rax);
|
|
535
526
|
DISPOSE((void *)rax);
|
|
536
527
|
return value;
|
|
537
528
|
}
|
|
538
529
|
OP(RunCallbackX) {
|
|
539
530
|
uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
|
|
540
|
-
return
|
|
531
|
+
return WrapPointer(call->env, inst->type, (void *)rax);
|
|
541
532
|
}
|
|
542
533
|
OP(RunRecordX) { K_UNREACHABLE(); return call->env.Null(); }
|
|
543
534
|
OP(RunUnionX) { K_UNREACHABLE(); return call->env.Null(); }
|
|
544
535
|
OP(RunArrayX) { K_UNREACHABLE(); return call->env.Null(); }
|
|
545
536
|
OP(RunFloat32X) {
|
|
546
537
|
float f = WRAP(ForwardCallFX(call->native, base, &call->saved_sp));
|
|
547
|
-
return
|
|
538
|
+
return NewFloat(call->env, f);
|
|
548
539
|
}
|
|
549
540
|
OP(RunFloat64X) {
|
|
550
541
|
double d = WRAP(ForwardCallDX(call->native, base, &call->saved_sp));
|
|
551
|
-
return
|
|
542
|
+
return NewFloat(call->env, d);
|
|
552
543
|
}
|
|
553
544
|
OP(RunPrototypeX) { K_UNREACHABLE(); return call->env.Null(); }
|
|
554
545
|
OP(RunAggregateRegX) {
|
|
@@ -574,7 +565,7 @@ namespace {
|
|
|
574
565
|
do { \
|
|
575
566
|
if (inst->type->dispose) { \
|
|
576
567
|
void *ptr = *(void **)base; \
|
|
577
|
-
inst->type->dispose(call->
|
|
568
|
+
inst->type->dispose(call->instance, inst->type, ptr); \
|
|
578
569
|
} \
|
|
579
570
|
} while (false)
|
|
580
571
|
#define INTEGER(CType) \
|
|
@@ -631,42 +622,42 @@ namespace {
|
|
|
631
622
|
OP(ReturnUInt64S) { INTEGER_SWAP(uint64_t); }
|
|
632
623
|
OP(ReturnString) {
|
|
633
624
|
uint64_t rax = *(uint64_t *)base;
|
|
634
|
-
napi_value value =
|
|
625
|
+
napi_value value = NewString(call->env, (const char *)rax);
|
|
635
626
|
DISPOSE();
|
|
636
627
|
return value;
|
|
637
628
|
}
|
|
638
629
|
OP(ReturnString16) {
|
|
639
630
|
uint64_t rax = *(uint64_t *)base;
|
|
640
|
-
napi_value value =
|
|
631
|
+
napi_value value = NewString(call->env, (const char16_t *)rax);
|
|
641
632
|
DISPOSE();
|
|
642
633
|
return value;
|
|
643
634
|
}
|
|
644
635
|
OP(ReturnString32) {
|
|
645
636
|
uint64_t rax = *(uint64_t *)base;
|
|
646
|
-
napi_value value =
|
|
637
|
+
napi_value value = NewString(call->env, (const char32_t *)rax);
|
|
647
638
|
DISPOSE();
|
|
648
639
|
return value;
|
|
649
640
|
}
|
|
650
641
|
OP(ReturnPointer) {
|
|
651
642
|
uint64_t rax = *(uint64_t *)base;
|
|
652
|
-
napi_value value =
|
|
643
|
+
napi_value value = WrapPointer(call->env, inst->type, (void *)rax);
|
|
653
644
|
DISPOSE();
|
|
654
645
|
return value;
|
|
655
646
|
}
|
|
656
647
|
OP(ReturnCallback) {
|
|
657
648
|
uint64_t rax = *(uint64_t *)base;
|
|
658
|
-
return
|
|
649
|
+
return WrapPointer(call->env, inst->type, (void *)rax);
|
|
659
650
|
}
|
|
660
651
|
OP(ReturnRecord) { K_UNREACHABLE(); return call->env.Null(); }
|
|
661
652
|
OP(ReturnUnion) { K_UNREACHABLE(); return call->env.Null(); }
|
|
662
653
|
OP(ReturnArray) { K_UNREACHABLE(); return call->env.Null(); }
|
|
663
654
|
OP(ReturnFloat32) {
|
|
664
655
|
float f = *(float *)base;
|
|
665
|
-
return
|
|
656
|
+
return NewFloat(call->env, f);
|
|
666
657
|
}
|
|
667
658
|
OP(ReturnFloat64) {
|
|
668
659
|
double d = *(double *)base;
|
|
669
|
-
return
|
|
660
|
+
return NewFloat(call->env, d);
|
|
670
661
|
}
|
|
671
662
|
OP(ReturnPrototype) { K_UNREACHABLE(); return call->env.Null(); }
|
|
672
663
|
OP(ReturnAggregateReg) { return DecodeObject(call->instance, base, inst->type); }
|
|
@@ -777,7 +768,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
777
768
|
uint64_t *xmm_ptr = gpr_ptr + 4;
|
|
778
769
|
uint64_t *stk_ptr = (uint64_t *)caller_sp;
|
|
779
770
|
|
|
780
|
-
uint8_t *return_ptr = !proto->ret.regular ? (uint8_t *)gpr_ptr[0] : nullptr;
|
|
771
|
+
uint8_t *return_ptr = !proto->ret.abi.regular ? (uint8_t *)gpr_ptr[0] : nullptr;
|
|
781
772
|
|
|
782
773
|
K_DEFER_N(err_guard) {
|
|
783
774
|
trampoline->state = -1;
|
|
@@ -888,56 +879,52 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
888
879
|
const char *str = *(const char **)(j < 4 ? gpr_ptr + j : stk_ptr);
|
|
889
880
|
stk_ptr += (j >= 4);
|
|
890
881
|
|
|
891
|
-
arguments[i] =
|
|
882
|
+
arguments[i] = NewString(env, str);
|
|
892
883
|
|
|
893
884
|
if (param.type->dispose) {
|
|
894
|
-
param.type->dispose(
|
|
885
|
+
param.type->dispose(instance, param.type, str);
|
|
895
886
|
}
|
|
896
887
|
} break;
|
|
897
888
|
case PrimitiveKind::String16: {
|
|
898
889
|
const char16_t *str16 = *(const char16_t **)(j < 4 ? gpr_ptr + j : stk_ptr);
|
|
899
890
|
stk_ptr += (j >= 4);
|
|
900
891
|
|
|
901
|
-
arguments[i] =
|
|
892
|
+
arguments[i] = NewString(env, str16);
|
|
902
893
|
|
|
903
894
|
if (param.type->dispose) {
|
|
904
|
-
param.type->dispose(
|
|
895
|
+
param.type->dispose(instance, param.type, str16);
|
|
905
896
|
}
|
|
906
897
|
} break;
|
|
907
898
|
case PrimitiveKind::String32: {
|
|
908
899
|
const char32_t *str32 = *(const char32_t **)(j < 4 ? gpr_ptr + j : stk_ptr);
|
|
909
900
|
stk_ptr += (j >= 4);
|
|
910
901
|
|
|
911
|
-
arguments[i] =
|
|
902
|
+
arguments[i] = NewString(env, str32);
|
|
912
903
|
|
|
913
904
|
if (param.type->dispose) {
|
|
914
|
-
param.type->dispose(
|
|
905
|
+
param.type->dispose(instance, param.type, str32);
|
|
915
906
|
}
|
|
916
907
|
} break;
|
|
917
908
|
case PrimitiveKind::Pointer: {
|
|
918
909
|
void *ptr2 = *(void **)(j < 4 ? gpr_ptr + j : stk_ptr);
|
|
919
910
|
stk_ptr += (j >= 4);
|
|
920
911
|
|
|
921
|
-
arguments[i] =
|
|
912
|
+
arguments[i] = WrapPointer(env, param.type->ref.type, ptr2);
|
|
922
913
|
|
|
923
914
|
if (param.type->dispose) {
|
|
924
|
-
param.type->dispose(
|
|
915
|
+
param.type->dispose(instance, param.type, ptr2);
|
|
925
916
|
}
|
|
926
917
|
} break;
|
|
927
918
|
case PrimitiveKind::Callback: {
|
|
928
919
|
void *ptr2 = *(void **)(j < 4 ? gpr_ptr + j : stk_ptr);
|
|
929
920
|
stk_ptr += (j >= 4);
|
|
930
921
|
|
|
931
|
-
arguments[i] =
|
|
932
|
-
|
|
933
|
-
if (param.type->dispose) {
|
|
934
|
-
param.type->dispose(env, param.type, ptr2);
|
|
935
|
-
}
|
|
922
|
+
arguments[i] = WrapPointer(env, param.type->ref.type, ptr2);
|
|
936
923
|
} break;
|
|
937
924
|
case PrimitiveKind::Record:
|
|
938
925
|
case PrimitiveKind::Union: {
|
|
939
926
|
uint8_t *ptr;
|
|
940
|
-
if (param.regular) {
|
|
927
|
+
if (param.abi.regular) {
|
|
941
928
|
ptr = (uint8_t *)(j < 4 ? gpr_ptr + j : stk_ptr);
|
|
942
929
|
} else {
|
|
943
930
|
ptr = *(uint8_t **)(j < 4 ? gpr_ptr + j : stk_ptr);
|
|
@@ -951,13 +938,13 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
951
938
|
float f = *(float *)(j < 4 ? xmm_ptr + j : stk_ptr);
|
|
952
939
|
stk_ptr += (j >= 4);
|
|
953
940
|
|
|
954
|
-
arguments[i] =
|
|
941
|
+
arguments[i] = NewFloat(env, f);
|
|
955
942
|
} break;
|
|
956
943
|
case PrimitiveKind::Float64: {
|
|
957
944
|
double d = *(double *)(j < 4 ? xmm_ptr + j : stk_ptr);
|
|
958
945
|
stk_ptr += (j >= 4);
|
|
959
946
|
|
|
960
|
-
arguments[i] =
|
|
947
|
+
arguments[i] = NewFloat(env, d);
|
|
961
948
|
} break;
|
|
962
949
|
|
|
963
950
|
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
@@ -1048,17 +1035,13 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
1048
1035
|
} break;
|
|
1049
1036
|
case PrimitiveKind::Record:
|
|
1050
1037
|
case PrimitiveKind::Union: {
|
|
1051
|
-
if (!IsObject(env, value)) [[unlikely]] {
|
|
1052
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
1053
|
-
return;
|
|
1054
|
-
}
|
|
1055
|
-
|
|
1056
1038
|
if (return_ptr) {
|
|
1057
|
-
if (!PushObject(value, type, return_ptr))
|
|
1039
|
+
if (!PushObject(value, type, return_ptr)) [[unlikely]]
|
|
1058
1040
|
return;
|
|
1059
1041
|
out_reg->rax = (uint64_t)return_ptr;
|
|
1060
1042
|
} else {
|
|
1061
|
-
PushObject(value, type, (uint8_t *)&out_reg->rax)
|
|
1043
|
+
if (!PushObject(value, type, (uint8_t *)&out_reg->rax)) [[unlikely]]
|
|
1044
|
+
return;
|
|
1062
1045
|
}
|
|
1063
1046
|
} break;
|
|
1064
1047
|
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|