koffi 1.3.0 → 1.3.3

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 (94) hide show
  1. package/CMakeLists.txt +32 -4
  2. package/ChangeLog.md +79 -0
  3. package/build/qemu/1.3.3/koffi_darwin_arm64.tar.gz +0 -0
  4. package/build/qemu/1.3.3/koffi_darwin_x64.tar.gz +0 -0
  5. package/build/qemu/1.3.3/koffi_freebsd_arm64.tar.gz +0 -0
  6. package/build/qemu/1.3.3/koffi_freebsd_ia32.tar.gz +0 -0
  7. package/build/qemu/1.3.3/koffi_freebsd_x64.tar.gz +0 -0
  8. package/build/qemu/1.3.3/koffi_linux_arm32hf.tar.gz +0 -0
  9. package/build/qemu/1.3.3/koffi_linux_arm64.tar.gz +0 -0
  10. package/build/qemu/1.3.3/koffi_linux_ia32.tar.gz +0 -0
  11. package/build/qemu/1.3.3/koffi_linux_riscv64hf64.tar.gz +0 -0
  12. package/build/qemu/1.3.3/koffi_linux_x64.tar.gz +0 -0
  13. package/build/qemu/1.3.3/koffi_openbsd_ia32.tar.gz +0 -0
  14. package/build/qemu/1.3.3/koffi_openbsd_x64.tar.gz +0 -0
  15. package/build/qemu/1.3.3/koffi_win32_arm64.tar.gz +0 -0
  16. package/build/qemu/1.3.3/koffi_win32_ia32.tar.gz +0 -0
  17. package/build/qemu/1.3.3/koffi_win32_x64.tar.gz +0 -0
  18. package/doc/_static/perf_linux_20220623.png +0 -0
  19. package/doc/_static/perf_linux_20220623_2.png +0 -0
  20. package/doc/_static/perf_windows_20220623.png +0 -0
  21. package/doc/_static/perf_windows_20220623_2.png +0 -0
  22. package/doc/benchmarks.md +40 -36
  23. package/doc/benchmarks.xlsx +0 -0
  24. package/doc/changes.md +2 -0
  25. package/doc/conf.py +10 -3
  26. package/doc/contribute.md +16 -0
  27. package/doc/dist/doctrees/benchmarks.doctree +0 -0
  28. package/doc/dist/doctrees/changes.doctree +0 -0
  29. package/doc/dist/doctrees/contribute.doctree +0 -0
  30. package/doc/dist/doctrees/environment.pickle +0 -0
  31. package/doc/dist/doctrees/functions.doctree +0 -0
  32. package/doc/dist/doctrees/index.doctree +0 -0
  33. package/doc/dist/doctrees/platforms.doctree +0 -0
  34. package/doc/dist/html/_sources/benchmarks.md.txt +40 -36
  35. package/doc/dist/html/_sources/changes.md.txt +2 -0
  36. package/doc/dist/html/_sources/contribute.md.txt +16 -0
  37. package/doc/dist/html/_sources/functions.md.txt +2 -0
  38. package/doc/dist/html/_sources/index.rst.txt +2 -1
  39. package/doc/dist/html/_sources/platforms.md.txt +2 -0
  40. package/doc/dist/html/_static/perf_linux_20220623.png +0 -0
  41. package/doc/dist/html/_static/perf_linux_20220623_2.png +0 -0
  42. package/doc/dist/html/_static/perf_windows_20220623.png +0 -0
  43. package/doc/dist/html/_static/perf_windows_20220623_2.png +0 -0
  44. package/doc/dist/html/benchmarks.html +52 -20
  45. package/doc/dist/html/changes.html +369 -0
  46. package/doc/dist/html/contribute.html +24 -2
  47. package/doc/dist/html/functions.html +2 -0
  48. package/doc/dist/html/genindex.html +1 -0
  49. package/doc/dist/html/index.html +15 -3
  50. package/doc/dist/html/memory.html +1 -0
  51. package/doc/dist/html/objects.inv +0 -0
  52. package/doc/dist/html/platforms.html +3 -1
  53. package/doc/dist/html/search.html +1 -0
  54. package/doc/dist/html/searchindex.js +1 -1
  55. package/doc/dist/html/start.html +1 -0
  56. package/doc/dist/html/types.html +1 -0
  57. package/doc/functions.md +2 -0
  58. package/doc/index.rst +2 -1
  59. package/doc/platforms.md +2 -0
  60. package/package.json +4 -3
  61. package/qemu/qemu.js +2 -1
  62. package/src/abi_arm32.cc +9 -9
  63. package/src/abi_arm64.cc +9 -9
  64. package/src/abi_riscv64.cc +9 -9
  65. package/src/abi_x64_sysv.cc +9 -9
  66. package/src/abi_x64_sysv_fwd.S +14 -4
  67. package/src/abi_x64_win.cc +9 -9
  68. package/src/abi_x86.cc +9 -9
  69. package/src/abi_x86_fwd.S +6 -4
  70. package/src/call.cc +10 -10
  71. package/src/call.hh +6 -0
  72. package/src/ffi.cc +3 -1
  73. package/src/parser.cc +1 -1
  74. package/src/util.hh +21 -1
  75. package/test/CMakeLists.txt +1 -1
  76. package/test/misc.c +20 -0
  77. package/test/sync.js +13 -3
  78. package/vendor/libcc/libcc.cc +17 -5
  79. package/vendor/libcc/libcc.hh +33 -1
  80. package/build/qemu/1.3.0/koffi_darwin_arm64.tar.gz +0 -0
  81. package/build/qemu/1.3.0/koffi_darwin_x64.tar.gz +0 -0
  82. package/build/qemu/1.3.0/koffi_freebsd_arm64.tar.gz +0 -0
  83. package/build/qemu/1.3.0/koffi_freebsd_ia32.tar.gz +0 -0
  84. package/build/qemu/1.3.0/koffi_freebsd_x64.tar.gz +0 -0
  85. package/build/qemu/1.3.0/koffi_linux_arm32hf.tar.gz +0 -0
  86. package/build/qemu/1.3.0/koffi_linux_arm64.tar.gz +0 -0
  87. package/build/qemu/1.3.0/koffi_linux_ia32.tar.gz +0 -0
  88. package/build/qemu/1.3.0/koffi_linux_riscv64hf64.tar.gz +0 -0
  89. package/build/qemu/1.3.0/koffi_linux_x64.tar.gz +0 -0
  90. package/build/qemu/1.3.0/koffi_openbsd_ia32.tar.gz +0 -0
  91. package/build/qemu/1.3.0/koffi_openbsd_x64.tar.gz +0 -0
  92. package/build/qemu/1.3.0/koffi_win32_arm64.tar.gz +0 -0
  93. package/build/qemu/1.3.0/koffi_win32_ia32.tar.gz +0 -0
  94. package/build/qemu/1.3.0/koffi_win32_x64.tar.gz +0 -0
