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.
Files changed (105) hide show
  1. package/CHANGELOG.md +26 -1
  2. package/README.md +1 -1
  3. package/build/koffi/darwin_arm64/koffi.node +0 -0
  4. package/build/koffi/darwin_x64/koffi.node +0 -0
  5. package/build/koffi/freebsd_arm64/koffi.node +0 -0
  6. package/build/koffi/freebsd_ia32/koffi.node +0 -0
  7. package/build/koffi/freebsd_x64/koffi.node +0 -0
  8. package/build/koffi/linux_arm64/koffi.node +0 -0
  9. package/build/koffi/linux_armhf/koffi.node +0 -0
  10. package/build/koffi/linux_ia32/koffi.node +0 -0
  11. package/build/koffi/linux_loong64/koffi.node +0 -0
  12. package/build/koffi/linux_riscv64d/koffi.node +0 -0
  13. package/build/koffi/linux_x64/koffi.node +0 -0
  14. package/build/koffi/musl_arm64/koffi.node +0 -0
  15. package/build/koffi/musl_x64/koffi.node +0 -0
  16. package/build/koffi/openbsd_ia32/koffi.node +0 -0
  17. package/build/koffi/openbsd_x64/koffi.node +0 -0
  18. package/build/koffi/win32_arm64/koffi.node +0 -0
  19. package/build/koffi/win32_ia32/koffi.node +0 -0
  20. package/build/koffi/win32_x64/koffi.node +0 -0
  21. package/doc/assets.ini +2 -1
  22. package/doc/build.sh +9 -0
  23. package/doc/pages/404.md +17 -0
  24. package/doc/pages/index.md +43 -4
  25. package/doc/pages/misc.md +16 -11
  26. package/doc/pages/platforms.md +8 -19
  27. package/doc/pages.ini +4 -7
  28. package/doc/static/highlight.js +2 -14
  29. package/doc/static/koffi.css +3 -15
  30. package/doc/static/perf_windows.png +0 -0
  31. package/doc/static/print.css +2 -14
  32. package/index.d.ts +29 -24
  33. package/index.js +10 -9
  34. package/indirect.js +10 -9
  35. package/{src/core → lib/native}/base/base.cc +1753 -1089
  36. package/{src/core → lib/native}/base/base.hh +868 -572
  37. package/{src/core → lib/native}/base/crc.inc +3 -21
  38. package/lib/native/base/crc_gen.py +72 -0
  39. package/{src/core → lib/native}/base/mimetypes.inc +2 -20
  40. package/{src/core → lib/native}/base/mimetypes_gen.py +2 -21
  41. package/lib/native/base/tower.cc +821 -0
  42. package/lib/native/base/tower.hh +81 -0
  43. package/{src/core → lib/native}/base/unicode.inc +3 -21
  44. package/{src/core → lib/native}/base/unicode_gen.py +5 -42
  45. package/package.json +3 -2
  46. package/src/cnoke/assets/FindCNoke.cmake +8 -20
  47. package/src/cnoke/assets/win_delay_hook.c +2 -20
  48. package/src/cnoke/cnoke.js +2 -21
  49. package/src/cnoke/src/builder.js +3 -22
  50. package/src/cnoke/src/index.js +2 -20
  51. package/src/cnoke/src/tools.js +2 -20
  52. package/src/koffi/CMakeLists.txt +19 -22
  53. package/src/koffi/cmake/raylib.cmake +5 -22
  54. package/src/koffi/cmake/sqlite3.cmake +2 -20
  55. package/src/koffi/src/abi_arm32.cc +31 -49
  56. package/src/koffi/src/abi_arm32_asm.S +2 -20
  57. package/src/koffi/src/abi_arm64.cc +36 -54
  58. package/src/koffi/src/abi_arm64_asm.S +2 -20
  59. package/src/koffi/src/abi_arm64_asm.asm +2 -20
  60. package/src/koffi/src/abi_loong64.cc +2 -20
  61. package/src/koffi/src/abi_loong64_asm.S +2 -20
  62. package/src/koffi/src/abi_riscv64.cc +34 -52
  63. package/src/koffi/src/abi_riscv64_asm.S +2 -20
  64. package/src/koffi/src/abi_x64_sysv.cc +36 -54
  65. package/src/koffi/src/abi_x64_sysv_asm.S +2 -20
  66. package/src/koffi/src/abi_x64_win.cc +32 -50
  67. package/src/koffi/src/abi_x64_win_asm.asm +2 -20
  68. package/src/koffi/src/abi_x86.cc +33 -51
  69. package/src/koffi/src/abi_x86_asm.S +2 -20
  70. package/src/koffi/src/abi_x86_asm.asm +2 -20
  71. package/src/koffi/src/call.cc +107 -281
  72. package/src/koffi/src/call.hh +9 -27
  73. package/src/koffi/src/errno.inc +2 -20
  74. package/src/koffi/src/ffi.cc +121 -121
  75. package/src/koffi/src/ffi.hh +23 -38
  76. package/src/koffi/src/init.js +2 -20
  77. package/src/koffi/src/parser.cc +15 -29
  78. package/src/koffi/src/parser.hh +4 -22
  79. package/src/koffi/src/trampolines/armasm.inc +0 -21
  80. package/src/koffi/src/trampolines/gnu.inc +0 -21
  81. package/src/koffi/src/trampolines/masm32.inc +0 -21
  82. package/src/koffi/src/trampolines/masm64.inc +0 -21
  83. package/src/koffi/src/trampolines/prototypes.inc +1 -22
  84. package/src/koffi/src/util.cc +87 -102
  85. package/src/koffi/src/util.hh +11 -29
  86. package/src/koffi/src/uv.cc +193 -0
  87. package/src/koffi/src/uv.def +10 -0
  88. package/src/koffi/src/uv.hh +40 -0
  89. package/src/koffi/src/win32.cc +7 -25
  90. package/src/koffi/src/win32.hh +4 -22
  91. package/vendor/node-api-headers/include/uv/aix.h +32 -0
  92. package/vendor/node-api-headers/include/uv/bsd.h +34 -0
  93. package/vendor/node-api-headers/include/uv/darwin.h +61 -0
  94. package/vendor/node-api-headers/include/uv/errno.h +483 -0
  95. package/vendor/node-api-headers/include/uv/linux.h +34 -0
  96. package/vendor/node-api-headers/include/uv/os390.h +33 -0
  97. package/vendor/node-api-headers/include/uv/posix.h +31 -0
  98. package/vendor/node-api-headers/include/uv/sunos.h +44 -0
  99. package/vendor/node-api-headers/include/uv/threadpool.h +37 -0
  100. package/vendor/node-api-headers/include/uv/tree.h +521 -0
  101. package/vendor/node-api-headers/include/uv/unix.h +512 -0
  102. package/vendor/node-api-headers/include/uv/version.h +43 -0
  103. package/vendor/node-api-headers/include/uv/win.h +698 -0
  104. package/vendor/node-api-headers/include/uv.h +1990 -0
  105. package/src/core/base/crc_gen.py +0 -109
