koffi 2.7.0 → 2.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -192,7 +192,8 @@ const TypeInfo *ResolveType(Napi::Env env, Span<const char> str, int *out_direct
192
192
  {
193
193
  InstanceData *instance = env.GetInstanceData<InstanceData>();
194
194
 
195
- int indirect = 0;
195
+ // Each item can be > 0 for array or 0 for a pointer
196
+ LocalArray<Size, 8> arrays;
196
197
  uint8_t disposables = 0;
197
198
 
198
199
  // Consume parameter direction qualifier
@@ -223,18 +224,18 @@ const TypeInfo *ResolveType(Napi::Env env, Span<const char> str, int *out_direct
223
224
  Span<const char> remain = str;
224
225
 
225
226
  // Skip initial const qualifiers
226
- remain = TrimStr(remain);
227
+ remain = TrimStrLeft(remain);
227
228
  while (SplitIdentifier(remain) == "const") {
228
229
  remain = remain.Take(6, remain.len - 6);
229
- remain = TrimStr(remain);
230
+ remain = TrimStrLeft(remain);
230
231
  }
231
- remain = TrimStr(remain);
232
+ remain = TrimStrLeft(remain);
232
233
 
233
234
  after = remain;
234
235
 
235
236
  // Consume one or more identifiers (e.g. unsigned int)
236
237
  for (;;) {
237
- after = TrimStr(after);
238
+ after = TrimStrLeft(after);
238
239
 
239
240
  Span<const char> token = SplitIdentifier(after);
240
241
  if (!token.len)
@@ -245,26 +246,57 @@ const TypeInfo *ResolveType(Napi::Env env, Span<const char> str, int *out_direct
245
246
  name = TrimStr(MakeSpan(remain.ptr, after.ptr - remain.ptr));
246
247
  }
247
248
 
248
- // Consume pointer indirections
249
+ // Consume type indirections (pointer, array, etc.)
249
250
  while (after.len) {
250
251
  if (after[0] == '*') {
251
252
  after = after.Take(1, after.len - 1);
252
- indirect++;
253
253
 
254
- if (indirect >= RG_SIZE(disposables) * 8) [[unlikely]] {
255
- ThrowError<Napi::Error>(env, "Too many pointer indirections");
254
+ if (!arrays.Available()) [[unlikely]] {
255
+ ThrowError<Napi::Error>(env, "Too many type indirections");
256
256
  return nullptr;
257
257
  }
258
+
259
+ arrays.Append(0);
258
260
  } else if (after[0] == '!') {
259
261
  after = after.Take(1, after.len - 1);
260
- disposables |= (1u << indirect);
262
+ disposables |= (1u << arrays.len);
263
+ } else if (after[0] == '[') {
264
+ after = after.Take(1, after.len - 1);
265
+
266
+ Size len = 0;
267
+
268
+ after = TrimStrLeft(after);
269
+ if (!ParseInt(after, &len, 0, &after) || len < 0) [[unlikely]] {
270
+ ThrowError<Napi::Error>(env, "Invalid array length");
271
+ return nullptr;
272
+ }
273
+ after = TrimStrLeft(after);
274
+ if (!after.len || after[0] != ']') [[unlikely]] {
275
+ ThrowError<Napi::Error>(env, "Expected ']' after array length");
276
+ return nullptr;
277
+ }
278
+ after = after.Take(1, after.len - 1);
279
+
280
+ if (!arrays.Available()) [[unlikely]] {
281
+ ThrowError<Napi::Error>(env, "Too many type indirections");
282
+ return nullptr;
283
+ }
284
+
285
+ arrays.Append(len);
261
286
  } else if (SplitIdentifier(after) == "const") {
262
287
  after = after.Take(6, after.len - 6);
263
288
  } else {
289
+ after = TrimStrRight(after);
290
+
291
+ if (after.len) [[unlikely]] {
292
+ ThrowError<Napi::Error>(env, "Unexpected character '%1' in type specifier", after[0]);
293
+ return nullptr;
294
+ }
295
+
264
296
  break;
265
297
  }
266
298
 
267
- after = TrimStr(after);
299
+ after = TrimStrLeft(after);
268
300
  }
269
301
 
270
302
  const TypeInfo *type = instance->types_map.FindValue(name, nullptr);
@@ -317,11 +349,29 @@ const TypeInfo *ResolveType(Napi::Env env, Span<const char> str, int *out_direct
317
349
  type = copy;
318
350
  }
319
351
 
320
- if (i >= indirect)
352
+ if (i >= arrays.len)
321
353
  break;
354
+ Size len = arrays[i];
322
355
 
323
- type = MakePointerType(instance, type);
324
- RG_ASSERT(type);
356
+ if (len > 0) {
357
+ if (type->flags & (int)TypeFlag::IsIncomplete) [[unlikely]] {
358
+ ThrowError<Napi::TypeError>(env, "Cannot make array of incomplete type");
359
+ return nullptr;
360
+ }
361
+
362
+ if (len > instance->config.max_type_size / type->size) {
363
+ ThrowError<Napi::TypeError>(env, "Array length is too high (max = %1)", instance->config.max_type_size / type->size);
364
+ return nullptr;
365
+ }
366
+
367
+ type = MakeArrayType(instance, type, len);
368
+ RG_ASSERT(type);
369
+ } else {
370
+ RG_ASSERT(!len);
371
+
372
+ type = MakePointerType(instance, type);
373
+ RG_ASSERT(type);
374
+ }
325
375
  }
326
376
 
327
377
  if (type->flags & (int)TypeFlag::IsIncomplete) [[unlikely]] {
@@ -22,15 +22,12 @@
22
22
  #pragma once
23
23
 
24
24
  #include "src/core/libcc/libcc.hh"
25
+ #include "ffi.hh"
25
26
 
26
27
  #include <napi.h>
27
28
 
28
29
  namespace RG {
29
30
 
30
- struct InstanceData;
31
- struct TypeInfo;
32
- struct FunctionInfo;
33
-
34
31
  extern const int TypeInfoMarker;
35
32
  extern const int CastMarker;
36
33
  extern const int MagicUnionMarker;
@@ -21,6 +21,7 @@
21
21
 
22
22
  #ifdef _WIN32
23
23
 
24
+ #include "util.hh"
24
25
  #include "win32.hh"
25
26
 
26
27
  #ifndef NOMINMAX
@@ -24,6 +24,7 @@
24
24
  #include "src/core/libcc/libcc.hh"
25
25
 
26
26
  #include <intrin.h>
27
+ #include <napi.h>
27
28
 
28
29
  namespace RG {
29
30