koffi 2.5.0-beta.2 → 2.5.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 +20 -0
- package/build/2.5.1/koffi_darwin_arm64/koffi.node +0 -0
- package/build/{2.5.0-beta.2 → 2.5.1}/koffi_darwin_x64/koffi.node +0 -0
- package/build/{2.5.0-beta.2 → 2.5.1}/koffi_freebsd_arm64/koffi.node +0 -0
- package/build/{2.5.0-beta.2 → 2.5.1}/koffi_freebsd_ia32/koffi.node +0 -0
- package/build/{2.5.0-beta.2 → 2.5.1}/koffi_freebsd_x64/koffi.node +0 -0
- package/build/2.5.1/koffi_linux_arm32hf/koffi.node +0 -0
- package/build/2.5.1/koffi_linux_arm64/koffi.node +0 -0
- package/build/{2.5.0-beta.2 → 2.5.1}/koffi_linux_ia32/koffi.node +0 -0
- package/build/{2.5.0-beta.2 → 2.5.1}/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/build/{2.5.0-beta.2 → 2.5.1}/koffi_linux_x64/koffi.node +0 -0
- package/build/{2.5.0-beta.2 → 2.5.1}/koffi_openbsd_ia32/koffi.node +0 -0
- package/build/{2.5.0-beta.2 → 2.5.1}/koffi_openbsd_x64/koffi.node +0 -0
- package/build/2.5.1/koffi_win32_arm64/koffi.node +0 -0
- package/build/{2.5.0-beta.2 → 2.5.1}/koffi_win32_ia32/koffi.node +0 -0
- package/build/{2.5.0-beta.2 → 2.5.1}/koffi_win32_x64/koffi.node +0 -0
- package/doc/functions.md +1 -1
- package/doc/unions.md +3 -3
- package/package.json +2 -2
- package/src/core/libcc/brotli.cc +1 -1
- package/src/core/libcc/libcc.cc +53 -65
- package/src/core/libcc/libcc.hh +67 -28
- package/src/core/libcc/miniz.cc +2 -2
- package/src/koffi/CMakeLists.txt +1 -5
- package/src/koffi/src/abi_arm32.cc +35 -35
- package/src/koffi/src/abi_arm64.cc +34 -34
- package/src/koffi/src/abi_riscv64.cc +29 -29
- package/src/koffi/src/abi_x64_sysv.cc +29 -28
- package/src/koffi/src/abi_x64_win.cc +23 -23
- package/src/koffi/src/abi_x86.cc +27 -27
- package/src/koffi/src/call.cc +62 -69
- package/src/koffi/src/call.hh +2 -2
- package/src/koffi/src/ffi.cc +24 -24
- package/src/koffi/src/ffi.hh +4 -4
- package/src/koffi/src/parser.cc +1 -1
- package/src/koffi/src/trampolines/prototypes.inc +1 -1
- package/src/koffi/src/util.cc +7 -7
- package/src/koffi/src/util.hh +1 -1
- package/src/koffi/src/win32.hh +4 -4
- package/build/2.5.0-beta.2/koffi_darwin_arm64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_linux_arm32hf/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_linux_arm64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_win32_arm64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_win32_x64/koffi.pdb +0 -0
- /package/build/{2.5.0-beta.2 → 2.5.1}/koffi_win32_arm64/koffi.exp +0 -0
- /package/build/{2.5.0-beta.2 → 2.5.1}/koffi_win32_arm64/koffi.lib +0 -0
- /package/build/{2.5.0-beta.2 → 2.5.1}/koffi_win32_ia32/koffi.exp +0 -0
- /package/build/{2.5.0-beta.2 → 2.5.1}/koffi_win32_ia32/koffi.lib +0 -0
- /package/build/{2.5.0-beta.2 → 2.5.1}/koffi_win32_x64/koffi.exp +0 -0
- /package/build/{2.5.0-beta.2 → 2.5.1}/koffi_win32_x64/koffi.lib +0 -0
|
@@ -133,10 +133,11 @@ static Size ClassifyType(const TypeInfo *type, Size offset, Span<RegisterClass>
|
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
for (const RecordMember &member: type->members) {
|
|
136
|
-
Size
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
Size member_offset = offset + member.offset;
|
|
137
|
+
Size start = member_offset / 8;
|
|
138
|
+
ClassifyType(member.type, member_offset % 8, classes.Take(start, classes.len - start));
|
|
139
139
|
}
|
|
140
|
+
offset += type->size;
|
|
140
141
|
|
|
141
142
|
return (offset + 7) / 8;
|
|
142
143
|
} break;
|
|
@@ -246,11 +247,11 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
246
247
|
uint64_t *xmm_ptr = nullptr;
|
|
247
248
|
|
|
248
249
|
// Return through registers unless it's too big
|
|
249
|
-
if (
|
|
250
|
+
if (!AllocStack(func->args_size, 16, &args_ptr)) [[unlikely]]
|
|
250
251
|
return false;
|
|
251
|
-
if (
|
|
252
|
+
if (!AllocStack(8 * 8, 8, &xmm_ptr)) [[unlikely]]
|
|
252
253
|
return false;
|
|
253
|
-
if (
|
|
254
|
+
if (!AllocStack(6 * 8, 8, &gpr_ptr)) [[unlikely]]
|
|
254
255
|
return false;
|
|
255
256
|
if (func->ret.use_memory) {
|
|
256
257
|
return_ptr = AllocHeap(func->ret.type->size, 16);
|
|
@@ -259,7 +260,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
259
260
|
|
|
260
261
|
#define PUSH_INTEGER(CType) \
|
|
261
262
|
do { \
|
|
262
|
-
if (
|
|
263
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
263
264
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
264
265
|
return false; \
|
|
265
266
|
} \
|
|
@@ -269,7 +270,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
269
270
|
} while (false)
|
|
270
271
|
#define PUSH_INTEGER_SWAP(CType) \
|
|
271
272
|
do { \
|
|
272
|
-
if (
|
|
273
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
273
274
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
274
275
|
return false; \
|
|
275
276
|
} \
|
|
@@ -289,7 +290,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
289
290
|
case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
|
|
290
291
|
|
|
291
292
|
case PrimitiveKind::Bool: {
|
|
292
|
-
if (
|
|
293
|
+
if (!value.IsBoolean()) [[unlikely]] {
|
|
293
294
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argmument %2, expected boolean", GetValueType(instance, value));
|
|
294
295
|
return false;
|
|
295
296
|
}
|
|
@@ -313,28 +314,28 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
313
314
|
case PrimitiveKind::UInt64S: { PUSH_INTEGER_SWAP(uint64_t); } break;
|
|
314
315
|
case PrimitiveKind::String: {
|
|
315
316
|
const char *str;
|
|
316
|
-
if (
|
|
317
|
+
if (!PushString(value, param.directions, &str)) [[unlikely]]
|
|
317
318
|
return false;
|
|
318
319
|
|
|
319
320
|
*(const char **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str;
|
|
320
321
|
} break;
|
|
321
322
|
case PrimitiveKind::String16: {
|
|
322
323
|
const char16_t *str16;
|
|
323
|
-
if (
|
|
324
|
+
if (!PushString16(value, param.directions, &str16)) [[unlikely]]
|
|
324
325
|
return false;
|
|
325
326
|
|
|
326
327
|
*(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str16;
|
|
327
328
|
} break;
|
|
328
329
|
case PrimitiveKind::Pointer: {
|
|
329
330
|
void *ptr;
|
|
330
|
-
if (
|
|
331
|
+
if (!PushPointer(value, param.type, param.directions, &ptr)) [[unlikely]]
|
|
331
332
|
return false;
|
|
332
333
|
|
|
333
334
|
*(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
|
|
334
335
|
} break;
|
|
335
336
|
case PrimitiveKind::Record:
|
|
336
337
|
case PrimitiveKind::Union: {
|
|
337
|
-
if (
|
|
338
|
+
if (!IsObject(value)) [[unlikely]] {
|
|
338
339
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
339
340
|
return false;
|
|
340
341
|
}
|
|
@@ -372,7 +373,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
372
373
|
} break;
|
|
373
374
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
374
375
|
case PrimitiveKind::Float32: {
|
|
375
|
-
if (
|
|
376
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
376
377
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
377
378
|
return false;
|
|
378
379
|
}
|
|
@@ -384,7 +385,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
384
385
|
*(float *)ptr = f;
|
|
385
386
|
} break;
|
|
386
387
|
case PrimitiveKind::Float64: {
|
|
387
|
-
if (
|
|
388
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
388
389
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
389
390
|
return false;
|
|
390
391
|
}
|
|
@@ -399,7 +400,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
399
400
|
Napi::Function func = value.As<Napi::Function>();
|
|
400
401
|
|
|
401
402
|
ptr = ReserveTrampoline(param.type->ref.proto, func);
|
|
402
|
-
if (
|
|
403
|
+
if (!ptr) [[unlikely]]
|
|
403
404
|
return false;
|
|
404
405
|
} else if (CheckValueTag(instance, value, param.type->ref.marker)) {
|
|
405
406
|
ptr = value.As<Napi::External<void>>().Data();
|
|
@@ -542,7 +543,7 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
542
543
|
|
|
543
544
|
void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async, BackRegisters *out_reg)
|
|
544
545
|
{
|
|
545
|
-
if (
|
|
546
|
+
if (env.IsExceptionPending()) [[unlikely]]
|
|
546
547
|
return;
|
|
547
548
|
|
|
548
549
|
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
@@ -559,7 +560,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
559
560
|
|
|
560
561
|
RG_DEFER_N(err_guard) { memset(out_reg, 0, RG_SIZE(*out_reg)); };
|
|
561
562
|
|
|
562
|
-
if (
|
|
563
|
+
if (trampoline.generation >= 0 && trampoline.generation != (int32_t)mem->generation) [[unlikely]] {
|
|
563
564
|
ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
|
|
564
565
|
return;
|
|
565
566
|
}
|
|
@@ -771,12 +772,12 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
771
772
|
}
|
|
772
773
|
Napi::Value value(env, ret);
|
|
773
774
|
|
|
774
|
-
if (
|
|
775
|
+
if (env.IsExceptionPending()) [[unlikely]]
|
|
775
776
|
return;
|
|
776
777
|
|
|
777
778
|
#define RETURN_INTEGER(CType) \
|
|
778
779
|
do { \
|
|
779
|
-
if (
|
|
780
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
780
781
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
781
782
|
return; \
|
|
782
783
|
} \
|
|
@@ -786,7 +787,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
786
787
|
} while (false)
|
|
787
788
|
#define RETURN_INTEGER_SWAP(CType) \
|
|
788
789
|
do { \
|
|
789
|
-
if (
|
|
790
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
790
791
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
791
792
|
return; \
|
|
792
793
|
} \
|
|
@@ -799,7 +800,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
799
800
|
switch (type->primitive) {
|
|
800
801
|
case PrimitiveKind::Void: {} break;
|
|
801
802
|
case PrimitiveKind::Bool: {
|
|
802
|
-
if (
|
|
803
|
+
if (!value.IsBoolean()) [[unlikely]] {
|
|
803
804
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
|
|
804
805
|
return;
|
|
805
806
|
}
|
|
@@ -823,14 +824,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
823
824
|
case PrimitiveKind::UInt64S: { RETURN_INTEGER_SWAP(uint64_t); } break;
|
|
824
825
|
case PrimitiveKind::String: {
|
|
825
826
|
const char *str;
|
|
826
|
-
if (
|
|
827
|
+
if (!PushString(value, 1, &str)) [[unlikely]]
|
|
827
828
|
return;
|
|
828
829
|
|
|
829
830
|
out_reg->rax = (uint64_t)str;
|
|
830
831
|
} break;
|
|
831
832
|
case PrimitiveKind::String16: {
|
|
832
833
|
const char16_t *str16;
|
|
833
|
-
if (
|
|
834
|
+
if (!PushString16(value, 1, &str16)) [[unlikely]]
|
|
834
835
|
return;
|
|
835
836
|
|
|
836
837
|
out_reg->rax = (uint64_t)str16;
|
|
@@ -859,7 +860,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
859
860
|
} break;
|
|
860
861
|
case PrimitiveKind::Record:
|
|
861
862
|
case PrimitiveKind::Union: {
|
|
862
|
-
if (
|
|
863
|
+
if (!IsObject(value)) [[unlikely]] {
|
|
863
864
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
864
865
|
return;
|
|
865
866
|
}
|
|
@@ -894,7 +895,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
894
895
|
} break;
|
|
895
896
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
896
897
|
case PrimitiveKind::Float32: {
|
|
897
|
-
if (
|
|
898
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
898
899
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
899
900
|
return;
|
|
900
901
|
}
|
|
@@ -905,7 +906,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
905
906
|
memcpy(&out_reg->xmm0, &f, 4);
|
|
906
907
|
} break;
|
|
907
908
|
case PrimitiveKind::Float64: {
|
|
908
|
-
if (
|
|
909
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
909
910
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
910
911
|
return;
|
|
911
912
|
}
|
|
@@ -920,7 +921,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
920
921
|
Napi::Function func2 = value.As<Napi::Function>();
|
|
921
922
|
|
|
922
923
|
ptr = ReserveTrampoline(type->ref.proto, func2);
|
|
923
|
-
if (
|
|
924
|
+
if (!ptr) [[unlikely]]
|
|
924
925
|
return;
|
|
925
926
|
} else if (CheckValueTag(instance, value, type->ref.marker)) {
|
|
926
927
|
ptr = value.As<Napi::External<void>>().Data();
|
|
@@ -68,7 +68,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
68
68
|
uint64_t *args_ptr = nullptr;
|
|
69
69
|
|
|
70
70
|
// Pass return value in register or through memory
|
|
71
|
-
if (
|
|
71
|
+
if (!AllocStack(func->args_size, 16, &args_ptr)) [[unlikely]]
|
|
72
72
|
return false;
|
|
73
73
|
if (!func->ret.regular) {
|
|
74
74
|
return_ptr = AllocHeap(func->ret.type->size, 16);
|
|
@@ -77,7 +77,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
77
77
|
|
|
78
78
|
#define PUSH_INTEGER(CType) \
|
|
79
79
|
do { \
|
|
80
|
-
if (
|
|
80
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
81
81
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
82
82
|
return false; \
|
|
83
83
|
} \
|
|
@@ -87,7 +87,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
87
87
|
} while (false)
|
|
88
88
|
#define PUSH_INTEGER_SWAP(CType) \
|
|
89
89
|
do { \
|
|
90
|
-
if (
|
|
90
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
91
91
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
92
92
|
return false; \
|
|
93
93
|
} \
|
|
@@ -107,7 +107,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
107
107
|
case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
|
|
108
108
|
|
|
109
109
|
case PrimitiveKind::Bool: {
|
|
110
|
-
if (
|
|
110
|
+
if (!value.IsBoolean()) [[unlikely]] {
|
|
111
111
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
|
|
112
112
|
return false;
|
|
113
113
|
}
|
|
@@ -132,28 +132,28 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
132
132
|
case PrimitiveKind::UInt64S: { PUSH_INTEGER_SWAP(uint64_t); } break;
|
|
133
133
|
case PrimitiveKind::String: {
|
|
134
134
|
const char *str;
|
|
135
|
-
if (
|
|
135
|
+
if (!PushString(value, param.directions, &str)) [[unlikely]]
|
|
136
136
|
return false;
|
|
137
137
|
|
|
138
138
|
*(const char **)(args_ptr++) = str;
|
|
139
139
|
} break;
|
|
140
140
|
case PrimitiveKind::String16: {
|
|
141
141
|
const char16_t *str16;
|
|
142
|
-
if (
|
|
142
|
+
if (!PushString16(value, param.directions, &str16)) [[unlikely]]
|
|
143
143
|
return false;
|
|
144
144
|
|
|
145
145
|
*(const char16_t **)(args_ptr++) = str16;
|
|
146
146
|
} break;
|
|
147
147
|
case PrimitiveKind::Pointer: {
|
|
148
148
|
void *ptr;
|
|
149
|
-
if (
|
|
149
|
+
if (!PushPointer(value, param.type, param.directions, &ptr)) [[unlikely]]
|
|
150
150
|
return false;
|
|
151
151
|
|
|
152
152
|
*(void **)(args_ptr++) = ptr;
|
|
153
153
|
} break;
|
|
154
154
|
case PrimitiveKind::Record:
|
|
155
155
|
case PrimitiveKind::Union: {
|
|
156
|
-
if (
|
|
156
|
+
if (!IsObject(value)) [[unlikely]] {
|
|
157
157
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
158
158
|
return false;
|
|
159
159
|
}
|
|
@@ -172,7 +172,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
172
172
|
} break;
|
|
173
173
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
174
174
|
case PrimitiveKind::Float32: {
|
|
175
|
-
if (
|
|
175
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
176
176
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
177
177
|
return false;
|
|
178
178
|
}
|
|
@@ -183,7 +183,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
183
183
|
*(float *)(args_ptr++) = f;
|
|
184
184
|
} break;
|
|
185
185
|
case PrimitiveKind::Float64: {
|
|
186
|
-
if (
|
|
186
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
187
187
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
188
188
|
return false;
|
|
189
189
|
}
|
|
@@ -198,7 +198,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
198
198
|
Napi::Function func = value.As<Napi::Function>();
|
|
199
199
|
|
|
200
200
|
ptr = ReserveTrampoline(param.type->ref.proto, func);
|
|
201
|
-
if (
|
|
201
|
+
if (!ptr) [[unlikely]]
|
|
202
202
|
return false;
|
|
203
203
|
} else if (CheckValueTag(instance, value, param.type->ref.marker)) {
|
|
204
204
|
ptr = value.As<Napi::External<void>>().Data();
|
|
@@ -348,7 +348,7 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
348
348
|
|
|
349
349
|
void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async, BackRegisters *out_reg)
|
|
350
350
|
{
|
|
351
|
-
if (
|
|
351
|
+
if (env.IsExceptionPending()) [[unlikely]]
|
|
352
352
|
return;
|
|
353
353
|
|
|
354
354
|
TEB *teb = GetTEB();
|
|
@@ -380,7 +380,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
380
380
|
|
|
381
381
|
RG_DEFER_N(err_guard) { memset(out_reg, 0, RG_SIZE(*out_reg)); };
|
|
382
382
|
|
|
383
|
-
if (
|
|
383
|
+
if (trampoline.generation >= 0 && trampoline.generation != (int32_t)mem->generation) [[unlikely]] {
|
|
384
384
|
ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
|
|
385
385
|
return;
|
|
386
386
|
}
|
|
@@ -591,12 +591,12 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
591
591
|
}
|
|
592
592
|
Napi::Value value(env, ret);
|
|
593
593
|
|
|
594
|
-
if (
|
|
594
|
+
if (env.IsExceptionPending()) [[unlikely]]
|
|
595
595
|
return;
|
|
596
596
|
|
|
597
597
|
#define RETURN_INTEGER(CType) \
|
|
598
598
|
do { \
|
|
599
|
-
if (
|
|
599
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
600
600
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
601
601
|
return; \
|
|
602
602
|
} \
|
|
@@ -606,7 +606,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
606
606
|
} while (false)
|
|
607
607
|
#define RETURN_INTEGER_SWAP(CType) \
|
|
608
608
|
do { \
|
|
609
|
-
if (
|
|
609
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
610
610
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
611
611
|
return; \
|
|
612
612
|
} \
|
|
@@ -618,7 +618,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
618
618
|
switch (type->primitive) {
|
|
619
619
|
case PrimitiveKind::Void: {} break;
|
|
620
620
|
case PrimitiveKind::Bool: {
|
|
621
|
-
if (
|
|
621
|
+
if (!value.IsBoolean()) [[unlikely]] {
|
|
622
622
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
|
|
623
623
|
return;
|
|
624
624
|
}
|
|
@@ -642,14 +642,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
642
642
|
case PrimitiveKind::UInt64S: { RETURN_INTEGER_SWAP(uint64_t); } break;
|
|
643
643
|
case PrimitiveKind::String: {
|
|
644
644
|
const char *str;
|
|
645
|
-
if (
|
|
645
|
+
if (!PushString(value, 1, &str)) [[unlikely]]
|
|
646
646
|
return;
|
|
647
647
|
|
|
648
648
|
out_reg->rax = (uint64_t)str;
|
|
649
649
|
} break;
|
|
650
650
|
case PrimitiveKind::String16: {
|
|
651
651
|
const char16_t *str16;
|
|
652
|
-
if (
|
|
652
|
+
if (!PushString16(value, 1, &str16)) [[unlikely]]
|
|
653
653
|
return;
|
|
654
654
|
|
|
655
655
|
out_reg->rax = (uint64_t)str16;
|
|
@@ -678,7 +678,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
678
678
|
} break;
|
|
679
679
|
case PrimitiveKind::Record:
|
|
680
680
|
case PrimitiveKind::Union: {
|
|
681
|
-
if (
|
|
681
|
+
if (!IsObject(value)) [[unlikely]] {
|
|
682
682
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
683
683
|
return;
|
|
684
684
|
}
|
|
@@ -695,7 +695,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
695
695
|
} break;
|
|
696
696
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
697
697
|
case PrimitiveKind::Float32: {
|
|
698
|
-
if (
|
|
698
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
699
699
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
700
700
|
return;
|
|
701
701
|
}
|
|
@@ -706,7 +706,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
706
706
|
memcpy(&out_reg->xmm0, &f, 4);
|
|
707
707
|
} break;
|
|
708
708
|
case PrimitiveKind::Float64: {
|
|
709
|
-
if (
|
|
709
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
710
710
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
711
711
|
return;
|
|
712
712
|
}
|
|
@@ -721,7 +721,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
721
721
|
Napi::Function func2 = value.As<Napi::Function>();
|
|
722
722
|
|
|
723
723
|
ptr = ReserveTrampoline(type->ref.proto, func2);
|
|
724
|
-
if (
|
|
724
|
+
if (!ptr) [[unlikely]]
|
|
725
725
|
return;
|
|
726
726
|
} else if (CheckValueTag(instance, value, type->ref.marker)) {
|
|
727
727
|
ptr = value.As<Napi::External<void>>().Data();
|
package/src/koffi/src/abi_x86.cc
CHANGED
|
@@ -135,7 +135,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
135
135
|
uint32_t *fast_ptr = nullptr;
|
|
136
136
|
|
|
137
137
|
// Pass return value in register or through memory
|
|
138
|
-
if (
|
|
138
|
+
if (!AllocStack(func->args_size, 16, &args_ptr)) [[unlikely]]
|
|
139
139
|
return false;
|
|
140
140
|
if (func->fast) {
|
|
141
141
|
fast_ptr = args_ptr;
|
|
@@ -148,7 +148,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
148
148
|
|
|
149
149
|
#define PUSH_INTEGER_32(CType) \
|
|
150
150
|
do { \
|
|
151
|
-
if (
|
|
151
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
152
152
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
153
153
|
return false; \
|
|
154
154
|
} \
|
|
@@ -158,7 +158,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
158
158
|
} while (false)
|
|
159
159
|
#define PUSH_INTEGER_32_SWAP(CType) \
|
|
160
160
|
do { \
|
|
161
|
-
if (
|
|
161
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
162
162
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
163
163
|
return false; \
|
|
164
164
|
} \
|
|
@@ -168,7 +168,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
168
168
|
} while (false)
|
|
169
169
|
#define PUSH_INTEGER_64(CType) \
|
|
170
170
|
do { \
|
|
171
|
-
if (
|
|
171
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
172
172
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
173
173
|
return false; \
|
|
174
174
|
} \
|
|
@@ -180,7 +180,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
180
180
|
} while (false)
|
|
181
181
|
#define PUSH_INTEGER_64_SWAP(CType) \
|
|
182
182
|
do { \
|
|
183
|
-
if (
|
|
183
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
184
184
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
185
185
|
return false; \
|
|
186
186
|
} \
|
|
@@ -202,7 +202,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
202
202
|
case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
|
|
203
203
|
|
|
204
204
|
case PrimitiveKind::Bool: {
|
|
205
|
-
if (
|
|
205
|
+
if (!value.IsBoolean()) [[unlikely]] {
|
|
206
206
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
|
|
207
207
|
return false;
|
|
208
208
|
}
|
|
@@ -226,28 +226,28 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
226
226
|
case PrimitiveKind::UInt64S: { PUSH_INTEGER_64_SWAP(uint64_t); } break;
|
|
227
227
|
case PrimitiveKind::String: {
|
|
228
228
|
const char *str;
|
|
229
|
-
if (
|
|
229
|
+
if (!PushString(value, param.directions, &str)) [[unlikely]]
|
|
230
230
|
return false;
|
|
231
231
|
|
|
232
232
|
*(const char **)((param.fast ? fast_ptr : args_ptr)++) = str;
|
|
233
233
|
} break;
|
|
234
234
|
case PrimitiveKind::String16: {
|
|
235
235
|
const char16_t *str16;
|
|
236
|
-
if (
|
|
236
|
+
if (!PushString16(value, param.directions, &str16)) [[unlikely]]
|
|
237
237
|
return false;
|
|
238
238
|
|
|
239
239
|
*(const char16_t **)((param.fast ? fast_ptr : args_ptr)++) = str16;
|
|
240
240
|
} break;
|
|
241
241
|
case PrimitiveKind::Pointer: {
|
|
242
242
|
void *ptr;
|
|
243
|
-
if (
|
|
243
|
+
if (!PushPointer(value, param.type, param.directions, &ptr)) [[unlikely]]
|
|
244
244
|
return false;
|
|
245
245
|
|
|
246
246
|
*(void **)((param.fast ? fast_ptr : args_ptr)++) = ptr;
|
|
247
247
|
} break;
|
|
248
248
|
case PrimitiveKind::Record:
|
|
249
249
|
case PrimitiveKind::Union: {
|
|
250
|
-
if (
|
|
250
|
+
if (!IsObject(value)) [[unlikely]] {
|
|
251
251
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
252
252
|
return false;
|
|
253
253
|
}
|
|
@@ -267,7 +267,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
267
267
|
} break;
|
|
268
268
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
269
269
|
case PrimitiveKind::Float32: {
|
|
270
|
-
if (
|
|
270
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
271
271
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
272
272
|
return false;
|
|
273
273
|
}
|
|
@@ -276,7 +276,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
276
276
|
*(float *)((param.fast ? fast_ptr : args_ptr)++) = f;
|
|
277
277
|
} break;
|
|
278
278
|
case PrimitiveKind::Float64: {
|
|
279
|
-
if (
|
|
279
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
280
280
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
281
281
|
return false;
|
|
282
282
|
}
|
|
@@ -292,7 +292,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
292
292
|
Napi::Function func = value.As<Napi::Function>();
|
|
293
293
|
|
|
294
294
|
ptr = ReserveTrampoline(param.type->ref.proto, func);
|
|
295
|
-
if (
|
|
295
|
+
if (!ptr) [[unlikely]]
|
|
296
296
|
return false;
|
|
297
297
|
} else if (CheckValueTag(instance, value, param.type->ref.marker)) {
|
|
298
298
|
ptr = value.As<Napi::External<void>>().Data();
|
|
@@ -462,7 +462,7 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
462
462
|
|
|
463
463
|
void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRegisters *out_reg)
|
|
464
464
|
{
|
|
465
|
-
if (
|
|
465
|
+
if (env.IsExceptionPending()) [[unlikely]]
|
|
466
466
|
return;
|
|
467
467
|
|
|
468
468
|
#ifdef _WIN32
|
|
@@ -510,7 +510,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRe
|
|
|
510
510
|
out_reg->ret_pop = pop;
|
|
511
511
|
};
|
|
512
512
|
|
|
513
|
-
if (
|
|
513
|
+
if (trampoline.generation >= 0 && trampoline.generation != (int32_t)mem->generation) [[unlikely]] {
|
|
514
514
|
ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
|
|
515
515
|
return;
|
|
516
516
|
}
|
|
@@ -704,12 +704,12 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRe
|
|
|
704
704
|
}
|
|
705
705
|
Napi::Value value(env, ret);
|
|
706
706
|
|
|
707
|
-
if (
|
|
707
|
+
if (env.IsExceptionPending()) [[unlikely]]
|
|
708
708
|
return;
|
|
709
709
|
|
|
710
710
|
#define RETURN_INTEGER_32(CType) \
|
|
711
711
|
do { \
|
|
712
|
-
if (
|
|
712
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
713
713
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
714
714
|
return; \
|
|
715
715
|
} \
|
|
@@ -719,7 +719,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRe
|
|
|
719
719
|
} while (false)
|
|
720
720
|
#define RETURN_INTEGER_32_SWAP(CType) \
|
|
721
721
|
do { \
|
|
722
|
-
if (
|
|
722
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
723
723
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
724
724
|
return; \
|
|
725
725
|
} \
|
|
@@ -729,7 +729,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRe
|
|
|
729
729
|
} while (false)
|
|
730
730
|
#define RETURN_INTEGER_64(CType) \
|
|
731
731
|
do { \
|
|
732
|
-
if (
|
|
732
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
733
733
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
734
734
|
return; \
|
|
735
735
|
} \
|
|
@@ -741,7 +741,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRe
|
|
|
741
741
|
} while (false)
|
|
742
742
|
#define RETURN_INTEGER_64_SWAP(CType) \
|
|
743
743
|
do { \
|
|
744
|
-
if (
|
|
744
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
745
745
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
746
746
|
return; \
|
|
747
747
|
} \
|
|
@@ -755,7 +755,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRe
|
|
|
755
755
|
switch (type->primitive) {
|
|
756
756
|
case PrimitiveKind::Void: {} break;
|
|
757
757
|
case PrimitiveKind::Bool: {
|
|
758
|
-
if (
|
|
758
|
+
if (!value.IsBoolean()) [[unlikely]] {
|
|
759
759
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
|
|
760
760
|
return;
|
|
761
761
|
}
|
|
@@ -779,14 +779,14 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRe
|
|
|
779
779
|
case PrimitiveKind::UInt64S: { RETURN_INTEGER_64_SWAP(uint64_t); } break;
|
|
780
780
|
case PrimitiveKind::String: {
|
|
781
781
|
const char *str;
|
|
782
|
-
if (
|
|
782
|
+
if (!PushString(value, 1, &str)) [[unlikely]]
|
|
783
783
|
return;
|
|
784
784
|
|
|
785
785
|
out_reg->eax = (uint32_t)str;
|
|
786
786
|
} break;
|
|
787
787
|
case PrimitiveKind::String16: {
|
|
788
788
|
const char16_t *str16;
|
|
789
|
-
if (
|
|
789
|
+
if (!PushString16(value, 1, &str16)) [[unlikely]]
|
|
790
790
|
return;
|
|
791
791
|
|
|
792
792
|
out_reg->eax = (uint32_t)str16;
|
|
@@ -815,7 +815,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRe
|
|
|
815
815
|
} break;
|
|
816
816
|
case PrimitiveKind::Record:
|
|
817
817
|
case PrimitiveKind::Union: {
|
|
818
|
-
if (
|
|
818
|
+
if (!IsObject(value)) [[unlikely]] {
|
|
819
819
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
820
820
|
return;
|
|
821
821
|
}
|
|
@@ -832,7 +832,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRe
|
|
|
832
832
|
} break;
|
|
833
833
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
834
834
|
case PrimitiveKind::Float32: {
|
|
835
|
-
if (
|
|
835
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
836
836
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
837
837
|
return;
|
|
838
838
|
}
|
|
@@ -841,7 +841,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRe
|
|
|
841
841
|
out_reg->x87_double = false;
|
|
842
842
|
} break;
|
|
843
843
|
case PrimitiveKind::Float64: {
|
|
844
|
-
if (
|
|
844
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
845
845
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
846
846
|
return;
|
|
847
847
|
}
|
|
@@ -856,7 +856,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRe
|
|
|
856
856
|
Napi::Function func2 = value.As<Napi::Function>();
|
|
857
857
|
|
|
858
858
|
ptr = ReserveTrampoline(type->ref.proto, func2);
|
|
859
|
-
if (
|
|
859
|
+
if (!ptr) [[unlikely]]
|
|
860
860
|
return;
|
|
861
861
|
} else if (CheckValueTag(instance, value, type->ref.marker)) {
|
|
862
862
|
ptr = value.As<Napi::External<void>>().Data();
|