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