@@ -35,13 +35,15 @@
35
35
  .global SYMBOL(ForwardCallXGD)
36
36
  .global SYMBOL(ForwardCallXDD)
37
37
 
38
+ #define ENDBR64 .byte 0xf3, 0x0f, 0x1e, 0xfa
39
+
38
40
  # Copy function pointer to R11, in order to save it through argument forwarding.
39
41
  # Also make a copy of the SP to CallData::old_sp because the callback system might need it.
40
42
  # Save RSP in RBX (non-volatile), and use carefully assembled stack provided by caller.
41
43
  .macro prologue
42
44
  .cfi_startproc
43
45
  .cfi_def_cfa rsp, 8
44
- endbr64
46
+ ENDBR64
45
47
  movq %rdi, %r11
46
48
  pushq %rbx
47
49
  .cfi_def_cfa rsp, 16
@@ -196,7 +198,7 @@ SYMBOL(ForwardCallXDD):
196
198
  .macro trampoline id
197
199
  .cfi_startproc
198
200
  .cfi_def_cfa rsp, 8
199
- endbr64
201
+ ENDBR64
200
202
  subq $152, %rsp
201
203
  .cfi_def_cfa rsp, 160
202
204
  movq %rdi, 0(%rsp)
@@ -209,7 +211,11 @@ SYMBOL(ForwardCallXDD):
209
211
  movq %rsp, %rsi
210
212
  leaq 160(%rsp), %rdx
211
213
  leaq 112(%rsp), %rcx
214
+ #ifdef __linux__
215
+ call *RelayCallback@GOTPCREL(%rip)
216
+ #else
212
217
  call SYMBOL(RelayCallback)
218
+ #endif
213
219
  movq 112(%rsp), %rax
214
220
  movq 120(%rsp), %rdx
215
221
  addq $152, %rsp
@@ -222,7 +228,7 @@ SYMBOL(ForwardCallXDD):
222
228
  .macro trampoline_xmm id
223
229
  .cfi_startproc
224
230
  .cfi_def_cfa rsp, 8
225
- endbr64
231
+ ENDBR64
226
232
  subq $152, %rsp
