koffi 1.3.12 → 2.0.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/CMakeLists.txt +7 -2
- package/ChangeLog.md +42 -16
- package/README.md +6 -0
- package/build/qemu/2.0.0/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_win32_x64.tar.gz +0 -0
- package/doc/benchmarks.md +2 -2
- package/doc/changes.md +156 -1
- package/doc/contribute.md +0 -1
- package/doc/dist/doctrees/changes.doctree +0 -0
- package/doc/dist/doctrees/environment.pickle +0 -0
- package/doc/dist/doctrees/functions.doctree +0 -0
- package/doc/dist/doctrees/types.doctree +0 -0
- package/doc/dist/html/_sources/changes.md.txt +156 -1
- package/doc/dist/html/_sources/functions.md.txt +8 -4
- package/doc/dist/html/_sources/types.md.txt +9 -0
- package/doc/dist/html/benchmarks.html +1 -1
- package/doc/dist/html/changes.html +226 -14
- package/doc/dist/html/contribute.html +1 -1
- package/doc/dist/html/functions.html +15 -12
- package/doc/dist/html/genindex.html +1 -1
- package/doc/dist/html/index.html +6 -16
- package/doc/dist/html/memory.html +3 -3
- package/doc/dist/html/objects.inv +0 -0
- package/doc/dist/html/platforms.html +1 -1
- package/doc/dist/html/search.html +1 -1
- package/doc/dist/html/searchindex.js +1 -1
- package/doc/dist/html/start.html +1 -1
- package/doc/dist/html/types.html +11 -3
- package/doc/functions.md +137 -13
- package/doc/types.md +35 -10
- package/package.json +1 -1
- package/qemu/registry/machines.json +5 -5
- package/qemu/registry/sha256sum.txt +16 -16
- package/src/abi_arm32.cc +90 -18
- package/src/abi_arm32_fwd.S +121 -57
- package/src/abi_arm64.cc +90 -18
- package/src/abi_arm64_fwd.S +96 -0
- package/src/abi_arm64_fwd.asm +128 -0
- package/src/abi_riscv64.cc +88 -18
- package/src/abi_riscv64_fwd.S +96 -0
- package/src/abi_x64_sysv.cc +93 -21
- package/src/abi_x64_sysv_fwd.S +96 -0
- package/src/abi_x64_win.cc +88 -18
- package/src/abi_x64_win_fwd.asm +128 -0
- package/src/abi_x86.cc +93 -18
- package/src/abi_x86_fwd.S +96 -0
- package/src/abi_x86_fwd.asm +128 -0
- package/src/call.cc +97 -63
- package/src/call.hh +2 -1
- package/src/ffi.cc +452 -140
- package/src/ffi.hh +23 -9
- package/src/parser.cc +18 -41
- package/src/util.cc +117 -27
- package/src/util.hh +3 -2
- package/test/callbacks.js +54 -8
- package/test/misc.c +29 -14
- package/test/raylib.js +1 -1
- package/test/sqlite.js +24 -16
- package/test/sync.js +41 -31
- package/vendor/libcc/libcc.cc +18 -5
- package/vendor/libcc/libcc.hh +70 -23
- package/build/qemu/1.3.12/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_win32_x64.tar.gz +0 -0
package/src/ffi.cc
CHANGED
|
@@ -199,8 +199,6 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
|
199
199
|
|
|
200
200
|
type->name = DuplicateString(name.c_str(), &instance->str_alloc).ptr;
|
|
201
201
|
|
|
202
|
-
type->defn.Reset(obj, 1);
|
|
203
|
-
|
|
204
202
|
type->primitive = PrimitiveKind::Record;
|
|
205
203
|
type->align = 1;
|
|
206
204
|
|
|
@@ -213,18 +211,20 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
|
213
211
|
Napi::Value value = obj[key];
|
|
214
212
|
|
|
215
213
|
member.name = DuplicateString(key.c_str(), &instance->str_alloc).ptr;
|
|
216
|
-
member.type = ResolveType(
|
|
214
|
+
member.type = ResolveType(value);
|
|
217
215
|
if (!member.type)
|
|
218
216
|
return env.Null();
|
|
219
|
-
if (member.type->primitive == PrimitiveKind::Void
|
|
220
|
-
|
|
217
|
+
if (member.type->primitive == PrimitiveKind::Void ||
|
|
218
|
+
member.type->primitive == PrimitiveKind::Prototype) {
|
|
219
|
+
ThrowError<Napi::TypeError>(env, "Type %1 cannot be used as a member (maybe try %1 *)", member.type->name);
|
|
221
220
|
return env.Null();
|
|
222
221
|
}
|
|
223
222
|
|
|
224
|
-
|
|
223
|
+
int16_t align = pad ? member.type->align : 1;
|
|
224
|
+
member.offset = (int16_t)AlignLen(type->size, align);
|
|
225
225
|
|
|
226
|
-
type->size = (int16_t)(
|
|
227
|
-
type->align = std::max(type->align,
|
|
226
|
+
type->size = (int16_t)(member.offset + member.type->size);
|
|
227
|
+
type->align = std::max(type->align, align);
|
|
228
228
|
|
|
229
229
|
if (!members.TrySet(member.name).second) {
|
|
230
230
|
ThrowError<Napi::Error>(env, "Duplicate member '%1' in struct '%2'", member.name, type->name);
|
|
@@ -242,7 +242,7 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
|
242
242
|
type->size = (int16_t)AlignLen(type->size, type->align);
|
|
243
243
|
|
|
244
244
|
// If the insert succeeds, we cannot fail anymore
|
|
245
|
-
if (named && !instance->types_map.TrySet(type).second) {
|
|
245
|
+
if (named && !instance->types_map.TrySet(type->name, type).second) {
|
|
246
246
|
ThrowError<Napi::Error>(env, "Duplicate type name '%1'", type->name);
|
|
247
247
|
return env.Null();
|
|
248
248
|
}
|
|
@@ -269,40 +269,26 @@ static Napi::Value CreateHandleType(const Napi::CallbackInfo &info)
|
|
|
269
269
|
Napi::Env env = info.Env();
|
|
270
270
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
271
271
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
}
|
|
276
|
-
if (!info[0].IsString()) {
|
|
272
|
+
bool named = (info.Length() >= 1);
|
|
273
|
+
|
|
274
|
+
if (named && !info[0].IsString()) {
|
|
277
275
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for name, expected string", GetValueType(instance, info[0]));
|
|
278
276
|
return env.Null();
|
|
279
277
|
}
|
|
280
278
|
|
|
279
|
+
std::string name = named ? info[0].As<Napi::String>() : std::string("<anonymous>");
|
|
280
|
+
|
|
281
281
|
TypeInfo *type = instance->types.AppendDefault();
|
|
282
282
|
RG_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
|
|
283
283
|
|
|
284
|
-
std::string name = info[0].As<Napi::String>();
|
|
285
|
-
|
|
286
284
|
type->name = DuplicateString(name.c_str(), &instance->str_alloc).ptr;
|
|
287
285
|
|
|
288
|
-
type->primitive = PrimitiveKind::
|
|
289
|
-
type->
|
|
290
|
-
type->
|
|
291
|
-
|
|
292
|
-
// Add single handle member
|
|
293
|
-
{
|
|
294
|
-
RecordMember member = {};
|
|
295
|
-
|
|
296
|
-
member.name = "value";
|
|
297
|
-
member.type = instance->types_map.FindValue("void *", nullptr);
|
|
298
|
-
RG_ASSERT(member.type);
|
|
299
|
-
member.align = type->align;
|
|
300
|
-
|
|
301
|
-
type->members.Append(member);
|
|
302
|
-
}
|
|
286
|
+
type->primitive = PrimitiveKind::Void;
|
|
287
|
+
type->size = 0;
|
|
288
|
+
type->align = 0;
|
|
303
289
|
|
|
304
290
|
// If the insert succeeds, we cannot fail anymore
|
|
305
|
-
if (!instance->types_map.TrySet(type).second) {
|
|
291
|
+
if (named && !instance->types_map.TrySet(type->name, type).second) {
|
|
306
292
|
ThrowError<Napi::Error>(env, "Duplicate type name '%1'", type->name);
|
|
307
293
|
return env.Null();
|
|
308
294
|
}
|
|
@@ -320,18 +306,65 @@ static Napi::Value CreatePointerType(const Napi::CallbackInfo &info)
|
|
|
320
306
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
321
307
|
|
|
322
308
|
if (info.Length() < 1) {
|
|
323
|
-
ThrowError<Napi::TypeError>(env, "Expected 1
|
|
309
|
+
ThrowError<Napi::TypeError>(env, "Expected 1 to 3 arguments, got %1", info.Length());
|
|
324
310
|
return env.Null();
|
|
325
311
|
}
|
|
326
312
|
|
|
327
|
-
|
|
328
|
-
|
|
313
|
+
bool named = (info.Length() >= 2 && !info[1].IsNumber());
|
|
314
|
+
|
|
315
|
+
if (named && !info[0].IsString()) {
|
|
316
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for name, expected string", GetValueType(instance, info[0]));
|
|
329
317
|
return env.Null();
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
std::string name = named ? info[0].As<Napi::String>() : std::string();
|
|
330
321
|
|
|
331
|
-
TypeInfo *type = (
|
|
322
|
+
const TypeInfo *type = ResolveType(info[named]);
|
|
323
|
+
if (!type)
|
|
324
|
+
return env.Null();
|
|
325
|
+
if (type->dispose) {
|
|
326
|
+
ThrowError<Napi::TypeError>(env, "Cannot create pointer to disposable type '%1'", type->name);
|
|
327
|
+
return env.Null();
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
int count = 0;
|
|
331
|
+
if (info.Length() >= 2u + named) {
|
|
332
|
+
if (!info[1 + named].IsNumber()) {
|
|
333
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for count, expected number", GetValueType(instance, info[1 + named]));
|
|
334
|
+
return env.Null();
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
count = info[1 + named].As<Napi::Number>();
|
|
338
|
+
|
|
339
|
+
if (count < 1 || count > 4) {
|
|
340
|
+
ThrowError<Napi::TypeError>(env, "Value of count must be between 1 and 4");
|
|
341
|
+
return env.Null();
|
|
342
|
+
}
|
|
343
|
+
} else {
|
|
344
|
+
count = 1;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
type = MakePointerType(instance, type, count);
|
|
332
348
|
RG_ASSERT(type);
|
|
333
349
|
|
|
334
|
-
|
|
350
|
+
if (named) {
|
|
351
|
+
TypeInfo *copy = instance->types.AppendDefault();
|
|
352
|
+
RG_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
|
|
353
|
+
|
|
354
|
+
memcpy((void *)copy, type, RG_SIZE(*type));
|
|
355
|
+
copy->name = DuplicateString(name.c_str(), &instance->str_alloc).ptr;
|
|
356
|
+
|
|
357
|
+
// If the insert succeeds, we cannot fail anymore
|
|
358
|
+
if (!instance->types_map.TrySet(copy->name, copy).second) {
|
|
359
|
+
ThrowError<Napi::Error>(env, "Duplicate type name '%1'", copy->name);
|
|
360
|
+
return env.Null();
|
|
361
|
+
}
|
|
362
|
+
err_guard.Disable();
|
|
363
|
+
|
|
364
|
+
type = copy;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
Napi::External<TypeInfo> external = Napi::External<TypeInfo>::New(env, (TypeInfo *)type);
|
|
335
368
|
SetValueTag(instance, external, &TypeInfoMarker);
|
|
336
369
|
|
|
337
370
|
return external;
|
|
@@ -349,7 +382,7 @@ static Napi::Value EncodePointerDirection(const Napi::CallbackInfo &info, int di
|
|
|
349
382
|
return env.Null();
|
|
350
383
|
}
|
|
351
384
|
|
|
352
|
-
const TypeInfo *type = ResolveType(
|
|
385
|
+
const TypeInfo *type = ResolveType(info[0]);
|
|
353
386
|
if (!type)
|
|
354
387
|
return env.Null();
|
|
355
388
|
|
|
@@ -382,6 +415,112 @@ static Napi::Value MarkInOut(const Napi::CallbackInfo &info)
|
|
|
382
415
|
return EncodePointerDirection(info, 3);
|
|
383
416
|
}
|
|
384
417
|
|
|
418
|
+
static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
|
|
419
|
+
{
|
|
420
|
+
Napi::Env env = info.Env();
|
|
421
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
422
|
+
|
|
423
|
+
if (info.Length() < 1) {
|
|
424
|
+
ThrowError<Napi::TypeError>(env, "Expected 1 or 2 arguments, got %1", info.Length());
|
|
425
|
+
return env.Null();
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
bool named = (info.Length() >= 2 && !info[1].IsFunction());
|
|
429
|
+
|
|
430
|
+
if (named && !info[0].IsString()) {
|
|
431
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for name, expected string", GetValueType(instance, info[0]));
|
|
432
|
+
return env.Null();
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
std::string name = named ? info[0].As<Napi::String>() : std::string("<anonymous>");
|
|
436
|
+
|
|
437
|
+
const TypeInfo *src = ResolveType(info[named]);
|
|
438
|
+
if (!src)
|
|
439
|
+
return env.Null();
|
|
440
|
+
if (src->primitive != PrimitiveKind::String &&
|
|
441
|
+
src->primitive != PrimitiveKind::String16 &&
|
|
442
|
+
src->primitive != PrimitiveKind::Pointer) {
|
|
443
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 type, expected pointer or string type", PrimitiveKindNames[(int)src->primitive]);
|
|
444
|
+
return env.Null();
|
|
445
|
+
}
|
|
446
|
+
if (src->dispose) {
|
|
447
|
+
ThrowError<Napi::TypeError>(env, "Cannot use disposable type '%1' to create new disposable", src->name);
|
|
448
|
+
return env.Null();
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
DisposeFunc *dispose;
|
|
452
|
+
Napi::Function dispose_func;
|
|
453
|
+
if (info.Length() >= 2u + named && !IsNullOrUndefined(info[1 + named])) {
|
|
454
|
+
Napi::Function func = info[1 + named].As<Napi::Function>();
|
|
455
|
+
|
|
456
|
+
if (!func.IsFunction()) {
|
|
457
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for func, expected function", GetValueType(instance, func));
|
|
458
|
+
return env.Null();
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
dispose = [](Napi::Env env, const TypeInfo *type, const void *ptr) {
|
|
462
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
463
|
+
const Napi::FunctionReference &ref = type->dispose_ref;
|
|
464
|
+
|
|
465
|
+
Napi::External<void> external = Napi::External<void>::New(env, (void *)ptr);
|
|
466
|
+
SetValueTag(instance, external, type->ref.marker);
|
|
467
|
+
|
|
468
|
+
Napi::Value self = env.Null();
|
|
469
|
+
napi_value args[] = {
|
|
470
|
+
external
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
ref.Call(self, RG_LEN(args), args);
|
|
474
|
+
};
|
|
475
|
+
dispose_func = func;
|
|
476
|
+
} else {
|
|
477
|
+
dispose = [](Napi::Env, const TypeInfo *, const void *ptr) { free((void *)ptr); };
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
TypeInfo *type = instance->types.AppendDefault();
|
|
481
|
+
RG_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
|
|
482
|
+
|
|
483
|
+
memcpy((void *)type, (const void *)src, RG_SIZE(*src));
|
|
484
|
+
type->name = DuplicateString(name.c_str(), &instance->str_alloc).ptr;
|
|
485
|
+
type->members.allocator = GetNullAllocator();
|
|
486
|
+
type->dispose = dispose;
|
|
487
|
+
type->dispose_ref = Napi::Persistent(dispose_func);
|
|
488
|
+
|
|
489
|
+
// If the insert succeeds, we cannot fail anymore
|
|
490
|
+
if (named && !instance->types_map.TrySet(type->name, type).second) {
|
|
491
|
+
ThrowError<Napi::Error>(env, "Duplicate type name '%1'", type->name);
|
|
492
|
+
return env.Null();
|
|
493
|
+
}
|
|
494
|
+
err_guard.Disable();
|
|
495
|
+
|
|
496
|
+
Napi::External<TypeInfo> external = Napi::External<TypeInfo>::New(env, type);
|
|
497
|
+
SetValueTag(instance, external, &TypeInfoMarker);
|
|
498
|
+
|
|
499
|
+
return external;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
static Napi::Value CallFree(const Napi::CallbackInfo &info)
|
|
503
|
+
{
|
|
504
|
+
Napi::Env env = info.Env();
|
|
505
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
506
|
+
|
|
507
|
+
if (info.Length() < 1) {
|
|
508
|
+
ThrowError<Napi::TypeError>(env, "Expected 1 or 2 arguments, got %1", info.Length());
|
|
509
|
+
return env.Null();
|
|
510
|
+
}
|
|
511
|
+
if (!info[0].IsExternal() || CheckValueTag(instance, info[0], &TypeInfoMarker)) {
|
|
512
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected external", GetValueType(instance, info[0]));
|
|
513
|
+
return env.Null();
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
Napi::External<void> external = info[0].As<Napi::External<void>>();
|
|
517
|
+
void *ptr = external.Data();
|
|
518
|
+
|
|
519
|
+
free(ptr);
|
|
520
|
+
|
|
521
|
+
return env.Null();
|
|
522
|
+
}
|
|
523
|
+
|
|
385
524
|
static Napi::Value CreateArrayType(const Napi::CallbackInfo &info)
|
|
386
525
|
{
|
|
387
526
|
Napi::Env env = info.Env();
|
|
@@ -396,7 +535,7 @@ static Napi::Value CreateArrayType(const Napi::CallbackInfo &info)
|
|
|
396
535
|
return env.Null();
|
|
397
536
|
}
|
|
398
537
|
|
|
399
|
-
const TypeInfo *ref = ResolveType(
|
|
538
|
+
const TypeInfo *ref = ResolveType(info[0]);
|
|
400
539
|
int64_t len = (uint16_t)info[1].As<Napi::Number>().Int64Value();
|
|
401
540
|
|
|
402
541
|
if (!ref)
|
|
@@ -448,7 +587,7 @@ static Napi::Value CreateArrayType(const Napi::CallbackInfo &info)
|
|
|
448
587
|
type->primitive = PrimitiveKind::Array;
|
|
449
588
|
type->align = ref->align;
|
|
450
589
|
type->size = (int16_t)(len * ref->size);
|
|
451
|
-
type->ref = ref;
|
|
590
|
+
type->ref.type = ref;
|
|
452
591
|
type->hint = hint;
|
|
453
592
|
|
|
454
593
|
Napi::External<TypeInfo> external = Napi::External<TypeInfo>::New(env, type);
|
|
@@ -476,7 +615,7 @@ static bool ParseClassicFunction(Napi::Env env, Napi::String name, Napi::Value r
|
|
|
476
615
|
|
|
477
616
|
func->name = DuplicateString(name.ToString().Utf8Value().c_str(), &instance->str_alloc).ptr;
|
|
478
617
|
|
|
479
|
-
func->ret.type = ResolveType(
|
|
618
|
+
func->ret.type = ResolveType(ret);
|
|
480
619
|
if (!func->ret.type)
|
|
481
620
|
return false;
|
|
482
621
|
if (func->ret.type->primitive == PrimitiveKind::Array) {
|
|
@@ -503,12 +642,13 @@ static bool ParseClassicFunction(Napi::Env env, Napi::String name, Napi::Value r
|
|
|
503
642
|
for (uint32_t j = 0; j < parameters_len; j++) {
|
|
504
643
|
ParameterInfo param = {};
|
|
505
644
|
|
|
506
|
-
param.type = ResolveType(
|
|
645
|
+
param.type = ResolveType(parameters[j], ¶m.directions);
|
|
507
646
|
if (!param.type)
|
|
508
647
|
return false;
|
|
509
648
|
if (param.type->primitive == PrimitiveKind::Void ||
|
|
510
|
-
param.type->primitive == PrimitiveKind::Array
|
|
511
|
-
|
|
649
|
+
param.type->primitive == PrimitiveKind::Array ||
|
|
650
|
+
param.type->primitive == PrimitiveKind::Prototype) {
|
|
651
|
+
ThrowError<Napi::TypeError>(env, "Type %1 cannot be used as a parameter (maybe try %1 *)", param.type->name);
|
|
512
652
|
return false;
|
|
513
653
|
}
|
|
514
654
|
|
|
@@ -573,12 +713,12 @@ static Napi::Value CreateCallbackType(const Napi::CallbackInfo &info)
|
|
|
573
713
|
|
|
574
714
|
type->name = func->name;
|
|
575
715
|
|
|
576
|
-
type->primitive = PrimitiveKind::
|
|
716
|
+
type->primitive = PrimitiveKind::Prototype;
|
|
577
717
|
type->align = alignof(void *);
|
|
578
718
|
type->size = RG_SIZE(void *);
|
|
579
|
-
type->proto = func;
|
|
719
|
+
type->ref.proto = func;
|
|
580
720
|
|
|
581
|
-
instance->types_map.Set(type);
|
|
721
|
+
instance->types_map.Set(type->name, type);
|
|
582
722
|
|
|
583
723
|
Napi::External<TypeInfo> external = Napi::External<TypeInfo>::New(env, type);
|
|
584
724
|
SetValueTag(instance, external, &TypeInfoMarker);
|
|
@@ -586,17 +726,50 @@ static Napi::Value CreateCallbackType(const Napi::CallbackInfo &info)
|
|
|
586
726
|
return external;
|
|
587
727
|
}
|
|
588
728
|
|
|
589
|
-
static Napi::Value
|
|
729
|
+
static Napi::Value CreateTypeAlias(const Napi::CallbackInfo &info)
|
|
590
730
|
{
|
|
591
731
|
Napi::Env env = info.Env();
|
|
592
732
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
593
733
|
|
|
734
|
+
if (info.Length() < 2) {
|
|
735
|
+
ThrowError<Napi::TypeError>(env, "Expected 2 arguments, got %1", info.Length());
|
|
736
|
+
return env.Null();
|
|
737
|
+
}
|
|
738
|
+
if (!info[0].IsString()) {
|
|
739
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for name, expected string", GetValueType(instance, info[0]));
|
|
740
|
+
return env.Null();
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
std::string name = info[0].As<Napi::String>();
|
|
744
|
+
const char *alias = DuplicateString(name.c_str(), &instance->str_alloc).ptr;
|
|
745
|
+
|
|
746
|
+
const TypeInfo *type = ResolveType(info[1]);
|
|
747
|
+
if (!type)
|
|
748
|
+
return env.Null();
|
|
749
|
+
|
|
750
|
+
std::pair<const TypeInfo **, bool> ret = instance->types_map.TrySet(alias, type);
|
|
751
|
+
|
|
752
|
+
if (!ret.second) {
|
|
753
|
+
ThrowError<Napi::Error>(env, "Type name '%1' already exists", alias);
|
|
754
|
+
return env.Null();
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
Napi::External<TypeInfo> external = Napi::External<TypeInfo>::New(env, (TypeInfo *)type);
|
|
758
|
+
SetValueTag(instance, external, &TypeInfoMarker);
|
|
759
|
+
|
|
760
|
+
return external;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
static Napi::Value GetTypeSize(const Napi::CallbackInfo &info)
|
|
764
|
+
{
|
|
765
|
+
Napi::Env env = info.Env();
|
|
766
|
+
|
|
594
767
|
if (info.Length() < 1) {
|
|
595
768
|
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
|
|
596
769
|
return env.Null();
|
|
597
770
|
}
|
|
598
771
|
|
|
599
|
-
const TypeInfo *type = ResolveType(
|
|
772
|
+
const TypeInfo *type = ResolveType(info[0]);
|
|
600
773
|
if (!type)
|
|
601
774
|
return env.Null();
|
|
602
775
|
|
|
@@ -606,20 +779,39 @@ static Napi::Value GetTypeSize(const Napi::CallbackInfo &info)
|
|
|
606
779
|
static Napi::Value GetTypeAlign(const Napi::CallbackInfo &info)
|
|
607
780
|
{
|
|
608
781
|
Napi::Env env = info.Env();
|
|
609
|
-
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
610
782
|
|
|
611
783
|
if (info.Length() < 1) {
|
|
612
784
|
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
|
|
613
785
|
return env.Null();
|
|
614
786
|
}
|
|
615
787
|
|
|
616
|
-
const TypeInfo *type = ResolveType(
|
|
788
|
+
const TypeInfo *type = ResolveType(info[0]);
|
|
617
789
|
if (!type)
|
|
618
790
|
return env.Null();
|
|
619
791
|
|
|
620
792
|
return Napi::Number::New(env, type->align);
|
|
621
793
|
}
|
|
622
794
|
|
|
795
|
+
static Napi::Value GetResolvedType(const Napi::CallbackInfo &info)
|
|
796
|
+
{
|
|
797
|
+
Napi::Env env = info.Env();
|
|
798
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
799
|
+
|
|
800
|
+
if (info.Length() < 1) {
|
|
801
|
+
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
|
|
802
|
+
return env.Null();
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
const TypeInfo *type = ResolveType(info[0]);
|
|
806
|
+
if (!type)
|
|
807
|
+
return env.Null();
|
|
808
|
+
|
|
809
|
+
Napi::External<TypeInfo> external = Napi::External<TypeInfo>::New(env, (TypeInfo *)type);
|
|
810
|
+
SetValueTag(instance, external, &TypeInfoMarker);
|
|
811
|
+
|
|
812
|
+
return external;
|
|
813
|
+
}
|
|
814
|
+
|
|
623
815
|
static Napi::Value GetTypeDefinition(const Napi::CallbackInfo &info)
|
|
624
816
|
{
|
|
625
817
|
Napi::Env env = info.Env();
|
|
@@ -630,12 +822,62 @@ static Napi::Value GetTypeDefinition(const Napi::CallbackInfo &info)
|
|
|
630
822
|
return env.Null();
|
|
631
823
|
}
|
|
632
824
|
|
|
633
|
-
const TypeInfo *type = ResolveType(
|
|
825
|
+
const TypeInfo *type = ResolveType(info[0]);
|
|
634
826
|
if (!type)
|
|
635
827
|
return env.Null();
|
|
828
|
+
|
|
636
829
|
if (type->defn.IsEmpty()) {
|
|
637
|
-
|
|
638
|
-
|
|
830
|
+
Napi::Object defn = Napi::Object::New(env);
|
|
831
|
+
|
|
832
|
+
defn.Set("name", Napi::String::New(env, type->name));
|
|
833
|
+
defn.Set("primitive", PrimitiveKindNames[(int)type->primitive]);
|
|
834
|
+
defn.Set("size", Napi::Number::New(env, (double)type->size));
|
|
835
|
+
defn.Set("alignment", Napi::Number::New(env, (double)type->align));
|
|
836
|
+
|
|
837
|
+
switch (type->primitive) {
|
|
838
|
+
case PrimitiveKind::Void:
|
|
839
|
+
case PrimitiveKind::Bool:
|
|
840
|
+
case PrimitiveKind::Int8:
|
|
841
|
+
case PrimitiveKind::UInt8:
|
|
842
|
+
case PrimitiveKind::Int16:
|
|
843
|
+
case PrimitiveKind::UInt16:
|
|
844
|
+
case PrimitiveKind::Int32:
|
|
845
|
+
case PrimitiveKind::UInt32:
|
|
846
|
+
case PrimitiveKind::Int64:
|
|
847
|
+
case PrimitiveKind::UInt64:
|
|
848
|
+
case PrimitiveKind::String:
|
|
849
|
+
case PrimitiveKind::String16:
|
|
850
|
+
case PrimitiveKind::Float32:
|
|
851
|
+
case PrimitiveKind::Float64:
|
|
852
|
+
case PrimitiveKind::Prototype:
|
|
853
|
+
case PrimitiveKind::Callback: {} break;
|
|
854
|
+
|
|
855
|
+
case PrimitiveKind::Array: {
|
|
856
|
+
uint32_t len = type->size / type->ref.type->size;
|
|
857
|
+
defn.Set("length", Napi::Number::New(env, (double)len));
|
|
858
|
+
} [[fallthrough]];
|
|
859
|
+
case PrimitiveKind::Pointer: {
|
|
860
|
+
Napi::External<TypeInfo> external = Napi::External<TypeInfo>::New(env, (TypeInfo *)type->ref.type);
|
|
861
|
+
SetValueTag(instance, external, &TypeInfoMarker);
|
|
862
|
+
|
|
863
|
+
defn.Set("ref", external);
|
|
864
|
+
} break;
|
|
865
|
+
case PrimitiveKind::Record: {
|
|
866
|
+
Napi::Object members = Napi::Object::New(env);
|
|
867
|
+
|
|
868
|
+
for (const RecordMember &member: type->members) {
|
|
869
|
+
Napi::External<TypeInfo> external = Napi::External<TypeInfo>::New(env, (TypeInfo *)member.type);
|
|
870
|
+
SetValueTag(instance, external, &TypeInfoMarker);
|
|
871
|
+
|
|
872
|
+
members.Set(member.name, external);
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
defn.Set("members", members);
|
|
876
|
+
} break;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
defn.Freeze();
|
|
880
|
+
type->defn.Reset(defn, 1);
|
|
639
881
|
}
|
|
640
882
|
|
|
641
883
|
return type->defn.Value();
|
|
@@ -743,12 +985,13 @@ static Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info)
|
|
|
743
985
|
for (Size i = func.parameters.len; i < (Size)info.Length(); i += 2) {
|
|
744
986
|
ParameterInfo param = {};
|
|
745
987
|
|
|
746
|
-
param.type = ResolveType(
|
|
988
|
+
param.type = ResolveType(info[i], ¶m.directions);
|
|
747
989
|
if (RG_UNLIKELY(!param.type))
|
|
748
990
|
return env.Null();
|
|
749
991
|
if (RG_UNLIKELY(param.type->primitive == PrimitiveKind::Void ||
|
|
750
|
-
param.type->primitive == PrimitiveKind::Array
|
|
751
|
-
|
|
992
|
+
param.type->primitive == PrimitiveKind::Array ||
|
|
993
|
+
param.type->primitive == PrimitiveKind::Prototype)) {
|
|
994
|
+
ThrowError<Napi::TypeError>(env, "Type %1 cannot be used as a parameter (maybe try %1 *)", PrimitiveKindNames[(int)param.type->primitive]);
|
|
752
995
|
return env.Null();
|
|
753
996
|
}
|
|
754
997
|
|
|
@@ -923,7 +1166,7 @@ static Napi::Value FindLibraryFunction(const Napi::CallbackInfo &info, CallConve
|
|
|
923
1166
|
uint16_t ordinal = (uint16_t)info[0].As<Napi::Number>().Uint32Value();
|
|
924
1167
|
|
|
925
1168
|
func->decorated_name = nullptr;
|
|
926
|
-
func->func = (void *)GetProcAddress((HMODULE)lib->module, (LPCSTR)ordinal);
|
|
1169
|
+
func->func = (void *)GetProcAddress((HMODULE)lib->module, (LPCSTR)(size_t)ordinal);
|
|
927
1170
|
}
|
|
928
1171
|
#else
|
|
929
1172
|
if (func->decorated_name) {
|
|
@@ -1032,6 +1275,89 @@ static Napi::Value LoadSharedLibrary(const Napi::CallbackInfo &info)
|
|
|
1032
1275
|
return obj;
|
|
1033
1276
|
}
|
|
1034
1277
|
|
|
1278
|
+
static Napi::Value RegisterCallback(const Napi::CallbackInfo &info)
|
|
1279
|
+
{
|
|
1280
|
+
Napi::Env env = info.Env();
|
|
1281
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
1282
|
+
|
|
1283
|
+
if (info.Length() < 2) {
|
|
1284
|
+
ThrowError<Napi::TypeError>(env, "Expected 2 arguments, got %1", info.Length());
|
|
1285
|
+
return env.Null();
|
|
1286
|
+
}
|
|
1287
|
+
if (!info[0].IsFunction()) {
|
|
1288
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for func, expected function", GetValueType(instance, info[0]));
|
|
1289
|
+
return env.Null();
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
Napi::Function func = info[0].As<Napi::Function>();
|
|
1293
|
+
|
|
1294
|
+
const TypeInfo *type = ResolveType(info[1]);
|
|
1295
|
+
if (!type)
|
|
1296
|
+
return env.Null();
|
|
1297
|
+
if (type->primitive != PrimitiveKind::Callback) {
|
|
1298
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 type, expected <callback> * type", type->name);
|
|
1299
|
+
return env.Null();
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
int idx = CountTrailingZeros(~instance->registered_trampolines);
|
|
1303
|
+
|
|
1304
|
+
if (RG_UNLIKELY(idx >= MaxTrampolines)) {
|
|
1305
|
+
ThrowError<Napi::Error>(env, "Too many registered callbacks are in use (max = %1)", MaxTrampolines);
|
|
1306
|
+
return env.Null();
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
instance->registered_trampolines |= 1u << idx;
|
|
1310
|
+
idx += MaxTrampolines;
|
|
1311
|
+
|
|
1312
|
+
TrampolineInfo *trampoline = &instance->trampolines[idx];
|
|
1313
|
+
|
|
1314
|
+
trampoline->proto = type->ref.proto;
|
|
1315
|
+
trampoline->func.Reset(func, 1);
|
|
1316
|
+
trampoline->generation = -1;
|
|
1317
|
+
|
|
1318
|
+
void *ptr = GetTrampoline(idx, type->ref.proto);
|
|
1319
|
+
|
|
1320
|
+
Napi::External<void> external = Napi::External<void>::New(env, ptr);
|
|
1321
|
+
SetValueTag(instance, external, type->ref.marker);
|
|
1322
|
+
|
|
1323
|
+
return external;
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
static Napi::Value UnregisterCallback(const Napi::CallbackInfo &info)
|
|
1327
|
+
{
|
|
1328
|
+
Napi::Env env = info.Env();
|
|
1329
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
1330
|
+
|
|
1331
|
+
if (info.Length() < 1) {
|
|
1332
|
+
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
|
|
1333
|
+
return env.Null();
|
|
1334
|
+
}
|
|
1335
|
+
if (!info[0].IsExternal()) {
|
|
1336
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for id, expected registered callback", GetValueType(instance, info[0]));
|
|
1337
|
+
return env.Null();
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
Napi::External<void> external = info[0].As<Napi::External<void>>();
|
|
1341
|
+
void *ptr = external.Data();
|
|
1342
|
+
|
|
1343
|
+
for (Size i = 0; i < MaxTrampolines; i++) {
|
|
1344
|
+
Size idx = i + MaxTrampolines;
|
|
1345
|
+
|
|
1346
|
+
if (!(instance->registered_trampolines & (1u << i)))
|
|
1347
|
+
continue;
|
|
1348
|
+
|
|
1349
|
+
const TrampolineInfo &trampoline = instance->trampolines[idx];
|
|
1350
|
+
|
|
1351
|
+
if (GetTrampoline(idx, trampoline.proto) == ptr) {
|
|
1352
|
+
instance->registered_trampolines &= ~(1u << i);
|
|
1353
|
+
return env.Null();
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
ThrowError<Napi::Error>(env, "Could not find matching registered callback");
|
|
1358
|
+
return env.Null();
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1035
1361
|
LibraryHolder::~LibraryHolder()
|
|
1036
1362
|
{
|
|
1037
1363
|
#ifdef _WIN32
|
|
@@ -1058,108 +1384,86 @@ void LibraryHolder::Unref() const
|
|
|
1058
1384
|
}
|
|
1059
1385
|
}
|
|
1060
1386
|
|
|
1061
|
-
static
|
|
1062
|
-
|
|
1387
|
+
static inline PrimitiveKind GetIntegerPrimitive(Size len, bool sign)
|
|
1388
|
+
{
|
|
1389
|
+
switch (len) {
|
|
1390
|
+
case 1: return sign ? PrimitiveKind::Int8 : PrimitiveKind::UInt8;
|
|
1391
|
+
case 2: return sign ? PrimitiveKind::Int16 : PrimitiveKind::UInt16;
|
|
1392
|
+
case 4: return sign ? PrimitiveKind::Int32 : PrimitiveKind::UInt32;
|
|
1393
|
+
case 8: return sign ? PrimitiveKind::Int64 : PrimitiveKind::UInt64;
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
RG_UNREACHABLE();
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
static void RegisterPrimitiveType(Napi::Env env, Napi::Object map, std::initializer_list<const char *> names,
|
|
1400
|
+
PrimitiveKind primitive, int16_t size, int16_t align, const char *ref = nullptr)
|
|
1063
1401
|
{
|
|
1402
|
+
RG_ASSERT(names.size() > 0);
|
|
1064
1403
|
RG_ASSERT(align <= size);
|
|
1065
1404
|
|
|
1405
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
1406
|
+
|
|
1066
1407
|
TypeInfo *type = instance->types.AppendDefault();
|
|
1067
1408
|
|
|
1068
|
-
type->name =
|
|
1409
|
+
type->name = *names.begin();
|
|
1069
1410
|
|
|
1070
1411
|
type->primitive = primitive;
|
|
1071
1412
|
type->size = size;
|
|
1072
1413
|
type->align = align;
|
|
1073
1414
|
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1415
|
+
if (ref) {
|
|
1416
|
+
const TypeInfo *marker = instance->types_map.FindValue(ref, nullptr);
|
|
1417
|
+
RG_ASSERT(marker);
|
|
1077
1418
|
|
|
1078
|
-
|
|
1079
|
-
static inline PrimitiveKind GetIntegerPrimitive(bool sign)
|
|
1080
|
-
{
|
|
1081
|
-
switch (RG_SIZE(T)) {
|
|
1082
|
-
case 1: return sign ? PrimitiveKind::Int8 : PrimitiveKind::UInt8;
|
|
1083
|
-
case 2: return sign ? PrimitiveKind::Int16 : PrimitiveKind::UInt16;
|
|
1084
|
-
case 4: return sign ? PrimitiveKind::Int32 : PrimitiveKind::UInt32;
|
|
1085
|
-
case 8: return sign ? PrimitiveKind::Int64 : PrimitiveKind::UInt64;
|
|
1419
|
+
type->ref.marker = marker;
|
|
1086
1420
|
}
|
|
1087
1421
|
|
|
1088
|
-
|
|
1422
|
+
Napi::External<TypeInfo> external = Napi::External<TypeInfo>::New(env, type);
|
|
1423
|
+
SetValueTag(instance, external, &TypeInfoMarker);
|
|
1424
|
+
|
|
1425
|
+
for (const char *name: names) {
|
|
1426
|
+
std::pair<const TypeInfo **, bool> ret = instance->types_map.TrySet(name, type);
|
|
1427
|
+
RG_ASSERT(ret.second);
|
|
1428
|
+
|
|
1429
|
+
if (!EndsWith(name, "*")) {
|
|
1430
|
+
map.Set(name, external);
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1089
1433
|
}
|
|
1090
1434
|
|
|
1091
1435
|
static Napi::Object InitBaseTypes(Napi::Env env)
|
|
1092
1436
|
{
|
|
1093
|
-
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
1094
|
-
|
|
1095
|
-
RG_ASSERT(!instance->types.len);
|
|
1096
|
-
|
|
1097
|
-
RegisterPrimitiveType(instance, "void", PrimitiveKind::Void, 0, 0);
|
|
1098
|
-
RegisterPrimitiveType(instance, "void *", PrimitiveKind::Pointer, RG_SIZE(void *), alignof(void *));
|
|
1099
|
-
RegisterPrimitiveType(instance, "bool", PrimitiveKind::Bool, RG_SIZE(bool), alignof(bool));
|
|
1100
|
-
RegisterPrimitiveType(instance, "int8", PrimitiveKind::Int8, 1, 1);
|
|
1101
|
-
RegisterPrimitiveType(instance, "int8_t", PrimitiveKind::Int8, 1, 1);
|
|
1102
|
-
RegisterPrimitiveType(instance, "uint8", PrimitiveKind::UInt8, 1, 1);
|
|
1103
|
-
RegisterPrimitiveType(instance, "uint8_t", PrimitiveKind::UInt8, 1, 1);
|
|
1104
|
-
RegisterPrimitiveType(instance, "char", PrimitiveKind::Int8, 1, 1);
|
|
1105
|
-
RegisterPrimitiveType(instance, "uchar", PrimitiveKind::UInt8, 1, 1);
|
|
1106
|
-
RegisterPrimitiveType(instance, "unsigned char", PrimitiveKind::UInt8, 1, 1);
|
|
1107
|
-
RegisterPrimitiveType(instance, "char16", PrimitiveKind::Int16, 2, 2);
|
|
1108
|
-
RegisterPrimitiveType(instance, "char16_t", PrimitiveKind::Int16, 2, 2);
|
|
1109
|
-
RegisterPrimitiveType(instance, "int16", PrimitiveKind::Int16, 2, 2);
|
|
1110
|
-
RegisterPrimitiveType(instance, "int16_t", PrimitiveKind::Int16, 2, 2);
|
|
1111
|
-
RegisterPrimitiveType(instance, "uint16", PrimitiveKind::UInt16, 2, 2);
|
|
1112
|
-
RegisterPrimitiveType(instance, "uint16_t", PrimitiveKind::UInt16, 2, 2);
|
|
1113
|
-
RegisterPrimitiveType(instance, "short", PrimitiveKind::Int16, 2, 2);
|
|
1114
|
-
RegisterPrimitiveType(instance, "ushort", PrimitiveKind::UInt16, 2, 2);
|
|
1115
|
-
RegisterPrimitiveType(instance, "unsigned short", PrimitiveKind::UInt16, 2, 2);
|
|
1116
|
-
RegisterPrimitiveType(instance, "int32", PrimitiveKind::Int32, 4, 4);
|
|
1117
|
-
RegisterPrimitiveType(instance, "int32_t", PrimitiveKind::Int32, 4, 4);
|
|
1118
|
-
RegisterPrimitiveType(instance, "uint32", PrimitiveKind::UInt32, 4, 4);
|
|
1119
|
-
RegisterPrimitiveType(instance, "uint32_t", PrimitiveKind::UInt32, 4, 4);
|
|
1120
|
-
RegisterPrimitiveType(instance, "int", PrimitiveKind::Int32, 4, 4);
|
|
1121
|
-
RegisterPrimitiveType(instance, "uint", PrimitiveKind::UInt32, 4, 4);
|
|
1122
|
-
RegisterPrimitiveType(instance, "unsigned int", PrimitiveKind::UInt32, 4, 4);
|
|
1123
|
-
RegisterPrimitiveType(instance, "int64", PrimitiveKind::Int64, 8, alignof(int64_t));
|
|
1124
|
-
RegisterPrimitiveType(instance, "int64_t", PrimitiveKind::Int64, 8, alignof(int64_t));
|
|
1125
|
-
RegisterPrimitiveType(instance, "uint64", PrimitiveKind::UInt64, 8, alignof(int64_t));
|
|
1126
|
-
RegisterPrimitiveType(instance, "uint64_t", PrimitiveKind::UInt64, 8, alignof(int64_t));
|
|
1127
|
-
RegisterPrimitiveType(instance, "intptr", GetIntegerPrimitive<intptr_t>(true), RG_SIZE(intptr_t), alignof(intptr_t));
|
|
1128
|
-
RegisterPrimitiveType(instance, "intptr_t", GetIntegerPrimitive<intptr_t>(true), RG_SIZE(intptr_t), alignof(intptr_t));
|
|
1129
|
-
RegisterPrimitiveType(instance, "uintptr", GetIntegerPrimitive<intptr_t>(false), RG_SIZE(intptr_t), alignof(intptr_t));
|
|
1130
|
-
RegisterPrimitiveType(instance, "uintptr_t", GetIntegerPrimitive<intptr_t>(false), RG_SIZE(intptr_t), alignof(intptr_t));
|
|
1131
|
-
RegisterPrimitiveType(instance, "long", GetIntegerPrimitive<long>(true), RG_SIZE(long), alignof(long));
|
|
1132
|
-
RegisterPrimitiveType(instance, "ulong", GetIntegerPrimitive<long>(false), RG_SIZE(long), alignof(long));
|
|
1133
|
-
RegisterPrimitiveType(instance, "unsigned long", GetIntegerPrimitive<long>(false), RG_SIZE(long), alignof(long));
|
|
1134
|
-
RegisterPrimitiveType(instance, "longlong", PrimitiveKind::Int64, RG_SIZE(int64_t), alignof(int64_t));
|
|
1135
|
-
RegisterPrimitiveType(instance, "long long", PrimitiveKind::Int64, RG_SIZE(int64_t), alignof(int64_t));
|
|
1136
|
-
RegisterPrimitiveType(instance, "ulonglong", PrimitiveKind::UInt64, RG_SIZE(uint64_t), alignof(uint64_t));
|
|
1137
|
-
RegisterPrimitiveType(instance, "unsigned long long", PrimitiveKind::UInt64, RG_SIZE(uint64_t), alignof(uint64_t));
|
|
1138
|
-
RegisterPrimitiveType(instance, "float32", PrimitiveKind::Float32, 4, alignof(float));
|
|
1139
|
-
RegisterPrimitiveType(instance, "float64", PrimitiveKind::Float64, 8, alignof(double));
|
|
1140
|
-
RegisterPrimitiveType(instance, "float", PrimitiveKind::Float32, 4, alignof(float));
|
|
1141
|
-
RegisterPrimitiveType(instance, "double", PrimitiveKind::Float64, 8, alignof(double));
|
|
1142
|
-
RegisterPrimitiveType(instance, "string", PrimitiveKind::String, RG_SIZE(void *), alignof(void *));
|
|
1143
|
-
RegisterPrimitiveType(instance, "string16", PrimitiveKind::String16, RG_SIZE(void *), alignof(void *));
|
|
1144
|
-
RegisterPrimitiveType(instance, "str", PrimitiveKind::String, RG_SIZE(void *), alignof(void *));
|
|
1145
|
-
RegisterPrimitiveType(instance, "str16", PrimitiveKind::String16, RG_SIZE(void *), alignof(void *));
|
|
1146
|
-
|
|
1147
1437
|
Napi::Object types = Napi::Object::New(env);
|
|
1148
|
-
for (TypeInfo &type: instance->types) {
|
|
1149
|
-
Napi::External<TypeInfo> external = Napi::External<TypeInfo>::New(env, &type);
|
|
1150
|
-
SetValueTag(instance, external, &TypeInfoMarker);
|
|
1151
1438
|
|
|
1152
|
-
|
|
1439
|
+
RegisterPrimitiveType(env, types, {"void"}, PrimitiveKind::Void, 0, 0);
|
|
1440
|
+
RegisterPrimitiveType(env, types, {"bool"}, PrimitiveKind::Bool, RG_SIZE(bool), alignof(bool));
|
|
1441
|
+
RegisterPrimitiveType(env, types, {"int8_t", "int8"}, PrimitiveKind::Int8, 1, 1);
|
|
1442
|
+
RegisterPrimitiveType(env, types, {"uint8_t", "uint8"}, PrimitiveKind::UInt8, 1, 1);
|
|
1443
|
+
RegisterPrimitiveType(env, types, {"char"}, PrimitiveKind::Int8, 1, 1);
|
|
1444
|
+
RegisterPrimitiveType(env, types, {"unsigned char", "uchar"}, PrimitiveKind::UInt8, 1, 1);
|
|
1445
|
+
RegisterPrimitiveType(env, types, {"char16_t", "char16"}, PrimitiveKind::Int16, 2, 2);
|
|
1446
|
+
RegisterPrimitiveType(env, types, {"int16_t", "int16"}, PrimitiveKind::Int16, 2, 2);
|
|
1447
|
+
RegisterPrimitiveType(env, types, {"uint16_t", "uint16"}, PrimitiveKind::UInt16, 2, 2);
|
|
1448
|
+
RegisterPrimitiveType(env, types, {"short"}, PrimitiveKind::Int16, 2, 2);
|
|
1449
|
+
RegisterPrimitiveType(env, types, {"unsigned short", "ushort"}, PrimitiveKind::UInt16, 2, 2);
|
|
1450
|
+
RegisterPrimitiveType(env, types, {"int32_t", "int32"}, PrimitiveKind::Int32, 4, 4);
|
|
1451
|
+
RegisterPrimitiveType(env, types, {"uint32_t", "uint32"}, PrimitiveKind::UInt32, 4, 4);
|
|
1452
|
+
RegisterPrimitiveType(env, types, {"int"}, PrimitiveKind::Int32, 4, 4);
|
|
1453
|
+
RegisterPrimitiveType(env, types, {"unsigned int", "uint"}, PrimitiveKind::UInt32, 4, 4);
|
|
1454
|
+
RegisterPrimitiveType(env, types, {"int64_t", "int64"}, PrimitiveKind::Int64, 8, alignof(int64_t));
|
|
1455
|
+
RegisterPrimitiveType(env, types, {"uint64_t", "uint64"}, PrimitiveKind::UInt64, 8, alignof(int64_t));
|
|
1456
|
+
RegisterPrimitiveType(env, types, {"intptr_t", "intptr"}, GetIntegerPrimitive(RG_SIZE(intptr_t), true), RG_SIZE(intptr_t), alignof(intptr_t));
|
|
1457
|
+
RegisterPrimitiveType(env, types, {"uintptr_t", "uintptr"}, GetIntegerPrimitive(RG_SIZE(intptr_t), false), RG_SIZE(intptr_t), alignof(intptr_t));
|
|
1458
|
+
RegisterPrimitiveType(env, types, {"long"}, GetIntegerPrimitive(RG_SIZE(long), true), RG_SIZE(long), alignof(long));
|
|
1459
|
+
RegisterPrimitiveType(env, types, {"unsigned long", "ulong"}, GetIntegerPrimitive(RG_SIZE(long), false), RG_SIZE(long), alignof(long));
|
|
1460
|
+
RegisterPrimitiveType(env, types, {"long long", "longlong"}, PrimitiveKind::Int64, RG_SIZE(int64_t), alignof(int64_t));
|
|
1461
|
+
RegisterPrimitiveType(env, types, {"unsigned long long", "ulonglong"}, PrimitiveKind::UInt64, RG_SIZE(uint64_t), alignof(uint64_t));
|
|
1462
|
+
RegisterPrimitiveType(env, types, {"float", "float32"}, PrimitiveKind::Float32, 4, alignof(float));
|
|
1463
|
+
RegisterPrimitiveType(env, types, {"double", "float64"}, PrimitiveKind::Float64, 8, alignof(double));
|
|
1464
|
+
RegisterPrimitiveType(env, types, {"char *", "str", "string"}, PrimitiveKind::String, RG_SIZE(void *), alignof(void *), "char");
|
|
1465
|
+
RegisterPrimitiveType(env, types, {"char16_t *", "char16 *", "str16", "string16"}, PrimitiveKind::String16, RG_SIZE(void *), alignof(void *), "char16_t");
|
|
1153
1466
|
|
|
1154
|
-
if (strchr(type.name, ' ')) {
|
|
1155
|
-
char name_buf[64] = {};
|
|
1156
|
-
for (Size i = 0; type.name[i]; i++) {
|
|
1157
|
-
RG_ASSERT(i < RG_SIZE(name_buf) - 1);
|
|
1158
|
-
name_buf[i] = type.name[i] != ' ' ? type.name[i] : '_';
|
|
1159
|
-
}
|
|
1160
|
-
types.Set(name_buf, external);
|
|
1161
|
-
}
|
|
1162
|
-
}
|
|
1163
1467
|
types.Freeze();
|
|
1164
1468
|
|
|
1165
1469
|
return types;
|
|
@@ -1222,9 +1526,11 @@ static void SetExports(Napi::Env env, Func func)
|
|
|
1222
1526
|
func("pointer", Napi::Function::New(env, CreatePointerType));
|
|
1223
1527
|
func("array", Napi::Function::New(env, CreateArrayType));
|
|
1224
1528
|
func("callback", Napi::Function::New(env, CreateCallbackType));
|
|
1529
|
+
func("alias", Napi::Function::New(env, CreateTypeAlias));
|
|
1225
1530
|
|
|
1226
1531
|
func("sizeof", Napi::Function::New(env, GetTypeSize));
|
|
1227
1532
|
func("alignof", Napi::Function::New(env, GetTypeAlign));
|
|
1533
|
+
func("resolve", Napi::Function::New(env, GetResolvedType));
|
|
1228
1534
|
func("introspect", Napi::Function::New(env, GetTypeDefinition));
|
|
1229
1535
|
|
|
1230
1536
|
func("load", Napi::Function::New(env, LoadSharedLibrary));
|
|
@@ -1233,6 +1539,12 @@ static void SetExports(Napi::Env env, Func func)
|
|
|
1233
1539
|
func("out", Napi::Function::New(env, MarkOut));
|
|
1234
1540
|
func("inout", Napi::Function::New(env, MarkInOut));
|
|
1235
1541
|
|
|
1542
|
+
func("disposable", Napi::Function::New(env, CreateDisposableType));
|
|
1543
|
+
func("free", Napi::Function::New(env, CallFree));
|
|
1544
|
+
|
|
1545
|
+
func("register", Napi::Function::New(env, RegisterCallback));
|
|
1546
|
+
func("unregister", Napi::Function::New(env, UnregisterCallback));
|
|
1547
|
+
|
|
1236
1548
|
#if defined(_WIN32)
|
|
1237
1549
|
func("extension", Napi::String::New(env, ".dll"));
|
|
1238
1550
|
#elif defined(__APPLE__)
|