koffi 2.1.4 → 2.2.0

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.
Files changed (89) hide show
  1. package/{src/koffi/ChangeLog.md → ChangeLog.md} +21 -1
  2. package/{src/koffi/LICENSE.txt → LICENSE.txt} +0 -0
  3. package/{src/koffi/README.md → README.md} +0 -0
  4. package/{src/koffi/doc → doc}/Makefile +1 -1
  5. package/{src/koffi/doc → doc}/benchmarks.md +0 -0
  6. package/{src/koffi/doc → doc}/benchmarks.xlsx +0 -0
  7. package/doc/callbacks.md +175 -0
  8. package/{src/koffi/doc → doc}/changes.md +2 -3
  9. package/{src/koffi/doc → doc}/conf.py +29 -6
  10. package/{src/koffi/doc → doc}/contribute.md +0 -0
  11. package/{src/koffi/doc → doc}/functions.md +39 -124
  12. package/{src/koffi/doc → doc}/index.rst +1 -0
  13. package/{src/koffi/doc → doc}/make.bat +1 -1
  14. package/{src/koffi/doc → doc}/memory.md +0 -0
  15. package/{src/koffi/doc → doc}/platforms.md +0 -0
  16. package/{src/koffi/doc → doc}/poetry.lock +0 -0
  17. package/{src/koffi/doc → doc}/pyproject.toml +0 -0
  18. package/{src/koffi/doc → doc}/start.md +0 -0
  19. package/{src/koffi/doc → doc}/static/bench_linux.png +0 -0
  20. package/{src/koffi/doc → doc}/static/bench_windows.png +0 -0
  21. package/{src/koffi/doc → doc}/static/custom.css +0 -0
  22. package/{src/koffi/doc → doc}/static/perf_linux_20220623.png +0 -0
  23. package/{src/koffi/doc → doc}/static/perf_linux_20220623_2.png +0 -0
  24. package/{src/koffi/doc → doc}/static/perf_linux_20220627.png +0 -0
  25. package/{src/koffi/doc → doc}/static/perf_linux_20220628.png +0 -0
  26. package/{src/koffi/doc → doc}/static/perf_linux_20220812.png +0 -0
  27. package/{src/koffi/doc → doc}/static/perf_windows_20220623.png +0 -0
  28. package/{src/koffi/doc → doc}/static/perf_windows_20220623_2.png +0 -0
  29. package/{src/koffi/doc → doc}/static/perf_windows_20220627.png +0 -0
  30. package/{src/koffi/doc → doc}/static/perf_windows_20220628.png +0 -0
  31. package/{src/koffi/doc → doc}/static/perf_windows_20220812.png +0 -0
  32. package/{src/koffi/doc → doc}/templates/badges.html +0 -0
  33. package/{src/koffi/doc → doc}/types.md +36 -9
  34. package/package.json +2 -2
  35. package/src/core/libcc/libcc.cc +89 -27
  36. package/src/core/libcc/libcc.hh +74 -39
  37. package/src/koffi/build/2.2.0/koffi_darwin_arm64.tar.gz +0 -0
  38. package/src/koffi/build/2.2.0/koffi_darwin_x64.tar.gz +0 -0
  39. package/src/koffi/build/2.2.0/koffi_freebsd_arm64.tar.gz +0 -0
  40. package/src/koffi/build/2.2.0/koffi_freebsd_ia32.tar.gz +0 -0
  41. package/src/koffi/build/2.2.0/koffi_freebsd_x64.tar.gz +0 -0
  42. package/src/koffi/build/2.2.0/koffi_linux_arm32hf.tar.gz +0 -0
  43. package/src/koffi/build/2.2.0/koffi_linux_arm64.tar.gz +0 -0
  44. package/src/koffi/build/2.2.0/koffi_linux_ia32.tar.gz +0 -0
  45. package/src/koffi/build/2.2.0/koffi_linux_riscv64hf64.tar.gz +0 -0
  46. package/src/koffi/build/2.2.0/koffi_linux_x64.tar.gz +0 -0
  47. package/src/koffi/build/2.2.0/koffi_openbsd_ia32.tar.gz +0 -0
  48. package/src/koffi/build/2.2.0/koffi_openbsd_x64.tar.gz +0 -0
  49. package/src/koffi/build/2.2.0/koffi_win32_arm64.tar.gz +0 -0
  50. package/src/koffi/build/2.2.0/koffi_win32_ia32.tar.gz +0 -0
  51. package/src/koffi/build/2.2.0/koffi_win32_x64.tar.gz +0 -0
  52. package/src/koffi/qemu/qemu.js +17 -7
  53. package/src/koffi/src/abi_arm32.cc +25 -23
  54. package/src/koffi/src/abi_arm64.cc +24 -22
  55. package/src/koffi/src/abi_riscv64.cc +20 -18
  56. package/src/koffi/src/abi_x64_sysv.cc +19 -17
  57. package/src/koffi/src/abi_x64_win.cc +18 -16
  58. package/src/koffi/src/abi_x86.cc +22 -20
  59. package/src/koffi/src/call.cc +220 -607
  60. package/src/koffi/src/call.hh +7 -11
  61. package/src/koffi/src/ffi.cc +229 -29
  62. package/src/koffi/src/ffi.hh +6 -2
  63. package/src/koffi/src/parser.cc +3 -9
  64. package/src/koffi/src/util.cc +546 -8
  65. package/src/koffi/src/util.hh +8 -2
  66. package/src/koffi/test/CMakeLists.txt +3 -3
  67. package/src/koffi/test/callbacks.js +70 -0
  68. package/src/koffi/test/misc.c +67 -0
  69. package/src/koffi/test/raylib.js +2 -2
  70. package/src/koffi/test/sqlite.js +1 -1
  71. package/src/koffi/test/sync.js +28 -6
  72. package/vendor/brotli/c/common/platform.h +2 -0
  73. package/vendor/sqlite3mc/sqlite3.c +243532 -0
  74. package/vendor/sqlite3mc/sqlite3.h +12887 -0
  75. package/src/koffi/build/2.1.4/koffi_darwin_arm64.tar.gz +0 -0
  76. package/src/koffi/build/2.1.4/koffi_darwin_x64.tar.gz +0 -0
  77. package/src/koffi/build/2.1.4/koffi_freebsd_arm64.tar.gz +0 -0
  78. package/src/koffi/build/2.1.4/koffi_freebsd_ia32.tar.gz +0 -0
  79. package/src/koffi/build/2.1.4/koffi_freebsd_x64.tar.gz +0 -0
  80. package/src/koffi/build/2.1.4/koffi_linux_arm32hf.tar.gz +0 -0
  81. package/src/koffi/build/2.1.4/koffi_linux_arm64.tar.gz +0 -0
  82. package/src/koffi/build/2.1.4/koffi_linux_ia32.tar.gz +0 -0
  83. package/src/koffi/build/2.1.4/koffi_linux_riscv64hf64.tar.gz +0 -0
  84. package/src/koffi/build/2.1.4/koffi_linux_x64.tar.gz +0 -0
  85. package/src/koffi/build/2.1.4/koffi_openbsd_ia32.tar.gz +0 -0
  86. package/src/koffi/build/2.1.4/koffi_openbsd_x64.tar.gz +0 -0
  87. package/src/koffi/build/2.1.4/koffi_win32_arm64.tar.gz +0 -0
  88. package/src/koffi/build/2.1.4/koffi_win32_ia32.tar.gz +0 -0
  89. package/src/koffi/build/2.1.4/koffi_win32_x64.tar.gz +0 -0
