koffi 3.0.1 → 3.1.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 +32 -3
- package/cnoke.cjs +2 -2
- package/doc/benchmarks.md +1 -1
- package/doc/callbacks.md +7 -26
- package/doc/{input.md → composites.md} +161 -147
- package/doc/contribute.md +3 -2
- package/doc/index.md +0 -14
- package/doc/{functions.md → load.md} +54 -113
- package/doc/migration.md +4 -7
- package/doc/misc.md +0 -103
- package/doc/output.md +5 -11
- package/doc/pointers.md +76 -17
- package/doc/primitives.md +151 -0
- package/doc/start.md +3 -13
- package/doc/types.md +88 -0
- package/doc/unions.md +0 -186
- package/doc/values.md +134 -0
- package/index.d.ts +375 -308
- package/lib/native/base/base.cc +66 -24
- package/lib/native/base/base.hh +55 -153
- package/package.json +16 -16
- package/src/koffi/CMakeLists.txt +20 -17
- package/src/koffi/index.cjs +30 -111
- package/src/koffi/index.js +22 -96
- package/src/koffi/indirect.cjs +30 -111
- package/src/koffi/indirect.js +24 -24
- package/src/koffi/src/abi/arm64.cc +48 -62
- package/src/koffi/src/abi/riscv64.cc +39 -57
- package/src/koffi/src/abi/x64sysv.cc +39 -57
- package/src/koffi/src/abi/x64win.cc +48 -65
- package/src/koffi/src/abi/x86.cc +47 -59
- package/src/koffi/src/call.cc +426 -209
- package/src/koffi/src/call.hh +7 -11
- package/src/koffi/src/ffi.cc +534 -303
- package/src/koffi/src/ffi.hh +71 -15
- package/src/koffi/src/parser.cc +5 -3
- package/src/koffi/src/parser.hh +2 -2
- package/src/koffi/src/static.cjs +122 -0
- package/src/koffi/src/static.js +125 -0
- package/src/koffi/src/type.cc +725 -0
- package/src/koffi/src/type.hh +71 -0
- package/src/koffi/src/util.cc +117 -1202
- package/src/koffi/src/util.hh +158 -156
- package/src/koffi/src/uv.cc +17 -11
- package/src/koffi/src/uv.hh +2 -1
- package/vendor/node-addon-api/README.md +1 -1
- package/vendor/node-addon-api/napi-inl.h +213 -35
- package/vendor/node-addon-api/napi.h +118 -7
- package/doc/variables.md +0 -102
- package/indirect.d.ts +0 -322
package/src/koffi/src/ffi.cc
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
#include "ffi.hh"
|
|
6
6
|
#include "call.hh"
|
|
7
7
|
#include "parser.hh"
|
|
8
|
+
#include "type.hh"
|
|
8
9
|
#include "util.hh"
|
|
9
10
|
#include "uv.hh"
|
|
10
11
|
#if defined(_WIN32)
|
|
@@ -35,23 +36,28 @@
|
|
|
35
36
|
|
|
36
37
|
namespace K {
|
|
37
38
|
|
|
39
|
+
// Value does not matter, the tag system uses memory addresses
|
|
40
|
+
const napi_type_tag LibraryHandleMarker = { 0xdb9b066e6f700474, 0x0aecd7e4c63fbda9 };
|
|
41
|
+
const napi_type_tag TypeObjectMarker = { 0x1cc449675b294374, 0xbb13a50e97dcb017 };
|
|
42
|
+
const napi_type_tag DirectionMarker = { 0xf9c306238b480580, 0xc2e168524a0823f5 };
|
|
43
|
+
const napi_type_tag UnionValueMarker = { 0x5eaf2245526a4c7d, 0x8c86c9ee2b96ffc8 };
|
|
44
|
+
const napi_type_tag CastMarker = { 0x77f459614a0a412f, 0x80b3dda1341dc8df };
|
|
45
|
+
|
|
38
46
|
SharedData shared;
|
|
39
47
|
|
|
40
48
|
// Some Node-API functions are loaded dynamically to work around bugs or because they are recent
|
|
49
|
+
napi_status (NAPI_CDECL *node_api_delete_reference)(node_api_basic_env env, napi_ref ref);
|
|
41
50
|
napi_status (NAPI_CDECL *node_api_get_buffer_info)(napi_env env, napi_value value, void **data, size_t *length);
|
|
42
51
|
napi_status (NAPI_CDECL *node_api_create_property_key_utf8)(napi_env env, const char* str, size_t length, napi_value* result);
|
|
43
52
|
napi_status (NAPI_CDECL *node_api_post_finalizer)(node_api_basic_env env, napi_finalize finalize_cb, void* finalize_data, void* finalize_hint);
|
|
44
53
|
napi_status (NAPI_CDECL *node_api_create_object_with_properties)(napi_env env, napi_value prototype_or_null, const napi_value *property_names,
|
|
45
54
|
const napi_value *property_values, size_t property_count, napi_value *result);
|
|
46
|
-
napi_value (*translate_zero_call)(napi_env env, napi_callback_info info);
|
|
47
55
|
|
|
48
|
-
static bool ChangeSize(const char *name, Napi::Value value, Size min_size, Size max_size, Size *out_size)
|
|
56
|
+
static bool ChangeSize(InstanceData *instance, const char *name, Napi::Value value, Size min_size, Size max_size, Size *out_size)
|
|
49
57
|
{
|
|
50
|
-
Napi::Env env =
|
|
58
|
+
Napi::Env env = instance->env;
|
|
51
59
|
|
|
52
60
|
if (!value.IsNumber()) {
|
|
53
|
-
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
54
|
-
|
|
55
61
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for '%2', expected number", GetValueType(instance, value), name);
|
|
56
62
|
return false;
|
|
57
63
|
}
|
|
@@ -67,21 +73,19 @@ static bool ChangeSize(const char *name, Napi::Value value, Size min_size, Size
|
|
|
67
73
|
return true;
|
|
68
74
|
}
|
|
69
75
|
|
|
70
|
-
static bool ChangeMemorySize(const char *name, Napi::Value value, Size *out_size)
|
|
76
|
+
static bool ChangeMemorySize(InstanceData *instance, const char *name, Napi::Value value, Size *out_size)
|
|
71
77
|
{
|
|
72
78
|
const Size MinSize = Kibibytes(1);
|
|
73
79
|
const Size MaxSize = Mebibytes(16);
|
|
74
80
|
|
|
75
|
-
return ChangeSize(name, value, MinSize, MaxSize, out_size);
|
|
81
|
+
return ChangeSize(instance, name, value, MinSize, MaxSize, out_size);
|
|
76
82
|
}
|
|
77
83
|
|
|
78
|
-
static bool ChangeAsyncLimit(const char *name, Napi::Value value, int max, int *out_limit)
|
|
84
|
+
static bool ChangeAsyncLimit(InstanceData *instance, const char *name, Napi::Value value, int max, int *out_limit)
|
|
79
85
|
{
|
|
80
86
|
Napi::Env env = value.Env();
|
|
81
87
|
|
|
82
88
|
if (!value.IsNumber()) {
|
|
83
|
-
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
84
|
-
|
|
85
89
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for '%2', expected number", GetValueType(instance, value), name);
|
|
86
90
|
return false;
|
|
87
91
|
}
|
|
@@ -100,7 +104,7 @@ static bool ChangeAsyncLimit(const char *name, Napi::Value value, int max, int *
|
|
|
100
104
|
static Napi::Value GetSetConfig(const Napi::CallbackInfo &info)
|
|
101
105
|
{
|
|
102
106
|
Napi::Env env = info.Env();
|
|
103
|
-
InstanceData *instance =
|
|
107
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
104
108
|
|
|
105
109
|
if (info.Length()) {
|
|
106
110
|
if (instance->memories.len) {
|
|
@@ -124,25 +128,25 @@ static Napi::Value GetSetConfig(const Napi::CallbackInfo &info)
|
|
|
124
128
|
Napi::Value value = obj[key];
|
|
125
129
|
|
|
126
130
|
if (key == "sync_stack_size") {
|
|
127
|
-
if (!ChangeMemorySize(key.c_str(), value, &new_config.sync_stack_size))
|
|
131
|
+
if (!ChangeMemorySize(instance, key.c_str(), value, &new_config.sync_stack_size))
|
|
128
132
|
return env.Null();
|
|
129
133
|
} else if (key == "sync_heap_size") {
|
|
130
|
-
if (!ChangeMemorySize(key.c_str(), value, &new_config.sync_heap_size))
|
|
134
|
+
if (!ChangeMemorySize(instance, key.c_str(), value, &new_config.sync_heap_size))
|
|
131
135
|
return env.Null();
|
|
132
136
|
} else if (key == "async_stack_size") {
|
|
133
|
-
if (!ChangeMemorySize(key.c_str(), value, &new_config.async_stack_size))
|
|
137
|
+
if (!ChangeMemorySize(instance, key.c_str(), value, &new_config.async_stack_size))
|
|
134
138
|
return env.Null();
|
|
135
139
|
} else if (key == "async_heap_size") {
|
|
136
|
-
if (!ChangeMemorySize(key.c_str(), value, &new_config.async_heap_size))
|
|
140
|
+
if (!ChangeMemorySize(instance, key.c_str(), value, &new_config.async_heap_size))
|
|
137
141
|
return env.Null();
|
|
138
142
|
} else if (key == "resident_async_pools") {
|
|
139
|
-
if (!ChangeAsyncLimit(key.c_str(), value, K_LEN(instance->memories.data) - 1, &new_config.resident_async_pools))
|
|
143
|
+
if (!ChangeAsyncLimit(instance, key.c_str(), value, K_LEN(instance->memories.data) - 1, &new_config.resident_async_pools))
|
|
140
144
|
return env.Null();
|
|
141
145
|
} else if (key == "max_async_calls") {
|
|
142
|
-
if (!ChangeAsyncLimit(key.c_str(), value, MaxAsyncCalls, &max_async_calls))
|
|
146
|
+
if (!ChangeAsyncLimit(instance, key.c_str(), value, MaxAsyncCalls, &max_async_calls))
|
|
143
147
|
return env.Null();
|
|
144
148
|
} else if (key == "max_type_size") {
|
|
145
|
-
if (!ChangeSize(key.c_str(), value, 32, Mebibytes(512), &new_config.max_type_size))
|
|
149
|
+
if (!ChangeSize(instance, key.c_str(), value, 32, Mebibytes(512), &new_config.max_type_size))
|
|
146
150
|
return env.Null();
|
|
147
151
|
} else {
|
|
148
152
|
ThrowError<Napi::Error>(env, "Unexpected config member '%1'", key.c_str());
|
|
@@ -175,7 +179,7 @@ static Napi::Value GetSetConfig(const Napi::CallbackInfo &info)
|
|
|
175
179
|
static Napi::Value GetStats(const Napi::CallbackInfo &info)
|
|
176
180
|
{
|
|
177
181
|
Napi::Env env = info.Env();
|
|
178
|
-
InstanceData *instance =
|
|
182
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
179
183
|
|
|
180
184
|
Napi::Object obj = Napi::Object::New(env);
|
|
181
185
|
|
|
@@ -228,9 +232,9 @@ static bool FinalizeCompositeType(Napi::Env env, TypeInfo *type, PrimitiveKind p
|
|
|
228
232
|
if (node_api_create_property_key_utf8) {
|
|
229
233
|
for (RecordMember &member: type->members) {
|
|
230
234
|
napi_value key = nullptr;
|
|
231
|
-
node_api_create_property_key_utf8(env, member.name, NAPI_AUTO_LENGTH, &key);
|
|
232
235
|
|
|
233
|
-
|
|
236
|
+
NAPI_OK(node_api_create_property_key_utf8(env, member.name, NAPI_AUTO_LENGTH, &key));
|
|
237
|
+
NAPI_OK(napi_create_reference(env, key, 1, &member.key));
|
|
234
238
|
}
|
|
235
239
|
}
|
|
236
240
|
|
|
@@ -247,7 +251,7 @@ static bool FinalizeCompositeType(Napi::Env env, TypeInfo *type, PrimitiveKind p
|
|
|
247
251
|
static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
248
252
|
{
|
|
249
253
|
Napi::Env env = info.Env();
|
|
250
|
-
InstanceData *instance =
|
|
254
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
251
255
|
|
|
252
256
|
if (info.Length() < 1) {
|
|
253
257
|
ThrowError<Napi::TypeError>(env, "Expected 1 or 2 arguments, got %1", info.Length());
|
|
@@ -299,11 +303,12 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
|
299
303
|
replace = external.Data();
|
|
300
304
|
#else
|
|
301
305
|
TypeObject *defn = nullptr;
|
|
302
|
-
napi_unwrap(env, name, (void **)&defn);
|
|
306
|
+
NAPI_OK(napi_unwrap(env, name, (void **)&defn));
|
|
303
307
|
|
|
304
308
|
replace = (TypeInfo *)defn->GetType();
|
|
305
309
|
#endif
|
|
306
310
|
|
|
311
|
+
type->instance = instance;
|
|
307
312
|
type->name = replace->name;
|
|
308
313
|
|
|
309
314
|
if (replace->primitive != PrimitiveKind::Void || replace == instance->void_type) {
|
|
@@ -311,11 +316,13 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
|
311
316
|
return env.Null();
|
|
312
317
|
}
|
|
313
318
|
} else if (named) {
|
|
319
|
+
type->instance = instance;
|
|
314
320
|
type->name = DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr;
|
|
315
321
|
|
|
316
322
|
if (!MapType(env, instance, type, type->name))
|
|
317
323
|
return env.Null();
|
|
318
324
|
} else {
|
|
325
|
+
type->instance = instance;
|
|
319
326
|
type->name = Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.count).ptr;
|
|
320
327
|
}
|
|
321
328
|
|
|
@@ -353,7 +360,7 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
|
353
360
|
align = (int16_t)align64;
|
|
354
361
|
}
|
|
355
362
|
|
|
356
|
-
member.type = ResolveType(value);
|
|
363
|
+
member.type = ResolveType(instance, value);
|
|
357
364
|
if (!member.type)
|
|
358
365
|
return env.Null();
|
|
359
366
|
if (!CanStoreType(member.type)) {
|
|
@@ -425,11 +432,12 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
|
425
432
|
err_guard.Disable();
|
|
426
433
|
|
|
427
434
|
if (replace) {
|
|
428
|
-
std::
|
|
435
|
+
*replace = std::move(*type);
|
|
429
436
|
type = replace;
|
|
430
437
|
}
|
|
431
438
|
|
|
432
|
-
|
|
439
|
+
napi_value wrapper = WrapType(instance, type);
|
|
440
|
+
return Napi::Value(env, wrapper);
|
|
433
441
|
}
|
|
434
442
|
|
|
435
443
|
static Napi::Value CreatePaddedStructType(const Napi::CallbackInfo &info)
|
|
@@ -445,7 +453,7 @@ static Napi::Value CreatePackedStructType(const Napi::CallbackInfo &info)
|
|
|
445
453
|
static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
|
|
446
454
|
{
|
|
447
455
|
Napi::Env env = info.Env();
|
|
448
|
-
InstanceData *instance =
|
|
456
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
449
457
|
|
|
450
458
|
if (info.Length() < 1) {
|
|
451
459
|
ThrowError<Napi::TypeError>(env, "Expected 1 or 2 arguments, got %1", info.Length());
|
|
@@ -497,11 +505,12 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
|
|
|
497
505
|
replace = external.Data();
|
|
498
506
|
#else
|
|
499
507
|
TypeObject *defn = nullptr;
|
|
500
|
-
napi_unwrap(env, name, (void **)&defn);
|
|
508
|
+
NAPI_OK(napi_unwrap(env, name, (void **)&defn));
|
|
501
509
|
|
|
502
510
|
replace = (TypeInfo *)defn->GetType();
|
|
503
511
|
#endif
|
|
504
512
|
|
|
513
|
+
type->instance = instance;
|
|
505
514
|
type->name = replace->name;
|
|
506
515
|
|
|
507
516
|
if (replace->primitive != PrimitiveKind::Void || replace == instance->void_type) {
|
|
@@ -509,11 +518,13 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
|
|
|
509
518
|
return env.Null();
|
|
510
519
|
}
|
|
511
520
|
} else if (named) {
|
|
521
|
+
type->instance = instance;
|
|
512
522
|
type->name = DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr;
|
|
513
523
|
|
|
514
524
|
if (!MapType(env, instance, type, type->name))
|
|
515
525
|
return env.Null();
|
|
516
526
|
} else {
|
|
527
|
+
type->instance = instance;
|
|
517
528
|
type->name = Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.count).ptr;
|
|
518
529
|
}
|
|
519
530
|
|
|
@@ -551,7 +562,7 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
|
|
|
551
562
|
align = (int16_t)align64;
|
|
552
563
|
}
|
|
553
564
|
|
|
554
|
-
member.type = ResolveType(value);
|
|
565
|
+
member.type = ResolveType(instance, value);
|
|
555
566
|
if (!member.type)
|
|
556
567
|
return env.Null();
|
|
557
568
|
if (!CanStoreType(member.type)) {
|
|
@@ -592,19 +603,22 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
|
|
|
592
603
|
return env.Null();
|
|
593
604
|
err_guard.Disable();
|
|
594
605
|
|
|
595
|
-
|
|
606
|
+
Napi::Object construct = UnionValue::InitClass(instance, type);
|
|
607
|
+
NAPI_OK(napi_create_reference(env, construct, 1, &type->construct));
|
|
596
608
|
|
|
597
609
|
if (replace) {
|
|
598
|
-
std::
|
|
610
|
+
*replace = std::move(*type);
|
|
599
611
|
type = replace;
|
|
600
612
|
}
|
|
601
613
|
|
|
602
|
-
|
|
614
|
+
napi_value wrapper = WrapType(instance, type);
|
|
615
|
+
return Napi::Value(env, wrapper);
|
|
603
616
|
}
|
|
604
617
|
|
|
605
618
|
Napi::Value InstantiateUnion(const Napi::CallbackInfo &info)
|
|
606
619
|
{
|
|
607
620
|
Napi::Env env = info.Env();
|
|
621
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
608
622
|
|
|
609
623
|
if (!info.IsConstructCall()) {
|
|
610
624
|
ThrowError<Napi::TypeError>(env, "This function is a constructor and must be called with new");
|
|
@@ -615,7 +629,7 @@ Napi::Value InstantiateUnion(const Napi::CallbackInfo &info)
|
|
|
615
629
|
return env.Null();
|
|
616
630
|
}
|
|
617
631
|
|
|
618
|
-
const TypeInfo *type = ResolveType(info[0]);
|
|
632
|
+
const TypeInfo *type = ResolveType(instance, info[0]);
|
|
619
633
|
if (!type)
|
|
620
634
|
return env.Null();
|
|
621
635
|
if (type->primitive != PrimitiveKind::Union) {
|
|
@@ -623,7 +637,15 @@ Napi::Value InstantiateUnion(const Napi::CallbackInfo &info)
|
|
|
623
637
|
return env.Null();
|
|
624
638
|
}
|
|
625
639
|
|
|
626
|
-
Napi::
|
|
640
|
+
Napi::Function construct;
|
|
641
|
+
{
|
|
642
|
+
napi_value value;
|
|
643
|
+
NAPI_OK(napi_get_reference_value(env, type->construct, &value));
|
|
644
|
+
|
|
645
|
+
construct = Napi::Function(env, value);
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
Napi::Object wrapper = construct.New({}).As<Napi::Object>();
|
|
627
649
|
SetValueTag(env, wrapper, &UnionValueMarker);
|
|
628
650
|
|
|
629
651
|
return wrapper;
|
|
@@ -632,7 +654,7 @@ Napi::Value InstantiateUnion(const Napi::CallbackInfo &info)
|
|
|
632
654
|
static Napi::Value CreateOpaqueType(const Napi::CallbackInfo &info)
|
|
633
655
|
{
|
|
634
656
|
Napi::Env env = info.Env();
|
|
635
|
-
InstanceData *instance =
|
|
657
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
636
658
|
|
|
637
659
|
bool named = (info.Length() >= 1) && !IsNullOrUndefined(env, info[0]);
|
|
638
660
|
|
|
@@ -646,6 +668,7 @@ static Napi::Value CreateOpaqueType(const Napi::CallbackInfo &info)
|
|
|
646
668
|
TypeInfo *type = instance->types.AppendDefault();
|
|
647
669
|
K_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
|
|
648
670
|
|
|
671
|
+
type->instance = instance;
|
|
649
672
|
type->name = named ? DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr
|
|
650
673
|
: Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.count).ptr;
|
|
651
674
|
|
|
@@ -658,13 +681,14 @@ static Napi::Value CreateOpaqueType(const Napi::CallbackInfo &info)
|
|
|
658
681
|
return env.Null();
|
|
659
682
|
err_guard.Disable();
|
|
660
683
|
|
|
661
|
-
|
|
684
|
+
napi_value wrapper = WrapType(instance, type);
|
|
685
|
+
return Napi::Value(env, wrapper);
|
|
662
686
|
}
|
|
663
687
|
|
|
664
688
|
static Napi::Value CreatePointerType(const Napi::CallbackInfo &info)
|
|
665
689
|
{
|
|
666
690
|
Napi::Env env = info.Env();
|
|
667
|
-
InstanceData *instance =
|
|
691
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
668
692
|
|
|
669
693
|
if (info.Length() < 1) {
|
|
670
694
|
ThrowError<Napi::TypeError>(env, "Expected 1 to 3 arguments, got %1", info.Length());
|
|
@@ -681,7 +705,7 @@ static Napi::Value CreatePointerType(const Napi::CallbackInfo &info)
|
|
|
681
705
|
|
|
682
706
|
std::string name = named ? info[0].As<Napi::String>() : std::string();
|
|
683
707
|
|
|
684
|
-
const TypeInfo *ref = ResolveType(info[skip]);
|
|
708
|
+
const TypeInfo *ref = ResolveType(instance, info[skip]);
|
|
685
709
|
if (!ref)
|
|
686
710
|
return env.Null();
|
|
687
711
|
|
|
@@ -713,7 +737,7 @@ static Napi::Value CreatePointerType(const Napi::CallbackInfo &info)
|
|
|
713
737
|
|
|
714
738
|
memcpy((void *)copy, type, K_SIZE(*type));
|
|
715
739
|
copy->name = named ? DuplicateString(name.c_str(), &instance->str_alloc).ptr : copy->name;
|
|
716
|
-
|
|
740
|
+
copy->defn = nullptr;
|
|
717
741
|
|
|
718
742
|
static_assert(!std::is_polymorphic_v<Napi::ObjectReference>);
|
|
719
743
|
|
|
@@ -730,7 +754,8 @@ static Napi::Value CreatePointerType(const Napi::CallbackInfo &info)
|
|
|
730
754
|
type = copy;
|
|
731
755
|
}
|
|
732
756
|
|
|
733
|
-
|
|
757
|
+
napi_value wrapper = WrapType(instance, type);
|
|
758
|
+
return Napi::Value(env, wrapper);
|
|
734
759
|
}
|
|
735
760
|
|
|
736
761
|
static Napi::Value EncodePointerDirection(const Napi::CallbackInfo &info, int directions)
|
|
@@ -738,13 +763,14 @@ static Napi::Value EncodePointerDirection(const Napi::CallbackInfo &info, int di
|
|
|
738
763
|
K_ASSERT(directions >= 1 && directions <= 3);
|
|
739
764
|
|
|
740
765
|
Napi::Env env = info.Env();
|
|
766
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
741
767
|
|
|
742
768
|
if (info.Length() < 1) {
|
|
743
769
|
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
|
|
744
770
|
return env.Null();
|
|
745
771
|
}
|
|
746
772
|
|
|
747
|
-
const TypeInfo *type = ResolveType(info[0]);
|
|
773
|
+
const TypeInfo *type = ResolveType(instance, info[0]);
|
|
748
774
|
if (!type)
|
|
749
775
|
return env.Null();
|
|
750
776
|
|
|
@@ -783,7 +809,7 @@ static Napi::Value MarkInOut(const Napi::CallbackInfo &info)
|
|
|
783
809
|
static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
|
|
784
810
|
{
|
|
785
811
|
Napi::Env env = info.Env();
|
|
786
|
-
InstanceData *instance =
|
|
812
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
787
813
|
|
|
788
814
|
if (info.Length() < 1) {
|
|
789
815
|
ThrowError<Napi::TypeError>(env, "Expected 1 or 2 arguments, got %1", info.Length());
|
|
@@ -800,7 +826,7 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
|
|
|
800
826
|
|
|
801
827
|
Napi::String name = info[0].As<Napi::String>();
|
|
802
828
|
|
|
803
|
-
const TypeInfo *src = ResolveType(info[skip]);
|
|
829
|
+
const TypeInfo *src = ResolveType(instance, info[skip]);
|
|
804
830
|
if (!src)
|
|
805
831
|
return env.Null();
|
|
806
832
|
if (src->primitive != PrimitiveKind::Pointer &&
|
|
@@ -825,23 +851,21 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
|
|
|
825
851
|
return env.Null();
|
|
826
852
|
}
|
|
827
853
|
|
|
828
|
-
dispose = [](
|
|
829
|
-
|
|
830
|
-
const Napi::FunctionReference &ref = type->dispose_ref;
|
|
854
|
+
dispose = [](InstanceData *instance, const TypeInfo *type, const void *ptr) {
|
|
855
|
+
Napi::Env env = instance->env;
|
|
831
856
|
|
|
832
|
-
|
|
857
|
+
napi_value func;
|
|
858
|
+
NAPI_OK(napi_get_reference_value(env, type->dispose_ref, &func));
|
|
833
859
|
|
|
834
860
|
napi_value self = env.Null();
|
|
835
|
-
napi_value
|
|
861
|
+
napi_value wrapper = WrapPointer(env, type->ref.type, (void *)ptr);
|
|
836
862
|
|
|
837
|
-
|
|
863
|
+
NAPI_OK(napi_call_function(env, self, func, 1, &wrapper, nullptr));
|
|
838
864
|
instance->stats.disposed++;
|
|
839
865
|
};
|
|
840
866
|
dispose_func = func;
|
|
841
867
|
} else {
|
|
842
|
-
dispose = [](
|
|
843
|
-
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
844
|
-
|
|
868
|
+
dispose = [](InstanceData *instance, const TypeInfo *, const void *ptr) {
|
|
845
869
|
free((void *)ptr);
|
|
846
870
|
instance->stats.disposed++;
|
|
847
871
|
};
|
|
@@ -851,9 +875,8 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
|
|
|
851
875
|
K_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
|
|
852
876
|
|
|
853
877
|
memcpy((void *)type, (const void *)src, K_SIZE(*src));
|
|
854
|
-
type->
|
|
855
|
-
type->members.
|
|
856
|
-
memset((void *)&type->defn, 0, K_SIZE(type->defn));
|
|
878
|
+
type->defn = nullptr;
|
|
879
|
+
K_ASSERT(!type->members.len);
|
|
857
880
|
|
|
858
881
|
static_assert(!std::is_polymorphic_v<Napi::ObjectReference>);
|
|
859
882
|
|
|
@@ -861,7 +884,7 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
|
|
|
861
884
|
: Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.count).ptr;
|
|
862
885
|
|
|
863
886
|
type->dispose = dispose;
|
|
864
|
-
type->dispose_ref
|
|
887
|
+
NAPI_OK(napi_create_reference(env, dispose_func, 1, &type->dispose_ref));
|
|
865
888
|
|
|
866
889
|
// If the insert succeeds, we cannot fail anymore
|
|
867
890
|
if (named) {
|
|
@@ -875,13 +898,14 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
|
|
|
875
898
|
}
|
|
876
899
|
err_guard.Disable();
|
|
877
900
|
|
|
878
|
-
|
|
901
|
+
napi_value wrapper = WrapType(instance, type);
|
|
902
|
+
return Napi::Value(env, wrapper);
|
|
879
903
|
}
|
|
880
904
|
|
|
881
905
|
static Napi::Value CallAlloc(const Napi::CallbackInfo &info)
|
|
882
906
|
{
|
|
883
907
|
Napi::Env env = info.Env();
|
|
884
|
-
InstanceData *instance =
|
|
908
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
885
909
|
|
|
886
910
|
if (info.Length() < 2) {
|
|
887
911
|
ThrowError<Napi::TypeError>(env, "Expected 2 arguments, got %1", info.Length());
|
|
@@ -892,7 +916,7 @@ static Napi::Value CallAlloc(const Napi::CallbackInfo &info)
|
|
|
892
916
|
return env.Null();
|
|
893
917
|
}
|
|
894
918
|
|
|
895
|
-
const TypeInfo *type = ResolveType(info[0]);
|
|
919
|
+
const TypeInfo *type = ResolveType(instance, info[0]);
|
|
896
920
|
if (!type)
|
|
897
921
|
return env.Null();
|
|
898
922
|
|
|
@@ -921,12 +945,14 @@ static Napi::Value CallAlloc(const Napi::CallbackInfo &info)
|
|
|
921
945
|
return env.Null();
|
|
922
946
|
}
|
|
923
947
|
|
|
924
|
-
|
|
948
|
+
napi_value wrapper = WrapPointer(env, type, ptr);
|
|
949
|
+
return Napi::Value(env, wrapper);
|
|
925
950
|
}
|
|
926
951
|
|
|
927
952
|
static Napi::Value CallFree(const Napi::CallbackInfo &info)
|
|
928
953
|
{
|
|
929
954
|
Napi::Env env = info.Env();
|
|
955
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
930
956
|
|
|
931
957
|
if (info.Length() < 1) {
|
|
932
958
|
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
|
|
@@ -935,8 +961,6 @@ static Napi::Value CallFree(const Napi::CallbackInfo &info)
|
|
|
935
961
|
|
|
936
962
|
void *ptr = nullptr;
|
|
937
963
|
if (!TryPointer(env, info[0], &ptr)) {
|
|
938
|
-
InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
|
|
939
|
-
|
|
940
964
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, info[0]));
|
|
941
965
|
return env.Null();
|
|
942
966
|
}
|
|
@@ -949,7 +973,7 @@ static Napi::Value CallFree(const Napi::CallbackInfo &info)
|
|
|
949
973
|
static Napi::Value GetOrSetErrNo(const Napi::CallbackInfo &info)
|
|
950
974
|
{
|
|
951
975
|
Napi::Env env = info.Env();
|
|
952
|
-
InstanceData *instance =
|
|
976
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
953
977
|
|
|
954
978
|
if (info.Length() >= 1) {
|
|
955
979
|
Napi::Number value = info[0].As<Napi::Number>();
|
|
@@ -969,14 +993,14 @@ static Napi::Value GetOrSetErrNo(const Napi::CallbackInfo &info)
|
|
|
969
993
|
static Napi::Value CreateArrayType(const Napi::CallbackInfo &info)
|
|
970
994
|
{
|
|
971
995
|
Napi::Env env = info.Env();
|
|
972
|
-
InstanceData *instance =
|
|
996
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
973
997
|
|
|
974
998
|
if (info.Length() < 2) {
|
|
975
999
|
ThrowError<Napi::TypeError>(env, "Expected 2 to 4 arguments, got %1", info.Length());
|
|
976
1000
|
return env.Null();
|
|
977
1001
|
}
|
|
978
1002
|
|
|
979
|
-
const TypeInfo *ref = ResolveType(info[0]);
|
|
1003
|
+
const TypeInfo *ref = ResolveType(instance, info[0]);
|
|
980
1004
|
if (!ref)
|
|
981
1005
|
return env.Null();
|
|
982
1006
|
|
|
@@ -1024,10 +1048,19 @@ static Napi::Value CreateArrayType(const Napi::CallbackInfo &info)
|
|
|
1024
1048
|
}
|
|
1025
1049
|
|
|
1026
1050
|
hint = ArrayHint::Typed;
|
|
1051
|
+
} else if (str == "Buffer" || str == "buffer") {
|
|
1052
|
+
if (!(ref->flags & (int)TypeFlag::HasTypedArray)) {
|
|
1053
|
+
ThrowError<Napi::Error>(env, "Array hint 'Buffer' cannot be used with type %1", ref->name);
|
|
1054
|
+
return env.Null();
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
hint = ArrayHint::Buffer;
|
|
1027
1058
|
} else if (str == "Array" || str == "array") {
|
|
1028
1059
|
hint = ArrayHint::Array;
|
|
1029
1060
|
} else if (str == "String" || str == "string") {
|
|
1030
|
-
if (ref->primitive != PrimitiveKind::Int8 &&
|
|
1061
|
+
if (ref->primitive != PrimitiveKind::Int8 &&
|
|
1062
|
+
ref->primitive != PrimitiveKind::Int16 &&
|
|
1063
|
+
ref->primitive != PrimitiveKind::Int32) {
|
|
1031
1064
|
ThrowError<Napi::Error>(env, "Array hint 'String' can only be used with 8, 16 and 32-bit signed integer types");
|
|
1032
1065
|
return env.Null();
|
|
1033
1066
|
}
|
|
@@ -1048,7 +1081,8 @@ static Napi::Value CreateArrayType(const Napi::CallbackInfo &info)
|
|
|
1048
1081
|
type->countedby = DuplicateString(str.Utf8Value().c_str(), &instance->str_alloc).ptr;
|
|
1049
1082
|
}
|
|
1050
1083
|
|
|
1051
|
-
|
|
1084
|
+
napi_value wrapper = WrapType(instance, type);
|
|
1085
|
+
return Napi::Value(env, wrapper);
|
|
1052
1086
|
}
|
|
1053
1087
|
|
|
1054
1088
|
static bool ParseClassicFunction(const Napi::CallbackInfo &info, bool concrete, FunctionInfo *out_func)
|
|
@@ -1056,7 +1090,7 @@ static bool ParseClassicFunction(const Napi::CallbackInfo &info, bool concrete,
|
|
|
1056
1090
|
K_ASSERT(info.Length() >= 2);
|
|
1057
1091
|
|
|
1058
1092
|
Napi::Env env = info.Env();
|
|
1059
|
-
InstanceData *instance =
|
|
1093
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
1060
1094
|
|
|
1061
1095
|
Napi::String name = info[0u].As<Napi::String>();
|
|
1062
1096
|
Napi::Value ret = info[1u];
|
|
@@ -1099,7 +1133,7 @@ static bool ParseClassicFunction(const Napi::CallbackInfo &info, bool concrete,
|
|
|
1099
1133
|
// Leave anonymous naming responsibility to caller
|
|
1100
1134
|
out_func->name = named ? DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr : nullptr;
|
|
1101
1135
|
|
|
1102
|
-
out_func->ret.type = ResolveType(ret);
|
|
1136
|
+
out_func->ret.type = ResolveType(instance, ret);
|
|
1103
1137
|
if (!out_func->ret.type)
|
|
1104
1138
|
return false;
|
|
1105
1139
|
if (!CanReturnType(out_func->ret.type)) {
|
|
@@ -1126,7 +1160,7 @@ static bool ParseClassicFunction(const Napi::CallbackInfo &info, bool concrete,
|
|
|
1126
1160
|
for (uint32_t j = 0; j < parameters_len; j++) {
|
|
1127
1161
|
ParameterInfo param = {};
|
|
1128
1162
|
|
|
1129
|
-
param.type = ResolveType(parameters[j], ¶m.directions);
|
|
1163
|
+
param.type = ResolveType(instance, parameters[j].AsValue(), ¶m.directions);
|
|
1130
1164
|
|
|
1131
1165
|
if (!param.type)
|
|
1132
1166
|
return false;
|
|
@@ -1152,7 +1186,7 @@ static bool ParseClassicFunction(const Napi::CallbackInfo &info, bool concrete,
|
|
|
1152
1186
|
static Napi::Value CreateFunctionType(const Napi::CallbackInfo &info)
|
|
1153
1187
|
{
|
|
1154
1188
|
Napi::Env env = info.Env();
|
|
1155
|
-
InstanceData *instance =
|
|
1189
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
1156
1190
|
|
|
1157
1191
|
FunctionInfo *func = instance->callbacks.AppendDefault();
|
|
1158
1192
|
K_DEFER_N(err_guard) { instance->callbacks.RemoveLast(1); };
|
|
@@ -1170,7 +1204,7 @@ static Napi::Value CreateFunctionType(const Napi::CallbackInfo &info)
|
|
|
1170
1204
|
}
|
|
1171
1205
|
|
|
1172
1206
|
std::string proto = info[0u].As<Napi::String>();
|
|
1173
|
-
if (!ParsePrototype(
|
|
1207
|
+
if (!ParsePrototype(instance, proto.c_str(), false, func))
|
|
1174
1208
|
return env.Null();
|
|
1175
1209
|
} else {
|
|
1176
1210
|
ThrowError<Napi::TypeError>(env, "Expected 1 to 4 arguments, got %1", info.Length());
|
|
@@ -1195,6 +1229,7 @@ static Napi::Value CreateFunctionType(const Napi::CallbackInfo &info)
|
|
|
1195
1229
|
|
|
1196
1230
|
TypeInfo *type = instance->types.AppendDefault();
|
|
1197
1231
|
|
|
1232
|
+
type->instance = instance;
|
|
1198
1233
|
type->name = func->name;
|
|
1199
1234
|
|
|
1200
1235
|
type->primitive = PrimitiveKind::Prototype;
|
|
@@ -1204,13 +1239,14 @@ static Napi::Value CreateFunctionType(const Napi::CallbackInfo &info)
|
|
|
1204
1239
|
|
|
1205
1240
|
instance->types_map.Set(type->name, type);
|
|
1206
1241
|
|
|
1207
|
-
|
|
1242
|
+
napi_value wrapper = WrapType(instance, type);
|
|
1243
|
+
return Napi::Value(env, wrapper);
|
|
1208
1244
|
}
|
|
1209
1245
|
|
|
1210
1246
|
static Napi::Value CreateEnumType(const Napi::CallbackInfo &info)
|
|
1211
1247
|
{
|
|
1212
1248
|
Napi::Env env = info.Env();
|
|
1213
|
-
InstanceData *instance =
|
|
1249
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
1214
1250
|
|
|
1215
1251
|
if (info.Length() < 1) {
|
|
1216
1252
|
ThrowError<Napi::TypeError>(env, "Expected 1 or 2 arguments, got %1", info.Length());
|
|
@@ -1236,6 +1272,7 @@ static Napi::Value CreateEnumType(const Napi::CallbackInfo &info)
|
|
|
1236
1272
|
TypeInfo *type = instance->types.AppendDefault();
|
|
1237
1273
|
K_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
|
|
1238
1274
|
|
|
1275
|
+
type->instance = instance;
|
|
1239
1276
|
type->name = named ? DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr
|
|
1240
1277
|
: Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.count).ptr;
|
|
1241
1278
|
|
|
@@ -1243,7 +1280,7 @@ static Napi::Value CreateEnumType(const Napi::CallbackInfo &info)
|
|
|
1243
1280
|
|
|
1244
1281
|
// Determine needed storage type
|
|
1245
1282
|
if (typed) {
|
|
1246
|
-
const TypeInfo *storage = ResolveType(info[1 + named]);
|
|
1283
|
+
const TypeInfo *storage = ResolveType(instance, info[1 + named]);
|
|
1247
1284
|
if (!storage)
|
|
1248
1285
|
return env.Null();
|
|
1249
1286
|
|
|
@@ -1360,19 +1397,30 @@ static Napi::Value CreateEnumType(const Napi::CallbackInfo &info)
|
|
|
1360
1397
|
return env.Null();
|
|
1361
1398
|
err_guard.Disable();
|
|
1362
1399
|
|
|
1363
|
-
|
|
1364
|
-
|
|
1400
|
+
napi_value wrapper = WrapType(instance, type, false);
|
|
1401
|
+
|
|
1402
|
+
#if defined(EXTERNAL_TYPES)
|
|
1403
|
+
Napi::Object defn;
|
|
1404
|
+
{
|
|
1405
|
+
napi_value value;
|
|
1406
|
+
NAPI_OK(napi_get_reference_value(env, type->defn, &defn));
|
|
1407
|
+
|
|
1408
|
+
defn = Napi::Object(env, value);
|
|
1409
|
+
}
|
|
1410
|
+
#else
|
|
1411
|
+
Napi::Object defn(env, wrapper);
|
|
1412
|
+
#endif
|
|
1365
1413
|
|
|
1366
1414
|
defn.Set("values", values);
|
|
1367
1415
|
defn.Freeze();
|
|
1368
1416
|
|
|
1369
|
-
return wrapper;
|
|
1417
|
+
return Napi::Value(env, wrapper);
|
|
1370
1418
|
}
|
|
1371
1419
|
|
|
1372
1420
|
static Napi::Value CreateTypeAlias(const Napi::CallbackInfo &info)
|
|
1373
1421
|
{
|
|
1374
1422
|
Napi::Env env = info.Env();
|
|
1375
|
-
InstanceData *instance =
|
|
1423
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
1376
1424
|
|
|
1377
1425
|
if (info.Length() < 2) {
|
|
1378
1426
|
ThrowError<Napi::TypeError>(env, "Expected 2 arguments, got %1", info.Length());
|
|
@@ -1386,7 +1434,7 @@ static Napi::Value CreateTypeAlias(const Napi::CallbackInfo &info)
|
|
|
1386
1434
|
std::string name = info[0].As<Napi::String>();
|
|
1387
1435
|
const char *alias = DuplicateString(name.c_str(), &instance->str_alloc).ptr;
|
|
1388
1436
|
|
|
1389
|
-
const TypeInfo *type = ResolveType(info[1]);
|
|
1437
|
+
const TypeInfo *type = ResolveType(instance, info[1]);
|
|
1390
1438
|
if (!type)
|
|
1391
1439
|
return env.Null();
|
|
1392
1440
|
|
|
@@ -1394,23 +1442,26 @@ static Napi::Value CreateTypeAlias(const Napi::CallbackInfo &info)
|
|
|
1394
1442
|
if (!MapType(env, instance, type, alias))
|
|
1395
1443
|
return env.Null();
|
|
1396
1444
|
|
|
1397
|
-
|
|
1445
|
+
napi_value wrapper = WrapType(instance, type);
|
|
1446
|
+
return Napi::Value(env, wrapper);
|
|
1398
1447
|
}
|
|
1399
1448
|
|
|
1400
1449
|
static Napi::Value GetResolvedType(const Napi::CallbackInfo &info)
|
|
1401
1450
|
{
|
|
1402
1451
|
Napi::Env env = info.Env();
|
|
1452
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
1403
1453
|
|
|
1404
1454
|
if (info.Length() < 1) {
|
|
1405
1455
|
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
|
|
1406
1456
|
return env.Null();
|
|
1407
1457
|
}
|
|
1408
1458
|
|
|
1409
|
-
const TypeInfo *type = ResolveType(info[0]);
|
|
1459
|
+
const TypeInfo *type = ResolveType(instance, info[0]);
|
|
1410
1460
|
if (!type)
|
|
1411
1461
|
return env.Null();
|
|
1412
1462
|
|
|
1413
|
-
|
|
1463
|
+
napi_value wrapper = WrapType(instance, type);
|
|
1464
|
+
return Napi::Value(env, wrapper);
|
|
1414
1465
|
}
|
|
1415
1466
|
|
|
1416
1467
|
#if defined(EXTERNAL_TYPES)
|
|
@@ -1418,20 +1469,24 @@ static Napi::Value GetResolvedType(const Napi::CallbackInfo &info)
|
|
|
1418
1469
|
static Napi::Value GetTypeDefinition(const Napi::CallbackInfo &info)
|
|
1419
1470
|
{
|
|
1420
1471
|
Napi::Env env = info.Env();
|
|
1472
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
1421
1473
|
|
|
1422
1474
|
if (info.Length() < 1) {
|
|
1423
1475
|
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
|
|
1424
1476
|
return env.Null();
|
|
1425
1477
|
}
|
|
1426
1478
|
|
|
1427
|
-
const TypeInfo *type = ResolveType(info[0]);
|
|
1479
|
+
const TypeInfo *type = ResolveType(instance, info[0]);
|
|
1428
1480
|
if (!type)
|
|
1429
1481
|
return env.Null();
|
|
1430
1482
|
|
|
1431
1483
|
// Make sure definition is available
|
|
1432
|
-
WrapType(
|
|
1484
|
+
WrapType(instance, type);
|
|
1433
1485
|
|
|
1434
|
-
|
|
1486
|
+
napi_value defn;
|
|
1487
|
+
NAPI_OK(napi_get_reference_value(env, instance->defn, &defn));
|
|
1488
|
+
|
|
1489
|
+
return defn;
|
|
1435
1490
|
}
|
|
1436
1491
|
|
|
1437
1492
|
#endif
|
|
@@ -1530,13 +1585,32 @@ void ReleaseMemory(InstanceData *instance, InstanceMemory *mem)
|
|
|
1530
1585
|
}
|
|
1531
1586
|
}
|
|
1532
1587
|
|
|
1533
|
-
|
|
1588
|
+
TypeInfo::~TypeInfo()
|
|
1589
|
+
{
|
|
1590
|
+
if (!instance)
|
|
1591
|
+
return;
|
|
1592
|
+
|
|
1593
|
+
Napi::Env env = instance->env;
|
|
1594
|
+
|
|
1595
|
+
for (RecordMember &member: members) {
|
|
1596
|
+
node_api_delete_reference(env, member.key);
|
|
1597
|
+
member.key = nullptr;
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
node_api_delete_reference(env, dispose_ref);
|
|
1601
|
+
node_api_delete_reference(env, construct);
|
|
1602
|
+
node_api_delete_reference(env, defn);
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
Napi::Function LibraryHandle::InitClass(InstanceData *instance)
|
|
1534
1606
|
{
|
|
1607
|
+
Napi::Env env = instance->env;
|
|
1608
|
+
|
|
1535
1609
|
// node-addon-api wants std::vector
|
|
1536
1610
|
std::vector<Napi::ClassPropertyDescriptor<LibraryHandle>> properties = {
|
|
1537
|
-
InstanceMethod("func", &LibraryHandle::Func),
|
|
1538
|
-
InstanceMethod("symbol", &LibraryHandle::Symbol),
|
|
1539
|
-
InstanceMethod("unload", &LibraryHandle::Unload)
|
|
1611
|
+
InstanceMethod("func", &LibraryHandle::Func, napi_default, instance),
|
|
1612
|
+
InstanceMethod("symbol", &LibraryHandle::Symbol, napi_default, instance),
|
|
1613
|
+
InstanceMethod("unload", &LibraryHandle::Unload, napi_default, instance)
|
|
1540
1614
|
};
|
|
1541
1615
|
|
|
1542
1616
|
if (Napi::Value dispose = env.RunScript("Symbol.dispose"); !IsNullOrUndefined(env, dispose)) {
|
|
@@ -1564,7 +1638,7 @@ LibraryHandle::LibraryHandle(const Napi::CallbackInfo &info)
|
|
|
1564
1638
|
|
|
1565
1639
|
void LibraryHandle::Finalize(Napi::BasicEnv env)
|
|
1566
1640
|
{
|
|
1567
|
-
|
|
1641
|
+
node_api_delete_reference(env, *this);
|
|
1568
1642
|
SuppressDestruct();
|
|
1569
1643
|
|
|
1570
1644
|
lib->Unref();
|
|
@@ -1573,7 +1647,7 @@ void LibraryHandle::Finalize(Napi::BasicEnv env)
|
|
|
1573
1647
|
Napi::Value LibraryHandle::Func(const Napi::CallbackInfo &info)
|
|
1574
1648
|
{
|
|
1575
1649
|
Napi::Env env = info.Env();
|
|
1576
|
-
InstanceData *instance =
|
|
1650
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
1577
1651
|
|
|
1578
1652
|
FunctionInfo *func = new FunctionInfo();
|
|
1579
1653
|
K_DEFER { func->Unref(); };
|
|
@@ -1592,7 +1666,7 @@ Napi::Value LibraryHandle::Func(const Napi::CallbackInfo &info)
|
|
|
1592
1666
|
}
|
|
1593
1667
|
|
|
1594
1668
|
std::string proto = info[0u].As<Napi::String>();
|
|
1595
|
-
if (!ParsePrototype(
|
|
1669
|
+
if (!ParsePrototype(instance, proto.c_str(), true, func))
|
|
1596
1670
|
return env.Null();
|
|
1597
1671
|
} else {
|
|
1598
1672
|
ThrowError<Napi::TypeError>(env, "Expected 1 to 4 arguments, got %1", info.Length());
|
|
@@ -1635,28 +1709,40 @@ Napi::Value LibraryHandle::Func(const Napi::CallbackInfo &info)
|
|
|
1635
1709
|
return env.Null();
|
|
1636
1710
|
}
|
|
1637
1711
|
|
|
1638
|
-
|
|
1712
|
+
napi_value wrapper = WrapFunction(instance, func);
|
|
1713
|
+
return Napi::Value(env, wrapper);
|
|
1639
1714
|
}
|
|
1640
1715
|
|
|
1641
1716
|
Napi::Value LibraryHandle::Symbol(const Napi::CallbackInfo &info)
|
|
1642
1717
|
{
|
|
1643
1718
|
Napi::Env env = info.Env();
|
|
1644
|
-
InstanceData *instance =
|
|
1719
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
1645
1720
|
|
|
1721
|
+
#if defined(EXTERNAL_POINTERS)
|
|
1646
1722
|
if (info.Length() < 2) {
|
|
1647
|
-
ThrowError<Napi::TypeError>(env, "Expected 2, got %1", info.Length());
|
|
1723
|
+
ThrowError<Napi::TypeError>(env, "Expected 2 arguments, got %1", info.Length());
|
|
1648
1724
|
return env.Null();
|
|
1649
1725
|
}
|
|
1650
|
-
|
|
1726
|
+
#else
|
|
1727
|
+
if (info.Length() < 1) {
|
|
1728
|
+
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
|
|
1729
|
+
return env.Null();
|
|
1730
|
+
}
|
|
1731
|
+
#endif
|
|
1732
|
+
if (!info[0].IsString()) {
|
|
1651
1733
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for name, expected string", GetValueType(instance, info[0]));
|
|
1652
1734
|
return env.Null();
|
|
1653
1735
|
}
|
|
1654
1736
|
|
|
1655
1737
|
std::string name = info[0].As<Napi::String>();
|
|
1656
1738
|
|
|
1657
|
-
|
|
1739
|
+
#if defined(EXTERNAL_POINTERS)
|
|
1740
|
+
const TypeInfo *type = ResolveType(instance, info[1]);
|
|
1658
1741
|
if (!type)
|
|
1659
1742
|
return env.Null();
|
|
1743
|
+
#else
|
|
1744
|
+
const TypeInfo *type = nullptr;
|
|
1745
|
+
#endif
|
|
1660
1746
|
|
|
1661
1747
|
#if defined(_WIN32)
|
|
1662
1748
|
void *ptr = (void *)GetProcAddress((HMODULE)lib->module, name.c_str());
|
|
@@ -1668,7 +1754,8 @@ Napi::Value LibraryHandle::Symbol(const Napi::CallbackInfo &info)
|
|
|
1668
1754
|
return env.Null();
|
|
1669
1755
|
}
|
|
1670
1756
|
|
|
1671
|
-
|
|
1757
|
+
napi_value wrapper = WrapPointer(env, type, ptr);
|
|
1758
|
+
return Napi::Value(env, wrapper);
|
|
1672
1759
|
}
|
|
1673
1760
|
|
|
1674
1761
|
Napi::Value LibraryHandle::Unload(const Napi::CallbackInfo &info)
|
|
@@ -1683,7 +1770,7 @@ Napi::Value LibraryHandle::Unload(const Napi::CallbackInfo &info)
|
|
|
1683
1770
|
static Napi::Value LoadSharedLibrary(const Napi::CallbackInfo &info)
|
|
1684
1771
|
{
|
|
1685
1772
|
Napi::Env env = info.Env();
|
|
1686
|
-
InstanceData *instance =
|
|
1773
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
1687
1774
|
|
|
1688
1775
|
if (info.Length() < 1) {
|
|
1689
1776
|
ThrowError<Napi::TypeError>(env, "Expected 1 or 2 arguments, got %1", info.Length());
|
|
@@ -1768,7 +1855,7 @@ static Napi::Value LoadSharedLibrary(const Napi::CallbackInfo &info)
|
|
|
1768
1855
|
static Napi::Value RegisterCallback(const Napi::CallbackInfo &info)
|
|
1769
1856
|
{
|
|
1770
1857
|
Napi::Env env = info.Env();
|
|
1771
|
-
InstanceData *instance =
|
|
1858
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
1772
1859
|
|
|
1773
1860
|
if (!InitAsyncBroker(env, instance)) [[unlikely]]
|
|
1774
1861
|
return env.Null();
|
|
@@ -1784,7 +1871,7 @@ static Napi::Value RegisterCallback(const Napi::CallbackInfo &info)
|
|
|
1784
1871
|
|
|
1785
1872
|
Napi::Function func = info[0].As<Napi::Function>();
|
|
1786
1873
|
|
|
1787
|
-
const TypeInfo *type = ResolveType(info[1]);
|
|
1874
|
+
const TypeInfo *type = ResolveType(instance, info[1]);
|
|
1788
1875
|
if (!type)
|
|
1789
1876
|
return env.Null();
|
|
1790
1877
|
if (type->primitive != PrimitiveKind::Callback) {
|
|
@@ -1811,20 +1898,21 @@ static Napi::Value RegisterCallback(const Napi::CallbackInfo &info)
|
|
|
1811
1898
|
trampoline->instance = instance;
|
|
1812
1899
|
trampoline->stack0 = instance->memories[0]->stack0;
|
|
1813
1900
|
trampoline->proto = type->proto;
|
|
1814
|
-
napi_create_reference(env, func, 1, &trampoline->func);
|
|
1901
|
+
NAPI_OK(napi_create_reference(env, func, 1, &trampoline->func));
|
|
1815
1902
|
|
|
1816
1903
|
void *ptr = GetTrampoline(idx);
|
|
1817
1904
|
|
|
1818
1905
|
// Cache index for fast unregistration
|
|
1819
1906
|
instance->trampolines_map.Set(ptr, idx);
|
|
1820
1907
|
|
|
1821
|
-
|
|
1908
|
+
napi_value wrapper = WrapPointer(env, type->ref.type, ptr);
|
|
1909
|
+
return Napi::Value(env, wrapper);
|
|
1822
1910
|
}
|
|
1823
1911
|
|
|
1824
1912
|
static Napi::Value UnregisterCallback(const Napi::CallbackInfo &info)
|
|
1825
1913
|
{
|
|
1826
1914
|
Napi::Env env = info.Env();
|
|
1827
|
-
InstanceData *instance =
|
|
1915
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
1828
1916
|
|
|
1829
1917
|
if (info.Length() < 1) {
|
|
1830
1918
|
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
|
|
@@ -1858,7 +1946,7 @@ static Napi::Value UnregisterCallback(const Napi::CallbackInfo &info)
|
|
|
1858
1946
|
K_ASSERT(trampoline->func);
|
|
1859
1947
|
|
|
1860
1948
|
trampoline->state = 0;
|
|
1861
|
-
|
|
1949
|
+
node_api_delete_reference(env, trampoline->func);
|
|
1862
1950
|
trampoline->func = nullptr;
|
|
1863
1951
|
|
|
1864
1952
|
shared.available.Append(idx);
|
|
@@ -1870,6 +1958,7 @@ static Napi::Value UnregisterCallback(const Napi::CallbackInfo &info)
|
|
|
1870
1958
|
static Napi::Value CastValue(const Napi::CallbackInfo &info)
|
|
1871
1959
|
{
|
|
1872
1960
|
Napi::Env env = info.Env();
|
|
1961
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
1873
1962
|
|
|
1874
1963
|
if (info.Length() < 2) [[unlikely]] {
|
|
1875
1964
|
ThrowError<Napi::TypeError>(env, "Expected 2 arguments, got %1", info.Length());
|
|
@@ -1878,7 +1967,7 @@ static Napi::Value CastValue(const Napi::CallbackInfo &info)
|
|
|
1878
1967
|
|
|
1879
1968
|
Napi::Value value = info[0];
|
|
1880
1969
|
|
|
1881
|
-
const TypeInfo *type = ResolveType(info[1]);
|
|
1970
|
+
const TypeInfo *type = ResolveType(instance, info[1]);
|
|
1882
1971
|
if (!type) [[unlikely]]
|
|
1883
1972
|
return env.Null();
|
|
1884
1973
|
if (type->primitive != PrimitiveKind::Pointer &&
|
|
@@ -1893,10 +1982,10 @@ static Napi::Value CastValue(const Napi::CallbackInfo &info)
|
|
|
1893
1982
|
ValueCast *cast = new ValueCast();
|
|
1894
1983
|
|
|
1895
1984
|
cast->env = env;
|
|
1896
|
-
napi_create_reference(env, value, 1, &cast->ref);
|
|
1985
|
+
NAPI_OK(napi_create_reference(env, value, 1, &cast->ref));
|
|
1897
1986
|
cast->type = type;
|
|
1898
1987
|
|
|
1899
|
-
Napi::External<ValueCast> external = Napi::External<ValueCast>::New(env, cast, [](Napi::
|
|
1988
|
+
Napi::External<ValueCast> external = Napi::External<ValueCast>::New(env, cast, [](Napi::BasicEnv, ValueCast *cast) { delete cast; });
|
|
1900
1989
|
SetValueTag(env, external, &CastMarker);
|
|
1901
1990
|
|
|
1902
1991
|
return external;
|
|
@@ -1905,6 +1994,7 @@ static Napi::Value CastValue(const Napi::CallbackInfo &info)
|
|
|
1905
1994
|
static Napi::Value DecodeValue(const Napi::CallbackInfo &info)
|
|
1906
1995
|
{
|
|
1907
1996
|
Napi::Env env = info.Env();
|
|
1997
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
1908
1998
|
|
|
1909
1999
|
bool has_offset = (info.Length() >= 2 && info[1].IsNumber());
|
|
1910
2000
|
bool has_len = (info.Length() >= 3u + has_offset && info[2 + has_offset].IsNumber());
|
|
@@ -1914,22 +2004,78 @@ static Napi::Value DecodeValue(const Napi::CallbackInfo &info)
|
|
|
1914
2004
|
return env.Null();
|
|
1915
2005
|
}
|
|
1916
2006
|
|
|
1917
|
-
const TypeInfo *type = ResolveType(info[1u + has_offset]);
|
|
2007
|
+
const TypeInfo *type = ResolveType(instance, info[1u + has_offset]);
|
|
1918
2008
|
if (!type) [[unlikely]]
|
|
1919
2009
|
return env.Null();
|
|
1920
2010
|
|
|
1921
|
-
|
|
2011
|
+
napi_value ref = info[0];
|
|
1922
2012
|
int64_t offset = has_offset ? info[1].As<Napi::Number>().Int64Value() : 0;
|
|
1923
2013
|
|
|
2014
|
+
const void *src = nullptr;
|
|
2015
|
+
Size len = 0;
|
|
2016
|
+
|
|
2017
|
+
if (!TryPointer(env, ref, (void **)&src, &len)) {
|
|
2018
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for reference, expected pointer", GetValueType(instance, ref));
|
|
2019
|
+
return env.Null();
|
|
2020
|
+
}
|
|
2021
|
+
|
|
2022
|
+
if (len >= 0) {
|
|
2023
|
+
if (offset < 0) [[unlikely]] {
|
|
2024
|
+
ThrowError<Napi::Error>(env, "Offset must be >= 0");
|
|
2025
|
+
return env.Null();
|
|
2026
|
+
}
|
|
2027
|
+
if (len - offset < type->size) [[unlikely]] {
|
|
2028
|
+
ThrowError<Napi::Error>(env, "Expected buffer with size superior or equal to type %1 (%2 bytes)",
|
|
2029
|
+
type->name, type->size + offset);
|
|
2030
|
+
return env.Null();
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
|
|
2034
|
+
if (!src) [[unlikely]] {
|
|
2035
|
+
ThrowError<Napi::Error>(env, "Cannot encode data in NULL pointer");
|
|
2036
|
+
return env.Null();
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
src = (const void *)((const uint8_t *)src + offset);
|
|
2040
|
+
|
|
1924
2041
|
if (has_len) {
|
|
1925
2042
|
Size len = info[2 + has_offset].As<Napi::Number>();
|
|
1926
2043
|
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
2044
|
+
if (len >= 0) {
|
|
2045
|
+
type = MakeArrayType(instance, type, len);
|
|
2046
|
+
} else {
|
|
2047
|
+
switch (type->primitive) {
|
|
2048
|
+
case PrimitiveKind::Int8:
|
|
2049
|
+
case PrimitiveKind::UInt8: {
|
|
2050
|
+
Size count = strlen((const char *)src);
|
|
2051
|
+
type = MakeArrayType(instance, type, count);
|
|
2052
|
+
} break;
|
|
2053
|
+
case PrimitiveKind::Int16:
|
|
2054
|
+
case PrimitiveKind::UInt16: {
|
|
2055
|
+
Size count = NullTerminatedLength((const char16_t *)src);
|
|
2056
|
+
type = MakeArrayType(instance, type, count);
|
|
2057
|
+
} break;
|
|
2058
|
+
case PrimitiveKind::Int32:
|
|
2059
|
+
case PrimitiveKind::UInt32: {
|
|
2060
|
+
Size count = NullTerminatedLength((const char32_t *)src);
|
|
2061
|
+
type = MakeArrayType(instance, type, count);
|
|
2062
|
+
} break;
|
|
2063
|
+
|
|
2064
|
+
case PrimitiveKind::Pointer: {
|
|
2065
|
+
Size count = NullTerminatedLength((const void **)src);
|
|
2066
|
+
type = MakeArrayType(instance, type, count);
|
|
2067
|
+
} break;
|
|
2068
|
+
|
|
2069
|
+
default: {
|
|
2070
|
+
ThrowError<Napi::TypeError>(env, "Cannot determine null-terminated length for type %1", type->name);
|
|
2071
|
+
return env.Null();
|
|
2072
|
+
} break;
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
1932
2075
|
}
|
|
2076
|
+
|
|
2077
|
+
napi_value ret = Decode(instance, (const uint8_t *)src, type);
|
|
2078
|
+
return Napi::Value(env, ret);
|
|
1933
2079
|
}
|
|
1934
2080
|
|
|
1935
2081
|
template <typename T>
|
|
@@ -1937,9 +2083,9 @@ static FORCE_INLINE napi_value DecodeInteger(napi_env env, napi_callback_info in
|
|
|
1937
2083
|
{
|
|
1938
2084
|
napi_value arg;
|
|
1939
2085
|
size_t count = 1;
|
|
2086
|
+
InstanceData *instance;
|
|
1940
2087
|
|
|
1941
|
-
|
|
1942
|
-
K_ASSERT(status == napi_ok);
|
|
2088
|
+
NAPI_OK(napi_get_cb_info(env, info, &count, &arg, nullptr, (void **)&instance));
|
|
1943
2089
|
|
|
1944
2090
|
if (count < 1) [[unlikely]] {
|
|
1945
2091
|
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", count);
|
|
@@ -1948,8 +2094,6 @@ static FORCE_INLINE napi_value DecodeInteger(napi_env env, napi_callback_info in
|
|
|
1948
2094
|
|
|
1949
2095
|
void *ptr = nullptr;
|
|
1950
2096
|
if (!TryPointer(env, arg, &ptr)) [[unlikely]] {
|
|
1951
|
-
InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
|
|
1952
|
-
|
|
1953
2097
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, arg));
|
|
1954
2098
|
return Napi::Env(env).Null();
|
|
1955
2099
|
}
|
|
@@ -1960,13 +2104,14 @@ static FORCE_INLINE napi_value DecodeInteger(napi_env env, napi_callback_info in
|
|
|
1960
2104
|
return NewInt(env, i);
|
|
1961
2105
|
}
|
|
1962
2106
|
|
|
1963
|
-
|
|
2107
|
+
template <typename T>
|
|
2108
|
+
static FORCE_INLINE napi_value DecodeIntegerSwap(napi_env env, napi_callback_info info)
|
|
1964
2109
|
{
|
|
1965
2110
|
napi_value arg;
|
|
1966
2111
|
size_t count = 1;
|
|
2112
|
+
InstanceData *instance;
|
|
1967
2113
|
|
|
1968
|
-
|
|
1969
|
-
K_ASSERT(status == napi_ok);
|
|
2114
|
+
NAPI_OK(napi_get_cb_info(env, info, &count, &arg, nullptr, (void **)&instance));
|
|
1970
2115
|
|
|
1971
2116
|
if (count < 1) [[unlikely]] {
|
|
1972
2117
|
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", count);
|
|
@@ -1975,8 +2120,47 @@ static napi_value DecodeFloat(napi_env env, napi_callback_info info)
|
|
|
1975
2120
|
|
|
1976
2121
|
void *ptr = nullptr;
|
|
1977
2122
|
if (!TryPointer(env, arg, &ptr)) [[unlikely]] {
|
|
1978
|
-
|
|
2123
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, arg));
|
|
2124
|
+
return Napi::Env(env).Null();
|
|
2125
|
+
}
|
|
2126
|
+
|
|
2127
|
+
T i;
|
|
2128
|
+
memcpy(&i, ptr, K_SIZE(i));
|
|
2129
|
+
|
|
2130
|
+
return NewInt(env, ReverseBytes(i));
|
|
2131
|
+
}
|
|
2132
|
+
|
|
2133
|
+
#if defined(K_BIG_ENDIAN)
|
|
2134
|
+
|
|
2135
|
+
template <typename T>
|
|
2136
|
+
static FORCE_INLINE napi_value DecodeIntegerLE(napi_env env, napi_callback_info info) { return DecodeIntegerSwap<T>(env, info); }
|
|
2137
|
+
template <typename T>
|
|
2138
|
+
static FORCE_INLINE napi_value DecodeIntegerBE(napi_env env, napi_callback_info info) { return DecodeInteger<T>(env, info); }
|
|
2139
|
+
|
|
2140
|
+
#else
|
|
1979
2141
|
|
|
2142
|
+
template <typename T>
|
|
2143
|
+
static FORCE_INLINE napi_value DecodeIntegerLE(napi_env env, napi_callback_info info) { return DecodeInteger<T>(env, info); }
|
|
2144
|
+
template <typename T>
|
|
2145
|
+
static FORCE_INLINE napi_value DecodeIntegerBE(napi_env env, napi_callback_info info) { return DecodeIntegerSwap<T>(env, info); }
|
|
2146
|
+
|
|
2147
|
+
#endif
|
|
2148
|
+
|
|
2149
|
+
static napi_value DecodeFloat(napi_env env, napi_callback_info info)
|
|
2150
|
+
{
|
|
2151
|
+
napi_value arg;
|
|
2152
|
+
size_t count = 1;
|
|
2153
|
+
InstanceData *instance;
|
|
2154
|
+
|
|
2155
|
+
NAPI_OK(napi_get_cb_info(env, info, &count, &arg, nullptr, (void **)&instance));
|
|
2156
|
+
|
|
2157
|
+
if (count < 1) [[unlikely]] {
|
|
2158
|
+
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", count);
|
|
2159
|
+
return Napi::Env(env).Null();
|
|
2160
|
+
}
|
|
2161
|
+
|
|
2162
|
+
void *ptr = nullptr;
|
|
2163
|
+
if (!TryPointer(env, arg, &ptr)) [[unlikely]] {
|
|
1980
2164
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, arg));
|
|
1981
2165
|
return Napi::Env(env).Null();
|
|
1982
2166
|
}
|
|
@@ -1984,16 +2168,16 @@ static napi_value DecodeFloat(napi_env env, napi_callback_info info)
|
|
|
1984
2168
|
float f;
|
|
1985
2169
|
memcpy(&f, ptr, K_SIZE(f));
|
|
1986
2170
|
|
|
1987
|
-
return
|
|
2171
|
+
return NewFloat(env, f);
|
|
1988
2172
|
}
|
|
1989
2173
|
|
|
1990
2174
|
static napi_value DecodeDouble(napi_env env, napi_callback_info info)
|
|
1991
2175
|
{
|
|
1992
2176
|
napi_value arg;
|
|
1993
2177
|
size_t count = 1;
|
|
2178
|
+
InstanceData *instance;
|
|
1994
2179
|
|
|
1995
|
-
|
|
1996
|
-
K_ASSERT(status == napi_ok);
|
|
2180
|
+
NAPI_OK(napi_get_cb_info(env, info, &count, &arg, nullptr, (void **)&instance));
|
|
1997
2181
|
|
|
1998
2182
|
if (count < 1) [[unlikely]] {
|
|
1999
2183
|
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", count);
|
|
@@ -2002,8 +2186,6 @@ static napi_value DecodeDouble(napi_env env, napi_callback_info info)
|
|
|
2002
2186
|
|
|
2003
2187
|
void *ptr = nullptr;
|
|
2004
2188
|
if (!TryPointer(env, arg, &ptr)) [[unlikely]] {
|
|
2005
|
-
InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
|
|
2006
|
-
|
|
2007
2189
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, arg));
|
|
2008
2190
|
return Napi::Env(env).Null();
|
|
2009
2191
|
}
|
|
@@ -2011,16 +2193,16 @@ static napi_value DecodeDouble(napi_env env, napi_callback_info info)
|
|
|
2011
2193
|
double d;
|
|
2012
2194
|
memcpy(&d, ptr, K_SIZE(d));
|
|
2013
2195
|
|
|
2014
|
-
return
|
|
2196
|
+
return NewFloat(env, d);
|
|
2015
2197
|
}
|
|
2016
2198
|
|
|
2017
2199
|
static napi_value DecodeString(napi_env env, napi_callback_info info)
|
|
2018
2200
|
{
|
|
2019
2201
|
napi_value args[2];
|
|
2020
2202
|
size_t count = 2;
|
|
2203
|
+
InstanceData *instance;
|
|
2021
2204
|
|
|
2022
|
-
|
|
2023
|
-
K_ASSERT(status == napi_ok);
|
|
2205
|
+
NAPI_OK(napi_get_cb_info(env, info, &count, args, nullptr, (void **)&instance));
|
|
2024
2206
|
|
|
2025
2207
|
if (count < 1) [[unlikely]] {
|
|
2026
2208
|
ThrowError<Napi::TypeError>(env, "Expected 1 to 2 arguments, got %1", count);
|
|
@@ -2029,8 +2211,6 @@ static napi_value DecodeString(napi_env env, napi_callback_info info)
|
|
|
2029
2211
|
|
|
2030
2212
|
void *ptr = nullptr;
|
|
2031
2213
|
if (!TryPointer(env, args[0], &ptr)) [[unlikely]] {
|
|
2032
|
-
InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
|
|
2033
|
-
|
|
2034
2214
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, args[0]));
|
|
2035
2215
|
return Napi::Env(env).Null();
|
|
2036
2216
|
}
|
|
@@ -2038,15 +2218,13 @@ static napi_value DecodeString(napi_env env, napi_callback_info info)
|
|
|
2038
2218
|
if (count >= 2) {
|
|
2039
2219
|
Size len;
|
|
2040
2220
|
if (!TryNumber(env, args[1], &len)) [[unlikely]] {
|
|
2041
|
-
InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
|
|
2042
|
-
|
|
2043
2221
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for length, expected number", GetValueType(instance, args[1]));
|
|
2044
2222
|
return Napi::Env(env).Null();
|
|
2045
2223
|
}
|
|
2046
2224
|
|
|
2047
|
-
return
|
|
2225
|
+
return NewString(env, (const char *)ptr, (size_t)len);
|
|
2048
2226
|
} else {
|
|
2049
|
-
return
|
|
2227
|
+
return NewString(env, (const char *)ptr);
|
|
2050
2228
|
}
|
|
2051
2229
|
}
|
|
2052
2230
|
|
|
@@ -2054,9 +2232,9 @@ static napi_value DecodeString16(napi_env env, napi_callback_info info)
|
|
|
2054
2232
|
{
|
|
2055
2233
|
napi_value args[2];
|
|
2056
2234
|
size_t count = 2;
|
|
2235
|
+
InstanceData *instance;
|
|
2057
2236
|
|
|
2058
|
-
|
|
2059
|
-
K_ASSERT(status == napi_ok);
|
|
2237
|
+
NAPI_OK(napi_get_cb_info(env, info, &count, args, nullptr, (void **)&instance));
|
|
2060
2238
|
|
|
2061
2239
|
if (count < 1) [[unlikely]] {
|
|
2062
2240
|
ThrowError<Napi::TypeError>(env, "Expected 1 to 2 arguments, got %1", count);
|
|
@@ -2065,8 +2243,6 @@ static napi_value DecodeString16(napi_env env, napi_callback_info info)
|
|
|
2065
2243
|
|
|
2066
2244
|
void *ptr = nullptr;
|
|
2067
2245
|
if (!TryPointer(env, args[0], &ptr)) [[unlikely]] {
|
|
2068
|
-
InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
|
|
2069
|
-
|
|
2070
2246
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, args[0]));
|
|
2071
2247
|
return Napi::Env(env).Null();
|
|
2072
2248
|
}
|
|
@@ -2074,15 +2250,13 @@ static napi_value DecodeString16(napi_env env, napi_callback_info info)
|
|
|
2074
2250
|
if (count >= 2) {
|
|
2075
2251
|
Size len;
|
|
2076
2252
|
if (!TryNumber(env, args[1], &len)) [[unlikely]] {
|
|
2077
|
-
InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
|
|
2078
|
-
|
|
2079
2253
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for length, expected number", GetValueType(instance, args[1]));
|
|
2080
2254
|
return Napi::Env(env).Null();
|
|
2081
2255
|
}
|
|
2082
2256
|
|
|
2083
|
-
return
|
|
2257
|
+
return NewString(env, (const char16_t *)ptr, (size_t)len);
|
|
2084
2258
|
} else {
|
|
2085
|
-
return
|
|
2259
|
+
return NewString(env, (const char16_t *)ptr);
|
|
2086
2260
|
}
|
|
2087
2261
|
}
|
|
2088
2262
|
|
|
@@ -2090,9 +2264,9 @@ static napi_value DecodeString32(napi_env env, napi_callback_info info)
|
|
|
2090
2264
|
{
|
|
2091
2265
|
napi_value args[2];
|
|
2092
2266
|
size_t count = 2;
|
|
2267
|
+
InstanceData *instance;
|
|
2093
2268
|
|
|
2094
|
-
|
|
2095
|
-
K_ASSERT(status == napi_ok);
|
|
2269
|
+
NAPI_OK(napi_get_cb_info(env, info, &count, args, nullptr, (void **)&instance));
|
|
2096
2270
|
|
|
2097
2271
|
if (count < 1) [[unlikely]] {
|
|
2098
2272
|
ThrowError<Napi::TypeError>(env, "Expected 1 to 2 arguments, got %1", count);
|
|
@@ -2101,8 +2275,6 @@ static napi_value DecodeString32(napi_env env, napi_callback_info info)
|
|
|
2101
2275
|
|
|
2102
2276
|
void *ptr = nullptr;
|
|
2103
2277
|
if (!TryPointer(env, args[0], &ptr)) [[unlikely]] {
|
|
2104
|
-
InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
|
|
2105
|
-
|
|
2106
2278
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, args[0]));
|
|
2107
2279
|
return Napi::Env(env).Null();
|
|
2108
2280
|
}
|
|
@@ -2110,21 +2282,20 @@ static napi_value DecodeString32(napi_env env, napi_callback_info info)
|
|
|
2110
2282
|
if (count >= 2) {
|
|
2111
2283
|
Size len;
|
|
2112
2284
|
if (!TryNumber(env, args[1], &len)) [[unlikely]] {
|
|
2113
|
-
InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
|
|
2114
|
-
|
|
2115
2285
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for length, expected number", GetValueType(instance, args[1]));
|
|
2116
2286
|
return Napi::Env(env).Null();
|
|
2117
2287
|
}
|
|
2118
2288
|
|
|
2119
|
-
return
|
|
2289
|
+
return NewString(env, (const char32_t *)ptr, len);
|
|
2120
2290
|
} else {
|
|
2121
|
-
return
|
|
2291
|
+
return NewString(env, (const char32_t *)ptr);
|
|
2122
2292
|
}
|
|
2123
2293
|
}
|
|
2124
2294
|
|
|
2125
2295
|
static Napi::Value GetPointerAddress(const Napi::CallbackInfo &info)
|
|
2126
2296
|
{
|
|
2127
2297
|
Napi::Env env = info.Env();
|
|
2298
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
2128
2299
|
|
|
2129
2300
|
if (info.Length() < 1) {
|
|
2130
2301
|
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
|
|
@@ -2133,8 +2304,6 @@ static Napi::Value GetPointerAddress(const Napi::CallbackInfo &info)
|
|
|
2133
2304
|
|
|
2134
2305
|
void *ptr = nullptr;
|
|
2135
2306
|
if (!TryPointer(env, info[0], &ptr)) {
|
|
2136
|
-
InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
|
|
2137
|
-
|
|
2138
2307
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, info[0]));
|
|
2139
2308
|
return env.Null();
|
|
2140
2309
|
}
|
|
@@ -2148,6 +2317,7 @@ static Napi::Value GetPointerAddress(const Napi::CallbackInfo &info)
|
|
|
2148
2317
|
static Napi::Value CallPointerSync(const Napi::CallbackInfo &info)
|
|
2149
2318
|
{
|
|
2150
2319
|
Napi::Env env = info.Env();
|
|
2320
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
2151
2321
|
|
|
2152
2322
|
if (info.Length() < 2) [[unlikely]] {
|
|
2153
2323
|
ThrowError<Napi::TypeError>(env, "Expected 2 or more arguments, got %1", info.Length());
|
|
@@ -2156,18 +2326,14 @@ static Napi::Value CallPointerSync(const Napi::CallbackInfo &info)
|
|
|
2156
2326
|
|
|
2157
2327
|
void *ptr = nullptr;
|
|
2158
2328
|
if (!TryPointer(env, info[0], &ptr)) {
|
|
2159
|
-
InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
|
|
2160
|
-
|
|
2161
2329
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, info[0]));
|
|
2162
2330
|
return env.Null();
|
|
2163
2331
|
}
|
|
2164
2332
|
|
|
2165
|
-
const TypeInfo *type = ResolveType(info[1]);
|
|
2333
|
+
const TypeInfo *type = ResolveType(instance, info[1]);
|
|
2166
2334
|
if (!type) [[unlikely]]
|
|
2167
2335
|
return env.Null();
|
|
2168
2336
|
if (type->primitive != PrimitiveKind::Prototype) [[unlikely]] {
|
|
2169
|
-
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
2170
|
-
|
|
2171
2337
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for type, expected function type", GetValueType(instance, info[1]));
|
|
2172
2338
|
return env.Null();
|
|
2173
2339
|
}
|
|
@@ -2179,6 +2345,7 @@ static Napi::Value CallPointerSync(const Napi::CallbackInfo &info)
|
|
|
2179
2345
|
static Napi::Value EncodeValue(const Napi::CallbackInfo &info)
|
|
2180
2346
|
{
|
|
2181
2347
|
Napi::Env env = info.Env();
|
|
2348
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
2182
2349
|
|
|
2183
2350
|
bool has_offset = (info.Length() >= 2 && info[1].IsNumber());
|
|
2184
2351
|
bool has_len = (info.Length() >= 4u + has_offset && info[3 + has_offset].IsNumber());
|
|
@@ -2188,7 +2355,7 @@ static Napi::Value EncodeValue(const Napi::CallbackInfo &info)
|
|
|
2188
2355
|
return env.Null();
|
|
2189
2356
|
}
|
|
2190
2357
|
|
|
2191
|
-
const TypeInfo *type = ResolveType(info[1u + has_offset]);
|
|
2358
|
+
const TypeInfo *type = ResolveType(instance, info[1u + has_offset]);
|
|
2192
2359
|
if (!type) [[unlikely]]
|
|
2193
2360
|
return env.Null();
|
|
2194
2361
|
|
|
@@ -2196,38 +2363,71 @@ static Napi::Value EncodeValue(const Napi::CallbackInfo &info)
|
|
|
2196
2363
|
int64_t offset = has_offset ? info[1].As<Napi::Number>().Int64Value() : 0;
|
|
2197
2364
|
Napi::Value value = info[2 + has_offset];
|
|
2198
2365
|
|
|
2199
|
-
|
|
2200
|
-
|
|
2366
|
+
void *dest = nullptr;
|
|
2367
|
+
Size len = 0;
|
|
2201
2368
|
|
|
2202
|
-
|
|
2369
|
+
if (!TryPointer(env, ref, &dest, &len)) {
|
|
2370
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for reference, expected pointer", GetValueType(instance, ref));
|
|
2371
|
+
return env.Null();
|
|
2372
|
+
}
|
|
2373
|
+
|
|
2374
|
+
if (len >= 0) {
|
|
2375
|
+
if (offset < 0) [[unlikely]] {
|
|
2376
|
+
ThrowError<Napi::Error>(env, "Offset must be >= 0");
|
|
2203
2377
|
return env.Null();
|
|
2204
|
-
|
|
2205
|
-
if (
|
|
2378
|
+
}
|
|
2379
|
+
if (len - offset < type->size) [[unlikely]] {
|
|
2380
|
+
ThrowError<Napi::Error>(env, "Expected buffer with size superior or equal to type %1 (%2 bytes)",
|
|
2381
|
+
type->name, type->size + offset);
|
|
2206
2382
|
return env.Null();
|
|
2383
|
+
}
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
if (!dest) [[unlikely]] {
|
|
2387
|
+
ThrowError<Napi::Error>(env, "Cannot encode data in NULL pointer");
|
|
2388
|
+
return env.Null();
|
|
2389
|
+
}
|
|
2390
|
+
|
|
2391
|
+
dest = (void *)((uint8_t *)dest + offset);
|
|
2392
|
+
|
|
2393
|
+
if (has_len) {
|
|
2394
|
+
Size len = info[3 + has_offset].As<Napi::Number>();
|
|
2395
|
+
|
|
2396
|
+
if (type->primitive != PrimitiveKind::String &&
|
|
2397
|
+
type->primitive != PrimitiveKind::String16 &&
|
|
2398
|
+
type->primitive != PrimitiveKind::String32 &&
|
|
2399
|
+
type->primitive != PrimitiveKind::Prototype) {
|
|
2400
|
+
if (len < 0) [[unlikely]] {
|
|
2401
|
+
ThrowError<Napi::TypeError>(env, "Automatic (negative) length is only supported when decoding");
|
|
2402
|
+
return env.Null();
|
|
2403
|
+
}
|
|
2404
|
+
|
|
2405
|
+
type = MakeArrayType(instance, type, len);
|
|
2406
|
+
}
|
|
2207
2407
|
}
|
|
2208
2408
|
|
|
2409
|
+
if (!Encode(instance, (uint8_t *)dest, value, type))
|
|
2410
|
+
return env.Null();
|
|
2411
|
+
|
|
2209
2412
|
return env.Undefined();
|
|
2210
2413
|
}
|
|
2211
2414
|
|
|
2212
2415
|
static Napi::Value CreateView(const Napi::CallbackInfo &info)
|
|
2213
2416
|
{
|
|
2214
2417
|
Napi::Env env = info.Env();
|
|
2418
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
2215
2419
|
|
|
2216
2420
|
if (info.Length() < 1) {
|
|
2217
2421
|
ThrowError<Napi::TypeError>(env, "Expected 2 arguments, got %1", info.Length());
|
|
2218
2422
|
return env.Null();
|
|
2219
2423
|
}
|
|
2220
2424
|
if (!info[1].IsNumber()) {
|
|
2221
|
-
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
2222
|
-
|
|
2223
2425
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for length, expected integer", GetValueType(instance, info[1]));
|
|
2224
2426
|
return env.Null();
|
|
2225
2427
|
}
|
|
2226
2428
|
|
|
2227
2429
|
void *ptr = nullptr;
|
|
2228
2430
|
if (!TryPointer(env, info[0], &ptr)) {
|
|
2229
|
-
InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
|
|
2230
|
-
|
|
2231
2431
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, info[0]));
|
|
2232
2432
|
return env.Null();
|
|
2233
2433
|
}
|
|
@@ -2256,7 +2456,7 @@ static Napi::Value CreateView(const Napi::CallbackInfo &info)
|
|
|
2256
2456
|
static Napi::Value ResetKoffi(const Napi::CallbackInfo &info)
|
|
2257
2457
|
{
|
|
2258
2458
|
Napi::Env env = info.Env();
|
|
2259
|
-
InstanceData *instance =
|
|
2459
|
+
InstanceData *instance = (InstanceData *)info.Data();
|
|
2260
2460
|
|
|
2261
2461
|
if (instance->broker) {
|
|
2262
2462
|
napi_release_threadsafe_function(instance->broker, napi_tsfn_abort);
|
|
@@ -2309,7 +2509,7 @@ void LibraryHolder::Unload()
|
|
|
2309
2509
|
|
|
2310
2510
|
ValueCast::~ValueCast()
|
|
2311
2511
|
{
|
|
2312
|
-
|
|
2512
|
+
node_api_delete_reference(env, ref);
|
|
2313
2513
|
}
|
|
2314
2514
|
|
|
2315
2515
|
FunctionInfo::~FunctionInfo()
|
|
@@ -2338,16 +2538,15 @@ InstanceMemory::~InstanceMemory()
|
|
|
2338
2538
|
#endif
|
|
2339
2539
|
}
|
|
2340
2540
|
|
|
2341
|
-
static void RegisterPrimitiveType(
|
|
2541
|
+
static void RegisterPrimitiveType(InstanceData *instance, Napi::Object map, std::initializer_list<const char *> names,
|
|
2342
2542
|
PrimitiveKind primitive, int32_t size, int16_t align, const char *ref = nullptr)
|
|
2343
2543
|
{
|
|
2344
2544
|
K_ASSERT(names.size() > 0);
|
|
2345
2545
|
K_ASSERT(align <= size);
|
|
2346
2546
|
|
|
2347
|
-
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
2348
|
-
|
|
2349
2547
|
TypeInfo *type = instance->types.AppendDefault();
|
|
2350
2548
|
|
|
2549
|
+
type->instance = instance;
|
|
2351
2550
|
type->name = *names.begin();
|
|
2352
2551
|
|
|
2353
2552
|
type->primitive = primitive;
|
|
@@ -2369,7 +2568,7 @@ static void RegisterPrimitiveType(Napi::Env env, Napi::Object map, std::initiali
|
|
|
2369
2568
|
K_ASSERT(type->ref.type);
|
|
2370
2569
|
}
|
|
2371
2570
|
|
|
2372
|
-
|
|
2571
|
+
napi_value wrapper = WrapType(instance, type);
|
|
2373
2572
|
|
|
2374
2573
|
for (const char *name: names) {
|
|
2375
2574
|
bool inserted;
|
|
@@ -2428,12 +2627,12 @@ static bool CanCallNapiGetBufferInfoDirectly(const napi_node_version &node, uint
|
|
|
2428
2627
|
return false;
|
|
2429
2628
|
}
|
|
2430
2629
|
|
|
2431
|
-
static bool CanReferencePrimitiveValues(const napi_node_version
|
|
2630
|
+
static bool CanReferencePrimitiveValues(const napi_node_version &, uint32_t napi)
|
|
2432
2631
|
{
|
|
2433
2632
|
return napi >= 10;
|
|
2434
2633
|
}
|
|
2435
2634
|
|
|
2436
|
-
static bool CanDeleteReferenceInFinalizer(const napi_node_version &node, uint32_t
|
|
2635
|
+
static bool CanDeleteReferenceInFinalizer(const napi_node_version &node, uint32_t)
|
|
2437
2636
|
{
|
|
2438
2637
|
if (node.major >= 24)
|
|
2439
2638
|
return true;
|
|
@@ -2451,12 +2650,12 @@ static bool CanDeleteReferenceInFinalizer(const napi_node_version &node, uint32_
|
|
|
2451
2650
|
return false;
|
|
2452
2651
|
}
|
|
2453
2652
|
|
|
2454
|
-
static napi_value CreateFunction(
|
|
2653
|
+
static napi_value CreateFunction(InstanceData *instance, napi_callback native, const char *name = nullptr)
|
|
2455
2654
|
{
|
|
2456
|
-
|
|
2655
|
+
Napi::Env env = instance->env;
|
|
2457
2656
|
|
|
2458
|
-
|
|
2459
|
-
|
|
2657
|
+
napi_value func;
|
|
2658
|
+
NAPI_OK(napi_create_function(env, name, NAPI_AUTO_LENGTH, native, instance, &func));
|
|
2460
2659
|
|
|
2461
2660
|
return func;
|
|
2462
2661
|
}
|
|
@@ -2508,6 +2707,21 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
|
|
|
2508
2707
|
// errors out (or even asserts) if it gets called in a finalizer. In this case,
|
|
2509
2708
|
// use experimental API to try to run it later.
|
|
2510
2709
|
node_api_post_finalizer = SYMBOL(node_api_post_finalizer);
|
|
2710
|
+
|
|
2711
|
+
if (node_api_post_finalizer) {
|
|
2712
|
+
node_api_delete_reference = [](node_api_basic_env env, napi_ref ref) {
|
|
2713
|
+
node_api_post_finalizer((napi_env)env, [](napi_env env, void *data, void *) {
|
|
2714
|
+
napi_ref ref = (napi_ref)data;
|
|
2715
|
+
napi_delete_reference(env, ref);
|
|
2716
|
+
}, (void *)ref, nullptr);
|
|
2717
|
+
|
|
2718
|
+
return napi_ok;
|
|
2719
|
+
};
|
|
2720
|
+
} else {
|
|
2721
|
+
node_api_delete_reference = napi_delete_reference;
|
|
2722
|
+
}
|
|
2723
|
+
} else {
|
|
2724
|
+
node_api_delete_reference = napi_delete_reference;
|
|
2511
2725
|
}
|
|
2512
2726
|
|
|
2513
2727
|
node_api_create_object_with_properties = SYMBOL(node_api_create_object_with_properties);
|
|
@@ -2520,85 +2734,102 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
|
|
|
2520
2734
|
K_CRITICAL(instance, "Failed to initialize Koffi");
|
|
2521
2735
|
|
|
2522
2736
|
instance->env = env;
|
|
2523
|
-
env.SetInstanceData(instance);
|
|
2524
2737
|
|
|
2525
2738
|
#if defined(__clang__)
|
|
2526
2739
|
// First call to napi_create_double() does some weird stuff I can't explain
|
|
2527
2740
|
// in clang-cl builds. I don't like this... but this fixes it, somehow ><
|
|
2528
|
-
|
|
2741
|
+
NewFloat(env, 0.0);
|
|
2529
2742
|
#endif
|
|
2530
2743
|
|
|
2531
|
-
exports.Set("config", Napi::Function::New(env, GetSetConfig, "config"));
|
|
2532
|
-
exports.Set("stats", Napi::Function::New(env, GetStats, "stats"));
|
|
2533
|
-
|
|
2534
|
-
exports.Set("struct", Napi::Function::New(env, CreatePaddedStructType, "struct"));
|
|
2535
|
-
exports.Set("pack", Napi::Function::New(env, CreatePackedStructType, "pack"));
|
|
2536
|
-
exports.Set("union", Napi::Function::New(env, CreateUnionType, "union"));
|
|
2537
|
-
exports.Set("Union", Napi::Function::New(env, InstantiateUnion, "Union"));
|
|
2538
|
-
exports.Set("opaque", Napi::Function::New(env, CreateOpaqueType, "opaque"));
|
|
2539
|
-
exports.Set("pointer", Napi::Function::New(env, CreatePointerType, "pointer"));
|
|
2540
|
-
exports.Set("array", Napi::Function::New(env, CreateArrayType, "array"));
|
|
2541
|
-
exports.Set("proto", Napi::Function::New(env, CreateFunctionType, "proto"));
|
|
2542
|
-
exports.Set("alias", Napi::Function::New(env, CreateTypeAlias, "alias"));
|
|
2543
|
-
exports.Set("enumeration", Napi::Function::New(env, CreateEnumType, "enumeration"));
|
|
2544
|
-
|
|
2545
|
-
exports.Set("type", Napi::Function::New(env, GetResolvedType, "type"));
|
|
2744
|
+
exports.Set("config", Napi::Function::New(env, GetSetConfig, "config", instance));
|
|
2745
|
+
exports.Set("stats", Napi::Function::New(env, GetStats, "stats", instance));
|
|
2746
|
+
|
|
2747
|
+
exports.Set("struct", Napi::Function::New(env, CreatePaddedStructType, "struct", instance));
|
|
2748
|
+
exports.Set("pack", Napi::Function::New(env, CreatePackedStructType, "pack", instance));
|
|
2749
|
+
exports.Set("union", Napi::Function::New(env, CreateUnionType, "union", instance));
|
|
2750
|
+
exports.Set("Union", Napi::Function::New(env, InstantiateUnion, "Union", instance));
|
|
2751
|
+
exports.Set("opaque", Napi::Function::New(env, CreateOpaqueType, "opaque", instance));
|
|
2752
|
+
exports.Set("pointer", Napi::Function::New(env, CreatePointerType, "pointer", instance));
|
|
2753
|
+
exports.Set("array", Napi::Function::New(env, CreateArrayType, "array", instance));
|
|
2754
|
+
exports.Set("proto", Napi::Function::New(env, CreateFunctionType, "proto", instance));
|
|
2755
|
+
exports.Set("alias", Napi::Function::New(env, CreateTypeAlias, "alias", instance));
|
|
2756
|
+
exports.Set("enumeration", Napi::Function::New(env, CreateEnumType, "enumeration", instance));
|
|
2757
|
+
|
|
2758
|
+
exports.Set("type", Napi::Function::New(env, GetResolvedType, "type", instance));
|
|
2546
2759
|
#if defined(EXTERNAL_TYPES)
|
|
2547
|
-
exports.Set("introspect", Napi::Function::New(env, GetTypeDefinition, "introspect"));
|
|
2760
|
+
exports.Set("introspect", Napi::Function::New(env, GetTypeDefinition, "introspect", instance));
|
|
2548
2761
|
#endif
|
|
2549
2762
|
|
|
2550
|
-
exports.Set("load", Napi::Function::New(env, LoadSharedLibrary, "load"));
|
|
2763
|
+
exports.Set("load", Napi::Function::New(env, LoadSharedLibrary, "load", instance));
|
|
2551
2764
|
|
|
2552
|
-
exports.Set("in", Napi::Function::New(env, MarkIn, "in"));
|
|
2553
|
-
exports.Set("out", Napi::Function::New(env, MarkOut, "out"));
|
|
2554
|
-
exports.Set("inout", Napi::Function::New(env, MarkInOut, "inout"));
|
|
2765
|
+
exports.Set("in", Napi::Function::New(env, MarkIn, "in", instance));
|
|
2766
|
+
exports.Set("out", Napi::Function::New(env, MarkOut, "out", instance));
|
|
2767
|
+
exports.Set("inout", Napi::Function::New(env, MarkInOut, "inout", instance));
|
|
2555
2768
|
|
|
2556
|
-
exports.Set("disposable", Napi::Function::New(env, CreateDisposableType, "disposable"));
|
|
2557
|
-
exports.Set("alloc", Napi::Function::New(env, CallAlloc, "alloc"));
|
|
2558
|
-
exports.Set("free", Napi::Function::New(env, CallFree, "free"));
|
|
2769
|
+
exports.Set("disposable", Napi::Function::New(env, CreateDisposableType, "disposable", instance));
|
|
2770
|
+
exports.Set("alloc", Napi::Function::New(env, CallAlloc, "alloc", instance));
|
|
2771
|
+
exports.Set("free", Napi::Function::New(env, CallFree, "free", instance));
|
|
2559
2772
|
|
|
2560
|
-
exports.Set("register", Napi::Function::New(env, RegisterCallback, "register"));
|
|
2561
|
-
exports.Set("unregister", Napi::Function::New(env, UnregisterCallback, "unregister"));
|
|
2773
|
+
exports.Set("register", Napi::Function::New(env, RegisterCallback, "register", instance));
|
|
2774
|
+
exports.Set("unregister", Napi::Function::New(env, UnregisterCallback, "unregister", instance));
|
|
2562
2775
|
|
|
2563
|
-
exports.Set("as", Napi::Function::New(env, CastValue, "as"));
|
|
2564
|
-
exports.Set("address", Napi::Function::New(env, GetPointerAddress, "address"));
|
|
2565
|
-
exports.Set("call", Napi::Function::New(env, CallPointerSync, "call"));
|
|
2566
|
-
exports.Set("encode", Napi::Function::New(env, EncodeValue, "encode"));
|
|
2567
|
-
exports.Set("view", Napi::Function::New(env, CreateView, "view"));
|
|
2776
|
+
exports.Set("as", Napi::Function::New(env, CastValue, "as", instance));
|
|
2777
|
+
exports.Set("address", Napi::Function::New(env, GetPointerAddress, "address", instance));
|
|
2778
|
+
exports.Set("call", Napi::Function::New(env, CallPointerSync, "call", instance));
|
|
2779
|
+
exports.Set("encode", Napi::Function::New(env, EncodeValue, "encode", instance));
|
|
2780
|
+
exports.Set("view", Napi::Function::New(env, CreateView, "view", instance));
|
|
2568
2781
|
|
|
2569
2782
|
{
|
|
2570
|
-
Napi::Function decode = Napi::Function::New(env, DecodeValue, "decode");
|
|
2571
|
-
|
|
2572
|
-
decode.Set("char", CreateFunction(
|
|
2573
|
-
decode.Set("uchar", CreateFunction(
|
|
2574
|
-
decode.Set("short", CreateFunction(
|
|
2575
|
-
decode.Set("ushort", CreateFunction(
|
|
2576
|
-
decode.Set("int", CreateFunction(
|
|
2577
|
-
decode.Set("uint", CreateFunction(
|
|
2578
|
-
decode.Set("long", CreateFunction(
|
|
2579
|
-
decode.Set("ulong", CreateFunction(
|
|
2580
|
-
decode.Set("longlong", CreateFunction(
|
|
2581
|
-
decode.Set("ulonglong", CreateFunction(
|
|
2582
|
-
decode.Set("int8", CreateFunction(
|
|
2583
|
-
decode.Set("uint8", CreateFunction(
|
|
2584
|
-
decode.Set("int16", CreateFunction(
|
|
2585
|
-
decode.Set("
|
|
2586
|
-
decode.Set("
|
|
2587
|
-
decode.Set("
|
|
2588
|
-
decode.Set("
|
|
2589
|
-
decode.Set("
|
|
2590
|
-
decode.Set("
|
|
2591
|
-
decode.Set("
|
|
2592
|
-
decode.Set("
|
|
2593
|
-
decode.Set("
|
|
2594
|
-
decode.Set("
|
|
2783
|
+
Napi::Function decode = Napi::Function::New(env, DecodeValue, "decode", instance);
|
|
2784
|
+
|
|
2785
|
+
decode.Set("char", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<char>(env, info); }, "char"));
|
|
2786
|
+
decode.Set("uchar", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<unsigned char>(env, info); }, "uchar"));
|
|
2787
|
+
decode.Set("short", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<short>(env, info); }, "short"));
|
|
2788
|
+
decode.Set("ushort", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<unsigned short>(env, info); }, "ushort"));
|
|
2789
|
+
decode.Set("int", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<int>(env, info); }, "int"));
|
|
2790
|
+
decode.Set("uint", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<unsigned int>(env, info); }, "uint"));
|
|
2791
|
+
decode.Set("long", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<long>(env, info); }, "long"));
|
|
2792
|
+
decode.Set("ulong", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<unsigned long>(env, info); }, "ulong"));
|
|
2793
|
+
decode.Set("longlong", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<long long>(env, info); }, "longlong"));
|
|
2794
|
+
decode.Set("ulonglong", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<unsigned long long>(env, info); }, "ulonglong"));
|
|
2795
|
+
decode.Set("int8", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<int8_t>(env, info); }, "int8"));
|
|
2796
|
+
decode.Set("uint8", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<uint8_t>(env, info); }, "uint8"));
|
|
2797
|
+
decode.Set("int16", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<int16_t>(env, info); }, "int16"));
|
|
2798
|
+
decode.Set("int16le", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerLE<int16_t>(env, info); }, "int16le"));
|
|
2799
|
+
decode.Set("int16be", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerBE<int16_t>(env, info); }, "int16be"));
|
|
2800
|
+
decode.Set("uint16", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<uint16_t>(env, info); }, "uint16"));
|
|
2801
|
+
decode.Set("uint16le", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerLE<uint16_t>(env, info); }, "uint16le"));
|
|
2802
|
+
decode.Set("uint16be", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerBE<uint16_t>(env, info); }, "uint16be"));
|
|
2803
|
+
decode.Set("int32", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<int32_t>(env, info); }, "int32"));
|
|
2804
|
+
decode.Set("int32le", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerLE<int32_t>(env, info); }, "int32le"));
|
|
2805
|
+
decode.Set("int32be", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerBE<int32_t>(env, info); }, "int32be"));
|
|
2806
|
+
decode.Set("uint32", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<uint32_t>(env, info); }, "uint32"));
|
|
2807
|
+
decode.Set("uint32le", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerLE<uint32_t>(env, info); }, "uint32le"));
|
|
2808
|
+
decode.Set("uint32be", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerBE<uint32_t>(env, info); }, "uint32be"));
|
|
2809
|
+
decode.Set("int64", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<int64_t>(env, info); }, "int64"));
|
|
2810
|
+
decode.Set("int64le", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerLE<int64_t>(env, info); }, "int64le"));
|
|
2811
|
+
decode.Set("int64be", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerBE<int64_t>(env, info); }, "int64be"));
|
|
2812
|
+
decode.Set("uint64", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<uint64_t>(env, info); }, "uint64"));
|
|
2813
|
+
decode.Set("uint64le", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerLE<uint64_t>(env, info); }, "uint64le"));
|
|
2814
|
+
decode.Set("uint64be", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerBE<uint64_t>(env, info); }, "uint64be"));
|
|
2815
|
+
decode.Set("float", CreateFunction(instance, DecodeFloat, "float"));
|
|
2816
|
+
decode.Set("double", CreateFunction(instance, DecodeDouble, "double"));
|
|
2817
|
+
decode.Set("string", CreateFunction(instance, DecodeString, "string"));
|
|
2818
|
+
decode.Set("string16", CreateFunction(instance, DecodeString16, "string16"));
|
|
2819
|
+
decode.Set("string32", CreateFunction(instance, DecodeString32, "string32"));
|
|
2820
|
+
if constexpr (K_SIZE(wchar_t) == 2) {
|
|
2821
|
+
decode.Set("wstring", CreateFunction(instance, DecodeString16, "wstring"));
|
|
2822
|
+
} else if constexpr (K_SIZE(wchar_t) == 4) {
|
|
2823
|
+
decode.Set("wstring", CreateFunction(instance, DecodeString32, "wstring"));
|
|
2824
|
+
}
|
|
2825
|
+
static_assert(K_SIZE(wchar_t) == 2 || K_SIZE(wchar_t) == 4);
|
|
2595
2826
|
|
|
2596
2827
|
exports.Set("decode", decode);
|
|
2597
2828
|
}
|
|
2598
2829
|
|
|
2599
|
-
exports.Set("reset", Napi::Function::New(env, ResetKoffi, "reset"));
|
|
2830
|
+
exports.Set("reset", Napi::Function::New(env, ResetKoffi, "reset", instance));
|
|
2600
2831
|
|
|
2601
|
-
exports.Set("errno", Napi::Function::New(env, GetOrSetErrNo, "errno"));
|
|
2832
|
+
exports.Set("errno", Napi::Function::New(env, GetOrSetErrNo, "errno", instance));
|
|
2602
2833
|
|
|
2603
2834
|
// Export useful OS info
|
|
2604
2835
|
{
|
|
@@ -2615,21 +2846,21 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
|
|
|
2615
2846
|
}
|
|
2616
2847
|
|
|
2617
2848
|
#if defined(_WIN32)
|
|
2618
|
-
exports.Set("extension",
|
|
2849
|
+
exports.Set("extension", NewString(env, ".dll"));
|
|
2619
2850
|
#elif defined(__APPLE__)
|
|
2620
|
-
exports.Set("extension",
|
|
2851
|
+
exports.Set("extension", NewString(env, ".dylib"));
|
|
2621
2852
|
#else
|
|
2622
|
-
exports.Set("extension",
|
|
2853
|
+
exports.Set("extension", NewString(env, ".so"));
|
|
2623
2854
|
#endif
|
|
2624
2855
|
|
|
2625
2856
|
// Init object classes and symbols
|
|
2626
2857
|
{
|
|
2627
2858
|
instance->object_constructor = Napi::Persistent(env.RunScript("Object.prototype").As<Napi::Object>());
|
|
2628
|
-
instance->construct_lib = Napi::Persistent(LibraryHandle::InitClass(
|
|
2859
|
+
instance->construct_lib = Napi::Persistent(LibraryHandle::InitClass(instance));
|
|
2629
2860
|
#if !defined(EXTERNAL_TYPES)
|
|
2630
|
-
instance->construct_type = Napi::Persistent(TypeObject::InitClass(
|
|
2861
|
+
instance->construct_type = Napi::Persistent(TypeObject::InitClass(instance));
|
|
2631
2862
|
#endif
|
|
2632
|
-
instance->construct_poll = Napi::Persistent(PollHandle::InitClass(
|
|
2863
|
+
instance->construct_poll = Napi::Persistent(PollHandle::InitClass(instance));
|
|
2633
2864
|
instance->active_symbol = Napi::Persistent(Napi::Symbol::New(env, "active"));
|
|
2634
2865
|
|
|
2635
2866
|
exports.Set("LibraryHandle", instance->construct_lib.Value());
|
|
@@ -2643,58 +2874,59 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
|
|
|
2643
2874
|
Napi::Object types = Napi::Object::New(env);
|
|
2644
2875
|
exports.Set("types", types);
|
|
2645
2876
|
|
|
2646
|
-
RegisterPrimitiveType(
|
|
2647
|
-
RegisterPrimitiveType(
|
|
2648
|
-
RegisterPrimitiveType(
|
|
2649
|
-
RegisterPrimitiveType(
|
|
2650
|
-
RegisterPrimitiveType(
|
|
2651
|
-
RegisterPrimitiveType(
|
|
2652
|
-
RegisterPrimitiveType(
|
|
2653
|
-
RegisterPrimitiveType(
|
|
2654
|
-
if (K_SIZE(wchar_t) == 2) {
|
|
2655
|
-
RegisterPrimitiveType(
|
|
2656
|
-
} else if (K_SIZE(wchar_t) == 4) {
|
|
2657
|
-
RegisterPrimitiveType(
|
|
2658
|
-
}
|
|
2659
|
-
RegisterPrimitiveType(
|
|
2660
|
-
RegisterPrimitiveType(
|
|
2661
|
-
RegisterPrimitiveType(
|
|
2662
|
-
RegisterPrimitiveType(
|
|
2663
|
-
RegisterPrimitiveType(
|
|
2664
|
-
RegisterPrimitiveType(
|
|
2665
|
-
RegisterPrimitiveType(
|
|
2666
|
-
RegisterPrimitiveType(
|
|
2667
|
-
RegisterPrimitiveType(
|
|
2668
|
-
RegisterPrimitiveType(
|
|
2669
|
-
RegisterPrimitiveType(
|
|
2670
|
-
RegisterPrimitiveType(
|
|
2671
|
-
RegisterPrimitiveType(
|
|
2672
|
-
RegisterPrimitiveType(
|
|
2673
|
-
RegisterPrimitiveType(
|
|
2674
|
-
RegisterPrimitiveType(
|
|
2675
|
-
RegisterPrimitiveType(
|
|
2676
|
-
RegisterPrimitiveType(
|
|
2677
|
-
RegisterPrimitiveType(
|
|
2678
|
-
RegisterPrimitiveType(
|
|
2679
|
-
RegisterPrimitiveType(
|
|
2680
|
-
RegisterPrimitiveType(
|
|
2681
|
-
RegisterPrimitiveType(
|
|
2682
|
-
RegisterPrimitiveType(
|
|
2683
|
-
RegisterPrimitiveType(
|
|
2684
|
-
RegisterPrimitiveType(
|
|
2685
|
-
RegisterPrimitiveType(
|
|
2686
|
-
RegisterPrimitiveType(
|
|
2687
|
-
RegisterPrimitiveType(
|
|
2688
|
-
RegisterPrimitiveType(
|
|
2689
|
-
RegisterPrimitiveType(
|
|
2690
|
-
RegisterPrimitiveType(
|
|
2691
|
-
RegisterPrimitiveType(
|
|
2692
|
-
RegisterPrimitiveType(
|
|
2693
|
-
if (K_SIZE(wchar_t) == 2) {
|
|
2694
|
-
RegisterPrimitiveType(
|
|
2695
|
-
} else if (K_SIZE(wchar_t) == 4) {
|
|
2696
|
-
RegisterPrimitiveType(
|
|
2877
|
+
RegisterPrimitiveType(instance, types, {"void"}, PrimitiveKind::Void, 0, 0);
|
|
2878
|
+
RegisterPrimitiveType(instance, types, {"bool"}, PrimitiveKind::Bool, K_SIZE(bool), alignof(bool));
|
|
2879
|
+
RegisterPrimitiveType(instance, types, {"int8_t", "int8"}, PrimitiveKind::Int8, 1, 1);
|
|
2880
|
+
RegisterPrimitiveType(instance, types, {"uint8_t", "uint8"}, PrimitiveKind::UInt8, 1, 1);
|
|
2881
|
+
RegisterPrimitiveType(instance, types, {"char"}, PrimitiveKind::Int8, 1, 1);
|
|
2882
|
+
RegisterPrimitiveType(instance, types, {"unsigned char", "uchar"}, PrimitiveKind::UInt8, 1, 1);
|
|
2883
|
+
RegisterPrimitiveType(instance, types, {"char16_t", "char16"}, PrimitiveKind::Int16, 2, 2);
|
|
2884
|
+
RegisterPrimitiveType(instance, types, {"char32_t", "char32"}, PrimitiveKind::Int32, 4, 4);
|
|
2885
|
+
if constexpr (K_SIZE(wchar_t) == 2) {
|
|
2886
|
+
RegisterPrimitiveType(instance, types, {"wchar_t", "wchar"}, PrimitiveKind::Int16, 2, 2);
|
|
2887
|
+
} else if constexpr (K_SIZE(wchar_t) == 4) {
|
|
2888
|
+
RegisterPrimitiveType(instance, types, {"wchar_t", "wchar"}, PrimitiveKind::Int32, 4, 4);
|
|
2889
|
+
}
|
|
2890
|
+
RegisterPrimitiveType(instance, types, {"int16_t", "int16"}, PrimitiveKind::Int16, 2, 2);
|
|
2891
|
+
RegisterPrimitiveType(instance, types, {"int16_le_t", "int16_le"}, GetLittleEndianPrimitive(PrimitiveKind::Int16), 2, 2);
|
|
2892
|
+
RegisterPrimitiveType(instance, types, {"int16_be_t", "int16_be"}, GetBigEndianPrimitive(PrimitiveKind::Int16), 2, 2);
|
|
2893
|
+
RegisterPrimitiveType(instance, types, {"uint16_t", "uint16"}, PrimitiveKind::UInt16, 2, 2);
|
|
2894
|
+
RegisterPrimitiveType(instance, types, {"uint16_le_t", "uint16_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt16), 2, 2);
|
|
2895
|
+
RegisterPrimitiveType(instance, types, {"uint16_be_t", "uint16_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt16), 2, 2);
|
|
2896
|
+
RegisterPrimitiveType(instance, types, {"short"}, PrimitiveKind::Int16, 2, 2);
|
|
2897
|
+
RegisterPrimitiveType(instance, types, {"unsigned short", "ushort"}, PrimitiveKind::UInt16, 2, 2);
|
|
2898
|
+
RegisterPrimitiveType(instance, types, {"int32_t", "int32"}, PrimitiveKind::Int32, 4, 4);
|
|
2899
|
+
RegisterPrimitiveType(instance, types, {"int32_le_t", "int32_le"}, GetLittleEndianPrimitive(PrimitiveKind::Int32), 4, 4);
|
|
2900
|
+
RegisterPrimitiveType(instance, types, {"int32_be_t", "int32_be"}, GetBigEndianPrimitive(PrimitiveKind::Int32), 4, 4);
|
|
2901
|
+
RegisterPrimitiveType(instance, types, {"uint32_t", "uint32"}, PrimitiveKind::UInt32, 4, 4);
|
|
2902
|
+
RegisterPrimitiveType(instance, types, {"uint32_le_t", "uint32_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt32), 4, 4);
|
|
2903
|
+
RegisterPrimitiveType(instance, types, {"uint32_be_t", "uint32_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt32), 4, 4);
|
|
2904
|
+
RegisterPrimitiveType(instance, types, {"int"}, PrimitiveKind::Int32, 4, 4);
|
|
2905
|
+
RegisterPrimitiveType(instance, types, {"unsigned int", "uint"}, PrimitiveKind::UInt32, 4, 4);
|
|
2906
|
+
RegisterPrimitiveType(instance, types, {"int64_t", "int64"}, PrimitiveKind::Int64, 8, alignof(int64_t));
|
|
2907
|
+
RegisterPrimitiveType(instance, types, {"int64_le_t", "int64_le"}, GetLittleEndianPrimitive(PrimitiveKind::Int64), 8, alignof(int64_t));
|
|
2908
|
+
RegisterPrimitiveType(instance, types, {"int64_be_t", "int64_be"}, GetBigEndianPrimitive(PrimitiveKind::Int64), 8, alignof(int64_t));
|
|
2909
|
+
RegisterPrimitiveType(instance, types, {"uint64_t", "uint64"}, PrimitiveKind::UInt64, 8, alignof(int64_t));
|
|
2910
|
+
RegisterPrimitiveType(instance, types, {"uint64_le_t", "uint64_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt64), 8, alignof(int64_t));
|
|
2911
|
+
RegisterPrimitiveType(instance, types, {"uint64_be_t", "uint64_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt64), 8, alignof(int64_t));
|
|
2912
|
+
RegisterPrimitiveType(instance, types, {"intptr_t", "intptr"}, GetSignPrimitive(K_SIZE(intptr_t), true), K_SIZE(intptr_t), alignof(intptr_t));
|
|
2913
|
+
RegisterPrimitiveType(instance, types, {"uintptr_t", "uintptr"}, GetSignPrimitive(K_SIZE(intptr_t), false), K_SIZE(intptr_t), alignof(intptr_t));
|
|
2914
|
+
RegisterPrimitiveType(instance, types, {"size_t"}, GetSignPrimitive(K_SIZE(size_t), false), K_SIZE(size_t), alignof(size_t));
|
|
2915
|
+
RegisterPrimitiveType(instance, types, {"long"}, GetSignPrimitive(K_SIZE(long), true), K_SIZE(long), alignof(long));
|
|
2916
|
+
RegisterPrimitiveType(instance, types, {"unsigned long", "ulong"}, GetSignPrimitive(K_SIZE(long), false), K_SIZE(long), alignof(long));
|
|
2917
|
+
RegisterPrimitiveType(instance, types, {"long long", "longlong"}, PrimitiveKind::Int64, K_SIZE(int64_t), alignof(int64_t));
|
|
2918
|
+
RegisterPrimitiveType(instance, types, {"unsigned long long", "ulonglong"}, PrimitiveKind::UInt64, K_SIZE(uint64_t), alignof(uint64_t));
|
|
2919
|
+
RegisterPrimitiveType(instance, types, {"float", "float32"}, PrimitiveKind::Float32, 4, alignof(float));
|
|
2920
|
+
RegisterPrimitiveType(instance, types, {"double", "float64"}, PrimitiveKind::Float64, 8, alignof(double));
|
|
2921
|
+
RegisterPrimitiveType(instance, types, {"char *", "str", "string"}, PrimitiveKind::String, K_SIZE(void *), alignof(void *), "char");
|
|
2922
|
+
RegisterPrimitiveType(instance, types, {"char16_t *", "char16 *", "str16", "string16"}, PrimitiveKind::String16, K_SIZE(void *), alignof(void *), "char16_t");
|
|
2923
|
+
RegisterPrimitiveType(instance, types, {"char32_t *", "char32 *", "str32", "string32"}, PrimitiveKind::String32, K_SIZE(void *), alignof(void *), "char32_t");
|
|
2924
|
+
if constexpr (K_SIZE(wchar_t) == 2) {
|
|
2925
|
+
RegisterPrimitiveType(instance, types, {"wchar_t *", "wchar *", "wstring"}, PrimitiveKind::String16, K_SIZE(void *), alignof(void *), "wchar_t");
|
|
2926
|
+
} else if constexpr (K_SIZE(wchar_t) == 4) {
|
|
2927
|
+
RegisterPrimitiveType(instance, types, {"wchar_t *", "wchar *", "wstring"}, PrimitiveKind::String32, K_SIZE(void *), alignof(void *), "wchar_t");
|
|
2697
2928
|
}
|
|
2929
|
+
static_assert(K_SIZE(wchar_t) == 2 || K_SIZE(wchar_t) == 4);
|
|
2698
2930
|
|
|
2699
2931
|
instance->void_type = instance->types_map.FindValue("void", nullptr);
|
|
2700
2932
|
instance->char_type = instance->types_map.FindValue("char", nullptr);
|
|
@@ -2714,11 +2946,11 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
|
|
|
2714
2946
|
|
|
2715
2947
|
node.Set("env", WrapPointer(env, instance->void_type, (napi_env)env));
|
|
2716
2948
|
|
|
2717
|
-
node.Set("poll", Napi::Function::New(env, &Poll, "poll"));
|
|
2949
|
+
node.Set("poll", Napi::Function::New(env, &Poll, "poll", instance));
|
|
2718
2950
|
node.Set("PollHandle", instance->construct_poll.Value());
|
|
2719
2951
|
}
|
|
2720
2952
|
|
|
2721
|
-
exports.Set("version",
|
|
2953
|
+
exports.Set("version", NewString(env, K_STRINGIFY(VERSION)));
|
|
2722
2954
|
|
|
2723
2955
|
#if defined(_WIN32)
|
|
2724
2956
|
{
|
|
@@ -2729,7 +2961,6 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
|
|
|
2729
2961
|
}
|
|
2730
2962
|
#endif
|
|
2731
2963
|
|
|
2732
|
-
instance->translate_zero_call = translate_zero_call;
|
|
2733
2964
|
instance->main_thread_id = std::this_thread::get_id();
|
|
2734
2965
|
|
|
2735
2966
|
napi_add_env_cleanup_hook(env, [](void *udata) {
|
|
@@ -2764,7 +2995,7 @@ InstanceData::~InstanceData()
|
|
|
2764
2995
|
if (trampoline->instance == this) {
|
|
2765
2996
|
trampoline->instance = nullptr;
|
|
2766
2997
|
if (trampoline->func) {
|
|
2767
|
-
|
|
2998
|
+
node_api_delete_reference(env, trampoline->func);
|
|
2768
2999
|
trampoline->func = nullptr;
|
|
2769
3000
|
}
|
|
2770
3001
|
trampoline->state = 0;
|