koffi 2.1.5 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/ChangeLog.md +21 -1
  2. package/doc/Makefile +1 -1
  3. package/doc/callbacks.md +175 -0
  4. package/doc/changes.md +2 -3
  5. package/doc/conf.py +29 -6
  6. package/doc/functions.md +39 -124
  7. package/doc/index.rst +1 -0
  8. package/doc/make.bat +1 -1
  9. package/doc/types.md +36 -9
  10. package/package.json +2 -2
  11. package/src/core/libcc/libcc.cc +89 -27
  12. package/src/core/libcc/libcc.hh +74 -39
  13. package/src/koffi/build/2.2.1/koffi_darwin_arm64.tar.gz +0 -0
  14. package/src/koffi/build/2.2.1/koffi_darwin_x64.tar.gz +0 -0
  15. package/src/koffi/build/2.2.1/koffi_freebsd_arm64.tar.gz +0 -0
  16. package/src/koffi/build/2.2.1/koffi_freebsd_ia32.tar.gz +0 -0
  17. package/src/koffi/build/2.2.1/koffi_freebsd_x64.tar.gz +0 -0
  18. package/src/koffi/build/2.2.1/koffi_linux_arm32hf.tar.gz +0 -0
  19. package/src/koffi/build/2.2.1/koffi_linux_arm64.tar.gz +0 -0
  20. package/src/koffi/build/2.2.1/koffi_linux_ia32.tar.gz +0 -0
  21. package/src/koffi/build/2.2.1/koffi_linux_riscv64hf64.tar.gz +0 -0
  22. package/src/koffi/build/2.2.1/koffi_linux_x64.tar.gz +0 -0
  23. package/src/koffi/build/2.2.1/koffi_openbsd_ia32.tar.gz +0 -0
  24. package/src/koffi/build/2.2.1/koffi_openbsd_x64.tar.gz +0 -0
  25. package/src/koffi/build/2.2.1/koffi_win32_arm64.tar.gz +0 -0
  26. package/src/koffi/build/2.2.1/koffi_win32_ia32.tar.gz +0 -0
  27. package/src/koffi/build/2.2.1/koffi_win32_x64.tar.gz +0 -0
  28. package/src/koffi/qemu/qemu.js +3 -1
  29. package/src/koffi/src/abi_arm32.cc +26 -23
  30. package/src/koffi/src/abi_arm64.cc +25 -22
  31. package/src/koffi/src/abi_riscv64.cc +21 -18
  32. package/src/koffi/src/abi_x64_sysv.cc +20 -17
  33. package/src/koffi/src/abi_x64_win.cc +19 -16
  34. package/src/koffi/src/abi_x86.cc +23 -20
  35. package/src/koffi/src/call.cc +222 -607
  36. package/src/koffi/src/call.hh +7 -11
  37. package/src/koffi/src/ffi.cc +229 -29
  38. package/src/koffi/src/ffi.hh +6 -2
  39. package/src/koffi/src/parser.cc +3 -9
  40. package/src/koffi/src/util.cc +546 -8
  41. package/src/koffi/src/util.hh +8 -2
  42. package/src/koffi/test/CMakeLists.txt +3 -3
  43. package/src/koffi/test/callbacks.js +89 -0
  44. package/src/koffi/test/misc.c +78 -0
  45. package/src/koffi/test/raylib.js +2 -2
  46. package/src/koffi/test/sqlite.js +1 -1
  47. package/src/koffi/test/sync.js +28 -6
  48. package/vendor/brotli/c/common/platform.h +2 -0
  49. package/vendor/sqlite3mc/sqlite3.c +243532 -0
  50. package/vendor/sqlite3mc/sqlite3.h +12887 -0
  51. package/src/koffi/build/2.1.5/koffi_darwin_arm64.tar.gz +0 -0
  52. package/src/koffi/build/2.1.5/koffi_darwin_x64.tar.gz +0 -0
  53. package/src/koffi/build/2.1.5/koffi_freebsd_arm64.tar.gz +0 -0
  54. package/src/koffi/build/2.1.5/koffi_freebsd_ia32.tar.gz +0 -0
  55. package/src/koffi/build/2.1.5/koffi_freebsd_x64.tar.gz +0 -0
  56. package/src/koffi/build/2.1.5/koffi_linux_arm32hf.tar.gz +0 -0
  57. package/src/koffi/build/2.1.5/koffi_linux_arm64.tar.gz +0 -0
  58. package/src/koffi/build/2.1.5/koffi_linux_ia32.tar.gz +0 -0
  59. package/src/koffi/build/2.1.5/koffi_linux_riscv64hf64.tar.gz +0 -0
  60. package/src/koffi/build/2.1.5/koffi_linux_x64.tar.gz +0 -0
  61. package/src/koffi/build/2.1.5/koffi_openbsd_ia32.tar.gz +0 -0
  62. package/src/koffi/build/2.1.5/koffi_openbsd_x64.tar.gz +0 -0
  63. package/src/koffi/build/2.1.5/koffi_win32_arm64.tar.gz +0 -0
  64. package/src/koffi/build/2.1.5/koffi_win32_ia32.tar.gz +0 -0
  65. package/src/koffi/build/2.1.5/koffi_win32_x64.tar.gz +0 -0