@@ -48,38 +48,67 @@ CallData::~CallData()
48
48
  }
49
49
  }
50
50
 
51
- bool CallData::PushString(Napi::Value value, const char **out_str)
51
+ bool CallData::PushString(Napi::Value value, int directions, const char **out_str)
52
52
  {
53
53
  if (value.IsString()) {
54
- Span<char> buf;
55
- size_t len = 0;
56
- napi_status status;
54
+ if (RG_UNLIKELY(directions & 2)) {
55
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
56
+ return false;
57
+ }
57
58
 
58
- buf.ptr = (char *)mem->heap.ptr;
59
- buf.len = std::max((Size)0, mem->heap.len - Kibibytes(32));
59
+ PushStringValue(value, out_str);
60
+ return true;
61
+ } else if (IsNullOrUndefined(value)) {
62
+ *out_str = nullptr;
63
+ return true;
64
+ } else if (value.IsArray()) {
65
+ Napi::Array array = value.As<Napi::Array>();
60
66
 
61
- status = napi_get_value_string_utf8(env, value, buf.ptr, (size_t)buf.len, &len);
62
- RG_ASSERT(status == napi_ok);
67
+ if (RG_UNLIKELY(!(directions & 2))) {
68
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
69
+ return false;
70
+ }
71
+ if (RG_UNLIKELY(array.Length() != 1)) {
72
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected [string]", GetValueType(instance, value));
73
+ return false;
74
+ }
63
75
 
64
- len++;
76
+ value = array[0u];
65
77
 
66
- if (RG_LIKELY(len < (size_t)buf.len)) {
67
- mem->heap.ptr += (Size)len;
68
- mem->heap.len -= (Size)len;
69
- } else {
70
- status = napi_get_value_string_utf8(env, value, nullptr, 0, &len);
71
- RG_ASSERT(status == napi_ok);
78
+ if (RG_UNLIKELY(!value.IsString())) {
79
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected [string]", GetValueType(instance, array[0u]));
80
+ return false;
81
+ }
82
+
83
+ Size len = PushStringValue(value, out_str);
84
+ if (RG_UNLIKELY(len < 0))
85
+ return false;
86
+
87
+ // Create array type
88
+ TypeInfo *type;
89
+ {
90
+ type = AllocateOne<TypeInfo>(&call_alloc, (int)AllocFlag::Zero);
91
+
92
+ type->name = "<temporary>";
93
+
94
+ type->primitive = PrimitiveKind::Array;
95
+ type->align = 1;
96
+ type->size = (int32_t)len;
97
+ type->ref.type = instance->char_type;
98
+ type->hint = TypeInfo::ArrayHint::String;
99
+ }
72
100
 
73
- buf = AllocateSpan<char>(&call_alloc, (Size)len + 1);
101
+ // Prepare output argument
102
+ {
103
+ OutArgument *out = out_arguments.AppendDefault();
74
104
 
75
- status = napi_get_value_string_utf8(env, value, buf.ptr, (size_t)buf.len, &len);
105
+ napi_status status = napi_create_reference(env, array, 1, &out->ref);
76
106
  RG_ASSERT(status == napi_ok);
107
+
108
+ out->ptr = (const uint8_t *)*out_str;
109
+ out->type = type;
77
110
  }
78
111
 
79
- *out_str = buf.ptr;
80
- return true;
81
- } else if (IsNullOrUndefined(value)) {
82
- *out_str = nullptr;
83
112
  return true;
84
113
  } else {
85
114
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
@@ -87,38 +116,100 @@ bool CallData::PushString(Napi::Value value, const char **out_str)
87
116
  }
88
117
  }
89
118
 
90
- bool CallData::PushString16(Napi::Value value, const char16_t **out_str16)
119
+ Size CallData::PushStringValue(Napi::Value value, const char **out_str)
91
120
  {
92
- if (value.IsString()) {
93
- Span<char16_t> buf;
94
- size_t len = 0;
95
- napi_status status;
121
+ Span<char> buf;
122
+ size_t len = 0;
123
+ napi_status status;
96
124
 
97
- buf.ptr = (char16_t *)mem->heap.ptr;
98
- buf.len = std::max((Size)0, mem->heap.len - Kibibytes(32)) / 2;
125
+ buf.ptr = (char *)mem->heap.ptr;
126
+ buf.len = std::max((Size)0, mem->heap.len - Kibibytes(32));
99
127
 
100
- status = napi_get_value_string_utf16(env, value, buf.ptr, (size_t)buf.len, &len);
128
+ status = napi_get_value_string_utf8(env, value, buf.ptr, (size_t)buf.len, &len);
129
+ RG_ASSERT(status == napi_ok);
130
+
131
+ len++;
132
+
133
+ if (RG_LIKELY(len < (size_t)buf.len)) {
134
+ mem->heap.ptr += (Size)len;
135
+ mem->heap.len -= (Size)len;
136
+ } else {
137
+ status = napi_get_value_string_utf8(env, value, nullptr, 0, &len);
101
138
  RG_ASSERT(status == napi_ok);
102
139
 
103
- len++;
140
+ buf = AllocateSpan<char>(&call_alloc, (Size)len + 1);
104
141
 
105
- if (RG_LIKELY(len < (size_t)buf.len)) {
106
- mem->heap.ptr += (Size)len * 2;
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);
142
+ status = napi_get_value_string_utf8(env, value, buf.ptr, (size_t)buf.len, &len);
143
+ RG_ASSERT(status == napi_ok);
111
144
 
112
- buf = AllocateSpan<char16_t>(&call_alloc, ((Size)len + 1) * 2);
145
+ len++;
146
+ }
113
147
 
114
- status = napi_get_value_string_utf16(env, value, buf.ptr, (size_t)buf.len, &len);
115
- RG_ASSERT(status == napi_ok);
148
+ *out_str = buf.ptr;
149
+ return (Size)len;
150
+ }
151
+
152
+ bool CallData::PushString16(Napi::Value value, int directions, const char16_t **out_str16)
153
+ {
154
+ if (value.IsString()) {
155
+ if (RG_UNLIKELY(directions & 2)) {
156
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
157
+ return false;
116
158
  }
117
159
 
118
- *out_str16 = buf.ptr;
160
+ PushString16Value(value, out_str16);
119
161
  return true;
120
162
  } else if (IsNullOrUndefined(value)) {
121
163
  *out_str16 = nullptr;
164
+ return true;
165
+ } else if (value.IsArray()) {
166
+ Napi::Array array = value.As<Napi::Array>();
167
+
168
+ if (RG_UNLIKELY(!(directions & 2))) {
169
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
170
+ return false;
171
+ }
172
+ if (RG_UNLIKELY(array.Length() != 1)) {
173
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected [string]", GetValueType(instance, value));
174
+ return false;
175
+ }
176
+
177
+ value = array[0u];
178
+
179
+ if (RG_UNLIKELY(!value.IsString())) {
180
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected [string]", GetValueType(instance, array[0u]));
181
+ return false;
182
+ }
183
+
184
+ Size len = PushString16Value(value, out_str16);
185
+ if (RG_UNLIKELY(len < 0))
186
+ return false;
187
+
188
+ // Create array type
189
+ TypeInfo *type;
190
+ {
191
+ type = AllocateOne<TypeInfo>(&call_alloc, (int)AllocFlag::Zero);
192
+
193
+ type->name = "<temporary>";
194
+
195
+ type->primitive = PrimitiveKind::Array;
196
+ type->align = 1;
197
+ type->size = (int32_t)(len * 2);
198
+ type->ref.type = instance->char16_type;
199
+ type->hint = TypeInfo::ArrayHint::String;
200
+ }
201
+
202
+ // Prepare output argument
203
+ {
204
+ OutArgument *out = out_arguments.AppendDefault();
205
+
206
+ napi_status status = napi_create_reference(env, array, 1, &out->ref);
207
+ RG_ASSERT(status == napi_ok);
208
+
209
+ out->ptr = (const uint8_t *)*out_str16;
210
+ out->type = type;
211
+ }
212
+
122
213
  return true;
123
214
  } else {
124
215
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
@@ -126,6 +217,39 @@ bool CallData::PushString16(Napi::Value value, const char16_t **out_str16)
126
217
  }
127
218
  }
128
219
 
220
+ Size CallData::PushString16Value(Napi::Value value, const char16_t **out_str16)
221
+ {
222
+ Span<char16_t> buf;
223
+ size_t len = 0;
224
+ napi_status status;
225
+
226
+ buf.ptr = (char16_t *)mem->heap.ptr;
227
+ buf.len = std::max((Size)0, mem->heap.len - Kibibytes(32)) / 2;
228
+
229
+ status = napi_get_value_string_utf16(env, value, buf.ptr, (size_t)buf.len, &len);
230
+ RG_ASSERT(status == napi_ok);
231
+
232
+ len++;
233
+
234
+ if (RG_LIKELY(len < (size_t)buf.len)) {
235
+ mem->heap.ptr += (Size)len * 2;
236
+ mem->heap.len -= (Size)len * 2;
237
+ } else {
238
+ status = napi_get_value_string_utf16(env, value, nullptr, 0, &len);
239
+ RG_ASSERT(status == napi_ok);
240
+
241
+ buf = AllocateSpan<char16_t>(&call_alloc, ((Size)len + 1) * 2);
242
+
243
+ status = napi_get_value_string_utf16(env, value, buf.ptr, (size_t)buf.len, &len);
244
+ RG_ASSERT(status == napi_ok);
245
+
246
+ len++;
247
+ }
248
+
249
+ *out_str16 = buf.ptr;
250
+ return (Size)len;
251
+ }
252
+
129
253
  bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origin, int16_t realign)
130
254
  {
131
255
  RG_ASSERT(IsObject(obj));
@@ -161,7 +285,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
161
285
  return false;
162
286
  }
163
287
 
164
- int8_t v = CopyNumber<int8_t>(value);
288
+ int8_t v = GetNumber<int8_t>(value);
165
289
  *(int8_t *)dest = v;
166
290
  } break;
