koffi 1.0.1 → 1.0.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.
Files changed (50) hide show
  1. package/CMakeLists.txt +12 -11
  2. package/README.md +23 -20
  3. package/build/qemu/1.0.4/koffi_darwin_x64.tar.gz +0 -0
  4. package/build/qemu/1.0.4/koffi_freebsd_arm64.tar.gz +0 -0
  5. package/build/qemu/1.0.4/koffi_freebsd_ia32.tar.gz +0 -0
  6. package/build/qemu/1.0.4/koffi_freebsd_x64.tar.gz +0 -0
  7. package/build/qemu/1.0.4/koffi_linux_arm.tar.gz +0 -0
  8. package/build/qemu/1.0.4/koffi_linux_arm64.tar.gz +0 -0
  9. package/build/qemu/1.0.4/koffi_linux_ia32.tar.gz +0 -0
  10. package/build/qemu/1.0.4/koffi_linux_x64.tar.gz +0 -0
  11. package/build/qemu/1.0.4/koffi_win32_ia32.tar.gz +0 -0
  12. package/build/qemu/1.0.4/koffi_win32_x64.tar.gz +0 -0
  13. package/package.json +8 -4
  14. package/qemu/qemu.js +794 -0
  15. package/qemu/registry/machines.json +415 -0
  16. package/qemu/registry/sha256sum.txt +45 -0
  17. package/src/{call_arm32.cc → abi_arm32.cc} +153 -219
  18. package/src/{call_arm32_fwd.S → abi_arm32_fwd.S} +0 -0
  19. package/src/{call_arm64.cc → abi_arm64.cc} +130 -123
  20. package/src/{call_arm64_fwd.S → abi_arm64_fwd.S} +0 -0
  21. package/src/{call_x64_sysv.cc → abi_x64_sysv.cc} +138 -135
  22. package/src/{call_x64_sysv_fwd.S → abi_x64_sysv_fwd.S} +0 -0
  23. package/src/{call_x64_win.cc → abi_x64_win.cc} +107 -99
  24. package/src/{call_x64_win_fwd.asm → abi_x64_win_fwd.asm} +0 -0
  25. package/src/{call_x86.cc → abi_x86.cc} +110 -107
  26. package/src/{call_x86_fwd.S → abi_x86_fwd.S} +0 -0
  27. package/src/{call_x86_fwd.asm → abi_x86_fwd.asm} +0 -0
  28. package/src/call.cc +353 -0
  29. package/src/call.hh +132 -4
  30. package/src/ffi.cc +16 -2
  31. package/src/ffi.hh +8 -12
  32. package/src/util.cc +7 -280
  33. package/src/util.hh +0 -107
  34. package/test/CMakeLists.txt +1 -0
  35. package/test/misc.c +355 -0
  36. package/test/misc.def +3 -0
  37. package/test/misc.js +227 -0
  38. package/test/raylib.js +165 -0
  39. package/test/sqlite.js +104 -0
  40. package/vendor/libcc/libcc.hh +1 -1
  41. package/build/qemu/1.0.1/koffi_darwin_x64.tar.gz +0 -0
  42. package/build/qemu/1.0.1/koffi_freebsd_arm64.tar.gz +0 -0
  43. package/build/qemu/1.0.1/koffi_freebsd_ia32.tar.gz +0 -0
  44. package/build/qemu/1.0.1/koffi_freebsd_x64.tar.gz +0 -0
  45. package/build/qemu/1.0.1/koffi_linux_arm.tar.gz +0 -0
  46. package/build/qemu/1.0.1/koffi_linux_arm64.tar.gz +0 -0
  47. package/build/qemu/1.0.1/koffi_linux_ia32.tar.gz +0 -0
  48. package/build/qemu/1.0.1/koffi_linux_x64.tar.gz +0 -0
  49. package/build/qemu/1.0.1/koffi_win32_ia32.tar.gz +0 -0
  50. package/build/qemu/1.0.1/koffi_win32_x64.tar.gz +0 -0
@@ -84,6 +84,7 @@ bool AnalyseFunction(InstanceData *, FunctionInfo *func)
84
84
  case PrimitiveKind::Int32:
85
85
  case PrimitiveKind::UInt32:
86
86
  case PrimitiveKind::String:
