koffi 1.0.3 → 1.1.0-beta.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 (271) hide show
  1. package/README.md +48 -22
  2. package/build/qemu/1.1.0-beta.0/koffi_darwin_x64.tar.gz +0 -0
  3. package/build/qemu/1.1.0-beta.0/koffi_freebsd_arm64.tar.gz +0 -0
  4. package/build/qemu/1.1.0-beta.0/koffi_freebsd_ia32.tar.gz +0 -0
  5. package/build/qemu/1.1.0-beta.0/koffi_freebsd_x64.tar.gz +0 -0
  6. package/build/qemu/1.1.0-beta.0/koffi_linux_arm.tar.gz +0 -0
  7. package/build/qemu/1.1.0-beta.0/koffi_linux_arm64.tar.gz +0 -0
  8. package/build/qemu/1.1.0-beta.0/koffi_linux_ia32.tar.gz +0 -0
  9. package/build/qemu/1.1.0-beta.0/koffi_linux_x64.tar.gz +0 -0
  10. package/build/qemu/1.1.0-beta.0/koffi_win32_ia32.tar.gz +0 -0
  11. package/build/qemu/1.1.0-beta.0/koffi_win32_x64.tar.gz +0 -0
  12. package/package.json +1 -1
  13. package/qemu/qemu.js +11 -5
  14. package/qemu/registry/machines.json +20 -10
  15. package/src/abi_arm32.cc +130 -215
  16. package/src/abi_arm64.cc +103 -117
  17. package/src/abi_x64_sysv.cc +117 -135
  18. package/src/abi_x64_win.cc +89 -98
  19. package/src/abi_x86.cc +91 -99
  20. package/src/call.cc +164 -40
  21. package/src/call.hh +53 -31
  22. package/src/ffi.cc +163 -19
  23. package/src/ffi.hh +30 -22
  24. package/src/util.cc +0 -127
  25. package/src/util.hh +0 -16
  26. package/test/misc.c +68 -2
  27. package/vendor/libcc/libcc.hh +1 -1
  28. package/build/qemu/1.0.3/koffi_darwin_x64.tar.gz +0 -0
  29. package/build/qemu/1.0.3/koffi_freebsd_arm64.tar.gz +0 -0
  30. package/build/qemu/1.0.3/koffi_freebsd_ia32.tar.gz +0 -0
  31. package/build/qemu/1.0.3/koffi_freebsd_x64.tar.gz +0 -0
  32. package/build/qemu/1.0.3/koffi_linux_arm.tar.gz +0 -0
  33. package/build/qemu/1.0.3/koffi_linux_arm64.tar.gz +0 -0
  34. package/build/qemu/1.0.3/koffi_linux_ia32.tar.gz +0 -0
  35. package/build/qemu/1.0.3/koffi_linux_x64.tar.gz +0 -0
  36. package/build/qemu/1.0.3/koffi_win32_ia32.tar.gz +0 -0
  37. package/build/qemu/1.0.3/koffi_win32_x64.tar.gz +0 -0
  38. package/test/misc.js +0 -180
  39. package/vendor/node-addon-api/CODE_OF_CONDUCT.md +0 -4
  40. package/vendor/node-addon-api/CONTRIBUTING.md +0 -93
  41. package/vendor/node-addon-api/appveyor.yml +0 -37
  42. package/vendor/node-addon-api/benchmark/README.md +0 -47
  43. package/vendor/node-addon-api/benchmark/binding.gyp +0 -25
  44. package/vendor/node-addon-api/benchmark/function_args.cc +0 -217
  45. package/vendor/node-addon-api/benchmark/function_args.js +0 -60
  46. package/vendor/node-addon-api/benchmark/index.js +0 -34
  47. package/vendor/node-addon-api/benchmark/property_descriptor.cc +0 -91
  48. package/vendor/node-addon-api/benchmark/property_descriptor.js +0 -37
  49. package/vendor/node-addon-api/doc/addon.md +0 -163
  50. package/vendor/node-addon-api/doc/array.md +0 -81
  51. package/vendor/node-addon-api/doc/array_buffer.md +0 -155
  52. package/vendor/node-addon-api/doc/async_context.md +0 -86
  53. package/vendor/node-addon-api/doc/async_operations.md +0 -31
  54. package/vendor/node-addon-api/doc/async_worker.md +0 -427
  55. package/vendor/node-addon-api/doc/async_worker_variants.md +0 -557
  56. package/vendor/node-addon-api/doc/bigint.md +0 -97
  57. package/vendor/node-addon-api/doc/boolean.md +0 -68
  58. package/vendor/node-addon-api/doc/buffer.md +0 -150
  59. package/vendor/node-addon-api/doc/callback_scope.md +0 -54
  60. package/vendor/node-addon-api/doc/callbackinfo.md +0 -97
  61. package/vendor/node-addon-api/doc/checker-tool.md +0 -32
  62. package/vendor/node-addon-api/doc/class_property_descriptor.md +0 -123
  63. package/vendor/node-addon-api/doc/cmake-js.md +0 -68
  64. package/vendor/node-addon-api/doc/conversion-tool.md +0 -28
  65. package/vendor/node-addon-api/doc/creating_a_release.md +0 -62
  66. package/vendor/node-addon-api/doc/dataview.md +0 -248
  67. package/vendor/node-addon-api/doc/date.md +0 -68
  68. package/vendor/node-addon-api/doc/env.md +0 -196
  69. package/vendor/node-addon-api/doc/error.md +0 -120
  70. package/vendor/node-addon-api/doc/error_handling.md +0 -254
  71. package/vendor/node-addon-api/doc/escapable_handle_scope.md +0 -80
  72. package/vendor/node-addon-api/doc/external.md +0 -63
  73. package/vendor/node-addon-api/doc/function.md +0 -402
  74. package/vendor/node-addon-api/doc/function_reference.md +0 -238
  75. package/vendor/node-addon-api/doc/generator.md +0 -13
  76. package/vendor/node-addon-api/doc/handle_scope.md +0 -63
  77. package/vendor/node-addon-api/doc/hierarchy.md +0 -91
  78. package/vendor/node-addon-api/doc/instance_wrap.md +0 -408
  79. package/vendor/node-addon-api/doc/maybe.md +0 -76
  80. package/vendor/node-addon-api/doc/memory_management.md +0 -27
  81. package/vendor/node-addon-api/doc/name.md +0 -29
  82. package/vendor/node-addon-api/doc/node-gyp.md +0 -82
  83. package/vendor/node-addon-api/doc/number.md +0 -163
  84. package/vendor/node-addon-api/doc/object.md +0 -411
  85. package/vendor/node-addon-api/doc/object_lifetime_management.md +0 -83
  86. package/vendor/node-addon-api/doc/object_reference.md +0 -117
  87. package/vendor/node-addon-api/doc/object_wrap.md +0 -588
  88. package/vendor/node-addon-api/doc/prebuild_tools.md +0 -16
  89. package/vendor/node-addon-api/doc/promises.md +0 -79
  90. package/vendor/node-addon-api/doc/property_descriptor.md +0 -286
  91. package/vendor/node-addon-api/doc/propertylvalue.md +0 -50
  92. package/vendor/node-addon-api/doc/range_error.md +0 -59
  93. package/vendor/node-addon-api/doc/reference.md +0 -113
  94. package/vendor/node-addon-api/doc/setup.md +0 -110
  95. package/vendor/node-addon-api/doc/string.md +0 -93
  96. package/vendor/node-addon-api/doc/symbol.md +0 -61
  97. package/vendor/node-addon-api/doc/threadsafe.md +0 -121
  98. package/vendor/node-addon-api/doc/threadsafe_function.md +0 -290
  99. package/vendor/node-addon-api/doc/type_error.md +0 -59
  100. package/vendor/node-addon-api/doc/typed_array.md +0 -78
  101. package/vendor/node-addon-api/doc/typed_array_of.md +0 -137
  102. package/vendor/node-addon-api/doc/typed_threadsafe_function.md +0 -306
  103. package/vendor/node-addon-api/doc/value.md +0 -340
  104. package/vendor/node-addon-api/doc/version_management.md +0 -43
  105. package/vendor/node-addon-api/package.json +0 -415
  106. package/vendor/node-addon-api/test/README.md +0 -91
  107. package/vendor/node-addon-api/test/addon.cc +0 -36
  108. package/vendor/node-addon-api/test/addon.js +0 -11
  109. package/vendor/node-addon-api/test/addon_build/index.js +0 -49
  110. package/vendor/node-addon-api/test/addon_build/tpl/addon.cc +0 -17
  111. package/vendor/node-addon-api/test/addon_build/tpl/binding.gyp +0 -62
  112. package/vendor/node-addon-api/test/addon_build/tpl/index.js +0 -9
  113. package/vendor/node-addon-api/test/addon_build/tpl/package.json +0 -11
  114. package/vendor/node-addon-api/test/addon_data.cc +0 -99
  115. package/vendor/node-addon-api/test/addon_data.js +0 -46
  116. package/vendor/node-addon-api/test/array_buffer.cc +0 -243
  117. package/vendor/node-addon-api/test/array_buffer.js +0 -69
  118. package/vendor/node-addon-api/test/async_context.cc +0 -36
  119. package/vendor/node-addon-api/test/async_context.js +0 -122
  120. package/vendor/node-addon-api/test/async_progress_queue_worker.cc +0 -83
  121. package/vendor/node-addon-api/test/async_progress_queue_worker.js +0 -46
  122. package/vendor/node-addon-api/test/async_progress_worker.cc +0 -134
  123. package/vendor/node-addon-api/test/async_progress_worker.js +0 -61
  124. package/vendor/node-addon-api/test/async_worker.cc +0 -106
  125. package/vendor/node-addon-api/test/async_worker.js +0 -179
  126. package/vendor/node-addon-api/test/async_worker_nocallback.js +0 -13
  127. package/vendor/node-addon-api/test/async_worker_persistent.cc +0 -63
  128. package/vendor/node-addon-api/test/async_worker_persistent.js +0 -24
  129. package/vendor/node-addon-api/test/basic_types/array.cc +0 -40
  130. package/vendor/node-addon-api/test/basic_types/array.js +0 -35
  131. package/vendor/node-addon-api/test/basic_types/boolean.cc +0 -38
  132. package/vendor/node-addon-api/test/basic_types/boolean.js +0 -35
  133. package/vendor/node-addon-api/test/basic_types/number.cc +0 -99
  134. package/vendor/node-addon-api/test/basic_types/number.js +0 -114
  135. package/vendor/node-addon-api/test/basic_types/value.cc +0 -120
  136. package/vendor/node-addon-api/test/basic_types/value.js +0 -133
  137. package/vendor/node-addon-api/test/bigint.cc +0 -91
  138. package/vendor/node-addon-api/test/bigint.js +0 -53
  139. package/vendor/node-addon-api/test/binding-swallowexcept.cc +0 -12
  140. package/vendor/node-addon-api/test/binding.cc +0 -173
  141. package/vendor/node-addon-api/test/binding.gyp +0 -124
  142. package/vendor/node-addon-api/test/buffer.cc +0 -183
  143. package/vendor/node-addon-api/test/buffer.js +0 -69
  144. package/vendor/node-addon-api/test/callbackscope.cc +0 -22
  145. package/vendor/node-addon-api/test/callbackscope.js +0 -49
  146. package/vendor/node-addon-api/test/common/index.js +0 -114
  147. package/vendor/node-addon-api/test/common/test_helper.h +0 -71
  148. package/vendor/node-addon-api/test/dataview/dataview.cc +0 -48
  149. package/vendor/node-addon-api/test/dataview/dataview.js +0 -35
  150. package/vendor/node-addon-api/test/dataview/dataview_read_write.cc +0 -115
  151. package/vendor/node-addon-api/test/dataview/dataview_read_write.js +0 -90
  152. package/vendor/node-addon-api/test/date.cc +0 -44
  153. package/vendor/node-addon-api/test/date.js +0 -18
  154. package/vendor/node-addon-api/test/env_cleanup.cc +0 -88
  155. package/vendor/node-addon-api/test/env_cleanup.js +0 -56
  156. package/vendor/node-addon-api/test/error.cc +0 -287
  157. package/vendor/node-addon-api/test/error.js +0 -81
  158. package/vendor/node-addon-api/test/error_handling_for_primitives.cc +0 -13
  159. package/vendor/node-addon-api/test/error_handling_for_primitives.js +0 -29
  160. package/vendor/node-addon-api/test/error_terminating_environment.js +0 -95
  161. package/vendor/node-addon-api/test/external.cc +0 -81
  162. package/vendor/node-addon-api/test/external.js +0 -88
  163. package/vendor/node-addon-api/test/function.cc +0 -324
  164. package/vendor/node-addon-api/test/function.js +0 -133
  165. package/vendor/node-addon-api/test/function_reference.cc +0 -202
  166. package/vendor/node-addon-api/test/function_reference.js +0 -157
  167. package/vendor/node-addon-api/test/globalObject/global_object.cc +0 -61
  168. package/vendor/node-addon-api/test/globalObject/global_object_delete_property.cc +0 -31
  169. package/vendor/node-addon-api/test/globalObject/global_object_delete_property.js +0 -61
  170. package/vendor/node-addon-api/test/globalObject/global_object_get_property.cc +0 -40
  171. package/vendor/node-addon-api/test/globalObject/global_object_get_property.js +0 -57
  172. package/vendor/node-addon-api/test/globalObject/global_object_has_own_property.cc +0 -28
  173. package/vendor/node-addon-api/test/globalObject/global_object_has_own_property.js +0 -48
  174. package/vendor/node-addon-api/test/globalObject/global_object_set_property.cc +0 -31
  175. package/vendor/node-addon-api/test/globalObject/global_object_set_property.js +0 -58
  176. package/vendor/node-addon-api/test/handlescope.cc +0 -60
  177. package/vendor/node-addon-api/test/handlescope.js +0 -14
  178. package/vendor/node-addon-api/test/index.js +0 -159
  179. package/vendor/node-addon-api/test/maybe/check.cc +0 -23
  180. package/vendor/node-addon-api/test/maybe/index.js +0 -38
  181. package/vendor/node-addon-api/test/memory_management.cc +0 -17
  182. package/vendor/node-addon-api/test/memory_management.js +0 -9
  183. package/vendor/node-addon-api/test/movable_callbacks.cc +0 -23
  184. package/vendor/node-addon-api/test/movable_callbacks.js +0 -21
  185. package/vendor/node-addon-api/test/name.cc +0 -108
  186. package/vendor/node-addon-api/test/name.js +0 -59
  187. package/vendor/node-addon-api/test/napi_child.js +0 -14
  188. package/vendor/node-addon-api/test/object/delete_property.cc +0 -38
  189. package/vendor/node-addon-api/test/object/delete_property.js +0 -41
  190. package/vendor/node-addon-api/test/object/finalizer.cc +0 -29
  191. package/vendor/node-addon-api/test/object/finalizer.js +0 -28
  192. package/vendor/node-addon-api/test/object/get_property.cc +0 -34
  193. package/vendor/node-addon-api/test/object/get_property.js +0 -40
  194. package/vendor/node-addon-api/test/object/has_own_property.cc +0 -34
  195. package/vendor/node-addon-api/test/object/has_own_property.js +0 -34
  196. package/vendor/node-addon-api/test/object/has_property.cc +0 -38
  197. package/vendor/node-addon-api/test/object/has_property.js +0 -37
  198. package/vendor/node-addon-api/test/object/object.cc +0 -350
  199. package/vendor/node-addon-api/test/object/object.js +0 -217
  200. package/vendor/node-addon-api/test/object/object_deprecated.cc +0 -66
  201. package/vendor/node-addon-api/test/object/object_deprecated.js +0 -47
  202. package/vendor/node-addon-api/test/object/object_freeze_seal.cc +0 -25
  203. package/vendor/node-addon-api/test/object/object_freeze_seal.js +0 -61
  204. package/vendor/node-addon-api/test/object/set_property.cc +0 -45
  205. package/vendor/node-addon-api/test/object/set_property.js +0 -30
  206. package/vendor/node-addon-api/test/object/subscript_operator.cc +0 -58
  207. package/vendor/node-addon-api/test/object/subscript_operator.js +0 -17
  208. package/vendor/node-addon-api/test/object_reference.cc +0 -219
  209. package/vendor/node-addon-api/test/object_reference.js +0 -259
  210. package/vendor/node-addon-api/test/objectwrap.cc +0 -268
  211. package/vendor/node-addon-api/test/objectwrap.js +0 -284
  212. package/vendor/node-addon-api/test/objectwrap_constructor_exception.cc +0 -26
  213. package/vendor/node-addon-api/test/objectwrap_constructor_exception.js +0 -18
  214. package/vendor/node-addon-api/test/objectwrap_function.cc +0 -45
  215. package/vendor/node-addon-api/test/objectwrap_function.js +0 -22
  216. package/vendor/node-addon-api/test/objectwrap_multiple_inheritance.cc +0 -30
  217. package/vendor/node-addon-api/test/objectwrap_multiple_inheritance.js +0 -13
  218. package/vendor/node-addon-api/test/objectwrap_removewrap.cc +0 -45
  219. package/vendor/node-addon-api/test/objectwrap_removewrap.js +0 -40
  220. package/vendor/node-addon-api/test/objectwrap_worker_thread.js +0 -19
  221. package/vendor/node-addon-api/test/promise.cc +0 -29
  222. package/vendor/node-addon-api/test/promise.js +0 -18
  223. package/vendor/node-addon-api/test/reference.cc +0 -24
  224. package/vendor/node-addon-api/test/reference.js +0 -14
  225. package/vendor/node-addon-api/test/run_script.cc +0 -56
  226. package/vendor/node-addon-api/test/run_script.js +0 -45
  227. package/vendor/node-addon-api/test/symbol.cc +0 -79
  228. package/vendor/node-addon-api/test/symbol.js +0 -73
  229. package/vendor/node-addon-api/test/testUtil.js +0 -54
  230. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function.cc +0 -195
  231. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function.js +0 -188
  232. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ctx.cc +0 -63
  233. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ctx.js +0 -12
  234. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_existing_tsfn.cc +0 -115
  235. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_existing_tsfn.js +0 -14
  236. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ptr.cc +0 -26
  237. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ptr.js +0 -7
  238. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_sum.cc +0 -225
  239. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_sum.js +0 -59
  240. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_unref.cc +0 -42
  241. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_unref.js +0 -53
  242. package/vendor/node-addon-api/test/thunking_manual.cc +0 -140
  243. package/vendor/node-addon-api/test/thunking_manual.js +0 -17
  244. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function.cc +0 -215
  245. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function.js +0 -188
  246. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ctx.cc +0 -68
  247. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ctx.js +0 -12
  248. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_existing_tsfn.cc +0 -127
  249. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_existing_tsfn.js +0 -14
  250. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ptr.cc +0 -28
  251. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ptr.js +0 -7
  252. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_sum.cc +0 -237
  253. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_sum.js +0 -59
  254. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_unref.cc +0 -53
  255. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_unref.js +0 -53
  256. package/vendor/node-addon-api/test/typedarray-bigint.js +0 -58
  257. package/vendor/node-addon-api/test/typedarray.cc +0 -216
  258. package/vendor/node-addon-api/test/typedarray.js +0 -69
  259. package/vendor/node-addon-api/test/version_management.cc +0 -27
  260. package/vendor/node-addon-api/test/version_management.js +0 -31
  261. package/vendor/node-addon-api/unit-test/README.md +0 -28
  262. package/vendor/node-addon-api/unit-test/binding-file-template.js +0 -39
  263. package/vendor/node-addon-api/unit-test/binding.gyp +0 -72
  264. package/vendor/node-addon-api/unit-test/exceptions.js +0 -32
  265. package/vendor/node-addon-api/unit-test/generate-binding-cc.js +0 -61
  266. package/vendor/node-addon-api/unit-test/injectTestParams.js +0 -101
  267. package/vendor/node-addon-api/unit-test/listOfTestModules.js +0 -88
  268. package/vendor/node-addon-api/unit-test/matchModules.js +0 -65
  269. package/vendor/node-addon-api/unit-test/setup.js +0 -13
  270. package/vendor/node-addon-api/unit-test/spawnTask.js +0 -26
  271. package/vendor/node-addon-api/unit-test/test.js +0 -30
