koffi 1.0.5 → 1.1.0-beta.2
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 +4 -0
- package/README.md +54 -24
- package/build/qemu/1.1.0-beta.2/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.2/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.2/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.2/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.2/koffi_linux_arm.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.2/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.2/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.2/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.2/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.2/koffi_win32_x64.tar.gz +0 -0
- package/package.json +1 -1
- package/qemu/qemu.js +12 -5
- package/qemu/registry/machines.json +20 -10
- package/src/abi_arm32.cc +40 -51
- package/src/abi_arm64.cc +71 -138
- package/src/abi_x64_sysv.cc +37 -13
- package/src/abi_x64_win.cc +16 -6
- package/src/abi_x86.cc +16 -6
- package/src/call.cc +564 -58
- package/src/call.hh +32 -44
- package/src/ffi.cc +218 -19
- package/src/ffi.hh +27 -11
- package/src/parser.cc +4 -0
- package/src/util.cc +72 -0
- package/src/util.hh +2 -0
- package/test/misc.c +16 -10
- package/build/qemu/1.0.5/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.0.5/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.0.5/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.0.5/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.0.5/koffi_linux_arm.tar.gz +0 -0
- package/build/qemu/1.0.5/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.0.5/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.0.5/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.0.5/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.0.5/koffi_win32_x64.tar.gz +0 -0
- package/test/misc.js +0 -227
package/src/abi_arm64.cc
CHANGED
|
@@ -41,28 +41,9 @@ extern "C" X0X1Ret ForwardCallXGG(const void *func, uint8_t *sp);
|
|
|
41
41
|
extern "C" float ForwardCallXF(const void *func, uint8_t *sp);
|
|
42
42
|
extern "C" HfaRet ForwardCallXDDDD(const void *func, uint8_t *sp);
|
|
43
43
|
|
|
44
|
-
static bool IsHFA(const TypeInfo *type)
|
|
45
|
-
{
|
|
46
|
-
if (type->primitive != PrimitiveKind::Record)
|
|
47
|
-
return false;
|
|
48
|
-
|
|
49
|
-
if (type->members.len < 1 || type->members.len > 4)
|
|
50
|
-
return false;
|
|
51
|
-
if (type->members[0].type->primitive != PrimitiveKind::Float32 &&
|
|
52
|
-
type->members[0].type->primitive != PrimitiveKind::Float64)
|
|
53
|
-
return false;
|
|
54
|
-
|
|
55
|
-
for (Size i = 1; i < type->members.len; i++) {
|
|
56
|
-
if (type->members[i].type != type->members[0].type)
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return true;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
44
|
bool AnalyseFunction(InstanceData *, FunctionInfo *func)
|
|
64
45
|
{
|
|
65
|
-
if (IsHFA(func->ret.type)) {
|
|
46
|
+
if (IsHFA(func->ret.type, 1, 4)) {
|
|
66
47
|
func->ret.vec_count = func->ret.type->members.len;
|
|
67
48
|
} else if (func->ret.type->size <= 16) {
|
|
68
49
|
func->ret.gpr_count = (func->ret.type->size + 7) / 8;
|
|
@@ -99,20 +80,6 @@ bool AnalyseFunction(InstanceData *, FunctionInfo *func)
|
|
|
99
80
|
gpr_avail--;
|
|
100
81
|
}
|
|
101
82
|
} break;
|
|
102
|
-
|
|
103
|
-
case PrimitiveKind::Float32:
|
|
104
|
-
case PrimitiveKind::Float64: {
|
|
105
|
-
#ifdef __APPLE__
|
|
106
|
-
if (param.variadic)
|
|
107
|
-
break;
|
|
108
|
-
#endif
|
|
109
|
-
|
|
110
|
-
if (vec_avail) {
|
|
111
|
-
param.vec_count = 1;
|
|
112
|
-
vec_avail--;
|
|
113
|
-
}
|
|
114
|
-
} break;
|
|
115
|
-
|
|
116
83
|
case PrimitiveKind::Record: {
|
|
117
84
|
#ifdef __APPLE__
|
|
118
85
|
if (param.variadic) {
|
|
@@ -121,7 +88,7 @@ bool AnalyseFunction(InstanceData *, FunctionInfo *func)
|
|
|
121
88
|
}
|
|
122
89
|
#endif
|
|
123
90
|
|
|
124
|
-
if (IsHFA(param.type)) {
|
|
91
|
+
if (IsHFA(param.type, 1, 4)) {
|
|
125
92
|
int vec_count = (int)param.type->members.len;
|
|
126
93
|
|
|
127
94
|
if (vec_count <= vec_avail) {
|
|
@@ -148,6 +115,19 @@ bool AnalyseFunction(InstanceData *, FunctionInfo *func)
|
|
|
148
115
|
param.use_memory = true;
|
|
149
116
|
}
|
|
150
117
|
} break;
|
|
118
|
+
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
119
|
+
case PrimitiveKind::Float32:
|
|
120
|
+
case PrimitiveKind::Float64: {
|
|
121
|
+
#ifdef __APPLE__
|
|
122
|
+
if (param.variadic)
|
|
123
|
+
break;
|
|
124
|
+
#endif
|
|
125
|
+
|
|
126
|
+
if (vec_avail) {
|
|
127
|
+
param.vec_count = 1;
|
|
128
|
+
vec_avail--;
|
|
129
|
+
}
|
|
130
|
+
} break;
|
|
151
131
|
}
|
|
152
132
|
}
|
|
153
133
|
|
|
@@ -157,62 +137,6 @@ bool AnalyseFunction(InstanceData *, FunctionInfo *func)
|
|
|
157
137
|
return true;
|
|
158
138
|
}
|
|
159
139
|
|
|
160
|
-
static bool PushHFA(const Napi::Object &obj, const TypeInfo *type, uint8_t *dest)
|
|
161
|
-
{
|
|
162
|
-
Napi::Env env = obj.Env();
|
|
163
|
-
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
164
|
-
|
|
165
|
-
RG_ASSERT(IsObject(obj));
|
|
166
|
-
RG_ASSERT(IsHFA(type));
|
|
167
|
-
RG_ASSERT(type->primitive == PrimitiveKind::Record);
|
|
168
|
-
RG_ASSERT(AlignUp(dest, type->members[0].type->size) == dest);
|
|
169
|
-
|
|
170
|
-
bool float32 = (type->members[0].type->primitive == PrimitiveKind::Float32);
|
|
171
|
-
|
|
172
|
-
for (const RecordMember &member: type->members) {
|
|
173
|
-
Napi::Value value = obj.Get(member.name);
|
|
174
|
-
|
|
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
|
-
}
|
|
179
|
-
|
|
180
|
-
if (float32) {
|
|
181
|
-
*(float *)dest = CopyNumber<float>(value);
|
|
182
|
-
} else {
|
|
183
|
-
*(double *)dest = CopyNumber<double>(value);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
dest += 8;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
return true;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
static Napi::Object PopHFA(napi_env env, const uint8_t *ptr, const TypeInfo *type)
|
|
193
|
-
{
|
|
194
|
-
RG_ASSERT(type->primitive == PrimitiveKind::Record);
|
|
195
|
-
RG_ASSERT(IsHFA(type));
|
|
196
|
-
|
|
197
|
-
Napi::Object obj = Napi::Object::New(env);
|
|
198
|
-
|
|
199
|
-
bool float32 = (type->members[0].type->primitive == PrimitiveKind::Float32);
|
|
200
|
-
|
|
201
|
-
for (const RecordMember &member: type->members) {
|
|
202
|
-
if (float32) {
|
|
203
|
-
float f = *(float *)ptr;
|
|
204
|
-
obj.Set(member.name, Napi::Number::New(env, (double)f));
|
|
205
|
-
} else {
|
|
206
|
-
double d = *(double *)ptr;
|
|
207
|
-
obj.Set(member.name, Napi::Number::New(env, d));
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
ptr += 8;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
return obj;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
140
|
bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
217
141
|
{
|
|
218
142
|
uint8_t *args_ptr = nullptr;
|
|
@@ -288,42 +212,6 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
288
212
|
#endif
|
|
289
213
|
}
|
|
290
214
|
} break;
|
|
291
|
-
case PrimitiveKind::Float32: {
|
|
292
|
-
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
293
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
|
|
294
|
-
return false;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
float f = CopyNumber<float>(value);
|
|
298
|
-
|
|
299
|
-
if (RG_LIKELY(param.vec_count)) {
|
|
300
|
-
memcpy(vec_ptr++, &f, 4);
|
|
301
|
-
} else {
|
|
302
|
-
args_ptr = AlignUp(args_ptr, 4);
|
|
303
|
-
memcpy(args_ptr, &f, 4);
|
|
304
|
-
#ifdef __APPLE__
|
|
305
|
-
args_ptr += 4;
|
|
306
|
-
#else
|
|
307
|
-
args_ptr += 8;
|
|
308
|
-
#endif
|
|
309
|
-
}
|
|
310
|
-
} break;
|
|
311
|
-
case PrimitiveKind::Float64: {
|
|
312
|
-
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
313
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
|
|
314
|
-
return false;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
double d = CopyNumber<double>(value);
|
|
318
|
-
|
|
319
|
-
if (RG_LIKELY(param.vec_count)) {
|
|
320
|
-
memcpy(vec_ptr++, &d, 8);
|
|
321
|
-
} else {
|
|
322
|
-
args_ptr = AlignUp(args_ptr, 8);
|
|
323
|
-
memcpy(args_ptr, &d, 8);
|
|
324
|
-
args_ptr += 8;
|
|
325
|
-
}
|
|
326
|
-
} break;
|
|
327
215
|
case PrimitiveKind::String: {
|
|
328
216
|
const char *str;
|
|
329
217
|
if (RG_LIKELY(value.IsString())) {
|
|
@@ -384,8 +272,11 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
384
272
|
memset(ptr, 0, param.type->size);
|
|
385
273
|
}
|
|
386
274
|
if (param.directions & 2) {
|
|
387
|
-
OutObject out =
|
|
388
|
-
|
|
275
|
+
OutObject *out = out_objects.AppendDefault();
|
|
276
|
+
|
|
277
|
+
out->ref.Reset(obj, 1);
|
|
278
|
+
out->ptr = ptr;
|
|
279
|
+
out->type = param.type->ref;
|
|
389
280
|
}
|
|
390
281
|
} else if (IsNullOrUndefined(value)) {
|
|
391
282
|
ptr = nullptr;
|
|
@@ -402,7 +293,6 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
402
293
|
args_ptr += 8;
|
|
403
294
|
}
|
|
404
295
|
} break;
|
|
405
|
-
|
|
406
296
|
case PrimitiveKind::Record: {
|
|
407
297
|
if (RG_UNLIKELY(!IsObject(value))) {
|
|
408
298
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected object", GetValueType(instance, value), i + 1);
|
|
@@ -411,8 +301,8 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
411
301
|
|
|
412
302
|
Napi::Object obj = value.As<Napi::Object>();
|
|
413
303
|
|
|
414
|
-
if (param.vec_count) {
|
|
415
|
-
if (!
|
|
304
|
+
if (param.vec_count) { // HFA
|
|
305
|
+
if (!PushObject(obj, param.type, (uint8_t *)vec_ptr, 8))
|
|
416
306
|
return false;
|
|
417
307
|
vec_ptr += param.vec_count;
|
|
418
308
|
} else if (!param.use_memory) {
|
|
@@ -448,9 +338,49 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
448
338
|
return false;
|
|
449
339
|
}
|
|
450
340
|
} break;
|
|
341
|
+
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
342
|
+
case PrimitiveKind::Float32: {
|
|
343
|
+
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
344
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
|
|
345
|
+
return false;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
float f = CopyNumber<float>(value);
|
|
349
|
+
|
|
350
|
+
if (RG_LIKELY(param.vec_count)) {
|
|
351
|
+
memcpy(vec_ptr++, &f, 4);
|
|
352
|
+
} else {
|
|
353
|
+
args_ptr = AlignUp(args_ptr, 4);
|
|
354
|
+
memcpy(args_ptr, &f, 4);
|
|
355
|
+
#ifdef __APPLE__
|
|
356
|
+
args_ptr += 4;
|
|
357
|
+
#else
|
|
358
|
+
args_ptr += 8;
|
|
359
|
+
#endif
|
|
360
|
+
}
|
|
361
|
+
} break;
|
|
362
|
+
case PrimitiveKind::Float64: {
|
|
363
|
+
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
364
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
double d = CopyNumber<double>(value);
|
|
369
|
+
|
|
370
|
+
if (RG_LIKELY(param.vec_count)) {
|
|
371
|
+
memcpy(vec_ptr++, &d, 8);
|
|
372
|
+
} else {
|
|
373
|
+
args_ptr = AlignUp(args_ptr, 8);
|
|
374
|
+
memcpy(args_ptr, &d, 8);
|
|
375
|
+
args_ptr += 8;
|
|
376
|
+
}
|
|
377
|
+
} break;
|
|
451
378
|
}
|
|
452
379
|
}
|
|
453
380
|
|
|
381
|
+
stack = MakeSpan(mem->stack.end(), old_stack_mem.end() - mem->stack.end());
|
|
382
|
+
heap = MakeSpan(old_heap_mem.ptr, mem->heap.ptr - old_heap_mem.ptr);
|
|
383
|
+
|
|
454
384
|
return true;
|
|
455
385
|
}
|
|
456
386
|
|
|
@@ -458,8 +388,8 @@ void CallData::Execute()
|
|
|
458
388
|
{
|
|
459
389
|
#define PERFORM_CALL(Suffix) \
|
|
460
390
|
([&]() { \
|
|
461
|
-
auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func,
|
|
462
|
-
: ForwardCall ## Suffix(func->func,
|
|
391
|
+
auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, stack.ptr) \
|
|
392
|
+
: ForwardCall ## Suffix(func->func, stack.ptr)); \
|
|
463
393
|
return ret; \
|
|
464
394
|
})()
|
|
465
395
|
|
|
@@ -489,6 +419,7 @@ void CallData::Execute()
|
|
|
489
419
|
PERFORM_CALL(GG);
|
|
490
420
|
}
|
|
491
421
|
} break;
|
|
422
|
+
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
492
423
|
case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
|
|
493
424
|
case PrimitiveKind::Float64: { result.d = PERFORM_CALL(DDDD).d0; } break;
|
|
494
425
|
}
|
|
@@ -498,8 +429,9 @@ void CallData::Execute()
|
|
|
498
429
|
|
|
499
430
|
Napi::Value CallData::Complete()
|
|
500
431
|
{
|
|
501
|
-
for (const OutObject &
|
|
502
|
-
|
|
432
|
+
for (const OutObject &out: out_objects) {
|
|
433
|
+
Napi::Object obj = out.ref.Value().As<Napi::Object>();
|
|
434
|
+
PopObject(obj, out.ptr, out.type);
|
|
503
435
|
}
|
|
504
436
|
|
|
505
437
|
switch (func->ret.type->primitive) {
|
|
@@ -522,8 +454,8 @@ Napi::Value CallData::Complete()
|
|
|
522
454
|
return external;
|
|
523
455
|
} break;
|
|
524
456
|
case PrimitiveKind::Record: {
|
|
525
|
-
if (func->ret.vec_count) {
|
|
526
|
-
Napi::Object obj =
|
|
457
|
+
if (func->ret.vec_count) { // HFA
|
|
458
|
+
Napi::Object obj = PopObject((const uint8_t *)&result.buf, func->ret.type, 8);
|
|
527
459
|
return obj;
|
|
528
460
|
} else {
|
|
529
461
|
const uint8_t *ptr = return_ptr ? (const uint8_t *)return_ptr
|
|
@@ -533,6 +465,7 @@ Napi::Value CallData::Complete()
|
|
|
533
465
|
return obj;
|
|
534
466
|
}
|
|
535
467
|
} break;
|
|
468
|
+
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
536
469
|
case PrimitiveKind::Float32: return Napi::Number::New(env, (double)result.f);
|
|
537
470
|
case PrimitiveKind::Float64: return Napi::Number::New(env, result.d);
|
|
538
471
|
}
|
package/src/abi_x64_sysv.cc
CHANGED
|
@@ -98,13 +98,6 @@ static Size ClassifyType(const TypeInfo *type, Size offset, Span<RegisterClass>
|
|
|
98
98
|
classes[0] = MergeClasses(classes[0], RegisterClass::Integer);
|
|
99
99
|
return 1;
|
|
100
100
|
} break;
|
|
101
|
-
|
|
102
|
-
case PrimitiveKind::Float32:
|
|
103
|
-
case PrimitiveKind::Float64: {
|
|
104
|
-
classes[0] = MergeClasses(classes[0], RegisterClass::SSE);
|
|
105
|
-
return 1;
|
|
106
|
-
} break;
|
|
107
|
-
|
|
108
101
|
case PrimitiveKind::Record: {
|
|
109
102
|
if (type->size > 64) {
|
|
110
103
|
classes[0] = MergeClasses(classes[0], RegisterClass::Memory);
|
|
@@ -119,6 +112,27 @@ static Size ClassifyType(const TypeInfo *type, Size offset, Span<RegisterClass>
|
|
|
119
112
|
|
|
120
113
|
return (offset + 7) / 8;
|
|
121
114
|
} break;
|
|
115
|
+
case PrimitiveKind::Array: {
|
|
116
|
+
if (type->size > 64) {
|
|
117
|
+
classes[0] = MergeClasses(classes[0], RegisterClass::Memory);
|
|
118
|
+
return 1;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
Size len = type->size / type->ref->size;
|
|
122
|
+
|
|
123
|
+
for (Size i = 0; i < len; i++) {
|
|
124
|
+
Size start = offset / 8;
|
|
125
|
+
ClassifyType(type->ref, offset % 8, classes.Take(start, classes.len - start));
|
|
126
|
+
offset += type->ref->size;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return (offset + 7) / 8;
|
|
130
|
+
} break;
|
|
131
|
+
case PrimitiveKind::Float32:
|
|
132
|
+
case PrimitiveKind::Float64: {
|
|
133
|
+
classes[0] = MergeClasses(classes[0], RegisterClass::SSE);
|
|
134
|
+
return 1;
|
|
135
|
+
} break;
|
|
122
136
|
}
|
|
123
137
|
|
|
124
138
|
RG_UNREACHABLE();
|
|
@@ -308,8 +322,11 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
308
322
|
memset(ptr, 0, param.type->size);
|
|
309
323
|
}
|
|
310
324
|
if (param.directions & 2) {
|
|
311
|
-
OutObject out =
|
|
312
|
-
|
|
325
|
+
OutObject *out = out_objects.AppendDefault();
|
|
326
|
+
|
|
327
|
+
out->ref.Reset(obj, 1);
|
|
328
|
+
out->ptr = ptr;
|
|
329
|
+
out->type = param.type->ref;
|
|
313
330
|
}
|
|
314
331
|
} else if (IsNullOrUndefined(value)) {
|
|
315
332
|
ptr = nullptr;
|
|
@@ -367,6 +384,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
367
384
|
args_ptr += AlignLen(param.type->size, 8);
|
|
368
385
|
}
|
|
369
386
|
} break;
|
|
387
|
+
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
370
388
|
case PrimitiveKind::Float32: {
|
|
371
389
|
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
372
390
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
|
|
@@ -402,6 +420,9 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
402
420
|
}
|
|
403
421
|
}
|
|
404
422
|
|
|
423
|
+
stack = MakeSpan(mem->stack.end(), old_stack_mem.end() - mem->stack.end());
|
|
424
|
+
heap = MakeSpan(old_heap_mem.ptr, mem->heap.ptr - old_heap_mem.ptr);
|
|
425
|
+
|
|
405
426
|
return true;
|
|
406
427
|
}
|
|
407
428
|
|
|
@@ -409,8 +430,8 @@ void CallData::Execute()
|
|
|
409
430
|
{
|
|
410
431
|
#define PERFORM_CALL(Suffix) \
|
|
411
432
|
([&]() { \
|
|
412
|
-
auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func,
|
|
413
|
-
: ForwardCall ## Suffix(func->func,
|
|
433
|
+
auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, stack.ptr) \
|
|
434
|
+
: ForwardCall ## Suffix(func->func, stack.ptr)); \
|
|
414
435
|
return ret; \
|
|
415
436
|
})()
|
|
416
437
|
|
|
@@ -444,6 +465,7 @@ void CallData::Execute()
|
|
|
444
465
|
memcpy_safe(&result.buf, &ret, RG_SIZE(ret));
|
|
445
466
|
}
|
|
446
467
|
} break;
|
|
468
|
+
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
447
469
|
case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
|
|
448
470
|
case PrimitiveKind::Float64: { result.d = PERFORM_CALL(DG).xmm0; } break;
|
|
449
471
|
}
|
|
@@ -453,8 +475,9 @@ void CallData::Execute()
|
|
|
453
475
|
|
|
454
476
|
Napi::Value CallData::Complete()
|
|
455
477
|
{
|
|
456
|
-
for (const OutObject &
|
|
457
|
-
|
|
478
|
+
for (const OutObject &out: out_objects) {
|
|
479
|
+
Napi::Object obj = out.ref.Value().As<Napi::Object>();
|
|
480
|
+
PopObject(obj, out.ptr, out.type);
|
|
458
481
|
}
|
|
459
482
|
|
|
460
483
|
switch (func->ret.type->primitive) {
|
|
@@ -483,6 +506,7 @@ Napi::Value CallData::Complete()
|
|
|
483
506
|
Napi::Object obj = PopObject(ptr, func->ret.type);
|
|
484
507
|
return obj;
|
|
485
508
|
} break;
|
|
509
|
+
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
486
510
|
case PrimitiveKind::Float32: return Napi::Number::New(env, (double)result.f);
|
|
487
511
|
case PrimitiveKind::Float64: return Napi::Number::New(env, result.d);
|
|
488
512
|
}
|
package/src/abi_x64_win.cc
CHANGED
|
@@ -148,8 +148,11 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
148
148
|
memset(ptr, 0, param.type->size);
|
|
149
149
|
}
|
|
150
150
|
if (param.directions & 2) {
|
|
151
|
-
OutObject out =
|
|
152
|
-
|
|
151
|
+
OutObject *out = out_objects.AppendDefault();
|
|
152
|
+
|
|
153
|
+
out->ref.Reset(obj, 1);
|
|
154
|
+
out->ptr = ptr;
|
|
155
|
+
out->type = param.type->ref;
|
|
153
156
|
}
|
|
154
157
|
} else if (IsNullOrUndefined(value)) {
|
|
155
158
|
ptr = nullptr;
|
|
@@ -179,6 +182,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
179
182
|
if (!PushObject(obj, param.type, ptr))
|
|
180
183
|
return false;
|
|
181
184
|
} break;
|
|
185
|
+
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
182
186
|
case PrimitiveKind::Float32: {
|
|
183
187
|
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
184
188
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
|
|
@@ -200,6 +204,9 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
200
204
|
}
|
|
201
205
|
}
|
|
202
206
|
|
|
207
|
+
stack = MakeSpan(mem->stack.end(), old_stack_mem.end() - mem->stack.end());
|
|
208
|
+
heap = MakeSpan(old_heap_mem.ptr, mem->heap.ptr - old_heap_mem.ptr);
|
|
209
|
+
|
|
203
210
|
return true;
|
|
204
211
|
}
|
|
205
212
|
|
|
@@ -207,8 +214,8 @@ void CallData::Execute()
|
|
|
207
214
|
{
|
|
208
215
|
#define PERFORM_CALL(Suffix) \
|
|
209
216
|
([&]() { \
|
|
210
|
-
auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func,
|
|
211
|
-
: ForwardCall ## Suffix(func->func,
|
|
217
|
+
auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, stack.ptr) \
|
|
218
|
+
: ForwardCall ## Suffix(func->func, stack.ptr)); \
|
|
212
219
|
return ret; \
|
|
213
220
|
})()
|
|
214
221
|
|
|
@@ -227,6 +234,7 @@ void CallData::Execute()
|
|
|
227
234
|
case PrimitiveKind::String16:
|
|
228
235
|
case PrimitiveKind::Pointer:
|
|
229
236
|
case PrimitiveKind::Record: { result.u64 = PERFORM_CALL(G); } break;
|
|
237
|
+
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
230
238
|
case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
|
|
231
239
|
case PrimitiveKind::Float64: { result.d = PERFORM_CALL(D); } break;
|
|
232
240
|
}
|
|
@@ -236,8 +244,9 @@ void CallData::Execute()
|
|
|
236
244
|
|
|
237
245
|
Napi::Value CallData::Complete()
|
|
238
246
|
{
|
|
239
|
-
for (const OutObject &
|
|
240
|
-
|
|
247
|
+
for (const OutObject &out: out_objects) {
|
|
248
|
+
Napi::Object obj = out.ref.Value().As<Napi::Object>();
|
|
249
|
+
PopObject(obj, out.ptr, out.type);
|
|
241
250
|
}
|
|
242
251
|
|
|
243
252
|
switch (func->ret.type->primitive) {
|
|
@@ -266,6 +275,7 @@ Napi::Value CallData::Complete()
|
|
|
266
275
|
Napi::Object obj = PopObject(ptr, func->ret.type);
|
|
267
276
|
return obj;
|
|
268
277
|
} break;
|
|
278
|
+
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
269
279
|
case PrimitiveKind::Float32: return Napi::Number::New(env, (double)result.f);
|
|
270
280
|
case PrimitiveKind::Float64: return Napi::Number::New(env, result.d);
|
|
271
281
|
}
|
package/src/abi_x86.cc
CHANGED
|
@@ -192,8 +192,11 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
192
192
|
memset(ptr, 0, param.type->size);
|
|
193
193
|
}
|
|
194
194
|
if (param.directions & 2) {
|
|
195
|
-
OutObject out =
|
|
196
|
-
|
|
195
|
+
OutObject *out = out_objects.AppendDefault();
|
|
196
|
+
|
|
197
|
+
out->ref.Reset(obj, 1);
|
|
198
|
+
out->ptr = ptr;
|
|
199
|
+
out->type = param.type->ref;
|
|
197
200
|
}
|
|
198
201
|
} else if (IsNullOrUndefined(value)) {
|
|
199
202
|
ptr = nullptr;
|
|
@@ -223,6 +226,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
223
226
|
args_ptr = (uint32_t *)AlignUp(ptr + param.type->size, 4);
|
|
224
227
|
}
|
|
225
228
|
} break;
|
|
229
|
+
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
226
230
|
case PrimitiveKind::Float32: {
|
|
227
231
|
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
228
232
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
|
|
@@ -245,6 +249,9 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
245
249
|
}
|
|
246
250
|
}
|
|
247
251
|
|
|
252
|
+
stack = MakeSpan(mem->stack.end(), old_stack_mem.end() - mem->stack.end());
|
|
253
|
+
heap = MakeSpan(old_heap_mem.ptr, mem->heap.ptr - old_heap_mem.ptr);
|
|
254
|
+
|
|
248
255
|
return true;
|
|
249
256
|
}
|
|
250
257
|
|
|
@@ -252,8 +259,8 @@ void CallData::Execute()
|
|
|
252
259
|
{
|
|
253
260
|
#define PERFORM_CALL(Suffix) \
|
|
254
261
|
([&]() { \
|
|
255
|
-
auto ret = (func->convention == CallConvention::Fastcall ? ForwardCallR ## Suffix(func->func,
|
|
256
|
-
: ForwardCall ## Suffix(func->func,
|
|
262
|
+
auto ret = (func->convention == CallConvention::Fastcall ? ForwardCallR ## Suffix(func->func, stack.ptr) \
|
|
263
|
+
: ForwardCall ## Suffix(func->func, stack.ptr)); \
|
|
257
264
|
return ret; \
|
|
258
265
|
})()
|
|
259
266
|
|
|
@@ -273,6 +280,7 @@ void CallData::Execute()
|
|
|
273
280
|
case PrimitiveKind::String16:
|
|
274
281
|
case PrimitiveKind::Pointer:
|
|
275
282
|
case PrimitiveKind::Record: { result.u64 = PERFORM_CALL(G); } break;
|
|
283
|
+
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
276
284
|
case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
|
|
277
285
|
case PrimitiveKind::Float64: { result.d = PERFORM_CALL(D); } break;
|
|
278
286
|
}
|
|
@@ -282,8 +290,9 @@ void CallData::Execute()
|
|
|
282
290
|
|
|
283
291
|
Napi::Value CallData::Complete()
|
|
284
292
|
{
|
|
285
|
-
for (const OutObject &
|
|
286
|
-
|
|
293
|
+
for (const OutObject &out: out_objects) {
|
|
294
|
+
Napi::Object obj = out.ref.Value().As<Napi::Object>();
|
|
295
|
+
PopObject(obj, out.ptr, out.type);
|
|
287
296
|
}
|
|
288
297
|
|
|
289
298
|
switch (func->ret.type->primitive) {
|
|
@@ -312,6 +321,7 @@ Napi::Value CallData::Complete()
|
|
|
312
321
|
Napi::Object obj = PopObject(ptr, func->ret.type);
|
|
313
322
|
return obj;
|
|
314
323
|
} break;
|
|
324
|
+
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
315
325
|
case PrimitiveKind::Float32: return Napi::Number::New(env, (double)result.f);
|
|
316
326
|
case PrimitiveKind::Float64: return Napi::Number::New(env, result.d);
|
|
317
327
|
}
|