@@ -170,16 +170,27 @@ const TypeInfo *MakePointerType(InstanceData *instance, const TypeInfo *ref, int
170
170
  return ref;
171
171
  }
172
172
 
173
- bool CanPassType(const TypeInfo *type)
173
+ bool CanPassType(const TypeInfo *type, int directions)
174
174
  {
175
- if (type->primitive == PrimitiveKind::Void)
176
- return false;
177
- if (type->primitive == PrimitiveKind::Array)
178
- return false;
179
- if (type->primitive == PrimitiveKind::Prototype)
180
- return false;
175
+ if (directions & 2) {
176
+ if (type->primitive == PrimitiveKind::Pointer)
177
+ return true;
178
+ if (type->primitive == PrimitiveKind::String)
179
+ return true;
180
+ if (type->primitive == PrimitiveKind::String16)
181
+ return true;
181
182
 
182
- return true;
183
+ return false;
184
+ } else {
185
+ if (type->primitive == PrimitiveKind::Void)
186
+ return false;
187
+ if (type->primitive == PrimitiveKind::Array)
188
+ return false;
189
+ if (type->primitive == PrimitiveKind::Prototype)
190
+ return false;
191
+
192
+ return true;
193
+ }
183
194
  }
184
195
 
185
196
  bool CanReturnType(const TypeInfo *type)
@@ -298,6 +309,533 @@ int GetTypedArrayType(const TypeInfo *type)
298
309
  RG_UNREACHABLE();
299
310
  }
300
311
 
