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.
- package/ChangeLog.md +21 -1
- package/doc/Makefile +1 -1
- package/doc/callbacks.md +175 -0
- package/doc/changes.md +2 -3
- package/doc/conf.py +29 -6
- package/doc/functions.md +39 -124
- package/doc/index.rst +1 -0
- package/doc/make.bat +1 -1
- package/doc/types.md +36 -9
- package/package.json +2 -2
- package/src/core/libcc/libcc.cc +89 -27
- package/src/core/libcc/libcc.hh +74 -39
- package/src/koffi/build/2.2.1/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_win32_x64.tar.gz +0 -0
- package/src/koffi/qemu/qemu.js +3 -1
- package/src/koffi/src/abi_arm32.cc +26 -23
- package/src/koffi/src/abi_arm64.cc +25 -22
- package/src/koffi/src/abi_riscv64.cc +21 -18
- package/src/koffi/src/abi_x64_sysv.cc +20 -17
- package/src/koffi/src/abi_x64_win.cc +19 -16
- package/src/koffi/src/abi_x86.cc +23 -20
- package/src/koffi/src/call.cc +222 -607
- package/src/koffi/src/call.hh +7 -11
- package/src/koffi/src/ffi.cc +229 -29
- package/src/koffi/src/ffi.hh +6 -2
- package/src/koffi/src/parser.cc +3 -9
- package/src/koffi/src/util.cc +546 -8
- package/src/koffi/src/util.hh +8 -2
- package/src/koffi/test/CMakeLists.txt +3 -3
- package/src/koffi/test/callbacks.js +89 -0
- package/src/koffi/test/misc.c +78 -0
- package/src/koffi/test/raylib.js +2 -2
- package/src/koffi/test/sqlite.js +1 -1
- package/src/koffi/test/sync.js +28 -6
- package/vendor/brotli/c/common/platform.h +2 -0
- package/vendor/sqlite3mc/sqlite3.c +243532 -0
- package/vendor/sqlite3mc/sqlite3.h +12887 -0
- package/src/koffi/build/2.1.5/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_win32_x64.tar.gz +0 -0
package/src/koffi/src/util.cc
CHANGED
|
@@ -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 (
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
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
|
-
|
|
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) {
|
package/src/koffi/src/util.hh
CHANGED
|
@@ -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
|
|
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(
|
|
104
|
-
set_target_properties(
|
|
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(
|
|
107
|
+
target_compile_definitions(sqlite3 PRIVATE SQLITE_API=__declspec\(dllexport\))
|
|
108
108
|
endif()
|
|
109
109
|
|
|
110
110
|
# ---- Misc ----
|