koffi 3.0.0 → 3.0.2
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 +20 -1
- package/README.md +5 -4
- package/cnoke.cjs +10 -10
- package/doc/benchmarks.md +24 -47
- package/doc/callbacks.md +4 -13
- package/doc/contribute.md +4 -4
- package/doc/index.md +3 -2
- package/doc/migration.md +100 -0
- package/doc/start.md +7 -5
- package/index.d.ts +53 -5
- package/index.js +2 -1
- package/indirect.js +2 -1
- package/package.json +20 -18
- package/src/koffi/CMakeLists.txt +20 -12
- package/src/koffi/index.cjs +92 -129
- package/src/koffi/index.js +128 -113
- package/src/koffi/indirect.cjs +91 -128
- package/src/koffi/indirect.js +129 -40
- package/src/koffi/src/abi/arm64.cc +30 -29
- package/src/koffi/src/abi/riscv64.cc +30 -29
- package/src/koffi/src/abi/x64sysv.cc +26 -25
- package/src/koffi/src/abi/x64win.cc +64 -63
- package/src/koffi/src/abi/x86.cc +67 -65
- package/src/koffi/src/call.cc +210 -99
- package/src/koffi/src/call.hh +2 -1
- package/src/koffi/src/ffi.cc +403 -237
- package/src/koffi/src/ffi.hh +46 -7
- package/src/koffi/src/parser.cc +3 -1
- package/src/koffi/src/primitives.inc +1 -4
- package/src/koffi/src/static.cjs +122 -0
- package/src/koffi/src/static.js +122 -0
- package/src/koffi/src/type.cc +715 -0
- package/src/koffi/src/type.hh +71 -0
- package/src/koffi/src/util.cc +189 -1120
- package/src/koffi/src/util.hh +85 -125
- package/src/koffi/src/uv.cc +16 -10
- package/src/koffi/src/uv.hh +2 -1
package/src/koffi/src/abi/x86.cc
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
#include "lib/native/base/base.hh"
|
|
7
7
|
#include "../ffi.hh"
|
|
8
8
|
#include "../call.hh"
|
|
9
|
+
#include "../type.hh"
|
|
9
10
|
#include "../util.hh"
|
|
10
11
|
#if defined(_WIN32)
|
|
11
12
|
#include "../win32.hh"
|
|
@@ -36,19 +37,19 @@ extern "C" double ForwardCallDR(const void *func, uint8_t *sp, uint8_t **out_sav
|
|
|
36
37
|
enum class AbiOpcode {
|
|
37
38
|
#define PRIMITIVE(Name) Push ## Name,
|
|
38
39
|
#include "../primitives.inc"
|
|
39
|
-
|
|
40
|
+
PushAggregateStack,
|
|
40
41
|
#define PRIMITIVE(Name) Run ## Name,
|
|
41
42
|
#include "../primitives.inc"
|
|
42
43
|
RunAggregateG,
|
|
43
44
|
RunAggregateF,
|
|
44
45
|
RunAggregateD,
|
|
45
|
-
|
|
46
|
+
RunAggregateMem,
|
|
46
47
|
#define PRIMITIVE(Name) Run ## Name ## R,
|
|
47
48
|
#include "../primitives.inc"
|
|
48
49
|
RunAggregateGR,
|
|
49
50
|
RunAggregateFR,
|
|
50
51
|
RunAggregateDR,
|
|
51
|
-
|
|
52
|
+
RunAggregateMemR,
|
|
52
53
|
Yield,
|
|
53
54
|
CallG,
|
|
54
55
|
CallF,
|
|
@@ -61,7 +62,7 @@ enum class AbiOpcode {
|
|
|
61
62
|
#define PRIMITIVE(Name) Return ## Name,
|
|
62
63
|
#include "../primitives.inc"
|
|
63
64
|
ReturnAggregateReg,
|
|
64
|
-
|
|
65
|
+
ReturnAggregateMem
|
|
65
66
|
};
|
|
66
67
|
|
|
67
68
|
static inline void *Code2Op(AbiOpcode code)
|
|
@@ -119,14 +120,14 @@ bool AnalyseFunction(Napi::Env env, InstanceData *instance, FunctionInfo *func)
|
|
|
119
120
|
}
|
|
120
121
|
|
|
121
122
|
if (param.type->primitive == PrimitiveKind::Record || param.type->primitive == PrimitiveKind::Union) {
|
|
122
|
-
func->sync.Append({ .op = Code2Op(AbiOpcode::
|
|
123
|
-
func->async.Append({ .op = Code2Op(AbiOpcode::
|
|
123
|
+
func->sync.Append({ .op = Code2Op(AbiOpcode::PushAggregateStack), .a = param.offset, .b1 = (int16_t)(offset * 4), .b2 = (int16_t)param.directions, .type = param.type });
|
|
124
|
+
func->async.Append({ .op = Code2Op(AbiOpcode::PushAggregateStack), .a = param.offset, .b1 = (int16_t)(offset * 4), .b2 = (int16_t)param.directions, .type = param.type });
|
|
124
125
|
} else {
|
|
125
126
|
int delta = (int)AbiOpcode::PushVoid - (int)PrimitiveKind::Void;
|
|
126
127
|
AbiOpcode code = (AbiOpcode)((int)param.type->primitive + delta);
|
|
127
128
|
|
|
128
|
-
func->sync.Append({ .op = Code2Op(code), .a = param.offset, .b1 = offset, .b2 = (int16_t)param.directions, .type = param.type });
|
|
129
|
-
func->async.Append({ .op = Code2Op(code), .a = param.offset, .b1 = offset, .b2 = (int16_t)param.directions, .type = param.type });
|
|
129
|
+
func->sync.Append({ .op = Code2Op(code), .a = param.offset, .b1 = (int16_t)(offset * 4), .b2 = (int16_t)param.directions, .type = param.type });
|
|
130
|
+
func->async.Append({ .op = Code2Op(code), .a = param.offset, .b1 = (int16_t)(offset * 4), .b2 = (int16_t)param.directions, .type = param.type });
|
|
130
131
|
}
|
|
131
132
|
}
|
|
132
133
|
|
|
@@ -232,12 +233,12 @@ bool AnalyseFunction(Napi::Env env, InstanceData *instance, FunctionInfo *func)
|
|
|
232
233
|
func->async.Append({ .op = Code2Op(call) });
|
|
233
234
|
func->async.Append({ .op = Code2Op(AbiOpcode::ReturnAggregateReg), .type = func->ret.type });
|
|
234
235
|
} else {
|
|
235
|
-
AbiOpcode run = fast ? AbiOpcode::
|
|
236
|
+
AbiOpcode run = fast ? AbiOpcode::RunAggregateMemR : AbiOpcode::RunAggregateMem;
|
|
236
237
|
AbiOpcode call = fast ? AbiOpcode::CallStackR : AbiOpcode::CallStack;
|
|
237
238
|
|
|
238
239
|
func->sync.Append({ .op = Code2Op(run), .a = (int32_t)func->ret.type->size, .type = func->ret.type });
|
|
239
240
|
func->async.Append({ .op = Code2Op(call), .a = (int32_t)func->ret.type->size });
|
|
240
|
-
func->async.Append({ .op = Code2Op(AbiOpcode::
|
|
241
|
+
func->async.Append({ .op = Code2Op(AbiOpcode::ReturnAggregateMem), .type = func->ret.type });
|
|
241
242
|
}
|
|
242
243
|
} break;
|
|
243
244
|
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
@@ -298,7 +299,7 @@ namespace {
|
|
|
298
299
|
#define NEXT() \
|
|
299
300
|
break
|
|
300
301
|
|
|
301
|
-
napi_value RunLoop(CallData *call, napi_value *args,
|
|
302
|
+
napi_value RunLoop(CallData *call, napi_value *args, uint8_t *base, const AbiInstruction *inst)
|
|
302
303
|
{
|
|
303
304
|
for (;; ++inst) {
|
|
304
305
|
switch ((intptr_t)inst->op) {
|
|
@@ -328,7 +329,7 @@ napi_value RunLoop(CallData *call, napi_value *args, uint32_t *base, const AbiIn
|
|
|
328
329
|
return call->env.Null(); \
|
|
329
330
|
} \
|
|
330
331
|
\
|
|
331
|
-
*(base + inst->b1) = (uint32_t)v; \
|
|
332
|
+
*(uint32_t *)(base + inst->b1) = (uint32_t)v; \
|
|
332
333
|
} while (false)
|
|
333
334
|
#define INTEGER32_SWAP(CType) \
|
|
334
335
|
do { \
|
|
@@ -338,7 +339,7 @@ napi_value RunLoop(CallData *call, napi_value *args, uint32_t *base, const AbiIn
|
|
|
338
339
|
return call->env.Null(); \
|
|
339
340
|
} \
|
|
340
341
|
\
|
|
341
|
-
*(base + inst->b1) = (uint32_t)ReverseBytes(v); \
|
|
342
|
+
*(uint32_t *)(base + inst->b1) = (uint32_t)ReverseBytes(v); \
|
|
342
343
|
} while (false)
|
|
343
344
|
#define INTEGER64(CType) \
|
|
344
345
|
do { \
|
|
@@ -459,7 +460,7 @@ napi_value RunLoop(CallData *call, napi_value *args, uint32_t *base, const AbiIn
|
|
|
459
460
|
NEXT();
|
|
460
461
|
}
|
|
461
462
|
OP(PushPrototype) { K_UNREACHABLE(); return call->env.Null(); }
|
|
462
|
-
OP(
|
|
463
|
+
OP(PushAggregateStack) {
|
|
463
464
|
napi_value arg = args[inst->a];
|
|
464
465
|
|
|
465
466
|
if (!IsObject(call->env, arg)) [[unlikely]] {
|
|
@@ -482,22 +483,22 @@ napi_value RunLoop(CallData *call, napi_value *args, uint32_t *base, const AbiIn
|
|
|
482
483
|
|
|
483
484
|
#define INTEGER32(Suffix, CType) \
|
|
484
485
|
do { \
|
|
485
|
-
uint32_t eax = (uint32_t)WRAP(ForwardCall ## Suffix(call->native,
|
|
486
|
+
uint32_t eax = (uint32_t)WRAP(ForwardCall ## Suffix(call->native, base, &call->saved_sp)); \
|
|
486
487
|
return NewInt(call->env, (CType)eax); \
|
|
487
488
|
} while (false)
|
|
488
489
|
#define INTEGER32_SWAP(Suffix, CType) \
|
|
489
490
|
do { \
|
|
490
|
-
uint32_t eax = (uint32_t)WRAP(ForwardCall ## Suffix(call->native,
|
|
491
|
+
uint32_t eax = (uint32_t)WRAP(ForwardCall ## Suffix(call->native, base, &call->saved_sp)); \
|
|
491
492
|
return NewInt(call->env, ReverseBytes((CType)eax)); \
|
|
492
493
|
} while (false)
|
|
493
494
|
#define INTEGER64(Suffix, CType) \
|
|
494
495
|
do { \
|
|
495
|
-
uint64_t ret = WRAP(ForwardCall ## Suffix(call->native,
|
|
496
|
+
uint64_t ret = WRAP(ForwardCall ## Suffix(call->native, base, &call->saved_sp)); \
|
|
496
497
|
return NewInt(call->env, (CType)ret); \
|
|
497
498
|
} while (false)
|
|
498
499
|
#define INTEGER64_SWAP(Suffix, CType) \
|
|
499
500
|
do { \
|
|
500
|
-
uint64_t ret = WRAP(ForwardCall ## Suffix(call->native,
|
|
501
|
+
uint64_t ret = WRAP(ForwardCall ## Suffix(call->native, base, &call->saved_sp)); \
|
|
501
502
|
return NewInt(call->env, ReverseBytes((CType)ret)); \
|
|
502
503
|
} while (false)
|
|
503
504
|
#define DISPOSE(Ptr) \
|
|
@@ -508,11 +509,11 @@ napi_value RunLoop(CallData *call, napi_value *args, uint32_t *base, const AbiIn
|
|
|
508
509
|
} while (false)
|
|
509
510
|
|
|
510
511
|
OP(RunVoid) {
|
|
511
|
-
WRAP(ForwardCallG(call->native,
|
|
512
|
+
WRAP(ForwardCallG(call->native, base, &call->saved_sp));
|
|
512
513
|
return nullptr;
|
|
513
514
|
}
|
|
514
515
|
OP(RunBool) {
|
|
515
|
-
uint32_t eax = (uint32_t)WRAP(ForwardCallG(call->native,
|
|
516
|
+
uint32_t eax = (uint32_t)WRAP(ForwardCallG(call->native, base, &call->saved_sp));
|
|
516
517
|
return Napi::Boolean::New(call->env, eax & 0x1);
|
|
517
518
|
}
|
|
518
519
|
OP(RunInt8) { INTEGER32(G, int8_t); }
|
|
@@ -530,68 +531,68 @@ napi_value RunLoop(CallData *call, napi_value *args, uint32_t *base, const AbiIn
|
|
|
530
531
|
OP(RunUInt64) { INTEGER64(G, uint64_t); }
|
|
531
532
|
OP(RunUInt64S) { INTEGER64_SWAP(G, uint64_t); }
|
|
532
533
|
OP(RunString) {
|
|
533
|
-
uint32_t eax = (uint32_t)WRAP(ForwardCallG(call->native,
|
|
534
|
+
uint32_t eax = (uint32_t)WRAP(ForwardCallG(call->native, base, &call->saved_sp));
|
|
534
535
|
napi_value value = eax ? Napi::String::New(call->env, (const char *)eax) : call->env.Null();
|
|
535
536
|
DISPOSE((void *)eax);
|
|
536
537
|
return value;
|
|
537
538
|
}
|
|
538
539
|
OP(RunString16) {
|
|
539
|
-
uint32_t eax = (uint32_t)WRAP(ForwardCallG(call->native,
|
|
540
|
+
uint32_t eax = (uint32_t)WRAP(ForwardCallG(call->native, base, &call->saved_sp));
|
|
540
541
|
napi_value value = eax ? Napi::String::New(call->env, (const char16_t *)eax) : call->env.Null();
|
|
541
542
|
DISPOSE((void *)eax);
|
|
542
543
|
return value;
|
|
543
544
|
}
|
|
544
545
|
OP(RunString32) {
|
|
545
|
-
uint32_t eax = (uint32_t)WRAP(ForwardCallG(call->native,
|
|
546
|
+
uint32_t eax = (uint32_t)WRAP(ForwardCallG(call->native, base, &call->saved_sp));
|
|
546
547
|
napi_value value = eax ? MakeStringFromUTF32(call->env, (const char32_t *)eax) : call->env.Null();
|
|
547
548
|
DISPOSE((void *)eax);
|
|
548
549
|
return value;
|
|
549
550
|
}
|
|
550
551
|
OP(RunPointer) {
|
|
551
|
-
uint32_t eax = (uint32_t)WRAP(ForwardCallG(call->native,
|
|
552
|
+
uint32_t eax = (uint32_t)WRAP(ForwardCallG(call->native, base, &call->saved_sp));
|
|
552
553
|
napi_value value = eax ? WrapPointer(call->env, inst->type, (void *)eax) : call->env.Null();
|
|
553
554
|
DISPOSE((void *)eax);
|
|
554
555
|
return value;
|
|
555
556
|
}
|
|
556
557
|
OP(RunCallback) {
|
|
557
|
-
uint32_t eax = (uint32_t)WRAP(ForwardCallG(call->native,
|
|
558
|
+
uint32_t eax = (uint32_t)WRAP(ForwardCallG(call->native, base, &call->saved_sp));
|
|
558
559
|
return eax ? WrapPointer(call->env, inst->type, (void *)eax) : call->env.Null();
|
|
559
560
|
}
|
|
560
561
|
OP(RunRecord) { K_UNREACHABLE(); return call->env.Null(); }
|
|
561
562
|
OP(RunUnion) { K_UNREACHABLE(); return call->env.Null(); }
|
|
562
563
|
OP(RunArray) { K_UNREACHABLE(); return call->env.Null(); }
|
|
563
564
|
OP(RunFloat32) {
|
|
564
|
-
float f = WRAP(ForwardCallF(call->native,
|
|
565
|
+
float f = WRAP(ForwardCallF(call->native, base, &call->saved_sp));
|
|
565
566
|
return Napi::Number::New(call->env, (double)f);
|
|
566
567
|
}
|
|
567
568
|
OP(RunFloat64) {
|
|
568
|
-
double d = WRAP(ForwardCallD(call->native,
|
|
569
|
+
double d = WRAP(ForwardCallD(call->native, base, &call->saved_sp));
|
|
569
570
|
return Napi::Number::New(call->env, d);
|
|
570
571
|
}
|
|
571
572
|
OP(RunPrototype) { K_UNREACHABLE(); return call->env.Null(); }
|
|
572
573
|
OP(RunAggregateG) {
|
|
573
|
-
auto ret = WRAP(ForwardCallG(call->native,
|
|
574
|
-
return DecodeObject(call->
|
|
574
|
+
auto ret = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
|
|
575
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
575
576
|
}
|
|
576
577
|
OP(RunAggregateF) {
|
|
577
|
-
auto ret = WRAP(ForwardCallF(call->native,
|
|
578
|
-
return DecodeObject(call->
|
|
578
|
+
auto ret = WRAP(ForwardCallF(call->native, base, &call->saved_sp));
|
|
579
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
579
580
|
}
|
|
580
581
|
OP(RunAggregateD) {
|
|
581
|
-
auto ret = WRAP(ForwardCallD(call->native,
|
|
582
|
-
return DecodeObject(call->
|
|
582
|
+
auto ret = WRAP(ForwardCallD(call->native, base, &call->saved_sp));
|
|
583
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
583
584
|
}
|
|
584
|
-
OP(
|
|
585
|
+
OP(RunAggregateMem) {
|
|
585
586
|
*(uint8_t **)base = call->AllocHeap(inst->a);
|
|
586
|
-
uint32_t eax = (uint32_t)WRAP(ForwardCallG(call->native,
|
|
587
|
-
return DecodeObject(call->
|
|
587
|
+
uint32_t eax = (uint32_t)WRAP(ForwardCallG(call->native, base, &call->saved_sp));
|
|
588
|
+
return DecodeObject(call->instance, (const uint8_t *)eax, inst->type);
|
|
588
589
|
}
|
|
589
590
|
OP(RunVoidR) {
|
|
590
|
-
WRAP(ForwardCallGR(call->native,
|
|
591
|
+
WRAP(ForwardCallGR(call->native, base, &call->saved_sp));
|
|
591
592
|
return nullptr;
|
|
592
593
|
}
|
|
593
594
|
OP(RunBoolR) {
|
|
594
|
-
uint32_t eax = (uint32_t)WRAP(ForwardCallGR(call->native,
|
|
595
|
+
uint32_t eax = (uint32_t)WRAP(ForwardCallGR(call->native, base, &call->saved_sp));
|
|
595
596
|
return Napi::Boolean::New(call->env, eax & 0x1);
|
|
596
597
|
}
|
|
597
598
|
OP(RunInt8R) { INTEGER32(GR, int8_t); }
|
|
@@ -609,65 +610,65 @@ napi_value RunLoop(CallData *call, napi_value *args, uint32_t *base, const AbiIn
|
|
|
609
610
|
OP(RunUInt64R) { INTEGER64(GR, uint64_t); }
|
|
610
611
|
OP(RunUInt64SR) { INTEGER64_SWAP(GR, uint64_t); }
|
|
611
612
|
OP(RunStringR) {
|
|
612
|
-
uint32_t eax = (uint32_t)WRAP(ForwardCallGR(call->native,
|
|
613
|
+
uint32_t eax = (uint32_t)WRAP(ForwardCallGR(call->native, base, &call->saved_sp));
|
|
613
614
|
napi_value value = eax ? Napi::String::New(call->env, (const char *)eax) : call->env.Null();
|
|
614
615
|
DISPOSE((void *)eax);
|
|
615
616
|
return value;
|
|
616
617
|
}
|
|
617
618
|
OP(RunString16R) {
|
|
618
|
-
uint32_t eax = (uint32_t)WRAP(ForwardCallGR(call->native,
|
|
619
|
+
uint32_t eax = (uint32_t)WRAP(ForwardCallGR(call->native, base, &call->saved_sp));
|
|
619
620
|
napi_value value = eax ? Napi::String::New(call->env, (const char16_t *)eax) : call->env.Null();
|
|
620
621
|
DISPOSE((void *)eax);
|
|
621
622
|
return value;
|
|
622
623
|
}
|
|
623
624
|
OP(RunString32R) {
|
|
624
|
-
uint32_t eax = (uint32_t)WRAP(ForwardCallGR(call->native,
|
|
625
|
+
uint32_t eax = (uint32_t)WRAP(ForwardCallGR(call->native, base, &call->saved_sp));
|
|
625
626
|
napi_value value = eax ? MakeStringFromUTF32(call->env, (const char32_t *)eax) : call->env.Null();
|
|
626
627
|
DISPOSE((void *)eax);
|
|
627
628
|
return value;
|
|
628
629
|
}
|
|
629
630
|
OP(RunPointerR) {
|
|
630
|
-
uint32_t eax = (uint32_t)WRAP(ForwardCallGR(call->native,
|
|
631
|
+
uint32_t eax = (uint32_t)WRAP(ForwardCallGR(call->native, base, &call->saved_sp));
|
|
631
632
|
napi_value value = eax ? WrapPointer(call->env, inst->type, (void *)eax) : call->env.Null();
|
|
632
633
|
DISPOSE((void *)eax);
|
|
633
634
|
return value;
|
|
634
635
|
}
|
|
635
636
|
OP(RunCallbackR) {
|
|
636
|
-
uint32_t eax = (uint32_t)WRAP(ForwardCallGR(call->native,
|
|
637
|
+
uint32_t eax = (uint32_t)WRAP(ForwardCallGR(call->native, base, &call->saved_sp));
|
|
637
638
|
return eax ? WrapPointer(call->env, inst->type, (void *)eax) : call->env.Null();
|
|
638
639
|
}
|
|
639
640
|
OP(RunRecordR) { K_UNREACHABLE(); return call->env.Null(); }
|
|
640
641
|
OP(RunUnionR) { K_UNREACHABLE(); return call->env.Null(); }
|
|
641
642
|
OP(RunArrayR) { K_UNREACHABLE(); return call->env.Null(); }
|
|
642
643
|
OP(RunFloat32R) {
|
|
643
|
-
float f = WRAP(ForwardCallFR(call->native,
|
|
644
|
+
float f = WRAP(ForwardCallFR(call->native, base, &call->saved_sp));
|
|
644
645
|
return Napi::Number::New(call->env, (double)f);
|
|
645
646
|
}
|
|
646
647
|
OP(RunFloat64R) {
|
|
647
|
-
double d = WRAP(ForwardCallDR(call->native,
|
|
648
|
+
double d = WRAP(ForwardCallDR(call->native, base, &call->saved_sp));
|
|
648
649
|
return Napi::Number::New(call->env, d);
|
|
649
650
|
}
|
|
650
651
|
OP(RunPrototypeR) { K_UNREACHABLE(); return call->env.Null(); }
|
|
651
652
|
OP(RunAggregateGR) {
|
|
652
|
-
auto ret = WRAP(ForwardCallGR(call->native,
|
|
653
|
-
return DecodeObject(call->
|
|
653
|
+
auto ret = WRAP(ForwardCallGR(call->native, base, &call->saved_sp));
|
|
654
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
654
655
|
}
|
|
655
656
|
OP(RunAggregateFR) {
|
|
656
|
-
auto ret = WRAP(ForwardCallFR(call->native,
|
|
657
|
-
return DecodeObject(call->
|
|
657
|
+
auto ret = WRAP(ForwardCallFR(call->native, base, &call->saved_sp));
|
|
658
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
658
659
|
}
|
|
659
660
|
OP(RunAggregateDR) {
|
|
660
|
-
auto ret = WRAP(ForwardCallDR(call->native,
|
|
661
|
-
return DecodeObject(call->
|
|
661
|
+
auto ret = WRAP(ForwardCallDR(call->native, base, &call->saved_sp));
|
|
662
|
+
return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
|
|
662
663
|
}
|
|
663
|
-
OP(
|
|
664
|
+
OP(RunAggregateMemR) {
|
|
664
665
|
#if defined(_WIN32)
|
|
665
|
-
*(uint8_t **)(base +
|
|
666
|
+
*(uint8_t **)(base + 16) = call->AllocHeap(inst->a);
|
|
666
667
|
#else
|
|
667
668
|
*(uint8_t **)base = call->AllocHeap(inst->a);
|
|
668
669
|
#endif
|
|
669
|
-
uint32_t eax = (uint32_t)WRAP(ForwardCallGR(call->native,
|
|
670
|
-
return DecodeObject(call->
|
|
670
|
+
uint32_t eax = (uint32_t)WRAP(ForwardCallGR(call->native, base, &call->saved_sp));
|
|
671
|
+
return DecodeObject(call->instance, (const uint8_t *)eax, inst->type);
|
|
671
672
|
}
|
|
672
673
|
|
|
673
674
|
#undef DISPOSE
|
|
@@ -678,7 +679,7 @@ napi_value RunLoop(CallData *call, napi_value *args, uint32_t *base, const AbiIn
|
|
|
678
679
|
|
|
679
680
|
#define CALL(Suffix) \
|
|
680
681
|
do { \
|
|
681
|
-
auto ret = WRAP(ForwardCall ## Suffix(call->native,
|
|
682
|
+
auto ret = WRAP(ForwardCall ## Suffix(call->native, base, &call->saved_sp)); \
|
|
682
683
|
memcpy(base, &ret, K_SIZE(ret)); \
|
|
683
684
|
} while (false)
|
|
684
685
|
#define DISPOSE() \
|
|
@@ -711,6 +712,7 @@ napi_value RunLoop(CallData *call, napi_value *args, uint32_t *base, const AbiIn
|
|
|
711
712
|
|
|
712
713
|
OP(Yield) {
|
|
713
714
|
call->async_ip = inst + 1;
|
|
715
|
+
call->async_base = base;
|
|
714
716
|
return nullptr;
|
|
715
717
|
}
|
|
716
718
|
|
|
@@ -727,7 +729,7 @@ napi_value RunLoop(CallData *call, napi_value *args, uint32_t *base, const AbiIn
|
|
|
727
729
|
OP(CallDR) { CALL(DR); return nullptr; }
|
|
728
730
|
OP(CallStackR) {
|
|
729
731
|
#if defined(_WIN32)
|
|
730
|
-
*(uint8_t **)(base +
|
|
732
|
+
*(uint8_t **)(base + 16) = call->AllocHeap(inst->a);
|
|
731
733
|
#else
|
|
732
734
|
*(uint8_t **)base = call->AllocHeap(inst->a);
|
|
733
735
|
#endif
|
|
@@ -794,10 +796,10 @@ napi_value RunLoop(CallData *call, napi_value *args, uint32_t *base, const AbiIn
|
|
|
794
796
|
return Napi::Number::New(call->env, d);
|
|
795
797
|
}
|
|
796
798
|
OP(ReturnPrototype) { K_UNREACHABLE(); return call->env.Null(); }
|
|
797
|
-
OP(ReturnAggregateReg) { return DecodeObject(call->
|
|
798
|
-
OP(
|
|
799
|
+
OP(ReturnAggregateReg) { return DecodeObject(call->instance, (const uint8_t *)base, inst->type); }
|
|
800
|
+
OP(ReturnAggregateMem) {
|
|
799
801
|
uint32_t eax = *(uint32_t *)base;
|
|
800
|
-
return DecodeObject(call->
|
|
802
|
+
return DecodeObject(call->instance, (const uint8_t *)eax, inst->type);
|
|
801
803
|
}
|
|
802
804
|
|
|
803
805
|
#undef DISPOSE
|
|
@@ -821,7 +823,7 @@ napi_value CallData::Run(const FunctionInfo *func, napi_value *args)
|
|
|
821
823
|
return env.Null();
|
|
822
824
|
|
|
823
825
|
const AbiInstruction *first = func->sync.ptr;
|
|
824
|
-
return RunLoop(this, args,
|
|
826
|
+
return RunLoop(this, args, base, first);
|
|
825
827
|
}
|
|
826
828
|
|
|
827
829
|
bool CallData::PrepareAsync(const FunctionInfo *func, napi_value *args)
|
|
@@ -832,19 +834,19 @@ bool CallData::PrepareAsync(const FunctionInfo *func, napi_value *args)
|
|
|
832
834
|
async_base = base;
|
|
833
835
|
|
|
834
836
|
const AbiInstruction *first = func->async.ptr;
|
|
835
|
-
return !RunLoop(this, args,
|
|
837
|
+
return !RunLoop(this, args, base, first); // Yield returns nullptr
|
|
836
838
|
}
|
|
837
839
|
|
|
838
840
|
void CallData::ExecuteAsync()
|
|
839
841
|
{
|
|
840
842
|
const AbiInstruction *next = async_ip++;
|
|
841
|
-
RunLoop(this, nullptr,
|
|
843
|
+
RunLoop(this, nullptr, async_base, next);
|
|
842
844
|
}
|
|
843
845
|
|
|
844
846
|
napi_value CallData::EndAsync()
|
|
845
847
|
{
|
|
846
848
|
const AbiInstruction *next = async_ip++;
|
|
847
|
-
return RunLoop(this, nullptr,
|
|
849
|
+
return RunLoop(this, nullptr, async_base, next);
|
|
848
850
|
}
|
|
849
851
|
|
|
850
852
|
void CallData::Relay(Size idx, uint8_t *sp)
|
|
@@ -1000,7 +1002,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
1000
1002
|
case PrimitiveKind::Record:
|
|
1001
1003
|
case PrimitiveKind::Union: {
|
|
1002
1004
|
uint8_t *ptr = (uint8_t *)args_ptr;
|
|
1003
|
-
arguments[i] = DecodeObject(
|
|
1005
|
+
arguments[i] = DecodeObject(instance, ptr, param.type);
|
|
1004
1006
|
|
|
1005
1007
|
args_ptr = (uint32_t *)AlignUp(ptr + param.type->size, 4);
|
|
1006
1008
|
} break;
|