87
+ case PrimitiveKind::String16:
87
88
  case PrimitiveKind::Pointer: {
88
89
  if (gpr_avail) {
89
90
  param.gpr_count = 1;
@@ -161,77 +162,8 @@ bool AnalyseFunction(InstanceData *, FunctionInfo *func)
161
162
  return true;
162
163
  }
163
164
 
164
- static bool PushHFA(const Napi::Object &obj, const TypeInfo *type, uint8_t *dest)
165
+ bool CallData::Prepare(const Napi::CallbackInfo &info)
165
166
  {
166
- Napi::Env env = obj.Env();
167
- InstanceData *instance = env.GetInstanceData<InstanceData>();
168
-
169
- RG_ASSERT(IsObject(obj));
170
- RG_ASSERT(type->primitive == PrimitiveKind::Record);
171
- RG_ASSERT(AlignUp(dest, type->members[0].type->size) == dest);
172
-
173
- for (const RecordMember &member: type->members) {
174
- Napi::Value value = obj.Get(member.name);
175
-
176
- if (member.type->primitive == PrimitiveKind::Float32) {
177
- if (!value.IsNumber() && !value.IsBigInt()) {
178
- ThrowError<Napi::TypeError>(env, "Unexpected value %1 for member '%2', expected number", GetValueType(instance, value), member.name);
179
- return false;
180
- }
181
-
182
- *(float *)dest = CopyNumber<float>(value);
183
- } else if (member.type->primitive == PrimitiveKind::Float64) {
184
- if (!value.IsNumber() && !value.IsBigInt()) {
185
- ThrowError<Napi::TypeError>(env, "Unexpected value %1 for member '%2', expected number", GetValueType(instance, value), member.name);
186
- return false;
187
- }
188
-
189
- *(double *)dest = CopyNumber<double>(value);
190
- } else {
191
- RG_UNREACHABLE();
192
- }
193
-
194
- dest += type->members[0].type->size;
195
- }
196
-
197
- return true;
198
- }
199
-
200
- static Napi::Object PopHFA(napi_env env, const uint8_t *ptr, const TypeInfo *type)
201
- {
202
- RG_ASSERT(type->primitive == PrimitiveKind::Record);
203
-
204
- Napi::Object obj = Napi::Object::New(env);
205
-
206
- for (const RecordMember &member: type->members) {
207
- if (member.type->primitive == PrimitiveKind::Float32) {
208
- float f = *(float *)ptr;
209
- obj.Set(member.name, Napi::Number::New(env, (double)f));
210
- } else if (member.type->primitive == PrimitiveKind::Float64) {
211
- double d = *(double *)ptr;
212
- obj.Set(member.name, Napi::Number::New(env, d));
213
- } else {
214
- RG_UNREACHABLE();
215
- }
216
-
217
- ptr += member.type->size;
218
- }
219
-
220
- return obj;
221
- }
222
-
223
- Napi::Value TranslateCall(InstanceData *instance, const FunctionInfo *func, const Napi::CallbackInfo &info)
224
- {
225
- Napi::Env env = info.Env();
226
- CallData call(env, instance, func);
227
-
228
- // Sanity checks
229
- if (info.Length() < (uint32_t)func->parameters.len) {
230
- ThrowError<Napi::TypeError>(env, "Expected %1 arguments, got %2", func->parameters.len, info.Length());
231
- return env.Null();
232
- }
233
-
234
- uint8_t *return_ptr = nullptr;
235
167
  uint8_t *args_ptr = nullptr;
236
168
  uint32_t *gpr_ptr = nullptr;
237
169
  uint32_t *vec_ptr = nullptr;
@@ -240,20 +172,18 @@ Napi::Value TranslateCall(InstanceData *instance, const FunctionInfo *func, cons
240
172
  // registers just before the stack (so behind the vector ones).
241
173
  // In the armv7hf calling convention, some arguments can end up
242
174
  // partially in GPR, partially in the stack.
243
- if (RG_UNLIKELY(!call.AllocStack(func->args_size, 16, &args_ptr)))
244
- return env.Null();
245
- if (RG_UNLIKELY(!call.AllocStack(4 * 4, 8, &gpr_ptr)))
246
- return env.Null();
247
- if (RG_UNLIKELY(!call.AllocStack(8 * 8, 8, &vec_ptr)))
248
- return env.Null();
175
+ if (RG_UNLIKELY(!AllocStack(func->args_size, 16, &args_ptr)))
176
+ return false;
177
+ if (RG_UNLIKELY(!AllocStack(4 * 4, 8, &gpr_ptr)))
178
+ return false;
179
+ if (RG_UNLIKELY(!AllocStack(8 * 8, 8, &vec_ptr)))
180
+ return false;
249
181
  if (func->ret.use_memory) {
250
- if (RG_UNLIKELY(!call.AllocHeap(func->ret.type->size, 16, &return_ptr)))
251
- return env.Null();
182
+ if (RG_UNLIKELY(!AllocHeap(func->ret.type->size, 16, &return_ptr)))
183
+ return false;
252
184
  *(uint8_t **)(gpr_ptr++) = return_ptr;
253
185
  }
254
186
 
255
- LocalArray<OutObject, MaxOutParameters> out_objects;
256
-
257
187
  // Push arguments
258
188
  for (Size i = 0; i < func->parameters.len; i++) {
259
189
  const ParameterInfo &param = func->parameters[i];
@@ -267,7 +197,7 @@ Napi::Value TranslateCall(InstanceData *instance, const FunctionInfo *func, cons
267
197
  case PrimitiveKind::Bool: {
268
198
  if (RG_UNLIKELY(!value.IsBoolean())) {
269
199
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected boolean", GetValueType(instance, value), i + 1);
270
- return env.Null();
200
+ return false;
271
201
  }
272
202
 
273
203
  bool b = value.As<Napi::Boolean>();
@@ -287,7 +217,7 @@ Napi::Value TranslateCall(InstanceData *instance, const FunctionInfo *func, cons
287
217
  case PrimitiveKind::UInt32: {
288
218
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
289
219
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
290
- return env.Null();
220
+ return false;
291
221
  }
292
222
 
293
223
  int64_t v = CopyNumber<int64_t>(value);
@@ -303,7 +233,7 @@ Napi::Value TranslateCall(InstanceData *instance, const FunctionInfo *func, cons
303
233
  case PrimitiveKind::UInt64: {
304
234
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
305
235
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
306
- return env.Null();
236
+ return false;
307
237
  }
308
238
 
309
239
  int64_t v = CopyNumber<int64_t>(value);
@@ -317,54 +247,17 @@ Napi::Value TranslateCall(InstanceData *instance, const FunctionInfo *func, cons
317
247
  args_ptr += 8;
318
248
  }
319
249
  } break;
320
- case PrimitiveKind::Float32: {
321
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
322
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
323
- return env.Null();
324
- }
325
-
326
- float f = CopyNumber<float>(value);
327
-
328
- if (RG_LIKELY(param.vec_count)) {
329
- memcpy(vec_ptr++, &f, 4);
330
- } else if (param.gpr_count) {
331
- memcpy(gpr_ptr++, &f, 4);
332
- } else {
333
- memcpy(args_ptr, &f, 4);
334
- args_ptr += 4;
335
- }
336
- } break;
337
- case PrimitiveKind::Float64: {
338
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
339
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
340
- return env.Null();
341
- }
342
-
343
- double d = CopyNumber<double>(value);
344
-
345
- if (RG_LIKELY(param.vec_count)) {
346
- memcpy(vec_ptr, &d, 8);
347
- vec_ptr += 2;
348
- } else if (param.gpr_count) {
349
- memcpy(gpr_ptr, &d, 8);
350
- gpr_ptr += 2;
351
- } else {
352
- args_ptr = AlignUp(args_ptr, 8);
353
- memcpy(args_ptr, &d, 8);
354
- args_ptr += 8;
355
- }
356
- } break;
357
250
  case PrimitiveKind::String: {
358
251
  const char *str;
359
252
  if (RG_LIKELY(value.IsString())) {
360
- str = call.PushString(value);
253
+ str = PushString(value);
361
254
  if (RG_UNLIKELY(!str))
362
- return env.Null();
255
+ return false;
363
256
  } else if (IsNullOrUndefined(value)) {
364
257
  str = nullptr;
365
258
  } else {
366
259
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected string", GetValueType(instance, value), i + 1);
367
- return env.Null();
260
+ return false;
368
261
  }
369
262
 
370
263
  if (RG_LIKELY(param.gpr_count)) {
@@ -374,6 +267,26 @@ Napi::Value TranslateCall(InstanceData *instance, const FunctionInfo *func, cons
374
267
  args_ptr += 4;
375
268
  }
376
269
  } break;
270
+ case PrimitiveKind::String16: {
271
+ const char16_t *str16;
272
+ if (RG_LIKELY(value.IsString())) {
273
+ str16 = PushString16(value);
274
+ if (RG_UNLIKELY(!str16))
275
+ return false;
276
+ } else if (IsNullOrUndefined(value)) {
277
+ str16 = nullptr;
278
+ } else {
279
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected string", GetValueType(instance, value), i + 1);
280
+ return false;
281
+ }
282
+
283
+ if (RG_LIKELY(param.gpr_count)) {
284
+ *(gpr_ptr++) = (uint64_t)str16;
285
+ } else {
286
+ *(const char16_t **)args_ptr = str16;
287
+ args_ptr += 4;
288
+ }
289
+ } break;
377
290
  case PrimitiveKind::Pointer: {
378
291
  uint8_t *ptr;
379
292
 
@@ -382,12 +295,12 @@ Napi::Value TranslateCall(InstanceData *instance, const FunctionInfo *func, cons
382
295
  } else if (IsObject(value) && param.type->ref->primitive == PrimitiveKind::Record) {
383
296
  Napi::Object obj = value.As<Napi::Object>();
384
297
 
385
- if (RG_UNLIKELY(!call.AllocHeap(param.type->ref->size, 16, &ptr)))
386
- return env.Null();
298
+ if (RG_UNLIKELY(!AllocHeap(param.type->ref->size, 16, &ptr)))
299
+ return false;
387
300
 
388
301
  if (param.directions & 1) {
389
- if (!call.PushObject(obj, param.type->ref, ptr))
390
- return env.Null();
302
+ if (!PushObject(obj, param.type->ref, ptr))
303
+ return false;
391
304
  } else {
392
305
  memset(ptr, 0, param.type->size);
393
306
  }
@@ -399,7 +312,7 @@ Napi::Value TranslateCall(InstanceData *instance, const FunctionInfo *func, cons
399
312
  ptr = nullptr;
400
313
  } else {
401
314
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected %3", GetValueType(instance, value), i + 1, param.type->name);
402
- return env.Null();
315
+ return false;
403
316
  }
404
317
 
405
318
  if (RG_LIKELY(param.gpr_count)) {
@@ -409,132 +322,153 @@ Napi::Value TranslateCall(InstanceData *instance, const FunctionInfo *func, cons
409
322
  args_ptr += 4;
410
323
  }
411
324
  } break;
412
-
413
325
  case PrimitiveKind::Record: {
414
326
  if (RG_UNLIKELY(!IsObject(value))) {
415
327
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected object", GetValueType(instance, value), i + 1);
416
- return env.Null();
328
+ return false;
417
329
  }
418
330
 
419
331
  Napi::Object obj = value.As<Napi::Object>();
420
332
 
421
333
  if (param.vec_count) {
422
- if (!PushHFA(obj, param.type, (uint8_t *)vec_ptr))
423
- return env.Null();
334
+ if (!PushObject(obj, param.type, (uint8_t *)vec_ptr))
335
+ return false;
424
336
  vec_ptr += param.vec_count;
425
- } else {
426
- if (param.gpr_count) {
427
- RG_ASSERT(param.type->align <= 8);
337
+ } else if (param.gpr_count) {
338
+ RG_ASSERT(param.type->align <= 8);
428
339
 
429
- if (!call.PushObject(obj, param.type, (uint8_t *)gpr_ptr))
430
- return env.Null();
340
+ if (!PushObject(obj, param.type, (uint8_t *)gpr_ptr))
341
+ return false;
431
342
 
432
- gpr_ptr += param.gpr_count;
433
- args_ptr += AlignLen(param.type->size - param.gpr_count * 4, 4);
434
- } else if (param.type->size) {
435
- int16_t align = (param.type->align <= 4) ? 4 : 8;
343
+ gpr_ptr += param.gpr_count;
344
+ args_ptr += AlignLen(param.type->size - param.gpr_count * 4, 4);
345
+ } else if (param.type->size) {
346
+ int16_t align = (param.type->align <= 4) ? 4 : 8;
436
347
 
437
- args_ptr = AlignUp(args_ptr, align);
438
- if (!call.PushObject(obj, param.type, args_ptr))
439
- return env.Null();
440
- args_ptr += AlignLen(param.type->size, 4);
441
- }
348
+ args_ptr = AlignUp(args_ptr, align);
349
+ if (!PushObject(obj, param.type, args_ptr))
350
+ return false;
351
+ args_ptr += AlignLen(param.type->size, 4);
352
+ }
353
+ } break;
354
+ case PrimitiveKind::Float32: {
355
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
356
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
357
+ return false;
358
+ }
359
+
360
+ float f = CopyNumber<float>(value);
361
+
362
+ if (RG_LIKELY(param.vec_count)) {
363
+ memcpy(vec_ptr++, &f, 4);
364
+ } else if (param.gpr_count) {
365
+ memcpy(gpr_ptr++, &f, 4);
366
+ } else {
367
+ memcpy(args_ptr, &f, 4);
368
+ args_ptr += 4;
369
+ }
370
+ } break;
371
+ case PrimitiveKind::Float64: {
372
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
373
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
374
+ return false;
375
+ }
376
+
377
+ double d = CopyNumber<double>(value);
378
+
379
+ if (RG_LIKELY(param.vec_count)) {
380
+ memcpy(vec_ptr, &d, 8);
381
+ vec_ptr += 2;
382
+ } else if (param.gpr_count) {
383
+ memcpy(gpr_ptr, &d, 8);
384
+ gpr_ptr += 2;
385
+ } else {
386
+ args_ptr = AlignUp(args_ptr, 8);
387
+ memcpy(args_ptr, &d, 8);
388
+ args_ptr += 8;
442
389
  }
443
390
  } break;
444
391
  }
445
392
  }
446
393
 
447
- if (instance->debug) {
448
- call.DumpDebug();
449
- }
394
+ return true;
395
+ }
450
396
 
397
+ void CallData::Execute()
398
+ {
451
399
  #define PERFORM_CALL(Suffix) \
452
400
  ([&]() { \
453
- auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, call.GetSP()) \
454
- : ForwardCall ## Suffix(func->func, call.GetSP())); \
455
- PopOutArguments(out_objects); \
401
+ auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, GetSP()) \
402
+ : ForwardCall ## Suffix(func->func, GetSP())); \
456
403
  return ret; \
457
404
  })()
458
405
 
459
406
  // Execute and convert return value
460
407
  switch (func->ret.type->primitive) {
461
- case PrimitiveKind::Float32: {
462
- float f = PERFORM_CALL(F);
463
-
464
- return Napi::Number::New(env, (double)f);
465
- } break;
466
-
467
- case PrimitiveKind::Float64: {
468
- HfaRet ret = PERFORM_CALL(DDDD);
469
-
470
- return Napi::Number::New(env, (double)ret.d0);
471
- } break;
472
-
408
+ case PrimitiveKind::Void:
409
+ case PrimitiveKind::Bool:
410
+ case PrimitiveKind::Int8:
411
+ case PrimitiveKind::UInt8:
412
+ case PrimitiveKind::Int16:
413
+ case PrimitiveKind::UInt16:
414
+ case PrimitiveKind::Int32:
415
+ case PrimitiveKind::UInt32:
416
+ case PrimitiveKind::Int64:
417
+ case PrimitiveKind::UInt64:
418
+ case PrimitiveKind::String:
419
+ case PrimitiveKind::String16:
420
+ case PrimitiveKind::Pointer: { result.u64 = PERFORM_CALL(GG); } break;
473
421
  case PrimitiveKind::Record: {
474
- if (func->ret.gpr_count) {
475
- RG_ASSERT(func->ret.gpr_count <= 1);
476
-
477
- uint64_t ret = PERFORM_CALL(GG);
478
- uint32_t r0 = (uint32_t)ret;
479
-
480
- Napi::Object obj = PopObject(env, (const uint8_t *)&r0, func->ret.type);
481
- return obj;
482
- } else if (func->ret.vec_count) {
422
+ if (func->ret.vec_count) {
483
423
  HfaRet ret = PERFORM_CALL(DDDD);
424
+ memcpy_safe(&result.buf, &ret, RG_SIZE(ret));
425
+ } else {
426
+ result.u64 = PERFORM_CALL(GG);
427
+ }
428
+ } break;
429
+ case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
430
+ case PrimitiveKind::Float64: { result.d = PERFORM_CALL(DDDD).d0; } break;
431
+ }
484
432
 
485
- Napi::Object obj = PopHFA(env, (const uint8_t *)&ret, func->ret.type);
486
- return obj;
487
- } else if (func->ret.type->size) {
488
- RG_ASSERT(return_ptr);
489
-
490
- uint64_t ret = PERFORM_CALL(GG);
491
- uint32_t r0 = (uint32_t)ret;
492
- RG_ASSERT(r0 == (uint32_t)return_ptr);
433
+ #undef PERFORM_CALL
434
+ }
493
435
 
494
- Napi::Object obj = PopObject(env, return_ptr, func->ret.type);
495
- return obj;
496
- } else {
497
- PERFORM_CALL(GG);
436
+ Napi::Value CallData::Complete()
437
+ {
438
+ for (const OutObject &obj: out_objects) {
439
+ PopObject(obj.obj, obj.ptr, obj.type);
440
+ }
498
441
 
499
- Napi::Object obj = Napi::Object::New(env);
500
- return obj;
501
- }
442
+ switch (func->ret.type->primitive) {
443
+ case PrimitiveKind::Void: return env.Null();
444
+ case PrimitiveKind::Bool: return Napi::Boolean::New(env, result.u32);
445
+ case PrimitiveKind::Int8:
446
+ case PrimitiveKind::UInt8:
447
+ case PrimitiveKind::Int16:
448
+ case PrimitiveKind::UInt16:
449
+ case PrimitiveKind::Int32:
450
+ case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)result.u32);
451
+ case PrimitiveKind::Int64: return Napi::BigInt::New(env, (int64_t)result.u64);
452
+ case PrimitiveKind::UInt64: return Napi::BigInt::New(env, result.u64);
453
+ case PrimitiveKind::String: return Napi::String::New(env, (const char *)result.ptr);
454
+ case PrimitiveKind::String16: return Napi::String::New(env, (const char16_t *)result.ptr);
455
+ case PrimitiveKind::Pointer: {
456
+ Napi::External<void> external = Napi::External<void>::New(env, result.ptr);
457
+ SetValueTag(instance, external, func->ret.type);
458
+
459
+ return external;
502
460
  } break;
461
+ case PrimitiveKind::Record: {
462
+ const uint8_t *ptr = return_ptr ? (const uint8_t *)return_ptr
463
+ : (const uint8_t *)&result.buf;
503
464
 
504
- default: {
505
- uint64_t ret = PERFORM_CALL(GG);
506
- uint32_t r0 = (uint32_t)ret;
507
-
508
- switch (func->ret.type->primitive) {
509
- case PrimitiveKind::Void: return env.Null();
510
- case PrimitiveKind::Bool: return Napi::Boolean::New(env, r0);
511
- case PrimitiveKind::Int8: return Napi::Number::New(env, (double)r0);
512
- case PrimitiveKind::UInt8: return Napi::Number::New(env, (double)r0);
513
- case PrimitiveKind::Int16: return Napi::Number::New(env, (double)r0);
514
- case PrimitiveKind::UInt16: return Napi::Number::New(env, (double)r0);
515
- case PrimitiveKind::Int32: return Napi::Number::New(env, (double)r0);
516
- case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)r0);
517
- case PrimitiveKind::Int64: return Napi::BigInt::New(env, (int64_t)ret);
518
- case PrimitiveKind::UInt64: return Napi::BigInt::New(env, ret);
519
- case PrimitiveKind::Float32: { RG_UNREACHABLE(); } break;
520
- case PrimitiveKind::Float64: { RG_UNREACHABLE(); } break;
521
- case PrimitiveKind::String: return Napi::String::New(env, (const char *)r0);
522
- case PrimitiveKind::Pointer: {
523
- void *ptr = (void *)r0;
524
-
525
- Napi::External<void> external = Napi::External<void>::New(env, ptr);
526
- SetValueTag(instance, external, func->ret.type);
527
-
528
- return external;
529
- } break;
530
-
531
- case PrimitiveKind::Record: { RG_UNREACHABLE(); } break;
532
- }
465
+ Napi::Object obj = PopObject(ptr, func->ret.type);
466
+ return obj;
533
467
  } break;
468
+ case PrimitiveKind::Float32: return Napi::Number::New(env, (double)result.f);
469
+ case PrimitiveKind::Float64: return Napi::Number::New(env, result.d);
534
470
  }
535
471
 
536
- #undef PERFORM_CALL
537
-
538
472
  RG_UNREACHABLE();
539
473
  }
540
474
 
File without changes