167
291
  case PrimitiveKind::UInt8: {
@@ -170,7 +294,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
170
294
  return false;
171
295
  }
172
296
 
173
- uint8_t v = CopyNumber<uint8_t>(value);
297
+ uint8_t v = GetNumber<uint8_t>(value);
174
298
  *(uint8_t *)dest = v;
175
299
  } break;
176
300
  case PrimitiveKind::Int16: {
@@ -179,7 +303,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
179
303
  return false;
180
304
  }
181
305
 
182
- int16_t v = CopyNumber<int16_t>(value);
306
+ int16_t v = GetNumber<int16_t>(value);
183
307
  *(int16_t *)dest = v;
184
308
  } break;
185
309
  case PrimitiveKind::Int16S: {
@@ -188,7 +312,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
188
312
  return false;
189
313
  }
190
314
 
191
- int16_t v = CopyNumber<int16_t>(value);
315
+ int16_t v = GetNumber<int16_t>(value);
192
316
  *(int16_t *)dest = ReverseBytes(v);
193
317
  } break;
194
318
  case PrimitiveKind::UInt16: {
@@ -197,7 +321,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
197
321
  return false;
198
322
  }
199
323
 
200
- uint16_t v = CopyNumber<uint16_t>(value);
324
+ uint16_t v = GetNumber<uint16_t>(value);
201
325
  *(uint16_t *)dest = v;
