koffi 2.1.5 → 2.2.1
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/ChangeLog.md +21 -1
- package/doc/Makefile +1 -1
- package/doc/callbacks.md +175 -0
- package/doc/changes.md +2 -3
- package/doc/conf.py +29 -6
- package/doc/functions.md +39 -124
- package/doc/index.rst +1 -0
- package/doc/make.bat +1 -1
- package/doc/types.md +36 -9
- package/package.json +2 -2
- package/src/core/libcc/libcc.cc +89 -27
- package/src/core/libcc/libcc.hh +74 -39
- package/src/koffi/build/2.2.1/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_win32_x64.tar.gz +0 -0
- package/src/koffi/qemu/qemu.js +3 -1
- package/src/koffi/src/abi_arm32.cc +26 -23
- package/src/koffi/src/abi_arm64.cc +25 -22
- package/src/koffi/src/abi_riscv64.cc +21 -18
- package/src/koffi/src/abi_x64_sysv.cc +20 -17
- package/src/koffi/src/abi_x64_win.cc +19 -16
- package/src/koffi/src/abi_x86.cc +23 -20
- package/src/koffi/src/call.cc +222 -607
- package/src/koffi/src/call.hh +7 -11
- package/src/koffi/src/ffi.cc +229 -29
- package/src/koffi/src/ffi.hh +6 -2
- package/src/koffi/src/parser.cc +3 -9
- package/src/koffi/src/util.cc +546 -8
- package/src/koffi/src/util.hh +8 -2
- package/src/koffi/test/CMakeLists.txt +3 -3
- package/src/koffi/test/callbacks.js +89 -0
- package/src/koffi/test/misc.c +78 -0
- package/src/koffi/test/raylib.js +2 -2
- package/src/koffi/test/sqlite.js +1 -1
- package/src/koffi/test/sync.js +28 -6
- package/vendor/brotli/c/common/platform.h +2 -0
- package/vendor/sqlite3mc/sqlite3.c +243532 -0
- package/vendor/sqlite3mc/sqlite3.h +12887 -0
- package/src/koffi/build/2.1.5/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.1.5/koffi_win32_x64.tar.gz +0 -0
package/src/koffi/src/call.cc
CHANGED
|
@@ -46,40 +46,71 @@ CallData::~CallData()
|
|
|
46
46
|
if (!--mem->depth && mem->temporary) {
|
|
47
47
|
delete mem;
|
|
48
48
|
}
|
|
49
|
+
|
|
50
|
+
instance = nullptr;
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
bool CallData::PushString(Napi::Value value, const char **out_str)
|
|
53
|
+
bool CallData::PushString(Napi::Value value, int directions, const char **out_str)
|
|
52
54
|
{
|
|
53
55
|
if (value.IsString()) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
if (RG_UNLIKELY(directions & 2)) {
|
|
57
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
57
60
|
|
|
58
|
-
|
|
59
|
-
|
|
61
|
+
PushStringValue(value, out_str);
|
|
62
|
+
return true;
|
|
63
|
+
} else if (IsNullOrUndefined(value)) {
|
|
64
|
+
*out_str = nullptr;
|
|
65
|
+
return true;
|
|
66
|
+
} else if (value.IsArray()) {
|
|
67
|
+
Napi::Array array = value.As<Napi::Array>();
|
|
60
68
|
|
|
61
|
-
|
|
62
|
-
|
|
69
|
+
if (RG_UNLIKELY(!(directions & 2))) {
|
|
70
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
if (RG_UNLIKELY(array.Length() != 1)) {
|
|
74
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected [string]", GetValueType(instance, value));
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
63
77
|
|
|
64
|
-
|
|
78
|
+
value = array[0u];
|
|
65
79
|
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
80
|
+
if (RG_UNLIKELY(!value.IsString())) {
|
|
81
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected [string]", GetValueType(instance, array[0u]));
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
Size len = PushStringValue(value, out_str);
|
|
86
|
+
if (RG_UNLIKELY(len < 0))
|
|
87
|
+
return false;
|
|
88
|
+
|
|
89
|
+
// Create array type
|
|
90
|
+
TypeInfo *type;
|
|
91
|
+
{
|
|
92
|
+
type = AllocateOne<TypeInfo>(&call_alloc, (int)AllocFlag::Zero);
|
|
93
|
+
|
|
94
|
+
type->name = "<temporary>";
|
|
72
95
|
|
|
73
|
-
|
|
96
|
+
type->primitive = PrimitiveKind::Array;
|
|
97
|
+
type->align = 1;
|
|
98
|
+
type->size = (int32_t)len;
|
|
99
|
+
type->ref.type = instance->char_type;
|
|
100
|
+
type->hint = TypeInfo::ArrayHint::String;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Prepare output argument
|
|
104
|
+
{
|
|
105
|
+
OutArgument *out = out_arguments.AppendDefault();
|
|
74
106
|
|
|
75
|
-
status =
|
|
107
|
+
napi_status status = napi_create_reference(env, array, 1, &out->ref);
|
|
76
108
|
RG_ASSERT(status == napi_ok);
|
|
109
|
+
|
|
110
|
+
out->ptr = (const uint8_t *)*out_str;
|
|
111
|
+
out->type = type;
|
|
77
112
|
}
|
|
78
113
|
|
|
79
|
-
*out_str = buf.ptr;
|
|
80
|
-
return true;
|
|
81
|
-
} else if (IsNullOrUndefined(value)) {
|
|
82
|
-
*out_str = nullptr;
|
|
83
114
|
return true;
|
|
84
115
|
} else {
|
|
85
116
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
|
|
@@ -87,38 +118,100 @@ bool CallData::PushString(Napi::Value value, const char **out_str)
|
|
|
87
118
|
}
|
|
88
119
|
}
|
|
89
120
|
|
|
90
|
-
|
|
121
|
+
Size CallData::PushStringValue(Napi::Value value, const char **out_str)
|
|
91
122
|
{
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
napi_status status;
|
|
123
|
+
Span<char> buf;
|
|
124
|
+
size_t len = 0;
|
|
125
|
+
napi_status status;
|
|
96
126
|
|
|
97
|
-
|
|
98
|
-
|
|
127
|
+
buf.ptr = (char *)mem->heap.ptr;
|
|
128
|
+
buf.len = std::max((Size)0, mem->heap.len - Kibibytes(32));
|
|
99
129
|
|
|
100
|
-
|
|
130
|
+
status = napi_get_value_string_utf8(env, value, buf.ptr, (size_t)buf.len, &len);
|
|
131
|
+
RG_ASSERT(status == napi_ok);
|
|
132
|
+
|
|
133
|
+
len++;
|
|
134
|
+
|
|
135
|
+
if (RG_LIKELY(len < (size_t)buf.len)) {
|
|
136
|
+
mem->heap.ptr += (Size)len;
|
|
137
|
+
mem->heap.len -= (Size)len;
|
|
138
|
+
} else {
|
|
139
|
+
status = napi_get_value_string_utf8(env, value, nullptr, 0, &len);
|
|
101
140
|
RG_ASSERT(status == napi_ok);
|
|
102
141
|
|
|
103
|
-
len
|
|
142
|
+
buf = AllocateSpan<char>(&call_alloc, (Size)len + 1);
|
|
104
143
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
mem->heap.len -= (Size)len * 2;
|
|
108
|
-
} else {
|
|
109
|
-
status = napi_get_value_string_utf16(env, value, nullptr, 0, &len);
|
|
110
|
-
RG_ASSERT(status == napi_ok);
|
|
144
|
+
status = napi_get_value_string_utf8(env, value, buf.ptr, (size_t)buf.len, &len);
|
|
145
|
+
RG_ASSERT(status == napi_ok);
|
|
111
146
|
|
|
112
|
-
|
|
147
|
+
len++;
|
|
148
|
+
}
|
|
113
149
|
|
|
114
|
-
|
|
115
|
-
|
|
150
|
+
*out_str = buf.ptr;
|
|
151
|
+
return (Size)len;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
bool CallData::PushString16(Napi::Value value, int directions, const char16_t **out_str16)
|
|
155
|
+
{
|
|
156
|
+
if (value.IsString()) {
|
|
157
|
+
if (RG_UNLIKELY(directions & 2)) {
|
|
158
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
|
|
159
|
+
return false;
|
|
116
160
|
}
|
|
117
161
|
|
|
118
|
-
|
|
162
|
+
PushString16Value(value, out_str16);
|
|
119
163
|
return true;
|
|
120
164
|
} else if (IsNullOrUndefined(value)) {
|
|
121
165
|
*out_str16 = nullptr;
|
|
166
|
+
return true;
|
|
167
|
+
} else if (value.IsArray()) {
|
|
168
|
+
Napi::Array array = value.As<Napi::Array>();
|
|
169
|
+
|
|
170
|
+
if (RG_UNLIKELY(!(directions & 2))) {
|
|
171
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
if (RG_UNLIKELY(array.Length() != 1)) {
|
|
175
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected [string]", GetValueType(instance, value));
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
value = array[0u];
|
|
180
|
+
|
|
181
|
+
if (RG_UNLIKELY(!value.IsString())) {
|
|
182
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected [string]", GetValueType(instance, array[0u]));
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
Size len = PushString16Value(value, out_str16);
|
|
187
|
+
if (RG_UNLIKELY(len < 0))
|
|
188
|
+
return false;
|
|
189
|
+
|
|
190
|
+
// Create array type
|
|
191
|
+
TypeInfo *type;
|
|
192
|
+
{
|
|
193
|
+
type = AllocateOne<TypeInfo>(&call_alloc, (int)AllocFlag::Zero);
|
|
194
|
+
|
|
195
|
+
type->name = "<temporary>";
|
|
196
|
+
|
|
197
|
+
type->primitive = PrimitiveKind::Array;
|
|
198
|
+
type->align = 1;
|
|
199
|
+
type->size = (int32_t)(len * 2);
|
|
200
|
+
type->ref.type = instance->char16_type;
|
|
201
|
+
type->hint = TypeInfo::ArrayHint::String;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Prepare output argument
|
|
205
|
+
{
|
|
206
|
+
OutArgument *out = out_arguments.AppendDefault();
|
|
207
|
+
|
|
208
|
+
napi_status status = napi_create_reference(env, array, 1, &out->ref);
|
|
209
|
+
RG_ASSERT(status == napi_ok);
|
|
210
|
+
|
|
211
|
+
out->ptr = (const uint8_t *)*out_str16;
|
|
212
|
+
out->type = type;
|
|
213
|
+
}
|
|
214
|
+
|
|
122
215
|
return true;
|
|
123
216
|
} else {
|
|
124
217
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
|
|
@@ -126,6 +219,39 @@ bool CallData::PushString16(Napi::Value value, const char16_t **out_str16)
|
|
|
126
219
|
}
|
|
127
220
|
}
|
|
128
221
|
|
|
222
|
+
Size CallData::PushString16Value(Napi::Value value, const char16_t **out_str16)
|
|
223
|
+
{
|
|
224
|
+
Span<char16_t> buf;
|
|
225
|
+
size_t len = 0;
|
|
226
|
+
napi_status status;
|
|
227
|
+
|
|
228
|
+
buf.ptr = (char16_t *)mem->heap.ptr;
|
|
229
|
+
buf.len = std::max((Size)0, mem->heap.len - Kibibytes(32)) / 2;
|
|
230
|
+
|
|
231
|
+
status = napi_get_value_string_utf16(env, value, buf.ptr, (size_t)buf.len, &len);
|
|
232
|
+
RG_ASSERT(status == napi_ok);
|
|
233
|
+
|
|
234
|
+
len++;
|
|
235
|
+
|
|
236
|
+
if (RG_LIKELY(len < (size_t)buf.len)) {
|
|
237
|
+
mem->heap.ptr += (Size)len * 2;
|
|
238
|
+
mem->heap.len -= (Size)len * 2;
|
|
239
|
+
} else {
|
|
240
|
+
status = napi_get_value_string_utf16(env, value, nullptr, 0, &len);
|
|
241
|
+
RG_ASSERT(status == napi_ok);
|
|
242
|
+
|
|
243
|
+
buf = AllocateSpan<char16_t>(&call_alloc, ((Size)len + 1) * 2);
|
|
244
|
+
|
|
245
|
+
status = napi_get_value_string_utf16(env, value, buf.ptr, (size_t)buf.len, &len);
|
|
246
|
+
RG_ASSERT(status == napi_ok);
|
|
247
|
+
|
|
248
|
+
len++;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
*out_str16 = buf.ptr;
|
|
252
|
+
return (Size)len;
|
|
253
|
+
}
|
|
254
|
+
|
|
129
255
|
bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origin, int16_t realign)
|
|
130
256
|
{
|
|
131
257
|
RG_ASSERT(IsObject(obj));
|
|
@@ -161,7 +287,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
161
287
|
return false;
|
|
162
288
|
}
|
|
163
289
|
|
|
164
|
-
int8_t v =
|
|
290
|
+
int8_t v = GetNumber<int8_t>(value);
|
|
165
291
|
*(int8_t *)dest = v;
|
|
166
292
|
} break;
|
|
167
293
|
case PrimitiveKind::UInt8: {
|
|
@@ -170,7 +296,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
170
296
|
return false;
|
|
171
297
|
}
|
|
172
298
|
|
|
173
|
-
uint8_t v =
|
|
299
|
+
uint8_t v = GetNumber<uint8_t>(value);
|
|
174
300
|
*(uint8_t *)dest = v;
|
|
175
301
|
} break;
|
|
176
302
|
case PrimitiveKind::Int16: {
|
|
@@ -179,7 +305,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
179
305
|
return false;
|
|
180
306
|
}
|
|
181
307
|
|
|
182
|
-
int16_t v =
|
|
308
|
+
int16_t v = GetNumber<int16_t>(value);
|
|
183
309
|
*(int16_t *)dest = v;
|
|
184
310
|
} break;
|
|
185
311
|
case PrimitiveKind::Int16S: {
|
|
@@ -188,7 +314,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
188
314
|
return false;
|
|
189
315
|
}
|
|
190
316
|
|
|
191
|
-
int16_t v =
|
|
317
|
+
int16_t v = GetNumber<int16_t>(value);
|
|
192
318
|
*(int16_t *)dest = ReverseBytes(v);
|
|
193
319
|
} break;
|
|
194
320
|
case PrimitiveKind::UInt16: {
|
|
@@ -197,7 +323,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
197
323
|
return false;
|
|
198
324
|
}
|
|
199
325
|
|
|
200
|
-
uint16_t v =
|
|
326
|
+
uint16_t v = GetNumber<uint16_t>(value);
|
|
201
327
|
*(uint16_t *)dest = v;
|
|
202
328
|
} break;
|
|
203
329
|
case PrimitiveKind::UInt16S: {
|
|
@@ -206,7 +332,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
206
332
|
return false;
|
|
207
333
|
}
|
|
208
334
|
|
|
209
|
-
uint16_t v =
|
|
335
|
+
uint16_t v = GetNumber<uint16_t>(value);
|
|
210
336
|
*(uint16_t *)dest = ReverseBytes(v);
|
|
211
337
|
} break;
|
|
212
338
|
case PrimitiveKind::Int32: {
|
|
@@ -215,7 +341,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
215
341
|
return false;
|
|
216
342
|
}
|
|
217
343
|
|
|
218
|
-
int32_t v =
|
|
344
|
+
int32_t v = GetNumber<int32_t>(value);
|
|
219
345
|
*(int32_t *)dest = v;
|
|
220
346
|
} break;
|
|
221
347
|
case PrimitiveKind::Int32S: {
|
|
@@ -224,7 +350,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
224
350
|
return false;
|
|
225
351
|
}
|
|
226
352
|
|
|
227
|
-
int32_t v =
|
|
353
|
+
int32_t v = GetNumber<int32_t>(value);
|
|
228
354
|
*(int32_t *)dest = ReverseBytes(v);
|
|
229
355
|
} break;
|
|
230
356
|
case PrimitiveKind::UInt32: {
|
|
@@ -233,7 +359,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
233
359
|
return false;
|
|
234
360
|
}
|
|
235
361
|
|
|
236
|
-
uint32_t v =
|
|
362
|
+
uint32_t v = GetNumber<uint32_t>(value);
|
|
237
363
|
*(uint32_t *)dest = v;
|
|
238
364
|
} break;
|
|
239
365
|
case PrimitiveKind::UInt32S: {
|
|
@@ -242,7 +368,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
242
368
|
return false;
|
|
243
369
|
}
|
|
244
370
|
|
|
245
|
-
uint32_t v =
|
|
371
|
+
uint32_t v = GetNumber<uint32_t>(value);
|
|
246
372
|
*(uint32_t *)dest = ReverseBytes(v);
|
|
247
373
|
} break;
|
|
248
374
|
case PrimitiveKind::Int64: {
|
|
@@ -251,7 +377,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
251
377
|
return false;
|
|
252
378
|
}
|
|
253
379
|
|
|
254
|
-
int64_t v =
|
|
380
|
+
int64_t v = GetNumber<int64_t>(value);
|
|
255
381
|
*(int64_t *)dest = v;
|
|
256
382
|
} break;
|
|
257
383
|
case PrimitiveKind::Int64S: {
|
|
@@ -260,7 +386,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
260
386
|
return false;
|
|
261
387
|
}
|
|
262
388
|
|
|
263
|
-
int64_t v =
|
|
389
|
+
int64_t v = GetNumber<int64_t>(value);
|
|
264
390
|
*(int64_t *)dest = ReverseBytes(v);
|
|
265
391
|
} break;
|
|
266
392
|
case PrimitiveKind::UInt64: {
|
|
@@ -269,7 +395,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
269
395
|
return false;
|
|
270
396
|
}
|
|
271
397
|
|
|
272
|
-
uint64_t v =
|
|
398
|
+
uint64_t v = GetNumber<uint64_t>(value);
|
|
273
399
|
*(uint64_t *)dest = v;
|
|
274
400
|
} break;
|
|
275
401
|
case PrimitiveKind::UInt64S: {
|
|
@@ -278,19 +404,19 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
278
404
|
return false;
|
|
279
405
|
}
|
|
280
406
|
|
|
281
|
-
uint64_t v =
|
|
407
|
+
uint64_t v = GetNumber<uint64_t>(value);
|
|
282
408
|
*(uint64_t *)dest = ReverseBytes(v);
|
|
283
409
|
} break;
|
|
284
410
|
case PrimitiveKind::String: {
|
|
285
411
|
const char *str;
|
|
286
|
-
if (RG_UNLIKELY(!PushString(value, &str)))
|
|
412
|
+
if (RG_UNLIKELY(!PushString(value, 1, &str)))
|
|
287
413
|
return false;
|
|
288
414
|
|
|
289
415
|
*(const char **)dest = str;
|
|
290
416
|
} break;
|
|
291
417
|
case PrimitiveKind::String16: {
|
|
292
418
|
const char16_t *str16;
|
|
293
|
-
if (RG_UNLIKELY(!PushString16(value, &str16)))
|
|
419
|
+
if (RG_UNLIKELY(!PushString16(value, 1, &str16)))
|
|
294
420
|
return false;
|
|
295
421
|
|
|
296
422
|
*(const char16_t **)dest = str16;
|
|
@@ -317,13 +443,13 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
317
443
|
Napi::Array array = value.As<Napi::Array>();
|
|
318
444
|
Size len = (Size)member.type->size / member.type->ref.type->size;
|
|
319
445
|
|
|
320
|
-
if (!PushNormalArray(array, len, member.type
|
|
446
|
+
if (!PushNormalArray(array, len, member.type, dest, realign))
|
|
321
447
|
return false;
|
|
322
448
|
} else if (value.IsTypedArray()) {
|
|
323
449
|
Napi::TypedArray array = value.As<Napi::TypedArray>();
|
|
324
450
|
Size len = (Size)member.type->size / member.type->ref.type->size;
|
|
325
451
|
|
|
326
|
-
if (!PushTypedArray(array, len, member.type
|
|
452
|
+
if (!PushTypedArray(array, len, member.type, dest, realign))
|
|
327
453
|
return false;
|
|
328
454
|
} else if (value.IsString() && !realign) {
|
|
329
455
|
if (!PushStringArray(value, member.type, dest))
|
|
@@ -339,7 +465,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
339
465
|
return false;
|
|
340
466
|
}
|
|
341
467
|
|
|
342
|
-
float f =
|
|
468
|
+
float f = GetNumber<float>(value);
|
|
343
469
|
*(float *)dest = f;
|
|
344
470
|
} break;
|
|
345
471
|
case PrimitiveKind::Float64: {
|
|
@@ -348,7 +474,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
348
474
|
return false;
|
|
349
475
|
}
|
|
350
476
|
|
|
351
|
-
double d =
|
|
477
|
+
double d = GetNumber<double>(value);
|
|
352
478
|
*(double *)dest = d;
|
|
353
479
|
} break;
|
|
354
480
|
case PrimitiveKind::Callback: {
|
|
@@ -380,10 +506,12 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
380
506
|
return true;
|
|
381
507
|
}
|
|
382
508
|
|
|
383
|
-
bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *
|
|
509
|
+
bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *type, uint8_t *origin, int16_t realign)
|
|
384
510
|
{
|
|
385
511
|
RG_ASSERT(array.IsArray());
|
|
386
512
|
|
|
513
|
+
const TypeInfo *ref = type->ref.type;
|
|
514
|
+
|
|
387
515
|
if (RG_UNLIKELY(array.Length() != (size_t)len)) {
|
|
388
516
|
ThrowError<Napi::Error>(env, "Expected array of length %1, got %2", len, array.Length());
|
|
389
517
|
return false;
|
|
@@ -413,7 +541,10 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
|
|
|
413
541
|
} while (false)
|
|
414
542
|
|
|
415
543
|
switch (ref->primitive) {
|
|
416
|
-
case PrimitiveKind::Void: {
|
|
544
|
+
case PrimitiveKind::Void: {
|
|
545
|
+
ThrowError<Napi::TypeError>(env, "Ambigous parameter type %1, use koffi.as(value, type)", type->name); \
|
|
546
|
+
return false;
|
|
547
|
+
} break;
|
|
417
548
|
|
|
418
549
|
case PrimitiveKind::Bool: {
|
|
419
550
|
PUSH_ARRAY(value.IsBoolean(), "boolean", {
|
|
@@ -423,92 +554,92 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
|
|
|
423
554
|
} break;
|
|
424
555
|
case PrimitiveKind::Int8: {
|
|
425
556
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
426
|
-
int8_t v =
|
|
557
|
+
int8_t v = GetNumber<int8_t>(value);
|
|
427
558
|
*(int8_t *)dest = v;
|
|
428
559
|
});
|
|
429
560
|
} break;
|
|
430
561
|
case PrimitiveKind::UInt8: {
|
|
431
562
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
432
|
-
uint8_t v =
|
|
563
|
+
uint8_t v = GetNumber<uint8_t>(value);
|
|
433
564
|
*(uint8_t *)dest = v;
|
|
434
565
|
});
|
|
435
566
|
} break;
|
|
436
567
|
case PrimitiveKind::Int16: {
|
|
437
568
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
438
|
-
int16_t v =
|
|
569
|
+
int16_t v = GetNumber<int16_t>(value);
|
|
439
570
|
*(int16_t *)dest = v;
|
|
440
571
|
});
|
|
441
572
|
} break;
|
|
442
573
|
case PrimitiveKind::Int16S: {
|
|
443
574
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
444
|
-
int16_t v =
|
|
575
|
+
int16_t v = GetNumber<int16_t>(value);
|
|
445
576
|
*(int16_t *)dest = ReverseBytes(v);
|
|
446
577
|
});
|
|
447
578
|
} break;
|
|
448
579
|
case PrimitiveKind::UInt16: {
|
|
449
580
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
450
|
-
uint16_t v =
|
|
581
|
+
uint16_t v = GetNumber<uint16_t>(value);
|
|
451
582
|
*(uint16_t *)dest = v;
|
|
452
583
|
});
|
|
453
584
|
} break;
|
|
454
585
|
case PrimitiveKind::UInt16S: {
|
|
455
586
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
456
|
-
uint16_t v =
|
|
587
|
+
uint16_t v = GetNumber<uint16_t>(value);
|
|
457
588
|
*(uint16_t *)dest = ReverseBytes(v);
|
|
458
589
|
});
|
|
459
590
|
} break;
|
|
460
591
|
case PrimitiveKind::Int32: {
|
|
461
592
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
462
|
-
int32_t v =
|
|
593
|
+
int32_t v = GetNumber<int32_t>(value);
|
|
463
594
|
*(int32_t *)dest = v;
|
|
464
595
|
});
|
|
465
596
|
} break;
|
|
466
597
|
case PrimitiveKind::Int32S: {
|
|
467
598
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
468
|
-
int32_t v =
|
|
599
|
+
int32_t v = GetNumber<int32_t>(value);
|
|
469
600
|
*(int32_t *)dest = ReverseBytes(v);
|
|
470
601
|
});
|
|
471
602
|
} break;
|
|
472
603
|
case PrimitiveKind::UInt32: {
|
|
473
604
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
474
|
-
uint32_t v =
|
|
605
|
+
uint32_t v = GetNumber<uint32_t>(value);
|
|
475
606
|
*(uint32_t *)dest = v;
|
|
476
607
|
});
|
|
477
608
|
} break;
|
|
478
609
|
case PrimitiveKind::UInt32S: {
|
|
479
610
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
480
|
-
uint32_t v =
|
|
611
|
+
uint32_t v = GetNumber<uint32_t>(value);
|
|
481
612
|
*(uint32_t *)dest = ReverseBytes(v);
|
|
482
613
|
});
|
|
483
614
|
} break;
|
|
484
615
|
case PrimitiveKind::Int64: {
|
|
485
616
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
486
|
-
int64_t v =
|
|
617
|
+
int64_t v = GetNumber<int64_t>(value);
|
|
487
618
|
*(int64_t *)dest = v;
|
|
488
619
|
});
|
|
489
620
|
} break;
|
|
490
621
|
case PrimitiveKind::Int64S: {
|
|
491
622
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
492
|
-
int64_t v =
|
|
623
|
+
int64_t v = GetNumber<int64_t>(value);
|
|
493
624
|
*(int64_t *)dest = ReverseBytes(v);
|
|
494
625
|
});
|
|
495
626
|
} break;
|
|
496
627
|
case PrimitiveKind::UInt64: {
|
|
497
628
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
498
|
-
uint64_t v =
|
|
629
|
+
uint64_t v = GetNumber<uint64_t>(value);
|
|
499
630
|
*(uint64_t *)dest = v;
|
|
500
631
|
});
|
|
501
632
|
} break;
|
|
502
633
|
case PrimitiveKind::UInt64S: {
|
|
503
634
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
504
|
-
uint64_t v =
|
|
635
|
+
uint64_t v = GetNumber<uint64_t>(value);
|
|
505
636
|
*(uint64_t *)dest = ReverseBytes(v);
|
|
506
637
|
});
|
|
507
638
|
} break;
|
|
508
639
|
case PrimitiveKind::String: {
|
|
509
640
|
PUSH_ARRAY(true, "string", {
|
|
510
641
|
const char *str;
|
|
511
|
-
if (RG_UNLIKELY(!PushString(value, &str)))
|
|
642
|
+
if (RG_UNLIKELY(!PushString(value, 1, &str)))
|
|
512
643
|
return false;
|
|
513
644
|
|
|
514
645
|
*(const char **)dest = str;
|
|
@@ -517,7 +648,7 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
|
|
|
517
648
|
case PrimitiveKind::String16: {
|
|
518
649
|
PUSH_ARRAY(true, "string", {
|
|
519
650
|
const char16_t *str16;
|
|
520
|
-
if (RG_UNLIKELY(!PushString16(value, &str16)))
|
|
651
|
+
if (RG_UNLIKELY(!PushString16(value, 1, &str16)))
|
|
521
652
|
return false;
|
|
522
653
|
|
|
523
654
|
*(const char16_t **)dest = str16;
|
|
@@ -552,13 +683,13 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
|
|
|
552
683
|
Napi::Array array2 = value.As<Napi::Array>();
|
|
553
684
|
Size len2 = (Size)ref->size / ref->ref.type->size;
|
|
554
685
|
|
|
555
|
-
if (!PushNormalArray(array2, len2, ref
|
|
686
|
+
if (!PushNormalArray(array2, len2, ref, dest, realign))
|
|
556
687
|
return false;
|
|
557
688
|
} else if (value.IsTypedArray()) {
|
|
558
689
|
Napi::TypedArray array2 = value.As<Napi::TypedArray>();
|
|
559
690
|
Size len2 = (Size)ref->size / ref->ref.type->size;
|
|
560
691
|
|
|
561
|
-
if (!PushTypedArray(array2, len2, ref
|
|
692
|
+
if (!PushTypedArray(array2, len2, ref, dest, realign))
|
|
562
693
|
return false;
|
|
563
694
|
} else if (value.IsString() && !realign) {
|
|
564
695
|
if (!PushStringArray(value, ref, dest))
|
|
@@ -573,13 +704,13 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
|
|
|
573
704
|
} break;
|
|
574
705
|
case PrimitiveKind::Float32: {
|
|
575
706
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
576
|
-
float f =
|
|
707
|
+
float f = GetNumber<float>(value);
|
|
577
708
|
*(float *)dest = f;
|
|
578
709
|
});
|
|
579
710
|
} break;
|
|
580
711
|
case PrimitiveKind::Float64: {
|
|
581
712
|
PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
|
|
582
|
-
double d =
|
|
713
|
+
double d = GetNumber<double>(value);
|
|
583
714
|
*(double *)dest = d;
|
|
584
715
|
});
|
|
585
716
|
} break;
|
|
@@ -624,10 +755,12 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
|
|
|
624
755
|
return true;
|
|
625
756
|
}
|
|
626
757
|
|
|
627
|
-
bool CallData::PushTypedArray(Napi::TypedArray array, Size len, const TypeInfo *
|
|
758
|
+
bool CallData::PushTypedArray(Napi::TypedArray array, Size len, const TypeInfo *type, uint8_t *origin, int16_t realign)
|
|
628
759
|
{
|
|
629
760
|
RG_ASSERT(array.IsTypedArray());
|
|
630
761
|
|
|
762
|
+
const TypeInfo *ref = type->ref.type;
|
|
763
|
+
|
|
631
764
|
if (RG_UNLIKELY(array.ElementLength() != (size_t)len)) {
|
|
632
765
|
ThrowError<Napi::Error>(env, "Expected array of length %1, got %2", len, array.ElementLength());
|
|
633
766
|
return false;
|
|
@@ -732,7 +865,7 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
|
|
|
732
865
|
ptr = AllocHeap(size, 16);
|
|
733
866
|
|
|
734
867
|
if (directions & 1) {
|
|
735
|
-
if (!PushNormalArray(array, len, type
|
|
868
|
+
if (!PushNormalArray(array, len, type, ptr))
|
|
736
869
|
return false;
|
|
737
870
|
} else {
|
|
738
871
|
memset(ptr, 0, size);
|
|
@@ -746,7 +879,7 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
|
|
|
746
879
|
ptr = AllocHeap(size, 16);
|
|
747
880
|
|
|
748
881
|
if (directions & 1) {
|
|
749
|
-
if (!PushTypedArray(array, len, type
|
|
882
|
+
if (!PushTypedArray(array, len, type, ptr))
|
|
750
883
|
return false;
|
|
751
884
|
} else {
|
|
752
885
|
if (RG_UNLIKELY(array.TypedArrayType() != GetTypedArrayType(type->ref.type) &&
|
|
@@ -813,13 +946,13 @@ void CallData::PopOutArguments()
|
|
|
813
946
|
|
|
814
947
|
if (value.IsArray()) {
|
|
815
948
|
Napi::Array array(env, value);
|
|
816
|
-
|
|
949
|
+
DecodeNormalArray(array, out.ptr, out.type);
|
|
817
950
|
} else if (value.IsTypedArray()) {
|
|
818
951
|
Napi::TypedArray array(env, value);
|
|
819
|
-
|
|
952
|
+
DecodeTypedArray(array, out.ptr, out.type);
|
|
820
953
|
} else {
|
|
821
954
|
Napi::Object obj(env, value);
|
|
822
|
-
|
|
955
|
+
DecodeObject(obj, out.ptr, out.type);
|
|
823
956
|
}
|
|
824
957
|
|
|
825
958
|
if (out.type->dispose) {
|
|
@@ -845,531 +978,13 @@ void *CallData::ReserveTrampoline(const FunctionInfo *proto, Napi::Function func
|
|
|
845
978
|
|
|
846
979
|
trampoline->proto = proto;
|
|
847
980
|
trampoline->func.Reset(func, 1);
|
|
981
|
+
trampoline->recv.Reset();
|
|
848
982
|
trampoline->generation = (int32_t)mem->generation;
|
|
849
983
|
|
|
850
984
|
void *ptr = GetTrampoline(idx, proto);
|
|
851
985
|
return ptr;
|
|
852
986
|
}
|
|
853
987
|
|
|
854
|
-
void CallData::PopObject(Napi::Object obj, const uint8_t *origin, const TypeInfo *type, int16_t realign)
|
|
855
|
-
{
|
|
856
|
-
Napi::Env env = obj.Env();
|
|
857
|
-
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
858
|
-
|
|
859
|
-
RG_ASSERT(type->primitive == PrimitiveKind::Record);
|
|
860
|
-
|
|
861
|
-
for (Size i = 0; i < type->members.len; i++) {
|
|
862
|
-
const RecordMember &member = type->members[i];
|
|
863
|
-
|
|
864
|
-
Size offset = realign ? (i * realign) : member.offset;
|
|
865
|
-
const uint8_t *src = origin + offset;
|
|
866
|
-
|
|
867
|
-
switch (member.type->primitive) {
|
|
868
|
-
case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
|
|
869
|
-
|
|
870
|
-
case PrimitiveKind::Bool: {
|
|
871
|
-
bool b = *(bool *)src;
|
|
872
|
-
obj.Set(member.name, Napi::Boolean::New(env, b));
|
|
873
|
-
} break;
|
|
874
|
-
case PrimitiveKind::Int8: {
|
|
875
|
-
double d = (double)*(int8_t *)src;
|
|
876
|
-
obj.Set(member.name, Napi::Number::New(env, d));
|
|
877
|
-
} break;
|
|
878
|
-
case PrimitiveKind::UInt8: {
|
|
879
|
-
double d = (double)*(uint8_t *)src;
|
|
880
|
-
obj.Set(member.name, Napi::Number::New(env, d));
|
|
881
|
-
} break;
|
|
882
|
-
case PrimitiveKind::Int16: {
|
|
883
|
-
double d = (double)*(int16_t *)src;
|
|
884
|
-
obj.Set(member.name, Napi::Number::New(env, d));
|
|
885
|
-
} break;
|
|
886
|
-
case PrimitiveKind::Int16S: {
|
|
887
|
-
int16_t v = *(int16_t *)src;
|
|
888
|
-
double d = (double)ReverseBytes(v);
|
|
889
|
-
|
|
890
|
-
obj.Set(member.name, Napi::Number::New(env, d));
|
|
891
|
-
} break;
|
|
892
|
-
case PrimitiveKind::UInt16: {
|
|
893
|
-
double d = (double)*(uint16_t *)src;
|
|
894
|
-
obj.Set(member.name, Napi::Number::New(env, d));
|
|
895
|
-
} break;
|
|
896
|
-
case PrimitiveKind::UInt16S: {
|
|
897
|
-
uint16_t v = *(uint16_t *)src;
|
|
898
|
-
double d = (double)ReverseBytes(v);
|
|
899
|
-
|
|
900
|
-
obj.Set(member.name, Napi::Number::New(env, d));
|
|
901
|
-
} break;
|
|
902
|
-
case PrimitiveKind::Int32: {
|
|
903
|
-
double d = (double)*(int32_t *)src;
|
|
904
|
-
obj.Set(member.name, Napi::Number::New(env, d));
|
|
905
|
-
} break;
|
|
906
|
-
case PrimitiveKind::Int32S: {
|
|
907
|
-
int32_t v = *(int32_t *)src;
|
|
908
|
-
double d = (double)ReverseBytes(v);
|
|
909
|
-
|
|
910
|
-
obj.Set(member.name, Napi::Number::New(env, d));
|
|
911
|
-
} break;
|
|
912
|
-
case PrimitiveKind::UInt32: {
|
|
913
|
-
double d = (double)*(uint32_t *)src;
|
|
914
|
-
obj.Set(member.name, Napi::Number::New(env, d));
|
|
915
|
-
} break;
|
|
916
|
-
case PrimitiveKind::UInt32S: {
|
|
917
|
-
uint32_t v = *(uint32_t *)src;
|
|
918
|
-
double d = (double)ReverseBytes(v);
|
|
919
|
-
|
|
920
|
-
obj.Set(member.name, Napi::Number::New(env, d));
|
|
921
|
-
} break;
|
|
922
|
-
case PrimitiveKind::Int64: {
|
|
923
|
-
int64_t v = *(int64_t *)src;
|
|
924
|
-
obj.Set(member.name, NewBigInt(env, v));
|
|
925
|
-
} break;
|
|
926
|
-
case PrimitiveKind::Int64S: {
|
|
927
|
-
int64_t v = ReverseBytes(*(int64_t *)src);
|
|
928
|
-
obj.Set(member.name, NewBigInt(env, v));
|
|
929
|
-
} break;
|
|
930
|
-
case PrimitiveKind::UInt64: {
|
|
931
|
-
uint64_t v = *(uint64_t *)src;
|
|
932
|
-
obj.Set(member.name, NewBigInt(env, v));
|
|
933
|
-
} break;
|
|
934
|
-
case PrimitiveKind::UInt64S: {
|
|
935
|
-
uint64_t v = ReverseBytes(*(uint64_t *)src);
|
|
936
|
-
obj.Set(member.name, NewBigInt(env, v));
|
|
937
|
-
} break;
|
|
938
|
-
case PrimitiveKind::String: {
|
|
939
|
-
const char *str = *(const char **)src;
|
|
940
|
-
obj.Set(member.name, str ? Napi::String::New(env, str) : env.Null());
|
|
941
|
-
|
|
942
|
-
if (member.type->dispose) {
|
|
943
|
-
member.type->dispose(env, member.type, str);
|
|
944
|
-
}
|
|
945
|
-
} break;
|
|
946
|
-
case PrimitiveKind::String16: {
|
|
947
|
-
const char16_t *str16 = *(const char16_t **)src;
|
|
948
|
-
obj.Set(member.name, str16 ? Napi::String::New(env, str16) : env.Null());
|
|
949
|
-
|
|
950
|
-
if (member.type->dispose) {
|
|
951
|
-
member.type->dispose(env, member.type, str16);
|
|
952
|
-
}
|
|
953
|
-
} break;
|
|
954
|
-
case PrimitiveKind::Pointer:
|
|
955
|
-
case PrimitiveKind::Callback: {
|
|
956
|
-
void *ptr2 = *(void **)src;
|
|
957
|
-
|
|
958
|
-
if (ptr2) {
|
|
959
|
-
Napi::External<void> external = Napi::External<void>::New(env, ptr2);
|
|
960
|
-
SetValueTag(instance, external, member.type->ref.marker);
|
|
961
|
-
|
|
962
|
-
obj.Set(member.name, external);
|
|
963
|
-
} else {
|
|
964
|
-
obj.Set(member.name, env.Null());
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
if (member.type->dispose) {
|
|
968
|
-
member.type->dispose(env, member.type, ptr2);
|
|
969
|
-
}
|
|
970
|
-
} break;
|
|
971
|
-
case PrimitiveKind::Record: {
|
|
972
|
-
Napi::Object obj2 = PopObject(src, member.type, realign);
|
|
973
|
-
obj.Set(member.name, obj2);
|
|
974
|
-
} break;
|
|
975
|
-
case PrimitiveKind::Array: {
|
|
976
|
-
Napi::Value value = PopArray(src, member.type, realign);
|
|
977
|
-
obj.Set(member.name, value);
|
|
978
|
-
} break;
|
|
979
|
-
case PrimitiveKind::Float32: {
|
|
980
|
-
float f = *(float *)src;
|
|
981
|
-
obj.Set(member.name, Napi::Number::New(env, (double)f));
|
|
982
|
-
} break;
|
|
983
|
-
case PrimitiveKind::Float64: {
|
|
984
|
-
double d = *(double *)src;
|
|
985
|
-
obj.Set(member.name, Napi::Number::New(env, d));
|
|
986
|
-
} break;
|
|
987
|
-
|
|
988
|
-
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
989
|
-
}
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
Napi::Object CallData::PopObject(const uint8_t *origin, const TypeInfo *type, int16_t realign)
|
|
994
|
-
{
|
|
995
|
-
Napi::Object obj = Napi::Object::New(env);
|
|
996
|
-
PopObject(obj, origin, type, realign);
|
|
997
|
-
return obj;
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
static Size WideStringLength(const char16_t *str16, Size max)
|
|
1001
|
-
{
|
|
1002
|
-
Size len = 0;
|
|
1003
|
-
|
|
1004
|
-
while (len < max && str16[len]) {
|
|
1005
|
-
len++;
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
return len;
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
void CallData::PopNormalArray(Napi::Array array, const uint8_t *origin, const TypeInfo *ref, int16_t realign)
|
|
1012
|
-
{
|
|
1013
|
-
RG_ASSERT(array.IsArray());
|
|
1014
|
-
|
|
1015
|
-
Size offset = 0;
|
|
1016
|
-
uint32_t len = array.Length();
|
|
1017
|
-
|
|
1018
|
-
#define POP_ARRAY(SetCode) \
|
|
1019
|
-
do { \
|
|
1020
|
-
for (uint32_t i = 0; i < len; i++) { \
|
|
1021
|
-
int16_t align = std::max(realign, ref->align); \
|
|
1022
|
-
offset = AlignLen(offset, align); \
|
|
1023
|
-
\
|
|
1024
|
-
const uint8_t *src = origin + offset; \
|
|
1025
|
-
\
|
|
1026
|
-
SetCode \
|
|
1027
|
-
\
|
|
1028
|
-
offset += ref->size; \
|
|
1029
|
-
} \
|
|
1030
|
-
} while (false)
|
|
1031
|
-
#define POP_NUMBER_ARRAY(CType) \
|
|
1032
|
-
do { \
|
|
1033
|
-
POP_ARRAY({ \
|
|
1034
|
-
double d = (double)*(CType *)src; \
|
|
1035
|
-
array.Set(i, Napi::Number::New(env, d)); \
|
|
1036
|
-
}); \
|
|
1037
|
-
} while (false)
|
|
1038
|
-
#define POP_NUMBER_ARRAY_SWAP(CType) \
|
|
1039
|
-
do { \
|
|
1040
|
-
POP_ARRAY({ \
|
|
1041
|
-
CType v = *(CType *)src; \
|
|
1042
|
-
double d = (double)ReverseBytes(v); \
|
|
1043
|
-
array.Set(i, Napi::Number::New(env, d)); \
|
|
1044
|
-
}); \
|
|
1045
|
-
} while (false)
|
|
1046
|
-
|
|
1047
|
-
switch (ref->primitive) {
|
|
1048
|
-
case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
|
|
1049
|
-
|
|
1050
|
-
case PrimitiveKind::Bool: {
|
|
1051
|
-
POP_ARRAY({
|
|
1052
|
-
bool b = *(bool *)src;
|
|
1053
|
-
array.Set(i, Napi::Boolean::New(env, b));
|
|
1054
|
-
});
|
|
1055
|
-
} break;
|
|
1056
|
-
case PrimitiveKind::Int8: { POP_NUMBER_ARRAY(int8_t); } break;
|
|
1057
|
-
case PrimitiveKind::UInt8: { POP_NUMBER_ARRAY(uint8_t); } break;
|
|
1058
|
-
case PrimitiveKind::Int16: { POP_NUMBER_ARRAY(int16_t); } break;
|
|
1059
|
-
case PrimitiveKind::Int16S: { POP_NUMBER_ARRAY_SWAP(int16_t); } break;
|
|
1060
|
-
case PrimitiveKind::UInt16: { POP_NUMBER_ARRAY(uint16_t); } break;
|
|
1061
|
-
case PrimitiveKind::UInt16S: { POP_NUMBER_ARRAY_SWAP(uint16_t); } break;
|
|
1062
|
-
case PrimitiveKind::Int32: { POP_NUMBER_ARRAY(int32_t); } break;
|
|
1063
|
-
case PrimitiveKind::Int32S: { POP_NUMBER_ARRAY_SWAP(int32_t); } break;
|
|
1064
|
-
case PrimitiveKind::UInt32: { POP_NUMBER_ARRAY(uint32_t); } break;
|
|
1065
|
-
case PrimitiveKind::UInt32S: { POP_NUMBER_ARRAY_SWAP(uint32_t); } break;
|
|
1066
|
-
case PrimitiveKind::Int64: {
|
|
1067
|
-
POP_ARRAY({
|
|
1068
|
-
int64_t v = *(int64_t *)src;
|
|
1069
|
-
array.Set(i, NewBigInt(env, v));
|
|
1070
|
-
});
|
|
1071
|
-
} break;
|
|
1072
|
-
case PrimitiveKind::Int64S: {
|
|
1073
|
-
POP_ARRAY({
|
|
1074
|
-
int64_t v = ReverseBytes(*(int64_t *)src);
|
|
1075
|
-
array.Set(i, NewBigInt(env, v));
|
|
1076
|
-
});
|
|
1077
|
-
} break;
|
|
1078
|
-
case PrimitiveKind::UInt64: {
|
|
1079
|
-
POP_ARRAY({
|
|
1080
|
-
uint64_t v = *(uint64_t *)src;
|
|
1081
|
-
array.Set(i, NewBigInt(env, v));
|
|
1082
|
-
});
|
|
1083
|
-
} break;
|
|
1084
|
-
case PrimitiveKind::UInt64S: {
|
|
1085
|
-
POP_ARRAY({
|
|
1086
|
-
uint64_t v = ReverseBytes(*(uint64_t *)src);
|
|
1087
|
-
array.Set(i, NewBigInt(env, v));
|
|
1088
|
-
});
|
|
1089
|
-
} break;
|
|
1090
|
-
case PrimitiveKind::String: {
|
|
1091
|
-
POP_ARRAY({
|
|
1092
|
-
const char *str = *(const char **)src;
|
|
1093
|
-
array.Set(i, str ? Napi::String::New(env, str) : env.Null());
|
|
1094
|
-
|
|
1095
|
-
if (ref->dispose) {
|
|
1096
|
-
ref->dispose(env, ref, str);
|
|
1097
|
-
}
|
|
1098
|
-
});
|
|
1099
|
-
} break;
|
|
1100
|
-
case PrimitiveKind::String16: {
|
|
1101
|
-
POP_ARRAY({
|
|
1102
|
-
const char16_t *str16 = *(const char16_t **)src;
|
|
1103
|
-
array.Set(i, str16 ? Napi::String::New(env, str16) : env.Null());
|
|
1104
|
-
|
|
1105
|
-
if (ref->dispose) {
|
|
1106
|
-
ref->dispose(env, ref, str16);
|
|
1107
|
-
}
|
|
1108
|
-
});
|
|
1109
|
-
} break;
|
|
1110
|
-
case PrimitiveKind::Pointer:
|
|
1111
|
-
case PrimitiveKind::Callback: {
|
|
1112
|
-
POP_ARRAY({
|
|
1113
|
-
void *ptr2 = *(void **)src;
|
|
1114
|
-
|
|
1115
|
-
if (ptr2) {
|
|
1116
|
-
Napi::External<void> external = Napi::External<void>::New(env, ptr2);
|
|
1117
|
-
SetValueTag(instance, external, ref->ref.marker);
|
|
1118
|
-
|
|
1119
|
-
array.Set(i, external);
|
|
1120
|
-
} else {
|
|
1121
|
-
array.Set(i, env.Null());
|
|
1122
|
-
}
|
|
1123
|
-
|
|
1124
|
-
if (ref->dispose) {
|
|
1125
|
-
ref->dispose(env, ref, ptr2);
|
|
1126
|
-
}
|
|
1127
|
-
});
|
|
1128
|
-
} break;
|
|
1129
|
-
case PrimitiveKind::Record: {
|
|
1130
|
-
POP_ARRAY({
|
|
1131
|
-
Napi::Object obj = PopObject(src, ref, realign);
|
|
1132
|
-
array.Set(i, obj);
|
|
1133
|
-
});
|
|
1134
|
-
} break;
|
|
1135
|
-
case PrimitiveKind::Array: {
|
|
1136
|
-
POP_ARRAY({
|
|
1137
|
-
Napi::Value value = PopArray(src, ref, realign);
|
|
1138
|
-
array.Set(i, value);
|
|
1139
|
-
});
|
|
1140
|
-
} break;
|
|
1141
|
-
case PrimitiveKind::Float32: { POP_NUMBER_ARRAY(float); } break;
|
|
1142
|
-
case PrimitiveKind::Float64: { POP_NUMBER_ARRAY(double); } break;
|
|
1143
|
-
|
|
1144
|
-
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
1145
|
-
}
|
|
1146
|
-
|
|
1147
|
-
#undef POP_NUMBER_ARRAY_SWAP
|
|
1148
|
-
#undef POP_NUMBER_ARRAY
|
|
1149
|
-
#undef POP_ARRAY
|
|
1150
|
-
}
|
|
1151
|
-
|
|
1152
|
-
void CallData::PopTypedArray(Napi::TypedArray array, const uint8_t *origin, const TypeInfo *ref, int16_t realign)
|
|
1153
|
-
{
|
|
1154
|
-
RG_ASSERT(array.IsTypedArray());
|
|
1155
|
-
RG_ASSERT(GetTypedArrayType(ref) == array.TypedArrayType() ||
|
|
1156
|
-
ref == instance->void_type);
|
|
1157
|
-
|
|
1158
|
-
uint8_t *buf = (uint8_t *)array.ArrayBuffer().Data();
|
|
1159
|
-
|
|
1160
|
-
if (realign) {
|
|
1161
|
-
Size offset = 0;
|
|
1162
|
-
Size len = (Size)array.ElementLength();
|
|
1163
|
-
Size size = (Size)array.ElementSize();
|
|
1164
|
-
|
|
1165
|
-
for (Size i = 0; i < len; i++) {
|
|
1166
|
-
offset = AlignLen(offset, realign);
|
|
1167
|
-
|
|
1168
|
-
uint8_t *dest = buf + i * size;
|
|
1169
|
-
const uint8_t *src = origin + offset;
|
|
1170
|
-
|
|
1171
|
-
memcpy(dest, src, size);
|
|
1172
|
-
|
|
1173
|
-
offset += size;
|
|
1174
|
-
}
|
|
1175
|
-
} else {
|
|
1176
|
-
memcpy_safe(buf, origin, (size_t)array.ByteLength());
|
|
1177
|
-
}
|
|
1178
|
-
|
|
1179
|
-
#define SWAP(CType) \
|
|
1180
|
-
do { \
|
|
1181
|
-
CType *data = (CType *)buf; \
|
|
1182
|
-
Size len = (Size)array.ElementLength(); \
|
|
1183
|
-
\
|
|
1184
|
-
for (Size i = 0; i < len; i++) { \
|
|
1185
|
-
data[i] = ReverseBytes(data[i]); \
|
|
1186
|
-
} \
|
|
1187
|
-
} while (false)
|
|
1188
|
-
|
|
1189
|
-
if (ref->primitive == PrimitiveKind::Int16S || ref->primitive == PrimitiveKind::UInt16S) {
|
|
1190
|
-
SWAP(uint16_t);
|
|
1191
|
-
} else if (ref->primitive == PrimitiveKind::Int32S || ref->primitive == PrimitiveKind::UInt32S) {
|
|
1192
|
-
SWAP(uint32_t);
|
|
1193
|
-
} else if (ref->primitive == PrimitiveKind::Int64S || ref->primitive == PrimitiveKind::UInt64S) {
|
|
1194
|
-
SWAP(uint64_t);
|
|
1195
|
-
}
|
|
1196
|
-
|
|
1197
|
-
#undef SWAP
|
|
1198
|
-
}
|
|
1199
|
-
|
|
1200
|
-
Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int16_t realign)
|
|
1201
|
-
{
|
|
1202
|
-
RG_ASSERT(type->primitive == PrimitiveKind::Array);
|
|
1203
|
-
|
|
1204
|
-
uint32_t len = type->size / type->ref.type->size;
|
|
1205
|
-
Size offset = 0;
|
|
1206
|
-
|
|
1207
|
-
#define POP_ARRAY(SetCode) \
|
|
1208
|
-
do { \
|
|
1209
|
-
Napi::Array array = Napi::Array::New(env); \
|
|
1210
|
-
\
|
|
1211
|
-
for (uint32_t i = 0; i < len; i++) { \
|
|
1212
|
-
int16_t align = std::max(realign, type->ref.type->align); \
|
|
1213
|
-
offset = AlignLen(offset, align); \
|
|
1214
|
-
\
|
|
1215
|
-
const uint8_t *src = origin + offset; \
|
|
1216
|
-
\
|
|
1217
|
-
SetCode \
|
|
1218
|
-
\
|
|
1219
|
-
offset += type->ref.type->size; \
|
|
1220
|
-
} \
|
|
1221
|
-
\
|
|
1222
|
-
return array; \
|
|
1223
|
-
} while (false)
|
|
1224
|
-
#define POP_NUMBER_ARRAY(TypedArrayType, CType) \
|
|
1225
|
-
do { \
|
|
1226
|
-
if (type->hint == TypeInfo::ArrayHint::Array) { \
|
|
1227
|
-
POP_ARRAY({ \
|
|
1228
|
-
double d = (double)*(CType *)src; \
|
|
1229
|
-
array.Set(i, Napi::Number::New(env, d)); \
|
|
1230
|
-
}); \
|
|
1231
|
-
} else { \
|
|
1232
|
-
Napi::TypedArrayType array = Napi::TypedArrayType::New(env, len); \
|
|
1233
|
-
PopTypedArray(array, origin, type->ref.type, realign); \
|
|
1234
|
-
\
|
|
1235
|
-
return array; \
|
|
1236
|
-
} \
|
|
1237
|
-
} while (false)
|
|
1238
|
-
#define POP_NUMBER_ARRAY_SWAP(TypedArrayType, CType) \
|
|
1239
|
-
do { \
|
|
1240
|
-
if (type->hint == TypeInfo::ArrayHint::Array) { \
|
|
1241
|
-
POP_ARRAY({ \
|
|
1242
|
-
CType v = *(CType *)src; \
|
|
1243
|
-
double d = (double)ReverseBytes(v); \
|
|
1244
|
-
array.Set(i, Napi::Number::New(env, d)); \
|
|
1245
|
-
}); \
|
|
1246
|
-
} else { \
|
|
1247
|
-
Napi::TypedArrayType array = Napi::TypedArrayType::New(env, len); \
|
|
1248
|
-
PopTypedArray(array, origin, type->ref.type, realign); \
|
|
1249
|
-
\
|
|
1250
|
-
return array; \
|
|
1251
|
-
} \
|
|
1252
|
-
} while (false)
|
|
1253
|
-
|
|
1254
|
-
switch (type->ref.type->primitive) {
|
|
1255
|
-
case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
|
|
1256
|
-
|
|
1257
|
-
case PrimitiveKind::Bool: {
|
|
1258
|
-
POP_ARRAY({
|
|
1259
|
-
bool b = *(bool *)src;
|
|
1260
|
-
array.Set(i, Napi::Boolean::New(env, b));
|
|
1261
|
-
});
|
|
1262
|
-
} break;
|
|
1263
|
-
case PrimitiveKind::Int8: {
|
|
1264
|
-
if (type->hint == TypeInfo::ArrayHint::String) {
|
|
1265
|
-
RG_ASSERT(!realign);
|
|
1266
|
-
|
|
1267
|
-
const char *ptr = (const char *)origin;
|
|
1268
|
-
size_t count = strnlen(ptr, (size_t)len);
|
|
1269
|
-
|
|
1270
|
-
Napi::String str = Napi::String::New(env, ptr, count);
|
|
1271
|
-
return str;
|
|
1272
|
-
}
|
|
1273
|
-
|
|
1274
|
-
POP_NUMBER_ARRAY(Int8Array, int8_t);
|
|
1275
|
-
} break;
|
|
1276
|
-
case PrimitiveKind::UInt8: { POP_NUMBER_ARRAY(Uint8Array, uint8_t); } break;
|
|
1277
|
-
case PrimitiveKind::Int16: {
|
|
1278
|
-
if (type->hint == TypeInfo::ArrayHint::String) {
|
|
1279
|
-
RG_ASSERT(!realign);
|
|
1280
|
-
|
|
1281
|
-
const char16_t *ptr = (const char16_t *)origin;
|
|
1282
|
-
Size count = WideStringLength(ptr, len);
|
|
1283
|
-
|
|
1284
|
-
Napi::String str = Napi::String::New(env, ptr, count);
|
|
1285
|
-
return str;
|
|
1286
|
-
}
|
|
1287
|
-
|
|
1288
|
-
POP_NUMBER_ARRAY(Int16Array, int16_t);
|
|
1289
|
-
} break;
|
|
1290
|
-
case PrimitiveKind::Int16S: { POP_NUMBER_ARRAY_SWAP(Int16Array, int16_t); } break;
|
|
1291
|
-
case PrimitiveKind::UInt16: { POP_NUMBER_ARRAY(Uint16Array, uint16_t); } break;
|
|
1292
|
-
case PrimitiveKind::UInt16S: { POP_NUMBER_ARRAY_SWAP(Uint16Array, uint16_t); } break;
|
|
1293
|
-
case PrimitiveKind::Int32: { POP_NUMBER_ARRAY(Int32Array, int32_t); } break;
|
|
1294
|
-
case PrimitiveKind::Int32S: { POP_NUMBER_ARRAY_SWAP(Int32Array, int32_t); } break;
|
|
1295
|
-
case PrimitiveKind::UInt32: { POP_NUMBER_ARRAY(Uint32Array, uint32_t); } break;
|
|
1296
|
-
case PrimitiveKind::UInt32S: { POP_NUMBER_ARRAY_SWAP(Uint32Array, uint32_t); } break;
|
|
1297
|
-
case PrimitiveKind::Int64: {
|
|
1298
|
-
POP_ARRAY({
|
|
1299
|
-
int64_t v = *(int64_t *)src;
|
|
1300
|
-
array.Set(i, NewBigInt(env, v));
|
|
1301
|
-
});
|
|
1302
|
-
} break;
|
|
1303
|
-
case PrimitiveKind::Int64S: {
|
|
1304
|
-
POP_ARRAY({
|
|
1305
|
-
int64_t v = ReverseBytes(*(int64_t *)src);
|
|
1306
|
-
array.Set(i, NewBigInt(env, v));
|
|
1307
|
-
});
|
|
1308
|
-
} break;
|
|
1309
|
-
case PrimitiveKind::UInt64: {
|
|
1310
|
-
POP_ARRAY({
|
|
1311
|
-
uint64_t v = *(uint64_t *)src;
|
|
1312
|
-
array.Set(i, NewBigInt(env, v));
|
|
1313
|
-
});
|
|
1314
|
-
} break;
|
|
1315
|
-
case PrimitiveKind::UInt64S: {
|
|
1316
|
-
POP_ARRAY({
|
|
1317
|
-
uint64_t v = ReverseBytes(*(uint64_t *)src);
|
|
1318
|
-
array.Set(i, NewBigInt(env, v));
|
|
1319
|
-
});
|
|
1320
|
-
} break;
|
|
1321
|
-
case PrimitiveKind::String: {
|
|
1322
|
-
POP_ARRAY({
|
|
1323
|
-
const char *str = *(const char **)src;
|
|
1324
|
-
array.Set(i, str ? Napi::String::New(env, str) : env.Null());
|
|
1325
|
-
});
|
|
1326
|
-
} break;
|
|
1327
|
-
case PrimitiveKind::String16: {
|
|
1328
|
-
POP_ARRAY({
|
|
1329
|
-
const char16_t *str16 = *(const char16_t **)src;
|
|
1330
|
-
array.Set(i, str16 ? Napi::String::New(env, str16) : env.Null());
|
|
1331
|
-
});
|
|
1332
|
-
} break;
|
|
1333
|
-
case PrimitiveKind::Pointer:
|
|
1334
|
-
case PrimitiveKind::Callback: {
|
|
1335
|
-
POP_ARRAY({
|
|
1336
|
-
void *ptr2 = *(void **)src;
|
|
1337
|
-
|
|
1338
|
-
if (ptr2) {
|
|
1339
|
-
Napi::External<void> external = Napi::External<void>::New(env, ptr2);
|
|
1340
|
-
SetValueTag(instance, external, type->ref.type->ref.marker);
|
|
1341
|
-
|
|
1342
|
-
array.Set(i, external);
|
|
1343
|
-
} else {
|
|
1344
|
-
array.Set(i, env.Null());
|
|
1345
|
-
}
|
|
1346
|
-
});
|
|
1347
|
-
} break;
|
|
1348
|
-
case PrimitiveKind::Record: {
|
|
1349
|
-
POP_ARRAY({
|
|
1350
|
-
Napi::Object obj = PopObject(src, type->ref.type, realign);
|
|
1351
|
-
array.Set(i, obj);
|
|
1352
|
-
});
|
|
1353
|
-
} break;
|
|
1354
|
-
case PrimitiveKind::Array: {
|
|
1355
|
-
POP_ARRAY({
|
|
1356
|
-
Napi::Value value = PopArray(src, type->ref.type, realign);
|
|
1357
|
-
array.Set(i, value);
|
|
1358
|
-
});
|
|
1359
|
-
} break;
|
|
1360
|
-
case PrimitiveKind::Float32: { POP_NUMBER_ARRAY(Float32Array, float); } break;
|
|
1361
|
-
case PrimitiveKind::Float64: { POP_NUMBER_ARRAY(Float64Array, double); } break;
|
|
1362
|
-
|
|
1363
|
-
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
1364
|
-
}
|
|
1365
|
-
|
|
1366
|
-
#undef POP_NUMBER_ARRAY_SWAP
|
|
1367
|
-
#undef POP_NUMBER_ARRAY
|
|
1368
|
-
#undef POP_ARRAY
|
|
1369
|
-
|
|
1370
|
-
RG_UNREACHABLE();
|
|
1371
|
-
}
|
|
1372
|
-
|
|
1373
988
|
void CallData::DumpForward() const
|
|
1374
989
|
{
|
|
1375
990
|
PrintLn(stderr, "%!..+---- %1 (%2) ----%!0", func->name, CallConventionNames[(int)func->convention]);
|