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
|
@@ -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
|
-
|
|
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(!
|
|
244
|
-
return
|
|
245
|
-
if (RG_UNLIKELY(!
|
|
246
|
-
return
|
|
247
|
-
if (RG_UNLIKELY(!
|
|
248
|
-
return
|
|
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(!
|
|
251
|
-
return
|
|
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 ¶m = 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
|
|
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
|
|
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
|
|
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 =
|
|
253
|
+
str = PushString(value);
|
|
361
254
|
if (RG_UNLIKELY(!str))
|
|
362
|
-
return
|
|
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
|
|
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(!
|
|
386
|
-
return
|
|
298
|
+
if (RG_UNLIKELY(!AllocHeap(param.type->ref->size, 16, &ptr)))
|
|
299
|
+
return false;
|
|
387
300
|
|
|
388
301
|
if (param.directions & 1) {
|
|
389
|
-
if (!
|
|
390
|
-
return
|
|
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
|
|
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
|
|
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 (!
|
|
423
|
-
return
|
|
334
|
+
if (!PushObject(obj, param.type, (uint8_t *)vec_ptr))
|
|
335
|
+
return false;
|
|
424
336
|
vec_ptr += param.vec_count;
|
|
425
|
-
} else {
|
|
426
|
-
|
|
427
|
-
RG_ASSERT(param.type->align <= 8);
|
|
337
|
+
} else if (param.gpr_count) {
|
|
338
|
+
RG_ASSERT(param.type->align <= 8);
|
|
428
339
|
|
|
429
|
-
|
|
430
|
-
|
|
340
|
+
if (!PushObject(obj, param.type, (uint8_t *)gpr_ptr))
|
|
341
|
+
return false;
|
|
431
342
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
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
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
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
|
-
|
|
448
|
-
|
|
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,
|
|
454
|
-
: ForwardCall ## Suffix(func->func,
|
|
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::
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
case PrimitiveKind::
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
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.
|
|
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
|
-
|
|
486
|
-
|
|
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
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
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
|
-
|
|
500
|
-
|
|
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
|
-
|
|
505
|
-
|
|
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
|