202
326
  } break;
203
327
  case PrimitiveKind::UInt16S: {
@@ -206,7 +330,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
206
330
  return false;
207
331
  }
208
332
 
209
- uint16_t v = CopyNumber<uint16_t>(value);
333
+ uint16_t v = GetNumber<uint16_t>(value);
210
334
  *(uint16_t *)dest = ReverseBytes(v);
211
335
  } break;
212
336
  case PrimitiveKind::Int32: {
@@ -215,7 +339,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
215
339
  return false;
216
340
  }
217
341
 
218
- int32_t v = CopyNumber<int32_t>(value);
342
+ int32_t v = GetNumber<int32_t>(value);
219
343
  *(int32_t *)dest = v;
220
344
  } break;
221
345
  case PrimitiveKind::Int32S: {
@@ -224,7 +348,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
224
348
  return false;
225
349
  }
226
350
 
227
- int32_t v = CopyNumber<int32_t>(value);
351
+ int32_t v = GetNumber<int32_t>(value);
228
352
  *(int32_t *)dest = ReverseBytes(v);
229
353
  } break;
230
354
  case PrimitiveKind::UInt32: {
@@ -233,7 +357,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
233
357
  return false;
234
358
  }
235
359
 
236
- uint32_t v = CopyNumber<uint32_t>(value);
360
+ uint32_t v = GetNumber<uint32_t>(value);
237
361
  *(uint32_t *)dest = v;