@@ -1,32 +1,14 @@
1
- // Copyright (C) 2025 Niels Martignène <niels.martignene@protonmail.com>
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.
21
-
22
- #include "src/core/base/base.hh"
1
+ // SPDX-License-Identifier: MIT
2
+ // SPDX-FileCopyrightText: 2025 Niels Martignène <niels.martignene@protonmail.com>
3
+
4
+ #include "lib/native/base/base.hh"
23
5
  #include "call.hh"
24
6
  #include "ffi.hh"
25
7
  #include "util.hh"
26
8
 
27
9
  #include <napi.h>
28
10
 
29
- namespace RG {
11
+ namespace K {
30
12
 
31
13
  // Value does not matter, the tag system uses memory addresses
32
14
  const napi_type_tag TypeInfoMarker = { 0x1cc449675b294374, 0xbb13a50e97dcb017 };
@@ -35,10 +17,10 @@ const napi_type_tag MagicUnionMarker = { 0x5eaf2245526a4c7d, 0x8c86c9ee2b96ffc8
35
17
 
36
18
  Napi::Function MagicUnion::InitClass(Napi::Env env, const TypeInfo *type)
37
19
  {
38
- RG_ASSERT(type->primitive == PrimitiveKind::Union);
20
+ K_ASSERT(type->primitive == PrimitiveKind::Union);
39
21
 
40
22
  // node-addon-api wants std::vector
41
- std::vector<Napi::ClassPropertyDescriptor<MagicUnion>> properties;
23
+ std::vector<Napi::ClassPropertyDescriptor<MagicUnion>> properties;
42
24
  properties.reserve(type->members.len);
43
25
 
44
26
  for (Size i = 0; i < type->members.len; i++) {
@@ -96,7 +78,7 @@ Napi::Value MagicUnion::Getter(const Napi::CallbackInfo &info)
96
78
  active_idx = idx;
97
79
  }
98
80
 
99
- RG_ASSERT(!value.IsEmpty());
81
+ K_ASSERT(!value.IsEmpty());
100
82
  return value;
101
83
  }
102
84
 
@@ -187,7 +169,7 @@ const TypeInfo *ResolveType(Napi::Value value, int *out_directions)
187
169
 
188
170
  // Cache for quick future access
189
171
  bool inserted;
190
- auto bucket = instance->types_map.TrySetDefault(remain.ptr, &inserted);
172
+ auto bucket = instance->types_map.InsertOrGetDefault(remain.ptr, &inserted);
191
173
 
192
174
  if (inserted) {
193
175
  bucket->key = DuplicateString(remain, &instance->str_alloc).ptr;
@@ -198,12 +180,12 @@ const TypeInfo *ResolveType(Napi::Value value, int *out_directions)
198
180
  }
199
181
 
200
182
  return type;
201
- } else if (CheckValueTag(instance, value, &TypeInfoMarker)) {
183
+ } else if (CheckValueTag(value, &TypeInfoMarker)) {
202
184
  Napi::External<TypeInfo> external = value.As<Napi::External<TypeInfo>>();
203
185
  const TypeInfo *raw = external.Data();
204
186
 
205
187
  const TypeInfo *type = AlignDown(raw, 4);
206
- RG_ASSERT(type);
188
+ K_ASSERT(type);
207
189
 
208
190
  if (out_directions) {
209
191
  Size delta = (uint8_t *)raw - (uint8_t *)type;
@@ -343,7 +325,7 @@ const TypeInfo *ResolveType(Napi::Env env, Span<const char> str)
343
325
 
344
326
  TypeInfo *copy = instance->types.AppendDefault();
345
327
 
346
- memcpy((void *)copy, (const void *)type, RG_SIZE(*type));
328
+ memcpy((void *)copy, (const void *)type, K_SIZE(*type));
347
329
  copy->name = Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.count).ptr;
348
330
  copy->members.allocator = GetNullAllocator();
349
331
 
@@ -373,12 +355,12 @@ const TypeInfo *ResolveType(Napi::Env env, Span<const char> str)
373
355
  }
374
356
 
375
357
  type = MakeArrayType(instance, type, len);
376
- RG_ASSERT(type);
358
+ K_ASSERT(type);
377
359
  } else {
378
- RG_ASSERT(!len);
360
+ K_ASSERT(!len);
379
361
 
380
362
  type = MakePointerType(instance, type);
381
- RG_ASSERT(type);
363
+ K_ASSERT(type);
382
364
  }
383
365
  }
