koffi 1.2.0-alpha.3 → 1.2.0-alpha.4
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 +9 -7
- package/package.json +4 -2
- package/qemu/registry/machines.json +26 -26
- package/src/abi_arm32.cc +63 -73
- package/src/abi_arm32_fwd.S +2 -2
- package/src/abi_arm64.cc +48 -55
- package/src/abi_arm64_fwd.S +2 -2
- package/src/abi_arm64_fwd.asm +2 -2
- package/src/abi_riscv64_fwd.S +2 -2
- package/src/abi_x64_sysv.cc +6 -1
- package/src/abi_x64_sysv_fwd.S +2 -2
- package/src/abi_x64_win.cc +4 -0
- package/src/abi_x64_win_fwd.asm +5 -5
- package/src/abi_x86.cc +2 -0
- package/src/abi_x86_fwd.S +4 -4
- package/src/abi_x86_fwd.asm +4 -4
- package/src/call.cc +49 -46
- package/src/call.hh +6 -6
- package/src/ffi.cc +4 -4
- package/src/util.cc +17 -0
- package/src/util.hh +2 -0
- package/test/async.js +92 -0
- package/test/callbacks.js +87 -0
- package/test/misc.c +25 -5
- package/test/sqlite.js +34 -5
- package/test/sync.js +323 -0
package/src/abi_arm64.cc
CHANGED
|
@@ -209,7 +209,7 @@ bool AnalyseFunction(InstanceData *, FunctionInfo *func)
|
|
|
209
209
|
|
|
210
210
|
bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
211
211
|
{
|
|
212
|
-
|
|
212
|
+
uint64_t *args_ptr = nullptr;
|
|
213
213
|
uint64_t *gpr_ptr = nullptr;
|
|
214
214
|
uint64_t *vec_ptr = nullptr;
|
|
215
215
|
|
|
@@ -244,16 +244,16 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
244
244
|
|
|
245
245
|
bool b = value.As<Napi::Boolean>();
|
|
246
246
|
|
|
247
|
+
#ifdef __APPLE__
|
|
247
248
|
if (RG_LIKELY(param.gpr_count)) {
|
|
248
249
|
*(gpr_ptr++) = (uint64_t)b;
|
|
249
250
|
} else {
|
|
250
|
-
*args_ptr =
|
|
251
|
-
|
|
252
|
-
|
|
251
|
+
*(uint8_t *)args_ptr = b;
|
|
252
|
+
args_ptr = (uint64_t *)((uint8_t *)args_ptr + 1);
|
|
253
|
+
}
|
|
253
254
|
#else
|
|
254
|
-
|
|
255
|
+
*((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint64_t)b;
|
|
255
256
|
#endif
|
|
256
|
-
}
|
|
257
257
|
} break;
|
|
258
258
|
case PrimitiveKind::Int8:
|
|
259
259
|
case PrimitiveKind::UInt8:
|
|
@@ -269,17 +269,17 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
269
269
|
|
|
270
270
|
int64_t v = CopyNumber<int64_t>(value);
|
|
271
271
|
|
|
272
|
+
#ifdef __APPLE__
|
|
272
273
|
if (RG_LIKELY(param.gpr_count)) {
|
|
273
274
|
*(int64_t *)(gpr_ptr++) = v;
|
|
274
275
|
} else {
|
|
275
276
|
args_ptr = AlignUp(args_ptr, param.type->align);
|
|
276
277
|
*(int64_t *)args_ptr = v;
|
|
277
|
-
|
|
278
|
-
|
|
278
|
+
args_ptr = (uint64_t *)((uint8_t *)args_ptr + param.type->size);
|
|
279
|
+
}
|
|
279
280
|
#else
|
|
280
|
-
|
|
281
|
+
*(int64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++) = v;
|
|
281
282
|
#endif
|
|
282
|
-
}
|
|
283
283
|
} break;
|
|
284
284
|
case PrimitiveKind::UInt64: {
|
|
285
285
|
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
@@ -289,13 +289,10 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
289
289
|
|
|
290
290
|
uint64_t v = CopyNumber<uint64_t>(value);
|
|
291
291
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
*(uint64_t *)args_ptr = v;
|
|
297
|
-
args_ptr += 8;
|
|
298
|
-
}
|
|
292
|
+
#ifdef __APPLE__
|
|
293
|
+
args_ptr = param.gpr_count ? args_ptr : AlignUp(args_ptr, 8);
|
|
294
|
+
#endif
|
|
295
|
+
*((param.gpr_count ? gpr_ptr : args_ptr)++) = v;
|
|
299
296
|
} break;
|
|
300
297
|
case PrimitiveKind::String: {
|
|
301
298
|
const char *str;
|
|
@@ -310,13 +307,10 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
310
307
|
return false;
|
|
311
308
|
}
|
|
312
309
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
*(uint64_t *)args_ptr = (uint64_t)str;
|
|
318
|
-
args_ptr += 8;
|
|
319
|
-
}
|
|
310
|
+
#ifdef __APPLE__
|
|
311
|
+
args_ptr = param.gpr_count ? args_ptr : AlignUp(args_ptr, 8);
|
|
312
|
+
#endif
|
|
313
|
+
*(const char **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str;
|
|
320
314
|
} break;
|
|
321
315
|
case PrimitiveKind::String16: {
|
|
322
316
|
const char16_t *str16;
|
|
@@ -331,13 +325,10 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
331
325
|
return false;
|
|
332
326
|
}
|
|
333
327
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
*(uint64_t *)args_ptr = (uint64_t)str16;
|
|
339
|
-
args_ptr += 8;
|
|
340
|
-
}
|
|
328
|
+
#ifdef __APPLE__
|
|
329
|
+
args_ptr = param.gpr_count ? args_ptr : AlignUp(args_ptr, 8);
|
|
330
|
+
#endif
|
|
331
|
+
*(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str16;
|
|
341
332
|
} break;
|
|
342
333
|
case PrimitiveKind::Pointer: {
|
|
343
334
|
uint8_t *ptr;
|
|
@@ -370,13 +361,10 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
370
361
|
return false;
|
|
371
362
|
}
|
|
372
363
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
*(uint64_t *)args_ptr = (uint64_t)ptr;
|
|
378
|
-
args_ptr += 8;
|
|
379
|
-
}
|
|
364
|
+
#ifdef __APPLE__
|
|
365
|
+
args_ptr = param.gpr_count ? args_ptr : AlignUp(args_ptr, 8);
|
|
366
|
+
#endif
|
|
367
|
+
*(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
|
|
380
368
|
} break;
|
|
381
369
|
case PrimitiveKind::Record: {
|
|
382
370
|
if (RG_UNLIKELY(!IsObject(value))) {
|
|
@@ -398,10 +386,12 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
398
386
|
return false;
|
|
399
387
|
gpr_ptr += param.gpr_count;
|
|
400
388
|
} else if (param.type->size) {
|
|
389
|
+
#ifdef __APPLE__
|
|
401
390
|
args_ptr = AlignUp(args_ptr, 8);
|
|
402
|
-
|
|
391
|
+
#endif
|
|
392
|
+
if (!PushObject(obj, param.type, (uint8_t *)args_ptr))
|
|
403
393
|
return false;
|
|
404
|
-
args_ptr +=
|
|
394
|
+
args_ptr += (param.type->size + 7) / 8;
|
|
405
395
|
}
|
|
406
396
|
} else {
|
|
407
397
|
uint8_t *ptr;
|
|
@@ -412,11 +402,12 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
412
402
|
RG_ASSERT(param.gpr_count == 1);
|
|
413
403
|
RG_ASSERT(param.vec_count == 0);
|
|
414
404
|
|
|
415
|
-
*(gpr_ptr++) =
|
|
405
|
+
*(uint8_t **)(gpr_ptr++) = ptr;
|
|
416
406
|
} else {
|
|
407
|
+
#ifdef __APPLE__
|
|
417
408
|
args_ptr = AlignUp(args_ptr, 8);
|
|
418
|
-
|
|
419
|
-
args_ptr
|
|
409
|
+
#endif
|
|
410
|
+
*(uint8_t **)(args_ptr++) = ptr;
|
|
420
411
|
}
|
|
421
412
|
|
|
422
413
|
if (!PushObject(obj, param.type, ptr))
|
|
@@ -433,14 +424,16 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
433
424
|
float f = CopyNumber<float>(value);
|
|
434
425
|
|
|
435
426
|
if (RG_LIKELY(param.vec_count)) {
|
|
427
|
+
memset((uint8_t *)vec_ptr + 4, 0, 4);
|
|
436
428
|
*(float *)(vec_ptr++) = f;
|
|
437
429
|
} else {
|
|
430
|
+
#ifdef __APPLE__
|
|
438
431
|
args_ptr = AlignUp(args_ptr, 4);
|
|
439
432
|
*(float *)args_ptr = f;
|
|
440
|
-
|
|
441
|
-
args_ptr += 4;
|
|
433
|
+
args_ptr = (uint64_t *)((uint8_t *)args_ptr + 4);
|
|
442
434
|
#else
|
|
443
|
-
args_ptr
|
|
435
|
+
memset((uint8_t *)args_ptr + 4, 0, 4);
|
|
436
|
+
*(float *)(args_ptr++) = f;
|
|
444
437
|
#endif
|
|
445
438
|
}
|
|
446
439
|
} break;
|
|
@@ -455,9 +448,10 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
455
448
|
if (RG_LIKELY(param.vec_count)) {
|
|
456
449
|
*(double *)(vec_ptr++) = d;
|
|
457
450
|
} else {
|
|
451
|
+
#ifdef __APPLE__
|
|
458
452
|
args_ptr = AlignUp(args_ptr, 8);
|
|
459
|
-
|
|
460
|
-
args_ptr
|
|
453
|
+
#endif
|
|
454
|
+
*(double *)(args_ptr++) = d;
|
|
461
455
|
}
|
|
462
456
|
} break;
|
|
463
457
|
case PrimitiveKind::Callback: {
|
|
@@ -480,13 +474,10 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
480
474
|
return false;
|
|
481
475
|
}
|
|
482
476
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
*(uint64_t *)args_ptr = (uint64_t)ptr;
|
|
488
|
-
args_ptr += 8;
|
|
489
|
-
}
|
|
477
|
+
#ifdef __APPLE__
|
|
478
|
+
args_ptr = param.gpr_count ? args_ptr : AlignUp(args_ptr, 8);
|
|
479
|
+
#endif
|
|
480
|
+
*(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
|
|
490
481
|
} break;
|
|
491
482
|
}
|
|
492
483
|
}
|
|
@@ -977,6 +968,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
977
968
|
}
|
|
978
969
|
|
|
979
970
|
float f = CopyNumber<float>(value);
|
|
971
|
+
|
|
972
|
+
memset((uint8_t *)&out_reg->d0 + 4, 0, 4);
|
|
980
973
|
memcpy(&out_reg->d0, &f, 4);
|
|
981
974
|
} break;
|
|
982
975
|
case PrimitiveKind::Float64: {
|
package/src/abi_arm64_fwd.S
CHANGED
|
@@ -287,8 +287,8 @@ SYMBOL(TrampolineX15):
|
|
|
287
287
|
trampoline_vec 15
|
|
288
288
|
|
|
289
289
|
# When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
290
|
-
# The
|
|
291
|
-
#
|
|
290
|
+
# The problem is that we're still running on the separate Koffi stack, and V8 will
|
|
291
|
+
# probably misdetect this as a "stack overflow". We have to restore the old
|
|
292
292
|
# stack pointer, call Node.js/V8 and go back to ours.
|
|
293
293
|
# The first three parameters (x0, x1, x2) are passed through untouched.
|
|
294
294
|
SYMBOL(CallSwitchStack):
|
package/src/abi_arm64_fwd.asm
CHANGED
|
@@ -302,8 +302,8 @@ TrampolineX15 PROC
|
|
|
302
302
|
ENDP
|
|
303
303
|
|
|
304
304
|
; When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
305
|
-
; The
|
|
306
|
-
;
|
|
305
|
+
; The problem is that we're still running on the separate Koffi stack, and V8 will
|
|
306
|
+
; probably misdetect this as a "stack overflow". We have to restore the old
|
|
307
307
|
; stack pointer, call Node.js/V8 and go back to ours.
|
|
308
308
|
; The first three parameters (x0, x1, x2) are passed through untouched.
|
|
309
309
|
CallSwitchStack PROC
|
package/src/abi_riscv64_fwd.S
CHANGED
|
@@ -300,8 +300,8 @@ TrampolineX15:
|
|
|
300
300
|
trampoline_vec 15
|
|
301
301
|
|
|
302
302
|
# When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
303
|
-
# The
|
|
304
|
-
#
|
|
303
|
+
# The problem is that we're still running on the separate Koffi stack, and V8 will
|
|
304
|
+
# probably misdetect this as a "stack overflow". We have to restore the old
|
|
305
305
|
# stack pointer, call Node.js/V8 and go back to ours.
|
|
306
306
|
# The first three parameters (a0, a1, a2) are passed through untouched.
|
|
307
307
|
CallSwitchStack:
|
package/src/abi_x64_sysv.cc
CHANGED
|
@@ -417,7 +417,10 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
417
417
|
}
|
|
418
418
|
|
|
419
419
|
float f = CopyNumber<float>(value);
|
|
420
|
-
*
|
|
420
|
+
uint64_t *ptr = (param.xmm_count ? xmm_ptr : args_ptr)++;
|
|
421
|
+
|
|
422
|
+
memset((uint8_t *)ptr + 4, 0, 4);
|
|
423
|
+
*(float *)ptr = f;
|
|
421
424
|
} break;
|
|
422
425
|
case PrimitiveKind::Float64: {
|
|
423
426
|
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
@@ -838,6 +841,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
838
841
|
}
|
|
839
842
|
|
|
840
843
|
float f = CopyNumber<float>(value);
|
|
844
|
+
|
|
845
|
+
memset((uint8_t *)&out_reg->xmm0 + 4, 0, 4);
|
|
841
846
|
memcpy(&out_reg->xmm0, &f, 4);
|
|
842
847
|
} break;
|
|
843
848
|
case PrimitiveKind::Float64: {
|
package/src/abi_x64_sysv_fwd.S
CHANGED
|
@@ -321,8 +321,8 @@ SYMBOL(TrampolineX15):
|
|
|
321
321
|
trampoline_xmm 15
|
|
322
322
|
|
|
323
323
|
# When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
324
|
-
# The
|
|
325
|
-
#
|
|
324
|
+
# The problem is that we're still running on the separate Koffi stack, and V8 will
|
|
325
|
+
# probably misdetect this as a "stack overflow". We have to restore the old
|
|
326
326
|
# stack pointer, call Node.js/V8 and go back to ours.
|
|
327
327
|
# The first three parameters (rdi, rsi, rdx) are passed through untouched.
|
|
328
328
|
SYMBOL(CallSwitchStack):
|
package/src/abi_x64_win.cc
CHANGED
|
@@ -244,6 +244,8 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
float f = CopyNumber<float>(value);
|
|
247
|
+
|
|
248
|
+
memset((uint8_t *)args_ptr + 4, 0, 4);
|
|
247
249
|
*(float *)(args_ptr++) = f;
|
|
248
250
|
} break;
|
|
249
251
|
case PrimitiveKind::Float64: {
|
|
@@ -622,6 +624,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
622
624
|
}
|
|
623
625
|
|
|
624
626
|
float f = CopyNumber<float>(value);
|
|
627
|
+
|
|
628
|
+
memset((uint8_t *)&out_reg->xmm0 + 4, 0, 4);
|
|
625
629
|
memcpy(&out_reg->xmm0, &f, 4);
|
|
626
630
|
} break;
|
|
627
631
|
case PrimitiveKind::Float64: {
|
package/src/abi_x64_win_fwd.asm
CHANGED
|
@@ -164,7 +164,7 @@ trampoline macro ID
|
|
|
164
164
|
lea r8, qword ptr [rsp+128]
|
|
165
165
|
lea r9, qword ptr [rsp+96]
|
|
166
166
|
call RelayCallBack
|
|
167
|
-
mov qword ptr [rsp+96]
|
|
167
|
+
mov rax, qword ptr [rsp+96]
|
|
168
168
|
add rsp, 120
|
|
169
169
|
ret
|
|
170
170
|
endm
|
|
@@ -188,8 +188,8 @@ trampoline_xmm macro ID
|
|
|
188
188
|
lea r8, qword ptr [rsp+128]
|
|
189
189
|
lea r9, qword ptr [rsp+96]
|
|
190
190
|
call RelayCallBack
|
|
191
|
-
mov qword ptr [rsp+96]
|
|
192
|
-
movsd qword ptr [rsp+104]
|
|
191
|
+
mov rax, qword ptr [rsp+96]
|
|
192
|
+
movsd xmm0, qword ptr [rsp+104]
|
|
193
193
|
add rsp, 120
|
|
194
194
|
ret
|
|
195
195
|
endm
|
|
@@ -293,8 +293,8 @@ TrampolineX15 proc frame
|
|
|
293
293
|
TrampolineX15 endp
|
|
294
294
|
|
|
295
295
|
; When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
296
|
-
; The
|
|
297
|
-
;
|
|
296
|
+
; The problem is that we're still running on the separate Koffi stack, and V8 will
|
|
297
|
+
; probably misdetect this as a "stack overflow". We have to restore the old
|
|
298
298
|
; stack pointer, call Node.js/V8 and go back to ours.
|
|
299
299
|
; The first three parameters (rcx, rdx, r8) are passed through untouched.
|
|
300
300
|
CallSwitchStack proc frame
|
package/src/abi_x86.cc
CHANGED
|
@@ -442,7 +442,9 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
442
442
|
used_trampolines &= ~(1u << idx);
|
|
443
443
|
|
|
444
444
|
uint32_t *args_ptr = (uint32_t *)caller_sp;
|
|
445
|
+
|
|
445
446
|
uint8_t *return_ptr = !proto->ret.trivial ? (uint8_t *)args_ptr[0] : nullptr;
|
|
447
|
+
args_ptr += !proto->ret.trivial;
|
|
446
448
|
|
|
447
449
|
LocalArray<napi_value, MaxParameters> arguments;
|
|
448
450
|
|
package/src/abi_x86_fwd.S
CHANGED
|
@@ -162,8 +162,8 @@ ForwardCallRD:
|
|
|
162
162
|
call GetEIP
|
|
163
163
|
addl $_GLOBAL_OFFSET_TABLE_, %ecx
|
|
164
164
|
call *RelayCallBack@GOT(%ecx)
|
|
165
|
-
cmpb $
|
|
166
|
-
|
|
165
|
+
cmpb $0, 36(%esp)
|
|
166
|
+
jne 2f
|
|
167
167
|
1:
|
|
168
168
|
flds 32(%esp)
|
|
169
169
|
jmp 3f
|
|
@@ -249,8 +249,8 @@ TrampolineX15:
|
|
|
249
249
|
trampoline_x87 15
|
|
250
250
|
|
|
251
251
|
# When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
252
|
-
# The
|
|
253
|
-
#
|
|
252
|
+
# The problem is that we're still running on the separate Koffi stack, and V8 will
|
|
253
|
+
# probably misdetect this as a "stack overflow". We have to restore the old
|
|
254
254
|
# stack pointer, call Node.js/V8 and go back to ours.
|
|
255
255
|
CallSwitchStack:
|
|
256
256
|
.cfi_startproc
|
package/src/abi_x86_fwd.asm
CHANGED
|
@@ -158,8 +158,8 @@ trampoline_x87 macro ID
|
|
|
158
158
|
lea eax, dword ptr [esp+16]
|
|
159
159
|
mov dword ptr [esp+12], eax
|
|
160
160
|
call RelayCallBack
|
|
161
|
-
cmp byte ptr[esp+36],
|
|
162
|
-
|
|
161
|
+
cmp byte ptr[esp+36], 0
|
|
162
|
+
jne l2
|
|
163
163
|
l1:
|
|
164
164
|
fld dword ptr [esp+32]
|
|
165
165
|
jmp l3
|
|
@@ -271,8 +271,8 @@ TrampolineX15 proc
|
|
|
271
271
|
TrampolineX15 endp
|
|
272
272
|
|
|
273
273
|
; When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
274
|
-
; The
|
|
275
|
-
;
|
|
274
|
+
; The problem is that we're still running on the separate Koffi stack, and V8 will
|
|
275
|
+
; probably misdetect this as a "stack overflow". We have to restore the old
|
|
276
276
|
; stack pointer, call Node.js/V8 and go back to ours.
|
|
277
277
|
CallSwitchStack proc
|
|
278
278
|
endbr32
|
package/src/call.cc
CHANGED
|
@@ -116,11 +116,13 @@ const char16_t *CallData::PushString16(const Napi::Value &value)
|
|
|
116
116
|
return buf.ptr;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
bool CallData::PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t *
|
|
119
|
+
bool CallData::PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t *origin, int16_t realign)
|
|
120
120
|
{
|
|
121
121
|
RG_ASSERT(IsObject(obj));
|
|
122
122
|
RG_ASSERT(type->primitive == PrimitiveKind::Record);
|
|
123
123
|
|
|
124
|
+
Size offset = 0;
|
|
125
|
+
|
|
124
126
|
for (const RecordMember &member: type->members) {
|
|
125
127
|
Napi::Value value = obj.Get(member.name);
|
|
126
128
|
|
|
@@ -130,7 +132,9 @@ bool CallData::PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t
|
|
|
130
132
|
}
|
|
131
133
|
|
|
132
134
|
int16_t align = std::max(member.align, realign);
|
|
133
|
-
|
|
135
|
+
offset = AlignLen(offset, align);
|
|
136
|
+
|
|
137
|
+
uint8_t *dest = origin + offset;
|
|
134
138
|
|
|
135
139
|
switch (member.type->primitive) {
|
|
136
140
|
case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
|
|
@@ -313,18 +317,19 @@ bool CallData::PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t
|
|
|
313
317
|
} break;
|
|
314
318
|
}
|
|
315
319
|
|
|
316
|
-
|
|
320
|
+
offset += member.type->size;
|
|
317
321
|
}
|
|
318
322
|
|
|
319
323
|
return true;
|
|
320
324
|
}
|
|
321
325
|
|
|
322
|
-
bool CallData::PushArray(const Napi::Value &obj, const TypeInfo *type, uint8_t *
|
|
326
|
+
bool CallData::PushArray(const Napi::Value &obj, const TypeInfo *type, uint8_t *origin, int16_t realign)
|
|
323
327
|
{
|
|
324
328
|
RG_ASSERT(obj.IsArray() || obj.IsTypedArray() || obj.IsString());
|
|
325
329
|
RG_ASSERT(type->primitive == PrimitiveKind::Array);
|
|
326
330
|
|
|
327
331
|
uint32_t len = type->size / type->ref->size;
|
|
332
|
+
Size offset = 0;
|
|
328
333
|
|
|
329
334
|
if (obj.IsArray()) {
|
|
330
335
|
Napi::Array array = obj.As<Napi::Array>();
|
|
@@ -340,7 +345,9 @@ bool CallData::PushArray(const Napi::Value &obj, const TypeInfo *type, uint8_t *
|
|
|
340
345
|
Napi::Value value = array[i]; \
|
|
341
346
|
\
|
|
342
347
|
int16_t align = std::max(type->ref->align, realign); \
|
|
343
|
-
|
|
348
|
+
\
|
|
349
|
+
offset = AlignLen(offset, align); \
|
|
350
|
+
uint8_t *dest = origin + offset; \
|
|
344
351
|
\
|
|
345
352
|
if (RG_UNLIKELY(!(Check))) { \
|
|
346
353
|
ThrowError<Napi::TypeError>(env, "Unexpected value %1 in array, expected %2", GetValueType(instance, value), (Expected)); \
|
|
@@ -349,7 +356,7 @@ bool CallData::PushArray(const Napi::Value &obj, const TypeInfo *type, uint8_t *
|
|
|
349
356
|
\
|
|
350
357
|
GetCode \
|
|
351
358
|
\
|
|
352
|
-
|
|
359
|
+
offset += type->ref->size; \
|
|
353
360
|
} \
|
|
354
361
|
} while (false)
|
|
355
362
|
|
|
@@ -467,7 +474,9 @@ bool CallData::PushArray(const Napi::Value &obj, const TypeInfo *type, uint8_t *
|
|
|
467
474
|
Napi::Value value = array[i];
|
|
468
475
|
|
|
469
476
|
int16_t align = std::max(type->ref->align, realign);
|
|
470
|
-
|
|
477
|
+
offset = AlignLen(offset, align);
|
|
478
|
+
|
|
479
|
+
uint8_t *dest = origin + offset;
|
|
471
480
|
|
|
472
481
|
void *ptr;
|
|
473
482
|
|
|
@@ -491,7 +500,7 @@ bool CallData::PushArray(const Napi::Value &obj, const TypeInfo *type, uint8_t *
|
|
|
491
500
|
|
|
492
501
|
*(void **)dest = ptr;
|
|
493
502
|
|
|
494
|
-
|
|
503
|
+
offset += type->ref->size;
|
|
495
504
|
}
|
|
496
505
|
} break;
|
|
497
506
|
}
|
|
@@ -526,20 +535,22 @@ bool CallData::PushArray(const Napi::Value &obj, const TypeInfo *type, uint8_t *
|
|
|
526
535
|
|
|
527
536
|
for (uint32_t i = 0; i < len; i++) {
|
|
528
537
|
int16_t align = std::max(type->ref->align, realign);
|
|
529
|
-
|
|
538
|
+
offset = AlignLen(offset, align);
|
|
539
|
+
|
|
540
|
+
uint8_t *dest = origin + offset;
|
|
530
541
|
|
|
531
542
|
memcpy(dest, buf + i * type->ref->size, type->ref->size);
|
|
532
543
|
|
|
533
|
-
|
|
544
|
+
offset += type->ref->size;
|
|
534
545
|
}
|
|
535
546
|
} else if (obj.IsString()) {
|
|
536
547
|
size_t encoded = 0;
|
|
537
548
|
|
|
538
549
|
if (type->ref->primitive == PrimitiveKind::Int8 || type->ref->primitive == PrimitiveKind::UInt8) {
|
|
539
|
-
napi_status status = napi_get_value_string_utf8(env, obj, (char *)
|
|
550
|
+
napi_status status = napi_get_value_string_utf8(env, obj, (char *)origin, type->size, &encoded);
|
|
540
551
|
RG_ASSERT(status == napi_ok);
|
|
541
552
|
} else if (type->ref->primitive == PrimitiveKind::Int16 || type->ref->primitive == PrimitiveKind::UInt16) {
|
|
542
|
-
napi_status status = napi_get_value_string_utf16(env, obj, (char16_t *)
|
|
553
|
+
napi_status status = napi_get_value_string_utf16(env, obj, (char16_t *)origin, type->size / 2, &encoded);
|
|
543
554
|
RG_ASSERT(status == napi_ok);
|
|
544
555
|
|
|
545
556
|
encoded *= 2;
|
|
@@ -548,7 +559,7 @@ bool CallData::PushArray(const Napi::Value &obj, const TypeInfo *type, uint8_t *
|
|
|
548
559
|
return false;
|
|
549
560
|
}
|
|
550
561
|
|
|
551
|
-
memset_safe(
|
|
562
|
+
memset_safe(origin + encoded, 0, type->size - encoded);
|
|
552
563
|
} else {
|
|
553
564
|
RG_UNREACHABLE();
|
|
554
565
|
}
|
|
@@ -574,16 +585,20 @@ Size CallData::ReserveTrampoline(const FunctionInfo *proto, Napi::Function func)
|
|
|
574
585
|
return idx;
|
|
575
586
|
}
|
|
576
587
|
|
|
577
|
-
void CallData::PopObject(Napi::Object obj, const uint8_t *
|
|
588
|
+
void CallData::PopObject(Napi::Object obj, const uint8_t *origin, const TypeInfo *type, int16_t realign)
|
|
578
589
|
{
|
|
579
590
|
Napi::Env env = obj.Env();
|
|
580
591
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
581
592
|
|
|
582
593
|
RG_ASSERT(type->primitive == PrimitiveKind::Record);
|
|
583
594
|
|
|
595
|
+
Size offset = 0;
|
|
596
|
+
|
|
584
597
|
for (const RecordMember &member: type->members) {
|
|
585
598
|
int16_t align = std::max(realign, member.align);
|
|
586
|
-
|
|
599
|
+
offset = AlignLen(offset, align);
|
|
600
|
+
|
|
601
|
+
const uint8_t *src = origin + offset;
|
|
587
602
|
|
|
588
603
|
switch (member.type->primitive) {
|
|
589
604
|
case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
|
|
@@ -663,18 +678,18 @@ void CallData::PopObject(Napi::Object obj, const uint8_t *src, const TypeInfo *t
|
|
|
663
678
|
} break;
|
|
664
679
|
}
|
|
665
680
|
|
|
666
|
-
|
|
681
|
+
offset += member.type->size;
|
|
667
682
|
}
|
|
668
683
|
}
|
|
669
684
|
|
|
670
|
-
Napi::Object CallData::PopObject(const uint8_t *
|
|
685
|
+
Napi::Object CallData::PopObject(const uint8_t *origin, const TypeInfo *type, int16_t realign)
|
|
671
686
|
{
|
|
672
687
|
Napi::Object obj = Napi::Object::New(env);
|
|
673
|
-
PopObject(obj,
|
|
688
|
+
PopObject(obj, origin, type, realign);
|
|
674
689
|
return obj;
|
|
675
690
|
}
|
|
676
691
|
|
|
677
|
-
Size WideStringLength(const char16_t *str16, Size max)
|
|
692
|
+
static Size WideStringLength(const char16_t *str16, Size max)
|
|
678
693
|
{
|
|
679
694
|
Size len = 0;
|
|
680
695
|
|
|
@@ -685,13 +700,14 @@ Size WideStringLength(const char16_t *str16, Size max)
|
|
|
685
700
|
return len;
|
|
686
701
|
}
|
|
687
702
|
|
|
688
|
-
Napi::Value CallData::PopArray(const uint8_t *
|
|
703
|
+
Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int16_t realign)
|
|
689
704
|
{
|
|
690
705
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
691
706
|
|
|
692
707
|
RG_ASSERT(type->primitive == PrimitiveKind::Array);
|
|
693
708
|
|
|
694
709
|
uint32_t len = type->size / type->ref->size;
|
|
710
|
+
Size offset = 0;
|
|
695
711
|
|
|
696
712
|
#define POP_ARRAY(SetCode) \
|
|
697
713
|
do { \
|
|
@@ -699,11 +715,13 @@ Napi::Value CallData::PopArray(const uint8_t *src, const TypeInfo *type, int16_t
|
|
|
699
715
|
\
|
|
700
716
|
for (uint32_t i = 0; i < len; i++) { \
|
|
701
717
|
int16_t align = std::max(realign, type->ref->align); \
|
|
702
|
-
|
|
718
|
+
offset = AlignLen(offset, align); \
|
|
719
|
+
\
|
|
720
|
+
const uint8_t *src = origin + offset; \
|
|
703
721
|
\
|
|
704
722
|
SetCode \
|
|
705
723
|
\
|
|
706
|
-
|
|
724
|
+
offset += type->ref->size; \
|
|
707
725
|
} \
|
|
708
726
|
\
|
|
709
727
|
return array; \
|
|
@@ -720,12 +738,14 @@ Napi::Value CallData::PopArray(const uint8_t *src, const TypeInfo *type, int16_t
|
|
|
720
738
|
\
|
|
721
739
|
for (uint32_t i = 0; i < len; i++) { \
|
|
722
740
|
int16_t align = std::max(realign, type->ref->align); \
|
|
723
|
-
|
|
741
|
+
offset = AlignLen(offset, align); \
|
|
742
|
+
\
|
|
743
|
+
const uint8_t *src = origin + offset; \
|
|
724
744
|
\
|
|
725
745
|
CType f = *(CType *)src; \
|
|
726
746
|
array[i] = f; \
|
|
727
747
|
\
|
|
728
|
-
|
|
748
|
+
offset += type->ref->size; \
|
|
729
749
|
} \
|
|
730
750
|
\
|
|
731
751
|
return array; \
|
|
@@ -745,7 +765,7 @@ Napi::Value CallData::PopArray(const uint8_t *src, const TypeInfo *type, int16_t
|
|
|
745
765
|
if (type->hint == TypeInfo::ArrayHint::String) {
|
|
746
766
|
RG_ASSERT(!realign);
|
|
747
767
|
|
|
748
|
-
const char *ptr = (const char *)
|
|
768
|
+
const char *ptr = (const char *)origin;
|
|
749
769
|
size_t count = strnlen(ptr, (size_t)len);
|
|
750
770
|
|
|
751
771
|
Napi::String str = Napi::String::New(env, ptr, count);
|
|
@@ -758,7 +778,7 @@ Napi::Value CallData::PopArray(const uint8_t *src, const TypeInfo *type, int16_t
|
|
|
758
778
|
if (type->hint == TypeInfo::ArrayHint::String) {
|
|
759
779
|
RG_ASSERT(!realign);
|
|
760
780
|
|
|
761
|
-
const char *ptr = (const char *)
|
|
781
|
+
const char *ptr = (const char *)origin;
|
|
762
782
|
size_t count = strnlen(ptr, (size_t)len);
|
|
763
783
|
|
|
764
784
|
Napi::String str = Napi::String::New(env, ptr, count);
|
|
@@ -771,7 +791,7 @@ Napi::Value CallData::PopArray(const uint8_t *src, const TypeInfo *type, int16_t
|
|
|
771
791
|
if (type->hint == TypeInfo::ArrayHint::String) {
|
|
772
792
|
RG_ASSERT(!realign);
|
|
773
793
|
|
|
774
|
-
const char16_t *ptr = (const char16_t *)
|
|
794
|
+
const char16_t *ptr = (const char16_t *)origin;
|
|
775
795
|
Size count = WideStringLength(ptr, len);
|
|
776
796
|
|
|
777
797
|
Napi::String str = Napi::String::New(env, ptr, count);
|
|
@@ -784,7 +804,7 @@ Napi::Value CallData::PopArray(const uint8_t *src, const TypeInfo *type, int16_t
|
|
|
784
804
|
if (type->hint == TypeInfo::ArrayHint::String) {
|
|
785
805
|
RG_ASSERT(!realign);
|
|
786
806
|
|
|
787
|
-
const char16_t *ptr = (const char16_t *)
|
|
807
|
+
const char16_t *ptr = (const char16_t *)origin;
|
|
788
808
|
Size count = WideStringLength(ptr, len);
|
|
789
809
|
|
|
790
810
|
Napi::String str = Napi::String::New(env, ptr, count);
|
|
@@ -856,24 +876,7 @@ Napi::Value CallData::PopArray(const uint8_t *src, const TypeInfo *type, int16_t
|
|
|
856
876
|
RG_UNREACHABLE();
|
|
857
877
|
}
|
|
858
878
|
|
|
859
|
-
|
|
860
|
-
{
|
|
861
|
-
if (bytes.len) {
|
|
862
|
-
PrintLn(stderr, "%1 at 0x%2 (%3):", type, bytes.ptr, FmtMemSize(bytes.len));
|
|
863
|
-
|
|
864
|
-
for (const uint8_t *ptr = bytes.begin(); ptr < bytes.end();) {
|
|
865
|
-
Print(stderr, " [0x%1 %2 %3] ", FmtArg(ptr).Pad0(-16),
|
|
866
|
-
FmtArg((ptr - bytes.begin()) / sizeof(void *)).Pad(-4),
|
|
867
|
-
FmtArg(ptr - bytes.begin()).Pad(-4));
|
|
868
|
-
for (int i = 0; ptr < bytes.end() && i < (int)sizeof(void *); i++, ptr++) {
|
|
869
|
-
Print(stderr, " %1", FmtHex(*ptr).Pad0(-2));
|
|
870
|
-
}
|
|
871
|
-
PrintLn(stderr);
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
|
|
876
|
-
void CallData::DumpDebug() const
|
|
879
|
+
void CallData::DumpForward() const
|
|
877
880
|
{
|
|
878
881
|
PrintLn(stderr, "%!..+---- %1 (%2) ----%!0", func->name, CallConventionNames[(int)func->convention]);
|
|
879
882
|
|