238
362
  } break;
239
363
  case PrimitiveKind::UInt32S: {
@@ -242,7 +366,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
242
366
  return false;
243
367
  }
244
368
 
245
- uint32_t v = CopyNumber<uint32_t>(value);
369
+ uint32_t v = GetNumber<uint32_t>(value);
246
370
  *(uint32_t *)dest = ReverseBytes(v);
247
371
  } break;
248
372
  case PrimitiveKind::Int64: {
@@ -251,7 +375,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
251
375
  return false;
252
376
  }
253
377
 
254
- int64_t v = CopyNumber<int64_t>(value);
378
+ int64_t v = GetNumber<int64_t>(value);
255
379
  *(int64_t *)dest = v;
256
380
  } break;
257
381
  case PrimitiveKind::Int64S: {
@@ -260,7 +384,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
260
384
  return false;
261
385
  }
262
386
 
263
- int64_t v = CopyNumber<int64_t>(value);
387
+ int64_t v = GetNumber<int64_t>(value);
264
388
  *(int64_t *)dest = ReverseBytes(v);
265
389
  } break;
266
390
  case PrimitiveKind::UInt64: {
@@ -269,7 +393,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
269
393
  return false;
270
394
  }
271
395
 
272
- uint64_t v = CopyNumber<uint64_t>(value);
396
+ uint64_t v = GetNumber<uint64_t>(value);
273
397
  *(uint64_t *)dest = v;
274
398
  } break;