312
+ Napi::Object DecodeObject(Napi::Env env, const uint8_t *origin, const TypeInfo *type, int16_t realign)
313
+ {
314
+ Napi::Object obj = Napi::Object::New(env);
315
+ DecodeObject(obj, origin, type, realign);
316
+ return obj;
317
+ }
318
+
319
+ void DecodeObject(Napi::Object obj, const uint8_t *origin, const TypeInfo *type, int16_t realign)
320
+ {
321
+ Napi::Env env = obj.Env();
322
+ InstanceData *instance = env.GetInstanceData<InstanceData>();
323
+
324
+ RG_ASSERT(type->primitive == PrimitiveKind::Record);
325
+
326
+ for (Size i = 0; i < type->members.len; i++) {
327
+ const RecordMember &member = type->members[i];
328
+
329
+ Size offset = realign ? (i * realign) : member.offset;
330
+ const uint8_t *src = origin + offset;
331
+
332
+ switch (member.type->primitive) {
333
+ case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
334
+
335
+ case PrimitiveKind::Bool: {
336
+ bool b = *(bool *)src;
337
+ obj.Set(member.name, Napi::Boolean::New(env, b));
338
+ } break;
339
+ case PrimitiveKind::Int8: {
340
+ double d = (double)*(int8_t *)src;
341
+ obj.Set(member.name, Napi::Number::New(env, d));
342
+ } break;
343
+ case PrimitiveKind::UInt8: {
344
+ double d = (double)*(uint8_t *)src;
345
+ obj.Set(member.name, Napi::Number::New(env, d));
346
+ } break;
347
+ case PrimitiveKind::Int16: {
348
+ double d = (double)*(int16_t *)src;
349
+ obj.Set(member.name, Napi::Number::New(env, d));
350
+ } break;
351
+ case PrimitiveKind::Int16S: {
352
+ int16_t v = *(int16_t *)src;
353
+ double d = (double)ReverseBytes(v);
354
+
355
+ obj.Set(member.name, Napi::Number::New(env, d));
356
+ } break;
357
+ case PrimitiveKind::UInt16: {
358
+ double d = (double)*(uint16_t *)src;
359
+ obj.Set(member.name, Napi::Number::New(env, d));
360
+ } break;
361
+ case PrimitiveKind::UInt16S: {
362
+ uint16_t v = *(uint16_t *)src;
363
+ double d = (double)ReverseBytes(v);
364
+
365
+ obj.Set(member.name, Napi::Number::New(env, d));
366
+ } break;
367
+ case PrimitiveKind::Int32: {
368
+ double d = (double)*(int32_t *)src;
369
+ obj.Set(member.name, Napi::Number::New(env, d));
370
+ } break;
371
+ case PrimitiveKind::Int32S: {
372
+ int32_t v = *(int32_t *)src;
373
+ double d = (double)ReverseBytes(v);
374
+
375
+ obj.Set(member.name, Napi::Number::New(env, d));
376
+ } break;
377
+ case PrimitiveKind::UInt32: {
378
+ double d = (double)*(uint32_t *)src;
379
+ obj.Set(member.name, Napi::Number::New(env, d));
380
+ } break;
381
+ case PrimitiveKind::UInt32S: {
382
+ uint32_t v = *(uint32_t *)src;
383
+ double d = (double)ReverseBytes(v);
384
+
385
+ obj.Set(member.name, Napi::Number::New(env, d));
386
+ } break;
387
+ case PrimitiveKind::Int64: {
388
+ int64_t v = *(int64_t *)src;
389
+ obj.Set(member.name, NewBigInt(env, v));
390
+ } break;
391
+ case PrimitiveKind::Int64S: {
392
+ int64_t v = ReverseBytes(*(int64_t *)src);
393
+ obj.Set(member.name, NewBigInt(env, v));
394
+ } break;
395
+ case PrimitiveKind::UInt64: {
396
+ uint64_t v = *(uint64_t *)src;
397
+ obj.Set(member.name, NewBigInt(env, v));
398
+ } break;
399
+ case PrimitiveKind::UInt64S: {
400
+ uint64_t v = ReverseBytes(*(uint64_t *)src);
401
+ obj.Set(member.name, NewBigInt(env, v));
402
+ } break;
403
+ case PrimitiveKind::String: {
404
+ const char *str = *(const char **)src;
405
+ obj.Set(member.name, str ? Napi::String::New(env, str) : env.Null());
406
+
407
+ if (member.type->dispose) {
408
+ member.type->dispose(env, member.type, str);
409
+ }
410
+ } break;
411
+ case PrimitiveKind::String16: {
412
+ const char16_t *str16 = *(const char16_t **)src;
413
+ obj.Set(member.name, str16 ? Napi::String::New(env, str16) : env.Null());
414
+
415
+ if (member.type->dispose) {
416
+ member.type->dispose(env, member.type, str16);
417
+ }
418
+ } break;
419
+ case PrimitiveKind::Pointer:
420
+ case PrimitiveKind::Callback: {
421
+ void *ptr2 = *(void **)src;
422
+
423
+ if (ptr2) {
424
+ Napi::External<void> external = Napi::External<void>::New(env, ptr2);
425
+ SetValueTag(instance, external, member.type->ref.marker);
426
+
427
+ obj.Set(member.name, external);
428
+ } else {
429
+ obj.Set(member.name, env.Null());
430
+ }
431
+
432
+ if (member.type->dispose) {
433
+ member.type->dispose(env, member.type, ptr2);
434
+ }
435
+ } break;
436
+ case PrimitiveKind::Record: {
437
+ Napi::Object obj2 = DecodeObject(env, src, member.type, realign);
438
+ obj.Set(member.name, obj2);
439
+ } break;
440
+ case PrimitiveKind::Array: {
441
+ Napi::Value value = DecodeArray(env, src, member.type, realign);
442
+ obj.Set(member.name, value);
443
+ } break;
444
+ case PrimitiveKind::Float32: {
445
+ float f = *(float *)src;
446
+ obj.Set(member.name, Napi::Number::New(env, (double)f));
447
+ } break;
448
+ case PrimitiveKind::Float64: {
449
+ double d = *(double *)src;
450
+ obj.Set(member.name, Napi::Number::New(env, d));
451
+ } break;
452
+
453
+ case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
454
+ }
455
+ }
456
+ }
457
+
458
+ static Size WideStringLength(const char16_t *str16, Size max)
459
+ {
460
+ Size len = 0;
461
+
462
+ while (len < max && str16[len]) {
463
+ len++;
464
+ }
465
+
466
+ return len;
467
+ }
468
+
469
+ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *type, int16_t realign)
470
+ {
471
+ InstanceData *instance = env.GetInstanceData<InstanceData>();
472
+
473
+ RG_ASSERT(type->primitive == PrimitiveKind::Array);
474
+
475
+ uint32_t len = type->size / type->ref.type->size;
476
+ Size offset = 0;
477
+
478
+ #define POP_ARRAY(SetCode) \
479
+ do { \
480
+ Napi::Array array = Napi::Array::New(env); \
481
+ \
482
+ for (uint32_t i = 0; i < len; i++) { \
483
+ int16_t align = std::max(realign, type->ref.type->align); \
484
+ offset = AlignLen(offset, align); \
485
+ \
486
+ const uint8_t *src = origin + offset; \
487
+ \
488
+ SetCode \
489
+ \
490
+ offset += type->ref.type->size; \
491
+ } \
492
+ \
493
+ return array; \
494
+ } while (false)
495
+ #define POP_NUMBER_ARRAY(TypedArrayType, CType) \
496
+ do { \
497
+ if (type->hint == TypeInfo::ArrayHint::Array) { \
498
+ POP_ARRAY({ \
499
+ double d = (double)*(CType *)src; \
500
+ array.Set(i, Napi::Number::New(env, d)); \
501
+ }); \
502
+ } else { \
503
+ Napi::TypedArrayType array = Napi::TypedArrayType::New(env, len); \
504
+ DecodeTypedArray(array, origin, type->ref.type, realign); \
505
+ \
506
+ return array; \
507
+ } \
508
+ } while (false)
509
+ #define POP_NUMBER_ARRAY_SWAP(TypedArrayType, CType) \
510
+ do { \
511
+ if (type->hint == TypeInfo::ArrayHint::Array) { \
512
+ POP_ARRAY({ \
513
+ CType v = *(CType *)src; \
514
+ double d = (double)ReverseBytes(v); \
515
+ array.Set(i, Napi::Number::New(env, d)); \
516
+ }); \
517
+ } else { \
518
+ Napi::TypedArrayType array = Napi::TypedArrayType::New(env, len); \
519
+ DecodeTypedArray(array, origin, type->ref.type, realign); \
520
+ \
521
+ return array; \
522
+ } \
523
+ } while (false)
524
+
525
+ switch (type->ref.type->primitive) {
526
+ case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
527
+
528
+ case PrimitiveKind::Bool: {
529
+ POP_ARRAY({
530
+ bool b = *(bool *)src;
531
+ array.Set(i, Napi::Boolean::New(env, b));
532
+ });
533
+ } break;
534
+ case PrimitiveKind::Int8: {
535
+ if (type->hint == TypeInfo::ArrayHint::String) {
536
+ RG_ASSERT(!realign);
537
+
538
+ const char *ptr = (const char *)origin;
539
+ size_t count = strnlen(ptr, (size_t)len);
540
+
541
+ Napi::String str = Napi::String::New(env, ptr, count);
542
+ return str;
543
+ }
544
+
545
+ POP_NUMBER_ARRAY(Int8Array, int8_t);
546
+ } break;
547
+ case PrimitiveKind::UInt8: { POP_NUMBER_ARRAY(Uint8Array, uint8_t); } break;
548
+ case PrimitiveKind::Int16: {
549
+ if (type->hint == TypeInfo::ArrayHint::String) {
550
+ RG_ASSERT(!realign);
551
+
552
+ const char16_t *ptr = (const char16_t *)origin;
553
+ Size count = WideStringLength(ptr, len);
554
+
555
+ Napi::String str = Napi::String::New(env, ptr, count);
556
+ return str;
557
+ }
558
+
559
+ POP_NUMBER_ARRAY(Int16Array, int16_t);
560
+ } break;
561
+ case PrimitiveKind::Int16S: { POP_NUMBER_ARRAY_SWAP(Int16Array, int16_t); } break;
562
+ case PrimitiveKind::UInt16: { POP_NUMBER_ARRAY(Uint16Array, uint16_t); } break;
563
+ case PrimitiveKind::UInt16S: { POP_NUMBER_ARRAY_SWAP(Uint16Array, uint16_t); } break;
564
+ case PrimitiveKind::Int32: { POP_NUMBER_ARRAY(Int32Array, int32_t); } break;
565
+ case PrimitiveKind::Int32S: { POP_NUMBER_ARRAY_SWAP(Int32Array, int32_t); } break;
566
+ case PrimitiveKind::UInt32: { POP_NUMBER_ARRAY(Uint32Array, uint32_t); } break;
567
+ case PrimitiveKind::UInt32S: { POP_NUMBER_ARRAY_SWAP(Uint32Array, uint32_t); } break;
568
+ case PrimitiveKind::Int64: {
569
+ POP_ARRAY({
570
+ int64_t v = *(int64_t *)src;
571
+ array.Set(i, NewBigInt(env, v));
572
+ });
573
+ } break;
574
+ case PrimitiveKind::Int64S: {
575
+ POP_ARRAY({
576
+ int64_t v = ReverseBytes(*(int64_t *)src);
577
+ array.Set(i, NewBigInt(env, v));
578
+ });
579
+ } break;
580
+ case PrimitiveKind::UInt64: {
581
+ POP_ARRAY({
582
+ uint64_t v = *(uint64_t *)src;
583
+ array.Set(i, NewBigInt(env, v));
584
+ });
585
+ } break;
586
+ case PrimitiveKind::UInt64S: {
587
+ POP_ARRAY({
588
+ uint64_t v = ReverseBytes(*(uint64_t *)src);
589
+ array.Set(i, NewBigInt(env, v));
590
+ });
591
+ } break;
592
+ case PrimitiveKind::String: {
593
+ POP_ARRAY({
594
+ const char *str = *(const char **)src;
595
+ array.Set(i, str ? Napi::String::New(env, str) : env.Null());
596
+ });
597
+ } break;
598
+ case PrimitiveKind::String16: {
599
+ POP_ARRAY({
600
+ const char16_t *str16 = *(const char16_t **)src;
601
+ array.Set(i, str16 ? Napi::String::New(env, str16) : env.Null());
602
+ });
603
+ } break;
604
+ case PrimitiveKind::Pointer:
605
+ case PrimitiveKind::Callback: {
606
+ POP_ARRAY({
607
+ void *ptr2 = *(void **)src;
608
+
609
+ if (ptr2) {
610
+ Napi::External<void> external = Napi::External<void>::New(env, ptr2);
611
+ SetValueTag(instance, external, type->ref.type->ref.marker);
612
+
613
+ array.Set(i, external);
614
+ } else {
615
+ array.Set(i, env.Null());
616
+ }
617
+ });
618
+ } break;
619
+ case PrimitiveKind::Record: {
620
+ POP_ARRAY({
621
+ Napi::Object obj = DecodeObject(env, src, type->ref.type, realign);
622
+ array.Set(i, obj);
623
+ });
624
+ } break;
625
+ case PrimitiveKind::Array: {
626
+ POP_ARRAY({
627
+ Napi::Value value = DecodeArray(env, src, type->ref.type, realign);
628
+ array.Set(i, value);
629
+ });
630
+ } break;
631
+ case PrimitiveKind::Float32: { POP_NUMBER_ARRAY(Float32Array, float); } break;
632
+ case PrimitiveKind::Float64: { POP_NUMBER_ARRAY(Float64Array, double); } break;
633
+
634
+ case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
635
+ }
636
+
637
+ #undef POP_NUMBER_ARRAY_SWAP
638
+ #undef POP_NUMBER_ARRAY
639
+ #undef POP_ARRAY
640
+
641
+ RG_UNREACHABLE();
642
+ }
643
+
644
+ void DecodeNormalArray(Napi::Array array, const uint8_t *origin, const TypeInfo *ref, int16_t realign)
645
+ {
646
+ Napi::Env env = array.Env();
647
+ InstanceData *instance = env.GetInstanceData<InstanceData>();
648
+
649
+ RG_ASSERT(array.IsArray());
650
+
651
+ Size offset = 0;
652
+ uint32_t len = array.Length();
653
+
654
+ #define POP_ARRAY(SetCode) \
655
+ do { \
656
+ for (uint32_t i = 0; i < len; i++) { \
657
+ int16_t align = std::max(realign, ref->align); \
658
+ offset = AlignLen(offset, align); \
659
+ \
660
+ const uint8_t *src = origin + offset; \
661
+ \
662
+ SetCode \
663
+ \
664
+ offset += ref->size; \
665
+ } \
666
+ } while (false)
667
+ #define POP_NUMBER_ARRAY(CType) \
668
+ do { \
669
+ POP_ARRAY({ \
670
+ double d = (double)*(CType *)src; \
671
+ array.Set(i, Napi::Number::New(env, d)); \
672
+ }); \
673
+ } while (false)
674
+ #define POP_NUMBER_ARRAY_SWAP(CType) \
675
+ do { \
676
+ POP_ARRAY({ \
677
+ CType v = *(CType *)src; \
678
+ double d = (double)ReverseBytes(v); \
679
+ array.Set(i, Napi::Number::New(env, d)); \
680
+ }); \
681
+ } while (false)
682
+
683
+ switch (ref->primitive) {
684
+ case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
685
+
686
+ case PrimitiveKind::Bool: {
687
+ POP_ARRAY({
688
+ bool b = *(bool *)src;
689
+ array.Set(i, Napi::Boolean::New(env, b));
690
+ });
691
+ } break;
692
+ case PrimitiveKind::Int8: { POP_NUMBER_ARRAY(int8_t); } break;
693
+ case PrimitiveKind::UInt8: { POP_NUMBER_ARRAY(uint8_t); } break;
694
+ case PrimitiveKind::Int16: { POP_NUMBER_ARRAY(int16_t); } break;
695
+ case PrimitiveKind::Int16S: { POP_NUMBER_ARRAY_SWAP(int16_t); } break;
696
+ case PrimitiveKind::UInt16: { POP_NUMBER_ARRAY(uint16_t); } break;
697
+ case PrimitiveKind::UInt16S: { POP_NUMBER_ARRAY_SWAP(uint16_t); } break;
698
+ case PrimitiveKind::Int32: { POP_NUMBER_ARRAY(int32_t); } break;
699
+ case PrimitiveKind::Int32S: { POP_NUMBER_ARRAY_SWAP(int32_t); } break;
700
+ case PrimitiveKind::UInt32: { POP_NUMBER_ARRAY(uint32_t); } break;
701
+ case PrimitiveKind::UInt32S: { POP_NUMBER_ARRAY_SWAP(uint32_t); } break;
702
+ case PrimitiveKind::Int64: {
703
+ POP_ARRAY({
704
+ int64_t v = *(int64_t *)src;
705
+ array.Set(i, NewBigInt(env, v));
706
+ });
707
+ } break;
708
+ case PrimitiveKind::Int64S: {
709
+ POP_ARRAY({
710
+ int64_t v = ReverseBytes(*(int64_t *)src);
711
+ array.Set(i, NewBigInt(env, v));
712
+ });
713
+ } break;
714
+ case PrimitiveKind::UInt64: {
715
+ POP_ARRAY({
716
+ uint64_t v = *(uint64_t *)src;
717
+ array.Set(i, NewBigInt(env, v));
718
+ });
719
+ } break;
720
+ case PrimitiveKind::UInt64S: {
721
+ POP_ARRAY({
722
+ uint64_t v = ReverseBytes(*(uint64_t *)src);
723
+ array.Set(i, NewBigInt(env, v));
724
+ });
725
+ } break;
726
+ case PrimitiveKind::String: {
727
+ POP_ARRAY({
728
+ const char *str = *(const char **)src;
729
+ array.Set(i, str ? Napi::String::New(env, str) : env.Null());
730
+
731
+ if (ref->dispose) {
732
+ ref->dispose(env, ref, str);
733
+ }
734
+ });
735
+ } break;
736
+ case PrimitiveKind::String16: {
737
+ POP_ARRAY({
738
+ const char16_t *str16 = *(const char16_t **)src;
739
+ array.Set(i, str16 ? Napi::String::New(env, str16) : env.Null());
740
+
741
+ if (ref->dispose) {
742
+ ref->dispose(env, ref, str16);
743
+ }
744
+ });
745
+ } break;
746
+ case PrimitiveKind::Pointer:
747
+ case PrimitiveKind::Callback: {
748
+ POP_ARRAY({
749
+ void *ptr2 = *(void **)src;
750
+
751
+ if (ptr2) {
752
+ Napi::External<void> external = Napi::External<void>::New(env, ptr2);
753
+ SetValueTag(instance, external, ref->ref.marker);
754
+
755
+ array.Set(i, external);
756
+ } else {
757
+ array.Set(i, env.Null());
758
+ }
759
+
760
+ if (ref->dispose) {
761
+ ref->dispose(env, ref, ptr2);
762
+ }
763
+ });
764
+ } break;
765
+ case PrimitiveKind::Record: {
766
+ POP_ARRAY({
767
+ Napi::Object obj = DecodeObject(env, src, ref, realign);
768
+ array.Set(i, obj);
769
+ });
770
+ } break;
771
+ case PrimitiveKind::Array: {
772
+ POP_ARRAY({
773
+ Napi::Value value = DecodeArray(env, src, ref, realign);
774
+ array.Set(i, value);
775
+ });
776
+ } break;
777
+ case PrimitiveKind::Float32: { POP_NUMBER_ARRAY(float); } break;
778
+ case PrimitiveKind::Float64: { POP_NUMBER_ARRAY(double); } break;
779
+
780
+ case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
781
+ }
782
+
783
+ #undef POP_NUMBER_ARRAY_SWAP
784
+ #undef POP_NUMBER_ARRAY
785
+ #undef POP_ARRAY
786
+ }
787
+
788
+ void DecodeTypedArray(Napi::TypedArray array, const uint8_t *origin, const TypeInfo *ref, int16_t realign)
789
+ {
790
+ Napi::Env env = array.Env();
791
+ InstanceData *instance = env.GetInstanceData<InstanceData>();
792
+
793
+ RG_ASSERT(array.IsTypedArray());
794
+ RG_ASSERT(GetTypedArrayType(ref) == array.TypedArrayType() ||
795
+ ref == instance->void_type);
796
+
797
+ uint8_t *buf = (uint8_t *)array.ArrayBuffer().Data();
798
+
799
+ if (realign) {
800
+ Size offset = 0;
801
+ Size len = (Size)array.ElementLength();
802
+ Size size = (Size)array.ElementSize();
803
+
804
+ for (Size i = 0; i < len; i++) {
805
+ offset = AlignLen(offset, realign);
806
+
807
+ uint8_t *dest = buf + i * size;
808
+ const uint8_t *src = origin + offset;
809
+
810
+ memcpy(dest, src, size);
811
+
812
+ offset += size;
813
+ }
814
+ } else {
815
+ memcpy_safe(buf, origin, (size_t)array.ByteLength());
816
+ }
817
+
818
+ #define SWAP(CType) \
819
+ do { \
820
+ CType *data = (CType *)buf; \
821
+ Size len = (Size)array.ElementLength(); \
822
+ \
823
+ for (Size i = 0; i < len; i++) { \
824
+ data[i] = ReverseBytes(data[i]); \
825
+ } \
826
+ } while (false)
827
+
828
+ if (ref->primitive == PrimitiveKind::Int16S || ref->primitive == PrimitiveKind::UInt16S) {
829
+ SWAP(uint16_t);
830
+ } else if (ref->primitive == PrimitiveKind::Int32S || ref->primitive == PrimitiveKind::UInt32S) {
831
+ SWAP(uint32_t);
832
+ } else if (ref->primitive == PrimitiveKind::Int64S || ref->primitive == PrimitiveKind::UInt64S) {
833
+ SWAP(uint64_t);
834
+ }
835
+
836
+ #undef SWAP
837
+ }
838
+
301
839
  static int AnalyseFlatRec(const TypeInfo *type, int offset, int count, FunctionRef<void(const TypeInfo *type, int offset, int count)> func)