384
366
 
@@ -392,14 +374,14 @@ const TypeInfo *ResolveType(Napi::Env env, Span<const char> str)
392
374
 
393
375
  TypeInfo *MakePointerType(InstanceData *instance, const TypeInfo *ref, int count)
394
376
  {
395
- RG_ASSERT(count >= 1);
377
+ K_ASSERT(count >= 1);
396
378
 
397
379
  for (int i = 0; i < count; i++) {
398
380
  char name_buf[256];
399
381
  Fmt(name_buf, "%1%2*", ref->name, EndsWith(ref->name, "*") ? "" : " ");
400
382
 
401
383
  bool inserted;
402
- auto bucket = instance->types_map.TrySetDefault(name_buf, &inserted);
384
+ auto bucket = instance->types_map.InsertOrGetDefault(name_buf, &inserted);
403
385
 
404
386
  if (inserted) {
405
387
  TypeInfo *type = instance->types.AppendDefault();
@@ -408,14 +390,14 @@ TypeInfo *MakePointerType(InstanceData *instance, const TypeInfo *ref, int count
408
390
 
409
391
  if (ref->primitive != PrimitiveKind::Prototype) {
410
392
  type->primitive = PrimitiveKind::Pointer;
411
- type->size = RG_SIZE(void *);
412
- type->align = RG_SIZE(void *);
393
+ type->size = K_SIZE(void *);
394
+ type->align = K_SIZE(void *);
413
395
  type->ref.type = ref;
414
396
  type->hint = (ref->flags & (int)TypeFlag::HasTypedArray) ? ArrayHint::Typed : ArrayHint::Array;
415
397
  } else {
416
398
  type->primitive = PrimitiveKind::Callback;
417
- type->size = RG_SIZE(void *);
418
- type->align = RG_SIZE(void *);
399
+ type->size = K_SIZE(void *);
400
+ type->align = K_SIZE(void *);
419
401
  type->ref.proto = ref->ref.proto;
420
402
  }
421
403
 
@@ -431,8 +413,8 @@ TypeInfo *MakePointerType(InstanceData *instance, const TypeInfo *ref, int count
431
413
 
432
414
  static TypeInfo *MakeArrayType(InstanceData *instance, const TypeInfo *ref, Size len, ArrayHint hint, bool insert)
433
415
  {
434
- RG_ASSERT(len >= 0);
435
- RG_ASSERT(len <= instance->config.max_type_size / ref->size);
416
+ K_ASSERT(len >= 0);
417
+ K_ASSERT(len <= instance->config.max_type_size / ref->size);
436
418
 
437
419
  TypeInfo *type = instance->types.AppendDefault();
438
420
 
@@ -446,7 +428,7 @@ static TypeInfo *MakeArrayType(InstanceData *instance, const TypeInfo *ref, Size
446
428
 
447
429
  if (insert) {
448
430
  bool inserted;
449
- type = (TypeInfo *)*instance->types_map.TrySet(type->name, type, &inserted);
431
+ type = (TypeInfo *)*instance->types_map.InsertOrGet(type->name, type, &inserted);
450
432
  instance->types.RemoveLast(!inserted);
451
433
  }
452
434
 
@@ -473,10 +455,10 @@ TypeInfo *MakeArrayType(InstanceData *instance, const TypeInfo *ref, Size len, A
473
455
  return MakeArrayType(instance, ref, len, hint, false);
474
456
  }
475
457
 
476
- Napi::External<TypeInfo> WrapType(Napi::Env env, InstanceData *instance, const TypeInfo *type)
458
+ Napi::External<TypeInfo> WrapType(Napi::Env env, const TypeInfo *type)
477
459
  {
478
460
  Napi::External<TypeInfo> external = Napi::External<TypeInfo>::New(env, (TypeInfo *)type);
479
- SetValueTag(instance, external, &TypeInfoMarker);
461
+ SetValueTag(external, &TypeInfoMarker);
480
462
 
481
463
  return external;
482
464
  }
@@ -540,17 +522,17 @@ bool CanStoreType(const TypeInfo *type)
540
522
 
541
523
  const char *GetValueType(const InstanceData *instance, Napi::Value value)
542
524
  {
543
- if (CheckValueTag(instance, value, &CastMarker)) {
525
+ if (CheckValueTag(value, &CastMarker)) {
544
526
  Napi::External<ValueCast> external = value.As<Napi::External<ValueCast>>();
545
527
  ValueCast *cast = external.Data();
546
528
 
547
529
  return cast->type->name;
548
530
  }
549
531
 
550
- if (CheckValueTag(instance, value, &TypeInfoMarker))
532
+ if (CheckValueTag(value, &TypeInfoMarker))
551
533
  return "Type";
552
534
  for (const TypeInfo &type: instance->types) {
553
- if (type.ref.marker && CheckValueTag(instance, value, type.ref.marker))
535
+ if (type.ref.marker && CheckValueTag(value, type.ref.marker))
554
536
  return type.name;
555
537
  }
556
538
 
@@ -595,9 +577,9 @@ const char *GetValueType(const InstanceData *instance, Napi::Value value)
595
577
  return "Unknown";
596
578
  }
597
579
 
598
- void SetValueTag(const InstanceData *instance, Napi::Value value, const void *marker)
580
+ void SetValueTag(Napi::Value value, const void *marker)
599
581
  {
600
- static_assert(RG_SIZE(TypeInfo) >= 16);
582
+ static_assert(K_SIZE(TypeInfo) >= 16);
601
583
 
602
584
  // We used to make a temporary tag on the stack with lower set to a constant value and
603
585
  // upper to the pointer address, but this broke in Node 20.12 and Node 21.6 due to ExternalWrapper
@@ -611,10 +593,10 @@ void SetValueTag(const InstanceData *instance, Napi::Value value, const void *ma
611
593
  const napi_type_tag *tag = (const napi_type_tag *)marker;
612
594
 
613
595
  napi_status status = napi_type_tag_object(value.Env(), value, tag);
614
- RG_ASSERT(status == napi_ok);
596
+ K_ASSERT(status == napi_ok);
615
597
  }
616
598
 
617
- bool CheckValueTag(const InstanceData *instance, Napi::Value value, const void *marker)
599
+ bool CheckValueTag(Napi::Value value, const void *marker)
618
600
  {
619
601
  bool match = false;
620
602
 
@@ -641,30 +623,32 @@ int GetTypedArrayType(const TypeInfo *type)
641
623
  default: return -1;
642
624
  }
643
625
 
644
- RG_UNREACHABLE();
626
+ K_UNREACHABLE();
645
627
  }
646
628
 
647
629
  Napi::String MakeStringFromUTF32(Napi::Env env, const char32_t *ptr, Size len)
648
630
  {
631
+ static const char16_t ReplacementChar = 0xFFFD;
632
+
649
633
  HeapArray<char16_t> buf;
650
634
  buf.Reserve(len * 2);
651
635
 
652
636
  for (Size i = 0; i < len; i++) {
653
637
  char32_t uc = ptr[i];
654
638
 
655
- if (uc < 0xFFFF) {
639
+ if (uc <= 0xFFFF) {
656
640
  if (uc < 0xD800 || uc > 0xDFFF) {
657
641
  buf.Append((char16_t)uc);
658
642
  } else {
659
- buf.Append('?');
643
+ buf.Append(ReplacementChar);
660
644
  }
661
- } else if (uc < 0x10FFFF) {
645
+ } else if (uc <= 0x10FFFF) {
662
646
  uc -= 0x0010000UL;
663
647
 
664
648
  buf.Append((char16_t)((uc >> 10) + 0xD800));
665
649
  buf.Append((char16_t)((uc & 0x3FFul) + 0xDC00));
666
650
  } else {
667
- buf.Append('?');
651
+ buf.Append(ReplacementChar);
668
652
  }
669
653
  }
670
654
 
@@ -676,10 +660,8 @@ Napi::Object DecodeObject(Napi::Env env, const uint8_t *origin, const TypeInfo *
676
660
  {
677
661
  // We can't decode unions because we don't know which member is valid
678
662
  if (type->primitive == PrimitiveKind::Union) {
679
- InstanceData *instance = env.GetInstanceData<InstanceData>();
680
-
681
663
  Napi::Object wrapper = type->construct.New({}).As<Napi::Object>();
682
- SetValueTag(instance, wrapper, &MagicUnionMarker);
664
+ SetValueTag(wrapper, &MagicUnionMarker);
683
665
 
684
666
  MagicUnion *u = MagicUnion::Unwrap(wrapper);
685
667
  u->SetRaw(origin);
@@ -766,18 +748,17 @@ static uint32_t DecodeDynamicLength(const uint8_t *origin, const RecordMember &b
766
748
  case PrimitiveKind::Array:
767
749
  case PrimitiveKind::Float32:
768
750
  case PrimitiveKind::Float64:
769
- case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
751
+ case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
770
752
  }
771
753
 
772
- RG_UNREACHABLE();
754
+ K_UNREACHABLE();
773
755
  }
774
756
 
775
757
  void DecodeObject(Napi::Object obj, const uint8_t *origin, const TypeInfo *type)
776
758
  {
777
759
  Napi::Env env = obj.Env();
778
- InstanceData *instance = env.GetInstanceData<InstanceData>();
779
760
 
780
- RG_ASSERT(type->primitive == PrimitiveKind::Record);
761
+ K_ASSERT(type->primitive == PrimitiveKind::Record);
781
762
 
782
763
  for (Size i = 0; i < type->members.len; i++) {
783
764
  const RecordMember &member = type->members[i];
@@ -785,7 +766,7 @@ void DecodeObject(Napi::Object obj, const uint8_t *origin, const TypeInfo *type)
785
766
  const uint8_t *src = origin + member.offset;
786
767
 
787
768
  switch (member.type->primitive) {
788
- case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
769
+ case PrimitiveKind::Void: { K_UNREACHABLE(); } break;
789
770
 
790
771
  case PrimitiveKind::Bool: {
791
772
  bool b = *(bool *)src;
@@ -887,7 +868,7 @@ void DecodeObject(Napi::Object obj, const uint8_t *origin, const TypeInfo *type)
887
868
  obj.Set(member.name, value);
888
869
  } else if (ptr2) {
889
870
  Napi::External<void> external = Napi::External<void>::New(env, ptr2);
890
- SetValueTag(instance, external, member.type->ref.marker);
871
+ SetValueTag(external, member.type->ref.marker);
891
872
 
892
873
  obj.Set(member.name, external);
893
874
  } else {
@@ -929,14 +910,13 @@ void DecodeObject(Napi::Object obj, const uint8_t *origin, const TypeInfo *type)
929
910
  obj.Set(member.name, Napi::Number::New(env, d));
930
911
  } break;
931
912
 
932
- case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
913
+ case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
933
914
  }
934
915
  }
935
916
  }
936
917
 
937
918
  Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *type, uint32_t len)
938
919
  {
939
- InstanceData *instance = env.GetInstanceData<InstanceData>();
940
920
  Size offset = 0;
941
921
 
942
922
  #define POP_ARRAY(SetCode) \
@@ -964,7 +944,7 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
964
944
  }); \
965
945
  } else { \
966
946
  Napi::TypedArrayType array = Napi::TypedArrayType::New(env, len); \
967
- Span<uint8_t> buffer = MakeSpan((uint8_t *)array.ArrayBuffer().Data(), (Size)len * RG_SIZE(CType)); \
947
+ Span<uint8_t> buffer = MakeSpan((uint8_t *)array.ArrayBuffer().Data(), (Size)len * K_SIZE(CType)); \
968
948
  \
969
949
  DecodeBuffer(buffer, origin, type->ref.type); \
970
950
  \
@@ -981,7 +961,7 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
981
961
  }); \
982
962
  } else { \
983
963
  Napi::TypedArrayType array = Napi::TypedArrayType::New(env, len); \
984
- Span<uint8_t> buffer = MakeSpan((uint8_t *)array.ArrayBuffer().Data(), (Size)len * RG_SIZE(CType)); \
964
+ Span<uint8_t> buffer = MakeSpan((uint8_t *)array.ArrayBuffer().Data(), (Size)len * K_SIZE(CType)); \
985
965
  \
986
966
  DecodeBuffer(buffer, origin, type->ref.type); \
987
967
  \
@@ -990,7 +970,7 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
990
970
  } while (false)
991
971
 
992
972
  switch (type->ref.type->primitive) {
993
- case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
973
+ case PrimitiveKind::Void: { K_UNREACHABLE(); } break;
994
974
 
995
975
  case PrimitiveKind::Bool: {
996
976
  POP_ARRAY({
@@ -1087,7 +1067,7 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
1087
1067
 
1088
1068
  if (ptr2) {
1089
1069
  Napi::External<void> external = Napi::External<void>::New(env, ptr2);
1090
- SetValueTag(instance, external, type->ref.type->ref.marker);
1070
+ SetValueTag(external, type->ref.type->ref.marker);
1091
1071
 
1092
1072
  array.Set(i, external);
1093
1073
  } else {
@@ -1111,19 +1091,19 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
1111
1091
  case PrimitiveKind::Float32: { POP_NUMBER_ARRAY(Float32Array, float); } break;
1112
1092
  case PrimitiveKind::Float64: { POP_NUMBER_ARRAY(Float64Array, double); } break;
1113
1093
 
1114
- case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
1094
+ case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
1115
1095
  }
1116
1096
 
1117
1097
  #undef POP_NUMBER_ARRAY_SWAP
1118
1098
  #undef POP_NUMBER_ARRAY
1119
1099
  #undef POP_ARRAY
1120
1100
 
1121
- RG_UNREACHABLE();
1101
+ K_UNREACHABLE();
1122
1102
  }
1123
1103
 
1124
1104
  Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *type)
1125
1105
  {
1126
- RG_ASSERT(type->primitive == PrimitiveKind::Array);
1106
+ K_ASSERT(type->primitive == PrimitiveKind::Array);
1127
1107
 
1128
1108
  uint32_t len = type->size / type->ref.type->size;
1129
1109
  return DecodeArray(env, origin, type, len);
@@ -1132,9 +1112,8 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
1132
1112
  void DecodeNormalArray(Napi::Array array, const uint8_t *origin, const TypeInfo *ref)
1133
1113
  {
1134
1114
  Napi::Env env = array.Env();
1135
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1136
1115
 
1137
- RG_ASSERT(array.IsArray());
1116
+ K_ASSERT(array.IsArray());
1138
1117
 
1139
1118
  Size offset = 0;
1140
1119
  uint32_t len = array.Length();
@@ -1168,7 +1147,7 @@ void DecodeNormalArray(Napi::Array array, const uint8_t *origin, const TypeInfo
1168
1147
  } while (false)
1169
1148
 
1170
1149
  switch (ref->primitive) {
1171
- case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
1150
+ case PrimitiveKind::Void: { K_UNREACHABLE(); } break;
1172
1151
 
1173
1152
  case PrimitiveKind::Bool: {
1174
1153
  POP_ARRAY({
@@ -1247,7 +1226,7 @@ void DecodeNormalArray(Napi::Array array, const uint8_t *origin, const TypeInfo
1247
1226
 
1248
1227
  if (ptr2) {
1249
1228
  Napi::External<void> external = Napi::External<void>::New(env, ptr2);
1250
- SetValueTag(instance, external, ref->ref.marker);
1229
+ SetValueTag(external, ref->ref.marker);
1251
1230
 
1252
1231
  array.Set(i, external);
1253
1232
  } else {
@@ -1275,7 +1254,7 @@ void DecodeNormalArray(Napi::Array array, const uint8_t *origin, const TypeInfo
1275
1254
  case PrimitiveKind::Float32: { POP_NUMBER_ARRAY(float); } break;
1276
1255
  case PrimitiveKind::Float64: { POP_NUMBER_ARRAY(double); } break;
1277
1256
 
1278
- case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
1257
+ case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
1279
1258
  }
1280
1259
 
1281
1260
  #undef POP_NUMBER_ARRAY_SWAP
@@ -1291,7 +1270,7 @@ void DecodeBuffer(Span<uint8_t> buffer, const uint8_t *origin, const TypeInfo *r
1291
1270
  #define SWAP(CType) \
1292
1271
  do { \
1293
1272
  CType *data = (CType *)buffer.ptr; \
1294
- Size len = buffer.len / RG_SIZE(CType); \
1273
+ Size len = buffer.len / K_SIZE(CType); \
1295
1274
  \
1296
1275
  for (Size i = 0; i < len; i++) { \
1297
1276
  data[i] = ReverseBytes(data[i]); \
@@ -1322,6 +1301,10 @@ Napi::Value Decode(Napi::Value value, Size offset, const TypeInfo *type, const S
1322
1301
  } else if (IsRawBuffer(value)) {
1323
1302
  Span<uint8_t> buffer = GetRawBuffer(value);
1324
1303
 
1304
+ if (offset < 0) [[unlikely]] {
1305
+ ThrowError<Napi::Error>(env, "Offset must be >= 0");
1306
+ return env.Null();
1307
+ }
1325
1308
  if (buffer.len - offset < type->size) [[unlikely]] {
1326
1309
  ThrowError<Napi::Error>(env, "Expected buffer with size superior or equal to type %1 (%2 bytes)",
1327
1310
  type->name, type->size + offset);
@@ -1354,24 +1337,24 @@ Napi::Value Decode(Napi::Env env, const uint8_t *ptr, const TypeInfo *type, cons
1354
1337
  type = MakeArrayType(instance, type, *len);
1355
1338
  } else {
1356
1339
  switch (type->primitive) {
1357
- case PrimitiveKind::Int8:
1340
+ case PrimitiveKind::Int8:
1358
1341
  case PrimitiveKind::UInt8: {
1359
1342
  Size count = strlen((const char *)ptr);
1360
1343
  type = MakeArrayType(instance, type, count);
1361
1344
  } break;
1362
- case PrimitiveKind::Int16:
1345
+ case PrimitiveKind::Int16:
1363
1346
  case PrimitiveKind::UInt16: {
1364
- Size count = NullTerminatedLength((const char16_t *)ptr, RG_SIZE_MAX);
1347
+ Size count = NullTerminatedLength((const char16_t *)ptr, K_SIZE_MAX);
1365
1348
  type = MakeArrayType(instance, type, count);
1366
1349
  } break;
1367
1350
  case PrimitiveKind::Int32:
1368
1351
  case PrimitiveKind::UInt32: {
1369
- Size count = NullTerminatedLength((const char32_t *)ptr, RG_SIZE_MAX);
1352
+ Size count = NullTerminatedLength((const char32_t *)ptr, K_SIZE_MAX);
1370
1353
  type = MakeArrayType(instance, type, count);
1371
1354
  } break;
1372
1355
 
1373
1356
  case PrimitiveKind::Pointer: {
1374
- Size count = NullTerminatedLength((const void **)ptr, RG_SIZE_MAX);
1357
+ Size count = NullTerminatedLength((const void **)ptr, K_SIZE_MAX);
1375
1358
  type = MakeArrayType(instance, type, count);
1376
1359
  } break;
1377
1360
 
@@ -1470,14 +1453,14 @@ Napi::Value Decode(Napi::Env env, const uint8_t *ptr, const TypeInfo *type, cons
1470
1453
 
1471
1454
  case PrimitiveKind::Prototype: {
1472
1455
  const FunctionInfo *proto = type->ref.proto;
1473
- RG_ASSERT(!proto->variadic);
1474
- RG_ASSERT(!proto->lib);
1456
+ K_ASSERT(!proto->variadic);
1457
+ K_ASSERT(!proto->lib);
1475
1458
 
1476
1459
  FunctionInfo *func = new FunctionInfo();
1477
- RG_DEFER { func->Unref(); };
1460
+ K_DEFER { func->Unref(); };
1478
1461
 
1479
- memcpy((void *)func, proto, RG_SIZE(*proto));
1480
- memset((void *)&func->parameters, 0, RG_SIZE(func->parameters));
1462
+ memcpy((void *)func, proto, K_SIZE(*proto));
1463
+ memset((void *)&func->parameters, 0, K_SIZE(func->parameters));
1481
1464
  func->parameters = proto->parameters;
1482
1465
 
1483
1466
  func->name = "<anonymous>";
@@ -1513,6 +1496,10 @@ bool Encode(Napi::Value ref, Size offset, Napi::Value value, const TypeInfo *typ
1513
1496
  } else if (IsRawBuffer(ref)) {
1514
1497
  Span<uint8_t> buffer = GetRawBuffer(ref);
1515
1498
 
1499
+ if (offset < 0) [[unlikely]] {
1500
+ ThrowError<Napi::Error>(env, "Offset must be >= 0");
1501
+ return env.Null();
1502
+ }
1516
1503
  if (buffer.len - offset < type->size) [[unlikely]] {
1517
1504
  ThrowError<Napi::Error>(env, "Expected buffer with size superior or equal to type %1 (%2 bytes)",
1518
1505
  type->name, type->size + offset);
@@ -1521,7 +1508,7 @@ bool Encode(Napi::Value ref, Size offset, Napi::Value value, const TypeInfo *typ
1521
1508
 
1522
1509
  ptr = (uint8_t *)buffer.ptr;
1523
1510
  } else {
1524
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for reference, expected external or TypedArray", GetValueType(instance, value));
1511
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for reference, expected external or TypedArray", GetValueType(instance, ref));
1525
1512
  return env.Null();
1526
1513
  }
1527
1514
 
@@ -1575,7 +1562,7 @@ bool Encode(Napi::Env env, uint8_t *origin, Napi::Value value, const TypeInfo *t
1575
1562
  } while (false)
1576
1563
 
1577
1564
  switch (type->primitive) {
1578
- case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
1565
+ case PrimitiveKind::Void: { K_UNREACHABLE(); } break;
1579
1566
 
1580
1567
  case PrimitiveKind::Bool: {
1581
1568
  if (!value.IsBoolean()) [[unlikely]] {
@@ -1676,7 +1663,7 @@ bool Encode(Napi::Env env, uint8_t *origin, Napi::Value value, const TypeInfo *t
1676
1663
  if (value.IsFunction()) {
1677
1664
  ThrowError<Napi::Error>(env, "Cannot encode non-registered callback");
1678
1665
  return false;
1679
- } else if (CheckValueTag(instance, value, type->ref.marker)) {
1666
+ } else if (CheckValueTag(value, type->ref.marker)) {
1680
1667
  ptr = value.As<Napi::External<void>>().Data();
1681
1668
  } else if (IsNullOrUndefined(value)) {
1682
1669
  ptr = nullptr;
@@ -1688,7 +1675,7 @@ bool Encode(Napi::Env env, uint8_t *origin, Napi::Value value, const TypeInfo *t
1688
1675
  *(void **)origin = ptr;
1689
1676
  } break;
1690
1677
 
1691
- case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
1678
+ case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
1692
1679
  }
1693
1680
 
1694
1681
  #undef PUSH_INTEGER_SWAP
@@ -1715,8 +1702,6 @@ bool Encode(Napi::Env env, uint8_t *origin, Napi::Value value, const TypeInfo *t
1715
1702
 
1716
1703
  Napi::Function WrapFunction(Napi::Env env, const FunctionInfo *func)
1717
1704
  {
1718
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1719
-
1720
1705
  Napi::Function wrapper;
1721
1706
  if (func->variadic) {
1722
1707
  Napi::Function::Callback call = TranslateVariadicCall;
@@ -1742,11 +1727,11 @@ Napi::Function WrapFunction(Napi::Env env, const FunctionInfo *func)
1742
1727
 
1743
1728
  meta.Set("name", Napi::String::New(env, func->name));
1744
1729
  meta.Set("arguments", arguments);
1745
- meta.Set("result", WrapType(env, instance, func->ret.type));
1730
+ meta.Set("result", WrapType(env, func->ret.type));
1746
1731
 
1747
1732
  for (Size i = 0; i < func->parameters.len; i++) {
1748
1733
  const ParameterInfo &param = func->parameters[i];
1749
- arguments.Set((uint32_t)i, WrapType(env, instance, param.type));
1734
+ arguments.Set((uint32_t)i, WrapType(env, param.type));
1750
1735
  }
1751
1736
 
1752
1737
  wrapper.Set("info", meta);
@@ -1811,11 +1796,11 @@ void DumpMemory(const char *type, Span<const uint8_t> bytes)
1811
1796
  PrintLn(StdErr, "%1 at 0x%2 (%3):", type, bytes.ptr, FmtMemSize(bytes.len));
1812
1797
 
1813
1798
  for (const uint8_t *ptr = bytes.begin(); ptr < bytes.end();) {
1814
- Print(StdErr, " [0x%1 %2 %3] ", FmtArg(ptr).Pad0(-16),
1815
- FmtArg((ptr - bytes.begin()) / sizeof(void *)).Pad(-4),
1816
- FmtArg(ptr - bytes.begin()).Pad(-4));
1799
+ Print(StdErr, " [0x%1 %2 %3] ", FmtInt((uintptr_t)ptr, 16),
1800
+ FmtInt((ptr - bytes.begin()) / sizeof(void *), 4, ' '),
1801
+ FmtInt(ptr - bytes.begin(), 4, ' '));
1817
1802
  for (int i = 0; ptr < bytes.end() && i < (int)sizeof(void *); i++, ptr++) {
1818
- Print(StdErr, " %1", FmtHex(*ptr).Pad0(-2));
1803
+ Print(StdErr, " %1", FmtHex(*ptr, 2));
1819
1804
  }
1820
1805
  PrintLn(StdErr);
1821
1806
  }
@@ -1,32 +1,14 @@
1
- // Copyright (C) 2025 Niels Martignène <niels.martignene@protonmail.com>
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
  #pragma once
23
5
 
24
- #include "src/core/base/base.hh"
6
+ #include "lib/native/base/base.hh"
25
7
  #include "ffi.hh"
26
8
 
27
9
  #include <napi.h>
28
10
 
29
- namespace RG {
11
+ namespace K {
30
12
 
31
13
  extern const napi_type_tag TypeInfoMarker;
32
14
  extern const napi_type_tag CastMarker;
@@ -94,7 +76,7 @@ TypeInfo *MakePointerType(InstanceData *instance, const TypeInfo *ref, int count
94
76
  TypeInfo *MakeArrayType(InstanceData *instance, const TypeInfo *ref, Size len);
95
77
  TypeInfo *MakeArrayType(InstanceData *instance, const TypeInfo *ref, Size len, ArrayHint hint);
96
78
 
97
- Napi::External<TypeInfo> WrapType(Napi::Env env, InstanceData *instance, const TypeInfo *type);
79
+ Napi::External<TypeInfo> WrapType(Napi::Env env, const TypeInfo *type);
98
80
 
99
81
  bool CanPassType(const TypeInfo *type, int directions);
100
82
  bool CanReturnType(const TypeInfo *type);
@@ -103,8 +85,8 @@ bool CanStoreType(const TypeInfo *type);
103
85
  // Can be slow, only use for error messages
104
86
  const char *GetValueType(const InstanceData *instance, Napi::Value value);
105
87
 
106
- void SetValueTag(const InstanceData *instance, Napi::Value value, const void *marker);
107
- bool CheckValueTag(const InstanceData *instance, Napi::Value value, const void *marker);
88
+ void SetValueTag(Napi::Value value, const void *marker);
89
+ bool CheckValueTag(Napi::Value value, const void *marker);
108
90
 
109
91
  static inline bool IsNullOrUndefined(Napi::Value value)
110
92
  {
@@ -151,7 +133,7 @@ static inline Span<uint8_t> GetRawBuffer(Napi::Value value)
151
133
  return MakeSpan((uint8_t *)buffer.Data(), (Size)buffer.ByteLength());
152
134
  }
153
135
 
154
- RG_UNREACHABLE();
136
+ K_UNREACHABLE();
155
137
  }
156
138
 
157
139
  int GetTypedArrayType(const TypeInfo *type);
@@ -159,7 +141,7 @@ int GetTypedArrayType(const TypeInfo *type);
159
141
  template <typename T>
160
142
  T GetNumber(Napi::Value value)
161
143
  {
162
- RG_ASSERT(value.IsNumber() || value.IsBigInt());
144
+ K_ASSERT(value.IsNumber() || value.IsBigInt());
163
145
 
164
146
  if (value.IsNumber()) [[likely]] {
165
147
  return (T)value.As<Napi::Number>().DoubleValue();
@@ -170,7 +152,7 @@ T GetNumber(Napi::Value value)
170
152
  return (T)bigint.Uint64Value(&lossless);
171
153
  }
172
154
 
173
- RG_UNREACHABLE();
155
+ K_UNREACHABLE();
174
156
  }
175
157
 
176
158
  template <typename T>
@@ -237,7 +219,7 @@ static inline Napi::Array GetOwnPropertyNames(Napi::Object obj)
237
219
  napi_status status = napi_get_all_property_names(env, obj, napi_key_own_only,
238
220
  (napi_key_filter)(napi_key_enumerable | napi_key_skip_symbols),
239
221
  napi_key_numbers_to_strings, &result);
240
- RG_ASSERT(status == napi_ok);
222
+ K_ASSERT(status == napi_ok);
241
223
 
242
224
  return Napi::Array(env, result);
243
225
  }