koffi 2.14.1 → 2.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- 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 +5 -3
- package/doc/pages/misc.md +18 -11
- package/doc/pages.ini +4 -0
- package/doc/static/highlight.js +2 -14
- package/doc/static/koffi.css +3 -15
- package/doc/static/print.css +2 -14
- package/doc/templates/code.html +1 -2
- package/doc/templates/page.html +1 -2
- package/index.d.ts +29 -24
- package/index.js +9 -9
- package/indirect.js +9 -9
- package/{src/core → lib/native}/base/base.cc +1137 -674
- package/{src/core → lib/native}/base/base.hh +362 -195
- package/{src/core → lib/native}/base/crc.inc +2 -20
- 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 +2 -20
- package/{src/core → lib/native}/base/unicode_gen.py +4 -41
- package/package.json +2 -2
- package/src/cnoke/assets/FindCNoke.cmake +24 -30
- package/src/cnoke/assets/win_delay_hook.c +6 -20
- package/src/cnoke/cnoke.js +2 -21
- package/src/cnoke/src/builder.js +51 -66
- package/src/cnoke/src/index.js +2 -20
- package/src/cnoke/src/tools.js +2 -20
- package/src/koffi/CMakeLists.txt +30 -23
- package/src/koffi/cmake/raylib.cmake +5 -22
- package/src/koffi/cmake/sqlite3.cmake +2 -20
- package/src/koffi/src/abi_arm32.cc +7 -25
- package/src/koffi/src/abi_arm32_asm.S +2 -20
- package/src/koffi/src/abi_arm64.cc +7 -25
- 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 +7 -25
- package/src/koffi/src/abi_riscv64_asm.S +2 -20
- package/src/koffi/src/abi_x64_sysv.cc +7 -25
- package/src/koffi/src/abi_x64_sysv_asm.S +2 -20
- package/src/koffi/src/abi_x64_win.cc +12 -30
- package/src/koffi/src/abi_x64_win_asm.S +162 -0
- package/src/koffi/src/abi_x64_win_asm.asm +2 -20
- package/src/koffi/src/abi_x86.cc +7 -25
- 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 +25 -45
- package/src/koffi/src/call.hh +3 -21
- package/src/koffi/src/errno.inc +2 -20
- package/src/koffi/src/ffi.cc +64 -63
- package/src/koffi/src/ffi.hh +15 -30
- package/src/koffi/src/init.js +2 -20
- package/src/koffi/src/parser.cc +13 -27
- package/src/koffi/src/parser.hh +3 -21
- 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 +0 -21
- package/src/koffi/src/util.cc +50 -64
- package/src/koffi/src/util.hh +8 -25
- 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 +2 -20
- package/src/koffi/src/win32.hh +3 -21
- package/vendor/node-api-headers/CHANGELOG.md +22 -0
- package/vendor/node-api-headers/README.md +6 -17
- package/vendor/node-api-headers/include/js_native_api.h +3 -13
- package/vendor/node-api-headers/include/js_native_api_types.h +15 -0
- package/vendor/node-api-headers/include/node_api.h +0 -4
- package/vendor/node-api-headers/include/node_api_types.h +6 -0
- 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/vendor/node-api-headers/package.json +1 -1
- package/vendor/node-api-headers/scripts/update-headers.js +6 -0
- package/src/core/base/crc_gen.py +0 -109
|
@@ -1,24 +1,3 @@
|
|
|
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
1
|
public Trampoline0
|
|
23
2
|
public Trampoline1
|
|
24
3
|
public Trampoline2
|
|
@@ -1,24 +1,3 @@
|
|
|
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
1
|
extern "C" int Trampoline0; extern "C" int TrampolineX0;
|
|
23
2
|
extern "C" int Trampoline1; extern "C" int TrampolineX1;
|
|
24
3
|
extern "C" int Trampoline2; extern "C" int TrampolineX2;
|
package/src/koffi/src/util.cc
CHANGED
|
@@ -1,25 +1,7 @@
|
|
|
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"
|
|
@@ -38,7 +20,7 @@ Napi::Function MagicUnion::InitClass(Napi::Env env, const TypeInfo *type)
|
|
|
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++) {
|
|
@@ -61,7 +43,7 @@ MagicUnion::MagicUnion(const Napi::CallbackInfo &info)
|
|
|
61
43
|
Napi::Env env = info.Env();
|
|
62
44
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
63
45
|
|
|
64
|
-
active_symbol
|
|
46
|
+
active_symbol.Reset(instance->active_symbol.Value(), 1);
|
|
65
47
|
}
|
|
66
48
|
|
|
67
49
|
void MagicUnion::SetRaw(const uint8_t *ptr)
|
|
@@ -69,7 +51,7 @@ void MagicUnion::SetRaw(const uint8_t *ptr)
|
|
|
69
51
|
raw.RemoveFrom(0);
|
|
70
52
|
raw.Append(MakeSpan(ptr, type->size));
|
|
71
53
|
|
|
72
|
-
Value().Set(active_symbol, Env().Undefined());
|
|
54
|
+
Value().Set(active_symbol.Value(), Env().Undefined());
|
|
73
55
|
active_idx = -1;
|
|
74
56
|
}
|
|
75
57
|
|
|
@@ -81,7 +63,7 @@ Napi::Value MagicUnion::Getter(const Napi::CallbackInfo &info)
|
|
|
81
63
|
Napi::Value value;
|
|
82
64
|
|
|
83
65
|
if (idx == active_idx) {
|
|
84
|
-
value = Value().Get(active_symbol);
|
|
66
|
+
value = Value().Get(active_symbol.Value());
|
|
85
67
|
} else {
|
|
86
68
|
Napi::Env env = info.Env();
|
|
87
69
|
|
|
@@ -92,7 +74,7 @@ Napi::Value MagicUnion::Getter(const Napi::CallbackInfo &info)
|
|
|
92
74
|
|
|
93
75
|
value = Decode(env, raw.ptr, member.type);
|
|
94
76
|
|
|
95
|
-
Value().Set(active_symbol, value);
|
|
77
|
+
Value().Set(active_symbol.Value(), value);
|
|
96
78
|
active_idx = idx;
|
|
97
79
|
}
|
|
98
80
|
|
|
@@ -104,7 +86,7 @@ void MagicUnion::Setter(const Napi::CallbackInfo &info, const Napi::Value &value
|
|
|
104
86
|
{
|
|
105
87
|
Size idx = (Size)info.Data();
|
|
106
88
|
|
|
107
|
-
Value().Set(active_symbol, value);
|
|
89
|
+
Value().Set(active_symbol.Value(), value);
|
|
108
90
|
active_idx = idx;
|
|
109
91
|
|
|
110
92
|
raw.Clear();
|
|
@@ -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,7 +180,7 @@ 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
|
|
|
@@ -399,7 +381,7 @@ TypeInfo *MakePointerType(InstanceData *instance, const TypeInfo *ref, int count
|
|
|
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();
|
|
@@ -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
|
|
|
@@ -567,6 +549,7 @@ const char *GetValueType(const InstanceData *instance, Napi::Value value)
|
|
|
567
549
|
case napi_uint16_array: return "Uint16Array";
|
|
568
550
|
case napi_int32_array: return "Int32Array";
|
|
569
551
|
case napi_uint32_array: return "Uint32Array";
|
|
552
|
+
case napi_float16_array: return "Float16Array";
|
|
570
553
|
case napi_float32_array: return "Float32Array";
|
|
571
554
|
case napi_float64_array: return "Float64Array";
|
|
572
555
|
case napi_bigint64_array: return "BigInt64Array";
|
|
@@ -595,7 +578,7 @@ const char *GetValueType(const InstanceData *instance, Napi::Value value)
|
|
|
595
578
|
return "Unknown";
|
|
596
579
|
}
|
|
597
580
|
|
|
598
|
-
void SetValueTag(
|
|
581
|
+
void SetValueTag(Napi::Value value, const void *marker)
|
|
599
582
|
{
|
|
600
583
|
static_assert(K_SIZE(TypeInfo) >= 16);
|
|
601
584
|
|
|
@@ -614,7 +597,7 @@ void SetValueTag(const InstanceData *instance, Napi::Value value, const void *ma
|
|
|
614
597
|
K_ASSERT(status == napi_ok);
|
|
615
598
|
}
|
|
616
599
|
|
|
617
|
-
bool CheckValueTag(
|
|
600
|
+
bool CheckValueTag(Napi::Value value, const void *marker)
|
|
618
601
|
{
|
|
619
602
|
bool match = false;
|
|
620
603
|
|
|
@@ -646,25 +629,27 @@ int GetTypedArrayType(const TypeInfo *type)
|
|
|
646
629
|
|
|
647
630
|
Napi::String MakeStringFromUTF32(Napi::Env env, const char32_t *ptr, Size len)
|
|
648
631
|
{
|
|
632
|
+
static const char16_t ReplacementChar = 0xFFFD;
|
|
633
|
+
|
|
649
634
|
HeapArray<char16_t> buf;
|
|
650
635
|
buf.Reserve(len * 2);
|
|
651
636
|
|
|
652
637
|
for (Size i = 0; i < len; i++) {
|
|
653
638
|
char32_t uc = ptr[i];
|
|
654
639
|
|
|
655
|
-
if (uc
|
|
640
|
+
if (uc <= 0xFFFF) {
|
|
656
641
|
if (uc < 0xD800 || uc > 0xDFFF) {
|
|
657
642
|
buf.Append((char16_t)uc);
|
|
658
643
|
} else {
|
|
659
|
-
buf.Append(
|
|
644
|
+
buf.Append(ReplacementChar);
|
|
660
645
|
}
|
|
661
|
-
} else if (uc
|
|
646
|
+
} else if (uc <= 0x10FFFF) {
|
|
662
647
|
uc -= 0x0010000UL;
|
|
663
648
|
|
|
664
649
|
buf.Append((char16_t)((uc >> 10) + 0xD800));
|
|
665
650
|
buf.Append((char16_t)((uc & 0x3FFul) + 0xDC00));
|
|
666
651
|
} else {
|
|
667
|
-
buf.Append(
|
|
652
|
+
buf.Append(ReplacementChar);
|
|
668
653
|
}
|
|
669
654
|
}
|
|
670
655
|
|
|
@@ -676,10 +661,8 @@ Napi::Object DecodeObject(Napi::Env env, const uint8_t *origin, const TypeInfo *
|
|
|
676
661
|
{
|
|
677
662
|
// We can't decode unions because we don't know which member is valid
|
|
678
663
|
if (type->primitive == PrimitiveKind::Union) {
|
|
679
|
-
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
680
|
-
|
|
681
664
|
Napi::Object wrapper = type->construct.New({}).As<Napi::Object>();
|
|
682
|
-
SetValueTag(
|
|
665
|
+
SetValueTag(wrapper, &MagicUnionMarker);
|
|
683
666
|
|
|
684
667
|
MagicUnion *u = MagicUnion::Unwrap(wrapper);
|
|
685
668
|
u->SetRaw(origin);
|
|
@@ -775,7 +758,6 @@ static uint32_t DecodeDynamicLength(const uint8_t *origin, const RecordMember &b
|
|
|
775
758
|
void DecodeObject(Napi::Object obj, const uint8_t *origin, const TypeInfo *type)
|
|
776
759
|
{
|
|
777
760
|
Napi::Env env = obj.Env();
|
|
778
|
-
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
779
761
|
|
|
780
762
|
K_ASSERT(type->primitive == PrimitiveKind::Record);
|
|
781
763
|
|
|
@@ -887,7 +869,7 @@ void DecodeObject(Napi::Object obj, const uint8_t *origin, const TypeInfo *type)
|
|
|
887
869
|
obj.Set(member.name, value);
|
|
888
870
|
} else if (ptr2) {
|
|
889
871
|
Napi::External<void> external = Napi::External<void>::New(env, ptr2);
|
|
890
|
-
SetValueTag(
|
|
872
|
+
SetValueTag(external, member.type->ref.marker);
|
|
891
873
|
|
|
892
874
|
obj.Set(member.name, external);
|
|
893
875
|
} else {
|
|
@@ -936,7 +918,6 @@ void DecodeObject(Napi::Object obj, const uint8_t *origin, const TypeInfo *type)
|
|
|
936
918
|
|
|
937
919
|
Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *type, uint32_t len)
|
|
938
920
|
{
|
|
939
|
-
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
940
921
|
Size offset = 0;
|
|
941
922
|
|
|
942
923
|
#define POP_ARRAY(SetCode) \
|
|
@@ -1087,7 +1068,7 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
|
|
|
1087
1068
|
|
|
1088
1069
|
if (ptr2) {
|
|
1089
1070
|
Napi::External<void> external = Napi::External<void>::New(env, ptr2);
|
|
1090
|
-
SetValueTag(
|
|
1071
|
+
SetValueTag(external, type->ref.type->ref.marker);
|
|
1091
1072
|
|
|
1092
1073
|
array.Set(i, external);
|
|
1093
1074
|
} else {
|
|
@@ -1132,7 +1113,6 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
|
|
|
1132
1113
|
void DecodeNormalArray(Napi::Array array, const uint8_t *origin, const TypeInfo *ref)
|
|
1133
1114
|
{
|
|
1134
1115
|
Napi::Env env = array.Env();
|
|
1135
|
-
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
1136
1116
|
|
|
1137
1117
|
K_ASSERT(array.IsArray());
|
|
1138
1118
|
|
|
@@ -1247,7 +1227,7 @@ void DecodeNormalArray(Napi::Array array, const uint8_t *origin, const TypeInfo
|
|
|
1247
1227
|
|
|
1248
1228
|
if (ptr2) {
|
|
1249
1229
|
Napi::External<void> external = Napi::External<void>::New(env, ptr2);
|
|
1250
|
-
SetValueTag(
|
|
1230
|
+
SetValueTag(external, ref->ref.marker);
|
|
1251
1231
|
|
|
1252
1232
|
array.Set(i, external);
|
|
1253
1233
|
} else {
|
|
@@ -1322,6 +1302,10 @@ Napi::Value Decode(Napi::Value value, Size offset, const TypeInfo *type, const S
|
|
|
1322
1302
|
} else if (IsRawBuffer(value)) {
|
|
1323
1303
|
Span<uint8_t> buffer = GetRawBuffer(value);
|
|
1324
1304
|
|
|
1305
|
+
if (offset < 0) [[unlikely]] {
|
|
1306
|
+
ThrowError<Napi::Error>(env, "Offset must be >= 0");
|
|
1307
|
+
return env.Null();
|
|
1308
|
+
}
|
|
1325
1309
|
if (buffer.len - offset < type->size) [[unlikely]] {
|
|
1326
1310
|
ThrowError<Napi::Error>(env, "Expected buffer with size superior or equal to type %1 (%2 bytes)",
|
|
1327
1311
|
type->name, type->size + offset);
|
|
@@ -1354,12 +1338,12 @@ Napi::Value Decode(Napi::Env env, const uint8_t *ptr, const TypeInfo *type, cons
|
|
|
1354
1338
|
type = MakeArrayType(instance, type, *len);
|
|
1355
1339
|
} else {
|
|
1356
1340
|
switch (type->primitive) {
|
|
1357
|
-
case PrimitiveKind::Int8:
|
|
1341
|
+
case PrimitiveKind::Int8:
|
|
1358
1342
|
case PrimitiveKind::UInt8: {
|
|
1359
1343
|
Size count = strlen((const char *)ptr);
|
|
1360
1344
|
type = MakeArrayType(instance, type, count);
|
|
1361
1345
|
} break;
|
|
1362
|
-
case PrimitiveKind::Int16:
|
|
1346
|
+
case PrimitiveKind::Int16:
|
|
1363
1347
|
case PrimitiveKind::UInt16: {
|
|
1364
1348
|
Size count = NullTerminatedLength((const char16_t *)ptr, K_SIZE_MAX);
|
|
1365
1349
|
type = MakeArrayType(instance, type, count);
|
|
@@ -1513,6 +1497,10 @@ bool Encode(Napi::Value ref, Size offset, Napi::Value value, const TypeInfo *typ
|
|
|
1513
1497
|
} else if (IsRawBuffer(ref)) {
|
|
1514
1498
|
Span<uint8_t> buffer = GetRawBuffer(ref);
|
|
1515
1499
|
|
|
1500
|
+
if (offset < 0) [[unlikely]] {
|
|
1501
|
+
ThrowError<Napi::Error>(env, "Offset must be >= 0");
|
|
1502
|
+
return env.Null();
|
|
1503
|
+
}
|
|
1516
1504
|
if (buffer.len - offset < type->size) [[unlikely]] {
|
|
1517
1505
|
ThrowError<Napi::Error>(env, "Expected buffer with size superior or equal to type %1 (%2 bytes)",
|
|
1518
1506
|
type->name, type->size + offset);
|
|
@@ -1521,7 +1509,7 @@ bool Encode(Napi::Value ref, Size offset, Napi::Value value, const TypeInfo *typ
|
|
|
1521
1509
|
|
|
1522
1510
|
ptr = (uint8_t *)buffer.ptr;
|
|
1523
1511
|
} else {
|
|
1524
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for reference, expected external or TypedArray", GetValueType(instance,
|
|
1512
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for reference, expected external or TypedArray", GetValueType(instance, ref));
|
|
1525
1513
|
return env.Null();
|
|
1526
1514
|
}
|
|
1527
1515
|
|
|
@@ -1676,7 +1664,7 @@ bool Encode(Napi::Env env, uint8_t *origin, Napi::Value value, const TypeInfo *t
|
|
|
1676
1664
|
if (value.IsFunction()) {
|
|
1677
1665
|
ThrowError<Napi::Error>(env, "Cannot encode non-registered callback");
|
|
1678
1666
|
return false;
|
|
1679
|
-
} else if (CheckValueTag(
|
|
1667
|
+
} else if (CheckValueTag(value, type->ref.marker)) {
|
|
1680
1668
|
ptr = value.As<Napi::External<void>>().Data();
|
|
1681
1669
|
} else if (IsNullOrUndefined(value)) {
|
|
1682
1670
|
ptr = nullptr;
|
|
@@ -1715,8 +1703,6 @@ bool Encode(Napi::Env env, uint8_t *origin, Napi::Value value, const TypeInfo *t
|
|
|
1715
1703
|
|
|
1716
1704
|
Napi::Function WrapFunction(Napi::Env env, const FunctionInfo *func)
|
|
1717
1705
|
{
|
|
1718
|
-
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
1719
|
-
|
|
1720
1706
|
Napi::Function wrapper;
|
|
1721
1707
|
if (func->variadic) {
|
|
1722
1708
|
Napi::Function::Callback call = TranslateVariadicCall;
|
|
@@ -1742,11 +1728,11 @@ Napi::Function WrapFunction(Napi::Env env, const FunctionInfo *func)
|
|
|
1742
1728
|
|
|
1743
1729
|
meta.Set("name", Napi::String::New(env, func->name));
|
|
1744
1730
|
meta.Set("arguments", arguments);
|
|
1745
|
-
meta.Set("result", WrapType(env,
|
|
1731
|
+
meta.Set("result", WrapType(env, func->ret.type));
|
|
1746
1732
|
|
|
1747
1733
|
for (Size i = 0; i < func->parameters.len; i++) {
|
|
1748
1734
|
const ParameterInfo ¶m = func->parameters[i];
|
|
1749
|
-
arguments.Set((uint32_t)i, WrapType(env,
|
|
1735
|
+
arguments.Set((uint32_t)i, WrapType(env, param.type));
|
|
1750
1736
|
}
|
|
1751
1737
|
|
|
1752
1738
|
wrapper.Set("info", meta);
|
|
@@ -1811,11 +1797,11 @@ void DumpMemory(const char *type, Span<const uint8_t> bytes)
|
|
|
1811
1797
|
PrintLn(StdErr, "%1 at 0x%2 (%3):", type, bytes.ptr, FmtMemSize(bytes.len));
|
|
1812
1798
|
|
|
1813
1799
|
for (const uint8_t *ptr = bytes.begin(); ptr < bytes.end();) {
|
|
1814
|
-
Print(StdErr, " [0x%1 %2 %3] ",
|
|
1815
|
-
|
|
1816
|
-
|
|
1800
|
+
Print(StdErr, " [0x%1 %2 %3] ", FmtInt((uintptr_t)ptr, 16),
|
|
1801
|
+
FmtInt((ptr - bytes.begin()) / sizeof(void *), 4, ' '),
|
|
1802
|
+
FmtInt(ptr - bytes.begin(), 4, ' '));
|
|
1817
1803
|
for (int i = 0; ptr < bytes.end() && i < (int)sizeof(void *); i++, ptr++) {
|
|
1818
|
-
Print(StdErr, " %1", FmtHex(*ptr
|
|
1804
|
+
Print(StdErr, " %1", FmtHex(*ptr, 2));
|
|
1819
1805
|
}
|
|
1820
1806
|
PrintLn(StdErr);
|
|
1821
1807
|
}
|
package/src/koffi/src/util.hh
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
|
#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>
|
|
@@ -35,7 +17,7 @@ extern const napi_type_tag MagicUnionMarker;
|
|
|
35
17
|
class MagicUnion: public Napi::ObjectWrap<MagicUnion> {
|
|
36
18
|
const TypeInfo *type;
|
|
37
19
|
|
|
38
|
-
|
|
20
|
+
Napi::Reference<Napi::Symbol> active_symbol;
|
|
39
21
|
Size active_idx = -1;
|
|
40
22
|
|
|
41
23
|
HeapArray<uint8_t> raw;
|
|
@@ -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
|
{
|
|
@@ -138,6 +120,7 @@ static inline Span<uint8_t> GetRawBuffer(Napi::Value value)
|
|
|
138
120
|
case napi_uint16_array: { length *= 2; } break;
|
|
139
121
|
case napi_int32_array: { length *= 4; } break;
|
|
140
122
|
case napi_uint32_array: { length *= 4; } break;
|
|
123
|
+
case napi_float16_array: { length *= 2; } break;
|
|
141
124
|
case napi_float32_array: { length *= 4; } break;
|
|
142
125
|
case napi_float64_array: { length *= 8; } break;
|
|
143
126
|
case napi_bigint64_array: { length *= 8; } break;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
#include "uv.hh"
|
|
4
|
+
#include "util.hh"
|
|
5
|
+
|
|
6
|
+
#include <uv.h>
|
|
7
|
+
|
|
8
|
+
namespace K {
|
|
9
|
+
|
|
10
|
+
Napi::Function PollHandle::Define(Napi::Env env)
|
|
11
|
+
{
|
|
12
|
+
return DefineClass(env, "PollHandle", {
|
|
13
|
+
InstanceMethod("start", &PollHandle::Start),
|
|
14
|
+
InstanceMethod("stop", &PollHandle::Stop),
|
|
15
|
+
InstanceMethod("close", &PollHandle::Close),
|
|
16
|
+
InstanceMethod("unref", &PollHandle::Unref),
|
|
17
|
+
InstanceMethod("ref", &PollHandle::Ref)
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
PollHandle::PollHandle(const Napi::CallbackInfo &info)
|
|
22
|
+
: Napi::ObjectWrap<PollHandle>(info), env(info.Env())
|
|
23
|
+
{
|
|
24
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
25
|
+
|
|
26
|
+
if (info.Length() < 1 || !info[0].IsNumber()) {
|
|
27
|
+
ThrowError<Napi::Error>(env, "Expected 1 argument, got %1", info.Length());
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (!info[0].IsNumber()) {
|
|
31
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for descriptor, expected number", GetValueType(instance, info[0]));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
int fd = info[0].As<Napi::Number>().Int32Value();
|
|
36
|
+
|
|
37
|
+
uv_loop_t *loop = nullptr;
|
|
38
|
+
if (napi_get_uv_event_loop(env, &loop) != napi_ok || !loop) {
|
|
39
|
+
ThrowError<Napi::Error>(env, "napi_get_uv_event_loop() failed");
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// We would store it inside the class, but the definition of uv_poll_t involves windows.h...
|
|
44
|
+
// and we won't want that on Windows. Heap allocation it is!
|
|
45
|
+
// Also, it may have to outlive the object, because uv_close() is asynchronous.
|
|
46
|
+
handle = new uv_poll_t();
|
|
47
|
+
|
|
48
|
+
if (int ret = uv_poll_init_socket(loop, handle, (uv_os_sock_t)fd); ret != 0) {
|
|
49
|
+
ThrowError<Napi::Error>(env, "Failed to init UV poll: %1", uv_strerror(ret));
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
handle->data = this;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
void PollHandle::Start(const Napi::CallbackInfo &info)
|
|
57
|
+
{
|
|
58
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
59
|
+
|
|
60
|
+
bool has_opts = (info.Length() >= 2 && info[0].IsObject());
|
|
61
|
+
|
|
62
|
+
if (info.Length() < 1u + has_opts) {
|
|
63
|
+
ThrowError<Napi::TypeError>(env, "Expected 1 to 2 arguments, got %1", info.Length());
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (!info[0u + has_opts].IsFunction()) {
|
|
67
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for callback, expected function", GetValueType(instance, info[0u + has_opts]));
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
int events = 0;
|
|
72
|
+
Napi::Function cb = info[0 + has_opts].As<Napi::Function>();
|
|
73
|
+
|
|
74
|
+
if (has_opts) {
|
|
75
|
+
Napi::Object opts = has_opts ? info[0].As<Napi::Object>() : Napi::Object::New(env);
|
|
76
|
+
|
|
77
|
+
events |= opts.Get("readable").ToBoolean() ? UV_READABLE : 0;
|
|
78
|
+
events |= opts.Get("writable").ToBoolean() ? UV_WRITABLE : 0;
|
|
79
|
+
events |= opts.Get("disconnect").ToBoolean() ? UV_DISCONNECT : 0;
|
|
80
|
+
} else {
|
|
81
|
+
events = UV_READABLE;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
callback.Reset(cb, 1);
|
|
85
|
+
|
|
86
|
+
if (int ret = uv_poll_start(handle, events, &PollHandle::OnPoll); ret != 0) {
|
|
87
|
+
callback.Reset();
|
|
88
|
+
ThrowError<Napi::Error>(env, "Failed to start UV poll: %1", uv_strerror(ret));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
void PollHandle::Stop(const Napi::CallbackInfo &)
|
|
93
|
+
{
|
|
94
|
+
uv_poll_stop(handle);
|
|
95
|
+
callback.Reset();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
void PollHandle::Close(const Napi::CallbackInfo &)
|
|
99
|
+
{
|
|
100
|
+
Close();
|
|
101
|
+
callback.Reset();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
void PollHandle::Ref(const Napi::CallbackInfo &)
|
|
105
|
+
{
|
|
106
|
+
uv_ref((uv_handle_t *)handle);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
void PollHandle::Unref(const Napi::CallbackInfo &)
|
|
110
|
+
{
|
|
111
|
+
uv_unref((uv_handle_t *)handle);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
void PollHandle::Close()
|
|
115
|
+
{
|
|
116
|
+
if (!handle)
|
|
117
|
+
return;
|
|
118
|
+
|
|
119
|
+
const auto release = [](uv_handle_t *ptr) {
|
|
120
|
+
uv_poll_t *handle = (uv_poll_t *)ptr;
|
|
121
|
+
delete handle;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
uv_poll_stop(handle);
|
|
125
|
+
uv_close((uv_handle_t *)handle, release);
|
|
126
|
+
|
|
127
|
+
handle = nullptr;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
void PollHandle::OnPoll(uv_poll_t *h, int status, int events)
|
|
131
|
+
{
|
|
132
|
+
PollHandle *poll = (PollHandle *)h->data;
|
|
133
|
+
|
|
134
|
+
if (poll->callback.IsEmpty()) [[unlikely]]
|
|
135
|
+
return;
|
|
136
|
+
|
|
137
|
+
Napi::Env env = poll->env;
|
|
138
|
+
Napi::HandleScope scope(env);
|
|
139
|
+
|
|
140
|
+
Napi::Object obj = Napi::Object::New(env);
|
|
141
|
+
|
|
142
|
+
obj.Set("readable", !!(events & UV_READABLE));
|
|
143
|
+
obj.Set("writable", !!(events & UV_WRITABLE));
|
|
144
|
+
obj.Set("disconnect", !!(events & UV_DISCONNECT));
|
|
145
|
+
|
|
146
|
+
napi_value args[] = { Napi::Number::New(env, status), obj };
|
|
147
|
+
poll->callback.Call(poll->Value(), K_LEN(args), args);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
Napi::Value Poll(const Napi::CallbackInfo &info)
|
|
151
|
+
{
|
|
152
|
+
Napi::Env env = info.Env();
|
|
153
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
154
|
+
|
|
155
|
+
bool has_opts = (info.Length() >= 3 && info[1].IsObject());
|
|
156
|
+
|
|
157
|
+
if (info.Length() < 2u + has_opts) {
|
|
158
|
+
ThrowError<Napi::TypeError>(env, "Expected 2 to 3 arguments, got %1", info.Length());
|
|
159
|
+
return env.Null();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (!info[0].IsNumber()) {
|
|
163
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for descriptor, expected number", GetValueType(instance, info[0]));
|
|
164
|
+
return env.Null();
|
|
165
|
+
}
|
|
166
|
+
if (!info[1 + has_opts].IsFunction()) {
|
|
167
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for callback, expected function", GetValueType(instance, info[1 + has_opts]));
|
|
168
|
+
return env.Null();
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
int fd = info[0].As<Napi::Number>().Int32Value();
|
|
172
|
+
|
|
173
|
+
Napi::Function ctor = PollHandle::Define(env);
|
|
174
|
+
Napi::Object inst = ctor.New({ Napi::Number::New(env, fd) });
|
|
175
|
+
Napi::Function start = inst.Get("start").As<Napi::Function>();
|
|
176
|
+
|
|
177
|
+
if (env.IsExceptionPending()) [[unlikely]]
|
|
178
|
+
return env.Null();
|
|
179
|
+
|
|
180
|
+
if (has_opts) {
|
|
181
|
+
Napi::Value opts = info[1];
|
|
182
|
+
Napi::Function cb = info[2].As<Napi::Function>();
|
|
183
|
+
|
|
184
|
+
start.Call(inst, { opts, cb });
|
|
185
|
+
} else {
|
|
186
|
+
Napi::Function cb = info[1].As<Napi::Function>();
|
|
187
|
+
start.Call(inst, { cb });
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return inst;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
}
|