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