koffi 0.9.2 → 0.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CMakeLists.txt +60 -60
- package/README.md +163 -153
- package/package.json +19 -18
- package/src/call.hh +27 -27
- package/src/call_arm64.cc +482 -482
- package/src/call_arm64_fwd.S +115 -115
- package/src/call_x64_sysv.cc +477 -477
- package/src/call_x64_sysv_fwd.S +131 -131
- package/src/call_x64_win.cc +243 -243
- package/src/call_x64_win_fwd.asm +105 -105
- package/src/call_x86.cc +259 -259
- package/src/call_x86_fwd.S +48 -48
- package/src/call_x86_fwd.asm +50 -50
- package/src/ffi.cc +504 -504
- package/src/ffi.hh +135 -135
- package/src/util.cc +296 -296
- package/src/util.hh +80 -80
- package/vendor/dragonbox/CMakeLists.txt +122 -122
- package/vendor/dragonbox/LICENSE-Apache2-LLVM +218 -218
- package/vendor/dragonbox/LICENSE-Boost +23 -23
- package/vendor/dragonbox/README.md +277 -277
- package/vendor/dragonbox/cmake/dragonboxConfig.cmake +1 -1
- package/vendor/dragonbox/include/dragonbox/dragonbox.h +2670 -2670
- package/vendor/dragonbox/include/dragonbox/dragonbox_to_chars.h +108 -108
- package/vendor/dragonbox/other_files/unknown_win64_vc2019.html +539 -539
- package/vendor/dragonbox/source/dragonbox_to_chars.cpp +303 -303
- package/vendor/dragonbox/subproject/3rdparty/grisu_exact/CMakeLists.txt +23 -23
- package/vendor/dragonbox/subproject/3rdparty/grisu_exact/fp_to_chars.cpp +238 -238
- package/vendor/dragonbox/subproject/3rdparty/grisu_exact/fp_to_chars.h +95 -95
- package/vendor/dragonbox/subproject/3rdparty/grisu_exact/grisu_exact.h +2666 -2666
- package/vendor/dragonbox/subproject/3rdparty/ryu/CMakeLists.txt +16 -16
- package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/common.h +114 -114
- package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/d2s.c +509 -509
- package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/d2s_full_table.h +367 -367
- package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/d2s_intrinsics.h +357 -357
- package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/digit_table.h +35 -35
- package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/f2s.c +345 -345
- package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/f2s_full_table.h +55 -55
- package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/f2s_intrinsics.h +128 -128
- package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/ryu.h +46 -46
- package/vendor/dragonbox/subproject/3rdparty/schubfach/CMakeLists.txt +21 -21
- package/vendor/dragonbox/subproject/3rdparty/schubfach/schubfach_32.cc +699 -699
- package/vendor/dragonbox/subproject/3rdparty/schubfach/schubfach_32.h +31 -31
- package/vendor/dragonbox/subproject/3rdparty/schubfach/schubfach_64.cc +1354 -1354
- package/vendor/dragonbox/subproject/3rdparty/schubfach/schubfach_64.h +31 -31
- package/vendor/dragonbox/subproject/3rdparty/shaded_plots/example_shaded_plots.m +68 -68
- package/vendor/dragonbox/subproject/3rdparty/shaded_plots/license.txt +25 -25
- package/vendor/dragonbox/subproject/3rdparty/shaded_plots/plot_distribution.m +92 -92
- package/vendor/dragonbox/subproject/3rdparty/shaded_plots/plot_distribution_prctile.m +121 -121
- package/vendor/dragonbox/subproject/3rdparty/shaded_plots/plot_histogram_shaded.m +99 -99
- package/vendor/dragonbox/subproject/3rdparty/shaded_plots/plot_shaded.m +93 -93
- package/vendor/dragonbox/subproject/benchmark/CMakeLists.txt +64 -64
- package/vendor/dragonbox/subproject/benchmark/include/benchmark.h +40 -40
- package/vendor/dragonbox/subproject/benchmark/matlab/plot_benchmarks.m +21 -21
- package/vendor/dragonbox/subproject/benchmark/matlab/plot_digit_benchmark.m +78 -78
- package/vendor/dragonbox/subproject/benchmark/matlab/plot_uniform_benchmark.m +95 -95
- package/vendor/dragonbox/subproject/benchmark/source/benchmark.cpp +237 -237
- package/vendor/dragonbox/subproject/benchmark/source/dragonbox.cpp +30 -30
- package/vendor/dragonbox/subproject/benchmark/source/grisu_exact.cpp +36 -36
- package/vendor/dragonbox/subproject/benchmark/source/ryu.cpp +27 -27
- package/vendor/dragonbox/subproject/benchmark/source/schubfach.cpp +31 -31
- package/vendor/dragonbox/subproject/common/CMakeLists.txt +41 -41
- package/vendor/dragonbox/subproject/common/include/best_rational_approx.h +96 -96
- package/vendor/dragonbox/subproject/common/include/big_uint.h +217 -217
- package/vendor/dragonbox/subproject/common/include/continued_fractions.h +173 -173
- package/vendor/dragonbox/subproject/common/include/good_rational_approx.h +266 -266
- package/vendor/dragonbox/subproject/common/include/random_float.h +182 -182
- package/vendor/dragonbox/subproject/common/include/rational_continued_fractions.h +56 -56
- package/vendor/dragonbox/subproject/common/source/big_uint.cpp +601 -601
- package/vendor/dragonbox/subproject/meta/CMakeLists.txt +40 -40
- package/vendor/dragonbox/subproject/meta/results/binary32_generated_cache.txt +81 -81
- package/vendor/dragonbox/subproject/meta/results/binary64_compressed_cache_error_table.txt +9 -9
- package/vendor/dragonbox/subproject/meta/results/binary64_generated_cache.txt +622 -622
- package/vendor/dragonbox/subproject/meta/source/generate_cache.cpp +126 -126
- package/vendor/dragonbox/subproject/meta/source/live_test.cpp +81 -81
- package/vendor/dragonbox/subproject/meta/source/perf_test.cpp +104 -104
- package/vendor/dragonbox/subproject/meta/source/sandbox.cpp +20 -20
- package/vendor/dragonbox/subproject/test/CMakeLists.txt +69 -69
- package/vendor/dragonbox/subproject/test/results/binary32.csv +255 -255
- package/vendor/dragonbox/subproject/test/results/binary64.csv +2047 -2047
- package/vendor/dragonbox/subproject/test/results/plot_required_bits.m +17 -17
- package/vendor/dragonbox/subproject/test/source/test_all_shorter_interval_cases.cpp +88 -88
- package/vendor/dragonbox/subproject/test/source/uniform_random_test.cpp +95 -95
- package/vendor/dragonbox/subproject/test/source/verify_cache_precision.cpp +337 -337
- package/vendor/dragonbox/subproject/test/source/verify_compressed_cache.cpp +154 -154
- package/vendor/dragonbox/subproject/test/source/verify_fast_multiplication.cpp +168 -168
- package/vendor/dragonbox/subproject/test/source/verify_log_computation.cpp +251 -251
- package/vendor/dragonbox/subproject/test/source/verify_magic_division.cpp +113 -113
- package/vendor/libcc/libcc.cc +7651 -7651
- package/vendor/libcc/libcc.hh +4312 -4312
- package/vendor/node-addon-api/CHANGELOG.md +859 -859
- package/vendor/node-addon-api/CODE_OF_CONDUCT.md +4 -4
- package/vendor/node-addon-api/CONTRIBUTING.md +93 -93
- package/vendor/node-addon-api/LICENSE.md +12 -12
- package/vendor/node-addon-api/README.md +293 -293
- package/vendor/node-addon-api/appveyor.yml +37 -37
- package/vendor/node-addon-api/benchmark/README.md +47 -47
- package/vendor/node-addon-api/benchmark/binding.gyp +25 -25
- package/vendor/node-addon-api/benchmark/function_args.cc +217 -217
- package/vendor/node-addon-api/benchmark/function_args.js +60 -60
- package/vendor/node-addon-api/benchmark/index.js +34 -34
- package/vendor/node-addon-api/benchmark/property_descriptor.cc +91 -91
- package/vendor/node-addon-api/benchmark/property_descriptor.js +37 -37
- package/vendor/node-addon-api/common.gypi +21 -21
- package/vendor/node-addon-api/doc/addon.md +163 -163
- package/vendor/node-addon-api/doc/array.md +81 -81
- package/vendor/node-addon-api/doc/array_buffer.md +155 -155
- package/vendor/node-addon-api/doc/async_context.md +86 -86
- package/vendor/node-addon-api/doc/async_operations.md +31 -31
- package/vendor/node-addon-api/doc/async_worker.md +427 -427
- package/vendor/node-addon-api/doc/async_worker_variants.md +557 -557
- package/vendor/node-addon-api/doc/bigint.md +97 -97
- package/vendor/node-addon-api/doc/boolean.md +68 -68
- package/vendor/node-addon-api/doc/buffer.md +150 -150
- package/vendor/node-addon-api/doc/callback_scope.md +54 -54
- package/vendor/node-addon-api/doc/callbackinfo.md +97 -97
- package/vendor/node-addon-api/doc/checker-tool.md +32 -32
- package/vendor/node-addon-api/doc/class_property_descriptor.md +115 -115
- package/vendor/node-addon-api/doc/cmake-js.md +68 -68
- package/vendor/node-addon-api/doc/conversion-tool.md +27 -27
- package/vendor/node-addon-api/doc/creating_a_release.md +62 -62
- package/vendor/node-addon-api/doc/dataview.md +248 -248
- package/vendor/node-addon-api/doc/date.md +68 -68
- package/vendor/node-addon-api/doc/env.md +196 -196
- package/vendor/node-addon-api/doc/error.md +120 -120
- package/vendor/node-addon-api/doc/error_handling.md +254 -254
- package/vendor/node-addon-api/doc/escapable_handle_scope.md +80 -80
- package/vendor/node-addon-api/doc/external.md +63 -63
- package/vendor/node-addon-api/doc/function.md +402 -402
- package/vendor/node-addon-api/doc/function_reference.md +238 -238
- package/vendor/node-addon-api/doc/generator.md +13 -13
- package/vendor/node-addon-api/doc/handle_scope.md +63 -63
- package/vendor/node-addon-api/doc/hierarchy.md +91 -91
- package/vendor/node-addon-api/doc/instance_wrap.md +408 -408
- package/vendor/node-addon-api/doc/maybe.md +76 -76
- package/vendor/node-addon-api/doc/memory_management.md +27 -27
- package/vendor/node-addon-api/doc/name.md +29 -29
- package/vendor/node-addon-api/doc/node-gyp.md +82 -82
- package/vendor/node-addon-api/doc/number.md +163 -163
- package/vendor/node-addon-api/doc/object.md +432 -432
- package/vendor/node-addon-api/doc/object_lifetime_management.md +83 -83
- package/vendor/node-addon-api/doc/object_reference.md +117 -117
- package/vendor/node-addon-api/doc/object_wrap.md +561 -561
- package/vendor/node-addon-api/doc/prebuild_tools.md +16 -16
- package/vendor/node-addon-api/doc/promises.md +79 -79
- package/vendor/node-addon-api/doc/property_descriptor.md +286 -286
- package/vendor/node-addon-api/doc/propertylvalue.md +50 -50
- package/vendor/node-addon-api/doc/range_error.md +59 -59
- package/vendor/node-addon-api/doc/reference.md +113 -113
- package/vendor/node-addon-api/doc/setup.md +110 -110
- package/vendor/node-addon-api/doc/string.md +93 -93
- package/vendor/node-addon-api/doc/symbol.md +60 -60
- package/vendor/node-addon-api/doc/threadsafe.md +121 -121
- package/vendor/node-addon-api/doc/threadsafe_function.md +290 -290
- package/vendor/node-addon-api/doc/type_error.md +59 -59
- package/vendor/node-addon-api/doc/typed_array.md +78 -78
- package/vendor/node-addon-api/doc/typed_array_of.md +137 -137
- package/vendor/node-addon-api/doc/typed_threadsafe_function.md +306 -306
- package/vendor/node-addon-api/doc/value.md +340 -340
- package/vendor/node-addon-api/doc/version_management.md +43 -43
- package/vendor/node-addon-api/except.gypi +25 -25
- package/vendor/node-addon-api/index.js +11 -11
- package/vendor/node-addon-api/napi-inl.deprecated.h +192 -192
- package/vendor/node-addon-api/napi-inl.h +6209 -6209
- package/vendor/node-addon-api/napi.h +2983 -2983
- package/vendor/node-addon-api/node_api.gyp +9 -9
- package/vendor/node-addon-api/noexcept.gypi +26 -26
- package/vendor/node-addon-api/package-support.json +21 -21
- package/vendor/node-addon-api/package.json +399 -399
- package/vendor/node-addon-api/test/README.md +91 -91
- package/vendor/node-addon-api/test/addon.cc +36 -36
- package/vendor/node-addon-api/test/addon.js +11 -11
- package/vendor/node-addon-api/test/addon_build/index.js +49 -49
- package/vendor/node-addon-api/test/addon_build/tpl/addon.cc +17 -17
- package/vendor/node-addon-api/test/addon_build/tpl/binding.gyp +62 -62
- package/vendor/node-addon-api/test/addon_build/tpl/index.js +9 -9
- package/vendor/node-addon-api/test/addon_build/tpl/package.json +11 -11
- package/vendor/node-addon-api/test/addon_data.cc +99 -99
- package/vendor/node-addon-api/test/addon_data.js +46 -46
- package/vendor/node-addon-api/test/array_buffer.cc +243 -243
- package/vendor/node-addon-api/test/array_buffer.js +69 -69
- package/vendor/node-addon-api/test/async_context.cc +21 -21
- package/vendor/node-addon-api/test/async_context.js +86 -86
- package/vendor/node-addon-api/test/async_progress_queue_worker.cc +83 -83
- package/vendor/node-addon-api/test/async_progress_queue_worker.js +46 -46
- package/vendor/node-addon-api/test/async_progress_worker.cc +134 -134
- package/vendor/node-addon-api/test/async_progress_worker.js +61 -61
- package/vendor/node-addon-api/test/async_worker.cc +106 -106
- package/vendor/node-addon-api/test/async_worker.js +179 -179
- package/vendor/node-addon-api/test/async_worker_nocallback.js +13 -13
- package/vendor/node-addon-api/test/async_worker_persistent.cc +63 -63
- package/vendor/node-addon-api/test/async_worker_persistent.js +24 -24
- package/vendor/node-addon-api/test/basic_types/array.cc +40 -40
- package/vendor/node-addon-api/test/basic_types/array.js +35 -35
- package/vendor/node-addon-api/test/basic_types/boolean.cc +38 -38
- package/vendor/node-addon-api/test/basic_types/boolean.js +35 -35
- package/vendor/node-addon-api/test/basic_types/number.cc +99 -99
- package/vendor/node-addon-api/test/basic_types/number.js +114 -114
- package/vendor/node-addon-api/test/basic_types/value.cc +120 -120
- package/vendor/node-addon-api/test/basic_types/value.js +133 -133
- package/vendor/node-addon-api/test/bigint.cc +91 -91
- package/vendor/node-addon-api/test/bigint.js +53 -53
- package/vendor/node-addon-api/test/binding-swallowexcept.cc +12 -12
- package/vendor/node-addon-api/test/binding.cc +171 -171
- package/vendor/node-addon-api/test/binding.gyp +117 -117
- package/vendor/node-addon-api/test/buffer.cc +183 -183
- package/vendor/node-addon-api/test/buffer.js +69 -69
- package/vendor/node-addon-api/test/callbackscope.cc +22 -22
- package/vendor/node-addon-api/test/callbackscope.js +49 -49
- package/vendor/node-addon-api/test/common/index.js +113 -113
- package/vendor/node-addon-api/test/common/test_helper.h +61 -61
- package/vendor/node-addon-api/test/dataview/dataview.cc +48 -48
- package/vendor/node-addon-api/test/dataview/dataview.js +35 -35
- package/vendor/node-addon-api/test/dataview/dataview_read_write.cc +115 -115
- package/vendor/node-addon-api/test/dataview/dataview_read_write.js +90 -90
- package/vendor/node-addon-api/test/date.cc +44 -44
- package/vendor/node-addon-api/test/date.js +18 -18
- package/vendor/node-addon-api/test/env_cleanup.cc +88 -88
- package/vendor/node-addon-api/test/env_cleanup.js +56 -56
- package/vendor/node-addon-api/test/error.cc +287 -287
- package/vendor/node-addon-api/test/error.js +81 -81
- package/vendor/node-addon-api/test/error_handling_for_primitives.cc +13 -13
- package/vendor/node-addon-api/test/error_handling_for_primitives.js +29 -29
- package/vendor/node-addon-api/test/error_terminating_environment.js +94 -94
- package/vendor/node-addon-api/test/external.cc +81 -81
- package/vendor/node-addon-api/test/external.js +88 -88
- package/vendor/node-addon-api/test/function.cc +295 -295
- package/vendor/node-addon-api/test/function.js +121 -121
- package/vendor/node-addon-api/test/function_reference.cc +202 -202
- package/vendor/node-addon-api/test/function_reference.js +157 -157
- package/vendor/node-addon-api/test/globalObject/global_object.cc +61 -61
- package/vendor/node-addon-api/test/globalObject/global_object_delete_property.cc +31 -31
- package/vendor/node-addon-api/test/globalObject/global_object_delete_property.js +61 -61
- package/vendor/node-addon-api/test/globalObject/global_object_get_property.cc +40 -40
- package/vendor/node-addon-api/test/globalObject/global_object_get_property.js +57 -57
- package/vendor/node-addon-api/test/globalObject/global_object_has_own_property.cc +28 -28
- package/vendor/node-addon-api/test/globalObject/global_object_has_own_property.js +48 -48
- package/vendor/node-addon-api/test/globalObject/global_object_set_property.cc +30 -30
- package/vendor/node-addon-api/test/globalObject/global_object_set_property.js +58 -58
- package/vendor/node-addon-api/test/handlescope.cc +60 -60
- package/vendor/node-addon-api/test/handlescope.js +14 -14
- package/vendor/node-addon-api/test/index.js +136 -136
- package/vendor/node-addon-api/test/maybe/check.cc +23 -23
- package/vendor/node-addon-api/test/maybe/index.js +38 -38
- package/vendor/node-addon-api/test/memory_management.cc +17 -17
- package/vendor/node-addon-api/test/memory_management.js +9 -9
- package/vendor/node-addon-api/test/movable_callbacks.cc +23 -23
- package/vendor/node-addon-api/test/movable_callbacks.js +21 -21
- package/vendor/node-addon-api/test/name.cc +108 -108
- package/vendor/node-addon-api/test/name.js +59 -59
- package/vendor/node-addon-api/test/napi_child.js +14 -14
- package/vendor/node-addon-api/test/object/delete_property.cc +38 -38
- package/vendor/node-addon-api/test/object/delete_property.js +41 -41
- package/vendor/node-addon-api/test/object/finalizer.cc +29 -29
- package/vendor/node-addon-api/test/object/finalizer.js +28 -28
- package/vendor/node-addon-api/test/object/get_property.cc +34 -34
- package/vendor/node-addon-api/test/object/get_property.js +40 -40
- package/vendor/node-addon-api/test/object/has_own_property.cc +34 -34
- package/vendor/node-addon-api/test/object/has_own_property.js +34 -34
- package/vendor/node-addon-api/test/object/has_property.cc +38 -38
- package/vendor/node-addon-api/test/object/has_property.js +37 -37
- package/vendor/node-addon-api/test/object/object.cc +348 -348
- package/vendor/node-addon-api/test/object/object.js +217 -217
- package/vendor/node-addon-api/test/object/object_deprecated.cc +66 -66
- package/vendor/node-addon-api/test/object/object_deprecated.js +47 -47
- package/vendor/node-addon-api/test/object/object_freeze_seal.cc +25 -25
- package/vendor/node-addon-api/test/object/object_freeze_seal.js +61 -61
- package/vendor/node-addon-api/test/object/set_property.cc +37 -37
- package/vendor/node-addon-api/test/object/set_property.js +29 -29
- package/vendor/node-addon-api/test/object/subscript_operator.cc +42 -42
- package/vendor/node-addon-api/test/object/subscript_operator.js +17 -17
- package/vendor/node-addon-api/test/object_reference.cc +219 -219
- package/vendor/node-addon-api/test/object_reference.js +259 -259
- package/vendor/node-addon-api/test/objectwrap.cc +268 -268
- package/vendor/node-addon-api/test/objectwrap.js +284 -284
- package/vendor/node-addon-api/test/objectwrap_constructor_exception.cc +26 -26
- package/vendor/node-addon-api/test/objectwrap_constructor_exception.js +18 -18
- package/vendor/node-addon-api/test/objectwrap_multiple_inheritance.cc +30 -30
- package/vendor/node-addon-api/test/objectwrap_multiple_inheritance.js +13 -13
- package/vendor/node-addon-api/test/objectwrap_removewrap.cc +45 -45
- package/vendor/node-addon-api/test/objectwrap_removewrap.js +40 -40
- package/vendor/node-addon-api/test/objectwrap_worker_thread.js +19 -19
- package/vendor/node-addon-api/test/promise.cc +29 -29
- package/vendor/node-addon-api/test/promise.js +18 -18
- package/vendor/node-addon-api/test/reference.cc +24 -24
- package/vendor/node-addon-api/test/reference.js +14 -14
- package/vendor/node-addon-api/test/run_script.cc +56 -56
- package/vendor/node-addon-api/test/run_script.js +45 -45
- package/vendor/node-addon-api/test/symbol.cc +79 -79
- package/vendor/node-addon-api/test/symbol.js +73 -73
- package/vendor/node-addon-api/test/testUtil.js +54 -54
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function.cc +195 -195
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function.js +188 -188
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ctx.cc +63 -63
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ctx.js +12 -12
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_existing_tsfn.cc +115 -115
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_existing_tsfn.js +14 -14
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ptr.cc +26 -26
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ptr.js +7 -7
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_sum.cc +225 -225
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_sum.js +59 -59
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_unref.cc +42 -42
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_unref.js +53 -53
- package/vendor/node-addon-api/test/thunking_manual.cc +140 -140
- package/vendor/node-addon-api/test/thunking_manual.js +17 -17
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function.cc +215 -215
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function.js +188 -188
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ctx.cc +68 -68
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ctx.js +12 -12
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_existing_tsfn.cc +127 -127
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_existing_tsfn.js +14 -14
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ptr.cc +28 -28
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ptr.js +7 -7
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_sum.cc +237 -237
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_sum.js +59 -59
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_unref.cc +53 -53
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_unref.js +53 -53
- package/vendor/node-addon-api/test/typedarray-bigint.js +58 -58
- package/vendor/node-addon-api/test/typedarray.cc +216 -216
- package/vendor/node-addon-api/test/typedarray.js +69 -69
- package/vendor/node-addon-api/test/version_management.cc +27 -27
- package/vendor/node-addon-api/test/version_management.js +31 -31
- package/vendor/node-addon-api/tools/README.md +73 -73
- package/vendor/node-addon-api/tools/check-napi.js +100 -100
- package/vendor/node-addon-api/tools/clang-format.js +68 -68
- package/vendor/node-addon-api/tools/conversion.js +309 -309
- package/vendor/node-addon-api/tools/eslint-format.js +71 -71
- package/build/ALL_BUILD.vcxproj +0 -186
- package/build/ALL_BUILD.vcxproj.filters +0 -8
- package/build/CMakeCache.txt +0 -417
- package/build/CMakeFiles/3.23.0-rc1/CMakeASMCompiler.cmake +0 -20
- package/build/CMakeFiles/3.23.0-rc1/CMakeASM_MASMCompiler.cmake +0 -20
- package/build/CMakeFiles/3.23.0-rc1/CMakeCCompiler.cmake +0 -72
- package/build/CMakeFiles/3.23.0-rc1/CMakeCXXCompiler.cmake +0 -83
- package/build/CMakeFiles/3.23.0-rc1/CMakeDetermineCompilerABI_C.bin +0 -0
- package/build/CMakeFiles/3.23.0-rc1/CMakeDetermineCompilerABI_CXX.bin +0 -0
- package/build/CMakeFiles/3.23.0-rc1/CMakeRCCompiler.cmake +0 -6
- package/build/CMakeFiles/3.23.0-rc1/CMakeSystem.cmake +0 -15
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/CMakeCCompilerId.c +0 -828
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/CompilerIdC.exe +0 -0
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/CompilerIdC.vcxproj +0 -71
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/Debug/CMakeCCompilerId.obj +0 -0
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/Debug/CompilerIdC.exe.recipe +0 -11
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/Debug/CompilerIdC.tlog/CL.command.1.tlog +0 -0
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/Debug/CompilerIdC.tlog/CL.read.1.tlog +0 -0
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/Debug/CompilerIdC.tlog/CL.write.1.tlog +0 -0
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/Debug/CompilerIdC.tlog/CompilerIdC.lastbuildstate +0 -2
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/Debug/CompilerIdC.tlog/link.command.1.tlog +0 -0
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/Debug/CompilerIdC.tlog/link.read.1.tlog +0 -0
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdC/Debug/CompilerIdC.tlog/link.write.1.tlog +0 -0
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/CMakeCXXCompilerId.cpp +0 -816
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/CompilerIdCXX.exe +0 -0
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/CompilerIdCXX.vcxproj +0 -71
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/Debug/CMakeCXXCompilerId.obj +0 -0
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/Debug/CompilerIdCXX.exe.recipe +0 -11
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/Debug/CompilerIdCXX.tlog/CL.command.1.tlog +0 -0
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/Debug/CompilerIdCXX.tlog/CL.read.1.tlog +0 -0
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/Debug/CompilerIdCXX.tlog/CL.write.1.tlog +0 -0
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/Debug/CompilerIdCXX.tlog/CompilerIdCXX.lastbuildstate +0 -2
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/Debug/CompilerIdCXX.tlog/link.command.1.tlog +0 -0
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/Debug/CompilerIdCXX.tlog/link.read.1.tlog +0 -0
- package/build/CMakeFiles/3.23.0-rc1/CompilerIdCXX/Debug/CompilerIdCXX.tlog/link.write.1.tlog +0 -0
- package/build/CMakeFiles/3.23.0-rc1/VCTargetsPath.txt +0 -1
- package/build/CMakeFiles/3.23.0-rc1/VCTargetsPath.vcxproj +0 -31
- package/build/CMakeFiles/3.23.0-rc1/x64/Debug/VCTargetsPath.recipe +0 -11
- package/build/CMakeFiles/3.23.0-rc1/x64/Debug/VCTargetsPath.tlog/VCTargetsPath.lastbuildstate +0 -2
- package/build/CMakeFiles/41bcd16856091d4a38fd1f71fbe2f202/generate.stamp.rule +0 -1
- package/build/CMakeFiles/CMakeError.log +0 -108
- package/build/CMakeFiles/CMakeOutput.log +0 -413
- package/build/CMakeFiles/TargetDirectories.txt +0 -3
- package/build/CMakeFiles/cmake.check_cache +0 -1
- package/build/CMakeFiles/generate.stamp +0 -1
- package/build/CMakeFiles/generate.stamp.depend +0 -109
- package/build/CMakeFiles/generate.stamp.list +0 -1
- package/build/Release/koffi.exp +0 -0
- package/build/Release/koffi.lib +0 -0
- package/build/Release/koffi.node +0 -0
- package/build/ZERO_CHECK.vcxproj +0 -176
- package/build/ZERO_CHECK.vcxproj.filters +0 -13
- package/build/cmake_install.cmake +0 -44
- package/build/koffi.dir/Release/call_arm64.obj +0 -0
- package/build/koffi.dir/Release/call_x64_sysv.obj +0 -0
- package/build/koffi.dir/Release/call_x64_win.obj +0 -0
- package/build/koffi.dir/Release/call_x64_win_fwd.obj +0 -0
- package/build/koffi.dir/Release/call_x86.obj +0 -0
- package/build/koffi.dir/Release/ffi.obj +0 -0
- package/build/koffi.dir/Release/koffi.node.recipe +0 -14
- package/build/koffi.dir/Release/koffi.tlog/CL.command.1.tlog +0 -0
- package/build/koffi.dir/Release/koffi.tlog/CL.read.1.tlog +0 -0
- package/build/koffi.dir/Release/koffi.tlog/CL.write.1.tlog +0 -0
- package/build/koffi.dir/Release/koffi.tlog/CustomBuild.command.1.tlog +0 -10
- package/build/koffi.dir/Release/koffi.tlog/CustomBuild.read.1.tlog +0 -108
- package/build/koffi.dir/Release/koffi.tlog/CustomBuild.write.1.tlog +0 -2
- package/build/koffi.dir/Release/koffi.tlog/Masm.read.1u.tlog +0 -0
- package/build/koffi.dir/Release/koffi.tlog/Masm.write.1u.tlog +0 -0
- package/build/koffi.dir/Release/koffi.tlog/koffi.lastbuildstate +0 -2
- package/build/koffi.dir/Release/koffi.tlog/koffi.write.1u.tlog +0 -0
- package/build/koffi.dir/Release/koffi.tlog/link.command.1.tlog +0 -0
- package/build/koffi.dir/Release/koffi.tlog/link.read.1.tlog +0 -0
- package/build/koffi.dir/Release/koffi.tlog/link.write.1.tlog +0 -0
- package/build/koffi.dir/Release/libcc.obj +0 -0
- package/build/koffi.dir/Release/util.obj +0 -0
- package/build/koffi.dir/Release/win_delay_load_hook.obj +0 -0
- package/build/koffi.sln +0 -53
- package/build/koffi.vcxproj +0 -363
- package/build/koffi.vcxproj.filters +0 -40
- package/build/x64/Release/ALL_BUILD/ALL_BUILD.recipe +0 -17
- package/build/x64/Release/ALL_BUILD/ALL_BUILD.tlog/ALL_BUILD.lastbuildstate +0 -2
- package/build/x64/Release/ALL_BUILD/ALL_BUILD.tlog/CustomBuild.command.1.tlog +0 -10
- package/build/x64/Release/ALL_BUILD/ALL_BUILD.tlog/CustomBuild.read.1.tlog +0 -108
- package/build/x64/Release/ALL_BUILD/ALL_BUILD.tlog/CustomBuild.write.1.tlog +0 -2
- package/build/x64/Release/ZERO_CHECK/ZERO_CHECK.recipe +0 -11
- package/build/x64/Release/ZERO_CHECK/ZERO_CHECK.tlog/CustomBuild.command.1.tlog +0 -10
- package/build/x64/Release/ZERO_CHECK/ZERO_CHECK.tlog/CustomBuild.read.1.tlog +0 -109
- package/build/x64/Release/ZERO_CHECK/ZERO_CHECK.tlog/CustomBuild.write.1.tlog +0 -2
- package/build/x64/Release/ZERO_CHECK/ZERO_CHECK.tlog/ZERO_CHECK.lastbuildstate +0 -2
package/src/call_x64_sysv.cc
CHANGED
|
@@ -1,477 +1,477 @@
|
|
|
1
|
-
// This program is free software: you can redistribute it and/or modify
|
|
2
|
-
// it under the terms of the GNU Affero General Public License as published by
|
|
3
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
4
|
-
// (at your option) any later version.
|
|
5
|
-
//
|
|
6
|
-
// This program is distributed in the hope that it will be useful,
|
|
7
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
8
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
9
|
-
// GNU Affero General Public License for more details.
|
|
10
|
-
//
|
|
11
|
-
// You should have received a copy of the GNU Affero General Public License
|
|
12
|
-
// along with this program. If not, see https://www.gnu.org/licenses/.
|
|
13
|
-
|
|
14
|
-
#if defined(__x86_64__) && !defined(_WIN64)
|
|
15
|
-
|
|
16
|
-
#include "vendor/libcc/libcc.hh"
|
|
17
|
-
#include "ffi.hh"
|
|
18
|
-
#include "call.hh"
|
|
19
|
-
#include "util.hh"
|
|
20
|
-
|
|
21
|
-
#include <napi.h>
|
|
22
|
-
|
|
23
|
-
namespace RG {
|
|
24
|
-
|
|
25
|
-
enum class RegisterClass {
|
|
26
|
-
NoClass = 0, // Explicitly 0
|
|
27
|
-
Integer,
|
|
28
|
-
SSE,
|
|
29
|
-
Memory
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
struct RaxRdxRet {
|
|
33
|
-
uint64_t rax;
|
|
34
|
-
uint64_t rdx;
|
|
35
|
-
};
|
|
36
|
-
struct RaxXmm0Ret {
|
|
37
|
-
uint64_t rax;
|
|
38
|
-
double xmm0;
|
|
39
|
-
};
|
|
40
|
-
struct Xmm0RaxRet {
|
|
41
|
-
double xmm0;
|
|
42
|
-
uint64_t rax;
|
|
43
|
-
};
|
|
44
|
-
struct Xmm0Xmm1Ret {
|
|
45
|
-
double xmm0;
|
|
46
|
-
double xmm1;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
extern "C" RaxRdxRet ForwardCallGG(const void *func, uint8_t *sp);
|
|
50
|
-
extern "C" float ForwardCallF(const void *func, uint8_t *sp);
|
|
51
|
-
extern "C" Xmm0RaxRet ForwardCallDG(const void *func, uint8_t *sp);
|
|
52
|
-
extern "C" RaxXmm0Ret ForwardCallGD(const void *func, uint8_t *sp);
|
|
53
|
-
extern "C" Xmm0Xmm1Ret ForwardCallDD(const void *func, uint8_t *sp);
|
|
54
|
-
|
|
55
|
-
extern "C" RaxRdxRet ForwardCallXGG(const void *func, uint8_t *sp);
|
|
56
|
-
extern "C" float ForwardCallXF(const void *func, uint8_t *sp);
|
|
57
|
-
extern "C" Xmm0RaxRet ForwardCallXDG(const void *func, uint8_t *sp);
|
|
58
|
-
extern "C" RaxXmm0Ret ForwardCallXGD(const void *func, uint8_t *sp);
|
|
59
|
-
extern "C" Xmm0Xmm1Ret ForwardCallXDD(const void *func, uint8_t *sp);
|
|
60
|
-
|
|
61
|
-
static inline RegisterClass MergeClasses(RegisterClass cls1, RegisterClass cls2)
|
|
62
|
-
{
|
|
63
|
-
if (cls1 == cls2)
|
|
64
|
-
return cls1;
|
|
65
|
-
|
|
66
|
-
if (cls1 == RegisterClass::NoClass)
|
|
67
|
-
return cls2;
|
|
68
|
-
if (cls2 == RegisterClass::NoClass)
|
|
69
|
-
return cls1;
|
|
70
|
-
|
|
71
|
-
if (cls1 == RegisterClass::Memory || cls2 == RegisterClass::Memory)
|
|
72
|
-
return RegisterClass::Memory;
|
|
73
|
-
if (cls1 == RegisterClass::Integer || cls2 == RegisterClass::Integer)
|
|
74
|
-
return RegisterClass::Integer;
|
|
75
|
-
|
|
76
|
-
return RegisterClass::SSE;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
static Size ClassifyType(const TypeInfo *type, Size offset, Span<RegisterClass> classes)
|
|
80
|
-
{
|
|
81
|
-
RG_ASSERT(classes.len > 0);
|
|
82
|
-
|
|
83
|
-
switch (type->primitive) {
|
|
84
|
-
case PrimitiveKind::Void: { return 0; } break;
|
|
85
|
-
|
|
86
|
-
case PrimitiveKind::Bool:
|
|
87
|
-
case PrimitiveKind::Int8:
|
|
88
|
-
case PrimitiveKind::UInt8:
|
|
89
|
-
case PrimitiveKind::Int16:
|
|
90
|
-
case PrimitiveKind::UInt16:
|
|
91
|
-
case PrimitiveKind::Int32:
|
|
92
|
-
case PrimitiveKind::UInt32:
|
|
93
|
-
case PrimitiveKind::Int64:
|
|
94
|
-
case PrimitiveKind::UInt64:
|
|
95
|
-
case PrimitiveKind::String:
|
|
96
|
-
case PrimitiveKind::Pointer: {
|
|
97
|
-
classes[0] = MergeClasses(classes[0], RegisterClass::Integer);
|
|
98
|
-
return 1;
|
|
99
|
-
} break;
|
|
100
|
-
|
|
101
|
-
case PrimitiveKind::Float32:
|
|
102
|
-
case PrimitiveKind::Float64: {
|
|
103
|
-
classes[0] = MergeClasses(classes[0], RegisterClass::SSE);
|
|
104
|
-
return 1;
|
|
105
|
-
} break;
|
|
106
|
-
|
|
107
|
-
case PrimitiveKind::Record: {
|
|
108
|
-
if (type->size > 64) {
|
|
109
|
-
classes[0] = MergeClasses(classes[0], RegisterClass::Memory);
|
|
110
|
-
return 1;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
for (const RecordMember &member: type->members) {
|
|
114
|
-
Size start = offset / 8;
|
|
115
|
-
ClassifyType(member.type, offset % 8, classes.Take(start, classes.len - start));
|
|
116
|
-
offset += member.type->size;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return (offset + 7) / 8;
|
|
120
|
-
} break;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
RG_UNREACHABLE();
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
static void AnalyseParameter(ParameterInfo *param, int gpr_avail, int xmm_avail)
|
|
127
|
-
{
|
|
128
|
-
LocalArray<RegisterClass, 8> classes = {};
|
|
129
|
-
classes.len = ClassifyType(param->type, 0, classes.data);
|
|
130
|
-
|
|
131
|
-
if (!classes.len)
|
|
132
|
-
return;
|
|
133
|
-
if (classes.len > 2) {
|
|
134
|
-
param->use_memory = true;
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
int gpr_count = 0;
|
|
139
|
-
int xmm_count = 0;
|
|
140
|
-
|
|
141
|
-
for (RegisterClass cls: classes) {
|
|
142
|
-
RG_ASSERT(cls != RegisterClass::NoClass);
|
|
143
|
-
|
|
144
|
-
if (cls == RegisterClass::Memory) {
|
|
145
|
-
param->use_memory = true;
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
gpr_count += (cls == RegisterClass::Integer);
|
|
150
|
-
xmm_count += (cls == RegisterClass::SSE);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (gpr_count <= gpr_avail && xmm_count <= xmm_avail){
|
|
154
|
-
param->gpr_count = (int8_t)gpr_count;
|
|
155
|
-
param->xmm_count = (int8_t)xmm_count;
|
|
156
|
-
param->gpr_first = (classes[0] == RegisterClass::Integer);
|
|
157
|
-
} else {
|
|
158
|
-
param->use_memory = true;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
bool AnalyseFunction(FunctionInfo *func)
|
|
163
|
-
{
|
|
164
|
-
AnalyseParameter(&func->ret, 2, 2);
|
|
165
|
-
|
|
166
|
-
int gpr_avail = 6 - func->ret.use_memory;
|
|
167
|
-
int xmm_avail = 8;
|
|
168
|
-
|
|
169
|
-
for (ParameterInfo ¶m: func->parameters) {
|
|
170
|
-
AnalyseParameter(¶m, gpr_avail, xmm_avail);
|
|
171
|
-
|
|
172
|
-
gpr_avail -= param.gpr_count;
|
|
173
|
-
xmm_avail -= param.xmm_count;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
func->forward_fp = (xmm_avail < 8);
|
|
177
|
-
|
|
178
|
-
return true;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
Napi::Value TranslateCall(const Napi::CallbackInfo &info)
|
|
182
|
-
{
|
|
183
|
-
Napi::Env env = info.Env();
|
|
184
|
-
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
185
|
-
|
|
186
|
-
FunctionInfo *func = (FunctionInfo *)info.Data();
|
|
187
|
-
LibraryData *lib = func->lib.get();
|
|
188
|
-
|
|
189
|
-
RG_DEFER { lib->tmp_alloc.ReleaseAll(); };
|
|
190
|
-
|
|
191
|
-
// Sanity checks
|
|
192
|
-
if (info.Length() < (uint32_t)func->parameters.len) {
|
|
193
|
-
ThrowError<Napi::TypeError>(env, "Expected %1 arguments, got %2", func->parameters.len, info.Length());
|
|
194
|
-
return env.Null();
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Stack pointer and register
|
|
198
|
-
uint8_t *top_ptr = lib->stack.end();
|
|
199
|
-
uint8_t *return_ptr = nullptr;
|
|
200
|
-
uint8_t *args_ptr = nullptr;
|
|
201
|
-
uint64_t *gpr_ptr = nullptr, *xmm_ptr = nullptr;
|
|
202
|
-
uint8_t *sp_ptr = nullptr;
|
|
203
|
-
|
|
204
|
-
// Return through registers unless it's too big
|
|
205
|
-
if (!func->ret.use_memory) {
|
|
206
|
-
args_ptr = top_ptr - func->scratch_size;
|
|
207
|
-
xmm_ptr = (uint64_t *)args_ptr - 8;
|
|
208
|
-
gpr_ptr = xmm_ptr - 6;
|
|
209
|
-
sp_ptr = (uint8_t *)gpr_ptr;
|
|
210
|
-
|
|
211
|
-
#ifdef RG_DEBUG
|
|
212
|
-
memset(sp_ptr, 0, top_ptr - sp_ptr);
|
|
213
|
-
#endif
|
|
214
|
-
} else {
|
|
215
|
-
return_ptr = top_ptr - AlignLen(func->ret.type->size, 16);
|
|
216
|
-
|
|
217
|
-
args_ptr = return_ptr - func->scratch_size;
|
|
218
|
-
xmm_ptr = (uint64_t *)args_ptr - 8;
|
|
219
|
-
gpr_ptr = xmm_ptr - 6;
|
|
220
|
-
sp_ptr = (uint8_t *)gpr_ptr;
|
|
221
|
-
|
|
222
|
-
#ifdef RG_DEBUG
|
|
223
|
-
memset(sp_ptr, 0, top_ptr - sp_ptr);
|
|
224
|
-
#endif
|
|
225
|
-
|
|
226
|
-
*(gpr_ptr++) = (uint64_t)return_ptr;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
RG_ASSERT(AlignUp(lib->stack.ptr, 16) == lib->stack.ptr);
|
|
230
|
-
RG_ASSERT(AlignUp(lib->stack.end(), 16) == lib->stack.end());
|
|
231
|
-
RG_ASSERT(AlignUp(args_ptr, 16) == args_ptr);
|
|
232
|
-
|
|
233
|
-
// Push arguments
|
|
234
|
-
for (Size i = 0; i < func->parameters.len; i++) {
|
|
235
|
-
const ParameterInfo ¶m = func->parameters[i];
|
|
236
|
-
Napi::Value value = info[i];
|
|
237
|
-
|
|
238
|
-
switch (param.type->primitive) {
|
|
239
|
-
case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
|
|
240
|
-
|
|
241
|
-
case PrimitiveKind::Bool: {
|
|
242
|
-
if (RG_UNLIKELY(!value.IsBoolean())) {
|
|
243
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argmument %2, expected boolean", GetValueType(instance, value), i + 1);
|
|
244
|
-
return env.Null();
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
bool b = value.As<Napi::Boolean>();
|
|
248
|
-
|
|
249
|
-
if (RG_LIKELY(param.gpr_count)) {
|
|
250
|
-
*(gpr_ptr++) = (uint64_t)b;
|
|
251
|
-
} else {
|
|
252
|
-
*(args_ptr++) = (uint8_t)b;
|
|
253
|
-
}
|
|
254
|
-
} break;
|
|
255
|
-
case PrimitiveKind::Int8:
|
|
256
|
-
case PrimitiveKind::UInt8:
|
|
257
|
-
case PrimitiveKind::Int16:
|
|
258
|
-
case PrimitiveKind::UInt16:
|
|
259
|
-
case PrimitiveKind::Int32:
|
|
260
|
-
case PrimitiveKind::UInt32:
|
|
261
|
-
case PrimitiveKind::Int64:
|
|
262
|
-
case PrimitiveKind::UInt64: {
|
|
263
|
-
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
264
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
|
|
265
|
-
return env.Null();
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
int64_t v = CopyNodeNumber<int64_t>(value);
|
|
269
|
-
|
|
270
|
-
if (RG_LIKELY(param.gpr_count)) {
|
|
271
|
-
*(gpr_ptr++) = (uint64_t)v;
|
|
272
|
-
} else {
|
|
273
|
-
args_ptr = AlignUp(args_ptr, param.type->align);
|
|
274
|
-
memcpy(args_ptr, &v, param.type->size); // Little Endian
|
|
275
|
-
args_ptr += param.type->size;
|
|
276
|
-
}
|
|
277
|
-
} break;
|
|
278
|
-
case PrimitiveKind::Float32: {
|
|
279
|
-
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
280
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
|
|
281
|
-
return env.Null();
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
float f = CopyNodeNumber<float>(value);
|
|
285
|
-
|
|
286
|
-
if (RG_LIKELY(param.xmm_count)) {
|
|
287
|
-
memcpy(xmm_ptr++, &f, 4);
|
|
288
|
-
} else {
|
|
289
|
-
args_ptr = AlignUp(args_ptr, 4);
|
|
290
|
-
memcpy(args_ptr, &f, 4);
|
|
291
|
-
args_ptr += 4;
|
|
292
|
-
}
|
|
293
|
-
} break;
|
|
294
|
-
case PrimitiveKind::Float64: {
|
|
295
|
-
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
296
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
|
|
297
|
-
return env.Null();
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
double d = CopyNodeNumber<double>(value);
|
|
301
|
-
|
|
302
|
-
if (RG_LIKELY(param.xmm_count)) {
|
|
303
|
-
memcpy(xmm_ptr++, &d, 8);
|
|
304
|
-
} else {
|
|
305
|
-
args_ptr = AlignUp(args_ptr, 8);
|
|
306
|
-
memcpy(args_ptr, &d, 8);
|
|
307
|
-
args_ptr += 8;
|
|
308
|
-
}
|
|
309
|
-
} break;
|
|
310
|
-
case PrimitiveKind::String: {
|
|
311
|
-
if (RG_UNLIKELY(!value.IsString())) {
|
|
312
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected string", GetValueType(instance, value), i + 1);
|
|
313
|
-
return env.Null();
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
const char *str = CopyNodeString(value, &lib->tmp_alloc);
|
|
317
|
-
|
|
318
|
-
if (RG_LIKELY(param.gpr_count)) {
|
|
319
|
-
*(gpr_ptr++) = (uint64_t)str;
|
|
320
|
-
} else {
|
|
321
|
-
args_ptr = AlignUp(args_ptr, 8);
|
|
322
|
-
*(uint64_t *)args_ptr = (uint64_t)str;
|
|
323
|
-
args_ptr += 8;
|
|
324
|
-
}
|
|
325
|
-
} break;
|
|
326
|
-
case PrimitiveKind::Pointer: {
|
|
327
|
-
if (RG_UNLIKELY(!CheckValueTag(instance, value, param.type))) {
|
|
328
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected %3", GetValueType(instance, value), i + 1, param.type->name);
|
|
329
|
-
return env.Null();
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
void *ptr = value.As<Napi::External<void>>();
|
|
333
|
-
|
|
334
|
-
if (RG_LIKELY(param.gpr_count)) {
|
|
335
|
-
*(gpr_ptr++) = (uint64_t)ptr;
|
|
336
|
-
} else {
|
|
337
|
-
args_ptr = AlignUp(args_ptr, 8);
|
|
338
|
-
*(uint64_t *)args_ptr = (uint64_t)ptr;
|
|
339
|
-
args_ptr += 8;
|
|
340
|
-
}
|
|
341
|
-
} break;
|
|
342
|
-
|
|
343
|
-
case PrimitiveKind::Record: {
|
|
344
|
-
if (RG_UNLIKELY(!value.IsObject())) {
|
|
345
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected object", GetValueType(instance, value), i + 1);
|
|
346
|
-
return env.Null();
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
Napi::Object obj = value.As<Napi::Object>();
|
|
350
|
-
|
|
351
|
-
if (param.gpr_count || param.xmm_count) {
|
|
352
|
-
RG_ASSERT(param.type->size <= 16);
|
|
353
|
-
|
|
354
|
-
uint64_t buf[2] = {};
|
|
355
|
-
if (!PushObject(obj, param.type, &lib->tmp_alloc, (uint8_t *)buf))
|
|
356
|
-
return env.Null();
|
|
357
|
-
|
|
358
|
-
if (param.gpr_first) {
|
|
359
|
-
uint64_t *ptr = buf;
|
|
360
|
-
|
|
361
|
-
*(gpr_ptr++) = *(ptr++);
|
|
362
|
-
if (param.gpr_count == 2) {
|
|
363
|
-
*(gpr_ptr++) = *(ptr++);
|
|
364
|
-
} else if (param.xmm_count == 1) {
|
|
365
|
-
*(xmm_ptr++) = *(ptr++);
|
|
366
|
-
}
|
|
367
|
-
} else {
|
|
368
|
-
uint64_t *ptr = buf;
|
|
369
|
-
|
|
370
|
-
*(xmm_ptr++) = *(ptr++);
|
|
371
|
-
if (param.xmm_count == 2) {
|
|
372
|
-
*(xmm_ptr++) = *(ptr++);
|
|
373
|
-
} else if (param.gpr_count == 1) {
|
|
374
|
-
*(gpr_ptr++) = *(ptr++);
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
} else if (param.use_memory) {
|
|
378
|
-
args_ptr = AlignUp(args_ptr, param.type->align);
|
|
379
|
-
if (!PushObject(obj, param.type, &lib->tmp_alloc, args_ptr))
|
|
380
|
-
return env.Null();
|
|
381
|
-
args_ptr += param.type->size;
|
|
382
|
-
}
|
|
383
|
-
} break;
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
// DumpStack(func, MakeSpan(sp_ptr, top_ptr - sp_ptr));
|
|
388
|
-
|
|
389
|
-
#define PERFORM_CALL(Suffix) \
|
|
390
|
-
(func->forward_fp ? ForwardCallX ## Suffix(func->func, sp_ptr) \
|
|
391
|
-
: ForwardCall ## Suffix(func->func, sp_ptr))
|
|
392
|
-
|
|
393
|
-
// Execute and convert return value
|
|
394
|
-
switch (func->ret.type->primitive) {
|
|
395
|
-
case PrimitiveKind::Float32: {
|
|
396
|
-
float f = PERFORM_CALL(F);
|
|
397
|
-
|
|
398
|
-
return Napi::Number::New(env, (double)f);
|
|
399
|
-
} break;
|
|
400
|
-
|
|
401
|
-
case PrimitiveKind::Float64: {
|
|
402
|
-
Xmm0RaxRet ret = PERFORM_CALL(DG);
|
|
403
|
-
|
|
404
|
-
return Napi::Number::New(env, ret.xmm0);
|
|
405
|
-
} break;
|
|
406
|
-
|
|
407
|
-
case PrimitiveKind::Record: {
|
|
408
|
-
if (func->ret.gpr_first && !func->ret.xmm_count) {
|
|
409
|
-
RaxRdxRet ret = PERFORM_CALL(GG);
|
|
410
|
-
|
|
411
|
-
Napi::Object obj = PopObject(env, (const uint8_t *)&ret, func->ret.type);
|
|
412
|
-
return obj;
|
|
413
|
-
} else if (func->ret.gpr_first) {
|
|
414
|
-
RaxXmm0Ret ret = PERFORM_CALL(GD);
|
|
415
|
-
|
|
416
|
-
Napi::Object obj = PopObject(env, (const uint8_t *)&ret, func->ret.type);
|
|
417
|
-
return obj;
|
|
418
|
-
} else if (func->ret.xmm_count) {
|
|
419
|
-
Xmm0RaxRet ret = PERFORM_CALL(DG);
|
|
420
|
-
|
|
421
|
-
Napi::Object obj = PopObject(env, (const uint8_t *)&ret, func->ret.type);
|
|
422
|
-
return obj;
|
|
423
|
-
} else if (func->ret.type->size) {
|
|
424
|
-
RG_ASSERT(return_ptr);
|
|
425
|
-
|
|
426
|
-
RaxRdxRet ret = PERFORM_CALL(GG);
|
|
427
|
-
RG_ASSERT(ret.rax == (uint64_t)return_ptr);
|
|
428
|
-
|
|
429
|
-
Napi::Object obj = PopObject(env, return_ptr, func->ret.type);
|
|
430
|
-
return obj;
|
|
431
|
-
} else {
|
|
432
|
-
PERFORM_CALL(GG);
|
|
433
|
-
|
|
434
|
-
Napi::Object obj = Napi::Object::New(env);
|
|
435
|
-
return obj;
|
|
436
|
-
}
|
|
437
|
-
} break;
|
|
438
|
-
|
|
439
|
-
default: {
|
|
440
|
-
RaxRdxRet ret = PERFORM_CALL(GG);
|
|
441
|
-
|
|
442
|
-
switch (func->ret.type->primitive) {
|
|
443
|
-
case PrimitiveKind::Void: return env.Null();
|
|
444
|
-
case PrimitiveKind::Bool: return Napi::Boolean::New(env, ret.rax);
|
|
445
|
-
case PrimitiveKind::Int8: return Napi::Number::New(env, (double)ret.rax);
|
|
446
|
-
case PrimitiveKind::UInt8: return Napi::Number::New(env, (double)ret.rax);
|
|
447
|
-
case PrimitiveKind::Int16: return Napi::Number::New(env, (double)ret.rax);
|
|
448
|
-
case PrimitiveKind::UInt16: return Napi::Number::New(env, (double)ret.rax);
|
|
449
|
-
case PrimitiveKind::Int32: return Napi::Number::New(env, (double)ret.rax);
|
|
450
|
-
case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)ret.rax);
|
|
451
|
-
case PrimitiveKind::Int64: return Napi::BigInt::New(env, (int64_t)ret.rax);
|
|
452
|
-
case PrimitiveKind::UInt64: return Napi::BigInt::New(env, ret.rax);
|
|
453
|
-
case PrimitiveKind::Float32: { RG_UNREACHABLE(); } break;
|
|
454
|
-
case PrimitiveKind::Float64: { RG_UNREACHABLE(); } break;
|
|
455
|
-
case PrimitiveKind::String: return Napi::String::New(env, (const char *)ret.rax);
|
|
456
|
-
case PrimitiveKind::Pointer: {
|
|
457
|
-
void *ptr = (void *)ret.rax;
|
|
458
|
-
|
|
459
|
-
Napi::External<void> external = Napi::External<void>::New(env, ptr);
|
|
460
|
-
SetValueTag(instance, external, func->ret.type);
|
|
461
|
-
|
|
462
|
-
return external;
|
|
463
|
-
} break;
|
|
464
|
-
|
|
465
|
-
case PrimitiveKind::Record: { RG_UNREACHABLE(); } break;
|
|
466
|
-
}
|
|
467
|
-
} break;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
#undef PERFORM_CALL
|
|
471
|
-
|
|
472
|
-
RG_UNREACHABLE();
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
#endif
|
|
1
|
+
// This program is free software: you can redistribute it and/or modify
|
|
2
|
+
// it under the terms of the GNU Affero General Public License as published by
|
|
3
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
4
|
+
// (at your option) any later version.
|
|
5
|
+
//
|
|
6
|
+
// This program is distributed in the hope that it will be useful,
|
|
7
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
8
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
9
|
+
// GNU Affero General Public License for more details.
|
|
10
|
+
//
|
|
11
|
+
// You should have received a copy of the GNU Affero General Public License
|
|
12
|
+
// along with this program. If not, see https://www.gnu.org/licenses/.
|
|
13
|
+
|
|
14
|
+
#if defined(__x86_64__) && !defined(_WIN64)
|
|
15
|
+
|
|
16
|
+
#include "vendor/libcc/libcc.hh"
|
|
17
|
+
#include "ffi.hh"
|
|
18
|
+
#include "call.hh"
|
|
19
|
+
#include "util.hh"
|
|
20
|
+
|
|
21
|
+
#include <napi.h>
|
|
22
|
+
|
|
23
|
+
namespace RG {
|
|
24
|
+
|
|
25
|
+
enum class RegisterClass {
|
|
26
|
+
NoClass = 0, // Explicitly 0
|
|
27
|
+
Integer,
|
|
28
|
+
SSE,
|
|
29
|
+
Memory
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
struct RaxRdxRet {
|
|
33
|
+
uint64_t rax;
|
|
34
|
+
uint64_t rdx;
|
|
35
|
+
};
|
|
36
|
+
struct RaxXmm0Ret {
|
|
37
|
+
uint64_t rax;
|
|
38
|
+
double xmm0;
|
|
39
|
+
};
|
|
40
|
+
struct Xmm0RaxRet {
|
|
41
|
+
double xmm0;
|
|
42
|
+
uint64_t rax;
|
|
43
|
+
};
|
|
44
|
+
struct Xmm0Xmm1Ret {
|
|
45
|
+
double xmm0;
|
|
46
|
+
double xmm1;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
extern "C" RaxRdxRet ForwardCallGG(const void *func, uint8_t *sp);
|
|
50
|
+
extern "C" float ForwardCallF(const void *func, uint8_t *sp);
|
|
51
|
+
extern "C" Xmm0RaxRet ForwardCallDG(const void *func, uint8_t *sp);
|
|
52
|
+
extern "C" RaxXmm0Ret ForwardCallGD(const void *func, uint8_t *sp);
|
|
53
|
+
extern "C" Xmm0Xmm1Ret ForwardCallDD(const void *func, uint8_t *sp);
|
|
54
|
+
|
|
55
|
+
extern "C" RaxRdxRet ForwardCallXGG(const void *func, uint8_t *sp);
|
|
56
|
+
extern "C" float ForwardCallXF(const void *func, uint8_t *sp);
|
|
57
|
+
extern "C" Xmm0RaxRet ForwardCallXDG(const void *func, uint8_t *sp);
|
|
58
|
+
extern "C" RaxXmm0Ret ForwardCallXGD(const void *func, uint8_t *sp);
|
|
59
|
+
extern "C" Xmm0Xmm1Ret ForwardCallXDD(const void *func, uint8_t *sp);
|
|
60
|
+
|
|
61
|
+
static inline RegisterClass MergeClasses(RegisterClass cls1, RegisterClass cls2)
|
|
62
|
+
{
|
|
63
|
+
if (cls1 == cls2)
|
|
64
|
+
return cls1;
|
|
65
|
+
|
|
66
|
+
if (cls1 == RegisterClass::NoClass)
|
|
67
|
+
return cls2;
|
|
68
|
+
if (cls2 == RegisterClass::NoClass)
|
|
69
|
+
return cls1;
|
|
70
|
+
|
|
71
|
+
if (cls1 == RegisterClass::Memory || cls2 == RegisterClass::Memory)
|
|
72
|
+
return RegisterClass::Memory;
|
|
73
|
+
if (cls1 == RegisterClass::Integer || cls2 == RegisterClass::Integer)
|
|
74
|
+
return RegisterClass::Integer;
|
|
75
|
+
|
|
76
|
+
return RegisterClass::SSE;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static Size ClassifyType(const TypeInfo *type, Size offset, Span<RegisterClass> classes)
|
|
80
|
+
{
|
|
81
|
+
RG_ASSERT(classes.len > 0);
|
|
82
|
+
|
|
83
|
+
switch (type->primitive) {
|
|
84
|
+
case PrimitiveKind::Void: { return 0; } break;
|
|
85
|
+
|
|
86
|
+
case PrimitiveKind::Bool:
|
|
87
|
+
case PrimitiveKind::Int8:
|
|
88
|
+
case PrimitiveKind::UInt8:
|
|
89
|
+
case PrimitiveKind::Int16:
|
|
90
|
+
case PrimitiveKind::UInt16:
|
|
91
|
+
case PrimitiveKind::Int32:
|
|
92
|
+
case PrimitiveKind::UInt32:
|
|
93
|
+
case PrimitiveKind::Int64:
|
|
94
|
+
case PrimitiveKind::UInt64:
|
|
95
|
+
case PrimitiveKind::String:
|
|
96
|
+
case PrimitiveKind::Pointer: {
|
|
97
|
+
classes[0] = MergeClasses(classes[0], RegisterClass::Integer);
|
|
98
|
+
return 1;
|
|
99
|
+
} break;
|
|
100
|
+
|
|
101
|
+
case PrimitiveKind::Float32:
|
|
102
|
+
case PrimitiveKind::Float64: {
|
|
103
|
+
classes[0] = MergeClasses(classes[0], RegisterClass::SSE);
|
|
104
|
+
return 1;
|
|
105
|
+
} break;
|
|
106
|
+
|
|
107
|
+
case PrimitiveKind::Record: {
|
|
108
|
+
if (type->size > 64) {
|
|
109
|
+
classes[0] = MergeClasses(classes[0], RegisterClass::Memory);
|
|
110
|
+
return 1;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
for (const RecordMember &member: type->members) {
|
|
114
|
+
Size start = offset / 8;
|
|
115
|
+
ClassifyType(member.type, offset % 8, classes.Take(start, classes.len - start));
|
|
116
|
+
offset += member.type->size;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return (offset + 7) / 8;
|
|
120
|
+
} break;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
RG_UNREACHABLE();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
static void AnalyseParameter(ParameterInfo *param, int gpr_avail, int xmm_avail)
|
|
127
|
+
{
|
|
128
|
+
LocalArray<RegisterClass, 8> classes = {};
|
|
129
|
+
classes.len = ClassifyType(param->type, 0, classes.data);
|
|
130
|
+
|
|
131
|
+
if (!classes.len)
|
|
132
|
+
return;
|
|
133
|
+
if (classes.len > 2) {
|
|
134
|
+
param->use_memory = true;
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
int gpr_count = 0;
|
|
139
|
+
int xmm_count = 0;
|
|
140
|
+
|
|
141
|
+
for (RegisterClass cls: classes) {
|
|
142
|
+
RG_ASSERT(cls != RegisterClass::NoClass);
|
|
143
|
+
|
|
144
|
+
if (cls == RegisterClass::Memory) {
|
|
145
|
+
param->use_memory = true;
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
gpr_count += (cls == RegisterClass::Integer);
|
|
150
|
+
xmm_count += (cls == RegisterClass::SSE);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (gpr_count <= gpr_avail && xmm_count <= xmm_avail){
|
|
154
|
+
param->gpr_count = (int8_t)gpr_count;
|
|
155
|
+
param->xmm_count = (int8_t)xmm_count;
|
|
156
|
+
param->gpr_first = (classes[0] == RegisterClass::Integer);
|
|
157
|
+
} else {
|
|
158
|
+
param->use_memory = true;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
bool AnalyseFunction(FunctionInfo *func)
|
|
163
|
+
{
|
|
164
|
+
AnalyseParameter(&func->ret, 2, 2);
|
|
165
|
+
|
|
166
|
+
int gpr_avail = 6 - func->ret.use_memory;
|
|
167
|
+
int xmm_avail = 8;
|
|
168
|
+
|
|
169
|
+
for (ParameterInfo ¶m: func->parameters) {
|
|
170
|
+
AnalyseParameter(¶m, gpr_avail, xmm_avail);
|
|
171
|
+
|
|
172
|
+
gpr_avail -= param.gpr_count;
|
|
173
|
+
xmm_avail -= param.xmm_count;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
func->forward_fp = (xmm_avail < 8);
|
|
177
|
+
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
Napi::Value TranslateCall(const Napi::CallbackInfo &info)
|
|
182
|
+
{
|
|
183
|
+
Napi::Env env = info.Env();
|
|
184
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
185
|
+
|
|
186
|
+
FunctionInfo *func = (FunctionInfo *)info.Data();
|
|
187
|
+
LibraryData *lib = func->lib.get();
|
|
188
|
+
|
|
189
|
+
RG_DEFER { lib->tmp_alloc.ReleaseAll(); };
|
|
190
|
+
|
|
191
|
+
// Sanity checks
|
|
192
|
+
if (info.Length() < (uint32_t)func->parameters.len) {
|
|
193
|
+
ThrowError<Napi::TypeError>(env, "Expected %1 arguments, got %2", func->parameters.len, info.Length());
|
|
194
|
+
return env.Null();
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Stack pointer and register
|
|
198
|
+
uint8_t *top_ptr = lib->stack.end();
|
|
199
|
+
uint8_t *return_ptr = nullptr;
|
|
200
|
+
uint8_t *args_ptr = nullptr;
|
|
201
|
+
uint64_t *gpr_ptr = nullptr, *xmm_ptr = nullptr;
|
|
202
|
+
uint8_t *sp_ptr = nullptr;
|
|
203
|
+
|
|
204
|
+
// Return through registers unless it's too big
|
|
205
|
+
if (!func->ret.use_memory) {
|
|
206
|
+
args_ptr = top_ptr - func->scratch_size;
|
|
207
|
+
xmm_ptr = (uint64_t *)args_ptr - 8;
|
|
208
|
+
gpr_ptr = xmm_ptr - 6;
|
|
209
|
+
sp_ptr = (uint8_t *)gpr_ptr;
|
|
210
|
+
|
|
211
|
+
#ifdef RG_DEBUG
|
|
212
|
+
memset(sp_ptr, 0, top_ptr - sp_ptr);
|
|
213
|
+
#endif
|
|
214
|
+
} else {
|
|
215
|
+
return_ptr = top_ptr - AlignLen(func->ret.type->size, 16);
|
|
216
|
+
|
|
217
|
+
args_ptr = return_ptr - func->scratch_size;
|
|
218
|
+
xmm_ptr = (uint64_t *)args_ptr - 8;
|
|
219
|
+
gpr_ptr = xmm_ptr - 6;
|
|
220
|
+
sp_ptr = (uint8_t *)gpr_ptr;
|
|
221
|
+
|
|
222
|
+
#ifdef RG_DEBUG
|
|
223
|
+
memset(sp_ptr, 0, top_ptr - sp_ptr);
|
|
224
|
+
#endif
|
|
225
|
+
|
|
226
|
+
*(gpr_ptr++) = (uint64_t)return_ptr;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
RG_ASSERT(AlignUp(lib->stack.ptr, 16) == lib->stack.ptr);
|
|
230
|
+
RG_ASSERT(AlignUp(lib->stack.end(), 16) == lib->stack.end());
|
|
231
|
+
RG_ASSERT(AlignUp(args_ptr, 16) == args_ptr);
|
|
232
|
+
|
|
233
|
+
// Push arguments
|
|
234
|
+
for (Size i = 0; i < func->parameters.len; i++) {
|
|
235
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
236
|
+
Napi::Value value = info[i];
|
|
237
|
+
|
|
238
|
+
switch (param.type->primitive) {
|
|
239
|
+
case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
|
|
240
|
+
|
|
241
|
+
case PrimitiveKind::Bool: {
|
|
242
|
+
if (RG_UNLIKELY(!value.IsBoolean())) {
|
|
243
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argmument %2, expected boolean", GetValueType(instance, value), i + 1);
|
|
244
|
+
return env.Null();
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
bool b = value.As<Napi::Boolean>();
|
|
248
|
+
|
|
249
|
+
if (RG_LIKELY(param.gpr_count)) {
|
|
250
|
+
*(gpr_ptr++) = (uint64_t)b;
|
|
251
|
+
} else {
|
|
252
|
+
*(args_ptr++) = (uint8_t)b;
|
|
253
|
+
}
|
|
254
|
+
} break;
|
|
255
|
+
case PrimitiveKind::Int8:
|
|
256
|
+
case PrimitiveKind::UInt8:
|
|
257
|
+
case PrimitiveKind::Int16:
|
|
258
|
+
case PrimitiveKind::UInt16:
|
|
259
|
+
case PrimitiveKind::Int32:
|
|
260
|
+
case PrimitiveKind::UInt32:
|
|
261
|
+
case PrimitiveKind::Int64:
|
|
262
|
+
case PrimitiveKind::UInt64: {
|
|
263
|
+
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
264
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
|
|
265
|
+
return env.Null();
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
int64_t v = CopyNodeNumber<int64_t>(value);
|
|
269
|
+
|
|
270
|
+
if (RG_LIKELY(param.gpr_count)) {
|
|
271
|
+
*(gpr_ptr++) = (uint64_t)v;
|
|
272
|
+
} else {
|
|
273
|
+
args_ptr = AlignUp(args_ptr, param.type->align);
|
|
274
|
+
memcpy(args_ptr, &v, param.type->size); // Little Endian
|
|
275
|
+
args_ptr += param.type->size;
|
|
276
|
+
}
|
|
277
|
+
} break;
|
|
278
|
+
case PrimitiveKind::Float32: {
|
|
279
|
+
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
280
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
|
|
281
|
+
return env.Null();
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
float f = CopyNodeNumber<float>(value);
|
|
285
|
+
|
|
286
|
+
if (RG_LIKELY(param.xmm_count)) {
|
|
287
|
+
memcpy(xmm_ptr++, &f, 4);
|
|
288
|
+
} else {
|
|
289
|
+
args_ptr = AlignUp(args_ptr, 4);
|
|
290
|
+
memcpy(args_ptr, &f, 4);
|
|
291
|
+
args_ptr += 4;
|
|
292
|
+
}
|
|
293
|
+
} break;
|
|
294
|
+
case PrimitiveKind::Float64: {
|
|
295
|
+
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
296
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
|
|
297
|
+
return env.Null();
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
double d = CopyNodeNumber<double>(value);
|
|
301
|
+
|
|
302
|
+
if (RG_LIKELY(param.xmm_count)) {
|
|
303
|
+
memcpy(xmm_ptr++, &d, 8);
|
|
304
|
+
} else {
|
|
305
|
+
args_ptr = AlignUp(args_ptr, 8);
|
|
306
|
+
memcpy(args_ptr, &d, 8);
|
|
307
|
+
args_ptr += 8;
|
|
308
|
+
}
|
|
309
|
+
} break;
|
|
310
|
+
case PrimitiveKind::String: {
|
|
311
|
+
if (RG_UNLIKELY(!value.IsString())) {
|
|
312
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected string", GetValueType(instance, value), i + 1);
|
|
313
|
+
return env.Null();
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const char *str = CopyNodeString(value, &lib->tmp_alloc);
|
|
317
|
+
|
|
318
|
+
if (RG_LIKELY(param.gpr_count)) {
|
|
319
|
+
*(gpr_ptr++) = (uint64_t)str;
|
|
320
|
+
} else {
|
|
321
|
+
args_ptr = AlignUp(args_ptr, 8);
|
|
322
|
+
*(uint64_t *)args_ptr = (uint64_t)str;
|
|
323
|
+
args_ptr += 8;
|
|
324
|
+
}
|
|
325
|
+
} break;
|
|
326
|
+
case PrimitiveKind::Pointer: {
|
|
327
|
+
if (RG_UNLIKELY(!CheckValueTag(instance, value, param.type))) {
|
|
328
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected %3", GetValueType(instance, value), i + 1, param.type->name);
|
|
329
|
+
return env.Null();
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
void *ptr = value.As<Napi::External<void>>();
|
|
333
|
+
|
|
334
|
+
if (RG_LIKELY(param.gpr_count)) {
|
|
335
|
+
*(gpr_ptr++) = (uint64_t)ptr;
|
|
336
|
+
} else {
|
|
337
|
+
args_ptr = AlignUp(args_ptr, 8);
|
|
338
|
+
*(uint64_t *)args_ptr = (uint64_t)ptr;
|
|
339
|
+
args_ptr += 8;
|
|
340
|
+
}
|
|
341
|
+
} break;
|
|
342
|
+
|
|
343
|
+
case PrimitiveKind::Record: {
|
|
344
|
+
if (RG_UNLIKELY(!value.IsObject())) {
|
|
345
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected object", GetValueType(instance, value), i + 1);
|
|
346
|
+
return env.Null();
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
Napi::Object obj = value.As<Napi::Object>();
|
|
350
|
+
|
|
351
|
+
if (param.gpr_count || param.xmm_count) {
|
|
352
|
+
RG_ASSERT(param.type->size <= 16);
|
|
353
|
+
|
|
354
|
+
uint64_t buf[2] = {};
|
|
355
|
+
if (!PushObject(obj, param.type, &lib->tmp_alloc, (uint8_t *)buf))
|
|
356
|
+
return env.Null();
|
|
357
|
+
|
|
358
|
+
if (param.gpr_first) {
|
|
359
|
+
uint64_t *ptr = buf;
|
|
360
|
+
|
|
361
|
+
*(gpr_ptr++) = *(ptr++);
|
|
362
|
+
if (param.gpr_count == 2) {
|
|
363
|
+
*(gpr_ptr++) = *(ptr++);
|
|
364
|
+
} else if (param.xmm_count == 1) {
|
|
365
|
+
*(xmm_ptr++) = *(ptr++);
|
|
366
|
+
}
|
|
367
|
+
} else {
|
|
368
|
+
uint64_t *ptr = buf;
|
|
369
|
+
|
|
370
|
+
*(xmm_ptr++) = *(ptr++);
|
|
371
|
+
if (param.xmm_count == 2) {
|
|
372
|
+
*(xmm_ptr++) = *(ptr++);
|
|
373
|
+
} else if (param.gpr_count == 1) {
|
|
374
|
+
*(gpr_ptr++) = *(ptr++);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
} else if (param.use_memory) {
|
|
378
|
+
args_ptr = AlignUp(args_ptr, param.type->align);
|
|
379
|
+
if (!PushObject(obj, param.type, &lib->tmp_alloc, args_ptr))
|
|
380
|
+
return env.Null();
|
|
381
|
+
args_ptr += param.type->size;
|
|
382
|
+
}
|
|
383
|
+
} break;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// DumpStack(func, MakeSpan(sp_ptr, top_ptr - sp_ptr));
|
|
388
|
+
|
|
389
|
+
#define PERFORM_CALL(Suffix) \
|
|
390
|
+
(func->forward_fp ? ForwardCallX ## Suffix(func->func, sp_ptr) \
|
|
391
|
+
: ForwardCall ## Suffix(func->func, sp_ptr))
|
|
392
|
+
|
|
393
|
+
// Execute and convert return value
|
|
394
|
+
switch (func->ret.type->primitive) {
|
|
395
|
+
case PrimitiveKind::Float32: {
|
|
396
|
+
float f = PERFORM_CALL(F);
|
|
397
|
+
|
|
398
|
+
return Napi::Number::New(env, (double)f);
|
|
399
|
+
} break;
|
|
400
|
+
|
|
401
|
+
case PrimitiveKind::Float64: {
|
|
402
|
+
Xmm0RaxRet ret = PERFORM_CALL(DG);
|
|
403
|
+
|
|
404
|
+
return Napi::Number::New(env, ret.xmm0);
|
|
405
|
+
} break;
|
|
406
|
+
|
|
407
|
+
case PrimitiveKind::Record: {
|
|
408
|
+
if (func->ret.gpr_first && !func->ret.xmm_count) {
|
|
409
|
+
RaxRdxRet ret = PERFORM_CALL(GG);
|
|
410
|
+
|
|
411
|
+
Napi::Object obj = PopObject(env, (const uint8_t *)&ret, func->ret.type);
|
|
412
|
+
return obj;
|
|
413
|
+
} else if (func->ret.gpr_first) {
|
|
414
|
+
RaxXmm0Ret ret = PERFORM_CALL(GD);
|
|
415
|
+
|
|
416
|
+
Napi::Object obj = PopObject(env, (const uint8_t *)&ret, func->ret.type);
|
|
417
|
+
return obj;
|
|
418
|
+
} else if (func->ret.xmm_count) {
|
|
419
|
+
Xmm0RaxRet ret = PERFORM_CALL(DG);
|
|
420
|
+
|
|
421
|
+
Napi::Object obj = PopObject(env, (const uint8_t *)&ret, func->ret.type);
|
|
422
|
+
return obj;
|
|
423
|
+
} else if (func->ret.type->size) {
|
|
424
|
+
RG_ASSERT(return_ptr);
|
|
425
|
+
|
|
426
|
+
RaxRdxRet ret = PERFORM_CALL(GG);
|
|
427
|
+
RG_ASSERT(ret.rax == (uint64_t)return_ptr);
|
|
428
|
+
|
|
429
|
+
Napi::Object obj = PopObject(env, return_ptr, func->ret.type);
|
|
430
|
+
return obj;
|
|
431
|
+
} else {
|
|
432
|
+
PERFORM_CALL(GG);
|
|
433
|
+
|
|
434
|
+
Napi::Object obj = Napi::Object::New(env);
|
|
435
|
+
return obj;
|
|
436
|
+
}
|
|
437
|
+
} break;
|
|
438
|
+
|
|
439
|
+
default: {
|
|
440
|
+
RaxRdxRet ret = PERFORM_CALL(GG);
|
|
441
|
+
|
|
442
|
+
switch (func->ret.type->primitive) {
|
|
443
|
+
case PrimitiveKind::Void: return env.Null();
|
|
444
|
+
case PrimitiveKind::Bool: return Napi::Boolean::New(env, ret.rax);
|
|
445
|
+
case PrimitiveKind::Int8: return Napi::Number::New(env, (double)ret.rax);
|
|
446
|
+
case PrimitiveKind::UInt8: return Napi::Number::New(env, (double)ret.rax);
|
|
447
|
+
case PrimitiveKind::Int16: return Napi::Number::New(env, (double)ret.rax);
|
|
448
|
+
case PrimitiveKind::UInt16: return Napi::Number::New(env, (double)ret.rax);
|
|
449
|
+
case PrimitiveKind::Int32: return Napi::Number::New(env, (double)ret.rax);
|
|
450
|
+
case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)ret.rax);
|
|
451
|
+
case PrimitiveKind::Int64: return Napi::BigInt::New(env, (int64_t)ret.rax);
|
|
452
|
+
case PrimitiveKind::UInt64: return Napi::BigInt::New(env, ret.rax);
|
|
453
|
+
case PrimitiveKind::Float32: { RG_UNREACHABLE(); } break;
|
|
454
|
+
case PrimitiveKind::Float64: { RG_UNREACHABLE(); } break;
|
|
455
|
+
case PrimitiveKind::String: return Napi::String::New(env, (const char *)ret.rax);
|
|
456
|
+
case PrimitiveKind::Pointer: {
|
|
457
|
+
void *ptr = (void *)ret.rax;
|
|
458
|
+
|
|
459
|
+
Napi::External<void> external = Napi::External<void>::New(env, ptr);
|
|
460
|
+
SetValueTag(instance, external, func->ret.type);
|
|
461
|
+
|
|
462
|
+
return external;
|
|
463
|
+
} break;
|
|
464
|
+
|
|
465
|
+
case PrimitiveKind::Record: { RG_UNREACHABLE(); } break;
|
|
466
|
+
}
|
|
467
|
+
} break;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
#undef PERFORM_CALL
|
|
471
|
+
|
|
472
|
+
RG_UNREACHABLE();
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
#endif
|