koffi 2.14.0 → 2.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -1
- package/README.md +1 -1
- 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/assets.ini +2 -1
- package/doc/build.sh +9 -0
- package/doc/pages/404.md +17 -0
- package/doc/pages/index.md +43 -4
- package/doc/pages/misc.md +16 -11
- package/doc/pages/platforms.md +8 -19
- package/doc/pages.ini +4 -7
- package/doc/static/highlight.js +2 -14
- package/doc/static/koffi.css +3 -15
- package/doc/static/perf_windows.png +0 -0
- package/doc/static/print.css +2 -14
- package/index.d.ts +29 -24
- package/index.js +10 -9
- package/indirect.js +10 -9
- package/{src/core → lib/native}/base/base.cc +1753 -1089
- package/{src/core → lib/native}/base/base.hh +868 -572
- package/{src/core → lib/native}/base/crc.inc +3 -21
- package/lib/native/base/crc_gen.py +72 -0
- package/{src/core → lib/native}/base/mimetypes.inc +2 -20
- package/{src/core → lib/native}/base/mimetypes_gen.py +2 -21
- package/lib/native/base/tower.cc +821 -0
- package/lib/native/base/tower.hh +81 -0
- package/{src/core → lib/native}/base/unicode.inc +3 -21
- package/{src/core → lib/native}/base/unicode_gen.py +5 -42
- package/package.json +3 -2
- package/src/cnoke/assets/FindCNoke.cmake +8 -20
- package/src/cnoke/assets/win_delay_hook.c +2 -20
- package/src/cnoke/cnoke.js +2 -21
- package/src/cnoke/src/builder.js +3 -22
- package/src/cnoke/src/index.js +2 -20
- package/src/cnoke/src/tools.js +2 -20
- package/src/koffi/CMakeLists.txt +19 -22
- package/src/koffi/cmake/raylib.cmake +5 -22
- package/src/koffi/cmake/sqlite3.cmake +2 -20
- package/src/koffi/src/abi_arm32.cc +31 -49
- package/src/koffi/src/abi_arm32_asm.S +2 -20
- package/src/koffi/src/abi_arm64.cc +36 -54
- package/src/koffi/src/abi_arm64_asm.S +2 -20
- package/src/koffi/src/abi_arm64_asm.asm +2 -20
- package/src/koffi/src/abi_loong64.cc +2 -20
- package/src/koffi/src/abi_loong64_asm.S +2 -20
- package/src/koffi/src/abi_riscv64.cc +34 -52
- package/src/koffi/src/abi_riscv64_asm.S +2 -20
- package/src/koffi/src/abi_x64_sysv.cc +36 -54
- package/src/koffi/src/abi_x64_sysv_asm.S +2 -20
- package/src/koffi/src/abi_x64_win.cc +32 -50
- package/src/koffi/src/abi_x64_win_asm.asm +2 -20
- package/src/koffi/src/abi_x86.cc +33 -51
- package/src/koffi/src/abi_x86_asm.S +2 -20
- package/src/koffi/src/abi_x86_asm.asm +2 -20
- package/src/koffi/src/call.cc +107 -281
- package/src/koffi/src/call.hh +9 -27
- package/src/koffi/src/errno.inc +2 -20
- package/src/koffi/src/ffi.cc +121 -121
- package/src/koffi/src/ffi.hh +23 -38
- package/src/koffi/src/init.js +2 -20
- package/src/koffi/src/parser.cc +15 -29
- package/src/koffi/src/parser.hh +4 -22
- package/src/koffi/src/trampolines/armasm.inc +0 -21
- package/src/koffi/src/trampolines/gnu.inc +0 -21
- package/src/koffi/src/trampolines/masm32.inc +0 -21
- package/src/koffi/src/trampolines/masm64.inc +0 -21
- package/src/koffi/src/trampolines/prototypes.inc +1 -22
- package/src/koffi/src/util.cc +87 -102
- package/src/koffi/src/util.hh +11 -29
- package/src/koffi/src/uv.cc +193 -0
- package/src/koffi/src/uv.def +10 -0
- package/src/koffi/src/uv.hh +40 -0
- package/src/koffi/src/win32.cc +7 -25
- package/src/koffi/src/win32.hh +4 -22
- package/vendor/node-api-headers/include/uv/aix.h +32 -0
- package/vendor/node-api-headers/include/uv/bsd.h +34 -0
- package/vendor/node-api-headers/include/uv/darwin.h +61 -0
- package/vendor/node-api-headers/include/uv/errno.h +483 -0
- package/vendor/node-api-headers/include/uv/linux.h +34 -0
- package/vendor/node-api-headers/include/uv/os390.h +33 -0
- package/vendor/node-api-headers/include/uv/posix.h +31 -0
- package/vendor/node-api-headers/include/uv/sunos.h +44 -0
- package/vendor/node-api-headers/include/uv/threadpool.h +37 -0
- package/vendor/node-api-headers/include/uv/tree.h +521 -0
- package/vendor/node-api-headers/include/uv/unix.h +512 -0
- package/vendor/node-api-headers/include/uv/version.h +43 -0
- package/vendor/node-api-headers/include/uv/win.h +698 -0
- package/vendor/node-api-headers/include/uv.h +1990 -0
- package/src/core/base/crc_gen.py +0 -109
|
@@ -1,27 +1,9 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
-
// this software and associated documentation files (the “Software”), to deal in
|
|
5
|
-
// the Software without restriction, including without limitation the rights to use,
|
|
6
|
-
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
-
// Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
-
// subject to the following conditions:
|
|
9
|
-
//
|
|
10
|
-
// The above copyright notice and this permission notice shall be included in all
|
|
11
|
-
// copies or substantial portions of the Software.
|
|
12
|
-
//
|
|
13
|
-
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
-
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
-
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
-
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
-
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
-
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
-
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
-
// OTHER DEALINGS IN THE SOFTWARE.
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// SPDX-FileCopyrightText: 2025 Niels Martignène <niels.martignene@protonmail.com>
|
|
21
3
|
|
|
22
4
|
#if defined(_WIN32) && (defined(__x86_64__) || defined(_M_AMD64))
|
|
23
5
|
|
|
24
|
-
#include "
|
|
6
|
+
#include "lib/native/base/base.hh"
|
|
25
7
|
#include "ffi.hh"
|
|
26
8
|
#include "call.hh"
|
|
27
9
|
#include "util.hh"
|
|
@@ -29,7 +11,7 @@
|
|
|
29
11
|
|
|
30
12
|
#include <napi.h>
|
|
31
13
|
|
|
32
|
-
namespace
|
|
14
|
+
namespace K {
|
|
33
15
|
|
|
34
16
|
struct BackRegisters {
|
|
35
17
|
uint64_t rax;
|
|
@@ -99,12 +81,12 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
99
81
|
// Push arguments
|
|
100
82
|
for (Size i = 0; i < func->parameters.len; i++) {
|
|
101
83
|
const ParameterInfo ¶m = func->parameters[i];
|
|
102
|
-
|
|
84
|
+
K_ASSERT(param.directions >= 1 && param.directions <= 3);
|
|
103
85
|
|
|
104
86
|
Napi::Value value = info[param.offset];
|
|
105
87
|
|
|
106
88
|
switch (param.type->primitive) {
|
|
107
|
-
case PrimitiveKind::Void: {
|
|
89
|
+
case PrimitiveKind::Void: { K_UNREACHABLE(); } break;
|
|
108
90
|
|
|
109
91
|
case PrimitiveKind::Bool: {
|
|
110
92
|
if (!value.IsBoolean()) [[unlikely]] {
|
|
@@ -177,7 +159,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
177
159
|
if (!PushObject(obj, param.type, ptr))
|
|
178
160
|
return false;
|
|
179
161
|
} break;
|
|
180
|
-
case PrimitiveKind::Array: {
|
|
162
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
181
163
|
case PrimitiveKind::Float32: {
|
|
182
164
|
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
183
165
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
@@ -206,7 +188,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
206
188
|
*(void **)(args_ptr++) = ptr;
|
|
207
189
|
} break;
|
|
208
190
|
|
|
209
|
-
case PrimitiveKind::Prototype: {
|
|
191
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
210
192
|
}
|
|
211
193
|
}
|
|
212
194
|
|
|
@@ -223,12 +205,12 @@ void CallData::Execute(const FunctionInfo *func, void *native)
|
|
|
223
205
|
TEB *teb = GetTEB();
|
|
224
206
|
|
|
225
207
|
// Restore previous stack limits at the end
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
208
|
+
K_DEFER_C(exception_list = teb->ExceptionList,
|
|
209
|
+
base = teb->StackBase,
|
|
210
|
+
limit = teb->StackLimit,
|
|
211
|
+
dealloc = teb->DeallocationStack,
|
|
212
|
+
guaranteed = teb->GuaranteedStackBytes,
|
|
213
|
+
stfs = teb->SameTebFlags) {
|
|
232
214
|
teb->ExceptionList = exception_list;
|
|
233
215
|
teb->StackBase = base;
|
|
234
216
|
teb->StackLimit = limit;
|
|
@@ -280,11 +262,11 @@ void CallData::Execute(const FunctionInfo *func, void *native)
|
|
|
280
262
|
case PrimitiveKind::Record:
|
|
281
263
|
case PrimitiveKind::Union:
|
|
282
264
|
case PrimitiveKind::Callback: { result.u64 = PERFORM_CALL(G); } break;
|
|
283
|
-
case PrimitiveKind::Array: {
|
|
265
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
284
266
|
case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
|
|
285
267
|
case PrimitiveKind::Float64: { result.d = PERFORM_CALL(D); } break;
|
|
286
268
|
|
|
287
|
-
case PrimitiveKind::Prototype: {
|
|
269
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
288
270
|
}
|
|
289
271
|
|
|
290
272
|
#undef PERFORM_CALL
|
|
@@ -292,7 +274,7 @@ void CallData::Execute(const FunctionInfo *func, void *native)
|
|
|
292
274
|
|
|
293
275
|
Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
294
276
|
{
|
|
295
|
-
|
|
277
|
+
K_DEFER {
|
|
296
278
|
PopOutArguments();
|
|
297
279
|
|
|
298
280
|
if (func->ret.type->dispose) {
|
|
@@ -324,7 +306,7 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
324
306
|
case PrimitiveKind::Callback: {
|
|
325
307
|
if (result.ptr) {
|
|
326
308
|
Napi::External<void> external = Napi::External<void>::New(env, result.ptr);
|
|
327
|
-
SetValueTag(
|
|
309
|
+
SetValueTag(external, func->ret.type->ref.marker);
|
|
328
310
|
|
|
329
311
|
return external;
|
|
330
312
|
} else {
|
|
@@ -339,14 +321,14 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
339
321
|
Napi::Object obj = DecodeObject(env, ptr, func->ret.type);
|
|
340
322
|
return obj;
|
|
341
323
|
} break;
|
|
342
|
-
case PrimitiveKind::Array: {
|
|
324
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
343
325
|
case PrimitiveKind::Float32: return Napi::Number::New(env, (double)result.f);
|
|
344
326
|
case PrimitiveKind::Float64: return Napi::Number::New(env, result.d);
|
|
345
327
|
|
|
346
|
-
case PrimitiveKind::Prototype: {
|
|
328
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
347
329
|
}
|
|
348
330
|
|
|
349
|
-
|
|
331
|
+
K_UNREACHABLE();
|
|
350
332
|
}
|
|
351
333
|
|
|
352
334
|
void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_stack, BackRegisters *out_reg)
|
|
@@ -357,7 +339,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
357
339
|
TEB *teb = GetTEB();
|
|
358
340
|
|
|
359
341
|
// Restore previous stack limits at the end
|
|
360
|
-
|
|
342
|
+
K_DEFER_C(base = teb->StackBase,
|
|
361
343
|
limit = teb->StackLimit,
|
|
362
344
|
dealloc = teb->DeallocationStack) {
|
|
363
345
|
teb->StackBase = base;
|
|
@@ -381,7 +363,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
381
363
|
|
|
382
364
|
uint8_t *return_ptr = !proto->ret.regular ? (uint8_t *)gpr_ptr[0] : nullptr;
|
|
383
365
|
|
|
384
|
-
|
|
366
|
+
K_DEFER_N(err_guard) { memset(out_reg, 0, K_SIZE(*out_reg)); };
|
|
385
367
|
|
|
386
368
|
if (trampoline.generation >= 0 && trampoline.generation != (int32_t)mem->generation) [[unlikely]] {
|
|
387
369
|
ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
|
|
@@ -395,10 +377,10 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
395
377
|
// Convert to JS arguments
|
|
396
378
|
for (Size i = 0, j = !!return_ptr; i < proto->parameters.len; i++, j++) {
|
|
397
379
|
const ParameterInfo ¶m = proto->parameters[i];
|
|
398
|
-
|
|
380
|
+
K_ASSERT(param.directions >= 1 && param.directions <= 3);
|
|
399
381
|
|
|
400
382
|
switch (param.type->primitive) {
|
|
401
|
-
case PrimitiveKind::Void: {
|
|
383
|
+
case PrimitiveKind::Void: { K_UNREACHABLE(); } break;
|
|
402
384
|
|
|
403
385
|
case PrimitiveKind::Bool: {
|
|
404
386
|
bool b = *(bool *)(j < 4 ? gpr_ptr + j : args_ptr);
|
|
@@ -545,7 +527,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
545
527
|
|
|
546
528
|
if (ptr2) {
|
|
547
529
|
Napi::External<void> external = Napi::External<void>::New(env, ptr2);
|
|
548
|
-
SetValueTag(
|
|
530
|
+
SetValueTag(external, param.type->ref.marker);
|
|
549
531
|
|
|
550
532
|
arguments.Append(external);
|
|
551
533
|
} else {
|
|
@@ -569,7 +551,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
569
551
|
Napi::Object obj2 = DecodeObject(env, ptr, param.type);
|
|
570
552
|
arguments.Append(obj2);
|
|
571
553
|
} break;
|
|
572
|
-
case PrimitiveKind::Array: {
|
|
554
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
573
555
|
case PrimitiveKind::Float32: {
|
|
574
556
|
float f = *(float *)(j < 4 ? xmm_ptr + j : args_ptr);
|
|
575
557
|
args_ptr += (j >= 4);
|
|
@@ -585,7 +567,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
585
567
|
arguments.Append(arg);
|
|
586
568
|
} break;
|
|
587
569
|
|
|
588
|
-
case PrimitiveKind::Prototype: {
|
|
570
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
589
571
|
}
|
|
590
572
|
}
|
|
591
573
|
|
|
@@ -674,7 +656,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
674
656
|
case PrimitiveKind::Pointer: {
|
|
675
657
|
uint8_t *ptr;
|
|
676
658
|
|
|
677
|
-
if (CheckValueTag(
|
|
659
|
+
if (CheckValueTag(value, type->ref.marker)) {
|
|
678
660
|
ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
679
661
|
} else if (IsObject(value) && (type->ref.type->primitive == PrimitiveKind::Record ||
|
|
680
662
|
type->ref.type->primitive == PrimitiveKind::Union)) {
|
|
@@ -710,7 +692,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
710
692
|
PushObject(obj, type, (uint8_t *)&out_reg->rax);
|
|
711
693
|
}
|
|
712
694
|
} break;
|
|
713
|
-
case PrimitiveKind::Array: {
|
|
695
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
714
696
|
case PrimitiveKind::Float32: {
|
|
715
697
|
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
716
698
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
@@ -740,7 +722,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
740
722
|
ptr = ReserveTrampoline(type->ref.proto, func2);
|
|
741
723
|
if (!ptr) [[unlikely]]
|
|
742
724
|
return;
|
|
743
|
-
} else if (CheckValueTag(
|
|
725
|
+
} else if (CheckValueTag(value, type->ref.marker)) {
|
|
744
726
|
ptr = value.As<Napi::External<void>>().Data();
|
|
745
727
|
} else if (IsNullOrUndefined(value)) {
|
|
746
728
|
ptr = nullptr;
|
|
@@ -752,7 +734,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
|
|
|
752
734
|
out_reg->rax = (uint64_t)ptr;
|
|
753
735
|
} break;
|
|
754
736
|
|
|
755
|
-
case PrimitiveKind::Prototype: {
|
|
737
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
756
738
|
}
|
|
757
739
|
|
|
758
740
|
#undef RETURN_INTEGER_SWAP
|
|
@@ -1,23 +1,5 @@
|
|
|
1
|
-
;
|
|
2
|
-
;
|
|
3
|
-
; Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
-
; this software and associated documentation files (the “Software”), to deal in
|
|
5
|
-
; the Software without restriction, including without limitation the rights to use,
|
|
6
|
-
; copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
-
; Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
-
; subject to the following conditions:
|
|
9
|
-
;
|
|
10
|
-
; The above copyright notice and this permission notice shall be included in all
|
|
11
|
-
; copies or substantial portions of the Software.
|
|
12
|
-
;
|
|
13
|
-
; THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
-
; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
-
; OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
-
; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
-
; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
-
; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
-
; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
-
; OTHER DEALINGS IN THE SOFTWARE.
|
|
1
|
+
; SPDX-License-Identifier: MIT
|
|
2
|
+
; SPDX-FileCopyrightText: 2025 Niels Martignène <niels.martignene@protonmail.com>
|
|
21
3
|
|
|
22
4
|
; Forward
|
|
23
5
|
; ----------------------------
|
package/src/koffi/src/abi_x86.cc
CHANGED
|
@@ -1,27 +1,9 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
-
// this software and associated documentation files (the “Software”), to deal in
|
|
5
|
-
// the Software without restriction, including without limitation the rights to use,
|
|
6
|
-
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
-
// Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
-
// subject to the following conditions:
|
|
9
|
-
//
|
|
10
|
-
// The above copyright notice and this permission notice shall be included in all
|
|
11
|
-
// copies or substantial portions of the Software.
|
|
12
|
-
//
|
|
13
|
-
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
-
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
-
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
-
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
-
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
-
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
-
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
-
// OTHER DEALINGS IN THE SOFTWARE.
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// SPDX-FileCopyrightText: 2025 Niels Martignène <niels.martignene@protonmail.com>
|
|
21
3
|
|
|
22
4
|
#if defined(__i386__) || defined(_M_IX86)
|
|
23
5
|
|
|
24
|
-
#include "
|
|
6
|
+
#include "lib/native/base/base.hh"
|
|
25
7
|
#include "ffi.hh"
|
|
26
8
|
#include "call.hh"
|
|
27
9
|
#include "util.hh"
|
|
@@ -31,7 +13,7 @@
|
|
|
31
13
|
|
|
32
14
|
#include <napi.h>
|
|
33
15
|
|
|
34
|
-
namespace
|
|
16
|
+
namespace K {
|
|
35
17
|
|
|
36
18
|
struct BackRegisters {
|
|
37
19
|
uint32_t eax;
|
|
@@ -112,16 +94,16 @@ bool AnalyseFunction(Napi::Env env, InstanceData *instance, FunctionInfo *func)
|
|
|
112
94
|
func->decorated_name = Fmt(&instance->str_alloc, "_%1", func->name).ptr;
|
|
113
95
|
} break;
|
|
114
96
|
case CallConvention::Stdcall: {
|
|
115
|
-
|
|
97
|
+
K_ASSERT(!func->variadic);
|
|
116
98
|
func->decorated_name = Fmt(&instance->str_alloc, "_%1@%2", func->name, params_size).ptr;
|
|
117
99
|
} break;
|
|
118
100
|
case CallConvention::Fastcall: {
|
|
119
|
-
|
|
101
|
+
K_ASSERT(!func->variadic);
|
|
120
102
|
func->decorated_name = Fmt(&instance->str_alloc, "@%1@%2", func->name, params_size).ptr;
|
|
121
103
|
func->args_size += 16;
|
|
122
104
|
} break;
|
|
123
105
|
case CallConvention::Thiscall: {
|
|
124
|
-
|
|
106
|
+
K_ASSERT(!func->variadic);
|
|
125
107
|
func->args_size += 16;
|
|
126
108
|
} break;
|
|
127
109
|
}
|
|
@@ -194,12 +176,12 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
194
176
|
// Push arguments
|
|
195
177
|
for (Size i = 0; i < func->parameters.len; i++) {
|
|
196
178
|
const ParameterInfo ¶m = func->parameters[i];
|
|
197
|
-
|
|
179
|
+
K_ASSERT(param.directions >= 1 && param.directions <= 3);
|
|
198
180
|
|
|
199
181
|
Napi::Value value = info[param.offset];
|
|
200
182
|
|
|
201
183
|
switch (param.type->primitive) {
|
|
202
|
-
case PrimitiveKind::Void: {
|
|
184
|
+
case PrimitiveKind::Void: { K_UNREACHABLE(); } break;
|
|
203
185
|
|
|
204
186
|
case PrimitiveKind::Bool: {
|
|
205
187
|
if (!value.IsBoolean()) [[unlikely]] {
|
|
@@ -272,7 +254,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
272
254
|
args_ptr = (uint32_t *)AlignUp(ptr + param.type->size, 4);
|
|
273
255
|
}
|
|
274
256
|
} break;
|
|
275
|
-
case PrimitiveKind::Array: {
|
|
257
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
276
258
|
case PrimitiveKind::Float32: {
|
|
277
259
|
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
278
260
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
@@ -300,7 +282,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
300
282
|
*(void **)((param.fast ? fast_ptr : args_ptr)++) = ptr;
|
|
301
283
|
} break;
|
|
302
284
|
|
|
303
|
-
case PrimitiveKind::Prototype: {
|
|
285
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
304
286
|
}
|
|
305
287
|
}
|
|
306
288
|
|
|
@@ -320,7 +302,7 @@ void CallData::Execute(const FunctionInfo *func, void *native)
|
|
|
320
302
|
TEB *teb = GetTEB();
|
|
321
303
|
|
|
322
304
|
// Restore previous stack limits at the end
|
|
323
|
-
|
|
305
|
+
K_DEFER_C(exception_list = teb->ExceptionList,
|
|
324
306
|
base = teb->StackBase,
|
|
325
307
|
limit = teb->StackLimit,
|
|
326
308
|
dealloc = teb->DeallocationStack,
|
|
@@ -387,18 +369,18 @@ void CallData::Execute(const FunctionInfo *func, void *native)
|
|
|
387
369
|
} else if (func->ret.fast == 2) {
|
|
388
370
|
result.d = PERFORM_CALL(D);
|
|
389
371
|
} else {
|
|
390
|
-
|
|
372
|
+
K_UNREACHABLE();
|
|
391
373
|
}
|
|
392
374
|
} break;
|
|
393
375
|
#else
|
|
394
376
|
case PrimitiveKind::Record:
|
|
395
377
|
case PrimitiveKind::Union: { result.u64 = PERFORM_CALL(G); } break;
|
|
396
378
|
#endif
|
|
397
|
-
case PrimitiveKind::Array: {
|
|
379
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
398
380
|
case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
|
|
399
381
|
case PrimitiveKind::Float64: { result.d = PERFORM_CALL(D); } break;
|
|
400
382
|
|
|
401
|
-
case PrimitiveKind::Prototype: {
|
|
383
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
402
384
|
}
|
|
403
385
|
|
|
404
386
|
#undef PERFORM_CALL
|
|
@@ -406,7 +388,7 @@ void CallData::Execute(const FunctionInfo *func, void *native)
|
|
|
406
388
|
|
|
407
389
|
Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
408
390
|
{
|
|
409
|
-
|
|
391
|
+
K_DEFER {
|
|
410
392
|
PopOutArguments();
|
|
411
393
|
|
|
412
394
|
if (func->ret.type->dispose) {
|
|
@@ -438,7 +420,7 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
438
420
|
case PrimitiveKind::Callback: {
|
|
439
421
|
if (result.ptr) {
|
|
440
422
|
Napi::External<void> external = Napi::External<void>::New(env, result.ptr);
|
|
441
|
-
SetValueTag(
|
|
423
|
+
SetValueTag(external, func->ret.type->ref.marker);
|
|
442
424
|
|
|
443
425
|
return external;
|
|
444
426
|
} else {
|
|
@@ -453,14 +435,14 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
453
435
|
Napi::Object obj = DecodeObject(env, ptr, func->ret.type);
|
|
454
436
|
return obj;
|
|
455
437
|
} break;
|
|
456
|
-
case PrimitiveKind::Array: {
|
|
438
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
457
439
|
case PrimitiveKind::Float32: return Napi::Number::New(env, (double)result.f);
|
|
458
440
|
case PrimitiveKind::Float64: return Napi::Number::New(env, result.d);
|
|
459
441
|
|
|
460
|
-
case PrimitiveKind::Prototype: {
|
|
442
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
461
443
|
}
|
|
462
444
|
|
|
463
|
-
|
|
445
|
+
K_UNREACHABLE();
|
|
464
446
|
}
|
|
465
447
|
|
|
466
448
|
void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack, BackRegisters *out_reg)
|
|
@@ -472,7 +454,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
472
454
|
TEB *teb = GetTEB();
|
|
473
455
|
|
|
474
456
|
// Restore previous stack limits at the end
|
|
475
|
-
|
|
457
|
+
K_DEFER_C(base = teb->StackBase,
|
|
476
458
|
limit = teb->StackLimit,
|
|
477
459
|
dealloc = teb->DeallocationStack) {
|
|
478
460
|
teb->StackBase = base;
|
|
@@ -506,9 +488,9 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
506
488
|
#endif
|
|
507
489
|
}
|
|
508
490
|
|
|
509
|
-
|
|
491
|
+
K_DEFER_N(err_guard) {
|
|
510
492
|
int pop = out_reg->ret_pop;
|
|
511
|
-
memset(out_reg, 0,
|
|
493
|
+
memset(out_reg, 0, K_SIZE(*out_reg));
|
|
512
494
|
out_reg->x87_double = true;
|
|
513
495
|
out_reg->ret_pop = pop;
|
|
514
496
|
};
|
|
@@ -525,10 +507,10 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
525
507
|
// Convert to JS arguments
|
|
526
508
|
for (Size i = 0; i < proto->parameters.len; i++) {
|
|
527
509
|
const ParameterInfo ¶m = proto->parameters[i];
|
|
528
|
-
|
|
510
|
+
K_ASSERT(param.directions >= 1 && param.directions <= 3);
|
|
529
511
|
|
|
530
512
|
switch (param.type->primitive) {
|
|
531
|
-
case PrimitiveKind::Void: {
|
|
513
|
+
case PrimitiveKind::Void: { K_UNREACHABLE(); } break;
|
|
532
514
|
|
|
533
515
|
case PrimitiveKind::Bool: {
|
|
534
516
|
bool b = *(bool *)(args_ptr++);
|
|
@@ -660,7 +642,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
660
642
|
|
|
661
643
|
if (ptr2) {
|
|
662
644
|
Napi::External<void> external = Napi::External<void>::New(env, ptr2);
|
|
663
|
-
SetValueTag(
|
|
645
|
+
SetValueTag(external, param.type->ref.marker);
|
|
664
646
|
|
|
665
647
|
arguments.Append(external);
|
|
666
648
|
} else {
|
|
@@ -673,7 +655,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
673
655
|
} break;
|
|
674
656
|
case PrimitiveKind::Record:
|
|
675
657
|
case PrimitiveKind::Union: {
|
|
676
|
-
|
|
658
|
+
K_ASSERT(!param.fast);
|
|
677
659
|
|
|
678
660
|
uint8_t *ptr = (uint8_t *)args_ptr;
|
|
679
661
|
|
|
@@ -682,7 +664,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
682
664
|
|
|
683
665
|
args_ptr = (uint32_t *)AlignUp(ptr + param.type->size, 4);
|
|
684
666
|
} break;
|
|
685
|
-
case PrimitiveKind::Array: {
|
|
667
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
686
668
|
case PrimitiveKind::Float32: {
|
|
687
669
|
float f = *(float *)(args_ptr++);
|
|
688
670
|
|
|
@@ -697,7 +679,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
697
679
|
arguments.Append(arg);
|
|
698
680
|
} break;
|
|
699
681
|
|
|
700
|
-
case PrimitiveKind::Prototype: {
|
|
682
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
701
683
|
}
|
|
702
684
|
}
|
|
703
685
|
|
|
@@ -810,7 +792,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
810
792
|
case PrimitiveKind::Pointer: {
|
|
811
793
|
uint8_t *ptr;
|
|
812
794
|
|
|
813
|
-
if (CheckValueTag(
|
|
795
|
+
if (CheckValueTag(value, type->ref.marker)) {
|
|
814
796
|
ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
815
797
|
} else if (IsObject(value) && (type->ref.type->primitive == PrimitiveKind::Record ||
|
|
816
798
|
type->ref.type->primitive == PrimitiveKind::Union)) {
|
|
@@ -846,7 +828,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
846
828
|
PushObject(obj, type, (uint8_t *)&out_reg->eax);
|
|
847
829
|
}
|
|
848
830
|
} break;
|
|
849
|
-
case PrimitiveKind::Array: {
|
|
831
|
+
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
850
832
|
case PrimitiveKind::Float32: {
|
|
851
833
|
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
852
834
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
|
|
@@ -874,7 +856,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
874
856
|
ptr = ReserveTrampoline(type->ref.proto, func2);
|
|
875
857
|
if (!ptr) [[unlikely]]
|
|
876
858
|
return;
|
|
877
|
-
} else if (CheckValueTag(
|
|
859
|
+
} else if (CheckValueTag(value, type->ref.marker)) {
|
|
878
860
|
ptr = value.As<Napi::External<void>>().Data();
|
|
879
861
|
} else if (IsNullOrUndefined(value)) {
|
|
880
862
|
ptr = nullptr;
|
|
@@ -886,7 +868,7 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool switch_stack,
|
|
|
886
868
|
out_reg->eax = (uint32_t)ptr;
|
|
887
869
|
} break;
|
|
888
870
|
|
|
889
|
-
case PrimitiveKind::Prototype: {
|
|
871
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
890
872
|
}
|
|
891
873
|
|
|
892
874
|
#undef RETURN_INTEGER_64_SWAP
|
|
@@ -1,23 +1,5 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
-
# this software and associated documentation files (the “Software”), to deal in
|
|
5
|
-
# the Software without restriction, including without limitation the rights to use,
|
|
6
|
-
# copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
-
# Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
-
# subject to the following conditions:
|
|
9
|
-
#
|
|
10
|
-
# The above copyright notice and this permission notice shall be included in all
|
|
11
|
-
# copies or substantial portions of the Software.
|
|
12
|
-
#
|
|
13
|
-
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
-
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
-
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
-
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
-
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
-
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
-
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
-
# OTHER DEALINGS IN THE SOFTWARE.
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# SPDX-FileCopyrightText: 2025 Niels Martignène <niels.martignene@protonmail.com>
|
|
21
3
|
|
|
22
4
|
#define SYMBOL(Symbol) Symbol
|
|
23
5
|
|
|
@@ -1,23 +1,5 @@
|
|
|
1
|
-
;
|
|
2
|
-
;
|
|
3
|
-
; Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
-
; this software and associated documentation files (the “Software”), to deal in
|
|
5
|
-
; the Software without restriction, including without limitation the rights to use,
|
|
6
|
-
; copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
-
; Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
-
; subject to the following conditions:
|
|
9
|
-
;
|
|
10
|
-
; The above copyright notice and this permission notice shall be included in all
|
|
11
|
-
; copies or substantial portions of the Software.
|
|
12
|
-
;
|
|
13
|
-
; THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
-
; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
-
; OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
-
; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
-
; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
-
; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
-
; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
-
; OTHER DEALINGS IN THE SOFTWARE.
|
|
1
|
+
; SPDX-License-Identifier: MIT
|
|
2
|
+
; SPDX-FileCopyrightText: 2025 Niels Martignène <niels.martignene@protonmail.com>
|
|
21
3
|
|
|
22
4
|
; Forward
|
|
23
5
|
; ----------------------------
|