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
package/src/koffi/src/util.cc
CHANGED
|
@@ -1,32 +1,14 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
|
|
4
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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(
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
358
|
+
K_ASSERT(type);
|
|
377
359
|
} else {
|
|
378
|
-
|
|
360
|
+
K_ASSERT(!len);
|
|
379
361
|
|
|
380
362
|
type = MakePointerType(instance, type);
|
|
381
|
-
|
|
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
|
-
|
|
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.
|
|
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 =
|
|
412
|
-
type->align =
|
|
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 =
|
|
418
|
-
type->align =
|
|
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
|
-
|
|
435
|
-
|
|
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.
|
|
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,
|
|
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(
|
|
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(
|
|
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(
|
|
532
|
+
if (CheckValueTag(value, &TypeInfoMarker))
|
|
551
533
|
return "Type";
|
|
552
534
|
for (const TypeInfo &type: instance->types) {
|
|
553
|
-
if (type.ref.marker && CheckValueTag(
|
|
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(
|
|
580
|
+
void SetValueTag(Napi::Value value, const void *marker)
|
|
599
581
|
{
|
|
600
|
-
static_assert(
|
|
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
|
-
|
|
596
|
+
K_ASSERT(status == napi_ok);
|
|
615
597
|
}
|
|
616
598
|
|
|
617
|
-
bool CheckValueTag(
|
|
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
|
-
|
|
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
|
|
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
|
|
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(
|
|
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: {
|
|
751
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
770
752
|
}
|
|
771
753
|
|
|
772
|
-
|
|
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
|
-
|
|
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: {
|
|
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(
|
|
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: {
|
|
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 *
|
|
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 *
|
|
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: {
|
|
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(
|
|
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: {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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: {
|
|
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(
|
|
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: {
|
|
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 /
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
1474
|
-
|
|
1456
|
+
K_ASSERT(!proto->variadic);
|
|
1457
|
+
K_ASSERT(!proto->lib);
|
|
1475
1458
|
|
|
1476
1459
|
FunctionInfo *func = new FunctionInfo();
|
|
1477
|
-
|
|
1460
|
+
K_DEFER { func->Unref(); };
|
|
1478
1461
|
|
|
1479
|
-
memcpy((void *)func, proto,
|
|
1480
|
-
memset((void *)&func->parameters, 0,
|
|
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,
|
|
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: {
|
|
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(
|
|
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: {
|
|
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,
|
|
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 ¶m = func->parameters[i];
|
|
1749
|
-
arguments.Set((uint32_t)i, WrapType(env,
|
|
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] ",
|
|
1815
|
-
|
|
1816
|
-
|
|
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
|
|
1803
|
+
Print(StdErr, " %1", FmtHex(*ptr, 2));
|
|
1819
1804
|
}
|
|
1820
1805
|
PrintLn(StdErr);
|
|
1821
1806
|
}
|
package/src/koffi/src/util.hh
CHANGED
|
@@ -1,32 +1,14 @@
|
|
|
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
|
#pragma once
|
|
23
5
|
|
|
24
|
-
#include "
|
|
6
|
+
#include "lib/native/base/base.hh"
|
|
25
7
|
#include "ffi.hh"
|
|
26
8
|
|
|
27
9
|
#include <napi.h>
|
|
28
10
|
|
|
29
|
-
namespace
|
|
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,
|
|
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(
|
|
107
|
-
bool CheckValueTag(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
222
|
+
K_ASSERT(status == napi_ok);
|
|
241
223
|
|
|
242
224
|
return Napi::Array(env, result);
|
|
243
225
|
}
|