koffi 2.5.0 → 2.5.2
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 +13 -0
- package/build/2.5.2/koffi_darwin_arm64/koffi.node +0 -0
- package/build/{2.5.0 → 2.5.2}/koffi_darwin_x64/koffi.node +0 -0
- package/build/{2.5.0 → 2.5.2}/koffi_freebsd_arm64/koffi.node +0 -0
- package/build/{2.5.0 → 2.5.2}/koffi_freebsd_ia32/koffi.node +0 -0
- package/build/{2.5.0 → 2.5.2}/koffi_freebsd_x64/koffi.node +0 -0
- package/build/2.5.2/koffi_linux_arm32hf/koffi.node +0 -0
- package/build/2.5.2/koffi_linux_arm64/koffi.node +0 -0
- package/build/{2.5.0 → 2.5.2}/koffi_linux_ia32/koffi.node +0 -0
- package/build/{2.5.0 → 2.5.2}/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/build/{2.5.0 → 2.5.2}/koffi_linux_x64/koffi.node +0 -0
- package/build/{2.5.0 → 2.5.2}/koffi_openbsd_ia32/koffi.node +0 -0
- package/build/{2.5.0 → 2.5.2}/koffi_openbsd_x64/koffi.node +0 -0
- package/build/2.5.2/koffi_win32_arm64/koffi.node +0 -0
- package/build/{2.5.0 → 2.5.2}/koffi_win32_ia32/koffi.node +0 -0
- package/build/{2.5.0 → 2.5.2}/koffi_win32_x64/koffi.node +0 -0
- 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 +65 -72
- 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/koffi_darwin_arm64/koffi.node +0 -0
- package/build/2.5.0/koffi_linux_arm32hf/koffi.node +0 -0
- package/build/2.5.0/koffi_linux_arm64/koffi.node +0 -0
- package/build/2.5.0/koffi_win32_arm64/koffi.node +0 -0
- package/build/2.5.0/koffi_win32_x64/koffi.pdb +0 -0
- /package/build/{2.5.0 → 2.5.2}/koffi_win32_arm64/koffi.exp +0 -0
- /package/build/{2.5.0 → 2.5.2}/koffi_win32_arm64/koffi.lib +0 -0
- /package/build/{2.5.0 → 2.5.2}/koffi_win32_ia32/koffi.exp +0 -0
- /package/build/{2.5.0 → 2.5.2}/koffi_win32_ia32/koffi.lib +0 -0
- /package/build/{2.5.0 → 2.5.2}/koffi_win32_x64/koffi.exp +0 -0
- /package/build/{2.5.0 → 2.5.2}/koffi_win32_x64/koffi.lib +0 -0
|
@@ -173,11 +173,11 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
173
173
|
uint64_t *vec_ptr = nullptr;
|
|
174
174
|
|
|
175
175
|
// Return through registers unless it's too big
|
|
176
|
-
if (
|
|
176
|
+
if (!AllocStack(func->args_size, 16, &args_ptr)) [[unlikely]]
|
|
177
177
|
return false;
|
|
178
|
-
if (
|
|
178
|
+
if (!AllocStack(8 * 8, 8, &gpr_ptr)) [[unlikely]]
|
|
179
179
|
return false;
|
|
180
|
-
if (
|
|
180
|
+
if (!AllocStack(8 * 8, 8, &vec_ptr)) [[unlikely]]
|
|
181
181
|
return false;
|
|
182
182
|
if (func->ret.use_memory) {
|
|
183
183
|
return_ptr = AllocHeap(func->ret.type->size, 16);
|
|
@@ -186,7 +186,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
186
186
|
|
|
187
187
|
#define PUSH_INTEGER(CType) \
|
|
188
188
|
do { \
|
|
189
|
-
if (
|
|
189
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
190
190
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
191
191
|
return false; \
|
|
192
192
|
} \
|
|
@@ -196,7 +196,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
196
196
|
} while (false)
|
|
197
197
|
#define PUSH_INTEGER_SWAP(CType) \
|
|
198
198
|
do { \
|
|
199
|
-
if (
|
|
199
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
200
200
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
201
201
|
return false; \
|
|
202
202
|
} \
|
|
@@ -216,7 +216,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
216
216
|
case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
|
|
217
217
|
|
|
218
218
|
case PrimitiveKind::Bool: {
|
|
219
|
-
if (
|
|
219
|
+
if (!value.IsBoolean()) [[unlikely]] {
|
|
220
220
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
|
|
221
221
|
return false;
|
|
222
222
|
}
|
|
@@ -240,28 +240,28 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
240
240
|
case PrimitiveKind::UInt64S: { PUSH_INTEGER_SWAP(uint64_t); } break;
|
|
241
241
|
case PrimitiveKind::String: {
|
|
242
242
|
const char *str;
|
|
243
|
-
if (
|
|
243
|
+
if (!PushString(value, param.directions, &str)) [[unlikely]]
|
|
244
244
|
return false;
|
|
245
245
|
|
|
246
246
|
*(const char **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str;
|
|
247
247
|
} break;
|
|
248
248
|
case PrimitiveKind::String16: {
|
|
249
249
|
const char16_t *str16;
|
|
250
|
-
if (
|
|
250
|
+
if (!PushString16(value, param.directions, &str16)) [[unlikely]]
|
|
251
251
|
return false;
|
|
252
252
|
|
|
253
253
|
*(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str16;
|
|
254
254
|
} break;
|
|
255
255
|
case PrimitiveKind::Pointer: {
|
|
256
256
|
void *ptr;
|
|
257
|
-
if (
|
|
257
|
+
if (!PushPointer(value, param.type, param.directions, &ptr)) [[unlikely]]
|
|
258
258
|
return false;
|
|
259
259
|
|
|
260
260
|
*(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
|
|
261
261
|
} break;
|
|
262
262
|
case PrimitiveKind::Record:
|
|
263
263
|
case PrimitiveKind::Union: {
|
|
264
|
-
if (
|
|
264
|
+
if (!IsObject(value)) [[unlikely]] {
|
|
265
265
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
266
266
|
return false;
|
|
267
267
|
}
|
|
@@ -319,14 +319,14 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
319
319
|
} break;
|
|
320
320
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
321
321
|
case PrimitiveKind::Float32: {
|
|
322
|
-
if (
|
|
322
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
323
323
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
324
324
|
return false;
|
|
325
325
|
}
|
|
326
326
|
|
|
327
327
|
float f = GetNumber<float>(value);
|
|
328
328
|
|
|
329
|
-
if (
|
|
329
|
+
if (param.vec_count) [[likely]] {
|
|
330
330
|
memset((uint8_t *)vec_ptr + 4, 0xFF, 4);
|
|
331
331
|
*(float *)(vec_ptr++) = f;
|
|
332
332
|
} else if (param.gpr_count) {
|
|
@@ -338,14 +338,14 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
338
338
|
}
|
|
339
339
|
} break;
|
|
340
340
|
case PrimitiveKind::Float64: {
|
|
341
|
-
if (
|
|
341
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
342
342
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
343
343
|
return false;
|
|
344
344
|
}
|
|
345
345
|
|
|
346
346
|
double d = GetNumber<double>(value);
|
|
347
347
|
|
|
348
|
-
if (
|
|
348
|
+
if (param.vec_count) [[likely]] {
|
|
349
349
|
*(double *)(vec_ptr++) = d;
|
|
350
350
|
} else if (param.gpr_count) {
|
|
351
351
|
*(double *)(gpr_ptr++) = d;
|
|
@@ -360,7 +360,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
360
360
|
Napi::Function func = value.As<Napi::Function>();
|
|
361
361
|
|
|
362
362
|
ptr = ReserveTrampoline(param.type->ref.proto, func);
|
|
363
|
-
if (
|
|
363
|
+
if (!ptr) [[unlikely]]
|
|
364
364
|
return false;
|
|
365
365
|
} else if (CheckValueTag(instance, value, param.type->ref.marker)) {
|
|
366
366
|
ptr = value.As<Napi::External<void>>().Data();
|
|
@@ -508,7 +508,7 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
508
508
|
|
|
509
509
|
void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async, BackRegisters *out_reg)
|
|
510
510
|
{
|
|
511
|
-
if (
|
|
511
|
+
if (env.IsExceptionPending()) [[unlikely]]
|
|
512
512
|
return;
|
|
513
513
|
|
|
514
514
|
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
@@ -525,7 +525,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
525
525
|
|
|
526
526
|
RG_DEFER_N(err_guard) { memset(out_reg, 0, RG_SIZE(*out_reg)); };
|
|
527
527
|
|
|
528
|
-
if (
|
|
528
|
+
if (trampoline.generation >= 0 && trampoline.generation != (int32_t)mem->generation) [[unlikely]] {
|
|
529
529
|
ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
|
|
530
530
|
return;
|
|
531
531
|
}
|
|
@@ -707,7 +707,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
707
707
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
708
708
|
case PrimitiveKind::Float32: {
|
|
709
709
|
float f;
|
|
710
|
-
if (
|
|
710
|
+
if (param.vec_count) [[likely]] {
|
|
711
711
|
f = *(float *)(vec_ptr++);
|
|
712
712
|
} else if (param.gpr_count) {
|
|
713
713
|
f = *(float *)(gpr_ptr++);
|
|
@@ -720,7 +720,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
720
720
|
} break;
|
|
721
721
|
case PrimitiveKind::Float64: {
|
|
722
722
|
double d;
|
|
723
|
-
if (
|
|
723
|
+
if (param.vec_count) [[likely]] {
|
|
724
724
|
d = *(double *)(vec_ptr++);
|
|
725
725
|
} else if (param.gpr_count) {
|
|
726
726
|
d = *(double *)(gpr_ptr++);
|
|
@@ -748,12 +748,12 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
748
748
|
}
|
|
749
749
|
Napi::Value value(env, ret);
|
|
750
750
|
|
|
751
|
-
if (
|
|
751
|
+
if (env.IsExceptionPending()) [[unlikely]]
|
|
752
752
|
return;
|
|
753
753
|
|
|
754
754
|
#define RETURN_INTEGER(CType) \
|
|
755
755
|
do { \
|
|
756
|
-
if (
|
|
756
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
757
757
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
758
758
|
return; \
|
|
759
759
|
} \
|
|
@@ -763,7 +763,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
763
763
|
} while (false)
|
|
764
764
|
#define RETURN_INTEGER_SWAP(CType) \
|
|
765
765
|
do { \
|
|
766
|
-
if (
|
|
766
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
|
|
767
767
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
|
|
768
768
|
return; \
|
|
769
769
|
} \
|
|
@@ -776,7 +776,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
776
776
|
switch (type->primitive) {
|
|
777
777
|
case PrimitiveKind::Void: {} break;
|
|
778
778
|
case PrimitiveKind::Bool: {
|
|
779
|
-
if (
|
|
779
|
+
if (!value.IsBoolean()) [[unlikely]] {
|
|
780
780
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
|
|
781
781
|
return;
|
|
782
782
|
}
|
|
@@ -800,14 +800,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
800
800
|
case PrimitiveKind::UInt64S: { RETURN_INTEGER_SWAP(uint64_t); } break;
|
|
801
801
|
case PrimitiveKind::String: {
|
|
802
802
|
const char *str;
|
|
803
|
-
if (
|
|
803
|
+
if (!PushString(value, 1, &str)) [[unlikely]]
|
|
804
804
|
return;
|
|
805
805
|
|
|
806
806
|
out_reg->a0 = (uint64_t)str;
|
|
807
807
|
} break;
|
|
808
808
|
case PrimitiveKind::String16: {
|
|
809
809
|
const char16_t *str16;
|
|
810
|
-
if (
|
|
810
|
+
if (!PushString16(value, 1, &str16)) [[unlikely]]
|
|
811
811
|
return;
|
|
812
812
|
|
|
813
813
|
out_reg->a0 = (uint64_t)str16;
|
|
@@ -836,7 +836,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
836
836
|
} break;
|
|
837
837
|
case PrimitiveKind::Record:
|
|
838
838
|
case PrimitiveKind::Union: {
|
|
839
|
-
if (
|
|
839
|
+
if (!IsObject(value)) [[unlikely]] {
|
|
840
840
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
|
|
841
841
|
return;
|
|
842
842
|
}
|
|
@@ -873,7 +873,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
873
873
|
} break;
|
|
874
874
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
875
875
|
case PrimitiveKind::Float32: {
|
|
876
|
-
if (
|
|
876
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
877
877
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
878
878
|
return;
|
|
879
879
|
}
|
|
@@ -883,7 +883,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
883
883
|
memcpy(&out_reg->fa0, &f, 4);
|
|
884
884
|
} break;
|
|
885
885
|
case PrimitiveKind::Float64: {
|
|
886
|
-
if (
|
|
886
|
+
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
887
887
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
888
888
|
return;
|
|
889
889
|
}
|
|
@@ -898,7 +898,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
898
898
|
Napi::Function func2 = value.As<Napi::Function>();
|
|
899
899
|
|
|
900
900
|
ptr = ReserveTrampoline(type->ref.proto, func2);
|
|
901
|
-
if (
|
|
901
|
+
if (!ptr) [[unlikely]]
|
|
902
902
|
return;
|
|
903
903
|
} else if (CheckValueTag(instance, value, type->ref.marker)) {
|
|
904
904
|
ptr = value.As<Napi::External<void>>().Data();
|
|
@@ -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();
|