302
840
  {
303
841
  if (type->primitive == PrimitiveKind::Record) {
@@ -57,7 +57,7 @@ const TypeInfo *ResolveType(Napi::Value value, int *out_directions = nullptr);
57
57
  const TypeInfo *ResolveType(InstanceData *instance, Span<const char> str, int *out_directions = nullptr);
58
58
  const TypeInfo *MakePointerType(InstanceData *instance, const TypeInfo *type, int count = 1);
59
59
 
60
- bool CanPassType(const TypeInfo *type);
60
+ bool CanPassType(const TypeInfo *type, int directions);
61
61
  bool CanReturnType(const TypeInfo *type);
62
62
  bool CanStoreType(const TypeInfo *type);
63
63
 
@@ -80,7 +80,7 @@ static inline bool IsObject(Napi::Value value)
80
80
  int GetTypedArrayType(const TypeInfo *type);
81
81
 
82
82
  template <typename T>
83
- T CopyNumber(Napi::Value value)
83
+ T GetNumber(Napi::Value value)
84
84
  {
85
85
  RG_ASSERT(value.IsNumber() || value.IsBigInt());
86
86
 
@@ -96,6 +96,12 @@ T CopyNumber(Napi::Value value)
96
96
  RG_UNREACHABLE();
97
97
  }
98
98
 
99
+ Napi::Object DecodeObject(Napi::Env env, const uint8_t *origin, const TypeInfo *type, int16_t realign = 0);
100
+ void DecodeObject(Napi::Object obj, const uint8_t *origin, const TypeInfo *type, int16_t realign = 0);
101
+ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *type, int16_t realign = 0);
102
+ void DecodeNormalArray(Napi::Array array, const uint8_t *origin, const TypeInfo *ref, int16_t realign = 0);
103
+ void DecodeTypedArray(Napi::TypedArray array, const uint8_t *origin, const TypeInfo *ref, int16_t realign = 0);
104
+
99
105
  static inline Napi::Value NewBigInt(Napi::Env env, int64_t value)
100
106
  {
101
107
  if (value <= 9007199254740992ll && value >= -9007199254740992ll) {
@@ -100,11 +100,11 @@ endif()
100
100
 
101
101
  # ---- SQLite ----
102
102
 
103
- add_library(sqlite3mc SHARED ../../../vendor/sqlite3mc/sqlite3mc.c)
104
- set_target_properties(sqlite3mc PROPERTIES PREFIX "")
103
+ add_library(sqlite3 SHARED ../../../vendor/sqlite3mc/sqlite3.c)
104
+ set_target_properties(sqlite3 PROPERTIES PREFIX "")
105
105
 
106
106
  if(WIN32)
107
- target_compile_definitions(sqlite3mc PRIVATE SQLITE_API=__declspec\(dllexport\))
107
+ target_compile_definitions(sqlite3 PRIVATE SQLITE_API=__declspec\(dllexport\))
108
108
  endif()
109
109
 
110
110
  # ---- Misc ----