package/src/call.cc CHANGED
@@ -20,19 +20,24 @@
20
20
 
21
21
  namespace RG {
22
22
 
23
- CallData::CallData(Napi::Env env, InstanceData *instance, const FunctionInfo *func)
24
- : env(env), instance(instance), func(func),
25
- stack_mem(&instance->stack_mem), heap_mem(&instance->heap_mem),
26
- old_stack_mem(instance->stack_mem), old_heap_mem(instance->heap_mem)
23
+ CallData::CallData(Napi::Env env, const FunctionInfo *func, InstanceMemory *mem, bool debug)
24
+ : env(env), instance(env.GetInstanceData<InstanceData>()), func(func), debug(debug),
25
+ mem(mem), old_stack_mem(mem->stack), old_heap_mem(mem->heap)
27
26
  {
28
- RG_ASSERT(AlignUp(stack_mem->ptr, 16) == stack_mem->ptr);
29
- RG_ASSERT(AlignUp(stack_mem->end(), 16) == stack_mem->end());
27
+ mem->depth++;
28
+
29
+ RG_ASSERT(AlignUp(mem->stack.ptr, 16) == mem->stack.ptr);
30
+ RG_ASSERT(AlignUp(mem->stack.end(), 16) == mem->stack.end());
30
31
  }
31
32
 
32
33
  CallData::~CallData()
33
34
  {
34
- instance->stack_mem = old_stack_mem;
35
- instance->heap_mem = old_heap_mem;
35
+ mem->stack = old_stack_mem;
36
+ mem->heap = old_heap_mem;
37
+
38
+ if (!--mem->depth && mem->temporary) {
39
+ delete mem;
40
+ }
36
41
  }
37
42
 
38
43
  const char *CallData::PushString(const Napi::Value &value)
@@ -45,8 +50,8 @@ const char *CallData::PushString(const Napi::Value &value)
45
50
  size_t len = 0;
46
51
  napi_status status;
47
52
 
48
- buf.ptr = (char *)heap_mem->ptr;
49
- buf.len = std::max((Size)0, heap_mem->len - Kibibytes(32));
53
+ buf.ptr = (char *)mem->heap.ptr;
54
+ buf.len = std::max((Size)0, mem->heap.len - Kibibytes(32));
50
55
 
51
56
  status = napi_get_value_string_utf8(env, value, buf.ptr, (size_t)buf.len, &len);
52
57
  RG_ASSERT(status == napi_ok);
@@ -54,15 +59,15 @@ const char *CallData::PushString(const Napi::Value &value)
54
59
  len++;
55
60
 
56
61
  if (RG_LIKELY(len < (size_t)buf.len)) {
57
- heap_mem->ptr += (Size)len;
58
- heap_mem->len -= (Size)len;
62
+ mem->heap.ptr += (Size)len;
63
+ mem->heap.len -= (Size)len;
59
64
  } else {
60
65
  status = napi_get_value_string_utf8(env, value, nullptr, 0, &len);
61
66
  RG_ASSERT(status == napi_ok);
62
67
 
63
68
  len++;
64
69
 
65
- buf.ptr = (char *)Allocator::Allocate(&big_alloc, (Size)len);
70
+ buf.ptr = (char *)Allocator::Allocate(&mem->big_alloc, (Size)len);
66
71
  buf.len = (Size)len;
67
72
 
68
73
  status = napi_get_value_string_utf8(env, value, buf.ptr, (size_t)buf.len, &len);
@@ -82,8 +87,8 @@ const char16_t *CallData::PushString16(const Napi::Value &value)
82
87
  size_t len = 0;
83
88
  napi_status status;
84
89
 
85
- buf.ptr = (char16_t *)heap_mem->ptr;
86
- buf.len = std::max((Size)0, heap_mem->len - Kibibytes(32)) / 2;
90
+ buf.ptr = (char16_t *)mem->heap.ptr;
91
+ buf.len = std::max((Size)0, mem->heap.len - Kibibytes(32)) / 2;
87
92
 
88
93
  status = napi_get_value_string_utf16(env, value, buf.ptr, (size_t)buf.len, &len);
89
94
  RG_ASSERT(status == napi_ok);
@@ -91,15 +96,15 @@ const char16_t *CallData::PushString16(const Napi::Value &value)
91
96
  len++;
92
97
 
93
98
  if (RG_LIKELY(len < (size_t)buf.len)) {
94
- heap_mem->ptr += (Size)len * 2;
95
- heap_mem->len -= (Size)len * 2;
99
+ mem->heap.ptr += (Size)len * 2;
100
+ mem->heap.len -= (Size)len * 2;
96
101
  } else {
97
102
  status = napi_get_value_string_utf16(env, value, nullptr, 0, &len);
98
103
  RG_ASSERT(status == napi_ok);
99
104
 
100
105
  len++;
101
106
 
102
- buf.ptr = (char16_t *)Allocator::Allocate(&big_alloc, (Size)len * 2);
107
+ buf.ptr = (char16_t *)Allocator::Allocate(&mem->big_alloc, (Size)len * 2);
103
108
  buf.len = (Size)len;
104
109
 
105
110
  status = napi_get_value_string_utf16(env, value, buf.ptr, (size_t)buf.len, &len);
@@ -111,9 +116,6 @@ const char16_t *CallData::PushString16(const Napi::Value &value)
111
116
 
112
117
  bool CallData::PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t *dest)
113
118
  {
114
- Napi::Env env = obj.Env();
115
- InstanceData *instance = env.GetInstanceData<InstanceData>();
116
-
117
119
  RG_ASSERT(IsObject(obj));
118
120
  RG_ASSERT(type->primitive == PrimitiveKind::Record);
119
121
 
@@ -156,24 +158,6 @@ bool CallData::PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t
156
158
  int64_t v = CopyNumber<int64_t>(value);
157
159
  memcpy(dest, &v, member.type->size); // Little Endian
158
160
  } break;
159
- case PrimitiveKind::Float32: {
160
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
161
- ThrowError<Napi::TypeError>(env, "Unexpected value %1 for member '%2', expected number", GetValueType(instance, value), member.name);
162
- return false;
163
- }
164
-
165
- float f = CopyNumber<float>(value);
166
- memcpy(dest, &f, 4);
167
- } break;
168
- case PrimitiveKind::Float64: {
169
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
170
- ThrowError<Napi::TypeError>(env, "Unexpected value %1 for member '%2', expected number", GetValueType(instance, value), member.name);
171
- return false;
172
- }
173
-
174
- double d = CopyNumber<double>(value);
175
- memcpy(dest, &d, 8);
176
- } break;
177
161
  case PrimitiveKind::String: {
178
162
  if (RG_UNLIKELY(!value.IsString())) {
179
163
  ThrowError<Napi::TypeError>(env, "Unexpected value %1 for member '%2', expected string", GetValueType(instance, value), member.name);
@@ -206,7 +190,6 @@ bool CallData::PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t
206
190
  void *ptr = external.Data();
207
191
  *(void **)dest = ptr;
208
192
  } break;
209
-
210
193
  case PrimitiveKind::Record: {
211
194
  if (RG_UNLIKELY(!IsObject(value))) {
212
195
  ThrowError<Napi::TypeError>(env, "Unexpected value %1 for member '%2', expected object", GetValueType(instance, value), member.name);
@@ -217,6 +200,24 @@ bool CallData::PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t
217
200
  if (!PushObject(obj, member.type, dest))
218
201
  return false;
219
202
  } break;
203
+ case PrimitiveKind::Float32: {
204
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
205
+ ThrowError<Napi::TypeError>(env, "Unexpected value %1 for member '%2', expected number", GetValueType(instance, value), member.name);
206
+ return false;
207
+ }
208
+
209
+ float f = CopyNumber<float>(value);
210
+ memcpy(dest, &f, 4);
211
+ } break;
212
+ case PrimitiveKind::Float64: {
213
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
214
+ ThrowError<Napi::TypeError>(env, "Unexpected value %1 for member '%2', expected number", GetValueType(instance, value), member.name);
215
+ return false;
216
+ }
217
+
218
+ double d = CopyNumber<double>(value);
219
+ memcpy(dest, &d, 8);
220
+ } break;
220
221
  }