275
399
  case PrimitiveKind::UInt64S: {
@@ -278,19 +402,19 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
278
402
  return false;
279
403
  }
280
404
 
281
- uint64_t v = CopyNumber<uint64_t>(value);
405
+ uint64_t v = GetNumber<uint64_t>(value);
282
406
  *(uint64_t *)dest = ReverseBytes(v);
283
407
  } break;
284
408
  case PrimitiveKind::String: {
285
409
  const char *str;
286
- if (RG_UNLIKELY(!PushString(value, &str)))
410
+ if (RG_UNLIKELY(!PushString(value, 1, &str)))
287
411
  return false;
288
412
 
289
413
  *(const char **)dest = str;
290
414
  } break;
291
415
  case PrimitiveKind::String16: {
292
416
  const char16_t *str16;
293
- if (RG_UNLIKELY(!PushString16(value, &str16)))
417
+ if (RG_UNLIKELY(!PushString16(value, 1, &str16)))
294
418
  return false;
295
419
 
296
420
  *(const char16_t **)dest = str16;
@@ -317,13 +441,13 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
317
441
  Napi::Array array = value.As<Napi::Array>();
318
442
  Size len = (Size)member.type->size / member.type->ref.type->size;
319
443
 
320
- if (!PushNormalArray(array, len, member.type->ref.type, dest, realign))
444
+ if (!PushNormalArray(array, len, member.type, dest, realign))
321
445
  return false;
322
446
  } else if (value.IsTypedArray()) {
323
447
  Napi::TypedArray array = value.As<Napi::TypedArray>();
324
448
  Size len = (Size)member.type->size / member.type->ref.type->size;
325
449
 
326
- if (!PushTypedArray(array, len, member.type->ref.type, dest, realign))
450
+ if (!PushTypedArray(array, len, member.type, dest, realign))
327
451
  return false;
328
452
  } else if (value.IsString() && !realign) {
329
453
  if (!PushStringArray(value, member.type, dest))
@@ -339,7 +463,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
339
463
  return false;
340
464
  }
341
465
 
342
- float f = CopyNumber<float>(value);
466
+ float f = GetNumber<float>(value);
343
467
  *(float *)dest = f;
344
468
  } break;
345
469
  case PrimitiveKind::Float64: {
@@ -348,7 +472,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
348
472
  return false;
349
473
  }
350
474
 
351
- double d = CopyNumber<double>(value);
475
+ double d = GetNumber<double>(value);
352
476
  *(double *)dest = d;
353
477
  } break;
354
478
  case PrimitiveKind::Callback: {
@@ -380,10 +504,12 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
380
504
  return true;
381
505
  }
382
506
 
383
- bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref, uint8_t *origin, int16_t realign)
507
+ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *type, uint8_t *origin, int16_t realign)
384
508
  {
385
509
  RG_ASSERT(array.IsArray());
386
510
 
511
+ const TypeInfo *ref = type->ref.type;
512
+
387
513
  if (RG_UNLIKELY(array.Length() != (size_t)len)) {
388
514
  ThrowError<Napi::Error>(env, "Expected array of length %1, got %2", len, array.Length());
389
515
  return false;
@@ -413,7 +539,10 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
413
539
  } while (false)
414
540
 
415
541
  switch (ref->primitive) {
416
- case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
542
+ case PrimitiveKind::Void: {
543
+ ThrowError<Napi::TypeError>(env, "Ambigous parameter type %1, use koffi.as(value, type)", type->name); \
544
+ return false;
545
+ } break;
417
546
 
418
547
  case PrimitiveKind::Bool: {
419
548
  PUSH_ARRAY(value.IsBoolean(), "boolean", {
@@ -423,92 +552,92 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
423
552
  } break;
424
553
  case PrimitiveKind::Int8: {
425
554
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
426
- int8_t v = CopyNumber<int8_t>(value);
555
+ int8_t v = GetNumber<int8_t>(value);
427
556
  *(int8_t *)dest = v;
428
557
  });
429
558
  } break;
430
559
  case PrimitiveKind::UInt8: {
431
560
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
432
- uint8_t v = CopyNumber<uint8_t>(value);
561
+ uint8_t v = GetNumber<uint8_t>(value);
433
562
  *(uint8_t *)dest = v;
434
563
  });
435
564
  } break;
436
565
  case PrimitiveKind::Int16: {
437
566
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
438
- int16_t v = CopyNumber<int16_t>(value);
567
+ int16_t v = GetNumber<int16_t>(value);
439
568
  *(int16_t *)dest = v;
440
569
  });
