koffi 3.0.2 → 3.1.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.
Files changed (48) hide show
  1. package/CHANGELOG.md +32 -7
  2. package/cnoke.cjs +2 -2
  3. package/doc/benchmarks.md +2 -2
  4. package/doc/callbacks.md +8 -27
  5. package/doc/{input.md → composites.md} +161 -147
  6. package/doc/contribute.md +2 -1
  7. package/doc/index.md +0 -14
  8. package/doc/{functions.md → load.md} +54 -113
  9. package/doc/migration.md +4 -7
  10. package/doc/misc.md +0 -103
  11. package/doc/output.md +5 -11
  12. package/doc/pointers.md +76 -17
  13. package/doc/primitives.md +151 -0
  14. package/doc/start.md +3 -13
  15. package/doc/types.md +88 -0
  16. package/doc/unions.md +0 -186
  17. package/doc/values.md +134 -0
  18. package/index.d.ts +23 -4
  19. package/lib/native/base/base.cc +142 -90
  20. package/lib/native/base/base.hh +69 -165
  21. package/package.json +16 -15
  22. package/src/koffi/CMakeLists.txt +19 -17
  23. package/src/koffi/index.cjs +8 -3
  24. package/src/koffi/index.js +1 -1
  25. package/src/koffi/indirect.cjs +8 -3
  26. package/src/koffi/indirect.js +1 -1
  27. package/src/koffi/src/abi/arm64.cc +47 -62
  28. package/src/koffi/src/abi/riscv64.cc +38 -57
  29. package/src/koffi/src/abi/x64sysv.cc +38 -57
  30. package/src/koffi/src/abi/x64win.cc +47 -65
  31. package/src/koffi/src/abi/x86.cc +46 -59
  32. package/src/koffi/src/call.cc +239 -133
  33. package/src/koffi/src/call.hh +5 -10
  34. package/src/koffi/src/ffi.cc +211 -90
  35. package/src/koffi/src/ffi.hh +36 -16
  36. package/src/koffi/src/parser.cc +3 -3
  37. package/src/koffi/src/parser.hh +2 -2
  38. package/src/koffi/src/static.cjs +8 -0
  39. package/src/koffi/src/static.js +11 -0
  40. package/src/koffi/src/type.cc +43 -33
  41. package/src/koffi/src/type.hh +1 -1
  42. package/src/koffi/src/util.cc +73 -173
  43. package/src/koffi/src/util.hh +84 -43
  44. package/src/koffi/src/uv.cc +1 -1
  45. package/vendor/node-addon-api/README.md +1 -1
  46. package/vendor/node-addon-api/napi-inl.h +213 -35
  47. package/vendor/node-addon-api/napi.h +118 -7
  48. package/doc/variables.md +0 -102
