koffi 2.15.0 → 2.16.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- 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 +4 -2
- package/doc/pages/misc.md +2 -0
- package/doc/templates/code.html +1 -2
- package/doc/templates/page.html +1 -2
- package/index.d.ts +11 -9
- package/index.js +9 -9
- package/indirect.js +9 -9
- package/lib/native/base/base.cc +79 -44
- package/lib/native/base/base.hh +31 -33
- package/package.json +2 -2
- package/src/cnoke/assets/FindCNoke.cmake +16 -10
- package/src/cnoke/assets/win_delay_hook.c +4 -0
- package/src/cnoke/src/builder.js +49 -46
- package/src/koffi/CMakeLists.txt +18 -8
- package/src/koffi/src/abi_arm32.cc +222 -219
- package/src/koffi/src/abi_arm32_asm.S +1 -29
- package/src/koffi/src/abi_arm64.cc +257 -235
- package/src/koffi/src/abi_arm64_asm.S +1 -32
- package/src/koffi/src/abi_arm64_asm.asm +1 -23
- package/src/koffi/src/abi_loong64_asm.S +1 -25
- package/src/koffi/src/abi_riscv64.cc +220 -217
- package/src/koffi/src/abi_riscv64_asm.S +1 -25
- package/src/koffi/src/abi_x64_sysv.cc +196 -192
- package/src/koffi/src/abi_x64_sysv_asm.S +1 -31
- package/src/koffi/src/abi_x64_win.cc +188 -172
- package/src/koffi/src/abi_x64_win_asm.S +144 -0
- package/src/koffi/src/abi_x64_win_asm.asm +1 -21
- package/src/koffi/src/abi_x86.cc +224 -189
- package/src/koffi/src/abi_x86_asm.S +6 -25
- package/src/koffi/src/abi_x86_asm.asm +9 -22
- package/src/koffi/src/call.cc +246 -428
- package/src/koffi/src/call.hh +9 -8
- package/src/koffi/src/ffi.cc +142 -88
- package/src/koffi/src/ffi.hh +13 -59
- package/src/koffi/src/primitives.inc +39 -0
- package/src/koffi/src/trampolines/armasm.inc +0 -32770
- package/src/koffi/src/trampolines/gnu.inc +0 -24578
- package/src/koffi/src/trampolines/masm32.inc +0 -32770
- package/src/koffi/src/trampolines/masm64.inc +0 -32770
- package/src/koffi/src/trampolines/prototypes.inc +16385 -16385
- package/src/koffi/src/util.cc +155 -112
- package/src/koffi/src/util.hh +77 -40
- package/vendor/node-api-headers/CHANGELOG.md +22 -0
- package/vendor/node-api-headers/README.md +6 -17
- package/vendor/node-api-headers/include/js_native_api.h +3 -13
- package/vendor/node-api-headers/include/js_native_api_types.h +15 -0
- package/vendor/node-api-headers/include/node_api.h +0 -4
- package/vendor/node-api-headers/include/node_api_types.h +6 -0
- package/vendor/node-api-headers/package.json +1 -1
- package/vendor/node-api-headers/scripts/update-headers.js +6 -0
package/src/koffi/src/util.cc
CHANGED
|
@@ -43,7 +43,7 @@ MagicUnion::MagicUnion(const Napi::CallbackInfo &info)
|
|
|
43
43
|
Napi::Env env = info.Env();
|
|
44
44
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
45
45
|
|
|
46
|
-
active_symbol
|
|
46
|
+
active_symbol.Reset(instance->active_symbol.Value(), 1);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
void MagicUnion::SetRaw(const uint8_t *ptr)
|
|
@@ -51,7 +51,7 @@ void MagicUnion::SetRaw(const uint8_t *ptr)
|
|
|
51
51
|
raw.RemoveFrom(0);
|
|
52
52
|
raw.Append(MakeSpan(ptr, type->size));
|
|
53
53
|
|
|
54
|
-
Value().Set(active_symbol, Env().Undefined());
|
|
54
|
+
Value().Set(active_symbol.Value(), Env().Undefined());
|
|
55
55
|
active_idx = -1;
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -63,7 +63,7 @@ Napi::Value MagicUnion::Getter(const Napi::CallbackInfo &info)
|
|
|
63
63
|
Napi::Value value;
|
|
64
64
|
|
|
65
65
|
if (idx == active_idx) {
|
|
66
|
-
value = Value().Get(active_symbol);
|
|
66
|
+
value = Value().Get(active_symbol.Value());
|
|
67
67
|
} else {
|
|
68
68
|
Napi::Env env = info.Env();
|
|
69
69
|
|
|
@@ -74,7 +74,7 @@ Napi::Value MagicUnion::Getter(const Napi::CallbackInfo &info)
|
|
|
74
74
|
|
|
75
75
|
value = Decode(env, raw.ptr, member.type);
|
|
76
76
|
|
|
77
|
-
Value().Set(active_symbol, value);
|
|
77
|
+
Value().Set(active_symbol.Value(), value);
|
|
78
78
|
active_idx = idx;
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -86,7 +86,7 @@ void MagicUnion::Setter(const Napi::CallbackInfo &info, const Napi::Value &value
|
|
|
86
86
|
{
|
|
87
87
|
Size idx = (Size)info.Data();
|
|
88
88
|
|
|
89
|
-
Value().Set(active_symbol, value);
|
|
89
|
+
Value().Set(active_symbol.Value(), value);
|
|
90
90
|
active_idx = idx;
|
|
91
91
|
|
|
92
92
|
raw.Clear();
|
|
@@ -532,7 +532,7 @@ const char *GetValueType(const InstanceData *instance, Napi::Value value)
|
|
|
532
532
|
if (CheckValueTag(value, &TypeInfoMarker))
|
|
533
533
|
return "Type";
|
|
534
534
|
for (const TypeInfo &type: instance->types) {
|
|
535
|
-
if (type.ref.
|
|
535
|
+
if (type.ref.type && CheckValueTag(value, type.ref.type))
|
|
536
536
|
return type.name;
|
|
537
537
|
}
|
|
538
538
|
|
|
@@ -549,6 +549,7 @@ const char *GetValueType(const InstanceData *instance, Napi::Value value)
|
|
|
549
549
|
case napi_uint16_array: return "Uint16Array";
|
|
550
550
|
case napi_int32_array: return "Int32Array";
|
|
551
551
|
case napi_uint32_array: return "Uint32Array";
|
|
552
|
+
case napi_float16_array: return "Float16Array";
|
|
552
553
|
case napi_float32_array: return "Float32Array";
|
|
553
554
|
case napi_float64_array: return "Float64Array";
|
|
554
555
|
case napi_bigint64_array: return "BigInt64Array";
|
|
@@ -856,8 +857,7 @@ void DecodeObject(Napi::Object obj, const uint8_t *origin, const TypeInfo *type)
|
|
|
856
857
|
const char32_t *str32 = *(const char32_t **)src;
|
|
857
858
|
obj.Set(member.name, str32 ? MakeStringFromUTF32(env, str32) : env.Null());
|
|
858
859
|
} break;
|
|
859
|
-
case PrimitiveKind::Pointer:
|
|
860
|
-
case PrimitiveKind::Callback: {
|
|
860
|
+
case PrimitiveKind::Pointer: {
|
|
861
861
|
void *ptr2 = *(void **)src;
|
|
862
862
|
|
|
863
863
|
if (member.countedby >= 0) {
|
|
@@ -866,19 +866,25 @@ void DecodeObject(Napi::Object obj, const uint8_t *origin, const TypeInfo *type)
|
|
|
866
866
|
|
|
867
867
|
Napi::Value value = DecodeArray(env, (const uint8_t *)ptr2, member.type, len);
|
|
868
868
|
obj.Set(member.name, value);
|
|
869
|
-
} else if (ptr2) {
|
|
870
|
-
Napi::External<void> external = Napi::External<void>::New(env, ptr2);
|
|
871
|
-
SetValueTag(external, member.type->ref.marker);
|
|
872
|
-
|
|
873
|
-
obj.Set(member.name, external);
|
|
874
869
|
} else {
|
|
875
|
-
|
|
870
|
+
Napi::Value p = ptr2 ? WrapPointer(env, member.type->ref.type, ptr2) : env.Null();
|
|
871
|
+
obj.Set(member.name, p);
|
|
876
872
|
}
|
|
877
873
|
|
|
878
874
|
if (member.type->dispose) {
|
|
879
875
|
member.type->dispose(env, member.type, ptr2);
|
|
880
876
|
}
|
|
881
877
|
} break;
|
|
878
|
+
case PrimitiveKind::Callback: {
|
|
879
|
+
void *ptr2 = *(void **)src;
|
|
880
|
+
|
|
881
|
+
Napi::Value p = ptr2 ? WrapCallback(env, member.type->ref.type, ptr2) : env.Null();
|
|
882
|
+
obj.Set(member.name, p);
|
|
883
|
+
|
|
884
|
+
if (member.type->dispose) {
|
|
885
|
+
member.type->dispose(env, member.type, ptr2);
|
|
886
|
+
}
|
|
887
|
+
} break;
|
|
882
888
|
case PrimitiveKind::Record:
|
|
883
889
|
case PrimitiveKind::Union: {
|
|
884
890
|
Napi::Object obj2 = DecodeObject(env, src, member.type);
|
|
@@ -935,7 +941,8 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
|
|
|
935
941
|
\
|
|
936
942
|
return array; \
|
|
937
943
|
} while (false)
|
|
938
|
-
|
|
944
|
+
|
|
945
|
+
#define POP_NUMBERS(TypedArrayType, CType) \
|
|
939
946
|
do { \
|
|
940
947
|
if (type->hint == ArrayHint::Array) { \
|
|
941
948
|
POP_ARRAY({ \
|
|
@@ -951,7 +958,7 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
|
|
|
951
958
|
return array; \
|
|
952
959
|
} \
|
|
953
960
|
} while (false)
|
|
954
|
-
#define
|
|
961
|
+
#define POP_NUMBERS_SWAP(TypedArrayType, CType) \
|
|
955
962
|
do { \
|
|
956
963
|
if (type->hint == ArrayHint::Array) { \
|
|
957
964
|
POP_ARRAY({ \
|
|
@@ -987,9 +994,9 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
|
|
|
987
994
|
return str;
|
|
988
995
|
}
|
|
989
996
|
|
|
990
|
-
|
|
997
|
+
POP_NUMBERS(Int8Array, int8_t);
|
|
991
998
|
} break;
|
|
992
|
-
case PrimitiveKind::UInt8: {
|
|
999
|
+
case PrimitiveKind::UInt8: { POP_NUMBERS(Uint8Array, uint8_t); } break;
|
|
993
1000
|
case PrimitiveKind::Int16: {
|
|
994
1001
|
if (type->hint == ArrayHint::String) {
|
|
995
1002
|
const char16_t *ptr = (const char16_t *)origin;
|
|
@@ -999,11 +1006,11 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
|
|
|
999
1006
|
return str;
|
|
1000
1007
|
}
|
|
1001
1008
|
|
|
1002
|
-
|
|
1009
|
+
POP_NUMBERS(Int16Array, int16_t);
|
|
1003
1010
|
} break;
|
|
1004
|
-
case PrimitiveKind::Int16S: {
|
|
1005
|
-
case PrimitiveKind::UInt16: {
|
|
1006
|
-
case PrimitiveKind::UInt16S: {
|
|
1011
|
+
case PrimitiveKind::Int16S: { POP_NUMBERS_SWAP(Int16Array, int16_t); } break;
|
|
1012
|
+
case PrimitiveKind::UInt16: { POP_NUMBERS(Uint16Array, uint16_t); } break;
|
|
1013
|
+
case PrimitiveKind::UInt16S: { POP_NUMBERS_SWAP(Uint16Array, uint16_t); } break;
|
|
1007
1014
|
case PrimitiveKind::Int32: {
|
|
1008
1015
|
if (type->hint == ArrayHint::String) {
|
|
1009
1016
|
const char32_t *ptr = (const char32_t *)origin;
|
|
@@ -1013,11 +1020,11 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
|
|
|
1013
1020
|
return str;
|
|
1014
1021
|
}
|
|
1015
1022
|
|
|
1016
|
-
|
|
1023
|
+
POP_NUMBERS(Int32Array, int32_t);
|
|
1017
1024
|
} break;
|
|
1018
|
-
case PrimitiveKind::Int32S: {
|
|
1019
|
-
case PrimitiveKind::UInt32: {
|
|
1020
|
-
case PrimitiveKind::UInt32S: {
|
|
1025
|
+
case PrimitiveKind::Int32S: { POP_NUMBERS_SWAP(Int32Array, int32_t); } break;
|
|
1026
|
+
case PrimitiveKind::UInt32: { POP_NUMBERS(Uint32Array, uint32_t); } break;
|
|
1027
|
+
case PrimitiveKind::UInt32S: { POP_NUMBERS_SWAP(Uint32Array, uint32_t); } break;
|
|
1021
1028
|
case PrimitiveKind::Int64: {
|
|
1022
1029
|
POP_ARRAY({
|
|
1023
1030
|
int64_t v = *(int64_t *)src;
|
|
@@ -1060,19 +1067,20 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
|
|
|
1060
1067
|
array.Set(i, str32 ? MakeStringFromUTF32(env, str32) : env.Null());
|
|
1061
1068
|
});
|
|
1062
1069
|
} break;
|
|
1063
|
-
case PrimitiveKind::Pointer:
|
|
1064
|
-
case PrimitiveKind::Callback: {
|
|
1070
|
+
case PrimitiveKind::Pointer: {
|
|
1065
1071
|
POP_ARRAY({
|
|
1066
1072
|
void *ptr2 = *(void **)src;
|
|
1067
1073
|
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1074
|
+
Napi::Value p = ptr2 ? WrapPointer(env, type->ref.type->ref.type, ptr2) : env.Null();
|
|
1075
|
+
array.Set(i, p);
|
|
1076
|
+
});
|
|
1077
|
+
} break;
|
|
1078
|
+
case PrimitiveKind::Callback: {
|
|
1079
|
+
POP_ARRAY({
|
|
1080
|
+
void *ptr2 = *(void **)src;
|
|
1071
1081
|
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
array.Set(i, env.Null());
|
|
1075
|
-
}
|
|
1082
|
+
Napi::Value p = ptr2 ? WrapCallback(env, type->ref.type->ref.type, ptr2) : env.Null();
|
|
1083
|
+
array.Set(i, p);
|
|
1076
1084
|
});
|
|
1077
1085
|
} break;
|
|
1078
1086
|
case PrimitiveKind::Record:
|
|
@@ -1088,14 +1096,15 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
|
|
|
1088
1096
|
array.Set(i, value);
|
|
1089
1097
|
});
|
|
1090
1098
|
} break;
|
|
1091
|
-
case PrimitiveKind::Float32: {
|
|
1092
|
-
case PrimitiveKind::Float64: {
|
|
1099
|
+
case PrimitiveKind::Float32: { POP_NUMBERS(Float32Array, float); } break;
|
|
1100
|
+
case PrimitiveKind::Float64: { POP_NUMBERS(Float64Array, double); } break;
|
|
1093
1101
|
|
|
1094
1102
|
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
1095
1103
|
}
|
|
1096
1104
|
|
|
1097
|
-
#undef
|
|
1098
|
-
#undef
|
|
1105
|
+
#undef POP_NUMBERS_SWAP
|
|
1106
|
+
#undef POP_NUMBERS
|
|
1107
|
+
|
|
1099
1108
|
#undef POP_ARRAY
|
|
1100
1109
|
|
|
1101
1110
|
K_UNREACHABLE();
|
|
@@ -1130,14 +1139,15 @@ void DecodeNormalArray(Napi::Array array, const uint8_t *origin, const TypeInfo
|
|
|
1130
1139
|
offset += ref->size; \
|
|
1131
1140
|
} \
|
|
1132
1141
|
} while (false)
|
|
1133
|
-
|
|
1142
|
+
|
|
1143
|
+
#define POP_NUMBERS(CType) \
|
|
1134
1144
|
do { \
|
|
1135
1145
|
POP_ARRAY({ \
|
|
1136
1146
|
double d = (double)*(CType *)src; \
|
|
1137
1147
|
array.Set(i, Napi::Number::New(env, d)); \
|
|
1138
1148
|
}); \
|
|
1139
1149
|
} while (false)
|
|
1140
|
-
#define
|
|
1150
|
+
#define POP_NUMBERS_SWAP(CType) \
|
|
1141
1151
|
do { \
|
|
1142
1152
|
POP_ARRAY({ \
|
|
1143
1153
|
CType v = *(CType *)src; \
|
|
@@ -1155,16 +1165,16 @@ void DecodeNormalArray(Napi::Array array, const uint8_t *origin, const TypeInfo
|
|
|
1155
1165
|
array.Set(i, Napi::Boolean::New(env, b));
|
|
1156
1166
|
});
|
|
1157
1167
|
} break;
|
|
1158
|
-
case PrimitiveKind::Int8: {
|
|
1159
|
-
case PrimitiveKind::UInt8: {
|
|
1160
|
-
case PrimitiveKind::Int16: {
|
|
1161
|
-
case PrimitiveKind::Int16S: {
|
|
1162
|
-
case PrimitiveKind::UInt16: {
|
|
1163
|
-
case PrimitiveKind::UInt16S: {
|
|
1164
|
-
case PrimitiveKind::Int32: {
|
|
1165
|
-
case PrimitiveKind::Int32S: {
|
|
1166
|
-
case PrimitiveKind::UInt32: {
|
|
1167
|
-
case PrimitiveKind::UInt32S: {
|
|
1168
|
+
case PrimitiveKind::Int8: { POP_NUMBERS(int8_t); } break;
|
|
1169
|
+
case PrimitiveKind::UInt8: { POP_NUMBERS(uint8_t); } break;
|
|
1170
|
+
case PrimitiveKind::Int16: { POP_NUMBERS(int16_t); } break;
|
|
1171
|
+
case PrimitiveKind::Int16S: { POP_NUMBERS_SWAP(int16_t); } break;
|
|
1172
|
+
case PrimitiveKind::UInt16: { POP_NUMBERS(uint16_t); } break;
|
|
1173
|
+
case PrimitiveKind::UInt16S: { POP_NUMBERS_SWAP(uint16_t); } break;
|
|
1174
|
+
case PrimitiveKind::Int32: { POP_NUMBERS(int32_t); } break;
|
|
1175
|
+
case PrimitiveKind::Int32S: { POP_NUMBERS_SWAP(int32_t); } break;
|
|
1176
|
+
case PrimitiveKind::UInt32: { POP_NUMBERS(uint32_t); } break;
|
|
1177
|
+
case PrimitiveKind::UInt32S: { POP_NUMBERS_SWAP(uint32_t); } break;
|
|
1168
1178
|
case PrimitiveKind::Int64: {
|
|
1169
1179
|
POP_ARRAY({
|
|
1170
1180
|
int64_t v = *(int64_t *)src;
|
|
@@ -1219,19 +1229,24 @@ void DecodeNormalArray(Napi::Array array, const uint8_t *origin, const TypeInfo
|
|
|
1219
1229
|
}
|
|
1220
1230
|
});
|
|
1221
1231
|
} break;
|
|
1222
|
-
case PrimitiveKind::Pointer:
|
|
1223
|
-
case PrimitiveKind::Callback: {
|
|
1232
|
+
case PrimitiveKind::Pointer: {
|
|
1224
1233
|
POP_ARRAY({
|
|
1225
1234
|
void *ptr2 = *(void **)src;
|
|
1226
1235
|
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
SetValueTag(external, ref->ref.marker);
|
|
1236
|
+
Napi::Value p = ptr2 ? WrapPointer(env, ref->ref.type, ptr2) : env.Null();
|
|
1237
|
+
array.Set(i, p);
|
|
1230
1238
|
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
array.Set(i, env.Null());
|
|
1239
|
+
if (ref->dispose) {
|
|
1240
|
+
ref->dispose(env, ref, ptr2);
|
|
1234
1241
|
}
|
|
1242
|
+
});
|
|
1243
|
+
} break;
|
|
1244
|
+
case PrimitiveKind::Callback: {
|
|
1245
|
+
POP_ARRAY({
|
|
1246
|
+
void *ptr2 = *(void **)src;
|
|
1247
|
+
|
|
1248
|
+
Napi::Value p = ptr2 ? WrapCallback(env, ref->ref.type, ptr2) : env.Null();
|
|
1249
|
+
array.Set(i, p);
|
|
1235
1250
|
|
|
1236
1251
|
if (ref->dispose) {
|
|
1237
1252
|
ref->dispose(env, ref, ptr2);
|
|
@@ -1251,14 +1266,15 @@ void DecodeNormalArray(Napi::Array array, const uint8_t *origin, const TypeInfo
|
|
|
1251
1266
|
array.Set(i, value);
|
|
1252
1267
|
});
|
|
1253
1268
|
} break;
|
|
1254
|
-
case PrimitiveKind::Float32: {
|
|
1255
|
-
case PrimitiveKind::Float64: {
|
|
1269
|
+
case PrimitiveKind::Float32: { POP_NUMBERS(float); } break;
|
|
1270
|
+
case PrimitiveKind::Float64: { POP_NUMBERS(double); } break;
|
|
1256
1271
|
|
|
1257
1272
|
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
1258
1273
|
}
|
|
1259
1274
|
|
|
1260
|
-
#undef
|
|
1261
|
-
#undef
|
|
1275
|
+
#undef POP_NUMBERS_SWAP
|
|
1276
|
+
#undef POP_NUMBERS
|
|
1277
|
+
|
|
1262
1278
|
#undef POP_ARRAY
|
|
1263
1279
|
}
|
|
1264
1280
|
|
|
@@ -1293,14 +1309,9 @@ Napi::Value Decode(Napi::Value value, Size offset, const TypeInfo *type, const S
|
|
|
1293
1309
|
Napi::Env env = value.Env();
|
|
1294
1310
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
1295
1311
|
|
|
1296
|
-
const uint8_t *
|
|
1297
|
-
|
|
1298
|
-
if (value.IsExternal()) {
|
|
1299
|
-
Napi::External<void> external = value.As<Napi::External<void>>();
|
|
1300
|
-
ptr = (const uint8_t *)external.Data();
|
|
1301
|
-
} else if (IsRawBuffer(value)) {
|
|
1302
|
-
Span<uint8_t> buffer = GetRawBuffer(value);
|
|
1312
|
+
const uint8_t *src = nullptr;
|
|
1303
1313
|
|
|
1314
|
+
if (Span<uint8_t> buffer = {}; TryBuffer(value, &buffer)) {
|
|
1304
1315
|
if (offset < 0) [[unlikely]] {
|
|
1305
1316
|
ThrowError<Napi::Error>(env, "Offset must be >= 0");
|
|
1306
1317
|
return env.Null();
|
|
@@ -1311,17 +1322,19 @@ Napi::Value Decode(Napi::Value value, Size offset, const TypeInfo *type, const S
|
|
|
1311
1322
|
return env.Null();
|
|
1312
1323
|
}
|
|
1313
1324
|
|
|
1314
|
-
|
|
1325
|
+
src = (const uint8_t *)buffer.ptr;
|
|
1326
|
+
} else if (void *ptr = nullptr; TryPointer(value, &ptr)) {
|
|
1327
|
+
src = (const uint8_t *)ptr;
|
|
1315
1328
|
} else {
|
|
1316
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for variable, expected
|
|
1329
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for variable, expected pointer", GetValueType(instance, value));
|
|
1317
1330
|
return env.Null();
|
|
1318
1331
|
}
|
|
1319
1332
|
|
|
1320
|
-
if (!
|
|
1333
|
+
if (!src)
|
|
1321
1334
|
return env.Null();
|
|
1322
|
-
|
|
1335
|
+
src += offset;
|
|
1323
1336
|
|
|
1324
|
-
Napi::Value ret = Decode(env,
|
|
1337
|
+
Napi::Value ret = Decode(env, src, type, len);
|
|
1325
1338
|
return ret;
|
|
1326
1339
|
}
|
|
1327
1340
|
|
|
@@ -1428,10 +1441,13 @@ Napi::Value Decode(Napi::Env env, const uint8_t *ptr, const TypeInfo *type, cons
|
|
|
1428
1441
|
return str32 ? MakeStringFromUTF32(env, str32) : env.Null();
|
|
1429
1442
|
}
|
|
1430
1443
|
} break;
|
|
1431
|
-
case PrimitiveKind::Pointer:
|
|
1444
|
+
case PrimitiveKind::Pointer: {
|
|
1445
|
+
void *ptr2 = *(void **)ptr;
|
|
1446
|
+
return ptr2 ? WrapPointer(env, type->ref.type, ptr2) : env.Null();
|
|
1447
|
+
} break;
|
|
1432
1448
|
case PrimitiveKind::Callback: {
|
|
1433
1449
|
void *ptr2 = *(void **)ptr;
|
|
1434
|
-
return ptr2 ?
|
|
1450
|
+
return ptr2 ? WrapCallback(env, type->ref.type, ptr2) : env.Null();
|
|
1435
1451
|
} break;
|
|
1436
1452
|
case PrimitiveKind::Record:
|
|
1437
1453
|
case PrimitiveKind::Union: {
|
|
@@ -1461,10 +1477,12 @@ Napi::Value Decode(Napi::Env env, const uint8_t *ptr, const TypeInfo *type, cons
|
|
|
1461
1477
|
|
|
1462
1478
|
memcpy((void *)func, proto, K_SIZE(*proto));
|
|
1463
1479
|
memset((void *)&func->parameters, 0, K_SIZE(func->parameters));
|
|
1464
|
-
func->
|
|
1480
|
+
memset((void *)&func->primitives, 0, K_SIZE(func->primitives));
|
|
1465
1481
|
|
|
1466
1482
|
func->name = "<anonymous>";
|
|
1467
1483
|
func->native = (void *)ptr;
|
|
1484
|
+
func->parameters = proto->parameters;
|
|
1485
|
+
func->primitives = proto->primitives;
|
|
1468
1486
|
|
|
1469
1487
|
// Fix back parameter offset
|
|
1470
1488
|
for (ParameterInfo ¶m: func->parameters) {
|
|
@@ -1488,14 +1506,9 @@ bool Encode(Napi::Value ref, Size offset, Napi::Value value, const TypeInfo *typ
|
|
|
1488
1506
|
Napi::Env env = ref.Env();
|
|
1489
1507
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
1490
1508
|
|
|
1491
|
-
uint8_t *
|
|
1492
|
-
|
|
1493
|
-
if (ref.IsExternal()) {
|
|
1494
|
-
Napi::External<void> external = ref.As<Napi::External<void>>();
|
|
1495
|
-
ptr = (uint8_t *)external.Data();
|
|
1496
|
-
} else if (IsRawBuffer(ref)) {
|
|
1497
|
-
Span<uint8_t> buffer = GetRawBuffer(ref);
|
|
1509
|
+
uint8_t *dest = nullptr;
|
|
1498
1510
|
|
|
1511
|
+
if (Span<uint8_t> buffer = {}; TryBuffer(ref, &buffer)) {
|
|
1499
1512
|
if (offset < 0) [[unlikely]] {
|
|
1500
1513
|
ThrowError<Napi::Error>(env, "Offset must be >= 0");
|
|
1501
1514
|
return env.Null();
|
|
@@ -1506,19 +1519,21 @@ bool Encode(Napi::Value ref, Size offset, Napi::Value value, const TypeInfo *typ
|
|
|
1506
1519
|
return env.Null();
|
|
1507
1520
|
}
|
|
1508
1521
|
|
|
1509
|
-
|
|
1522
|
+
dest = (uint8_t *)buffer.ptr;
|
|
1523
|
+
} else if (void *ptr = nullptr; TryPointer(ref, &ptr)) {
|
|
1524
|
+
dest = (uint8_t *)ptr;
|
|
1510
1525
|
} else {
|
|
1511
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for reference, expected
|
|
1526
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for reference, expected pointer", GetValueType(instance, ref));
|
|
1512
1527
|
return env.Null();
|
|
1513
1528
|
}
|
|
1514
1529
|
|
|
1515
|
-
if (!
|
|
1530
|
+
if (!dest) [[unlikely]] {
|
|
1516
1531
|
ThrowError<Napi::Error>(env, "Cannot encode data in NULL pointer");
|
|
1517
1532
|
return env.Null();
|
|
1518
1533
|
}
|
|
1519
|
-
|
|
1534
|
+
dest += offset;
|
|
1520
1535
|
|
|
1521
|
-
return Encode(env,
|
|
1536
|
+
return Encode(env, dest, value, type, len);
|
|
1522
1537
|
}
|
|
1523
1538
|
|
|
1524
1539
|
bool Encode(Napi::Env env, uint8_t *origin, Napi::Value value, const TypeInfo *type, const Size *len)
|
|
@@ -1542,22 +1557,24 @@ bool Encode(Napi::Env env, uint8_t *origin, Napi::Value value, const TypeInfo *t
|
|
|
1542
1557
|
|
|
1543
1558
|
#define PUSH_INTEGER(CType) \
|
|
1544
1559
|
do { \
|
|
1545
|
-
|
|
1560
|
+
CType v; \
|
|
1561
|
+
\
|
|
1562
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
1546
1563
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
1547
1564
|
return false; \
|
|
1548
1565
|
} \
|
|
1549
1566
|
\
|
|
1550
|
-
CType v = GetNumber<CType>(value); \
|
|
1551
1567
|
*(CType *)origin = v; \
|
|
1552
1568
|
} while (false)
|
|
1553
1569
|
#define PUSH_INTEGER_SWAP(CType) \
|
|
1554
1570
|
do { \
|
|
1555
|
-
|
|
1571
|
+
CType v; \
|
|
1572
|
+
\
|
|
1573
|
+
if (!TryNumber(value, &v)) [[unlikely]] { \
|
|
1556
1574
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
1557
1575
|
return false; \
|
|
1558
1576
|
} \
|
|
1559
1577
|
\
|
|
1560
|
-
CType v = GetNumber<CType>(value); \
|
|
1561
1578
|
*(CType *)origin = ReverseBytes(v); \
|
|
1562
1579
|
} while (false)
|
|
1563
1580
|
|
|
@@ -1565,12 +1582,14 @@ bool Encode(Napi::Env env, uint8_t *origin, Napi::Value value, const TypeInfo *t
|
|
|
1565
1582
|
case PrimitiveKind::Void: { K_UNREACHABLE(); } break;
|
|
1566
1583
|
|
|
1567
1584
|
case PrimitiveKind::Bool: {
|
|
1568
|
-
|
|
1585
|
+
bool b;
|
|
1586
|
+
napi_status status = napi_get_value_bool(env, value, &b);
|
|
1587
|
+
|
|
1588
|
+
if (status != napi_ok) [[unlikely]] {
|
|
1569
1589
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
|
|
1570
1590
|
return false;
|
|
1571
1591
|
}
|
|
1572
1592
|
|
|
1573
|
-
bool b = value.As<Napi::Boolean>();
|
|
1574
1593
|
*(bool *)origin = b;
|
|
1575
1594
|
} break;
|
|
1576
1595
|
case PrimitiveKind::Int8: { PUSH_INTEGER(int8_t); } break;
|
|
@@ -1628,8 +1647,7 @@ bool Encode(Napi::Env env, uint8_t *origin, Napi::Value value, const TypeInfo *t
|
|
|
1628
1647
|
Napi::Array array = value.As<Napi::Array>();
|
|
1629
1648
|
if (!call.PushNormalArray(array, type, type->size, origin))
|
|
1630
1649
|
return false;
|
|
1631
|
-
} else if (
|
|
1632
|
-
Span<const uint8_t> buffer = GetRawBuffer(value);
|
|
1650
|
+
} else if (Span<uint8_t> buffer = {}; TryBuffer(value, &buffer)) {
|
|
1633
1651
|
call.PushBuffer(buffer, type, origin);
|
|
1634
1652
|
} else if (value.IsString()) {
|
|
1635
1653
|
if (!call.PushStringArray(value, type, origin))
|
|
@@ -1640,35 +1658,34 @@ bool Encode(Napi::Env env, uint8_t *origin, Napi::Value value, const TypeInfo *t
|
|
|
1640
1658
|
}
|
|
1641
1659
|
} break;
|
|
1642
1660
|
case PrimitiveKind::Float32: {
|
|
1643
|
-
|
|
1661
|
+
float f;
|
|
1662
|
+
|
|
1663
|
+
if (!TryNumber(value, &f)) [[unlikely]] {
|
|
1644
1664
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
1645
1665
|
return false;
|
|
1646
1666
|
}
|
|
1647
1667
|
|
|
1648
|
-
float f = GetNumber<float>(value);
|
|
1649
1668
|
*(float *)origin = f;
|
|
1650
1669
|
} break;
|
|
1651
1670
|
case PrimitiveKind::Float64: {
|
|
1652
|
-
|
|
1671
|
+
double d;
|
|
1672
|
+
|
|
1673
|
+
if (!TryNumber(value, &d)) [[unlikely]] {
|
|
1653
1674
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
1654
1675
|
return false;
|
|
1655
1676
|
}
|
|
1656
1677
|
|
|
1657
|
-
double d = GetNumber<double>(value);
|
|
1658
1678
|
*(double *)origin = d;
|
|
1659
1679
|
} break;
|
|
1660
1680
|
case PrimitiveKind::Callback: {
|
|
1661
1681
|
void *ptr;
|
|
1662
1682
|
|
|
1663
|
-
if (value
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
ptr = nullptr;
|
|
1670
|
-
} else {
|
|
1671
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected %2", GetValueType(instance, value), type->name);
|
|
1683
|
+
if (!TryPointer(value, &ptr)) [[unlikely]] {
|
|
1684
|
+
if (value.IsFunction()) {
|
|
1685
|
+
ThrowError<Napi::Error>(env, "Cannot encode non-registered callback");
|
|
1686
|
+
} else {
|
|
1687
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected %2", GetValueType(instance, value), type->name);
|
|
1688
|
+
}
|
|
1672
1689
|
return false;
|
|
1673
1690
|
}
|
|
1674
1691
|
|
|
@@ -1740,6 +1757,32 @@ Napi::Function WrapFunction(Napi::Env env, const FunctionInfo *func)
|
|
|
1740
1757
|
return wrapper;
|
|
1741
1758
|
}
|
|
1742
1759
|
|
|
1760
|
+
Napi::Value WrapPointer(Napi::Env env, const TypeInfo *ref, void *ptr)
|
|
1761
|
+
{
|
|
1762
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
1763
|
+
|
|
1764
|
+
if (instance->config.fast_pointers) {
|
|
1765
|
+
Napi::BigInt big = Napi::BigInt::New(env, (uint64_t)(uintptr_t)ptr);
|
|
1766
|
+
return big;
|
|
1767
|
+
} else {
|
|
1768
|
+
Napi::External<void> external = Napi::External<void>::New(env, ptr);
|
|
1769
|
+
return external;
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
Napi::Value WrapCallback(Napi::Env env, const TypeInfo *ref, void *ptr)
|
|
1774
|
+
{
|
|
1775
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
1776
|
+
|
|
1777
|
+
if (instance->config.fast_callbacks) {
|
|
1778
|
+
Napi::BigInt big = Napi::BigInt::New(env, (uint64_t)(uintptr_t)ptr);
|
|
1779
|
+
return big;
|
|
1780
|
+
} else {
|
|
1781
|
+
Napi::External<void> external = Napi::External<void>::New(env, ptr);
|
|
1782
|
+
return external;
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1743
1786
|
bool DetectCallConvention(Span<const char> name, CallConvention *out_convention)
|
|
1744
1787
|
{
|
|
1745
1788
|
if (name == "__cdecl") {
|
|
@@ -1796,7 +1839,7 @@ void DumpMemory(const char *type, Span<const uint8_t> bytes)
|
|
|
1796
1839
|
PrintLn(StdErr, "%1 at 0x%2 (%3):", type, bytes.ptr, FmtMemSize(bytes.len));
|
|
1797
1840
|
|
|
1798
1841
|
for (const uint8_t *ptr = bytes.begin(); ptr < bytes.end();) {
|
|
1799
|
-
Print(StdErr, " [0x%1 %2 %3] ",
|
|
1842
|
+
Print(StdErr, " [0x%1 %2 %3] ", FmtHex((uintptr_t)ptr, 16),
|
|
1800
1843
|
FmtInt((ptr - bytes.begin()) / sizeof(void *), 4, ' '),
|
|
1801
1844
|
FmtInt(ptr - bytes.begin(), 4, ' '));
|
|
1802
1845
|
for (int i = 0; ptr < bytes.end() && i < (int)sizeof(void *); i++, ptr++) {
|