koffi 2.0.1 → 2.1.0-beta.3
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 +2 -9
- package/ChangeLog.md +17 -0
- package/benchmark/atoi_koffi.js +12 -8
- package/benchmark/atoi_napi.js +12 -8
- package/benchmark/atoi_node_ffi.js +11 -10
- package/benchmark/raylib_cc.cc +12 -9
- package/benchmark/raylib_koffi.js +15 -13
- package/benchmark/raylib_node_ffi.js +15 -13
- package/benchmark/raylib_node_raylib.js +14 -11
- package/build/qemu/2.1.0-beta.3/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.3/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.3/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.3/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.3/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.3/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.3/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.3/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.3/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.3/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.3/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.3/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.3/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.3/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.3/koffi_win32_x64.tar.gz +0 -0
- package/doc/Makefile +1 -1
- package/doc/changes.md +12 -8
- package/doc/conf.py +5 -0
- 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/index.doctree +0 -0
- package/doc/dist/doctrees/types.doctree +0 -0
- package/doc/dist/html/.buildinfo +1 -1
- package/doc/dist/html/_sources/changes.md.txt +12 -8
- package/doc/dist/html/_sources/functions.md.txt +71 -5
- package/doc/dist/html/_sources/types.md.txt +147 -159
- package/doc/dist/html/benchmarks.html +2 -3
- package/doc/dist/html/changes.html +64 -35
- package/doc/dist/html/contribute.html +2 -3
- package/doc/dist/html/functions.html +73 -12
- package/doc/dist/html/genindex.html +2 -3
- package/doc/dist/html/index.html +6 -7
- package/doc/dist/html/memory.html +2 -3
- package/doc/dist/html/objects.inv +0 -0
- package/doc/dist/html/platforms.html +3 -4
- package/doc/dist/html/search.html +2 -3
- package/doc/dist/html/searchindex.js +1 -1
- package/doc/dist/html/start.html +2 -3
- package/doc/dist/html/types.html +238 -237
- package/doc/functions.md +71 -5
- package/doc/make.bat +1 -1
- package/doc/templates/badges.html +1 -2
- package/doc/types.md +149 -159
- package/package.json +3 -2
- package/qemu/qemu.js +1 -1
- package/src/abi_arm32.cc +208 -102
- package/src/abi_arm64.cc +239 -55
- package/src/abi_riscv64.cc +128 -40
- package/src/abi_x64_sysv.cc +135 -41
- package/src/abi_x64_win.cc +134 -40
- package/src/abi_x86.cc +182 -67
- package/src/call.cc +241 -26
- package/src/call.hh +15 -3
- package/src/ffi.cc +120 -31
- package/src/ffi.hh +19 -0
- package/src/index.js +4 -2
- package/src/parser.cc +3 -5
- package/src/util.cc +44 -1
- package/src/util.hh +4 -0
- package/test/async.js +1 -2
- package/test/callbacks.js +2 -3
- package/test/misc.c +64 -1
- package/test/raylib.js +1 -1
- package/test/sqlite.js +3 -3
- package/test/sync.js +108 -3
- package/build/qemu/2.0.1/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/2.0.1/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/2.0.1/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/2.0.1/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/2.0.1/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/2.0.1/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/2.0.1/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/2.0.1/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/2.0.1/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/2.0.1/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/2.0.1/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/2.0.1/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/2.0.1/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/2.0.1/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/2.0.1/koffi_win32_x64.tar.gz +0 -0
package/src/call.cc
CHANGED
|
@@ -178,6 +178,15 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
178
178
|
int16_t v = CopyNumber<int16_t>(value);
|
|
179
179
|
*(int16_t *)dest = v;
|
|
180
180
|
} break;
|
|
181
|
+
case PrimitiveKind::Int16S: {
|
|
182
|
+
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
183
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
int16_t v = CopyNumber<int16_t>(value);
|
|
188
|
+
*(int16_t *)dest = ReverseBytes(v);
|
|
189
|
+
} break;
|
|
181
190
|
case PrimitiveKind::UInt16: {
|
|
182
191
|
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
183
192
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
|
|
@@ -187,6 +196,15 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
187
196
|
uint16_t v = CopyNumber<uint16_t>(value);
|
|
188
197
|
*(uint16_t *)dest = v;
|
|
189
198
|
} break;
|
|
199
|
+
case PrimitiveKind::UInt16S: {
|
|
200
|
+
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
201
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
uint16_t v = CopyNumber<uint16_t>(value);
|
|
206
|
+
*(uint16_t *)dest = ReverseBytes(v);
|
|
207
|
+
} break;
|
|
190
208
|
case PrimitiveKind::Int32: {
|
|
191
209
|
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
192
210
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
|
|
@@ -196,6 +214,15 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
196
214
|
int32_t v = CopyNumber<int32_t>(value);
|
|
197
215
|
*(int32_t *)dest = v;
|
|
198
216
|
} break;
|
|
217
|
+
case PrimitiveKind::Int32S: {
|
|
218
|
+
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
219
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
int32_t v = CopyNumber<int32_t>(value);
|
|
224
|
+
*(int32_t *)dest = ReverseBytes(v);
|
|
225
|
+
} break;
|
|
199
226
|
case PrimitiveKind::UInt32: {
|
|
200
227
|
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
201
228
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
|
|
@@ -205,6 +232,15 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
205
232
|
uint32_t v = CopyNumber<uint32_t>(value);
|
|
206
233
|
*(uint32_t *)dest = v;
|
|
207
234
|
} break;
|
|
235
|
+
case PrimitiveKind::UInt32S: {
|
|
236
|
+
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
237
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
uint32_t v = CopyNumber<uint32_t>(value);
|
|
242
|
+
*(uint32_t *)dest = ReverseBytes(v);
|
|
243
|
+
} break;
|
|
208
244
|
case PrimitiveKind::Int64: {
|
|
209
245
|
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
210
246
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
|
|
@@ -214,6 +250,15 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
214
250
|
int64_t v = CopyNumber<int64_t>(value);
|
|
215
251
|
*(int64_t *)dest = v;
|
|
216
252
|
} break;
|
|
253
|
+
case PrimitiveKind::Int64S: {
|
|
254
|
+
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
255
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
int64_t v = CopyNumber<int64_t>(value);
|
|
260
|
+
*(int64_t *)dest = ReverseBytes(v);
|
|
261
|
+
} break;
|
|
217
262
|
case PrimitiveKind::UInt64: {
|
|
218
263
|
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
219
264
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
|
|
@@ -223,6 +268,15 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
223
268
|
uint64_t v = CopyNumber<uint64_t>(value);
|
|
224
269
|
*(uint64_t *)dest = v;
|
|
225
270
|
} break;
|
|
271
|
+
case PrimitiveKind::UInt64S: {
|
|
272
|
+
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
273
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
uint64_t v = CopyNumber<uint64_t>(value);
|
|
278
|
+
*(uint64_t *)dest = ReverseBytes(v);
|
|
279
|
+
} break;
|
|
226
280
|
case PrimitiveKind::String: {
|
|
227
281
|
const char *str;
|
|
228
282
|
if (RG_LIKELY(value.IsString())) {
|
|
@@ -402,36 +456,72 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
|
|
|
402
456
|
*(int16_t *)dest = v;
|
|
403
457
|
});
|
|
404
458
|
} break;
|
|
459
|
+
case PrimitiveKind::Int16S: {
|
|
460
|
+
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
461
|
+
int16_t v = CopyNumber<int16_t>(value);
|
|
462
|
+
*(int16_t *)dest = ReverseBytes(v);
|
|
463
|
+
});
|
|
464
|
+
} break;
|
|
405
465
|
case PrimitiveKind::UInt16: {
|
|
406
466
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
407
467
|
uint16_t v = CopyNumber<uint16_t>(value);
|
|
408
468
|
*(uint16_t *)dest = v;
|
|
409
469
|
});
|
|
410
470
|
} break;
|
|
471
|
+
case PrimitiveKind::UInt16S: {
|
|
472
|
+
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
473
|
+
uint16_t v = CopyNumber<uint16_t>(value);
|
|
474
|
+
*(uint16_t *)dest = ReverseBytes(v);
|
|
475
|
+
});
|
|
476
|
+
} break;
|
|
411
477
|
case PrimitiveKind::Int32: {
|
|
412
478
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
413
479
|
int32_t v = CopyNumber<int32_t>(value);
|
|
414
480
|
*(int32_t *)dest = v;
|
|
415
481
|
});
|
|
416
482
|
} break;
|
|
483
|
+
case PrimitiveKind::Int32S: {
|
|
484
|
+
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
485
|
+
int32_t v = CopyNumber<int32_t>(value);
|
|
486
|
+
*(int32_t *)dest = ReverseBytes(v);
|
|
487
|
+
});
|
|
488
|
+
} break;
|
|
417
489
|
case PrimitiveKind::UInt32: {
|
|
418
490
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
419
491
|
uint32_t v = CopyNumber<uint32_t>(value);
|
|
420
492
|
*(uint32_t *)dest = v;
|
|
421
493
|
});
|
|
422
494
|
} break;
|
|
495
|
+
case PrimitiveKind::UInt32S: {
|
|
496
|
+
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
497
|
+
uint32_t v = CopyNumber<uint32_t>(value);
|
|
498
|
+
*(uint32_t *)dest = ReverseBytes(v);
|
|
499
|
+
});
|
|
500
|
+
} break;
|
|
423
501
|
case PrimitiveKind::Int64: {
|
|
424
502
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
425
503
|
int64_t v = CopyNumber<int64_t>(value);
|
|
426
504
|
*(int64_t *)dest = v;
|
|
427
505
|
});
|
|
428
506
|
} break;
|
|
507
|
+
case PrimitiveKind::Int64S: {
|
|
508
|
+
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
509
|
+
int64_t v = CopyNumber<int64_t>(value);
|
|
510
|
+
*(int64_t *)dest = ReverseBytes(v);
|
|
511
|
+
});
|
|
512
|
+
} break;
|
|
429
513
|
case PrimitiveKind::UInt64: {
|
|
430
514
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
431
515
|
uint64_t v = CopyNumber<uint64_t>(value);
|
|
432
516
|
*(uint64_t *)dest = v;
|
|
433
517
|
});
|
|
434
518
|
} break;
|
|
519
|
+
case PrimitiveKind::UInt64S: {
|
|
520
|
+
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
521
|
+
uint64_t v = CopyNumber<uint64_t>(value);
|
|
522
|
+
*(uint64_t *)dest = ReverseBytes(v);
|
|
523
|
+
});
|
|
524
|
+
} break;
|
|
435
525
|
case PrimitiveKind::String: {
|
|
436
526
|
PUSH_ARRAY(value.IsString() || IsNullOrUndefined(value), "string", {
|
|
437
527
|
if (!IsNullOrUndefined(value)) {
|
|
@@ -567,24 +657,26 @@ bool CallData::PushTypedArray(Napi::TypedArray array, Size len, const TypeInfo *
|
|
|
567
657
|
return false;
|
|
568
658
|
}
|
|
569
659
|
|
|
570
|
-
Size offset = 0;
|
|
571
660
|
const uint8_t *buf = (const uint8_t *)array.ArrayBuffer().Data();
|
|
572
661
|
|
|
573
|
-
if (RG_UNLIKELY(array.TypedArrayType() != GetTypedArrayType(ref)
|
|
662
|
+
if (RG_UNLIKELY(array.TypedArrayType() != GetTypedArrayType(ref) &&
|
|
663
|
+
ref != instance->void_type)) {
|
|
574
664
|
ThrowError<Napi::TypeError>(env, "Cannot use %1 value for %2 array", GetValueType(instance, array), ref->name);
|
|
575
665
|
return false;
|
|
576
666
|
}
|
|
577
667
|
|
|
578
668
|
if (realign) {
|
|
669
|
+
Size offset = 0;
|
|
670
|
+
Size size = (Size)array.ElementSize();
|
|
671
|
+
|
|
579
672
|
for (uint32_t i = 0; i < len; i++) {
|
|
580
|
-
|
|
581
|
-
offset = AlignLen(offset, align);
|
|
673
|
+
offset = AlignLen(offset, realign);
|
|
582
674
|
|
|
583
675
|
uint8_t *dest = origin + offset;
|
|
676
|
+
const uint8_t *src = buf + i * size;
|
|
584
677
|
|
|
585
|
-
memcpy(dest,
|
|
586
|
-
|
|
587
|
-
offset += ref->size;
|
|
678
|
+
memcpy(dest, src, size);
|
|
679
|
+
offset += size;
|
|
588
680
|
}
|
|
589
681
|
} else {
|
|
590
682
|
memcpy_safe(origin, buf, (size_t)array.ByteLength());
|
|
@@ -625,6 +717,16 @@ bool CallData::PushStringArray(Napi::Value obj, const TypeInfo *type, uint8_t *o
|
|
|
625
717
|
|
|
626
718
|
bool CallData::PushPointer(Napi::Value value, const ParameterInfo ¶m, void **out_ptr)
|
|
627
719
|
{
|
|
720
|
+
const TypeInfo *type = param.type;
|
|
721
|
+
|
|
722
|
+
if (CheckValueTag(instance, value, &CastMarker)) {
|
|
723
|
+
Napi::External<ValueCast> external = value.As<Napi::External<ValueCast>>();
|
|
724
|
+
ValueCast *cast = external.Data();
|
|
725
|
+
|
|
726
|
+
value = cast->ref.Value();
|
|
727
|
+
type = cast->type;
|
|
728
|
+
}
|
|
729
|
+
|
|
628
730
|
switch (value.Type()) {
|
|
629
731
|
case napi_undefined:
|
|
630
732
|
case napi_null: {
|
|
@@ -633,9 +735,11 @@ bool CallData::PushPointer(Napi::Value value, const ParameterInfo ¶m, void *
|
|
|
633
735
|
} break;
|
|
634
736
|
|
|
635
737
|
case napi_external: {
|
|
636
|
-
RG_ASSERT(
|
|
738
|
+
RG_ASSERT(type->primitive == PrimitiveKind::Pointer);
|
|
637
739
|
|
|
638
|
-
if (RG_UNLIKELY(!CheckValueTag(instance, value,
|
|
740
|
+
if (RG_UNLIKELY(!CheckValueTag(instance, value, type->ref.marker) &&
|
|
741
|
+
!CheckValueTag(instance, value, instance->void_type) &&
|
|
742
|
+
type->ref.type != instance->void_type))
|
|
639
743
|
goto unexpected;
|
|
640
744
|
|
|
641
745
|
*out_ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
@@ -649,12 +753,12 @@ bool CallData::PushPointer(Napi::Value value, const ParameterInfo ¶m, void *
|
|
|
649
753
|
Napi::Array array = value.As<Napi::Array>();
|
|
650
754
|
|
|
651
755
|
Size len = (Size)array.Length();
|
|
652
|
-
Size size = len *
|
|
756
|
+
Size size = len * type->ref.type->size;
|
|
653
757
|
|
|
654
758
|
ptr = AllocHeap(size, 16);
|
|
655
759
|
|
|
656
760
|
if (param.directions & 1) {
|
|
657
|
-
if (!PushNormalArray(array, len,
|
|
761
|
+
if (!PushNormalArray(array, len, type->ref.type, ptr))
|
|
658
762
|
return false;
|
|
659
763
|
} else {
|
|
660
764
|
memset(ptr, 0, size);
|
|
@@ -668,27 +772,28 @@ bool CallData::PushPointer(Napi::Value value, const ParameterInfo ¶m, void *
|
|
|
668
772
|
ptr = AllocHeap(size, 16);
|
|
669
773
|
|
|
670
774
|
if (param.directions & 1) {
|
|
671
|
-
if (!PushTypedArray(array, len,
|
|
775
|
+
if (!PushTypedArray(array, len, type->ref.type, ptr))
|
|
672
776
|
return false;
|
|
673
777
|
} else {
|
|
674
|
-
if (RG_UNLIKELY(array.TypedArrayType() != GetTypedArrayType(
|
|
675
|
-
|
|
778
|
+
if (RG_UNLIKELY(array.TypedArrayType() != GetTypedArrayType(type->ref.type) &&
|
|
779
|
+
type->ref.type != instance->void_type)) {
|
|
780
|
+
ThrowError<Napi::TypeError>(env, "Cannot use %1 value for %2 array", GetValueType(instance, array), type->ref.type->name);
|
|
676
781
|
return false;
|
|
677
782
|
}
|
|
678
783
|
|
|
679
784
|
memset(ptr, 0, size);
|
|
680
785
|
}
|
|
681
|
-
} else if (RG_LIKELY(
|
|
786
|
+
} else if (RG_LIKELY(type->ref.type->primitive == PrimitiveKind::Record)) {
|
|
682
787
|
Napi::Object obj = value.As<Napi::Object>();
|
|
683
788
|
RG_ASSERT(IsObject(value));
|
|
684
789
|
|
|
685
|
-
ptr = AllocHeap(
|
|
790
|
+
ptr = AllocHeap(type->ref.type->size, 16);
|
|
686
791
|
|
|
687
792
|
if (param.directions & 1) {
|
|
688
|
-
if (!PushObject(obj,
|
|
793
|
+
if (!PushObject(obj, type->ref.type, ptr))
|
|
689
794
|
return false;
|
|
690
795
|
} else {
|
|
691
|
-
memset(ptr, 0,
|
|
796
|
+
memset(ptr, 0, type->size);
|
|
692
797
|
}
|
|
693
798
|
} else {
|
|
694
799
|
goto unexpected;
|
|
@@ -701,7 +806,7 @@ bool CallData::PushPointer(Napi::Value value, const ParameterInfo ¶m, void *
|
|
|
701
806
|
RG_ASSERT(status == napi_ok);
|
|
702
807
|
|
|
703
808
|
out->ptr = ptr;
|
|
704
|
-
out->type =
|
|
809
|
+
out->type = type->ref.type;
|
|
705
810
|
}
|
|
706
811
|
|
|
707
812
|
*out_ptr = ptr;
|
|
@@ -712,7 +817,7 @@ bool CallData::PushPointer(Napi::Value value, const ParameterInfo ¶m, void *
|
|
|
712
817
|
}
|
|
713
818
|
|
|
714
819
|
unexpected:
|
|
715
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected %3", GetValueType(instance, value), param.offset + 1,
|
|
820
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected %3", GetValueType(instance, value), param.offset + 1, type->name);
|
|
716
821
|
return false;
|
|
717
822
|
}
|
|
718
823
|
|
|
@@ -804,26 +909,58 @@ void CallData::PopObject(Napi::Object obj, const uint8_t *origin, const TypeInfo
|
|
|
804
909
|
double d = (double)*(int16_t *)src;
|
|
805
910
|
obj.Set(member.name, Napi::Number::New(env, d));
|
|
806
911
|
} break;
|
|
912
|
+
case PrimitiveKind::Int16S: {
|
|
913
|
+
int16_t v = *(int16_t *)src;
|
|
914
|
+
double d = (double)ReverseBytes(v);
|
|
915
|
+
|
|
916
|
+
obj.Set(member.name, Napi::Number::New(env, d));
|
|
917
|
+
} break;
|
|
807
918
|
case PrimitiveKind::UInt16: {
|
|
808
919
|
double d = (double)*(uint16_t *)src;
|
|
809
920
|
obj.Set(member.name, Napi::Number::New(env, d));
|
|
810
921
|
} break;
|
|
922
|
+
case PrimitiveKind::UInt16S: {
|
|
923
|
+
uint16_t v = *(uint16_t *)src;
|
|
924
|
+
double d = (double)ReverseBytes(v);
|
|
925
|
+
|
|
926
|
+
obj.Set(member.name, Napi::Number::New(env, d));
|
|
927
|
+
} break;
|
|
811
928
|
case PrimitiveKind::Int32: {
|
|
812
929
|
double d = (double)*(int32_t *)src;
|
|
813
930
|
obj.Set(member.name, Napi::Number::New(env, d));
|
|
814
931
|
} break;
|
|
932
|
+
case PrimitiveKind::Int32S: {
|
|
933
|
+
int32_t v = *(int32_t *)src;
|
|
934
|
+
double d = (double)ReverseBytes(v);
|
|
935
|
+
|
|
936
|
+
obj.Set(member.name, Napi::Number::New(env, d));
|
|
937
|
+
} break;
|
|
815
938
|
case PrimitiveKind::UInt32: {
|
|
816
939
|
double d = (double)*(uint32_t *)src;
|
|
817
940
|
obj.Set(member.name, Napi::Number::New(env, d));
|
|
818
941
|
} break;
|
|
942
|
+
case PrimitiveKind::UInt32S: {
|
|
943
|
+
uint32_t v = *(uint32_t *)src;
|
|
944
|
+
double d = (double)ReverseBytes(v);
|
|
945
|
+
|
|
946
|
+
obj.Set(member.name, Napi::Number::New(env, d));
|
|
947
|
+
} break;
|
|
819
948
|
case PrimitiveKind::Int64: {
|
|
820
949
|
int64_t v = *(int64_t *)src;
|
|
821
950
|
obj.Set(member.name, NewBigInt(env, v));
|
|
822
951
|
} break;
|
|
952
|
+
case PrimitiveKind::Int64S: {
|
|
953
|
+
int64_t v = ReverseBytes(*(int64_t *)src);
|
|
954
|
+
obj.Set(member.name, NewBigInt(env, v));
|
|
955
|
+
} break;
|
|
823
956
|
case PrimitiveKind::UInt64: {
|
|
824
957
|
uint64_t v = *(uint64_t *)src;
|
|
825
958
|
obj.Set(member.name, NewBigInt(env, v));
|
|
826
959
|
} break;
|
|
960
|
+
case PrimitiveKind::UInt64S: {
|
|
961
|
+
uint64_t v = ReverseBytes(*(uint64_t *)src);
|
|
962
|
+
obj.Set(member.name, NewBigInt(env, v));
|
|
963
|
+
} break;
|
|
827
964
|
case PrimitiveKind::String: {
|
|
828
965
|
const char *str = *(const char **)src;
|
|
829
966
|
obj.Set(member.name, str ? Napi::String::New(env, str) : env.Null());
|
|
@@ -924,6 +1061,14 @@ void CallData::PopNormalArray(Napi::Array array, const uint8_t *origin, const Ty
|
|
|
924
1061
|
array.Set(i, Napi::Number::New(env, d)); \
|
|
925
1062
|
}); \
|
|
926
1063
|
} while (false)
|
|
1064
|
+
#define POP_NUMBER_ARRAY_SWAP(CType) \
|
|
1065
|
+
do { \
|
|
1066
|
+
POP_ARRAY({ \
|
|
1067
|
+
CType v = *(CType *)src; \
|
|
1068
|
+
double d = (double)ReverseBytes(v); \
|
|
1069
|
+
array.Set(i, Napi::Number::New(env, d)); \
|
|
1070
|
+
}); \
|
|
1071
|
+
} while (false)
|
|
927
1072
|
|
|
928
1073
|
switch (ref->primitive) {
|
|
929
1074
|
case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
|
|
@@ -937,21 +1082,37 @@ void CallData::PopNormalArray(Napi::Array array, const uint8_t *origin, const Ty
|
|
|
937
1082
|
case PrimitiveKind::Int8: { POP_NUMBER_ARRAY(int8_t); } break;
|
|
938
1083
|
case PrimitiveKind::UInt8: { POP_NUMBER_ARRAY(uint8_t); } break;
|
|
939
1084
|
case PrimitiveKind::Int16: { POP_NUMBER_ARRAY(int16_t); } break;
|
|
1085
|
+
case PrimitiveKind::Int16S: { POP_NUMBER_ARRAY_SWAP(int16_t); } break;
|
|
940
1086
|
case PrimitiveKind::UInt16: { POP_NUMBER_ARRAY(uint16_t); } break;
|
|
1087
|
+
case PrimitiveKind::UInt16S: { POP_NUMBER_ARRAY_SWAP(uint16_t); } break;
|
|
941
1088
|
case PrimitiveKind::Int32: { POP_NUMBER_ARRAY(int32_t); } break;
|
|
1089
|
+
case PrimitiveKind::Int32S: { POP_NUMBER_ARRAY_SWAP(int32_t); } break;
|
|
942
1090
|
case PrimitiveKind::UInt32: { POP_NUMBER_ARRAY(uint32_t); } break;
|
|
1091
|
+
case PrimitiveKind::UInt32S: { POP_NUMBER_ARRAY_SWAP(uint32_t); } break;
|
|
943
1092
|
case PrimitiveKind::Int64: {
|
|
944
1093
|
POP_ARRAY({
|
|
945
1094
|
int64_t v = *(int64_t *)src;
|
|
946
1095
|
array.Set(i, NewBigInt(env, v));
|
|
947
1096
|
});
|
|
948
1097
|
} break;
|
|
1098
|
+
case PrimitiveKind::Int64S: {
|
|
1099
|
+
POP_ARRAY({
|
|
1100
|
+
int64_t v = ReverseBytes(*(int64_t *)src);
|
|
1101
|
+
array.Set(i, NewBigInt(env, v));
|
|
1102
|
+
});
|
|
1103
|
+
} break;
|
|
949
1104
|
case PrimitiveKind::UInt64: {
|
|
950
1105
|
POP_ARRAY({
|
|
951
1106
|
uint64_t v = *(uint64_t *)src;
|
|
952
1107
|
array.Set(i, NewBigInt(env, v));
|
|
953
1108
|
});
|
|
954
1109
|
} break;
|
|
1110
|
+
case PrimitiveKind::UInt64S: {
|
|
1111
|
+
POP_ARRAY({
|
|
1112
|
+
uint64_t v = ReverseBytes(*(uint64_t *)src);
|
|
1113
|
+
array.Set(i, NewBigInt(env, v));
|
|
1114
|
+
});
|
|
1115
|
+
} break;
|
|
955
1116
|
case PrimitiveKind::String: {
|
|
956
1117
|
POP_ARRAY({
|
|
957
1118
|
const char *str = *(const char **)src;
|
|
@@ -1009,6 +1170,7 @@ void CallData::PopNormalArray(Napi::Array array, const uint8_t *origin, const Ty
|
|
|
1009
1170
|
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
1010
1171
|
}
|
|
1011
1172
|
|
|
1173
|
+
#undef POP_NUMBER_ARRAY_SWAP
|
|
1012
1174
|
#undef POP_NUMBER_ARRAY
|
|
1013
1175
|
#undef POP_ARRAY
|
|
1014
1176
|
}
|
|
@@ -1016,28 +1178,49 @@ void CallData::PopNormalArray(Napi::Array array, const uint8_t *origin, const Ty
|
|
|
1016
1178
|
void CallData::PopTypedArray(Napi::TypedArray array, const uint8_t *origin, const TypeInfo *ref, int16_t realign)
|
|
1017
1179
|
{
|
|
1018
1180
|
RG_ASSERT(array.IsTypedArray());
|
|
1019
|
-
RG_ASSERT(GetTypedArrayType(ref) == array.TypedArrayType()
|
|
1181
|
+
RG_ASSERT(GetTypedArrayType(ref) == array.TypedArrayType() ||
|
|
1182
|
+
ref == instance->void_type);
|
|
1020
1183
|
|
|
1021
1184
|
uint8_t *buf = (uint8_t *)array.ArrayBuffer().Data();
|
|
1022
1185
|
|
|
1023
1186
|
if (realign) {
|
|
1024
1187
|
Size offset = 0;
|
|
1025
1188
|
Size len = (Size)array.ElementLength();
|
|
1189
|
+
Size size = (Size)array.ElementSize();
|
|
1026
1190
|
|
|
1027
1191
|
for (Size i = 0; i < len; i++) {
|
|
1028
|
-
|
|
1029
|
-
offset = AlignLen(offset, align);
|
|
1192
|
+
offset = AlignLen(offset, realign);
|
|
1030
1193
|
|
|
1031
|
-
uint8_t *dest = buf + i *
|
|
1194
|
+
uint8_t *dest = buf + i * size;
|
|
1032
1195
|
const uint8_t *src = origin + offset;
|
|
1033
1196
|
|
|
1034
|
-
memcpy(dest, src,
|
|
1197
|
+
memcpy(dest, src, size);
|
|
1035
1198
|
|
|
1036
|
-
offset +=
|
|
1199
|
+
offset += size;
|
|
1037
1200
|
}
|
|
1038
1201
|
} else {
|
|
1039
1202
|
memcpy_safe(buf, origin, (size_t)array.ByteLength());
|
|
1040
1203
|
}
|
|
1204
|
+
|
|
1205
|
+
#define SWAP(CType) \
|
|
1206
|
+
do { \
|
|
1207
|
+
CType *data = (CType *)buf; \
|
|
1208
|
+
Size len = (Size)array.ElementLength(); \
|
|
1209
|
+
\
|
|
1210
|
+
for (Size i = 0; i < len; i++) { \
|
|
1211
|
+
data[i] = ReverseBytes(data[i]); \
|
|
1212
|
+
} \
|
|
1213
|
+
} while (false)
|
|
1214
|
+
|
|
1215
|
+
if (ref->primitive == PrimitiveKind::Int16S || ref->primitive == PrimitiveKind::UInt16S) {
|
|
1216
|
+
SWAP(uint16_t);
|
|
1217
|
+
} else if (ref->primitive == PrimitiveKind::Int32S || ref->primitive == PrimitiveKind::UInt32S) {
|
|
1218
|
+
SWAP(uint32_t);
|
|
1219
|
+
} else if (ref->primitive == PrimitiveKind::Int64S || ref->primitive == PrimitiveKind::UInt64S) {
|
|
1220
|
+
SWAP(uint64_t);
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
#undef SWAP
|
|
1041
1224
|
}
|
|
1042
1225
|
|
|
1043
1226
|
Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int16_t realign)
|
|
@@ -1078,6 +1261,21 @@ Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int1
|
|
|
1078
1261
|
return array; \
|
|
1079
1262
|
} \
|
|
1080
1263
|
} while (false)
|
|
1264
|
+
#define POP_NUMBER_ARRAY_SWAP(TypedArrayType, CType) \
|
|
1265
|
+
do { \
|
|
1266
|
+
if (type->hint == TypeInfo::ArrayHint::Array) { \
|
|
1267
|
+
POP_ARRAY({ \
|
|
1268
|
+
CType v = *(CType *)src; \
|
|
1269
|
+
double d = (double)ReverseBytes(v); \
|
|
1270
|
+
array.Set(i, Napi::Number::New(env, d)); \
|
|
1271
|
+
}); \
|
|
1272
|
+
} else { \
|
|
1273
|
+
Napi::TypedArrayType array = Napi::TypedArrayType::New(env, len); \
|
|
1274
|
+
PopTypedArray(array, origin, type->ref.type, realign); \
|
|
1275
|
+
\
|
|
1276
|
+
return array; \
|
|
1277
|
+
} \
|
|
1278
|
+
} while (false)
|
|
1081
1279
|
|
|
1082
1280
|
switch (type->ref.type->primitive) {
|
|
1083
1281
|
case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
|
|
@@ -1115,21 +1313,37 @@ Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int1
|
|
|
1115
1313
|
|
|
1116
1314
|
POP_NUMBER_ARRAY(Int16Array, int16_t);
|
|
1117
1315
|
} break;
|
|
1316
|
+
case PrimitiveKind::Int16S: { POP_NUMBER_ARRAY_SWAP(Int16Array, int16_t); } break;
|
|
1118
1317
|
case PrimitiveKind::UInt16: { POP_NUMBER_ARRAY(Uint16Array, uint16_t); } break;
|
|
1318
|
+
case PrimitiveKind::UInt16S: { POP_NUMBER_ARRAY_SWAP(Uint16Array, uint16_t); } break;
|
|
1119
1319
|
case PrimitiveKind::Int32: { POP_NUMBER_ARRAY(Int32Array, int32_t); } break;
|
|
1320
|
+
case PrimitiveKind::Int32S: { POP_NUMBER_ARRAY_SWAP(Int32Array, int32_t); } break;
|
|
1120
1321
|
case PrimitiveKind::UInt32: { POP_NUMBER_ARRAY(Uint32Array, uint32_t); } break;
|
|
1322
|
+
case PrimitiveKind::UInt32S: { POP_NUMBER_ARRAY_SWAP(Uint32Array, uint32_t); } break;
|
|
1121
1323
|
case PrimitiveKind::Int64: {
|
|
1122
1324
|
POP_ARRAY({
|
|
1123
1325
|
int64_t v = *(int64_t *)src;
|
|
1124
1326
|
array.Set(i, NewBigInt(env, v));
|
|
1125
1327
|
});
|
|
1126
1328
|
} break;
|
|
1329
|
+
case PrimitiveKind::Int64S: {
|
|
1330
|
+
POP_ARRAY({
|
|
1331
|
+
int64_t v = ReverseBytes(*(int64_t *)src);
|
|
1332
|
+
array.Set(i, NewBigInt(env, v));
|
|
1333
|
+
});
|
|
1334
|
+
} break;
|
|
1127
1335
|
case PrimitiveKind::UInt64: {
|
|
1128
1336
|
POP_ARRAY({
|
|
1129
1337
|
uint64_t v = *(uint64_t *)src;
|
|
1130
1338
|
array.Set(i, NewBigInt(env, v));
|
|
1131
1339
|
});
|
|
1132
1340
|
} break;
|
|
1341
|
+
case PrimitiveKind::UInt64S: {
|
|
1342
|
+
POP_ARRAY({
|
|
1343
|
+
uint64_t v = ReverseBytes(*(uint64_t *)src);
|
|
1344
|
+
array.Set(i, NewBigInt(env, v));
|
|
1345
|
+
});
|
|
1346
|
+
} break;
|
|
1133
1347
|
case PrimitiveKind::String: {
|
|
1134
1348
|
POP_ARRAY({
|
|
1135
1349
|
const char *str = *(const char **)src;
|
|
@@ -1175,6 +1389,7 @@ Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int1
|
|
|
1175
1389
|
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
1176
1390
|
}
|
|
1177
1391
|
|
|
1392
|
+
#undef POP_NUMBER_ARRAY_SWAP
|
|
1178
1393
|
#undef POP_NUMBER_ARRAY
|
|
1179
1394
|
#undef POP_ARRAY
|
|
1180
1395
|
|
package/src/call.hh
CHANGED
|
@@ -71,9 +71,21 @@ public:
|
|
|
71
71
|
CallData(Napi::Env env, InstanceData *instance, const FunctionInfo *func, InstanceMemory *mem);
|
|
72
72
|
~CallData();
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
#ifdef UNITY_BUILD
|
|
75
|
+
#ifdef _MSC_VER
|
|
76
|
+
#define INLINE_IF_UNITY __forceinline
|
|
77
|
+
#else
|
|
78
|
+
#define INLINE_IF_UNITY __attribute__((always_inline)) inline
|
|
79
|
+
#endif
|
|
80
|
+
#else
|
|
81
|
+
#define INLINE_IF_UNITY
|
|
82
|
+
#endif
|
|
83
|
+
|
|
84
|
+
INLINE_IF_UNITY bool Prepare(const Napi::CallbackInfo &info);
|
|
85
|
+
INLINE_IF_UNITY void Execute();
|
|
86
|
+
INLINE_IF_UNITY Napi::Value Complete();
|
|
87
|
+
|
|
88
|
+
#undef INLINE_IF_UNITY
|
|
77
89
|
|
|
78
90
|
void Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg);
|
|
79
91
|
|