441
570
  } break;
442
571
  case PrimitiveKind::Int16S: {
443
572
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
444
- int16_t v = CopyNumber<int16_t>(value);
573
+ int16_t v = GetNumber<int16_t>(value);
445
574
  *(int16_t *)dest = ReverseBytes(v);
446
575
  });
447
576
  } break;
448
577
  case PrimitiveKind::UInt16: {
449
578
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
450
- uint16_t v = CopyNumber<uint16_t>(value);
579
+ uint16_t v = GetNumber<uint16_t>(value);
451
580
  *(uint16_t *)dest = v;
452
581
  });
453
582
  } break;
454
583
  case PrimitiveKind::UInt16S: {
455
584
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
456
- uint16_t v = CopyNumber<uint16_t>(value);
585
+ uint16_t v = GetNumber<uint16_t>(value);
457
586
  *(uint16_t *)dest = ReverseBytes(v);
458
587
  });
459
588
  } break;
460
589
  case PrimitiveKind::Int32: {
461
590
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
462
- int32_t v = CopyNumber<int32_t>(value);
591
+ int32_t v = GetNumber<int32_t>(value);
463
592
  *(int32_t *)dest = v;
464
593
  });
465
594
  } break;
466
595
  case PrimitiveKind::Int32S: {
467
596
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
468
- int32_t v = CopyNumber<int32_t>(value);
597
+ int32_t v = GetNumber<int32_t>(value);
469
598
  *(int32_t *)dest = ReverseBytes(v);
470
599
  });
471
600
  } break;
472
601
  case PrimitiveKind::UInt32: {
473
602
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
474
- uint32_t v = CopyNumber<uint32_t>(value);
603
+ uint32_t v = GetNumber<uint32_t>(value);
475
604
  *(uint32_t *)dest = v;
476
605
  });
477
606
  } break;
478
607
  case PrimitiveKind::UInt32S: {
479
608
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
480
- uint32_t v = CopyNumber<uint32_t>(value);
609
+ uint32_t v = GetNumber<uint32_t>(value);
481
610
  *(uint32_t *)dest = ReverseBytes(v);
482
611
  });
483
612
  } break;
484
613
  case PrimitiveKind::Int64: {
485
614
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
486
- int64_t v = CopyNumber<int64_t>(value);
615
+ int64_t v = GetNumber<int64_t>(value);
487
616
  *(int64_t *)dest = v;
488
617
  });
489
618
  } break;
490
619
  case PrimitiveKind::Int64S: {
491
620
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
492
- int64_t v = CopyNumber<int64_t>(value);
621
+ int64_t v = GetNumber<int64_t>(value);
493
622
  *(int64_t *)dest = ReverseBytes(v);
494
623
  });
495
624
  } break;
496
625
  case PrimitiveKind::UInt64: {
497
626
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
498
- uint64_t v = CopyNumber<uint64_t>(value);
627
+ uint64_t v = GetNumber<uint64_t>(value);
499
628
  *(uint64_t *)dest = v;
500
629
  });
501
630
  } break;
502
631
  case PrimitiveKind::UInt64S: {
503
632
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
504
- uint64_t v = CopyNumber<uint64_t>(value);
633
+ uint64_t v = GetNumber<uint64_t>(value);
505
634
  *(uint64_t *)dest = ReverseBytes(v);
506
635
  });
507
636
  } break;
