koffi 1.2.4 → 1.3.0-rc.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/README.md +7 -489
- package/benchmark/CMakeLists.txt +13 -9
- package/benchmark/raylib_node_raylib.js +67 -0
- package/build/qemu/1.3.0-rc.1/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_win32_x64.tar.gz +0 -0
- package/doc/Makefile +20 -0
- package/doc/_static/bench_linux.png +0 -0
- package/doc/_static/bench_windows.png +0 -0
- package/doc/_static/custom.css +22 -0
- package/doc/benchmarks.md +113 -0
- package/doc/benchmarks.xlsx +0 -0
- package/doc/conf.py +54 -0
- package/doc/contribute.md +115 -0
- package/doc/dist/doctrees/benchmarks.doctree +0 -0
- package/doc/dist/doctrees/contribute.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/memory.doctree +0 -0
- package/doc/dist/doctrees/platforms.doctree +0 -0
- package/doc/dist/doctrees/start.doctree +0 -0
- package/doc/dist/doctrees/types.doctree +0 -0
- package/doc/dist/html/.buildinfo +4 -0
- package/doc/dist/html/_sources/benchmarks.md.txt +113 -0
- package/doc/dist/html/_sources/contribute.md.txt +115 -0
- package/doc/dist/html/_sources/functions.md.txt +224 -0
- package/doc/dist/html/_sources/index.rst.txt +33 -0
- package/doc/dist/html/_sources/memory.md.txt +29 -0
- package/doc/dist/html/_sources/platforms.md.txt +17 -0
- package/doc/dist/html/_sources/start.md.txt +89 -0
- package/doc/dist/html/_sources/types.md.txt +514 -0
- package/doc/dist/html/_static/_sphinx_javascript_frameworks_compat.js +134 -0
- package/doc/dist/html/_static/basic.css +932 -0
- package/doc/dist/html/_static/bench_linux.png +0 -0
- package/doc/dist/html/_static/bench_windows.png +0 -0
- package/doc/dist/html/_static/custom.css +22 -0
- package/doc/dist/html/_static/debug.css +69 -0
- package/doc/dist/html/_static/doctools.js +264 -0
- package/doc/dist/html/_static/documentation_options.js +14 -0
- package/doc/dist/html/_static/file.png +0 -0
- package/doc/dist/html/_static/jquery-3.6.0.js +10881 -0
- package/doc/dist/html/_static/jquery.js +2 -0
- package/doc/dist/html/_static/language_data.js +199 -0
- package/doc/dist/html/_static/minus.png +0 -0
- package/doc/dist/html/_static/plus.png +0 -0
- package/doc/dist/html/_static/pygments.css +252 -0
- package/doc/dist/html/_static/scripts/furo-extensions.js +0 -0
- package/doc/dist/html/_static/scripts/furo.js +3 -0
- package/doc/dist/html/_static/scripts/furo.js.LICENSE.txt +7 -0
- package/doc/dist/html/_static/scripts/furo.js.map +1 -0
- package/doc/dist/html/_static/searchtools.js +531 -0
- package/doc/dist/html/_static/skeleton.css +296 -0
- package/doc/dist/html/_static/styles/furo-extensions.css +2 -0
- package/doc/dist/html/_static/styles/furo-extensions.css.map +1 -0
- package/doc/dist/html/_static/styles/furo.css +2 -0
- package/doc/dist/html/_static/styles/furo.css.map +1 -0
- package/doc/dist/html/_static/underscore-1.13.1.js +2042 -0
- package/doc/dist/html/_static/underscore.js +6 -0
- package/doc/dist/html/benchmarks.html +547 -0
- package/doc/dist/html/contribute.html +382 -0
- package/doc/dist/html/functions.html +530 -0
- package/doc/dist/html/genindex.html +249 -0
- package/doc/dist/html/index.html +342 -0
- package/doc/dist/html/memory.html +337 -0
- package/doc/dist/html/objects.inv +0 -0
- package/doc/dist/html/platforms.html +332 -0
- package/doc/dist/html/search.html +257 -0
- package/doc/dist/html/searchindex.js +1 -0
- package/doc/dist/html/start.html +367 -0
- package/doc/dist/html/types.html +1001 -0
- package/doc/functions.md +224 -0
- package/doc/index.rst +33 -0
- package/doc/make.bat +35 -0
- package/doc/memory.md +29 -0
- package/doc/platforms.md +17 -0
- package/doc/start.md +89 -0
- package/doc/types.md +514 -0
- package/package.json +5 -2
- package/qemu/qemu.js +41 -27
- package/qemu/registry/machines.json +59 -79
- package/qemu/registry/sha256sum.txt +4 -4
- package/src/abi_arm32.cc +20 -48
- package/src/abi_arm64.cc +18 -46
- package/src/abi_arm64_fwd.S +5 -0
- package/src/abi_riscv64.cc +19 -47
- package/src/abi_x64_sysv.cc +18 -46
- package/src/abi_x64_win.cc +19 -47
- package/src/abi_x86.cc +21 -49
- package/src/call.cc +505 -242
- package/src/call.hh +14 -7
- package/src/ffi.cc +47 -26
- package/src/ffi.hh +1 -1
- package/src/parser.cc +2 -20
- package/src/util.cc +50 -11
- package/src/util.hh +2 -0
- package/test/misc.c +31 -0
- package/test/sync.js +41 -4
- package/benchmark/atoi_cc.cc +0 -59
- package/build/qemu/1.2.4/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_linux_arm.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_linux_riscv64.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_win32_x64.tar.gz +0 -0
package/src/call.cc
CHANGED
|
@@ -32,6 +32,10 @@ CallData::CallData(Napi::Env env, InstanceData *instance, const FunctionInfo *fu
|
|
|
32
32
|
|
|
33
33
|
CallData::~CallData()
|
|
34
34
|
{
|
|
35
|
+
for (const OutArgument &out: out_arguments) {
|
|
36
|
+
napi_delete_reference(env, out.ref);
|
|
37
|
+
}
|
|
38
|
+
|
|
35
39
|
mem->stack = old_stack_mem;
|
|
36
40
|
mem->heap = old_heap_mem;
|
|
37
41
|
|
|
@@ -42,7 +46,7 @@ CallData::~CallData()
|
|
|
42
46
|
}
|
|
43
47
|
}
|
|
44
48
|
|
|
45
|
-
const char *CallData::PushString(
|
|
49
|
+
const char *CallData::PushString(Napi::Value value)
|
|
46
50
|
{
|
|
47
51
|
RG_ASSERT(value.IsString());
|
|
48
52
|
|
|
@@ -79,7 +83,7 @@ const char *CallData::PushString(const Napi::Value &value)
|
|
|
79
83
|
return buf.ptr;
|
|
80
84
|
}
|
|
81
85
|
|
|
82
|
-
const char16_t *CallData::PushString16(
|
|
86
|
+
const char16_t *CallData::PushString16(Napi::Value value)
|
|
83
87
|
{
|
|
84
88
|
RG_ASSERT(value.IsString());
|
|
85
89
|
|
|
@@ -116,7 +120,7 @@ const char16_t *CallData::PushString16(const Napi::Value &value)
|
|
|
116
120
|
return buf.ptr;
|
|
117
121
|
}
|
|
118
122
|
|
|
119
|
-
bool CallData::PushObject(
|
|
123
|
+
bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origin, int16_t realign)
|
|
120
124
|
{
|
|
121
125
|
RG_ASSERT(IsObject(obj));
|
|
122
126
|
RG_ASSERT(type->primitive == PrimitiveKind::Record);
|
|
@@ -265,14 +269,25 @@ bool CallData::PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t
|
|
|
265
269
|
return false;
|
|
266
270
|
} break;
|
|
267
271
|
case PrimitiveKind::Array: {
|
|
268
|
-
if (
|
|
272
|
+
if (value.IsArray()) {
|
|
273
|
+
Napi::Array array = value.As<Napi::Array>();
|
|
274
|
+
Size len = (Size)member.type->size / member.type->ref->size;
|
|
275
|
+
|
|
276
|
+
if (!PushNormalArray(array, len, member.type->ref, dest, realign))
|
|
277
|
+
return false;
|
|
278
|
+
} else if (value.IsTypedArray()) {
|
|
279
|
+
Napi::TypedArray array = value.As<Napi::TypedArray>();
|
|
280
|
+
Size len = (Size)member.type->size / member.type->ref->size;
|
|
281
|
+
|
|
282
|
+
if (!PushTypedArray(array, len, member.type->ref, dest, realign))
|
|
283
|
+
return false;
|
|
284
|
+
} else if (value.IsString() && !realign) {
|
|
285
|
+
if (!PushStringArray(value, member.type, dest))
|
|
286
|
+
return false;
|
|
287
|
+
} else {
|
|
269
288
|
ThrowError<Napi::TypeError>(env, "Unexpected value %1 for member '%2', expected array", GetValueType(instance, value), member.name);
|
|
270
289
|
return false;
|
|
271
290
|
}
|
|
272
|
-
|
|
273
|
-
Napi::Array array = value.As<Napi::Array>();
|
|
274
|
-
if (!PushArray(array, member.type, dest, realign))
|
|
275
|
-
return false;
|
|
276
291
|
} break;
|
|
277
292
|
case PrimitiveKind::Float32: {
|
|
278
293
|
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
@@ -321,248 +336,404 @@ bool CallData::PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t
|
|
|
321
336
|
return true;
|
|
322
337
|
}
|
|
323
338
|
|
|
324
|
-
bool CallData::
|
|
339
|
+
bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref, uint8_t *origin, int16_t realign)
|
|
325
340
|
{
|
|
326
|
-
RG_ASSERT(
|
|
327
|
-
RG_ASSERT(type->primitive == PrimitiveKind::Array);
|
|
341
|
+
RG_ASSERT(array.IsArray());
|
|
328
342
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
Napi::Array array = obj.As<Napi::Array>();
|
|
343
|
+
if (RG_UNLIKELY(array.Length() != len)) {
|
|
344
|
+
ThrowError<Napi::Error>(env, "Expected array of length %1, got %2", len, array.Length());
|
|
345
|
+
return false;
|
|
346
|
+
}
|
|
334
347
|
|
|
335
|
-
|
|
336
|
-
ThrowError<Napi::Error>(env, "Expected array of length %1, got %2", len, array.Length());
|
|
337
|
-
return false;
|
|
338
|
-
}
|
|
348
|
+
Size offset = 0;
|
|
339
349
|
|
|
340
350
|
#define PUSH_ARRAY(Check, Expected, GetCode) \
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
} \
|
|
354
|
-
\
|
|
355
|
-
GetCode \
|
|
356
|
-
\
|
|
357
|
-
offset += type->ref->size; \
|
|
351
|
+
do { \
|
|
352
|
+
for (uint32_t i = 0; i < len; i++) { \
|
|
353
|
+
Napi::Value value = array[i]; \
|
|
354
|
+
\
|
|
355
|
+
int16_t align = std::max(ref->align, realign); \
|
|
356
|
+
\
|
|
357
|
+
offset = AlignLen(offset, align); \
|
|
358
|
+
uint8_t *dest = origin + offset; \
|
|
359
|
+
\
|
|
360
|
+
if (RG_UNLIKELY(!(Check))) { \
|
|
361
|
+
ThrowError<Napi::TypeError>(env, "Unexpected value %1 in array, expected %2", GetValueType(instance, value), (Expected)); \
|
|
362
|
+
return false; \
|
|
358
363
|
} \
|
|
359
|
-
|
|
364
|
+
\
|
|
365
|
+
GetCode \
|
|
366
|
+
\
|
|
367
|
+
offset += ref->size; \
|
|
368
|
+
} \
|
|
369
|
+
} while (false)
|
|
360
370
|
|
|
361
|
-
|
|
362
|
-
|
|
371
|
+
switch (ref->primitive) {
|
|
372
|
+
case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
|
|
363
373
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
374
|
+
case PrimitiveKind::Bool: {
|
|
375
|
+
PUSH_ARRAY(value.IsBoolean(), "boolean", {
|
|
376
|
+
bool b = value.As<Napi::Boolean>();
|
|
377
|
+
*(bool *)dest = b;
|
|
378
|
+
});
|
|
379
|
+
} break;
|
|
380
|
+
case PrimitiveKind::Int8: {
|
|
381
|
+
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
382
|
+
int8_t v = CopyNumber<int8_t>(value);
|
|
383
|
+
*(int8_t *)dest = v;
|
|
384
|
+
});
|
|
385
|
+
} break;
|
|
386
|
+
case PrimitiveKind::UInt8: {
|
|
387
|
+
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
388
|
+
uint8_t v = CopyNumber<uint8_t>(value);
|
|
389
|
+
*(uint8_t *)dest = v;
|
|
390
|
+
});
|
|
391
|
+
} break;
|
|
392
|
+
case PrimitiveKind::Int16: {
|
|
393
|
+
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
394
|
+
int16_t v = CopyNumber<int16_t>(value);
|
|
395
|
+
*(int16_t *)dest = v;
|
|
396
|
+
});
|
|
397
|
+
} break;
|
|
398
|
+
case PrimitiveKind::UInt16: {
|
|
399
|
+
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
400
|
+
uint16_t v = CopyNumber<uint16_t>(value);
|
|
401
|
+
*(uint16_t *)dest = v;
|
|
402
|
+
});
|
|
403
|
+
} break;
|
|
404
|
+
case PrimitiveKind::Int32: {
|
|
405
|
+
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
406
|
+
int32_t v = CopyNumber<int32_t>(value);
|
|
407
|
+
*(int32_t *)dest = v;
|
|
408
|
+
});
|
|
409
|
+
} break;
|
|
410
|
+
case PrimitiveKind::UInt32: {
|
|
411
|
+
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
412
|
+
uint32_t v = CopyNumber<uint32_t>(value);
|
|
413
|
+
*(uint32_t *)dest = v;
|
|
414
|
+
});
|
|
415
|
+
} break;
|
|
416
|
+
case PrimitiveKind::Int64: {
|
|
417
|
+
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
418
|
+
int64_t v = CopyNumber<int64_t>(value);
|
|
419
|
+
*(int64_t *)dest = v;
|
|
420
|
+
});
|
|
421
|
+
} break;
|
|
422
|
+
case PrimitiveKind::UInt64: {
|
|
423
|
+
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
424
|
+
uint64_t v = CopyNumber<uint64_t>(value);
|
|
425
|
+
*(uint64_t *)dest = v;
|
|
426
|
+
});
|
|
427
|
+
} break;
|
|
428
|
+
case PrimitiveKind::String: {
|
|
429
|
+
PUSH_ARRAY(value.IsString() || IsNullOrUndefined(value), "string", {
|
|
430
|
+
if (!IsNullOrUndefined(value)) {
|
|
420
431
|
const char *str = PushString(value);
|
|
421
432
|
if (RG_UNLIKELY(!str))
|
|
422
433
|
return false;
|
|
423
434
|
*(const char **)dest = str;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
435
|
+
} else {
|
|
436
|
+
*(const char **)dest = nullptr;
|
|
437
|
+
}
|
|
438
|
+
});
|
|
439
|
+
} break;
|
|
440
|
+
case PrimitiveKind::String16: {
|
|
441
|
+
PUSH_ARRAY(value.IsString() || IsNullOrUndefined(value), "string", {
|
|
442
|
+
if (!IsNullOrUndefined(value)) {
|
|
428
443
|
const char16_t *str16 = PushString16(value);
|
|
429
444
|
if (RG_UNLIKELY(!str16))
|
|
430
445
|
return false;
|
|
431
446
|
*(const char16_t **)dest = str16;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
447
|
+
} else {
|
|
448
|
+
*(const char16_t **)dest = nullptr;
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
} break;
|
|
452
|
+
case PrimitiveKind::Pointer: {
|
|
453
|
+
PUSH_ARRAY(CheckValueTag(instance, value, ref) || IsNullOrUndefined(value), ref->name, {
|
|
454
|
+
if (!IsNullOrUndefined(value)) {
|
|
455
|
+
Napi::External external = value.As<Napi::External<void>>();
|
|
456
|
+
*(void **)dest = external.Data();
|
|
457
|
+
} else {
|
|
458
|
+
*(void **)dest = nullptr;
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
} break;
|
|
462
|
+
case PrimitiveKind::Record: {
|
|
463
|
+
PUSH_ARRAY(IsObject(value), "object", {
|
|
464
|
+
Napi::Object obj2 = value.As<Napi::Object>();
|
|
465
|
+
if (!PushObject(obj2, ref, dest, realign))
|
|
466
|
+
return false;
|
|
467
|
+
});
|
|
468
|
+
} break;
|
|
469
|
+
case PrimitiveKind::Array: {
|
|
470
|
+
for (uint32_t i = 0; i < len; i++) {
|
|
471
|
+
Napi::Value value = array[i];
|
|
472
|
+
|
|
473
|
+
int16_t align = std::max(ref->align, realign);
|
|
474
|
+
offset = AlignLen(offset, align);
|
|
475
|
+
|
|
476
|
+
uint8_t *dest = origin + offset;
|
|
477
|
+
|
|
478
|
+
if (value.IsArray()) {
|
|
479
|
+
Napi::Array array2 = value.As<Napi::Array>();
|
|
480
|
+
Size len2 = (Size)ref->size / ref->ref->size;
|
|
481
|
+
|
|
482
|
+
if (!PushNormalArray(array2, len2, ref->ref, dest, realign))
|
|
448
483
|
return false;
|
|
449
|
-
})
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
if (!PushArray(array2, type->ref, dest, realign))
|
|
484
|
+
} else if (value.IsTypedArray()) {
|
|
485
|
+
Napi::TypedArray array2 = value.As<Napi::TypedArray>();
|
|
486
|
+
Size len2 = (Size)ref->size / ref->ref->size;
|
|
487
|
+
|
|
488
|
+
if (!PushTypedArray(array2, len2, ref->ref, dest, realign))
|
|
455
489
|
return false;
|
|
456
|
-
})
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
490
|
+
} else if (value.IsString() && !realign) {
|
|
491
|
+
if (!PushStringArray(value, ref, dest))
|
|
492
|
+
return false;
|
|
493
|
+
} else {
|
|
494
|
+
ThrowError<Napi::TypeError>(env, "Unexpected value %1 in array, expected array", GetValueType(instance, value));
|
|
495
|
+
return false;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
offset += ref->size;
|
|
499
|
+
}
|
|
500
|
+
} break;
|
|
501
|
+
case PrimitiveKind::Float32: {
|
|
502
|
+
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
503
|
+
float f = CopyNumber<float>(value);
|
|
504
|
+
*(float *)dest = f;
|
|
505
|
+
});
|
|
506
|
+
} break;
|
|
507
|
+
case PrimitiveKind::Float64: {
|
|
508
|
+
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
509
|
+
double d = CopyNumber<double>(value);
|
|
510
|
+
*(double *)dest = d;
|
|
511
|
+
});
|
|
512
|
+
} break;
|
|
513
|
+
case PrimitiveKind::Callback: {
|
|
514
|
+
for (uint32_t i = 0; i < len; i++) {
|
|
515
|
+
Napi::Value value = array[i];
|
|
473
516
|
|
|
474
|
-
|
|
475
|
-
|
|
517
|
+
int16_t align = std::max(ref->align, realign);
|
|
518
|
+
offset = AlignLen(offset, align);
|
|
476
519
|
|
|
477
|
-
|
|
520
|
+
uint8_t *dest = origin + offset;
|
|
478
521
|
|
|
479
|
-
|
|
522
|
+
void *ptr;
|
|
480
523
|
|
|
481
|
-
|
|
482
|
-
|
|
524
|
+
if (value.IsFunction()) {
|
|
525
|
+
Napi::Function func = value.As<Napi::Function>();
|
|
483
526
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
return false;
|
|
487
|
-
} else if (CheckValueTag(instance, value, type->ref)) {
|
|
488
|
-
Napi::External external = value.As<Napi::External<void>>();
|
|
489
|
-
ptr = external.Data();
|
|
490
|
-
} else if (IsNullOrUndefined(value)) {
|
|
491
|
-
ptr = nullptr;
|
|
492
|
-
} else {
|
|
493
|
-
ThrowError<Napi::TypeError>(env, "Unexpected value %1 in array, expected %2", GetValueType(instance, value), type->ref->name);
|
|
527
|
+
ptr = ReserveTrampoline(ref->proto, func);
|
|
528
|
+
if (RG_UNLIKELY(!ptr))
|
|
494
529
|
return false;
|
|
495
|
-
|
|
530
|
+
} else if (CheckValueTag(instance, value, ref)) {
|
|
531
|
+
Napi::External external = value.As<Napi::External<void>>();
|
|
532
|
+
ptr = external.Data();
|
|
533
|
+
} else if (IsNullOrUndefined(value)) {
|
|
534
|
+
ptr = nullptr;
|
|
535
|
+
} else {
|
|
536
|
+
ThrowError<Napi::TypeError>(env, "Unexpected value %1 in array, expected %2", GetValueType(instance, value), ref->name);
|
|
537
|
+
return false;
|
|
538
|
+
}
|
|
496
539
|
|
|
497
|
-
|
|
540
|
+
*(void **)dest = ptr;
|
|
498
541
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
542
|
+
offset += ref->size;
|
|
543
|
+
}
|
|
544
|
+
} break;
|
|
545
|
+
}
|
|
503
546
|
|
|
504
547
|
#undef PUSH_ARRAY
|
|
505
|
-
} else if (obj.IsTypedArray()) {
|
|
506
|
-
Napi::TypedArray array = obj.As<Napi::TypedArray>();
|
|
507
|
-
const uint8_t *buf = (const uint8_t *)array.ArrayBuffer().Data();
|
|
508
548
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
return false;
|
|
512
|
-
}
|
|
549
|
+
return true;
|
|
550
|
+
}
|
|
513
551
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
case PrimitiveKind::Float32: { match = (array.TypedArrayType() == napi_float32_array); } break;
|
|
523
|
-
case PrimitiveKind::Float64: { match = (array.TypedArrayType() == napi_float64_array); } break;
|
|
524
|
-
|
|
525
|
-
default: { match = false; } break;
|
|
526
|
-
}
|
|
527
|
-
if (RG_UNLIKELY(!match)) {
|
|
528
|
-
ThrowError<Napi::TypeError>(env, "TypedArray is not approriate for %1 array", type->ref->name);
|
|
529
|
-
return false;
|
|
530
|
-
}
|
|
552
|
+
bool CallData::PushTypedArray(Napi::TypedArray array, Size len, const TypeInfo *ref, uint8_t *origin, int16_t realign)
|
|
553
|
+
{
|
|
554
|
+
RG_ASSERT(array.IsTypedArray());
|
|
555
|
+
|
|
556
|
+
if (RG_UNLIKELY(array.ElementLength() != (size_t)len)) {
|
|
557
|
+
ThrowError<Napi::Error>(env, "Expected array of length %1, got %2", len, array.ElementLength());
|
|
558
|
+
return false;
|
|
559
|
+
}
|
|
531
560
|
|
|
561
|
+
Size offset = 0;
|
|
562
|
+
const uint8_t *buf = (const uint8_t *)array.ArrayBuffer().Data();
|
|
563
|
+
|
|
564
|
+
if (RG_UNLIKELY(array.TypedArrayType() != GetTypedArrayType(ref))) {
|
|
565
|
+
ThrowError<Napi::TypeError>(env, "Cannot use %1 value for %2 array", GetValueType(instance, array), ref->name);
|
|
566
|
+
return false;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
if (realign) {
|
|
532
570
|
for (uint32_t i = 0; i < len; i++) {
|
|
533
|
-
int16_t align = std::max(
|
|
571
|
+
int16_t align = std::max(ref->align, realign);
|
|
534
572
|
offset = AlignLen(offset, align);
|
|
535
573
|
|
|
536
574
|
uint8_t *dest = origin + offset;
|
|
537
575
|
|
|
538
|
-
memcpy(dest, buf + i *
|
|
576
|
+
memcpy(dest, buf + i * ref->size, ref->size);
|
|
539
577
|
|
|
540
|
-
offset +=
|
|
578
|
+
offset += ref->size;
|
|
541
579
|
}
|
|
542
|
-
} else
|
|
543
|
-
|
|
580
|
+
} else {
|
|
581
|
+
memcpy_safe(origin, buf, (size_t)array.ByteLength());
|
|
582
|
+
}
|
|
544
583
|
|
|
545
|
-
|
|
584
|
+
return true;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
bool CallData::PushStringArray(Napi::Value obj, const TypeInfo *type, uint8_t *origin)
|
|
588
|
+
{
|
|
589
|
+
RG_ASSERT(obj.IsString());
|
|
590
|
+
RG_ASSERT(type->primitive == PrimitiveKind::Array);
|
|
591
|
+
|
|
592
|
+
size_t encoded = 0;
|
|
593
|
+
|
|
594
|
+
switch (type->ref->primitive) {
|
|
595
|
+
case PrimitiveKind::Int8: {
|
|
546
596
|
napi_status status = napi_get_value_string_utf8(env, obj, (char *)origin, type->size, &encoded);
|
|
547
597
|
RG_ASSERT(status == napi_ok);
|
|
548
|
-
}
|
|
598
|
+
} break;
|
|
599
|
+
case PrimitiveKind::Int16: {
|
|
549
600
|
napi_status status = napi_get_value_string_utf16(env, obj, (char16_t *)origin, type->size / 2, &encoded);
|
|
550
601
|
RG_ASSERT(status == napi_ok);
|
|
551
602
|
|
|
552
603
|
encoded *= 2;
|
|
553
|
-
}
|
|
604
|
+
} break;
|
|
605
|
+
|
|
606
|
+
default: {
|
|
554
607
|
ThrowError<Napi::TypeError>(env, "Strings cannot be converted to %1 array", type->ref->name);
|
|
555
608
|
return false;
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
memset_safe(origin + encoded, 0, type->size - encoded);
|
|
559
|
-
} else {
|
|
560
|
-
RG_UNREACHABLE();
|
|
609
|
+
} break;
|
|
561
610
|
}
|
|
562
611
|
|
|
612
|
+
memset_safe(origin + encoded, 0, type->size - encoded);
|
|
613
|
+
|
|
563
614
|
return true;
|
|
564
615
|
}
|
|
565
616
|
|
|
617
|
+
bool CallData::PushPointer(Napi::Value value, const ParameterInfo ¶m, void **out_ptr)
|
|
618
|
+
{
|
|
619
|
+
switch (value.Type()) {
|
|
620
|
+
case napi_undefined:
|
|
621
|
+
case napi_null: {
|
|
622
|
+
*out_ptr = nullptr;
|
|
623
|
+
return true;
|
|
624
|
+
} break;
|
|
625
|
+
|
|
626
|
+
case napi_external: {
|
|
627
|
+
if (RG_UNLIKELY(!CheckValueTag(instance, value, param.type)))
|
|
628
|
+
goto unexpected;
|
|
629
|
+
|
|
630
|
+
*out_ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
631
|
+
return true;
|
|
632
|
+
} break;
|
|
633
|
+
|
|
634
|
+
case napi_object: {
|
|
635
|
+
uint8_t *ptr = nullptr;
|
|
636
|
+
|
|
637
|
+
if (value.IsArray()) {
|
|
638
|
+
Napi::Array array = value.As<Napi::Array>();
|
|
639
|
+
|
|
640
|
+
Size len = (Size)array.Length();
|
|
641
|
+
Size size = len * param.type->ref->size;
|
|
642
|
+
|
|
643
|
+
ptr = AllocHeap(size, 16);
|
|
644
|
+
|
|
645
|
+
if (param.directions & 1) {
|
|
646
|
+
if (!PushNormalArray(array, len, param.type->ref, ptr))
|
|
647
|
+
return false;
|
|
648
|
+
} else {
|
|
649
|
+
memset(ptr, 0, size);
|
|
650
|
+
}
|
|
651
|
+
} else if (value.IsTypedArray()) {
|
|
652
|
+
Napi::TypedArray array = value.As<Napi::TypedArray>();
|
|
653
|
+
|
|
654
|
+
Size len = (Size)array.ElementLength();
|
|
655
|
+
Size size = (Size)array.ByteLength();
|
|
656
|
+
|
|
657
|
+
ptr = AllocHeap(size, 16);
|
|
658
|
+
|
|
659
|
+
if (param.directions & 1) {
|
|
660
|
+
if (!PushTypedArray(array, len, param.type->ref, ptr))
|
|
661
|
+
return false;
|
|
662
|
+
} else {
|
|
663
|
+
if (RG_UNLIKELY(array.TypedArrayType() != GetTypedArrayType(param.type->ref))) {
|
|
664
|
+
ThrowError<Napi::TypeError>(env, "Cannot use %1 value for %2 array", GetValueType(instance, array), param.type->ref->name);
|
|
665
|
+
return false;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
memset(ptr, 0, size);
|
|
669
|
+
}
|
|
670
|
+
} else if (RG_LIKELY(param.type->ref->primitive == PrimitiveKind::Record)) {
|
|
671
|
+
Napi::Object obj = value.As<Napi::Object>();
|
|
672
|
+
RG_ASSERT(IsObject(value));
|
|
673
|
+
|
|
674
|
+
ptr = AllocHeap(param.type->ref->size, 16);
|
|
675
|
+
|
|
676
|
+
if (param.directions & 1) {
|
|
677
|
+
if (!PushObject(obj, param.type->ref, ptr))
|
|
678
|
+
return false;
|
|
679
|
+
} else {
|
|
680
|
+
memset(ptr, 0, param.type->size);
|
|
681
|
+
}
|
|
682
|
+
} else {
|
|
683
|
+
goto unexpected;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
if (param.directions & 2) {
|
|
687
|
+
OutArgument *out = out_arguments.AppendDefault();
|
|
688
|
+
|
|
689
|
+
napi_status status = napi_create_reference(env, value, 1, &out->ref);
|
|
690
|
+
RG_ASSERT(status == napi_ok);
|
|
691
|
+
|
|
692
|
+
out->ptr = ptr;
|
|
693
|
+
out->type = param.type->ref;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
*out_ptr = ptr;
|
|
697
|
+
return true;
|
|
698
|
+
} break;
|
|
699
|
+
|
|
700
|
+
default: {} break;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
unexpected:
|
|
704
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected %3", GetValueType(instance, value), param.offset + 1, param.type->name);
|
|
705
|
+
return false;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
static inline Napi::Value GetReferenceValue(Napi::Env env, napi_ref ref)
|
|
709
|
+
{
|
|
710
|
+
napi_value value;
|
|
711
|
+
|
|
712
|
+
napi_status status = napi_get_reference_value(env, ref, &value);
|
|
713
|
+
RG_ASSERT(status == napi_ok);
|
|
714
|
+
|
|
715
|
+
return Napi::Value(env, value);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
void CallData::PopOutArguments()
|
|
719
|
+
{
|
|
720
|
+
for (const OutArgument &out: out_arguments) {
|
|
721
|
+
Napi::Value value = GetReferenceValue(env, out.ref);
|
|
722
|
+
RG_ASSERT(!value.IsEmpty());
|
|
723
|
+
|
|
724
|
+
if (value.IsArray()) {
|
|
725
|
+
Napi::Array array(env, value);
|
|
726
|
+
PopNormalArray(array, out.ptr, out.type);
|
|
727
|
+
} else if (value.IsTypedArray()) {
|
|
728
|
+
Napi::TypedArray array(env, value);
|
|
729
|
+
PopTypedArray(array, out.ptr, out.type);
|
|
730
|
+
} else {
|
|
731
|
+
Napi::Object obj(env, value);
|
|
732
|
+
PopObject(obj, out.ptr, out.type);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
|
|
566
737
|
void *CallData::ReserveTrampoline(const FunctionInfo *proto, Napi::Function func)
|
|
567
738
|
{
|
|
568
739
|
uint32_t idx = CountTrailingZeros(instance->free_trampolines);
|
|
@@ -638,11 +809,11 @@ void CallData::PopObject(Napi::Object obj, const uint8_t *origin, const TypeInfo
|
|
|
638
809
|
} break;
|
|
639
810
|
case PrimitiveKind::String: {
|
|
640
811
|
const char *str = *(const char **)src;
|
|
641
|
-
obj.Set(member.name, Napi::String::New(env, str));
|
|
812
|
+
obj.Set(member.name, str ? Napi::String::New(env, str) : env.Null());
|
|
642
813
|
} break;
|
|
643
814
|
case PrimitiveKind::String16: {
|
|
644
815
|
const char16_t *str16 = *(const char16_t **)src;
|
|
645
|
-
obj.Set(member.name, Napi::String::New(env, str16));
|
|
816
|
+
obj.Set(member.name, str16 ? Napi::String::New(env, str16) : env.Null());
|
|
646
817
|
} break;
|
|
647
818
|
case PrimitiveKind::Pointer:
|
|
648
819
|
case PrimitiveKind::Callback: {
|
|
@@ -697,10 +868,137 @@ static Size WideStringLength(const char16_t *str16, Size max)
|
|
|
697
868
|
return len;
|
|
698
869
|
}
|
|
699
870
|
|
|
700
|
-
|
|
871
|
+
void CallData::PopNormalArray(Napi::Array array, const uint8_t *origin, const TypeInfo *ref, int16_t realign)
|
|
701
872
|
{
|
|
702
|
-
|
|
873
|
+
RG_ASSERT(array.IsArray());
|
|
874
|
+
|
|
875
|
+
Size offset = 0;
|
|
876
|
+
uint32_t len = array.Length();
|
|
877
|
+
|
|
878
|
+
#define POP_ARRAY(SetCode) \
|
|
879
|
+
do { \
|
|
880
|
+
for (uint32_t i = 0; i < len; i++) { \
|
|
881
|
+
int16_t align = std::max(realign, ref->align); \
|
|
882
|
+
offset = AlignLen(offset, align); \
|
|
883
|
+
\
|
|
884
|
+
const uint8_t *src = origin + offset; \
|
|
885
|
+
\
|
|
886
|
+
SetCode \
|
|
887
|
+
\
|
|
888
|
+
offset += ref->size; \
|
|
889
|
+
} \
|
|
890
|
+
} while (false)
|
|
891
|
+
#define POP_NUMBER_ARRAY(CType) \
|
|
892
|
+
do { \
|
|
893
|
+
POP_ARRAY({ \
|
|
894
|
+
double d = (double)*(CType *)src; \
|
|
895
|
+
array.Set(i, Napi::Number::New(env, d)); \
|
|
896
|
+
}); \
|
|
897
|
+
} while (false)
|
|
898
|
+
|
|
899
|
+
switch (ref->primitive) {
|
|
900
|
+
case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
|
|
901
|
+
|
|
902
|
+
case PrimitiveKind::Bool: {
|
|
903
|
+
POP_ARRAY({
|
|
904
|
+
bool b = *(bool *)src;
|
|
905
|
+
array.Set(i, Napi::Boolean::New(env, b));
|
|
906
|
+
});
|
|
907
|
+
} break;
|
|
908
|
+
case PrimitiveKind::Int8: { POP_NUMBER_ARRAY(int8_t); } break;
|
|
909
|
+
case PrimitiveKind::UInt8: { POP_NUMBER_ARRAY(uint8_t); } break;
|
|
910
|
+
case PrimitiveKind::Int16: { POP_NUMBER_ARRAY(int16_t); } break;
|
|
911
|
+
case PrimitiveKind::UInt16: { POP_NUMBER_ARRAY(uint16_t); } break;
|
|
912
|
+
case PrimitiveKind::Int32: { POP_NUMBER_ARRAY(int32_t); } break;
|
|
913
|
+
case PrimitiveKind::UInt32: { POP_NUMBER_ARRAY(uint32_t); } break;
|
|
914
|
+
case PrimitiveKind::Int64: {
|
|
915
|
+
POP_ARRAY({
|
|
916
|
+
int64_t v = *(int64_t *)src;
|
|
917
|
+
array.Set(i, Napi::BigInt::New(env, v));
|
|
918
|
+
});
|
|
919
|
+
} break;
|
|
920
|
+
case PrimitiveKind::UInt64: {
|
|
921
|
+
POP_ARRAY({
|
|
922
|
+
uint64_t v = *(uint64_t *)src;
|
|
923
|
+
array.Set(i, Napi::BigInt::New(env, v));
|
|
924
|
+
});
|
|
925
|
+
} break;
|
|
926
|
+
case PrimitiveKind::String: {
|
|
927
|
+
POP_ARRAY({
|
|
928
|
+
const char *str = *(const char **)src;
|
|
929
|
+
array.Set(i, str ? Napi::String::New(env, str) : env.Null());
|
|
930
|
+
});
|
|
931
|
+
} break;
|
|
932
|
+
case PrimitiveKind::String16: {
|
|
933
|
+
POP_ARRAY({
|
|
934
|
+
const char16_t *str16 = *(const char16_t **)src;
|
|
935
|
+
array.Set(i, str16 ? Napi::String::New(env, str16) : env.Null());
|
|
936
|
+
});
|
|
937
|
+
} break;
|
|
938
|
+
case PrimitiveKind::Pointer:
|
|
939
|
+
case PrimitiveKind::Callback: {
|
|
940
|
+
POP_ARRAY({
|
|
941
|
+
void *ptr2 = *(void **)src;
|
|
942
|
+
|
|
943
|
+
if (ptr2) {
|
|
944
|
+
Napi::External<void> external = Napi::External<void>::New(env, ptr2);
|
|
945
|
+
SetValueTag(instance, external, ref);
|
|
946
|
+
|
|
947
|
+
array.Set(i, external);
|
|
948
|
+
} else {
|
|
949
|
+
array.Set(i, env.Null());
|
|
950
|
+
}
|
|
951
|
+
});
|
|
952
|
+
} break;
|
|
953
|
+
case PrimitiveKind::Record: {
|
|
954
|
+
POP_ARRAY({
|
|
955
|
+
Napi::Object obj = PopObject(src, ref, realign);
|
|
956
|
+
array.Set(i, obj);
|
|
957
|
+
});
|
|
958
|
+
} break;
|
|
959
|
+
case PrimitiveKind::Array: {
|
|
960
|
+
POP_ARRAY({
|
|
961
|
+
Napi::Value value = PopArray(src, ref, realign);
|
|
962
|
+
array.Set(i, value);
|
|
963
|
+
});
|
|
964
|
+
} break;
|
|
965
|
+
case PrimitiveKind::Float32: { POP_NUMBER_ARRAY(float); } break;
|
|
966
|
+
case PrimitiveKind::Float64: { POP_NUMBER_ARRAY(double); } break;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
#undef POP_NUMBER_ARRAY
|
|
970
|
+
#undef POP_ARRAY
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
void CallData::PopTypedArray(Napi::TypedArray array, const uint8_t *origin, const TypeInfo *ref, int16_t realign)
|
|
974
|
+
{
|
|
975
|
+
RG_ASSERT(array.IsTypedArray());
|
|
976
|
+
RG_ASSERT(GetTypedArrayType(ref) == array.TypedArrayType());
|
|
977
|
+
|
|
978
|
+
uint8_t *buf = (uint8_t *)array.ArrayBuffer().Data();
|
|
979
|
+
|
|
980
|
+
if (realign) {
|
|
981
|
+
Size offset = 0;
|
|
982
|
+
Size len = (Size)array.ElementLength();
|
|
983
|
+
|
|
984
|
+
for (Size i = 0; i < len; i++) {
|
|
985
|
+
int16_t align = std::max(ref->align, realign);
|
|
986
|
+
offset = AlignLen(offset, align);
|
|
703
987
|
|
|
988
|
+
uint8_t *dest = buf + i * ref->size;
|
|
989
|
+
const uint8_t *src = origin + offset;
|
|
990
|
+
|
|
991
|
+
memcpy(dest, src, ref->size);
|
|
992
|
+
|
|
993
|
+
offset += ref->size;
|
|
994
|
+
}
|
|
995
|
+
} else {
|
|
996
|
+
memcpy_safe(buf, origin, (size_t)array.ByteLength());
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int16_t realign)
|
|
1001
|
+
{
|
|
704
1002
|
RG_ASSERT(type->primitive == PrimitiveKind::Array);
|
|
705
1003
|
|
|
706
1004
|
uint32_t len = type->size / type->ref->size;
|
|
@@ -732,18 +1030,7 @@ Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int1
|
|
|
732
1030
|
}); \
|
|
733
1031
|
} else { \
|
|
734
1032
|
Napi::TypedArrayType array = Napi::TypedArrayType::New(env, len); \
|
|
735
|
-
|
|
736
|
-
for (uint32_t i = 0; i < len; i++) { \
|
|
737
|
-
int16_t align = std::max(realign, type->ref->align); \
|
|
738
|
-
offset = AlignLen(offset, align); \
|
|
739
|
-
\
|
|
740
|
-
const uint8_t *src = origin + offset; \
|
|
741
|
-
\
|
|
742
|
-
CType f = *(CType *)src; \
|
|
743
|
-
array[i] = f; \
|
|
744
|
-
\
|
|
745
|
-
offset += type->ref->size; \
|
|
746
|
-
} \
|
|
1033
|
+
PopTypedArray(array, origin, type->ref, realign); \
|
|
747
1034
|
\
|
|
748
1035
|
return array; \
|
|
749
1036
|
} \
|
|
@@ -771,19 +1058,7 @@ Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int1
|
|
|
771
1058
|
|
|
772
1059
|
POP_NUMBER_ARRAY(Int8Array, int8_t);
|
|
773
1060
|
} break;
|
|
774
|
-
case PrimitiveKind::UInt8: {
|
|
775
|
-
if (type->hint == TypeInfo::ArrayHint::String) {
|
|
776
|
-
RG_ASSERT(!realign);
|
|
777
|
-
|
|
778
|
-
const char *ptr = (const char *)origin;
|
|
779
|
-
size_t count = strnlen(ptr, (size_t)len);
|
|
780
|
-
|
|
781
|
-
Napi::String str = Napi::String::New(env, ptr, count);
|
|
782
|
-
return str;
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
POP_NUMBER_ARRAY(Uint8Array, uint8_t);
|
|
786
|
-
} break;
|
|
1061
|
+
case PrimitiveKind::UInt8: { POP_NUMBER_ARRAY(Uint8Array, uint8_t); } break;
|
|
787
1062
|
case PrimitiveKind::Int16: {
|
|
788
1063
|
if (type->hint == TypeInfo::ArrayHint::String) {
|
|
789
1064
|
RG_ASSERT(!realign);
|
|
@@ -797,19 +1072,7 @@ Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int1
|
|
|
797
1072
|
|
|
798
1073
|
POP_NUMBER_ARRAY(Int16Array, int16_t);
|
|
799
1074
|
} break;
|
|
800
|
-
case PrimitiveKind::UInt16: {
|
|
801
|
-
if (type->hint == TypeInfo::ArrayHint::String) {
|
|
802
|
-
RG_ASSERT(!realign);
|
|
803
|
-
|
|
804
|
-
const char16_t *ptr = (const char16_t *)origin;
|
|
805
|
-
Size count = WideStringLength(ptr, len);
|
|
806
|
-
|
|
807
|
-
Napi::String str = Napi::String::New(env, ptr, count);
|
|
808
|
-
return str;
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
POP_NUMBER_ARRAY(Uint16Array, uint16_t);
|
|
812
|
-
} break;
|
|
1075
|
+
case PrimitiveKind::UInt16: { POP_NUMBER_ARRAY(Uint16Array, uint16_t); } break;
|
|
813
1076
|
case PrimitiveKind::Int32: { POP_NUMBER_ARRAY(Int32Array, int32_t); } break;
|
|
814
1077
|
case PrimitiveKind::UInt32: { POP_NUMBER_ARRAY(Uint32Array, uint32_t); } break;
|
|
815
1078
|
case PrimitiveKind::Int64: {
|
|
@@ -827,13 +1090,13 @@ Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int1
|
|
|
827
1090
|
case PrimitiveKind::String: {
|
|
828
1091
|
POP_ARRAY({
|
|
829
1092
|
const char *str = *(const char **)src;
|
|
830
|
-
array.Set(i, Napi::String::New(env, str));
|
|
1093
|
+
array.Set(i, str ? Napi::String::New(env, str) : env.Null());
|
|
831
1094
|
});
|
|
832
1095
|
} break;
|
|
833
1096
|
case PrimitiveKind::String16: {
|
|
834
1097
|
POP_ARRAY({
|
|
835
1098
|
const char16_t *str16 = *(const char16_t **)src;
|
|
836
|
-
array.Set(i, Napi::String::New(env, str16));
|
|
1099
|
+
array.Set(i, str16 ? Napi::String::New(env, str16) : env.Null());
|
|
837
1100
|
});
|
|
838
1101
|
} break;
|
|
839
1102
|
case PrimitiveKind::Pointer:
|