@@ -684,13 +684,8 @@ namespace {
684
684
  OP(PushAggregateReg) {
685
685
  napi_value arg = args[inst->a];
686
686
 
687
- if (!IsObject(call->env, arg)) [[unlikely]] {
688
- ThrowError<Napi::TypeError>(call->env, "Unexpected %1 value, expected object", GetValueType(call->instance, args[inst->a]));
689
- return call->env.Null();
690
- }
691
-
692
687
  uint64_t buf[2];
693
- if (!call->PushObject(arg, inst->type, (uint8_t *)buf))
688
+ if (!call->PushObject(arg, inst->type, (uint8_t *)buf)) [[unlikely]]
694
689
  return call->env.Null();
695
690
 
696
691
  // The second part might be useless (if object fits in one register), in
@@ -705,12 +700,7 @@ namespace {
705
700
  OP(PushAggregateStack) {
706
701
  napi_value arg = args[inst->a];
707
702
 
708
- if (!IsObject(call->env, arg)) [[unlikely]] {
709
- ThrowError<Napi::TypeError>(call->env, "Unexpected %1 value, expected object", GetValueType(call->instance, arg));
710
- return call->env.Null();
711
- }
712
-
713
- if (!call->PushObject(arg, inst->type, base + inst->b1))
703
+ if (!call->PushObject(arg, inst->type, base + inst->b1)) [[unlikely]]
714
704
  return call->env.Null();
715
705
 
716
706
  NEXT();
@@ -734,7 +724,7 @@ namespace {
734
724
  #define DISPOSE(Ptr) \
735
725
  do { \
736
726
  if (inst->type->dispose) { \
737
- inst->type->dispose(call->env, inst->type, (Ptr)); \
727
+ inst->type->dispose(call->instance, inst->type, (Ptr)); \
738
728
  } \
739
729
  } while (false)
740
730
 
@@ -762,42 +752,42 @@ namespace {
762
752
  OP(RunUInt64S) { INTEGER_SWAP(GG, uint64_t); }
763
753
  OP(RunString) {
764
754
  uint64_t rax = WRAP(ForwardCallGG(call->native, base, &call->saved_sp).rax);
765
- napi_value value = rax ? Napi::String::New(call->env, (const char *)rax) : call->env.Null();
755
+ napi_value value = NewString(call->env, (const char *)rax);
766
756
  DISPOSE((void *)rax);
767
757
  return value;
768
758
  }
769
759
  OP(RunString16) {
770
760
  uint64_t rax = WRAP(ForwardCallGG(call->native, base, &call->saved_sp).rax);
771
- napi_value value = rax ? Napi::String::New(call->env, (const char16_t *)rax) : call->env.Null();
761
+ napi_value value = NewString(call->env, (const char16_t *)rax);
772
762
  DISPOSE((void *)rax);
773
763
  return value;
774
764
  }
775
765
  OP(RunString32) {
776
766
  uint64_t rax = WRAP(ForwardCallGG(call->native, base, &call->saved_sp).rax);
777
- napi_value value = rax ? MakeStringFromUTF32(call->env, (const char32_t *)rax) : call->env.Null();
767
+ napi_value value = NewString(call->env, (const char32_t *)rax);
778
768
  DISPOSE((void *)rax);
779
769
  return value;
780
770
  }
781
771
  OP(RunPointer) {
782
772
  uint64_t rax = WRAP(ForwardCallGG(call->native, base, &call->saved_sp).rax);
783
- napi_value value = rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
773
+ napi_value value = WrapPointer(call->env, inst->type, (void *)rax);
784
774
  DISPOSE((void *)rax);
785
775
  return value;
786
776
  }
787
777
  OP(RunCallback) {
788
778
  uint64_t rax = WRAP(ForwardCallGG(call->native, base, &call->saved_sp).rax);
789
- return rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
779
+ return WrapPointer(call->env, inst->type, (void *)rax);
790
780
  }
791
781
  OP(RunRecord) { K_UNREACHABLE(); return call->env.Null(); }
792
782
  OP(RunUnion) { K_UNREACHABLE(); return call->env.Null(); }
793
783
  OP(RunArray) { K_UNREACHABLE(); return call->env.Null(); }
794
784
  OP(RunFloat32) {
795
785
  float f = WRAP(ForwardCallF(call->native, base, &call->saved_sp));
796
- return Napi::Number::New(call->env, (double)f);
786
+ return NewFloat(call->env, f);
797
787
  }
798
788
  OP(RunFloat64) {
799
789
  double d = WRAP(ForwardCallDD(call->native, base, &call->saved_sp).xmm0);
800
- return Napi::Number::New(call->env, d);
790
+ return NewFloat(call->env, d);
801
791
  }
802
792
  OP(RunPrototype) { K_UNREACHABLE(); return call->env.Null(); }
803
793
  OP(RunAggregateGG) {
@@ -846,42 +836,42 @@ namespace {
846
836
  OP(RunUInt64SX) { INTEGER_SWAP(GGX, uint64_t); }
847
837
  OP(RunStringX) {
848
838
  uint64_t rax = WRAP(ForwardCallGGX(call->native, base, &call->saved_sp).rax);
849
- napi_value value = rax ? Napi::String::New(call->env, (const char *)rax) : call->env.Null();
839
+ napi_value value = NewString(call->env, (const char *)rax);
850
840
  DISPOSE((void *)rax);
851
841
  return value;
852
842
  }
853
843
  OP(RunString16X) {
854
844
  uint64_t rax = WRAP(ForwardCallGGX(call->native, base, &call->saved_sp).rax);
855
- napi_value value = rax ? Napi::String::New(call->env, (const char16_t *)rax) : call->env.Null();
845
+ napi_value value = NewString(call->env, (const char16_t *)rax);
856
846
  DISPOSE((void *)rax);
857
847
  return value;
858
848
  }
859
849
  OP(RunString32X) {
860
850
  uint64_t rax = WRAP(ForwardCallGGX(call->native, base, &call->saved_sp).rax);
861
- napi_value value = rax ? MakeStringFromUTF32(call->env, (const char32_t *)rax) : call->env.Null();
851
+ napi_value value = NewString(call->env, (const char32_t *)rax);
862
852
  DISPOSE((void *)rax);
863
853
  return value;
864
854
  }
865
855
  OP(RunPointerX) {
866
856
  uint64_t rax = WRAP(ForwardCallGGX(call->native, base, &call->saved_sp).rax);
867
- napi_value value = rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
857
+ napi_value value = WrapPointer(call->env, inst->type, (void *)rax);
868
858
  DISPOSE((void *)rax);
869
859
  return value;
870
860
  }
871
861
  OP(RunCallbackX) {
872
862
  uint64_t rax = WRAP(ForwardCallGGX(call->native, base, &call->saved_sp).rax);
873
- return rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
863
+ return WrapPointer(call->env, inst->type, (void *)rax);
874
864
  }
875
865
  OP(RunRecordX) { K_UNREACHABLE(); return call->env.Null(); }
876
866
  OP(RunUnionX) { K_UNREACHABLE(); return call->env.Null(); }
877
867
  OP(RunArrayX) { K_UNREACHABLE(); return call->env.Null(); }
878
868
  OP(RunFloat32X) {
879
869
  float f = WRAP(ForwardCallFX(call->native, base, &call->saved_sp));
880
- return Napi::Number::New(call->env, (double)f);
870
+ return NewFloat(call->env, f);
881
871
  }
882
872
  OP(RunFloat64X) {
883
873
  double d = WRAP(ForwardCallDDX(call->native, base, &call->saved_sp).xmm0);
884
- return Napi::Number::New(call->env, d);
874
+ return NewFloat(call->env, d);
885
875
  }
886
876
  OP(RunPrototypeX) { K_UNREACHABLE(); return call->env.Null(); }
887
877
  OP(RunAggregateGGX) {
@@ -920,7 +910,7 @@ namespace {
920
910
  do { \
921
911
  if (inst->type->dispose) { \
922
912
  void *ptr = *(void **)base; \
923
- inst->type->dispose(call->env, inst->type, ptr); \
913
+ inst->type->dispose(call->instance, inst->type, ptr); \
924
914
  } \
925
915
  } while (false)
926
916
  #define INTEGER(CType) \
@@ -983,42 +973,42 @@ namespace {
983
973
  OP(ReturnUInt64S) { INTEGER_SWAP(uint64_t); }
984
974
  OP(ReturnString) {
985
975
  uint64_t rax = *(uint64_t *)base;
986
- napi_value value = rax ? Napi::String::New(call->env, (const char *)rax) : call->env.Null();
976
+ napi_value value = NewString(call->env, (const char *)rax);
987
977
  DISPOSE();
988
978
  return value;
989
979
  }
990
980
  OP(ReturnString16) {
991
981
  uint64_t rax = *(uint64_t *)base;
992
- napi_value value = rax ? Napi::String::New(call->env, (const char16_t *)rax) : call->env.Null();
982
+ napi_value value = NewString(call->env, (const char16_t *)rax);
993
983
  DISPOSE();
994
984
  return value;
995
985
  }
996
986
  OP(ReturnString32) {
997
987
  uint64_t rax = *(uint64_t *)base;
998
- napi_value value = rax ? MakeStringFromUTF32(call->env, (const char32_t *)rax) : call->env.Null();
988
+ napi_value value = NewString(call->env, (const char32_t *)rax);
999
989
  DISPOSE();
1000
990
  return value;
1001
991
  }
1002
992
  OP(ReturnPointer) {
1003
993
  uint64_t rax = *(uint64_t *)base;
1004
- napi_value value = rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
994
+ napi_value value = WrapPointer(call->env, inst->type, (void *)rax);
1005
995
  DISPOSE();
1006
996
  return value;
1007
997
  }
1008
998
  OP(ReturnCallback) {
1009
999
  uint64_t rax = *(uint64_t *)base;
1010
- return rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
1000
+ return WrapPointer(call->env, inst->type, (void *)rax);
1011
1001
  }
1012
1002
  OP(ReturnRecord) { K_UNREACHABLE(); return call->env.Null(); }
1013
1003
  OP(ReturnUnion) { K_UNREACHABLE(); return call->env.Null(); }
1014
1004
  OP(ReturnArray) { K_UNREACHABLE(); return call->env.Null(); }
1015
1005
  OP(ReturnFloat32) {
1016
1006
  float f = *(float *)base;
1017
- return Napi::Number::New(call->env, (double)f);
1007
+ return NewFloat(call->env, f);
1018
1008
  }
1019
1009
  OP(ReturnFloat64) {
1020
1010
  double d = *(double *)base;
1021
- return Napi::Number::New(call->env, d);
1011
+ return NewFloat(call->env, d);
1022
1012
  }
1023
1013
  OP(ReturnPrototype) { K_UNREACHABLE(); return call->env.Null(); }
1024
1014
  OP(ReturnAggregateReg) { return DecodeObject(call->instance, base, inst->type); }
@@ -1188,30 +1178,30 @@ void CallData::Relay(Size idx, uint8_t *sp)
1188
1178
  const uint8_t *src = in_ptr + param.abi.offsets[0];
1189
1179
  const char *str = *(const char **)src;
1190
1180
 
1191
- arguments[i] = str ? Napi::String::New(env, str) : env.Null();
1181
+ arguments[i] = NewString(env, str);
1192
1182
 
1193
1183
  if (param.type->dispose) {
1194
- param.type->dispose(env, param.type, str);
1184
+ param.type->dispose(instance, param.type, str);
1195
1185
  }
1196
1186
  } break;
1197
1187
  case PrimitiveKind::String16: {
1198
1188
  const uint8_t *src = in_ptr + param.abi.offsets[0];
1199
1189
  const char16_t *str16 = *(const char16_t **)src;
1200
1190
 
1201
- arguments[i] = str16 ? Napi::String::New(env, str16) : env.Null();
1191
+ arguments[i] = NewString(env, str16);
1202
1192
 
1203
1193
  if (param.type->dispose) {
1204
- param.type->dispose(env, param.type, str16);
1194
+ param.type->dispose(instance, param.type, str16);
1205
1195
  }
1206
1196
  } break;
1207
1197
  case PrimitiveKind::String32: {
1208
1198
  const uint8_t *src = in_ptr + param.abi.offsets[0];
1209
1199
  const char32_t *str32 = *(const char32_t **)src;
1210
1200
 
1211
- arguments[i] = str32 ? MakeStringFromUTF32(env, str32) : env.Null();
1201
+ arguments[i] = NewString(env, str32);
1212
1202
 
1213
1203
  if (param.type->dispose) {
1214
- param.type->dispose(env, param.type, str32);
1204
+ param.type->dispose(instance, param.type, str32);
1215
1205
  }
1216
1206
  } break;
1217
1207
 
@@ -1219,10 +1209,10 @@ void CallData::Relay(Size idx, uint8_t *sp)
1219
1209
  const uint8_t *src = in_ptr + param.abi.offsets[0];
1220
1210
  void *ptr2 = *(void **)src;
1221
1211
 
1222
- arguments[i] = ptr2 ? WrapPointer(env, param.type->ref.type, ptr2) : env.Null();
1212
+ arguments[i] = WrapPointer(env, param.type->ref.type, ptr2);
1223
1213
 
1224
1214
  if (param.type->dispose) {
1225
- param.type->dispose(env, param.type, ptr2);
1215
+ param.type->dispose(instance, param.type, ptr2);
1226
1216
  }
1227
1217
  } break;
1228
1218
 
@@ -1244,24 +1234,20 @@ void CallData::Relay(Size idx, uint8_t *sp)
1244
1234
  const uint8_t *src = in_ptr + param.abi.offsets[0];
1245
1235
  float f = *(float *)src;
1246
1236
 
1247
- arguments[i] = Napi::Number::New(env, (double)f);
1237
+ arguments[i] = NewFloat(env, f);
1248
1238
  } break;
1249
1239
  case PrimitiveKind::Float64: {
1250
1240
  const uint8_t *src = in_ptr + param.abi.offsets[0];
1251
1241
  double d = *(double *)src;
1252
1242
 
1253
- arguments[i] = Napi::Number::New(env, d);
1243
+ arguments[i] = NewFloat(env, d);
1254
1244
  } break;
1255
1245
 
1256
1246
  case PrimitiveKind::Callback: {
1257
1247
  const uint8_t *src = in_ptr + param.abi.offsets[0];
1258
1248
  void *ptr2 = *(void **)src;
1259
1249
 
1260
- arguments[i] = ptr2 ? WrapPointer(env, param.type->ref.type, ptr2) : env.Null();
1261
-
1262
- if (param.type->dispose) {
1263
- param.type->dispose(env, param.type, ptr2);
1264
- }
1250
+ arguments[i] = WrapPointer(env, param.type->ref.type, ptr2);
1265
1251
  } break;
1266
1252
 
1267
1253
  case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
@@ -1361,16 +1347,11 @@ void CallData::Relay(Size idx, uint8_t *sp)
1361
1347
 
1362
1348
  case PrimitiveKind::Record:
1363
1349
  case PrimitiveKind::Union: {
1364
- if (!IsObject(env, value)) [[unlikely]] {
1365
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
1366
- return;
1367
- }
1368
-
1369
1350
  if (proto->ret.abi.method == AbiMethod::Stack) {
1370
1351
  uint64_t *gpr_ptr = (uint64_t *)in_ptr;
1371
1352
  uint8_t *dest = (uint8_t *)gpr_ptr[0];
1372
1353
 
1373
- if (!PushObject(value, type, dest))
1354
+ if (!PushObject(value, type, dest)) [[unlikely]]
1374
1355
  return;
1375
1356
 
1376
1357
  out_reg->rax = (uint64_t)dest;
@@ -1378,7 +1359,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
1378
1359
  K_ASSERT(type->size <= 16);
1379
1360
 
1380
1361
  uint8_t buf[16] = {};
1381
- if (!PushObject(value, type, buf))
1362
+ if (!PushObject(value, type, buf)) [[unlikely]]
1382
1363
  return;
1383
1364
 
1384
1365
  switch (proto->ret.abi.method) {
@@ -74,16 +74,16 @@ inline void *Code2Op(AbiOpcode code)
74
74
 
75
75
  bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
76
76
  {
77
- func->ret.regular = IsRegularSize(func->ret.type->size, 8);
77
+ func->ret.abi.regular = IsRegularSize(func->ret.type->size, 8);
78
78
 
79
79
  for (Size i = 0; i < func->parameters.len; i++) {
80
- int16_t arg = (int16_t)(!func->ret.regular + i);
80
+ int16_t arg = (int16_t)(!func->ret.abi.regular + i);
81
81
  ParameterInfo &param = func->parameters[i];
82
82
 
83
- param.regular = IsRegularSize(param.type->size, 8);
83
+ param.abi.regular = IsRegularSize(param.type->size, 8);
84
84
 
85
85
  if (param.type->primitive == PrimitiveKind::Record || param.type->primitive == PrimitiveKind::Union) {
86
- AbiOpcode code = param.regular ? AbiOpcode::PushAggregateReg : AbiOpcode::PushAggregateMem;
86
+ AbiOpcode code = param.abi.regular ? AbiOpcode::PushAggregateReg : AbiOpcode::PushAggregateMem;
87
87
 
88
88
  func->sync.Append({ .op = Code2Op(code), .a = param.offset, .b1 = (int16_t)(arg * 8), .b2 = (int16_t)param.directions, .type = param.type });
89
89
  func->async.Append({ .op = Code2Op(code), .a = param.offset, .b1 = (int16_t)(arg * 8), .b2 = (int16_t)param.directions, .type = param.type });
@@ -100,7 +100,7 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
100
100
 
101
101
  // At least 4 parameter registers
102
102
  {
103
- Size count = std::max((Size)4, func->parameters.len + !func->ret.regular);
103
+ Size count = std::max((Size)4, func->parameters.len + !func->ret.abi.regular);
104
104
  func->stk_size = AlignLen(8 * count, 16);
105
105
  }
106
106
 
@@ -168,7 +168,7 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
168
168
 
169
169
  case PrimitiveKind::Record:
170
170
  case PrimitiveKind::Union: {
171
- if (func->ret.regular) {
171
+ if (func->ret.abi.regular) {
172
172
  AbiOpcode run = func->forward_fp ? AbiOpcode::RunAggregateRegX : AbiOpcode::RunAggregateReg;
173
173
  AbiOpcode call = func->forward_fp ? AbiOpcode::CallGX : AbiOpcode::CallG;
174
174
 
@@ -370,14 +370,9 @@ namespace {
370
370
  OP(PushAggregateReg) {
371
371
  napi_value arg = args[inst->a];
372
372
 
373
- if (!IsObject(call->env, arg)) [[unlikely]] {
374
- ThrowError<Napi::TypeError>(call->env, "Unexpected %1 value, expected object", GetValueType(call->instance, arg));
375
- return call->env.Null();
376
- }
377
-
378
373
  uint8_t *ptr = (uint8_t *)(base + inst->b1);
379
374
 
380
- if (!call->PushObject(arg, inst->type, ptr))
375
+ if (!call->PushObject(arg, inst->type, ptr)) [[unlikely]]
381
376
  return call->env.Null();
382
377
 
383
378
  NEXT();
@@ -385,15 +380,10 @@ namespace {
385
380
  OP(PushAggregateMem) {
386
381
  napi_value arg = args[inst->a];
387
382
 
388
- if (!IsObject(call->env, arg)) [[unlikely]] {
389
- ThrowError<Napi::TypeError>(call->env, "Unexpected %1 value, expected object", GetValueType(call->instance, arg));
390
- return call->env.Null();
391
- }
392
-
393
383
  uint8_t *ptr = call->AllocHeap(inst->type->size);
394
384
  *(uint8_t **)(base + inst->b1) = ptr;
395
385
 
396
- if (!call->PushObject(arg, inst->type, ptr))
386
+ if (!call->PushObject(arg, inst->type, ptr)) [[unlikely]]
397
387
  return call->env.Null();
398
388
 
399
389
  NEXT();
@@ -415,7 +405,7 @@ namespace {
415
405
  #define DISPOSE(Ptr) \
416
406
  do { \
417
407
  if (inst->type->dispose) { \
418
- inst->type->dispose(call->env, inst->type, (Ptr)); \
408
+ inst->type->dispose(call->instance, inst->type, (Ptr)); \
419
409
  } \
420
410
  } while (false)
421
411
 
@@ -443,42 +433,42 @@ namespace {
443
433
  OP(RunUInt64S) { INTEGER_SWAP(G, uint64_t); }
444
434
  OP(RunString) {
445
435
  uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
446
- napi_value value = rax ? Napi::String::New(call->env, (const char *)rax) : call->env.Null();
436
+ napi_value value = NewString(call->env, (const char *)rax);
447
437
  DISPOSE((void *)rax);
448
438
  return value;
449
439
  }
450
440
  OP(RunString16) {
451
441
  uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
452
- napi_value value = rax ? Napi::String::New(call->env, (const char16_t *)rax) : call->env.Null();
442
+ napi_value value = NewString(call->env, (const char16_t *)rax);
453
443
  DISPOSE((void *)rax);
454
444
  return value;
455
445
  }
456
446
  OP(RunString32) {
457
447
  uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
458
- napi_value value = rax ? MakeStringFromUTF32(call->env, (const char32_t *)rax) : call->env.Null();
448
+ napi_value value = NewString(call->env, (const char32_t *)rax);
459
449
  DISPOSE((void *)rax);
460
450
  return value;
461
451
  }
462
452
  OP(RunPointer) {
463
453
  uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
464
- napi_value value = rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
454
+ napi_value value = WrapPointer(call->env, inst->type, (void *)rax);
465
455
  DISPOSE((void *)rax);
466
456
  return value;
467
457
  }
468
458
  OP(RunCallback) {
469
459
  uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
470
- return rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
460
+ return WrapPointer(call->env, inst->type, (void *)rax);
471
461
  }
472
462
  OP(RunRecord) { K_UNREACHABLE(); return call->env.Null(); }
473
463
  OP(RunUnion) { K_UNREACHABLE(); return call->env.Null(); }
474
464
  OP(RunArray) { K_UNREACHABLE(); return call->env.Null(); }
475
465
  OP(RunFloat32) {
476
466
  float f = WRAP(ForwardCallF(call->native, base, &call->saved_sp));
477
- return Napi::Number::New(call->env, (double)f);
467
+ return NewFloat(call->env, f);
478
468
  }
479
469
  OP(RunFloat64) {
480
470
  double d = WRAP(ForwardCallD(call->native, base, &call->saved_sp));
481
- return Napi::Number::New(call->env, d);
471
+ return NewFloat(call->env, d);
482
472
  }
483
473
  OP(RunPrototype) { K_UNREACHABLE(); return call->env.Null(); }
484
474
  OP(RunAggregateReg) {
@@ -514,42 +504,42 @@ namespace {
514
504
  OP(RunUInt64SX) { INTEGER_SWAP(GX, uint64_t); }
515
505
  OP(RunStringX) {
516
506
  uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
517
- napi_value value = rax ? Napi::String::New(call->env, (const char *)rax) : call->env.Null();
507
+ napi_value value = NewString(call->env, (const char *)rax);
518
508
  DISPOSE((void *)rax);
519
509
  return value;
520
510
  }
521
511
  OP(RunString16X) {
522
512
  uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
523
- napi_value value = rax ? Napi::String::New(call->env, (const char16_t *)rax) : call->env.Null();
513
+ napi_value value = NewString(call->env, (const char16_t *)rax);
524
514
  DISPOSE((void *)rax);
525
515
  return value;
526
516
  }
527
517
  OP(RunString32X) {
528
518
  uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
529
- napi_value value = rax ? MakeStringFromUTF32(call->env, (const char32_t *)rax) : call->env.Null();
519
+ napi_value value = NewString(call->env, (const char32_t *)rax);
530
520
  DISPOSE((void *)rax);
531
521
  return value;
532
522
  }
533
523
  OP(RunPointerX) {
534
524
  uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
535
- napi_value value = rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
525
+ napi_value value = WrapPointer(call->env, inst->type, (void *)rax);
536
526
  DISPOSE((void *)rax);
537
527
  return value;
538
528
  }
539
529
  OP(RunCallbackX) {
540
530
  uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
541
- return rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
531
+ return WrapPointer(call->env, inst->type, (void *)rax);
542
532
  }
543
533
  OP(RunRecordX) { K_UNREACHABLE(); return call->env.Null(); }
544
534
  OP(RunUnionX) { K_UNREACHABLE(); return call->env.Null(); }
545
535
  OP(RunArrayX) { K_UNREACHABLE(); return call->env.Null(); }
546
536
  OP(RunFloat32X) {
547
537
  float f = WRAP(ForwardCallFX(call->native, base, &call->saved_sp));
548
- return Napi::Number::New(call->env, (double)f);
538
+ return NewFloat(call->env, f);
549
539
  }
550
540
  OP(RunFloat64X) {
551
541
  double d = WRAP(ForwardCallDX(call->native, base, &call->saved_sp));
552
- return Napi::Number::New(call->env, d);
542
+ return NewFloat(call->env, d);
553
543
  }
554
544
  OP(RunPrototypeX) { K_UNREACHABLE(); return call->env.Null(); }
555
545
  OP(RunAggregateRegX) {
@@ -575,7 +565,7 @@ namespace {
575
565
  do { \
576
566
  if (inst->type->dispose) { \
577
567
  void *ptr = *(void **)base; \
578
- inst->type->dispose(call->env, inst->type, ptr); \
568
+ inst->type->dispose(call->instance, inst->type, ptr); \
579
569
  } \
580
570
  } while (false)
581
571
  #define INTEGER(CType) \
@@ -632,42 +622,42 @@ namespace {
632
622
  OP(ReturnUInt64S) { INTEGER_SWAP(uint64_t); }
633
623
  OP(ReturnString) {
634
624
  uint64_t rax = *(uint64_t *)base;
635
- napi_value value = rax ? Napi::String::New(call->env, (const char *)rax) : call->env.Null();
625
+ napi_value value = NewString(call->env, (const char *)rax);
636
626
  DISPOSE();
637
627
  return value;
638
628
  }
639
629
  OP(ReturnString16) {
640
630
  uint64_t rax = *(uint64_t *)base;
641
- napi_value value = rax ? Napi::String::New(call->env, (const char16_t *)rax) : call->env.Null();
631
+ napi_value value = NewString(call->env, (const char16_t *)rax);
642
632
  DISPOSE();
643
633
  return value;
644
634
  }
645
635
  OP(ReturnString32) {
646
636
  uint64_t rax = *(uint64_t *)base;
647
- napi_value value = rax ? MakeStringFromUTF32(call->env, (const char32_t *)rax) : call->env.Null();
637
+ napi_value value = NewString(call->env, (const char32_t *)rax);
648
638
  DISPOSE();
649
639
  return value;
650
640
  }
651
641
  OP(ReturnPointer) {
652
642
  uint64_t rax = *(uint64_t *)base;
653
- napi_value value = rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
643
+ napi_value value = WrapPointer(call->env, inst->type, (void *)rax);
654
644
  DISPOSE();
655
645
  return value;
656
646
  }
657
647
  OP(ReturnCallback) {
658
648
  uint64_t rax = *(uint64_t *)base;
659
- return rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
649
+ return WrapPointer(call->env, inst->type, (void *)rax);
660
650
  }
661
651
  OP(ReturnRecord) { K_UNREACHABLE(); return call->env.Null(); }
662
652
  OP(ReturnUnion) { K_UNREACHABLE(); return call->env.Null(); }
663
653
  OP(ReturnArray) { K_UNREACHABLE(); return call->env.Null(); }
664
654
  OP(ReturnFloat32) {
665
655
  float f = *(float *)base;
666
- return Napi::Number::New(call->env, (double)f);
656
+ return NewFloat(call->env, f);
667
657
  }
668
658
  OP(ReturnFloat64) {
669
659
  double d = *(double *)base;
670
- return Napi::Number::New(call->env, d);
660
+ return NewFloat(call->env, d);
671
661
  }
672
662
  OP(ReturnPrototype) { K_UNREACHABLE(); return call->env.Null(); }
673
663
  OP(ReturnAggregateReg) { return DecodeObject(call->instance, base, inst->type); }
@@ -778,7 +768,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
778
768
  uint64_t *xmm_ptr = gpr_ptr + 4;
779
769
  uint64_t *stk_ptr = (uint64_t *)caller_sp;
780
770
 
781
- uint8_t *return_ptr = !proto->ret.regular ? (uint8_t *)gpr_ptr[0] : nullptr;
771
+ uint8_t *return_ptr = !proto->ret.abi.regular ? (uint8_t *)gpr_ptr[0] : nullptr;
782
772
 
783
773
  K_DEFER_N(err_guard) {
784
774
  trampoline->state = -1;
@@ -889,56 +879,52 @@ void CallData::Relay(Size idx, uint8_t *sp)
889
879
  const char *str = *(const char **)(j < 4 ? gpr_ptr + j : stk_ptr);
890
880
  stk_ptr += (j >= 4);
891
881
 
892
- arguments[i] = str ? Napi::String::New(env, str) : env.Null();
882
+ arguments[i] = NewString(env, str);
893
883
 
894
884
  if (param.type->dispose) {
895
- param.type->dispose(env, param.type, str);
885
+ param.type->dispose(instance, param.type, str);
896
886
  }
897
887
  } break;
898
888
  case PrimitiveKind::String16: {
899
889
  const char16_t *str16 = *(const char16_t **)(j < 4 ? gpr_ptr + j : stk_ptr);
900
890
  stk_ptr += (j >= 4);
901
891
 
902
- arguments[i] = str16 ? Napi::String::New(env, str16) : env.Null();
892
+ arguments[i] = NewString(env, str16);
903
893
 
904
894
  if (param.type->dispose) {
905
- param.type->dispose(env, param.type, str16);
895
+ param.type->dispose(instance, param.type, str16);
906
896
  }
907
897
  } break;
908
898
  case PrimitiveKind::String32: {
909
899
  const char32_t *str32 = *(const char32_t **)(j < 4 ? gpr_ptr + j : stk_ptr);
910
900
  stk_ptr += (j >= 4);
911
901
 
912
- arguments[i] = str32 ? MakeStringFromUTF32(env, str32) : env.Null();
902
+ arguments[i] = NewString(env, str32);
913
903
 
914
904
  if (param.type->dispose) {
915
- param.type->dispose(env, param.type, str32);
905
+ param.type->dispose(instance, param.type, str32);
916
906
  }
917
907
  } break;
918
908
  case PrimitiveKind::Pointer: {
919
909
  void *ptr2 = *(void **)(j < 4 ? gpr_ptr + j : stk_ptr);
920
910
  stk_ptr += (j >= 4);
921
911
 
922
- arguments[i] = ptr2 ? WrapPointer(env, param.type->ref.type, ptr2) : env.Null();
912
+ arguments[i] = WrapPointer(env, param.type->ref.type, ptr2);
923
913
 
924
914
  if (param.type->dispose) {
925
- param.type->dispose(env, param.type, ptr2);
915
+ param.type->dispose(instance, param.type, ptr2);
926
916
  }
927
917
  } break;
928
918
  case PrimitiveKind::Callback: {
929
919
  void *ptr2 = *(void **)(j < 4 ? gpr_ptr + j : stk_ptr);
930
920
  stk_ptr += (j >= 4);
931
921
 
932
- arguments[i] = ptr2 ? WrapPointer(env, param.type->ref.type, ptr2) : env.Null();
933
-
934
- if (param.type->dispose) {
935
- param.type->dispose(env, param.type, ptr2);
936
- }
922
+ arguments[i] = WrapPointer(env, param.type->ref.type, ptr2);
937
923
  } break;
938
924
  case PrimitiveKind::Record:
939
925
  case PrimitiveKind::Union: {
940
926
  uint8_t *ptr;
941
- if (param.regular) {
927
+ if (param.abi.regular) {
942
928
  ptr = (uint8_t *)(j < 4 ? gpr_ptr + j : stk_ptr);
943
929
  } else {
944
930
  ptr = *(uint8_t **)(j < 4 ? gpr_ptr + j : stk_ptr);
@@ -952,13 +938,13 @@ void CallData::Relay(Size idx, uint8_t *sp)
952
938
  float f = *(float *)(j < 4 ? xmm_ptr + j : stk_ptr);
953
939
  stk_ptr += (j >= 4);
954
940
 
955
- arguments[i] = Napi::Number::New(env, (double)f);
941
+ arguments[i] = NewFloat(env, f);
956
942
  } break;
957
943
  case PrimitiveKind::Float64: {
958
944
  double d = *(double *)(j < 4 ? xmm_ptr + j : stk_ptr);
959
945
  stk_ptr += (j >= 4);
960
946
 
961
- arguments[i] = Napi::Number::New(env, d);
947
+ arguments[i] = NewFloat(env, d);
962
948
  } break;
963
949
 
964
950
  case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
@@ -1049,17 +1035,13 @@ void CallData::Relay(Size idx, uint8_t *sp)
1049
1035
  } break;
1050
1036
  case PrimitiveKind::Record:
1051
1037
  case PrimitiveKind::Union: {
1052
- if (!IsObject(env, value)) [[unlikely]] {
1053
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
1054
- return;
1055
- }
1056
-
1057
1038
  if (return_ptr) {
1058
- if (!PushObject(value, type, return_ptr))
1039
+ if (!PushObject(value, type, return_ptr)) [[unlikely]]
1059
1040
  return;
1060
1041
  out_reg->rax = (uint64_t)return_ptr;
1061
1042
  } else {
1062
- PushObject(value, type, (uint8_t *)&out_reg->rax);
1043
+ if (!PushObject(value, type, (uint8_t *)&out_reg->rax)) [[unlikely]]
1044
+ return;
1063
1045
  }
1064
1046
  } break;
1065
1047
  case PrimitiveKind::Array: { K_UNREACHABLE(); } break;