508
637
  case PrimitiveKind::String: {
509
638
  PUSH_ARRAY(true, "string", {
510
639
  const char *str;
511
- if (RG_UNLIKELY(!PushString(value, &str)))
640
+ if (RG_UNLIKELY(!PushString(value, 1, &str)))
512
641
  return false;
513
642
 
514
643
  *(const char **)dest = str;
@@ -517,7 +646,7 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
517
646
  case PrimitiveKind::String16: {
518
647
  PUSH_ARRAY(true, "string", {
519
648
  const char16_t *str16;
520
- if (RG_UNLIKELY(!PushString16(value, &str16)))
649
+ if (RG_UNLIKELY(!PushString16(value, 1, &str16)))
521
650
  return false;
522
651
 
523
652
  *(const char16_t **)dest = str16;
@@ -552,13 +681,13 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
552
681
  Napi::Array array2 = value.As<Napi::Array>();
553
682
  Size len2 = (Size)ref->size / ref->ref.type->size;
554
683
 
555
- if (!PushNormalArray(array2, len2, ref->ref.type, dest, realign))
684
+ if (!PushNormalArray(array2, len2, ref, dest, realign))
556
685
  return false;
557
686
  } else if (value.IsTypedArray()) {
558
687
  Napi::TypedArray array2 = value.As<Napi::TypedArray>();
559
688
  Size len2 = (Size)ref->size / ref->ref.type->size;
560
689
 
561
- if (!PushTypedArray(array2, len2, ref->ref.type, dest, realign))
690
+ if (!PushTypedArray(array2, len2, ref, dest, realign))
562
691
  return false;
563
692
  } else if (value.IsString() && !realign) {
564
693
  if (!PushStringArray(value, ref, dest))
@@ -573,13 +702,13 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
573
702
  } break;
574
703
  case PrimitiveKind::Float32: {
575
704
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
576
- float f = CopyNumber<float>(value);
705
+ float f = GetNumber<float>(value);
577
706
  *(float *)dest = f;
578
707
  });
579
708
  } break;
580
709
  case PrimitiveKind::Float64: {
581
710
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
582
- double d = CopyNumber<double>(value);
711
+ double d = GetNumber<double>(value);
583
712
  *(double *)dest = d;
584
713
  });
585
714
  } break;
@@ -624,10 +753,12 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
624
753
  return true;
625
754
  }
626
755
 
627
- bool CallData::PushTypedArray(Napi::TypedArray array, Size len, const TypeInfo *ref, uint8_t *origin, int16_t realign)
756
+ bool CallData::PushTypedArray(Napi::TypedArray array, Size len, const TypeInfo *type, uint8_t *origin, int16_t realign)
628
757
  {
629
758
  RG_ASSERT(array.IsTypedArray());
630
759
 
760
+ const TypeInfo *ref = type->ref.type;
761
+
631
762
  if (RG_UNLIKELY(array.ElementLength() != (size_t)len)) {
632
763
  ThrowError<Napi::Error>(env, "Expected array of length %1, got %2", len, array.ElementLength());
633
764
  return false;
@@ -732,7 +863,7 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
732
863
  ptr = AllocHeap(size, 16);
733
864
 
734
865
  if (directions & 1) {
735
- if (!PushNormalArray(array, len, type->ref.type, ptr))
866
+ if (!PushNormalArray(array, len, type, ptr))
736
867
  return false;
737
868
  } else {
738
869
  memset(ptr, 0, size);
@@ -746,7 +877,7 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
746
877
  ptr = AllocHeap(size, 16);
747
878
 
748
879
  if (directions & 1) {
749
- if (!PushTypedArray(array, len, type->ref.type, ptr))
880
+ if (!PushTypedArray(array, len, type, ptr))
750
881
  return false;
751
882
  } else {
752
883
  if (RG_UNLIKELY(array.TypedArrayType() != GetTypedArrayType(type->ref.type) &&
@@ -813,13 +944,13 @@ void CallData::PopOutArguments()
813
944
 
814
945
  if (value.IsArray()) {
815
946
  Napi::Array array(env, value);
816
- PopNormalArray(array, out.ptr, out.type);
947
+ DecodeNormalArray(array, out.ptr, out.type);
817
948
  } else if (value.IsTypedArray()) {
818
949
  Napi::TypedArray array(env, value);
819
- PopTypedArray(array, out.ptr, out.type);
950
+ DecodeTypedArray(array, out.ptr, out.type);
820
951
  } else {
821
952
  Napi::Object obj(env, value);
822
- PopObject(obj, out.ptr, out.type);
953
+ DecodeObject(obj, out.ptr, out.type);
823
954
  }
824
955
 
825
956
  if (out.type->dispose) {
@@ -845,531 +976,13 @@ void *CallData::ReserveTrampoline(const FunctionInfo *proto, Napi::Function func
845
976
 
846
977
  trampoline->proto = proto;
847
978
  trampoline->func.Reset(func, 1);
979
+ trampoline->recv.Reset();
848
980
  trampoline->generation = (int32_t)mem->generation;
849
981
 
850
982
  void *ptr = GetTrampoline(idx, proto);
851
983
  return ptr;
852
984
  }
853
985
 
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
986
  void CallData::DumpForward() const
1374
987
  {
1375
988
  PrintLn(stderr, "%!..+---- %1 (%2) ----%!0", func->name, CallConventionNames[(int)func->convention]);