221
222
 
222
223
  dest += member.type->size;
@@ -225,4 +226,127 @@ bool CallData::PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t
225
226
  return true;
226
227
  }
227
228
 
229
+ void CallData::PopObject(Napi::Object obj, const uint8_t *ptr, const TypeInfo *type)
230
+ {
231
+ RG_ASSERT(type->primitive == PrimitiveKind::Record);
232
+
233
+ for (const RecordMember &member: type->members) {
234
+ ptr = AlignUp(ptr, member.align);
235
+
236
+ switch (member.type->primitive) {
237
+ case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
238
+
239
+ case PrimitiveKind::Bool: {
240
+ bool b = *(bool *)ptr;
241
+ obj.Set(member.name, Napi::Boolean::New(env, b));
242
+ } break;
243
+ case PrimitiveKind::Int8: {
244
+ double d = (double)*(int8_t *)ptr;
245
+ obj.Set(member.name, Napi::Number::New(env, d));
246
+ } break;
247
+ case PrimitiveKind::UInt8: {
248
+ double d = (double)*(uint8_t *)ptr;
249
+ obj.Set(member.name, Napi::Number::New(env, d));
250
+ } break;
251
+ case PrimitiveKind::Int16: {
252
+ double d = (double)*(int16_t *)ptr;
253
+ obj.Set(member.name, Napi::Number::New(env, d));
254
+ } break;
255
+ case PrimitiveKind::UInt16: {
256
+ double d = (double)*(uint16_t *)ptr;
257
+ obj.Set(member.name, Napi::Number::New(env, d));
258
+ } break;
259
+ case PrimitiveKind::Int32: {
260
+ double d = (double)*(int32_t *)ptr;
261
+ obj.Set(member.name, Napi::Number::New(env, d));
262
+ } break;
263
+ case PrimitiveKind::UInt32: {
264
+ double d = (double)*(uint32_t *)ptr;
265
+ obj.Set(member.name, Napi::Number::New(env, d));
266
+ } break;
267
+ case PrimitiveKind::Int64: {
268
+ int64_t v = *(int64_t *)ptr;
269
+ obj.Set(member.name, Napi::BigInt::New(env, v));
270
+ } break;
271
+ case PrimitiveKind::UInt64: {
272
+ uint64_t v = *(uint64_t *)ptr;
273
+ obj.Set(member.name, Napi::BigInt::New(env, v));
274
+ } break;
275
+ case PrimitiveKind::String: {
276
+ const char *str = *(const char **)ptr;
277
+ obj.Set(member.name, Napi::String::New(env, str));
278
+ } break;
279
+ case PrimitiveKind::String16: {
280
+ const char16_t *str16 = *(const char16_t **)ptr;
281
+ obj.Set(member.name, Napi::String::New(env, str16));
282
+ } break;
283
+ case PrimitiveKind::Pointer: {
284
+ void *ptr2 = *(void **)ptr;
285
+
286
+ Napi::External<void> external = Napi::External<void>::New(env, ptr2);
287
+ SetValueTag(instance, external, member.type);
288
+
289
+ obj.Set(member.name, external);
290
+ } break;
291
+ case PrimitiveKind::Record: {
292
+ Napi::Object obj2 = PopObject(ptr, member.type);
293
+ obj.Set(member.name, obj2);
294
+ } break;
295
+ case PrimitiveKind::Float32: {
296
+ float f;
297
+ memcpy(&f, ptr, 4);
298
+ obj.Set(member.name, Napi::Number::New(env, (double)f));
299
+ } break;
300
+ case PrimitiveKind::Float64: {
301
+ double d;
302
+ memcpy(&d, ptr, 8);
303
+ obj.Set(member.name, Napi::Number::New(env, d));
304
+ } break;
305
+ }
306
+
307
+ ptr += member.type->size;
308
+ }
309
+ }
310
+
311
+ Napi::Object CallData::PopObject(const uint8_t *ptr, const TypeInfo *type)
312
+ {
313
+ Napi::Object obj = Napi::Object::New(env);
314
+ PopObject(obj, ptr, type);
315
+ return obj;
316
+ }
317
+
318
+ static void DumpMemory(const char *type, Span<const uint8_t> bytes)
319
+ {
320
+ if (bytes.len) {
321
+ PrintLn(stderr, "%1 at 0x%2 (%3):", type, bytes.ptr, FmtMemSize(bytes.len));
322
+
323
+ for (const uint8_t *ptr = bytes.begin(); ptr < bytes.end();) {
324
+ Print(stderr, " [0x%1 %2 %3] ", FmtArg(ptr).Pad0(-16),
325
+ FmtArg((ptr - bytes.begin()) / sizeof(void *)).Pad(-4),
326
+ FmtArg(ptr - bytes.begin()).Pad(-4));
327
+ for (int i = 0; ptr < bytes.end() && i < (int)sizeof(void *); i++, ptr++) {
328
+ Print(stderr, " %1", FmtHex(*ptr).Pad0(-2));
329
+ }
330
+ PrintLn(stderr);
331
+ }
332
+ }
333
+ }
334
+
335
+ void CallData::DumpDebug() const
336
+ {
337
+ PrintLn(stderr, "%!..+---- %1 (%2) ----%!0", func->name, CallConventionNames[(int)func->convention]);
338
+
339
+ if (func->parameters.len) {
340
+ PrintLn(stderr, "Parameters:");
341
+ for (Size i = 0; i < func->parameters.len; i++) {
342
+ const ParameterInfo &param = func->parameters[i];
343
+ PrintLn(stderr, " %1 = %2 (%3)", i, param.type->name, FmtMemSize(param.type->size));
344
+ }
345
+ }
346
+ PrintLn(stderr, "Return: %1 (%2)", func->ret.type->name, FmtMemSize(func->ret.type->size));
347
+
348
+ DumpMemory("Stack", stack);
349
+ DumpMemory("Heap", heap);
350
+ }
351
+
228
352
  }