227
233
  .cfi_def_cfa rsp, 160
228
234
  movq %rdi, 0(%rsp)
@@ -243,7 +249,11 @@ SYMBOL(ForwardCallXDD):
243
249
  movq %rsp, %rsi
244
250
  leaq 160(%rsp), %rdx
245
251
  leaq 112(%rsp), %rcx
252
+ #ifdef __linux__
253
+ call *RelayCallback@GOTPCREL(%rip)
254
+ #else
246
255
  call SYMBOL(RelayCallback)
256
+ #endif
247
257
  movq 112(%rsp), %rax
248
258
  movq 120(%rsp), %rdx
249
259
  movsd 128(%rsp), %xmm0
@@ -328,7 +338,7 @@ SYMBOL(TrampolineX15):
328
338
  SYMBOL(CallSwitchStack):
329
339
  .cfi_startproc
330
340
  .cfi_def_cfa rsp, 8
331
- endbr64
341
+ ENDBR64
332
342
  push %rbx
333
343
  .cfi_def_cfa rsp, 16
334
344
  movq %rsp, %rbx
@@ -299,14 +299,14 @@ Napi::Value CallData::Complete()
299
299
  switch (func->ret.type->primitive) {
300
300
  case PrimitiveKind::Void: return env.Null();
301
301
  case PrimitiveKind::Bool: return Napi::Boolean::New(env, result.u32);
302
- case PrimitiveKind::Int8:
303
- case PrimitiveKind::UInt8:
304
- case PrimitiveKind::Int16:
305
- case PrimitiveKind::UInt16:
306
- case PrimitiveKind::Int32:
302
+ case PrimitiveKind::Int8: return Napi::Number::New(env, (double)result.i8);
303
+ case PrimitiveKind::UInt8: return Napi::Number::New(env, (double)result.u8);
304
+ case PrimitiveKind::Int16: return Napi::Number::New(env, (double)result.i16);
305
+ case PrimitiveKind::UInt16: return Napi::Number::New(env, (double)result.u16);
306
+ case PrimitiveKind::Int32: return Napi::Number::New(env, (double)result.i32);
307
307
  case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)result.u32);
308
- case PrimitiveKind::Int64: return Napi::BigInt::New(env, (int64_t)result.u64);
309
- case PrimitiveKind::UInt64: return Napi::BigInt::New(env, result.u64);
308
+ case PrimitiveKind::Int64: return NewBigInt(env, result.i64);
309
+ case PrimitiveKind::UInt64: return NewBigInt(env, result.u64);
310
310
  case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
311
311
  case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
312
312
  case PrimitiveKind::Pointer:
@@ -409,14 +409,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
409
409
  int64_t v = *(int64_t *)(j < 4 ? gpr_ptr + j : args_ptr);
410
410
  args_ptr += (j >= 4);
411
411
 
412
- Napi::Value arg = Napi::BigInt::New(env, v);
412
+ Napi::Value arg = NewBigInt(env, v);
413
413
  arguments.Append(arg);
414
414
  } break;
415
415
  case PrimitiveKind::UInt64: {
416
416
  uint64_t v = *(uint64_t *)(j < 4 ? gpr_ptr + j : args_ptr);
417
417
  args_ptr += (j >= 4);
418
418
 
419
- Napi::Value arg = Napi::BigInt::New(env, v);
419
+ Napi::Value arg = NewBigInt(env, v);
420
420
  arguments.Append(arg);
421
421
  } break;
422
422
  case PrimitiveKind::String: {
package/src/abi_x86.cc CHANGED
@@ -373,14 +373,14 @@ Napi::Value CallData::Complete()
373
373
  switch (func->ret.type->primitive) {
374
374
  case PrimitiveKind::Void: return env.Null();
375
375
  case PrimitiveKind::Bool: return Napi::Boolean::New(env, result.u32);
376
- case PrimitiveKind::Int8:
377
- case PrimitiveKind::UInt8:
378
- case PrimitiveKind::Int16:
379
- case PrimitiveKind::UInt16:
380
- case PrimitiveKind::Int32:
376
+ case PrimitiveKind::Int8: return Napi::Number::New(env, (double)result.i8);
377
+ case PrimitiveKind::UInt8: return Napi::Number::New(env, (double)result.u8);
378
+ case PrimitiveKind::Int16: return Napi::Number::New(env, (double)result.i16);
379
+ case PrimitiveKind::UInt16: return Napi::Number::New(env, (double)result.u16);
380
+ case PrimitiveKind::Int32: return Napi::Number::New(env, (double)result.i32);
381
381
  case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)result.u32);
