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.
@@ -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
 
11
12
  #include <napi.h>
@@ -59,14 +60,14 @@ enum class AbiOpcode {
59
60
  RunAggregateDD,
60
61
  RunAggregateGD,
61
62
  RunAggregateDG,
62
- RunAggregateStack,
63
+ RunAggregateMem,
63
64
  #define PRIMITIVE(Name) Run ## Name ## X,
64
65
  #include "../primitives.inc"
65
66
  RunAggregateGGX,
66
67
  RunAggregateDDX,
67
68
  RunAggregateGDX,
68
69
  RunAggregateDGX,
69
- RunAggregateStackX,
70
+ RunAggregateMemX,
70
71
  Yield,
71
72
  CallGG,
72
73
  CallF,
@@ -83,7 +84,7 @@ enum class AbiOpcode {
83
84
  #define PRIMITIVE(Name) Return ## Name,
84
85
  #include "../primitives.inc"
85
86
  ReturnAggregateReg,
86
- ReturnAggregateStack
87
+ ReturnAggregateMem
87
88
  };
88
89
 
89
90
  enum class AbiMethod {
@@ -452,12 +453,12 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
452
453
  case PrimitiveKind::Union: {
453
454
  switch (func->ret.abi.method) {
454
455
  case AbiMethod::Stack: {
455
- AbiOpcode run = func->forward_fp ? AbiOpcode::RunAggregateStackX : AbiOpcode::RunAggregateStack;
456
+ AbiOpcode run = func->forward_fp ? AbiOpcode::RunAggregateMemX : AbiOpcode::RunAggregateMem;
456
457
  AbiOpcode call = func->forward_fp ? AbiOpcode::CallStackX : AbiOpcode::CallStack;
457
458
 
458
459
  func->sync.Append({ .op = Code2Op(run), .a = (int32_t)func->ret.type->size, .type = func->ret.type });
459
460
  func->async.Append({ .op = Code2Op(call), .a = (int32_t)func->ret.type->size });
460
- func->async.Append({ .op = Code2Op(AbiOpcode::ReturnAggregateStack), .type = func->ret.type });
461
+ func->async.Append({ .op = Code2Op(AbiOpcode::ReturnAggregateMem), .type = func->ret.type });
461
462
 
462
463
  // Allocate stack space for return value
463
464
  func->stk_size += AlignLen(func->ret.type->size, 16);
@@ -801,25 +802,25 @@ namespace {
801
802
  OP(RunPrototype) { K_UNREACHABLE(); return call->env.Null(); }
802
803
  OP(RunAggregateGG) {
803
804
  auto ret = WRAP(ForwardCallGG(call->native, base, &call->saved_sp));
804
- return DecodeObject(call->env, (const uint8_t *)&ret, inst->type);
805
+ return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
805
806
  }
806
807
  OP(RunAggregateDD) {
807
808
  auto ret = WRAP(ForwardCallDD(call->native, base, &call->saved_sp));
808
- return DecodeObject(call->env, (const uint8_t *)&ret, inst->type);
809
+ return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
809
810
  }
810
811
  OP(RunAggregateGD) {
811
812
  auto ret = WRAP(ForwardCallGD(call->native, base, &call->saved_sp));
812
- return DecodeObject(call->env, (const uint8_t *)&ret, inst->type);
813
+ return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
813
814
  }
814
815
  OP(RunAggregateDG) {
815
816
  auto ret = WRAP(ForwardCallDG(call->native, base, &call->saved_sp));
816
- return DecodeObject(call->env, (const uint8_t *)&ret, inst->type);
817
+ return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
817
818
  }
818
- OP(RunAggregateStack) {
819
+ OP(RunAggregateMem) {
819
820
  uint8_t *ptr = call->AllocHeap(inst->a);
820
821
  *(uint8_t **)base = ptr;
821
822
  WRAP(ForwardCallGG(call->native, base, &call->saved_sp).rax);
822
- return DecodeObject(call->env, ptr, inst->type);
823
+ return DecodeObject(call->instance, ptr, inst->type);
823
824
  }
824
825
  OP(RunVoidX) {
825
826
  WRAP(ForwardCallGGX(call->native, base, &call->saved_sp));
@@ -885,25 +886,25 @@ namespace {
885
886
  OP(RunPrototypeX) { K_UNREACHABLE(); return call->env.Null(); }
886
887
  OP(RunAggregateGGX) {
887
888
  auto ret = WRAP(ForwardCallGGX(call->native, base, &call->saved_sp));
888
- return DecodeObject(call->env, (const uint8_t *)&ret, inst->type);
889
+ return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
889
890
  }
890
891
  OP(RunAggregateDDX) {
891
892
  auto ret = WRAP(ForwardCallDDX(call->native, base, &call->saved_sp));
892
- return DecodeObject(call->env, (const uint8_t *)&ret, inst->type);
893
+ return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
893
894
  }
894
895
  OP(RunAggregateGDX) {
895
896
  auto ret = WRAP(ForwardCallGDX(call->native, base, &call->saved_sp));
896
- return DecodeObject(call->env, (const uint8_t *)&ret, inst->type);
897
+ return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
897
898
  }
898
899
  OP(RunAggregateDGX) {
899
900
  auto ret = WRAP(ForwardCallDGX(call->native, base, &call->saved_sp));
900
- return DecodeObject(call->env, (const uint8_t *)&ret, inst->type);
901
+ return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
901
902
  }
902
- OP(RunAggregateStackX) {
903
+ OP(RunAggregateMemX) {
903
904
  uint8_t *ptr = call->AllocHeap(inst->a);
904
905
  *(uint8_t **)base = ptr;
905
906
  WRAP(ForwardCallGGX(call->native, base, &call->saved_sp).rax);
906
- return DecodeObject(call->env, ptr, inst->type);
907
+ return DecodeObject(call->instance, ptr, inst->type);
907
908
  }
908
909
 
909
910
  #undef DISPOSE
@@ -1020,10 +1021,10 @@ namespace {
1020
1021
  return Napi::Number::New(call->env, d);
1021
1022
  }
1022
1023
  OP(ReturnPrototype) { K_UNREACHABLE(); return call->env.Null(); }
1023
- OP(ReturnAggregateReg) { return DecodeObject(call->env, base, inst->type); }
1024
- OP(ReturnAggregateStack) {
1024
+ OP(ReturnAggregateReg) { return DecodeObject(call->instance, base, inst->type); }
1025
+ OP(ReturnAggregateMem) {
1025
1026
  uint64_t rax = *(uint64_t *)base;
1026
- return DecodeObject(call->env, (const uint8_t *)rax, inst->type);
1027
+ return DecodeObject(call->instance, (const uint8_t *)rax, inst->type);
1027
1028
  }
1028
1029
 
1029
1030
  #undef INTEGER_SWAP
@@ -1043,14 +1044,14 @@ namespace {
1043
1044
  HandleRunAggregateDD,
1044
1045
  HandleRunAggregateGD,
1045
1046
  HandleRunAggregateDG,
1046
- HandleRunAggregateStack,
1047
+ HandleRunAggregateMem,
1047
1048
  #define PRIMITIVE(Name) HandleRun ## Name ## X,
1048
1049
  #include "../primitives.inc"
1049
1050
  HandleRunAggregateGGX,
1050
1051
  HandleRunAggregateDDX,
1051
1052
  HandleRunAggregateGDX,
1052
1053
  HandleRunAggregateDGX,
1053
- HandleRunAggregateStackX,
1054
+ HandleRunAggregateMemX,
1054
1055
  HandleYield,
1055
1056
  HandleCallGG,
1056
1057
  HandleCallF,
@@ -1067,7 +1068,7 @@ namespace {
1067
1068
  #define PRIMITIVE(Name) HandleReturn ## Name,
1068
1069
  #include "../primitives.inc"
1069
1070
  HandleReturnAggregateReg,
1070
- HandleReturnAggregateStack
1071
+ HandleReturnAggregateMem
1071
1072
  };
1072
1073
 
1073
1074
  FORCE_INLINE napi_value RunLoop(CallData *call, napi_value *args, uint8_t *base, const AbiInstruction *inst)
@@ -1232,9 +1233,9 @@ void CallData::Relay(Size idx, uint8_t *sp)
1232
1233
  buf[0] = *(uint64_t *)(in_ptr + param.abi.offsets[0]);
1233
1234
  buf[1] = *(uint64_t *)(in_ptr + param.abi.offsets[1]);
1234
1235
 
1235
- arguments[i] = DecodeObject(env, (const uint8_t *)buf, param.type);
1236
+ arguments[i] = DecodeObject(instance, (const uint8_t *)buf, param.type);
1236
1237
  } else {
1237
- arguments[i] = DecodeObject(env, in_ptr + param.abi.offsets[0], param.type);
1238
+ arguments[i] = DecodeObject(instance, in_ptr + param.abi.offsets[0], param.type);
1238
1239
  }
1239
1240
  } break;
1240
1241
  case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
@@ -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
  #include "../win32.hh"
11
12
 
@@ -29,15 +30,15 @@ enum class AbiOpcode {
29
30
  #define PRIMITIVE(Name) Push ## Name,
30
31
  #include "../primitives.inc"
31
32
  PushAggregateReg,
32
- PushAggregateStack,
33
+ PushAggregateMem,
33
34
  #define PRIMITIVE(Name) Run ## Name,
34
35
  #include "../primitives.inc"
35
36
  RunAggregateReg,
36
- RunAggregateStack,
37
+ RunAggregateMem,
37
38
  #define PRIMITIVE(Name) Run ## Name ## X,
38
39
  #include "../primitives.inc"
39
40
  RunAggregateRegX,
40
- RunAggregateStackX,
41
+ RunAggregateMemX,
41
42
  Yield,
42
43
  CallG,
43
44
  CallF,
@@ -50,12 +51,12 @@ enum class AbiOpcode {
50
51
  #define PRIMITIVE(Name) Return ## Name,
51
52
  #include "../primitives.inc"
52
53
  ReturnAggregateReg,
53
- ReturnAggregateStack
54
+ ReturnAggregateMem
54
55
  };
55
56
 
56
57
  namespace {
57
58
  #if defined(MUST_TAIL)
58
- PRESERVE_NONE typedef napi_value ForwardFunc(CallData *call, napi_value *args, uint64_t *base, const AbiInstruction *inst);
59
+ PRESERVE_NONE typedef napi_value ForwardFunc(CallData *call, napi_value *args, uint8_t *base, const AbiInstruction *inst);
59
60
 
60
61
  extern ForwardFunc *const ForwardDispatch[256];
61
62
 
@@ -82,16 +83,16 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
82
83
  param.regular = IsRegularSize(param.type->size, 8);
83
84
 
84
85
  if (param.type->primitive == PrimitiveKind::Record || param.type->primitive == PrimitiveKind::Union) {
85
- AbiOpcode code = param.regular ? AbiOpcode::PushAggregateReg : AbiOpcode::PushAggregateStack;
86
+ AbiOpcode code = param.regular ? AbiOpcode::PushAggregateReg : AbiOpcode::PushAggregateMem;
86
87
 
87
- func->sync.Append({ .op = Code2Op(code), .a = param.offset, .b1 = arg, .b2 = (int16_t)param.directions, .type = param.type });
88
- func->async.Append({ .op = Code2Op(code), .a = param.offset, .b1 = arg, .b2 = (int16_t)param.directions, .type = param.type });
88
+ func->sync.Append({ .op = Code2Op(code), .a = param.offset, .b1 = (int16_t)(arg * 8), .b2 = (int16_t)param.directions, .type = param.type });
89
+ func->async.Append({ .op = Code2Op(code), .a = param.offset, .b1 = (int16_t)(arg * 8), .b2 = (int16_t)param.directions, .type = param.type });
89
90
  } else {
90
91
  int delta = (int)AbiOpcode::PushVoid - (int)PrimitiveKind::Void;
91
92
  AbiOpcode code = (AbiOpcode)((int)param.type->primitive + delta);
92
93
 
93
- func->sync.Append({ .op = Code2Op(code), .a = param.offset, .b1 = arg, .b2 = (int16_t)param.directions, .type = param.type });
94
- func->async.Append({ .op = Code2Op(code), .a = param.offset, .b1 = arg, .b2 = (int16_t)param.directions, .type = param.type });
94
+ func->sync.Append({ .op = Code2Op(code), .a = param.offset, .b1 = (int16_t)(arg * 8), .b2 = (int16_t)param.directions, .type = param.type });
95
+ func->async.Append({ .op = Code2Op(code), .a = param.offset, .b1 = (int16_t)(arg * 8), .b2 = (int16_t)param.directions, .type = param.type });
95
96
  }
96
97
 
97
98
  func->forward_fp |= IsFloat(param.type);
@@ -175,12 +176,12 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
175
176
  func->async.Append({ .op = Code2Op(call) });
176
177
  func->async.Append({ .op = Code2Op(AbiOpcode::ReturnAggregateReg), .type = func->ret.type });
177
178
  } else {
178
- AbiOpcode run = func->forward_fp ? AbiOpcode::RunAggregateStackX : AbiOpcode::RunAggregateStack;
179
+ AbiOpcode run = func->forward_fp ? AbiOpcode::RunAggregateMemX : AbiOpcode::RunAggregateMem;
179
180
  AbiOpcode call = func->forward_fp ? AbiOpcode::CallStackX : AbiOpcode::CallStack;
180
181
 
181
182
  func->sync.Append({ .op = Code2Op(run), .a = (int32_t)func->ret.type->size, .type = func->ret.type });
182
183
  func->async.Append({ .op = Code2Op(call), .a = (int32_t)func->ret.type->size });
183
- func->async.Append({ .op = Code2Op(AbiOpcode::ReturnAggregateStack), .type = func->ret.type });
184
+ func->async.Append({ .op = Code2Op(AbiOpcode::ReturnAggregateMem), .type = func->ret.type });
184
185
  }
185
186
  } break;
186
187
  case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
@@ -216,7 +217,7 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
216
217
  namespace {
217
218
  #if defined(MUST_TAIL)
218
219
  #define OP(Code) \
219
- PRESERVE_NONE napi_value Handle ## Code(CallData *call, napi_value *args, uint64_t *base, const AbiInstruction *inst)
220
+ PRESERVE_NONE napi_value Handle ## Code(CallData *call, napi_value *args, uint8_t *base, const AbiInstruction *inst)
220
221
  #define NEXT() \
221
222
  do { \
222
223
  const AbiInstruction *next = inst + 1; \
@@ -228,7 +229,7 @@ namespace {
228
229
  #define NEXT() \
229
230
  break
230
231
 
231
- napi_value RunLoop(CallData *call, napi_value *args, uint64_t *base, const AbiInstruction *inst)
232
+ napi_value RunLoop(CallData *call, napi_value *args, uint8_t *base, const AbiInstruction *inst)
232
233
  {
233
234
  for (;; ++inst) {
234
235
  switch ((intptr_t)inst->op) {
@@ -255,7 +256,7 @@ namespace {
255
256
  return call->env.Null(); \
256
257
  } \
257
258
  \
258
- *(base + inst->b1) = (uint64_t)v; \
259
+ *(uint64_t *)(base + inst->b1) = (uint64_t)v; \
259
260
  } while (false)
260
261
  #define INTEGER_SWAP(CType) \
261
262
  do { \
@@ -265,7 +266,7 @@ namespace {
265
266
  return call->env.Null(); \
266
267
  } \
267
268
  \
268
- *(base + inst->b1) = (uint64_t)ReverseBytes(v); \
269
+ *(uint64_t *)(base + inst->b1) = (uint64_t)ReverseBytes(v); \
269
270
  } while (false)
270
271
 
271
272
  OP(PushVoid) { K_UNREACHABLE(); return call->env.Null(); }
@@ -381,7 +382,7 @@ namespace {
381
382
 
382
383
  NEXT();
383
384
  }
384
- OP(PushAggregateStack) {
385
+ OP(PushAggregateMem) {
385
386
  napi_value arg = args[inst->a];
386
387
 
387
388
  if (!IsObject(call->env, arg)) [[unlikely]] {
@@ -403,12 +404,12 @@ namespace {
403
404
 
404
405
  #define INTEGER(Suffix, CType) \
405
406
  do { \
406
- uint64_t rax = WRAP(ForwardCall ## Suffix(call->native, (uint8_t *)base, &call->saved_sp)); \
407
+ uint64_t rax = WRAP(ForwardCall ## Suffix(call->native, base, &call->saved_sp)); \
407
408
  return NewInt(call->env, (CType)rax); \
408
409
  } while (false)
409
410
  #define INTEGER_SWAP(Suffix, CType) \
410
411
  do { \
411
- uint64_t rax = WRAP(ForwardCall ## Suffix(call->native, (uint8_t *)base, &call->saved_sp)); \
412
+ uint64_t rax = WRAP(ForwardCall ## Suffix(call->native, base, &call->saved_sp)); \
412
413
  return NewInt(call->env, ReverseBytes((CType)rax)); \
413
414
  } while (false)
414
415
  #define DISPOSE(Ptr) \
@@ -419,11 +420,11 @@ namespace {
419
420
  } while (false)
420
421
 
421
422
  OP(RunVoid) {
422
- WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
423
+ WRAP(ForwardCallG(call->native, base, &call->saved_sp));
423
424
  return nullptr;
424
425
  }
425
426
  OP(RunBool) {
426
- uint64_t rax = WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
427
+ uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
427
428
  return Napi::Boolean::New(call->env, rax & 0x1);
428
429
  }
429
430
  OP(RunInt8) { INTEGER(G, int8_t); }
@@ -441,60 +442,60 @@ namespace {
441
442
  OP(RunUInt64) { INTEGER(G, uint64_t); }
442
443
  OP(RunUInt64S) { INTEGER_SWAP(G, uint64_t); }
443
444
  OP(RunString) {
444
- uint64_t rax = WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
445
+ uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
445
446
  napi_value value = rax ? Napi::String::New(call->env, (const char *)rax) : call->env.Null();
446
447
  DISPOSE((void *)rax);
447
448
  return value;
448
449
  }
449
450
  OP(RunString16) {
450
- uint64_t rax = WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
451
+ uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
451
452
  napi_value value = rax ? Napi::String::New(call->env, (const char16_t *)rax) : call->env.Null();
452
453
  DISPOSE((void *)rax);
453
454
  return value;
454
455
  }
455
456
  OP(RunString32) {
456
- uint64_t rax = WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
457
+ uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
457
458
  napi_value value = rax ? MakeStringFromUTF32(call->env, (const char32_t *)rax) : call->env.Null();
458
459
  DISPOSE((void *)rax);
459
460
  return value;
460
461
  }
461
462
  OP(RunPointer) {
462
- uint64_t rax = WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
463
+ uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
463
464
  napi_value value = rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
464
465
  DISPOSE((void *)rax);
465
466
  return value;
466
467
  }
467
468
  OP(RunCallback) {
468
- uint64_t rax = WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
469
+ uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
469
470
  return rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
470
471
  }
471
472
  OP(RunRecord) { K_UNREACHABLE(); return call->env.Null(); }
472
473
  OP(RunUnion) { K_UNREACHABLE(); return call->env.Null(); }
473
474
  OP(RunArray) { K_UNREACHABLE(); return call->env.Null(); }
474
475
  OP(RunFloat32) {
475
- float f = WRAP(ForwardCallF(call->native, (uint8_t *)base, &call->saved_sp));
476
+ float f = WRAP(ForwardCallF(call->native, base, &call->saved_sp));
476
477
  return Napi::Number::New(call->env, (double)f);
477
478
  }
478
479
  OP(RunFloat64) {
479
- double d = WRAP(ForwardCallD(call->native, (uint8_t *)base, &call->saved_sp));
480
+ double d = WRAP(ForwardCallD(call->native, base, &call->saved_sp));
480
481
  return Napi::Number::New(call->env, d);
481
482
  }
482
483
  OP(RunPrototype) { K_UNREACHABLE(); return call->env.Null(); }
483
484
  OP(RunAggregateReg) {
484
- auto ret = WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
485
- return DecodeObject(call->env, (const uint8_t *)&ret, inst->type);
485
+ auto ret = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
486
+ return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
486
487
  }
487
- OP(RunAggregateStack) {
488
+ OP(RunAggregateMem) {
488
489
  *(uint8_t **)base = call->AllocHeap(inst->a);
489
- uint64_t rax = WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
490
- return DecodeObject(call->env, (const uint8_t *)rax, inst->type);
490
+ uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
491
+ return DecodeObject(call->instance, (const uint8_t *)rax, inst->type);
491
492
  }
492
493
  OP(RunVoidX) {
493
- WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
494
+ WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
494
495
  return nullptr;
495
496
  }
496
497
  OP(RunBoolX) {
497
- uint64_t rax = WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
498
+ uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
498
499
  return Napi::Boolean::New(call->env, rax & 0x1);
499
500
  }
500
501
  OP(RunInt8X) { INTEGER(GX, int8_t); }
@@ -512,53 +513,53 @@ namespace {
512
513
  OP(RunUInt64X) { INTEGER(GX, uint64_t); }
513
514
  OP(RunUInt64SX) { INTEGER_SWAP(GX, uint64_t); }
514
515
  OP(RunStringX) {
515
- uint64_t rax = WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
516
+ uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
516
517
  napi_value value = rax ? Napi::String::New(call->env, (const char *)rax) : call->env.Null();
517
518
  DISPOSE((void *)rax);
518
519
  return value;
519
520
  }
520
521
  OP(RunString16X) {
521
- uint64_t rax = WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
522
+ uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
522
523
  napi_value value = rax ? Napi::String::New(call->env, (const char16_t *)rax) : call->env.Null();
523
524
  DISPOSE((void *)rax);
524
525
  return value;
525
526
  }
526
527
  OP(RunString32X) {
527
- uint64_t rax = WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
528
+ uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
528
529
  napi_value value = rax ? MakeStringFromUTF32(call->env, (const char32_t *)rax) : call->env.Null();
529
530
  DISPOSE((void *)rax);
530
531
  return value;
531
532
  }
532
533
  OP(RunPointerX) {
533
- uint64_t rax = WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
534
+ uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
534
535
  napi_value value = rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
535
536
  DISPOSE((void *)rax);
536
537
  return value;
537
538
  }
538
539
  OP(RunCallbackX) {
539
- uint64_t rax = WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
540
+ uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
540
541
  return rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
541
542
  }
542
543
  OP(RunRecordX) { K_UNREACHABLE(); return call->env.Null(); }
543
544
  OP(RunUnionX) { K_UNREACHABLE(); return call->env.Null(); }
544
545
  OP(RunArrayX) { K_UNREACHABLE(); return call->env.Null(); }
545
546
  OP(RunFloat32X) {
546
- float f = WRAP(ForwardCallFX(call->native, (uint8_t *)base, &call->saved_sp));
547
+ float f = WRAP(ForwardCallFX(call->native, base, &call->saved_sp));
547
548
  return Napi::Number::New(call->env, (double)f);
548
549
  }
549
550
  OP(RunFloat64X) {
550
- double d = WRAP(ForwardCallDX(call->native, (uint8_t *)base, &call->saved_sp));
551
+ double d = WRAP(ForwardCallDX(call->native, base, &call->saved_sp));
551
552
  return Napi::Number::New(call->env, d);
552
553
  }
553
554
  OP(RunPrototypeX) { K_UNREACHABLE(); return call->env.Null(); }
554
555
  OP(RunAggregateRegX) {
555
- auto ret = WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
556
- return DecodeObject(call->env, (const uint8_t *)&ret, inst->type);
556
+ auto ret = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
557
+ return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
557
558
  }
558
- OP(RunAggregateStackX) {
559
+ OP(RunAggregateMemX) {
559
560
  *(uint8_t **)base = call->AllocHeap(inst->a);
560
- uint64_t rax = WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
561
- return DecodeObject(call->env, (const uint8_t *)rax, inst->type);
561
+ uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
562
+ return DecodeObject(call->instance, (const uint8_t *)rax, inst->type);
562
563
  }
563
564
 
564
565
  #undef DISPOSE
@@ -567,7 +568,7 @@ namespace {
567
568
 
568
569
  #define CALL(Suffix) \
569
570
  do { \
570
- auto ret = WRAP(ForwardCall ## Suffix(call->native, (uint8_t *)base, &call->saved_sp)); \
571
+ auto ret = WRAP(ForwardCall ## Suffix(call->native, base, &call->saved_sp)); \
571
572
  memcpy(base, &ret, K_SIZE(ret)); \
572
573
  } while (false)
573
574
  #define DISPOSE() \
@@ -598,7 +599,7 @@ namespace {
598
599
  OP(CallD) { CALL(D); return nullptr; }
599
600
  OP(CallStack) {
600
601
  *(uint8_t **)base = call->AllocHeap(inst->a);
601
- *(uint64_t *)base = WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
602
+ *(uint64_t *)base = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
602
603
  return nullptr;
603
604
  }
604
605
  OP(CallGX) { CALL(GX); return nullptr; }
@@ -606,7 +607,7 @@ namespace {
606
607
  OP(CallDX) { CALL(DX); return nullptr; }
607
608
  OP(CallStackX) {
608
609
  *(uint8_t **)base = call->AllocHeap(inst->a);
609
- *(uint64_t *)base = WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
610
+ *(uint64_t *)base = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
610
611
  return nullptr;
611
612
  }
612
613
 
@@ -669,10 +670,10 @@ namespace {
669
670
  return Napi::Number::New(call->env, d);
670
671
  }
671
672
  OP(ReturnPrototype) { K_UNREACHABLE(); return call->env.Null(); }
672
- OP(ReturnAggregateReg) { return DecodeObject(call->env, (const uint8_t *)base, inst->type); }
673
- OP(ReturnAggregateStack) {
673
+ OP(ReturnAggregateReg) { return DecodeObject(call->instance, base, inst->type); }
674
+ OP(ReturnAggregateMem) {
674
675
  uint64_t rax = *(uint64_t *)base;
675
- return DecodeObject(call->env, (const uint8_t *)rax, inst->type);
676
+ return DecodeObject(call->instance, (const uint8_t *)rax, inst->type);
676
677
  }
677
678
 
678
679
  #undef INTEGER_SWAP
@@ -685,15 +686,15 @@ namespace {
685
686
  #define PRIMITIVE(Name) HandlePush ## Name,
686
687
  #include "../primitives.inc"
687
688
  HandlePushAggregateReg,
688
- HandlePushAggregateStack,
689
+ HandlePushAggregateMem,
689
690
  #define PRIMITIVE(Name) HandleRun ## Name,
690
691
  #include "../primitives.inc"
691
692
  HandleRunAggregateReg,
692
- HandleRunAggregateStack,
693
+ HandleRunAggregateMem,
693
694
  #define PRIMITIVE(Name) HandleRun ## Name ## X,
694
695
  #include "../primitives.inc"
695
696
  HandleRunAggregateRegX,
696
- HandleRunAggregateStackX,
697
+ HandleRunAggregateMemX,
697
698
  HandleYield,
698
699
  HandleCallG,
699
700
  HandleCallF,
@@ -706,10 +707,10 @@ namespace {
706
707
  #define PRIMITIVE(Name) HandleReturn ## Name,
707
708
  #include "../primitives.inc"
708
709
  HandleReturnAggregateReg,
709
- HandleReturnAggregateStack
710
+ HandleReturnAggregateMem
710
711
  };
711
712
 
712
- FORCE_INLINE napi_value RunLoop(CallData *call, napi_value *args, uint64_t *base, const AbiInstruction *inst)
713
+ FORCE_INLINE napi_value RunLoop(CallData *call, napi_value *args, uint8_t *base, const AbiInstruction *inst)
713
714
  {
714
715
  return ((ForwardFunc *)inst->op)(call, args, base, inst);
715
716
  }
@@ -738,7 +739,7 @@ napi_value CallData::Run(const FunctionInfo *func, napi_value *args)
738
739
  return env.Null();
739
740
 
740
741
  const AbiInstruction *first = func->sync.ptr;
741
- return RunLoop(this, args, (uint64_t *)base, first);
742
+ return RunLoop(this, args, base, first);
742
743
  }
743
744
 
744
745
  bool CallData::PrepareAsync(const FunctionInfo *func, napi_value *args)
@@ -749,19 +750,19 @@ bool CallData::PrepareAsync(const FunctionInfo *func, napi_value *args)
749
750
  async_base = base;
750
751
 
751
752
  const AbiInstruction *first = func->async.ptr;
752
- return !RunLoop(this, args, (uint64_t *)base, first); // Yield returns nullptr
753
+ return !RunLoop(this, args, base, first); // Yield returns nullptr
753
754
  }
754
755
 
755
756
  void CallData::ExecuteAsync()
756
757
  {
757
758
  const AbiInstruction *next = async_ip++;
758
- RunLoop(this, nullptr, (uint64_t *)async_base, next);
759
+ RunLoop(this, nullptr, async_base, next);
759
760
  }
760
761
 
761
762
  napi_value CallData::EndAsync()
762
763
  {
763
764
  const AbiInstruction *next = async_ip++;
764
- return RunLoop(this, nullptr, (uint64_t *)async_base, next);
765
+ return RunLoop(this, nullptr, async_base, next);
765
766
  }
766
767
 
767
768
  void CallData::Relay(Size idx, uint8_t *sp)
@@ -944,7 +945,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
944
945
  }
945
946
  stk_ptr += (j >= 4);
946
947
 
947
- arguments[i] = DecodeObject(env, ptr, param.type);
948
+ arguments[i] = DecodeObject(instance, ptr, param.type);
948
949
  } break;
949
950
  case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
950
951
  case PrimitiveKind::Float32: {