package/src/call.hh CHANGED
@@ -24,38 +24,61 @@ namespace RG {
24
24
  bool AnalyseFunction(InstanceData *instance, FunctionInfo *func);
25
25
 
26
26
  class CallData {
27
+ struct OutObject {
28
+ Napi::ObjectReference ref;
29
+ const uint8_t *ptr;
30
+ const TypeInfo *type;
31
+ };
32
+
27
33
  Napi::Env env;
28
34
  InstanceData *instance;
29
35
  const FunctionInfo *func;
30
36
 
31
- Span<uint8_t> *stack_mem;
32
- Span<uint8_t> *heap_mem;
33
- BlockAllocator big_alloc;
37
+ bool debug;
34
38
 
39
+ InstanceMemory *mem;
35
40
  Span<uint8_t> old_stack_mem;
36
41
  Span<uint8_t> old_heap_mem;
37
42
 
43
+ LocalArray<OutObject, MaxOutParameters> out_objects;
44
+
45
+ Span<uint8_t> heap;
46
+ Span<uint8_t> stack;
47
+
48
+ union {
49
+ uint32_t u32;
50
+ uint64_t u64;
51
+ float f;
52
+ double d;
53
+ void *ptr;
54
+ uint8_t buf[32];
55
+ } result;
56
+ uint8_t *return_ptr = nullptr;
57
+
38
58
  public:
39
- CallData(Napi::Env env, InstanceData *instance, const FunctionInfo *func);
59
+ CallData(Napi::Env env, const FunctionInfo *func, InstanceMemory *mem, bool debug);
40
60
  ~CallData();
41
61
 
42
- Span<uint8_t> GetStack() const
43
- {
44
- uint8_t *sp = stack_mem->end();
45
- Size len = old_stack_mem.end() - sp;
46
-
47
- return MakeSpan(sp, len);
48
- }
49
- uint8_t *GetSP() const { return stack_mem->end(); };
62
+ bool Prepare(const Napi::CallbackInfo &info);
63
+ void Execute();
64
+ Napi::Value Complete();
50
65
 
51
- Span<uint8_t> GetHeap() const
66
+ Napi::Value Run(const Napi::CallbackInfo &info)
52
67
  {
53
- uint8_t *ptr = old_heap_mem.ptr;
54
- Size len = heap_mem->ptr - ptr;
68
+ if (!RG_UNLIKELY(Prepare(info)))
69
+ return env.Null();
70
+
71
+ if (debug) {
72
+ DumpDebug();
73
+ }
74
+ Execute();
55
75
 
56
- return MakeSpan(ptr, len);
76
+ return Complete();
57
77
  }
58
78
 
79
+ void DumpDebug() const;
80
+
81
+ private:
59
82
  template <typename T = void>
60
83
  bool AllocStack(Size size, Size align, T **out_ptr = nullptr);
61
84
  template <typename T = void>
@@ -65,27 +88,26 @@ public:
65
88
  const char16_t *PushString16(const Napi::Value &value);
66
89
  bool PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t *dest);
67
90
 
68
- void DumpDebug() const;
69
-
70
- Napi::Value Execute(const Napi::CallbackInfo &info);
91
+ void PopObject(Napi::Object obj, const uint8_t *ptr, const TypeInfo *type);
92
+ Napi::Object PopObject(const uint8_t *ptr, const TypeInfo *type);
71
93
  };