382
- case PrimitiveKind::Int64: return Napi::BigInt::New(env, (int64_t)result.u64);
383
- case PrimitiveKind::UInt64: return Napi::BigInt::New(env, result.u64);
382
+ case PrimitiveKind::Int64: return NewBigInt(env, result.i64);
383
+ case PrimitiveKind::UInt64: return NewBigInt(env, result.u64);
384
384
  case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
385
385
  case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
386
386
  case PrimitiveKind::Pointer:
@@ -485,14 +485,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
485
485
  int64_t v = *(int64_t *)args_ptr;
486
486
  args_ptr += 2;
487
487
 
488
- Napi::Value arg = Napi::BigInt::New(env, v);
488
+ Napi::Value arg = NewBigInt(env, v);
489
489
  arguments.Append(arg);
490
490
  } break;
491
491
  case PrimitiveKind::UInt64: {
492
492
  uint64_t v = *(uint64_t *)args_ptr;
493
493
  args_ptr += 2;
494
494
 
495
- Napi::Value arg = Napi::BigInt::New(env, v);
495
+ Napi::Value arg = NewBigInt(env, v);
496
496
  arguments.Append(arg);
497
497
  } break;
498
498
  case PrimitiveKind::String: {
package/src/abi_x86_fwd.S CHANGED
@@ -18,13 +18,15 @@
18
18
  .global ForwardCallRF
19
19
  .global ForwardCallRD
20
20
 
21
+ #define ENDBR32 .byte 0xf3, 0x0f, 0x1e, 0xfb
22
+
21
23
  # Copy function pointer to EAX, in order to save it through argument forwarding.
22
24
  # Also make a copy of the SP to CallData::old_sp because the callback system might need it.
23
25
  # Save ESP in EBX (non-volatile), and use carefully assembled stack provided by caller.
24
26
  .macro prologue
25
27
  .cfi_startproc
26
28
  .cfi_def_cfa esp, 4
27
- endbr32
29
+ ENDBR32
28
30
  push %ebx
29
31
  .cfi_def_cfa esp, 8
30
32
  movl %esp, %ebx
@@ -125,7 +127,7 @@ ForwardCallRD:
125
127
  .macro trampoline id
126
128
  .cfi_startproc
127
129
  .cfi_def_cfa esp, 4
128
- endbr32
130
+ ENDBR32
129
131
  sub $44, %esp
130
132
  .cfi_def_cfa esp, 48
131
133
  movl $\id, 0(%esp)
@@ -153,7 +155,7 @@ ForwardCallRD:
153
155
  .macro trampoline_x87 id
154
156
  .cfi_startproc
155
157
  .cfi_def_cfa esp, 4
156
- endbr32
158
+ ENDBR32
157
159
  sub $44, %esp
158
160
  .cfi_def_cfa esp, 48
159
161
  movl $\id, 0(%esp)
@@ -260,7 +262,7 @@ TrampolineX15:
260
262
  CallSwitchStack:
261
263
  .cfi_startproc
262
264
  .cfi_def_cfa esp, 4
263
- endbr32
265
+ ENDBR32
264
266
  push %ebx
265
267
  .cfi_def_cfa esp, 8
266
268
  movl %esp, %ebx
package/src/call.cc CHANGED
@@ -248,7 +248,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
248
248
  } break;
