koffi 1.0.3 → 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.
- package/README.md +22 -21
- package/build/qemu/1.0.4/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.0.4/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.0.4/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.0.4/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.0.4/koffi_linux_arm.tar.gz +0 -0
- package/build/qemu/1.0.4/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.0.4/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.0.4/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.0.4/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.0.4/koffi_win32_x64.tar.gz +0 -0
- package/package.json +1 -1
- package/src/abi_arm32.cc +119 -211
- package/src/abi_arm64.cc +92 -113
- package/src/abi_x64_sysv.cc +106 -131
- package/src/abi_x64_win.cc +78 -94
- package/src/abi_x86.cc +80 -95
- package/src/call.cc +144 -19
- package/src/call.hh +39 -3
- package/src/ffi.cc +11 -2
- package/src/ffi.hh +6 -12
- package/src/util.cc +0 -127
- package/src/util.hh +0 -16
- package/test/misc.c +66 -0
- package/test/misc.js +47 -0
- package/vendor/libcc/libcc.hh +1 -1
- package/build/qemu/1.0.3/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.0.3/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.0.3/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.0.3/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.0.3/koffi_linux_arm.tar.gz +0 -0
- package/build/qemu/1.0.3/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.0.3/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.0.3/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.0.3/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.0.3/koffi_win32_x64.tar.gz +0 -0
package/src/abi_arm64.cc
CHANGED
|
@@ -163,28 +163,24 @@ static bool PushHFA(const Napi::Object &obj, const TypeInfo *type, uint8_t *dest
|
|
|
163
163
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
164
164
|
|
|
165
165
|
RG_ASSERT(IsObject(obj));
|
|
166
|
+
RG_ASSERT(IsHFA(type));
|
|
166
167
|
RG_ASSERT(type->primitive == PrimitiveKind::Record);
|
|
167
|
-
RG_ASSERT(AlignUp(dest,
|
|
168
|
+
RG_ASSERT(AlignUp(dest, type->members[0].type->size) == dest);
|
|
169
|
+
|
|
170
|
+
bool float32 = (type->members[0].type->primitive == PrimitiveKind::Float32);
|
|
168
171
|
|
|
169
172
|
for (const RecordMember &member: type->members) {
|
|
170
173
|
Napi::Value value = obj.Get(member.name);
|
|
171
174
|
|
|
172
|
-
if (
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
175
|
+
if (!value.IsNumber() && !value.IsBigInt()) {
|
|
176
|
+
ThrowError<Napi::TypeError>(env, "Unexpected value %1 for member '%2', expected number", GetValueType(instance, value), member.name);
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
177
179
|
|
|
180
|
+
if (float32) {
|
|
178
181
|
*(float *)dest = CopyNumber<float>(value);
|
|
179
|
-
} else if (member.type->primitive == PrimitiveKind::Float64) {
|
|
180
|
-
if (!value.IsNumber() && !value.IsBigInt()) {
|
|
181
|
-
ThrowError<Napi::TypeError>(env, "Unexpected value %1 for member '%2', expected number", GetValueType(instance, value), member.name);
|
|
182
|
-
return false;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
*(double *)dest = CopyNumber<double>(value);
|
|
186
182
|
} else {
|
|
187
|
-
|
|
183
|
+
*(double *)dest = CopyNumber<double>(value);
|
|
188
184
|
}
|
|
189
185
|
|
|
190
186
|
dest += 8;
|
|
@@ -196,18 +192,19 @@ static bool PushHFA(const Napi::Object &obj, const TypeInfo *type, uint8_t *dest
|
|
|
196
192
|
static Napi::Object PopHFA(napi_env env, const uint8_t *ptr, const TypeInfo *type)
|
|
197
193
|
{
|
|
198
194
|
RG_ASSERT(type->primitive == PrimitiveKind::Record);
|
|
195
|
+
RG_ASSERT(IsHFA(type));
|
|
199
196
|
|
|
200
197
|
Napi::Object obj = Napi::Object::New(env);
|
|
201
198
|
|
|
199
|
+
bool float32 = (type->members[0].type->primitive == PrimitiveKind::Float32);
|
|
200
|
+
|
|
202
201
|
for (const RecordMember &member: type->members) {
|
|
203
|
-
if (
|
|
202
|
+
if (float32) {
|
|
204
203
|
float f = *(float *)ptr;
|
|
205
204
|
obj.Set(member.name, Napi::Number::New(env, (double)f));
|
|
206
|
-
} else
|
|
205
|
+
} else {
|
|
207
206
|
double d = *(double *)ptr;
|
|
208
207
|
obj.Set(member.name, Napi::Number::New(env, d));
|
|
209
|
-
} else {
|
|
210
|
-
RG_UNREACHABLE();
|
|
211
208
|
}
|
|
212
209
|
|
|
213
210
|
ptr += 8;
|
|
@@ -216,34 +213,25 @@ static Napi::Object PopHFA(napi_env env, const uint8_t *ptr, const TypeInfo *typ
|
|
|
216
213
|
return obj;
|
|
217
214
|
}
|
|
218
215
|
|
|
219
|
-
|
|
216
|
+
bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
220
217
|
{
|
|
221
|
-
// Sanity checks
|
|
222
|
-
if (info.Length() < (uint32_t)func->parameters.len) {
|
|
223
|
-
ThrowError<Napi::TypeError>(env, "Expected %1 arguments, got %2", func->parameters.len, info.Length());
|
|
224
|
-
return env.Null();
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
uint8_t *return_ptr = nullptr;
|
|
228
218
|
uint8_t *args_ptr = nullptr;
|
|
229
219
|
uint64_t *gpr_ptr = nullptr;
|
|
230
220
|
uint64_t *vec_ptr = nullptr;
|
|
231
221
|
|
|
232
222
|
// Return through registers unless it's too big
|
|
233
223
|
if (RG_UNLIKELY(!AllocStack(func->args_size, 16, &args_ptr)))
|
|
234
|
-
return
|
|
224
|
+
return false;
|
|
235
225
|
if (RG_UNLIKELY(!AllocStack(8 * 8, 8, &vec_ptr)))
|
|
236
|
-
return
|
|
226
|
+
return false;
|
|
237
227
|
if (RG_UNLIKELY(!AllocStack(9 * 8, 8, &gpr_ptr)))
|
|
238
|
-
return
|
|
228
|
+
return false;
|
|
239
229
|
if (func->ret.use_memory) {
|
|
240
230
|
if (RG_UNLIKELY(!AllocHeap(func->ret.type->size, 16, &return_ptr)))
|
|
241
|
-
return
|
|
231
|
+
return false;
|
|
242
232
|
gpr_ptr[8] = (uint64_t)return_ptr;
|
|
243
233
|
}
|
|
244
234
|
|
|
245
|
-
LocalArray<OutObject, MaxOutParameters> out_objects;
|
|
246
|
-
|
|
247
235
|
// Push arguments
|
|
248
236
|
for (Size i = 0; i < func->parameters.len; i++) {
|
|
249
237
|
const ParameterInfo ¶m = func->parameters[i];
|
|
@@ -257,7 +245,7 @@ Napi::Value CallData::Execute(const Napi::CallbackInfo &info)
|
|
|
257
245
|
case PrimitiveKind::Bool: {
|
|
258
246
|
if (RG_UNLIKELY(!value.IsBoolean())) {
|
|
259
247
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected boolean", GetValueType(instance, value), i + 1);
|
|
260
|
-
return
|
|
248
|
+
return false;
|
|
261
249
|
}
|
|
262
250
|
|
|
263
251
|
bool b = value.As<Napi::Boolean>();
|
|
@@ -283,7 +271,7 @@ Napi::Value CallData::Execute(const Napi::CallbackInfo &info)
|
|
|
283
271
|
case PrimitiveKind::UInt64: {
|
|
284
272
|
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
285
273
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
|
|
286
|
-
return
|
|
274
|
+
return false;
|
|
287
275
|
}
|
|
288
276
|
|
|
289
277
|
int64_t v = CopyNumber<int64_t>(value);
|
|
@@ -303,7 +291,7 @@ Napi::Value CallData::Execute(const Napi::CallbackInfo &info)
|
|
|
303
291
|
case PrimitiveKind::Float32: {
|
|
304
292
|
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
305
293
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
|
|
306
|
-
return
|
|
294
|
+
return false;
|
|
307
295
|
}
|
|
308
296
|
|
|
309
297
|
float f = CopyNumber<float>(value);
|
|
@@ -323,7 +311,7 @@ Napi::Value CallData::Execute(const Napi::CallbackInfo &info)
|
|
|
323
311
|
case PrimitiveKind::Float64: {
|
|
324
312
|
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
325
313
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
|
|
326
|
-
return
|
|
314
|
+
return false;
|
|
327
315
|
}
|
|
328
316
|
|
|
329
317
|
double d = CopyNumber<double>(value);
|
|
@@ -341,12 +329,12 @@ Napi::Value CallData::Execute(const Napi::CallbackInfo &info)
|
|
|
341
329
|
if (RG_LIKELY(value.IsString())) {
|
|
342
330
|
str = PushString(value);
|
|
343
331
|
if (RG_UNLIKELY(!str))
|
|
344
|
-
return
|
|
332
|
+
return false;
|
|
345
333
|
} else if (IsNullOrUndefined(value)) {
|
|
346
334
|
str = nullptr;
|
|
347
335
|
} else {
|
|
348
336
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected string", GetValueType(instance, value), i + 1);
|
|
349
|
-
return
|
|
337
|
+
return false;
|
|
350
338
|
}
|
|
351
339
|
|
|
352
340
|
if (RG_LIKELY(param.gpr_count)) {
|
|
@@ -362,12 +350,12 @@ Napi::Value CallData::Execute(const Napi::CallbackInfo &info)
|
|
|
362
350
|
if (RG_LIKELY(value.IsString())) {
|
|
363
351
|
str16 = PushString16(value);
|
|
364
352
|
if (RG_UNLIKELY(!str16))
|
|
365
|
-
return
|
|
353
|
+
return false;
|
|
366
354
|
} else if (IsNullOrUndefined(value)) {
|
|
367
355
|
str16 = nullptr;
|
|
368
356
|
} else {
|
|
369
357
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected string", GetValueType(instance, value), i + 1);
|
|
370
|
-
return
|
|
358
|
+
return false;
|
|
371
359
|
}
|
|
372
360
|
|
|
373
361
|
if (RG_LIKELY(param.gpr_count)) {
|
|
@@ -387,11 +375,11 @@ Napi::Value CallData::Execute(const Napi::CallbackInfo &info)
|
|
|
387
375
|
Napi::Object obj = value.As<Napi::Object>();
|
|
388
376
|
|
|
389
377
|
if (RG_UNLIKELY(!AllocHeap(param.type->ref->size, 16, &ptr)))
|
|
390
|
-
return
|
|
378
|
+
return false;
|
|
391
379
|
|
|
392
380
|
if (param.directions & 1) {
|
|
393
381
|
if (!PushObject(obj, param.type->ref, ptr))
|
|
394
|
-
return
|
|
382
|
+
return false;
|
|
395
383
|
} else {
|
|
396
384
|
memset(ptr, 0, param.type->size);
|
|
397
385
|
}
|
|
@@ -403,7 +391,7 @@ Napi::Value CallData::Execute(const Napi::CallbackInfo &info)
|
|
|
403
391
|
ptr = nullptr;
|
|
404
392
|
} else {
|
|
405
393
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected %3", GetValueType(instance, value), i + 1, param.type->name);
|
|
406
|
-
return
|
|
394
|
+
return false;
|
|
407
395
|
}
|
|
408
396
|
|
|
409
397
|
if (RG_LIKELY(param.gpr_count)) {
|
|
@@ -418,32 +406,32 @@ Napi::Value CallData::Execute(const Napi::CallbackInfo &info)
|
|
|
418
406
|
case PrimitiveKind::Record: {
|
|
419
407
|
if (RG_UNLIKELY(!IsObject(value))) {
|
|
420
408
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected object", GetValueType(instance, value), i + 1);
|
|
421
|
-
return
|
|
409
|
+
return false;
|
|
422
410
|
}
|
|
423
411
|
|
|
424
412
|
Napi::Object obj = value.As<Napi::Object>();
|
|
425
413
|
|
|
426
414
|
if (param.vec_count) {
|
|
427
415
|
if (!PushHFA(obj, param.type, (uint8_t *)vec_ptr))
|
|
428
|
-
return
|
|
416
|
+
return false;
|
|
429
417
|
vec_ptr += param.vec_count;
|
|
430
418
|
} else if (!param.use_memory) {
|
|
431
419
|
if (param.gpr_count) {
|
|
432
420
|
RG_ASSERT(param.type->align <= 8);
|
|
433
421
|
|
|
434
422
|
if (!PushObject(obj, param.type, (uint8_t *)gpr_ptr))
|
|
435
|
-
return
|
|
423
|
+
return false;
|
|
436
424
|
gpr_ptr += param.gpr_count;
|
|
437
425
|
} else if (param.type->size) {
|
|
438
426
|
args_ptr = AlignUp(args_ptr, 8);
|
|
439
427
|
if (!PushObject(obj, param.type, args_ptr))
|
|
440
|
-
return
|
|
428
|
+
return false;
|
|
441
429
|
args_ptr += AlignLen(param.type->size, 8);
|
|
442
430
|
}
|
|
443
431
|
} else {
|
|
444
432
|
uint8_t *ptr;
|
|
445
433
|
if (RG_UNLIKELY(!AllocHeap(param.type->size, 16, &ptr)))
|
|
446
|
-
return
|
|
434
|
+
return false;
|
|
447
435
|
|
|
448
436
|
if (param.gpr_count) {
|
|
449
437
|
RG_ASSERT(param.gpr_count == 1);
|
|
@@ -457,107 +445,98 @@ Napi::Value CallData::Execute(const Napi::CallbackInfo &info)
|
|
|
457
445
|
}
|
|
458
446
|
|
|
459
447
|
if (!PushObject(obj, param.type, ptr))
|
|
460
|
-
return
|
|
448
|
+
return false;
|
|
461
449
|
}
|
|
462
450
|
} break;
|
|
463
451
|
}
|
|
464
452
|
}
|
|
465
453
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
}
|
|
454
|
+
return true;
|
|
455
|
+
}
|
|
469
456
|
|
|
457
|
+
void CallData::Execute()
|
|
458
|
+
{
|
|
470
459
|
#define PERFORM_CALL(Suffix) \
|
|
471
460
|
([&]() { \
|
|
472
461
|
auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, GetSP()) \
|
|
473
462
|
: ForwardCall ## Suffix(func->func, GetSP())); \
|
|
474
|
-
PopOutArguments(out_objects); \
|
|
475
463
|
return ret; \
|
|
476
464
|
})()
|
|
477
465
|
|
|
478
466
|
// Execute and convert return value
|
|
479
467
|
switch (func->ret.type->primitive) {
|
|
480
|
-
case PrimitiveKind::Void:
|
|
481
|
-
|
|
482
|
-
return env.Null();
|
|
483
|
-
} break;
|
|
484
|
-
case PrimitiveKind::Bool: {
|
|
485
|
-
X0X1Ret ret = PERFORM_CALL(GG);
|
|
486
|
-
return Napi::Boolean::New(env, ret.x0);
|
|
487
|
-
} break;
|
|
468
|
+
case PrimitiveKind::Void:
|
|
469
|
+
case PrimitiveKind::Bool:
|
|
488
470
|
case PrimitiveKind::Int8:
|
|
489
471
|
case PrimitiveKind::UInt8:
|
|
490
472
|
case PrimitiveKind::Int16:
|
|
491
473
|
case PrimitiveKind::UInt16:
|
|
492
474
|
case PrimitiveKind::Int32:
|
|
493
|
-
case PrimitiveKind::UInt32:
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
case PrimitiveKind::
|
|
498
|
-
|
|
499
|
-
return Napi::BigInt::New(env, (int64_t)ret.x0);
|
|
500
|
-
} break;
|
|
501
|
-
case PrimitiveKind::UInt64: {
|
|
502
|
-
X0X1Ret ret = PERFORM_CALL(GG);
|
|
503
|
-
return Napi::BigInt::New(env, ret.x0);
|
|
504
|
-
} break;
|
|
505
|
-
case PrimitiveKind::Float32: {
|
|
506
|
-
float f = PERFORM_CALL(F);
|
|
507
|
-
return Napi::Number::New(env, (double)f);
|
|
508
|
-
} break;
|
|
509
|
-
case PrimitiveKind::Float64: {
|
|
510
|
-
HfaRet ret = PERFORM_CALL(DDDD);
|
|
511
|
-
return Napi::Number::New(env, (double)ret.d0);
|
|
512
|
-
} break;
|
|
513
|
-
case PrimitiveKind::String: {
|
|
514
|
-
X0X1Ret ret = PERFORM_CALL(GG);
|
|
515
|
-
return Napi::String::New(env, (const char *)ret.x0);
|
|
516
|
-
} break;
|
|
517
|
-
case PrimitiveKind::String16: {
|
|
518
|
-
X0X1Ret ret = PERFORM_CALL(GG);
|
|
519
|
-
return Napi::String::New(env, (const char16_t *)ret.x0);
|
|
520
|
-
} break;
|
|
521
|
-
case PrimitiveKind::Pointer: {
|
|
522
|
-
X0X1Ret ret = PERFORM_CALL(GG);
|
|
523
|
-
void *ptr = (void *)ret.x0;
|
|
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
|
-
|
|
475
|
+
case PrimitiveKind::UInt32:
|
|
476
|
+
case PrimitiveKind::Int64:
|
|
477
|
+
case PrimitiveKind::UInt64:
|
|
478
|
+
case PrimitiveKind::String:
|
|
479
|
+
case PrimitiveKind::String16:
|
|
480
|
+
case PrimitiveKind::Pointer: { result.u64 = PERFORM_CALL(GG).x0; } break;
|
|
531
481
|
case PrimitiveKind::Record: {
|
|
532
482
|
if (func->ret.gpr_count) {
|
|
533
483
|
X0X1Ret ret = PERFORM_CALL(GG);
|
|
534
|
-
|
|
535
|
-
Napi::Object obj = PopObject(env, (const uint8_t *)&ret, func->ret.type);
|
|
536
|
-
return obj;
|
|
484
|
+
memcpy_safe(&result.buf, &ret, RG_SIZE(ret));
|
|
537
485
|
} else if (func->ret.vec_count) {
|
|
538
486
|
HfaRet ret = PERFORM_CALL(DDDD);
|
|
487
|
+
memcpy_safe(&result.buf, &ret, RG_SIZE(ret));
|
|
488
|
+
} else {
|
|
489
|
+
PERFORM_CALL(GG);
|
|
490
|
+
}
|
|
491
|
+
} break;
|
|
492
|
+
case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
|
|
493
|
+
case PrimitiveKind::Float64: { result.d = PERFORM_CALL(DDDD).d0; } break;
|
|
494
|
+
}
|
|
539
495
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
} else if (func->ret.type->size) {
|
|
543
|
-
RG_ASSERT(return_ptr);
|
|
496
|
+
#undef PERFORM_CALL
|
|
497
|
+
}
|
|
544
498
|
|
|
545
|
-
|
|
546
|
-
|
|
499
|
+
Napi::Value CallData::Complete()
|
|
500
|
+
{
|
|
501
|
+
for (const OutObject &obj: out_objects) {
|
|
502
|
+
PopObject(obj.obj, obj.ptr, obj.type);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
switch (func->ret.type->primitive) {
|
|
506
|
+
case PrimitiveKind::Void: return env.Null();
|
|
507
|
+
case PrimitiveKind::Bool: return Napi::Boolean::New(env, result.u32);
|
|
508
|
+
case PrimitiveKind::Int8:
|
|
509
|
+
case PrimitiveKind::UInt8:
|
|
510
|
+
case PrimitiveKind::Int16:
|
|
511
|
+
case PrimitiveKind::UInt16:
|
|
512
|
+
case PrimitiveKind::Int32:
|
|
513
|
+
case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)result.u32);
|
|
514
|
+
case PrimitiveKind::Int64: return Napi::BigInt::New(env, (int64_t)result.u64);
|
|
515
|
+
case PrimitiveKind::UInt64: return Napi::BigInt::New(env, result.u64);
|
|
516
|
+
case PrimitiveKind::String: return Napi::String::New(env, (const char *)result.ptr);
|
|
517
|
+
case PrimitiveKind::String16: return Napi::String::New(env, (const char16_t *)result.ptr);
|
|
518
|
+
case PrimitiveKind::Pointer: {
|
|
519
|
+
Napi::External<void> external = Napi::External<void>::New(env, result.ptr);
|
|
520
|
+
SetValueTag(instance, external, func->ret.type);
|
|
547
521
|
|
|
548
|
-
|
|
522
|
+
return external;
|
|
523
|
+
} break;
|
|
524
|
+
case PrimitiveKind::Record: {
|
|
525
|
+
if (func->ret.vec_count) {
|
|
526
|
+
Napi::Object obj = PopHFA(env, (const uint8_t *)&result.buf, func->ret.type);
|
|
549
527
|
return obj;
|
|
550
528
|
} else {
|
|
551
|
-
|
|
529
|
+
const uint8_t *ptr = return_ptr ? (const uint8_t *)return_ptr
|
|
530
|
+
: (const uint8_t *)&result.buf;
|
|
552
531
|
|
|
553
|
-
Napi::Object obj =
|
|
532
|
+
Napi::Object obj = PopObject(ptr, func->ret.type);
|
|
554
533
|
return obj;
|
|
555
534
|
}
|
|
556
535
|
} break;
|
|
536
|
+
case PrimitiveKind::Float32: return Napi::Number::New(env, (double)result.f);
|
|
537
|
+
case PrimitiveKind::Float64: return Napi::Number::New(env, result.d);
|
|
557
538
|
}
|
|
558
539
|
|
|
559
|
-
#undef PERFORM_CALL
|
|
560
|
-
|
|
561
540
|
RG_UNREACHABLE();
|
|
562
541
|
}
|
|
563
542
|
|