72
94
 
73
95
  template <typename T>
74
96
  bool CallData::AllocStack(Size size, Size align, T **out_ptr)
75
97
  {
76
- uint8_t *ptr = AlignDown(stack_mem->end() - size, align);
77
- Size delta = stack_mem->end() - ptr;
98
+ uint8_t *ptr = AlignDown(mem->stack.end() - size, align);
99
+ Size delta = mem->stack.end() - ptr;
78
100
 
79
- if (RG_UNLIKELY(stack_mem->len < delta)) {
101
+ if (RG_UNLIKELY(mem->stack.len < delta)) {
80
102
  ThrowError<Napi::Error>(env, "FFI call is taking up too much memory");
81
103
  return false;
82
104
  }
83
105
 
84
- if (instance->debug) {
106
+ if (debug) {
85
107
  memset(ptr, 0, delta);
86
108
  }
87
109
 
88
- stack_mem->len -= delta;
110
+ mem->stack.len -= delta;
89
111
 
90
112
  if (out_ptr) {
91
113
  *out_ptr = (T *)ptr;
@@ -96,20 +118,20 @@ bool CallData::AllocStack(Size size, Size align, T **out_ptr)
96
118
  template <typename T>
97
119
  bool CallData::AllocHeap(Size size, Size align, T **out_ptr)
98
120
  {
99
- uint8_t *ptr = AlignUp(heap_mem->ptr, align);
100
- Size delta = size + (ptr - heap_mem->ptr);
121
+ uint8_t *ptr = AlignUp(mem->heap.ptr, align);
122
+ Size delta = size + (ptr - mem->heap.ptr);
101
123
 
102
- if (RG_UNLIKELY(delta > heap_mem->len)) {
124
+ if (RG_UNLIKELY(delta > mem->heap.len)) {
103
125
  ThrowError<Napi::Error>(env, "FFI call is taking up too much memory");
104
126
  return false;
105
127
  }
106
128
 
107
- if (instance->debug) {
108
- memset(heap_mem->ptr, 0, (size_t)delta);
129
+ if (debug) {
130
+ memset(mem->heap.ptr, 0, (size_t)delta);
109
131
  }
110
132
 
111
- heap_mem->ptr += delta;
112
- heap_mem->len -= delta;
133
+ mem->heap.ptr += delta;
134
+ mem->heap.len -= delta;
113
135
 
114
136
  if (out_ptr) {
115
137
  *out_ptr = (T *)ptr;
package/src/ffi.cc CHANGED
@@ -241,14 +241,57 @@ static Napi::Value MarkInOut(const Napi::CallbackInfo &info)
241
241
  return EncodePointerDirection(info, 3);
242
242
  }
243
243
 
244
+ static Span<uint8_t> AllocateAndAlign16(Allocator *alloc, Size size)
245
+ {
246
+ RG_ASSERT(AlignLen(size, 16) == size);
247
+ RG_ASSERT(size >= Kibibytes(1));
248
+
249
+ // Account for allocator overhead
250
+ size -= 256;
251
+
252
+ uint8_t *ptr = (uint8_t *)Allocator::Allocate(alloc, size);
253
+ uint8_t *aligned = AlignUp(ptr, 16);
254
+ Size delta = AlignLen(aligned - ptr, 16);
255
+
256
+ return MakeSpan(aligned, size - delta);
257
+ }
258
+
259
+ static InstanceMemory *AllocateCallMemory(InstanceData *instance)
260
+ {
261
+ for (InstanceMemory *mem: instance->memories) {
262
+ if (!mem->depth)
263
+ return mem;
264
+ }
265
+
266
+ InstanceMemory *mem = new InstanceMemory();
267
+
268
+ mem->stack = AllocateAndAlign16(&mem->mem_alloc, Mebibytes(1));
269
+ mem->heap = AllocateAndAlign16(&mem->mem_alloc, Mebibytes(2));
270
+
271
+ if (instance->memories.Available()) {
272
+ instance->memories.Append(mem);
273
+ } else {
274
+ mem->temporary = true;
275
+ }
276
+
277
+ return mem;
278
+ }
279
+
244
280
  static Napi::Value TranslateNormalCall(const Napi::CallbackInfo &info)
245
281
  {
246
282
  Napi::Env env = info.Env();
247
283
  InstanceData *instance = env.GetInstanceData<InstanceData>();
248
284
  FunctionInfo *func = (FunctionInfo *)info.Data();
249
285
 
250
- CallData call(env, instance, func);
251
- return call.Execute(info);
286
+ if (info.Length() < (uint32_t)func->parameters.len) {
287
+ ThrowError<Napi::TypeError>(env, "Expected %1 arguments, got %2", func->parameters.len, info.Length());
288
+ return env.Null();
289
+ }
290
+
291
+ InstanceMemory *mem = AllocateCallMemory(instance);
292
+ CallData call(env, func, mem, instance->debug);
293
+
294
+ return call.Run(info);
252
295
  }
253
296
 
254
297
  static Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info)
@@ -266,6 +309,10 @@ static Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info)
266
309
  func.parameters.Leak();
267
310
  };
268
311
 
312
+ if (info.Length() < (uint32_t)func.parameters.len) {
313
+ ThrowError<Napi::TypeError>(env, "Expected %1 arguments or more, got %2", func.parameters.len, info.Length());
314
+ return env.Null();
315
+ }
269
316
  if ((info.Length() - func.parameters.len) % 2) {
270
317
  ThrowError<Napi::Error>(env, "Missing value argument for variadic call");
271
318
  return env.Null();
@@ -300,8 +347,91 @@ static Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info)
300
347
  if (!AnalyseFunction(instance, &func))
301
348
  return env.Null();
302
349
 
303
- CallData call(env, instance, &func);
304
- return call.Execute(info);
350
+ InstanceMemory *mem = AllocateCallMemory(instance);
351
+ CallData call(env, &func, mem, instance->debug);
352
+
353
+ return call.Run(info);
354
+ }
355
+
356
+ class AsyncCall: public Napi::AsyncWorker {
357
+ Napi::Env env;
358
+ const FunctionInfo *func;
359
+
360
+ CallData call;
361
+ bool prepared = false;
362
+
363
+ public:
364
+ AsyncCall(Napi::Env env, InstanceMemory *mem, FunctionInfo *func, bool debug,
365
+ Napi::Function &callback)
366
+ : Napi::AsyncWorker(callback), env(env), func(func->Ref()),
367
+ call(env, func, mem, debug) {}
368
+ ~AsyncCall() { func->Unref(); }
369
+
370
+ bool Prepare(const Napi::CallbackInfo &info) {
371
+ prepared = call.Prepare(info);
372
+
373
+ if (!prepared) {
374
+ Napi::Error err = env.GetAndClearPendingException();
375
+ SetError(err.Message());
376
+ }
377
+
378
+ return prepared;
379
+ }
380
+ void DumpDebug() { call.DumpDebug(); }
381
+
382
+ void Execute() override;
383
+ void OnOK() override;
384
+ };
385
+
386
+ void AsyncCall::Execute()
387
+ {
388
+ if (prepared) {
389
+ call.Execute();
390
+ }
391
+ }
392
+
393
+ void AsyncCall::OnOK()
394
+ {
395
+ RG_ASSERT(prepared);
396
+
397
+ Napi::FunctionReference &callback = Callback();
398
+
399
+ Napi::Value self = env.Null();
400
+ napi_value args[] = {
401
+ env.Null(),
402
+ call.Complete()
403
+ };
404
+
405
+ callback.Call(self, RG_LEN(args), args);
406
+ }
407
+
408
+ static Napi::Value TranslateAsyncCall(const Napi::CallbackInfo &info)
409
+ {
410
+ Napi::Env env = info.Env();
411
+ InstanceData *instance = env.GetInstanceData<InstanceData>();
412
+ FunctionInfo *func = (FunctionInfo *)info.Data();
413
+
414
+ if (info.Length() <= (uint32_t)func->parameters.len) {
415
+ ThrowError<Napi::TypeError>(env, "Expected %1 arguments, got %2", func->parameters.len + 1, info.Length());
416
+ return env.Null();
417
+ }
418
+
419
+ Napi::Function callback = info[(uint32_t)func->parameters.len].As<Napi::Function>();
420
+
421
+ if (!callback.IsFunction()) {
422
+ ThrowError<Napi::TypeError>(env, "Expected callback function as last arguments, got %1", GetValueType(instance, callback));
423
+ return env.Null();
424
+ }
425
+
426
+ InstanceMemory *mem = AllocateCallMemory(instance);
427
+ AsyncCall *async = new AsyncCall(env, mem, func, instance->debug, callback);
428
+
429
+ if (async->Prepare(info) && instance->debug) {
430
+ async->DumpDebug();
431
+ }
432
+ async->Queue();
433
+
434
+ return env.Null();
305
435
  }
306
436
 
307
437
  static bool ParseClassicFunction(Napi::Env env, Napi::String name, Napi::Value ret,
@@ -377,7 +507,7 @@ static Napi::Value FindLibraryFunction(const Napi::CallbackInfo &info, CallConve
377
507
  LibraryHolder *lib = (LibraryHolder *)info.Data();
378
508
 
379
509
  FunctionInfo *func = new FunctionInfo();
380
- RG_DEFER_N(func_guard) { delete func; };
510
+ RG_DEFER { func->Unref(); };
381
511
 
382
512
  func->lib = lib->Ref();
383
513
  func->convention = convention;
@@ -436,9 +566,14 @@ static Napi::Value FindLibraryFunction(const Napi::CallbackInfo &info, CallConve
436
566
  }
437
567
 
438
568
  Napi::Function::Callback call = func->variadic ? TranslateVariadicCall : TranslateNormalCall;
439
- Napi::Function wrapper = Napi::Function::New(env, call, func->name, (void *)func);
440
- wrapper.AddFinalizer([](Napi::Env, FunctionInfo *func) { delete func; }, func);
441
- func_guard.Disable();
569
+ Napi::Function wrapper = Napi::Function::New(env, call, func->name, (void *)func->Ref());
570
+ wrapper.AddFinalizer([](Napi::Env, FunctionInfo *func) { func->Unref(); }, func);
571
+
572
+ if (!func->variadic) {
573
+ Napi::Function async = Napi::Function::New(env, TranslateAsyncCall, func->name, (void *)func->Ref());
574
+ async.AddFinalizer([](Napi::Env, FunctionInfo *func) { func->Unref(); }, func);
575
+ wrapper.Set("async", async);
576
+ }
442
577
 
443
578
  return wrapper;
444
579
  }
@@ -531,13 +666,13 @@ LibraryHolder::~LibraryHolder()
531
666
  #endif
532
667
  }
533
668
 
534
- LibraryHolder *LibraryHolder::Ref()
669
+ const LibraryHolder *LibraryHolder::Ref() const
535
670
  {
536
671
  refcount++;
537
672
  return this;
538
673
  }
539
674
 
540
- void LibraryHolder::Unref()
675
+ void LibraryHolder::Unref() const
541
676
  {
542
677
  if (!--refcount) {
543
678
  delete this;
@@ -637,21 +772,30 @@ FunctionInfo::~FunctionInfo()
637
772
  }
638
773
  }
639
774
 
640
- static Span<uint8_t> AllocateAndAlign16(Allocator *alloc, Size size)
775
+ const FunctionInfo *FunctionInfo::Ref() const
641
776
  {
642
- RG_ASSERT(AlignLen(size, 16) == size);
643
-
644
- uint8_t *ptr = (uint8_t *)Allocator::Allocate(alloc, size);
645
- uint8_t *aligned = AlignUp(ptr, 16);
646
- Size delta = AlignLen(aligned - ptr, 16);
777
+ refcount++;
778
+ return this;
779
+ }
647
780
 
648
- return MakeSpan(aligned, size - delta);
781
+ void FunctionInfo::Unref() const
782
+ {
783
+ if (!--refcount) {
784
+ delete this;
785
+ }
649
786
  }
650
787
 
651
788
  InstanceData::InstanceData()
652
789
  {
653
- stack_mem = AllocateAndAlign16(&mem_alloc, Mebibytes(2));
654
- heap_mem = AllocateAndAlign16(&mem_alloc, Mebibytes(4));
790
+ AllocateCallMemory(this);
791
+ RG_ASSERT(memories.len == 1);
792
+ }
793
+
794
+ InstanceData::~InstanceData()
795
+ {
796
+ for (InstanceMemory *mem: memories) {
797
+ delete mem;
798
+ }
655
799
  }
656
800
 
657
801
  template <typename Func>