249
249
  case PrimitiveKind::Pointer: {
250
250
  if (CheckValueTag(instance, value, member.type)) {
251
- Napi::External external = value.As<Napi::External<void>>();
251
+ Napi::External<void> external = value.As<Napi::External<void>>();
252
252
  void *ptr = external.Data();
253
253
  *(void **)dest = ptr;
254
254
  } else if (IsNullOrUndefined(value)) {
@@ -317,7 +317,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
317
317
  if (RG_UNLIKELY(!ptr))
318
318
  return false;
319
319
  } else if (CheckValueTag(instance, value, member.type)) {
320
- Napi::External external = value.As<Napi::External<void>>();
320
+ Napi::External<void> external = value.As<Napi::External<void>>();
321
321
  ptr = external.Data();
322
322
  } else if (IsNullOrUndefined(value)) {
323
323
  ptr = nullptr;
@@ -452,7 +452,7 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
452
452
  case PrimitiveKind::Pointer: {
453
453
  PUSH_ARRAY(CheckValueTag(instance, value, ref) || IsNullOrUndefined(value), ref->name, {
454
454
  if (!IsNullOrUndefined(value)) {
455
- Napi::External external = value.As<Napi::External<void>>();
455
+ Napi::External<void> external = value.As<Napi::External<void>>();
456
456
  *(void **)dest = external.Data();
457
457
  } else {
458
458
  *(void **)dest = nullptr;
@@ -528,7 +528,7 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
528
528
  if (RG_UNLIKELY(!ptr))
529
529
  return false;
530
530
  } else if (CheckValueTag(instance, value, ref)) {
531
- Napi::External external = value.As<Napi::External<void>>();
531
+ Napi::External<void> external = value.As<Napi::External<void>>();
532
532
  ptr = external.Data();
533
533
  } else if (IsNullOrUndefined(value)) {
534
534
  ptr = nullptr;
@@ -801,11 +801,11 @@ void CallData::PopObject(Napi::Object obj, const uint8_t *origin, const TypeInfo
801
801
  } break;
802
802
  case PrimitiveKind::Int64: {
803
803
  int64_t v = *(int64_t *)src;
804
- obj.Set(member.name, Napi::BigInt::New(env, v));
804
+ obj.Set(member.name, NewBigInt(env, v));
805
805
  } break;
806
806
  case PrimitiveKind::UInt64: {
807
807
  uint64_t v = *(uint64_t *)src;
808
- obj.Set(member.name, Napi::BigInt::New(env, v));
808
+ obj.Set(member.name, NewBigInt(env, v));
809
809
  } break;
810
810
  case PrimitiveKind::String: {
811
811
  const char *str = *(const char **)src;
@@ -914,13 +914,13 @@ void CallData::PopNormalArray(Napi::Array array, const uint8_t *origin, const Ty
914
914
  case PrimitiveKind::Int64: {
915
915
  POP_ARRAY({
916
916
  int64_t v = *(int64_t *)src;
917
- array.Set(i, Napi::BigInt::New(env, v));
917
+ array.Set(i, NewBigInt(env, v));
918
918
  });
919
919
  } break;
920
920
  case PrimitiveKind::UInt64: {
921
921
  POP_ARRAY({
922
922
  uint64_t v = *(uint64_t *)src;
923
- array.Set(i, Napi::BigInt::New(env, v));
923
+ array.Set(i, NewBigInt(env, v));
924
924
  });
925
925
  } break;
926
926
  case PrimitiveKind::String: {
@@ -1078,13 +1078,13 @@ Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int1
1078
1078
  case PrimitiveKind::Int64: {
1079
1079
  POP_ARRAY({
1080
1080
  int64_t v = *(int64_t *)src;
1081
- array.Set(i, Napi::BigInt::New(env, v));
1081
+ array.Set(i, NewBigInt(env, v));
1082
1082
  });
1083
1083
  } break;
1084
1084
  case PrimitiveKind::UInt64: {
1085
1085
  POP_ARRAY({
1086
1086
  uint64_t v = *(uint64_t *)src;
1087
- array.Set(i, Napi::BigInt::New(env, v));
1087
+ array.Set(i, NewBigInt(env, v));
1088
1088
  });
1089
1089
  } break;
1090
1090
  case PrimitiveKind::String: {
package/src/call.hh CHANGED
@@ -50,7 +50,13 @@ class alignas(8) CallData {
50
50
  uint8_t *old_sp;
51
51
 
52
52
  union {
53
+ int8_t i8;
54
+ uint8_t u8;
55
+ int16_t i16;
56
+ uint16_t u16;
57
+ int32_t i32;
53
58
  uint32_t u32;
59
+ int64_t i64;
54
60
  uint64_t u64;
55
61
  float f;
56
62
  double d;
package/src/ffi.cc CHANGED
@@ -116,7 +116,7 @@ static Napi::Value GetSetConfig(const Napi::CallbackInfo &info)
116
116
  return env.Null();
117
117
  }
118
118
 
119
- instance->resident_async_pools = n;
119
+ instance->resident_async_pools = (int)n;
120
120
  } else {
121
121
  ThrowError<Napi::Error>(env, "Unexpected config member '%1'", key.c_str());
122
122
  return env.Null();
@@ -636,6 +636,8 @@ static InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, S
636
636
  #endif
637
637
  RG_CRITICAL(mem->heap.ptr, "Failed to allocate %1 of memory", mem->heap.len);
638
638
 
639
+ mem->depth = 0;
640
+
639
641
  if (instance->memories.len <= instance->resident_async_pools) {
640
642
  instance->memories.Append(mem);
641
643
  } else {
package/src/parser.cc CHANGED
@@ -44,7 +44,7 @@ bool PrototypeParser::Parse(const char *str, FunctionInfo *out_func)
44
44
  out_func->name = ParseIdentifier();
45
45
 
46
46
  Consume("(");
47
- if (offset < tokens.len && tokens[offset] != ")") {
47
+ if (offset < tokens.len && tokens[offset] != ")" && !Match("void")) {
48
48
  for (;;) {
49
49
  ParameterInfo param = {};
50
50
 
package/src/util.hh CHANGED
@@ -89,7 +89,7 @@ static inline bool IsObject(Napi::Value value)
89
89
  int GetTypedArrayType(const TypeInfo *type);
90
90
 
91
91
  template <typename T>
92
- T CopyNumber(const Napi::Value &value)
92
+ T CopyNumber(Napi::Value value)
93
93
  {
94
94
  RG_ASSERT(value.IsNumber() || value.IsBigInt());
95
95
 
@@ -105,6 +105,26 @@ T CopyNumber(const Napi::Value &value)
105
105
  RG_UNREACHABLE();
106
106
  }
107
107
 
108
+ static inline Napi::Value NewBigInt(Napi::Env env, int64_t value)
109
+ {
110
+ if (value <= 9007199254740992ll && value >= -9007199254740992ll) {
111
+ double d = (double)value;
112
+ return Napi::Number::New(env, d);
113
+ } else {
114
+ return Napi::BigInt::New(env, value);
115
+ }
116
+ }
117
+
118
+ static inline Napi::Value NewBigInt(Napi::Env env, uint64_t value)
119
+ {
120
+ if (value <= 9007199254740992ull) {
121
+ double d = (double)value;
122
+ return Napi::Number::New(env, d);
123
+ } else {
124
+ return Napi::BigInt::New(env, value);
125
+ }
126
+ }
127
+
108
128
  int AnalyseFlat(const TypeInfo *type, FunctionRef<void(const TypeInfo *type, int offset, int count)> func);
109
129
 
110
130
  int IsHFA(const TypeInfo *type, int min, int max);
@@ -11,7 +11,7 @@
11
11
  # You should have received a copy of the GNU Affero General Public License
12
12
  # along with this program. If not, see https://www.gnu.org/licenses/.
13
13
 
14
- cmake_minimum_required(VERSION 3.12)
14
+ cmake_minimum_required(VERSION 3.6)
15
15
  project(koffi_test C CXX)
16
16
 
17
17
  if(NOT TARGET koffi)
package/test/misc.c CHANGED
@@ -129,6 +129,26 @@ typedef struct IntContainer {
129
129
  int len;
130
130
  } IntContainer;
131
131
 
132
+ EXPORT int8_t GetMinusOne1(void)
133
+ {
134
+ return -1;
135
+ }
136
+
137
+ EXPORT int16_t GetMinusOne2(void)
138
+ {
139
+ return -1;
140
+ }
141
+
142
+ EXPORT int32_t GetMinusOne4(void)
143
+ {
144
+ return -1;
145
+ }
146
+
147
+ EXPORT int64_t GetMinusOne8(void)
148
+ {
149
+ return -1;
150
+ }
151
+
132
152
  EXPORT void FillPack1(int a, Pack1 *p)
133
153
  {
134
154
  p->a = a;
package/test/sync.js CHANGED
@@ -122,6 +122,10 @@ async function test() {
122
122
  let lib_filename = path.dirname(__filename) + '/build/misc' + koffi.extension;
123
123
  let lib = koffi.load(lib_filename);
124
124
 
125
+ const GetMinusOne1 = lib.func('int8_t GetMinusOne1(void)');
126
+ const GetMinusOne2 = lib.func('int16_t GetMinusOne2(void)');
127
+ const GetMinusOne4 = lib.func('int32_t GetMinusOne4(void)');
128
+ const GetMinusOne8 = lib.func('int64_t GetMinusOne8(void)');
125
129
  const FillPack1 = lib.func('FillPack1', 'void', ['int', koffi.out(koffi.pointer(Pack1))]);
126
130
  const RetPack1 = lib.func('RetPack1', Pack1, ['int']);
127
131
  const AddPack1 = lib.fastcall('AddPack1', 'void', ['int', koffi.inout(koffi.pointer(Pack1))]);
@@ -172,6 +176,12 @@ async function test() {
172
176
  const FillRange = lib.func('void FillRange(int init, int step, _Out_ int *out, int len)');
173
177
  const MultiplyIntegers = lib.func('void MultiplyIntegers(int multiplier, _Inout_ int *values, int len)');
174
178
 
179
+ // Simple signed value returns
180
+ assert.equal(GetMinusOne1(), -1);
181
+ assert.equal(GetMinusOne2(), -1);
182
+ assert.equal(GetMinusOne4(), -1);
183
+ assert.equal(GetMinusOne8(), -1);
184
+
175
185
  // Simple tests with Pack1
176
186
  {
177
187
  let p = {};
@@ -250,9 +260,9 @@ async function test() {
250
260
 
251
261
  // Many parameters
252
262
  {
253
- assert.equal(ConcatenateToInt1(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7), 561239440687n);
254
- assert.equal(ConcatenateToInt4(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7), 561239440687n);
255
- assert.equal(ConcatenateToInt8(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7), 561239440687n);
263
+ assert.equal(ConcatenateToInt1(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7), 561239440687);
264
+ assert.equal(ConcatenateToInt4(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7), 561239440687);
265
+ assert.equal(ConcatenateToInt8(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7), 561239440687);
256
266
  assert.equal(ConcatenateToStr1(5, 6, 1, 2, 3, 9, 4, 4, {i: 0, j: 6, k: 8}, 7), '561239440687');
257
267
  assert.equal(ConcatenateToStr4(5, 6, 1, 2, 3, 9, 4, 4, {i: 0, j: 6, k: 8}, 7), '561239440687');
258
268
  assert.equal(ConcatenateToStr8(5, 6, 1, 2, 3, 9, 4, 4, {i: 0, j: 6, k: 8}, 7), '561239440687');
@@ -20,7 +20,7 @@
20
20
  #include "vendor/brotli/c/include/brotli/decode.h"
21
21
  #include "vendor/brotli/c/include/brotli/encode.h"
22
22
  #endif
23
- #if __has_include("vendor/dragonbox/include/dragonbox/dragonbox.h")
23
+ #if __has_include("vendor/dragonbox/include/dragonbox/dragonbox.h") && __cplusplus >= 201703L
24
24
  #include "vendor/dragonbox/include/dragonbox/dragonbox.h"
25
25
  #endif
26
26
 
@@ -81,6 +81,9 @@
81
81
 
82
82
  extern char **environ;
83
83
  #endif
84
+ #ifdef __linux__
85
+ #include <sys/syscall.h>
86
+ #endif
84
87
  #ifdef __APPLE__
85
88
  #include <sys/random.h>
86
89
  #include <mach-o/dyld.h>
@@ -3741,8 +3744,8 @@ bool ExecuteCommandLine(const char *cmd_line, FunctionRef<Span<const uint8_t>()>
3741
3744
  #if defined(__OpenBSD__) || defined(__FreeBSD__)
3742
3745
  static const pthread_t main_thread = pthread_self();
3743
3746
  #endif
3744
- static std::atomic_bool flag_interrupt = false;
3745
- static std::atomic_bool explicit_interrupt = false;
3747
+ static std::atomic_bool flag_interrupt {false};
3748
+ static std::atomic_bool explicit_interrupt {false};
3746
3749
  static int interrupt_pfd[2] = {-1, -1};
3747
3750
 
3748
3751
  void SetSignalHandler(int signal, void (*func)(int), struct sigaction *prev)
@@ -4165,7 +4168,7 @@ void WaitDelay(int64_t delay)
4165
4168
 
4166
4169
  WaitForResult WaitForInterrupt(int64_t timeout)
4167
4170
  {
4168
- static std::atomic_bool message = false;
4171
+ static std::atomic_bool message {false};
4169
4172
 
4170
4173
  flag_interrupt = true;
4171
4174
  SetSignalHandler(SIGUSR1, [](int) { message = true; });
@@ -4755,8 +4758,17 @@ void FillRandomSafe(void *out_buf, Size len)
4755
4758
  struct { uint32_t key[8]; uint32_t iv[2]; } buf;
4756
4759
 
4757
4760
  memset(rnd_state, 0, RG_SIZE(rnd_state));
4758
- #ifdef _WIN32
4761
+ #if defined(_WIN32)
4759
4762
  RG_CRITICAL(RtlGenRandom(&buf, RG_SIZE(buf)), "RtlGenRandom() failed: %s", GetWin32ErrorString());
4763
+ #elif defined(__linux__)
4764
+ {
4765
+ restart:
4766
+ int ret = syscall(SYS_getrandom, &buf, RG_SIZE(buf), 0);
4767
+ RG_CRITICAL(ret >= 0, "getentropy() failed: %s", strerror(errno));
4768
+
4769
+ if (ret < RG_SIZE(buf))
4770
+ goto restart;
4771
+ }
4760
4772
  #else
4761
4773
  RG_CRITICAL(getentropy(&buf, RG_SIZE(buf)) == 0, "getentropy() failed: %s", strerror(errno));
4762
4774
  #endif
@@ -1204,7 +1204,11 @@ public:
1204
1204
  {
1205
1205
  RemoveFrom(0);
1206
1206
  Grow(other.capacity);
1207
+ #if __cplusplus >= 201703L
1207
1208
  if constexpr(!std::is_trivial<T>::value) {
1209
+ #else
1210
+ if (true) {
1211
+ #endif
1208
1212
  for (Size i = 0; i < other.len; i++) {
1209
1213
  ptr[i] = other.ptr[i];
1210
1214
  }
@@ -1308,7 +1312,11 @@ public:
1308
1312
  Grow(count);
1309
1313
 
1310
1314
  T *first = ptr + len;
1315
+ #if __cplusplus >= 201703L
1311
1316
  if constexpr(!std::is_trivial<T>::value) {
1317
+ #else
1318
+ if (true) {
1319
+ #endif
1312
1320
  for (Size i = 0; i < count; i++) {
1313
1321
  new (ptr + len) T();
1314
1322
  len++;
@@ -1325,7 +1333,11 @@ public:
1325
1333
  Grow();
1326
1334
 
1327
1335
  T *first = ptr + len;
1336
+ #if __cplusplus >= 201703L
1328
1337
  if constexpr(!std::is_trivial<T>::value) {
1338
+ #else
1339
+ if (true) {
1340
+ #endif
1329
1341
  new (ptr + len) T;
1330
1342
  }
1331
1343
  ptr[len++] = value;
@@ -1337,7 +1349,11 @@ public:
1337
1349
 
1338
1350
  T *first = ptr + len;
1339
1351
  for (const T &value: values) {
1352
+ #if __cplusplus >= 201703L
1340
1353
  if constexpr(!std::is_trivial<T>::value) {
1354
+ #else
1355
+ if (true) {
1356
+ #endif
1341
1357
  new (ptr + len) T;
1342
1358
  }
1343
1359
  ptr[len++] = value;
@@ -1349,7 +1365,11 @@ public:
1349
1365
  {
1350
1366
  RG_ASSERT(first >= 0 && first <= len);
1351
1367
 
1368
+ #if __cplusplus >= 201703L
1352
1369
  if constexpr(!std::is_trivial<T>::value) {
1370
+ #else
1371
+ if (true) {
1372
+ #endif
1353
1373
  for (Size i = first; i < len; i++) {
1354
1374
  ptr[i].~T();
1355
1375
  }
@@ -1655,7 +1675,11 @@ private:
1655
1675
  void DeleteValues([[maybe_unused]] iterator_type begin,
1656
1676
  [[maybe_unused]] iterator_type end)
1657
1677
  {
1678
+ #if __cplusplus >= 201703L
1658
1679
  if constexpr(!std::is_trivial<T>::value) {
1680
+ #else
1681
+ if (true) {
1682
+ #endif
1659
1683
  for (iterator_type it = begin; it != end; ++it) {
1660
1684
  it->~T();
1661
1685
  }
@@ -1932,7 +1956,11 @@ public:
1932
1956
  }
1933
1957
  ~HashTable()
1934
1958
  {
1959
+ #if __cplusplus >= 201703L
1935
1960
  if constexpr(std::is_trivial<ValueType>::value) {
1961
+ #else
1962
+ if (false) {
1963
+ #endif
1936
1964
  count = 0;
1937
1965
  Rehash(0);
1938
1966
  } else {
@@ -2102,7 +2130,11 @@ private:
2102
2130
  { return (ValueType *)((const HashTable *)this)->Find(idx, key); }
2103
2131
  const ValueType *Find(Size *idx, const KeyType &key) const
2104
2132
  {
2133
+ #if __cplusplus >= 201703L
2105
2134
  if constexpr(std::is_pointer<ValueType>::value) {
2135
+ #else
2136
+ if (false) {
2137
+ #endif
2106
2138
  while (data[*idx]) {
2107
2139
  const KeyType &it_key = Handler::GetKey(data[*idx]);
2108
2140
  if (Handler::TestKeys(it_key, key))
@@ -3017,7 +3049,7 @@ public:
3017
3049
 
3018
3050
  int repeat = 1;
3019
3051
  int pad_len = 0;
3020
- char pad_char;
3052
+ char pad_char = 0;
3021
3053
 
3022
3054
  FmtArg() = default;
3023
3055
  FmtArg(std::nullptr_t) : type(FmtType::Str1) { u.str1 = "(null)"; }