koffi 0.9.4 → 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
|
@@ -1,345 +1,345 @@
|
|
|
1
|
-
// Copyright 2018 Ulf Adams
|
|
2
|
-
//
|
|
3
|
-
// The contents of this file may be used under the terms of the Apache License,
|
|
4
|
-
// Version 2.0.
|
|
5
|
-
//
|
|
6
|
-
// (See accompanying file LICENSE-Apache or copy at
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0)
|
|
8
|
-
//
|
|
9
|
-
// Alternatively, the contents of this file may be used under the terms of
|
|
10
|
-
// the Boost Software License, Version 1.0.
|
|
11
|
-
// (See accompanying file LICENSE-Boost or copy at
|
|
12
|
-
// https://www.boost.org/LICENSE_1_0.txt)
|
|
13
|
-
//
|
|
14
|
-
// Unless required by applicable law or agreed to in writing, this software
|
|
15
|
-
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
16
|
-
// KIND, either express or implied.
|
|
17
|
-
|
|
18
|
-
// Runtime compiler options:
|
|
19
|
-
// -DRYU_DEBUG Generate verbose debugging output to stdout.
|
|
20
|
-
|
|
21
|
-
#include "ryu/ryu.h"
|
|
22
|
-
|
|
23
|
-
#include <assert.h>
|
|
24
|
-
#include <stdbool.h>
|
|
25
|
-
#include <stdint.h>
|
|
26
|
-
#include <stdlib.h>
|
|
27
|
-
#include <string.h>
|
|
28
|
-
#include <limits.h>
|
|
29
|
-
|
|
30
|
-
#ifdef RYU_DEBUG
|
|
31
|
-
#include <stdio.h>
|
|
32
|
-
#endif
|
|
33
|
-
|
|
34
|
-
#include "ryu/common.h"
|
|
35
|
-
#include "ryu/f2s_intrinsics.h"
|
|
36
|
-
#include "ryu/digit_table.h"
|
|
37
|
-
|
|
38
|
-
#define FLOAT_MANTISSA_BITS 23
|
|
39
|
-
#define FLOAT_EXPONENT_BITS 8
|
|
40
|
-
#define FLOAT_BIAS 127
|
|
41
|
-
|
|
42
|
-
// A floating decimal representing m * 10^e.
|
|
43
|
-
typedef struct floating_decimal_32 {
|
|
44
|
-
uint32_t mantissa;
|
|
45
|
-
// Decimal exponent's range is -45 to 38
|
|
46
|
-
// inclusive, and can fit in a short if needed.
|
|
47
|
-
int32_t exponent;
|
|
48
|
-
} floating_decimal_32;
|
|
49
|
-
|
|
50
|
-
static inline floating_decimal_32 f2d(const uint32_t ieeeMantissa, const uint32_t ieeeExponent) {
|
|
51
|
-
int32_t e2;
|
|
52
|
-
uint32_t m2;
|
|
53
|
-
if (ieeeExponent == 0) {
|
|
54
|
-
// We subtract 2 so that the bounds computation has 2 additional bits.
|
|
55
|
-
e2 = 1 - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2;
|
|
56
|
-
m2 = ieeeMantissa;
|
|
57
|
-
} else {
|
|
58
|
-
e2 = (int32_t) ieeeExponent - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2;
|
|
59
|
-
m2 = (1u << FLOAT_MANTISSA_BITS) | ieeeMantissa;
|
|
60
|
-
}
|
|
61
|
-
const bool even = (m2 & 1) == 0;
|
|
62
|
-
const bool acceptBounds = even;
|
|
63
|
-
|
|
64
|
-
#ifdef RYU_DEBUG
|
|
65
|
-
printf("-> %u * 2^%d\n", m2, e2 + 2);
|
|
66
|
-
#endif
|
|
67
|
-
|
|
68
|
-
// Step 2: Determine the interval of valid decimal representations.
|
|
69
|
-
const uint32_t mv = 4 * m2;
|
|
70
|
-
const uint32_t mp = 4 * m2 + 2;
|
|
71
|
-
// Implicit bool -> int conversion. True is 1, false is 0.
|
|
72
|
-
const uint32_t mmShift = ieeeMantissa != 0 || ieeeExponent <= 1;
|
|
73
|
-
const uint32_t mm = 4 * m2 - 1 - mmShift;
|
|
74
|
-
|
|
75
|
-
// Step 3: Convert to a decimal power base using 64-bit arithmetic.
|
|
76
|
-
uint32_t vr, vp, vm;
|
|
77
|
-
int32_t e10;
|
|
78
|
-
bool vmIsTrailingZeros = false;
|
|
79
|
-
bool vrIsTrailingZeros = false;
|
|
80
|
-
uint8_t lastRemovedDigit = 0;
|
|
81
|
-
if (e2 >= 0) {
|
|
82
|
-
const uint32_t q = log10Pow2(e2);
|
|
83
|
-
e10 = (int32_t) q;
|
|
84
|
-
const int32_t k = FLOAT_POW5_INV_BITCOUNT + pow5bits((int32_t) q) - 1;
|
|
85
|
-
const int32_t i = -e2 + (int32_t) q + k;
|
|
86
|
-
vr = mulPow5InvDivPow2(mv, q, i);
|
|
87
|
-
vp = mulPow5InvDivPow2(mp, q, i);
|
|
88
|
-
vm = mulPow5InvDivPow2(mm, q, i);
|
|
89
|
-
#ifdef RYU_DEBUG
|
|
90
|
-
printf("%u * 2^%d / 10^%u\n", mv, e2, q);
|
|
91
|
-
printf("V+=%u\nV =%u\nV-=%u\n", vp, vr, vm);
|
|
92
|
-
#endif
|
|
93
|
-
if (q != 0 && (vp - 1) / 10 <= vm / 10) {
|
|
94
|
-
// We need to know one removed digit even if we are not going to loop below. We could use
|
|
95
|
-
// q = X - 1 above, except that would require 33 bits for the result, and we've found that
|
|
96
|
-
// 32-bit arithmetic is faster even on 64-bit machines.
|
|
97
|
-
const int32_t l = FLOAT_POW5_INV_BITCOUNT + pow5bits((int32_t) (q - 1)) - 1;
|
|
98
|
-
lastRemovedDigit = (uint8_t) (mulPow5InvDivPow2(mv, q - 1, -e2 + (int32_t) q - 1 + l) % 10);
|
|
99
|
-
}
|
|
100
|
-
if (q <= 9) {
|
|
101
|
-
// The largest power of 5 that fits in 24 bits is 5^10, but q <= 9 seems to be safe as well.
|
|
102
|
-
// Only one of mp, mv, and mm can be a multiple of 5, if any.
|
|
103
|
-
if (mv % 5 == 0) {
|
|
104
|
-
vrIsTrailingZeros = multipleOfPowerOf5_32(mv, q);
|
|
105
|
-
} else if (acceptBounds) {
|
|
106
|
-
vmIsTrailingZeros = multipleOfPowerOf5_32(mm, q);
|
|
107
|
-
} else {
|
|
108
|
-
vp -= multipleOfPowerOf5_32(mp, q);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
} else {
|
|
112
|
-
const uint32_t q = log10Pow5(-e2);
|
|
113
|
-
e10 = (int32_t) q + e2;
|
|
114
|
-
const int32_t i = -e2 - (int32_t) q;
|
|
115
|
-
const int32_t k = pow5bits(i) - FLOAT_POW5_BITCOUNT;
|
|
116
|
-
int32_t j = (int32_t) q - k;
|
|
117
|
-
vr = mulPow5divPow2(mv, (uint32_t) i, j);
|
|
118
|
-
vp = mulPow5divPow2(mp, (uint32_t) i, j);
|
|
119
|
-
vm = mulPow5divPow2(mm, (uint32_t) i, j);
|
|
120
|
-
#ifdef RYU_DEBUG
|
|
121
|
-
printf("%u * 5^%d / 10^%u\n", mv, -e2, q);
|
|
122
|
-
printf("%u %d %d %d\n", q, i, k, j);
|
|
123
|
-
printf("V+=%u\nV =%u\nV-=%u\n", vp, vr, vm);
|
|
124
|
-
#endif
|
|
125
|
-
if (q != 0 && (vp - 1) / 10 <= vm / 10) {
|
|
126
|
-
j = (int32_t) q - 1 - (pow5bits(i + 1) - FLOAT_POW5_BITCOUNT);
|
|
127
|
-
lastRemovedDigit = (uint8_t) (mulPow5divPow2(mv, (uint32_t) (i + 1), j) % 10);
|
|
128
|
-
}
|
|
129
|
-
if (q <= 1) {
|
|
130
|
-
// {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q trailing 0 bits.
|
|
131
|
-
// mv = 4 * m2, so it always has at least two trailing 0 bits.
|
|
132
|
-
vrIsTrailingZeros = true;
|
|
133
|
-
if (acceptBounds) {
|
|
134
|
-
// mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff mmShift == 1.
|
|
135
|
-
vmIsTrailingZeros = mmShift == 1;
|
|
136
|
-
} else {
|
|
137
|
-
// mp = mv + 2, so it always has at least one trailing 0 bit.
|
|
138
|
-
--vp;
|
|
139
|
-
}
|
|
140
|
-
} else if (q < 31) { // TODO(ulfjack): Use a tighter bound here.
|
|
141
|
-
vrIsTrailingZeros = multipleOfPowerOf2_32(mv, q - 1);
|
|
142
|
-
#ifdef RYU_DEBUG
|
|
143
|
-
printf("vr is trailing zeros=%s\n", vrIsTrailingZeros ? "true" : "false");
|
|
144
|
-
#endif
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
#ifdef RYU_DEBUG
|
|
148
|
-
printf("e10=%d\n", e10);
|
|
149
|
-
printf("V+=%u\nV =%u\nV-=%u\n", vp, vr, vm);
|
|
150
|
-
printf("vm is trailing zeros=%s\n", vmIsTrailingZeros ? "true" : "false");
|
|
151
|
-
printf("vr is trailing zeros=%s\n", vrIsTrailingZeros ? "true" : "false");
|
|
152
|
-
#endif
|
|
153
|
-
|
|
154
|
-
// Step 4: Find the shortest decimal representation in the interval of valid representations.
|
|
155
|
-
int32_t removed = 0;
|
|
156
|
-
uint32_t output;
|
|
157
|
-
if (vmIsTrailingZeros || vrIsTrailingZeros) {
|
|
158
|
-
// General case, which happens rarely (~4.0%).
|
|
159
|
-
while (vp / 10 > vm / 10) {
|
|
160
|
-
#ifdef __clang__ // https://bugs.llvm.org/show_bug.cgi?id=23106
|
|
161
|
-
// The compiler does not realize that vm % 10 can be computed from vm / 10
|
|
162
|
-
// as vm - (vm / 10) * 10.
|
|
163
|
-
vmIsTrailingZeros &= vm - (vm / 10) * 10 == 0;
|
|
164
|
-
#else
|
|
165
|
-
vmIsTrailingZeros &= vm % 10 == 0;
|
|
166
|
-
#endif
|
|
167
|
-
vrIsTrailingZeros &= lastRemovedDigit == 0;
|
|
168
|
-
lastRemovedDigit = (uint8_t) (vr % 10);
|
|
169
|
-
vr /= 10;
|
|
170
|
-
vp /= 10;
|
|
171
|
-
vm /= 10;
|
|
172
|
-
++removed;
|
|
173
|
-
}
|
|
174
|
-
#ifdef RYU_DEBUG
|
|
175
|
-
printf("V+=%u\nV =%u\nV-=%u\n", vp, vr, vm);
|
|
176
|
-
printf("d-10=%s\n", vmIsTrailingZeros ? "true" : "false");
|
|
177
|
-
#endif
|
|
178
|
-
if (vmIsTrailingZeros) {
|
|
179
|
-
while (vm % 10 == 0) {
|
|
180
|
-
vrIsTrailingZeros &= lastRemovedDigit == 0;
|
|
181
|
-
lastRemovedDigit = (uint8_t) (vr % 10);
|
|
182
|
-
vr /= 10;
|
|
183
|
-
vp /= 10;
|
|
184
|
-
vm /= 10;
|
|
185
|
-
++removed;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
#ifdef RYU_DEBUG
|
|
189
|
-
printf("%u %d\n", vr, lastRemovedDigit);
|
|
190
|
-
printf("vr is trailing zeros=%s\n", vrIsTrailingZeros ? "true" : "false");
|
|
191
|
-
#endif
|
|
192
|
-
if (vrIsTrailingZeros && lastRemovedDigit == 5 && vr % 2 == 0) {
|
|
193
|
-
// Round even if the exact number is .....50..0.
|
|
194
|
-
lastRemovedDigit = 4;
|
|
195
|
-
}
|
|
196
|
-
// We need to take vr + 1 if vr is outside bounds or we need to round up.
|
|
197
|
-
output = vr + ((vr == vm && (!acceptBounds || !vmIsTrailingZeros)) || lastRemovedDigit >= 5);
|
|
198
|
-
} else {
|
|
199
|
-
// Specialized for the common case (~96.0%). Percentages below are relative to this.
|
|
200
|
-
// Loop iterations below (approximately):
|
|
201
|
-
// 0: 13.6%, 1: 70.7%, 2: 14.1%, 3: 1.39%, 4: 0.14%, 5+: 0.01%
|
|
202
|
-
while (vp / 10 > vm / 10) {
|
|
203
|
-
lastRemovedDigit = (uint8_t) (vr % 10);
|
|
204
|
-
vr /= 10;
|
|
205
|
-
vp /= 10;
|
|
206
|
-
vm /= 10;
|
|
207
|
-
++removed;
|
|
208
|
-
}
|
|
209
|
-
#ifdef RYU_DEBUG
|
|
210
|
-
printf("%u %d\n", vr, lastRemovedDigit);
|
|
211
|
-
printf("vr is trailing zeros=%s\n", vrIsTrailingZeros ? "true" : "false");
|
|
212
|
-
#endif
|
|
213
|
-
// We need to take vr + 1 if vr is outside bounds or we need to round up.
|
|
214
|
-
output = vr + (vr == vm || lastRemovedDigit >= 5);
|
|
215
|
-
}
|
|
216
|
-
const int32_t exp = e10 + removed;
|
|
217
|
-
|
|
218
|
-
#ifdef RYU_DEBUG
|
|
219
|
-
printf("V+=%u\nV =%u\nV-=%u\n", vp, vr, vm);
|
|
220
|
-
printf("O=%u\n", output);
|
|
221
|
-
printf("EXP=%d\n", exp);
|
|
222
|
-
#endif
|
|
223
|
-
|
|
224
|
-
floating_decimal_32 fd;
|
|
225
|
-
fd.exponent = exp;
|
|
226
|
-
fd.mantissa = output;
|
|
227
|
-
return fd;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
static inline int to_chars(const floating_decimal_32 v, const bool sign, char* const result) {
|
|
231
|
-
// Step 5: Print the decimal representation.
|
|
232
|
-
int index = 0;
|
|
233
|
-
if (sign) {
|
|
234
|
-
result[index++] = '-';
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
uint32_t output = v.mantissa;
|
|
238
|
-
const uint32_t olength = decimalLength9(output);
|
|
239
|
-
|
|
240
|
-
#ifdef RYU_DEBUG
|
|
241
|
-
printf("DIGITS=%u\n", v.mantissa);
|
|
242
|
-
printf("OLEN=%u\n", olength);
|
|
243
|
-
printf("EXP=%u\n", v.exponent + olength);
|
|
244
|
-
#endif
|
|
245
|
-
|
|
246
|
-
// Print the decimal digits.
|
|
247
|
-
// The following code is equivalent to:
|
|
248
|
-
// for (uint32_t i = 0; i < olength - 1; ++i) {
|
|
249
|
-
// const uint32_t c = output % 10; output /= 10;
|
|
250
|
-
// result[index + olength - i] = (char) ('0' + c);
|
|
251
|
-
// }
|
|
252
|
-
// result[index] = '0' + output % 10;
|
|
253
|
-
uint32_t i = 0;
|
|
254
|
-
while (output >= 10000) {
|
|
255
|
-
#ifdef __clang__ // https://bugs.llvm.org/show_bug.cgi?id=38217
|
|
256
|
-
const uint32_t c = output - 10000 * (output / 10000);
|
|
257
|
-
#else
|
|
258
|
-
const uint32_t c = output % 10000;
|
|
259
|
-
#endif
|
|
260
|
-
output /= 10000;
|
|
261
|
-
const uint32_t c0 = (c % 100) << 1;
|
|
262
|
-
const uint32_t c1 = (c / 100) << 1;
|
|
263
|
-
memcpy(result + index + olength - i - 1, DIGIT_TABLE + c0, 2);
|
|
264
|
-
memcpy(result + index + olength - i - 3, DIGIT_TABLE + c1, 2);
|
|
265
|
-
i += 4;
|
|
266
|
-
}
|
|
267
|
-
if (output >= 100) {
|
|
268
|
-
const uint32_t c = (output % 100) << 1;
|
|
269
|
-
output /= 100;
|
|
270
|
-
memcpy(result + index + olength - i - 1, DIGIT_TABLE + c, 2);
|
|
271
|
-
i += 2;
|
|
272
|
-
}
|
|
273
|
-
if (output >= 10) {
|
|
274
|
-
const uint32_t c = output << 1;
|
|
275
|
-
// We can't use memcpy here: the decimal dot goes between these two digits.
|
|
276
|
-
result[index + olength - i] = DIGIT_TABLE[c + 1];
|
|
277
|
-
result[index] = DIGIT_TABLE[c];
|
|
278
|
-
} else {
|
|
279
|
-
result[index] = (char) ('0' + output);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// Print decimal point if needed.
|
|
283
|
-
if (olength > 1) {
|
|
284
|
-
result[index + 1] = '.';
|
|
285
|
-
index += olength + 1;
|
|
286
|
-
} else {
|
|
287
|
-
++index;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// Print the exponent.
|
|
291
|
-
result[index++] = 'E';
|
|
292
|
-
int32_t exp = v.exponent + (int32_t) olength - 1;
|
|
293
|
-
if (exp < 0) {
|
|
294
|
-
result[index++] = '-';
|
|
295
|
-
exp = -exp;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
if (exp >= 10) {
|
|
299
|
-
memcpy(result + index, DIGIT_TABLE + 2 * exp, 2);
|
|
300
|
-
index += 2;
|
|
301
|
-
} else {
|
|
302
|
-
result[index++] = (char) ('0' + exp);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
return index;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
int f2s_buffered_n(float f, char* result) {
|
|
309
|
-
// Step 1: Decode the floating-point number, and unify normalized and subnormal cases.
|
|
310
|
-
const uint32_t bits = float_to_bits(f);
|
|
311
|
-
|
|
312
|
-
#ifdef RYU_DEBUG
|
|
313
|
-
printf("IN=");
|
|
314
|
-
for (int32_t bit = 31; bit >= 0; --bit) {
|
|
315
|
-
printf("%u", (bits >> bit) & 1);
|
|
316
|
-
}
|
|
317
|
-
printf("\n");
|
|
318
|
-
#endif
|
|
319
|
-
|
|
320
|
-
// Decode bits into sign, mantissa, and exponent.
|
|
321
|
-
const bool ieeeSign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0;
|
|
322
|
-
const uint32_t ieeeMantissa = bits & ((1u << FLOAT_MANTISSA_BITS) - 1);
|
|
323
|
-
const uint32_t ieeeExponent = (bits >> FLOAT_MANTISSA_BITS) & ((1u << FLOAT_EXPONENT_BITS) - 1);
|
|
324
|
-
|
|
325
|
-
// Case distinction; exit early for the easy cases.
|
|
326
|
-
if (ieeeExponent == ((1u << FLOAT_EXPONENT_BITS) - 1u) || (ieeeExponent == 0 && ieeeMantissa == 0)) {
|
|
327
|
-
return copy_special_str(result, ieeeSign, ieeeExponent, ieeeMantissa);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
const floating_decimal_32 v = f2d(ieeeMantissa, ieeeExponent);
|
|
331
|
-
return to_chars(v, ieeeSign, result);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
void f2s_buffered(float f, char* result) {
|
|
335
|
-
const int index = f2s_buffered_n(f, result);
|
|
336
|
-
|
|
337
|
-
// Terminate the string.
|
|
338
|
-
result[index] = '\0';
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
char* f2s(float f) {
|
|
342
|
-
char* const result = (char*) malloc(16);
|
|
343
|
-
f2s_buffered(f, result);
|
|
344
|
-
return result;
|
|
345
|
-
}
|
|
1
|
+
// Copyright 2018 Ulf Adams
|
|
2
|
+
//
|
|
3
|
+
// The contents of this file may be used under the terms of the Apache License,
|
|
4
|
+
// Version 2.0.
|
|
5
|
+
//
|
|
6
|
+
// (See accompanying file LICENSE-Apache or copy at
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0)
|
|
8
|
+
//
|
|
9
|
+
// Alternatively, the contents of this file may be used under the terms of
|
|
10
|
+
// the Boost Software License, Version 1.0.
|
|
11
|
+
// (See accompanying file LICENSE-Boost or copy at
|
|
12
|
+
// https://www.boost.org/LICENSE_1_0.txt)
|
|
13
|
+
//
|
|
14
|
+
// Unless required by applicable law or agreed to in writing, this software
|
|
15
|
+
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
16
|
+
// KIND, either express or implied.
|
|
17
|
+
|
|
18
|
+
// Runtime compiler options:
|
|
19
|
+
// -DRYU_DEBUG Generate verbose debugging output to stdout.
|
|
20
|
+
|
|
21
|
+
#include "ryu/ryu.h"
|
|
22
|
+
|
|
23
|
+
#include <assert.h>
|
|
24
|
+
#include <stdbool.h>
|
|
25
|
+
#include <stdint.h>
|
|
26
|
+
#include <stdlib.h>
|
|
27
|
+
#include <string.h>
|
|
28
|
+
#include <limits.h>
|
|
29
|
+
|
|
30
|
+
#ifdef RYU_DEBUG
|
|
31
|
+
#include <stdio.h>
|
|
32
|
+
#endif
|
|
33
|
+
|
|
34
|
+
#include "ryu/common.h"
|
|
35
|
+
#include "ryu/f2s_intrinsics.h"
|
|
36
|
+
#include "ryu/digit_table.h"
|
|
37
|
+
|
|
38
|
+
#define FLOAT_MANTISSA_BITS 23
|
|
39
|
+
#define FLOAT_EXPONENT_BITS 8
|
|
40
|
+
#define FLOAT_BIAS 127
|
|
41
|
+
|
|
42
|
+
// A floating decimal representing m * 10^e.
|
|
43
|
+
typedef struct floating_decimal_32 {
|
|
44
|
+
uint32_t mantissa;
|
|
45
|
+
// Decimal exponent's range is -45 to 38
|
|
46
|
+
// inclusive, and can fit in a short if needed.
|
|
47
|
+
int32_t exponent;
|
|
48
|
+
} floating_decimal_32;
|
|
49
|
+
|
|
50
|
+
static inline floating_decimal_32 f2d(const uint32_t ieeeMantissa, const uint32_t ieeeExponent) {
|
|
51
|
+
int32_t e2;
|
|
52
|
+
uint32_t m2;
|
|
53
|
+
if (ieeeExponent == 0) {
|
|
54
|
+
// We subtract 2 so that the bounds computation has 2 additional bits.
|
|
55
|
+
e2 = 1 - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2;
|
|
56
|
+
m2 = ieeeMantissa;
|
|
57
|
+
} else {
|
|
58
|
+
e2 = (int32_t) ieeeExponent - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2;
|
|
59
|
+
m2 = (1u << FLOAT_MANTISSA_BITS) | ieeeMantissa;
|
|
60
|
+
}
|
|
61
|
+
const bool even = (m2 & 1) == 0;
|
|
62
|
+
const bool acceptBounds = even;
|
|
63
|
+
|
|
64
|
+
#ifdef RYU_DEBUG
|
|
65
|
+
printf("-> %u * 2^%d\n", m2, e2 + 2);
|
|
66
|
+
#endif
|
|
67
|
+
|
|
68
|
+
// Step 2: Determine the interval of valid decimal representations.
|
|
69
|
+
const uint32_t mv = 4 * m2;
|
|
70
|
+
const uint32_t mp = 4 * m2 + 2;
|
|
71
|
+
// Implicit bool -> int conversion. True is 1, false is 0.
|
|
72
|
+
const uint32_t mmShift = ieeeMantissa != 0 || ieeeExponent <= 1;
|
|
73
|
+
const uint32_t mm = 4 * m2 - 1 - mmShift;
|
|
74
|
+
|
|
75
|
+
// Step 3: Convert to a decimal power base using 64-bit arithmetic.
|
|
76
|
+
uint32_t vr, vp, vm;
|
|
77
|
+
int32_t e10;
|
|
78
|
+
bool vmIsTrailingZeros = false;
|
|
79
|
+
bool vrIsTrailingZeros = false;
|
|
80
|
+
uint8_t lastRemovedDigit = 0;
|
|
81
|
+
if (e2 >= 0) {
|
|
82
|
+
const uint32_t q = log10Pow2(e2);
|
|
83
|
+
e10 = (int32_t) q;
|
|
84
|
+
const int32_t k = FLOAT_POW5_INV_BITCOUNT + pow5bits((int32_t) q) - 1;
|
|
85
|
+
const int32_t i = -e2 + (int32_t) q + k;
|
|
86
|
+
vr = mulPow5InvDivPow2(mv, q, i);
|
|
87
|
+
vp = mulPow5InvDivPow2(mp, q, i);
|
|
88
|
+
vm = mulPow5InvDivPow2(mm, q, i);
|
|
89
|
+
#ifdef RYU_DEBUG
|
|
90
|
+
printf("%u * 2^%d / 10^%u\n", mv, e2, q);
|
|
91
|
+
printf("V+=%u\nV =%u\nV-=%u\n", vp, vr, vm);
|
|
92
|
+
#endif
|
|
93
|
+
if (q != 0 && (vp - 1) / 10 <= vm / 10) {
|
|
94
|
+
// We need to know one removed digit even if we are not going to loop below. We could use
|
|
95
|
+
// q = X - 1 above, except that would require 33 bits for the result, and we've found that
|
|
96
|
+
// 32-bit arithmetic is faster even on 64-bit machines.
|
|
97
|
+
const int32_t l = FLOAT_POW5_INV_BITCOUNT + pow5bits((int32_t) (q - 1)) - 1;
|
|
98
|
+
lastRemovedDigit = (uint8_t) (mulPow5InvDivPow2(mv, q - 1, -e2 + (int32_t) q - 1 + l) % 10);
|
|
99
|
+
}
|
|
100
|
+
if (q <= 9) {
|
|
101
|
+
// The largest power of 5 that fits in 24 bits is 5^10, but q <= 9 seems to be safe as well.
|
|
102
|
+
// Only one of mp, mv, and mm can be a multiple of 5, if any.
|
|
103
|
+
if (mv % 5 == 0) {
|
|
104
|
+
vrIsTrailingZeros = multipleOfPowerOf5_32(mv, q);
|
|
105
|
+
} else if (acceptBounds) {
|
|
106
|
+
vmIsTrailingZeros = multipleOfPowerOf5_32(mm, q);
|
|
107
|
+
} else {
|
|
108
|
+
vp -= multipleOfPowerOf5_32(mp, q);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
const uint32_t q = log10Pow5(-e2);
|
|
113
|
+
e10 = (int32_t) q + e2;
|
|
114
|
+
const int32_t i = -e2 - (int32_t) q;
|
|
115
|
+
const int32_t k = pow5bits(i) - FLOAT_POW5_BITCOUNT;
|
|
116
|
+
int32_t j = (int32_t) q - k;
|
|
117
|
+
vr = mulPow5divPow2(mv, (uint32_t) i, j);
|
|
118
|
+
vp = mulPow5divPow2(mp, (uint32_t) i, j);
|
|
119
|
+
vm = mulPow5divPow2(mm, (uint32_t) i, j);
|
|
120
|
+
#ifdef RYU_DEBUG
|
|
121
|
+
printf("%u * 5^%d / 10^%u\n", mv, -e2, q);
|
|
122
|
+
printf("%u %d %d %d\n", q, i, k, j);
|
|
123
|
+
printf("V+=%u\nV =%u\nV-=%u\n", vp, vr, vm);
|
|
124
|
+
#endif
|
|
125
|
+
if (q != 0 && (vp - 1) / 10 <= vm / 10) {
|
|
126
|
+
j = (int32_t) q - 1 - (pow5bits(i + 1) - FLOAT_POW5_BITCOUNT);
|
|
127
|
+
lastRemovedDigit = (uint8_t) (mulPow5divPow2(mv, (uint32_t) (i + 1), j) % 10);
|
|
128
|
+
}
|
|
129
|
+
if (q <= 1) {
|
|
130
|
+
// {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q trailing 0 bits.
|
|
131
|
+
// mv = 4 * m2, so it always has at least two trailing 0 bits.
|
|
132
|
+
vrIsTrailingZeros = true;
|
|
133
|
+
if (acceptBounds) {
|
|
134
|
+
// mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff mmShift == 1.
|
|
135
|
+
vmIsTrailingZeros = mmShift == 1;
|
|
136
|
+
} else {
|
|
137
|
+
// mp = mv + 2, so it always has at least one trailing 0 bit.
|
|
138
|
+
--vp;
|
|
139
|
+
}
|
|
140
|
+
} else if (q < 31) { // TODO(ulfjack): Use a tighter bound here.
|
|
141
|
+
vrIsTrailingZeros = multipleOfPowerOf2_32(mv, q - 1);
|
|
142
|
+
#ifdef RYU_DEBUG
|
|
143
|
+
printf("vr is trailing zeros=%s\n", vrIsTrailingZeros ? "true" : "false");
|
|
144
|
+
#endif
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
#ifdef RYU_DEBUG
|
|
148
|
+
printf("e10=%d\n", e10);
|
|
149
|
+
printf("V+=%u\nV =%u\nV-=%u\n", vp, vr, vm);
|
|
150
|
+
printf("vm is trailing zeros=%s\n", vmIsTrailingZeros ? "true" : "false");
|
|
151
|
+
printf("vr is trailing zeros=%s\n", vrIsTrailingZeros ? "true" : "false");
|
|
152
|
+
#endif
|
|
153
|
+
|
|
154
|
+
// Step 4: Find the shortest decimal representation in the interval of valid representations.
|
|
155
|
+
int32_t removed = 0;
|
|
156
|
+
uint32_t output;
|
|
157
|
+
if (vmIsTrailingZeros || vrIsTrailingZeros) {
|
|
158
|
+
// General case, which happens rarely (~4.0%).
|
|
159
|
+
while (vp / 10 > vm / 10) {
|
|
160
|
+
#ifdef __clang__ // https://bugs.llvm.org/show_bug.cgi?id=23106
|
|
161
|
+
// The compiler does not realize that vm % 10 can be computed from vm / 10
|
|
162
|
+
// as vm - (vm / 10) * 10.
|
|
163
|
+
vmIsTrailingZeros &= vm - (vm / 10) * 10 == 0;
|
|
164
|
+
#else
|
|
165
|
+
vmIsTrailingZeros &= vm % 10 == 0;
|
|
166
|
+
#endif
|
|
167
|
+
vrIsTrailingZeros &= lastRemovedDigit == 0;
|
|
168
|
+
lastRemovedDigit = (uint8_t) (vr % 10);
|
|
169
|
+
vr /= 10;
|
|
170
|
+
vp /= 10;
|
|
171
|
+
vm /= 10;
|
|
172
|
+
++removed;
|
|
173
|
+
}
|
|
174
|
+
#ifdef RYU_DEBUG
|
|
175
|
+
printf("V+=%u\nV =%u\nV-=%u\n", vp, vr, vm);
|
|
176
|
+
printf("d-10=%s\n", vmIsTrailingZeros ? "true" : "false");
|
|
177
|
+
#endif
|
|
178
|
+
if (vmIsTrailingZeros) {
|
|
179
|
+
while (vm % 10 == 0) {
|
|
180
|
+
vrIsTrailingZeros &= lastRemovedDigit == 0;
|
|
181
|
+
lastRemovedDigit = (uint8_t) (vr % 10);
|
|
182
|
+
vr /= 10;
|
|
183
|
+
vp /= 10;
|
|
184
|
+
vm /= 10;
|
|
185
|
+
++removed;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
#ifdef RYU_DEBUG
|
|
189
|
+
printf("%u %d\n", vr, lastRemovedDigit);
|
|
190
|
+
printf("vr is trailing zeros=%s\n", vrIsTrailingZeros ? "true" : "false");
|
|
191
|
+
#endif
|
|
192
|
+
if (vrIsTrailingZeros && lastRemovedDigit == 5 && vr % 2 == 0) {
|
|
193
|
+
// Round even if the exact number is .....50..0.
|
|
194
|
+
lastRemovedDigit = 4;
|
|
195
|
+
}
|
|
196
|
+
// We need to take vr + 1 if vr is outside bounds or we need to round up.
|
|
197
|
+
output = vr + ((vr == vm && (!acceptBounds || !vmIsTrailingZeros)) || lastRemovedDigit >= 5);
|
|
198
|
+
} else {
|
|
199
|
+
// Specialized for the common case (~96.0%). Percentages below are relative to this.
|
|
200
|
+
// Loop iterations below (approximately):
|
|
201
|
+
// 0: 13.6%, 1: 70.7%, 2: 14.1%, 3: 1.39%, 4: 0.14%, 5+: 0.01%
|
|
202
|
+
while (vp / 10 > vm / 10) {
|
|
203
|
+
lastRemovedDigit = (uint8_t) (vr % 10);
|
|
204
|
+
vr /= 10;
|
|
205
|
+
vp /= 10;
|
|
206
|
+
vm /= 10;
|
|
207
|
+
++removed;
|
|
208
|
+
}
|
|
209
|
+
#ifdef RYU_DEBUG
|
|
210
|
+
printf("%u %d\n", vr, lastRemovedDigit);
|
|
211
|
+
printf("vr is trailing zeros=%s\n", vrIsTrailingZeros ? "true" : "false");
|
|
212
|
+
#endif
|
|
213
|
+
// We need to take vr + 1 if vr is outside bounds or we need to round up.
|
|
214
|
+
output = vr + (vr == vm || lastRemovedDigit >= 5);
|
|
215
|
+
}
|
|
216
|
+
const int32_t exp = e10 + removed;
|
|
217
|
+
|
|
218
|
+
#ifdef RYU_DEBUG
|
|
219
|
+
printf("V+=%u\nV =%u\nV-=%u\n", vp, vr, vm);
|
|
220
|
+
printf("O=%u\n", output);
|
|
221
|
+
printf("EXP=%d\n", exp);
|
|
222
|
+
#endif
|
|
223
|
+
|
|
224
|
+
floating_decimal_32 fd;
|
|
225
|
+
fd.exponent = exp;
|
|
226
|
+
fd.mantissa = output;
|
|
227
|
+
return fd;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
static inline int to_chars(const floating_decimal_32 v, const bool sign, char* const result) {
|
|
231
|
+
// Step 5: Print the decimal representation.
|
|
232
|
+
int index = 0;
|
|
233
|
+
if (sign) {
|
|
234
|
+
result[index++] = '-';
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
uint32_t output = v.mantissa;
|
|
238
|
+
const uint32_t olength = decimalLength9(output);
|
|
239
|
+
|
|
240
|
+
#ifdef RYU_DEBUG
|
|
241
|
+
printf("DIGITS=%u\n", v.mantissa);
|
|
242
|
+
printf("OLEN=%u\n", olength);
|
|
243
|
+
printf("EXP=%u\n", v.exponent + olength);
|
|
244
|
+
#endif
|
|
245
|
+
|
|
246
|
+
// Print the decimal digits.
|
|
247
|
+
// The following code is equivalent to:
|
|
248
|
+
// for (uint32_t i = 0; i < olength - 1; ++i) {
|
|
249
|
+
// const uint32_t c = output % 10; output /= 10;
|
|
250
|
+
// result[index + olength - i] = (char) ('0' + c);
|
|
251
|
+
// }
|
|
252
|
+
// result[index] = '0' + output % 10;
|
|
253
|
+
uint32_t i = 0;
|
|
254
|
+
while (output >= 10000) {
|
|
255
|
+
#ifdef __clang__ // https://bugs.llvm.org/show_bug.cgi?id=38217
|
|
256
|
+
const uint32_t c = output - 10000 * (output / 10000);
|
|
257
|
+
#else
|
|
258
|
+
const uint32_t c = output % 10000;
|
|
259
|
+
#endif
|
|
260
|
+
output /= 10000;
|
|
261
|
+
const uint32_t c0 = (c % 100) << 1;
|
|
262
|
+
const uint32_t c1 = (c / 100) << 1;
|
|
263
|
+
memcpy(result + index + olength - i - 1, DIGIT_TABLE + c0, 2);
|
|
264
|
+
memcpy(result + index + olength - i - 3, DIGIT_TABLE + c1, 2);
|
|
265
|
+
i += 4;
|
|
266
|
+
}
|
|
267
|
+
if (output >= 100) {
|
|
268
|
+
const uint32_t c = (output % 100) << 1;
|
|
269
|
+
output /= 100;
|
|
270
|
+
memcpy(result + index + olength - i - 1, DIGIT_TABLE + c, 2);
|
|
271
|
+
i += 2;
|
|
272
|
+
}
|
|
273
|
+
if (output >= 10) {
|
|
274
|
+
const uint32_t c = output << 1;
|
|
275
|
+
// We can't use memcpy here: the decimal dot goes between these two digits.
|
|
276
|
+
result[index + olength - i] = DIGIT_TABLE[c + 1];
|
|
277
|
+
result[index] = DIGIT_TABLE[c];
|
|
278
|
+
} else {
|
|
279
|
+
result[index] = (char) ('0' + output);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Print decimal point if needed.
|
|
283
|
+
if (olength > 1) {
|
|
284
|
+
result[index + 1] = '.';
|
|
285
|
+
index += olength + 1;
|
|
286
|
+
} else {
|
|
287
|
+
++index;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Print the exponent.
|
|
291
|
+
result[index++] = 'E';
|
|
292
|
+
int32_t exp = v.exponent + (int32_t) olength - 1;
|
|
293
|
+
if (exp < 0) {
|
|
294
|
+
result[index++] = '-';
|
|
295
|
+
exp = -exp;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (exp >= 10) {
|
|
299
|
+
memcpy(result + index, DIGIT_TABLE + 2 * exp, 2);
|
|
300
|
+
index += 2;
|
|
301
|
+
} else {
|
|
302
|
+
result[index++] = (char) ('0' + exp);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return index;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
int f2s_buffered_n(float f, char* result) {
|
|
309
|
+
// Step 1: Decode the floating-point number, and unify normalized and subnormal cases.
|
|
310
|
+
const uint32_t bits = float_to_bits(f);
|
|
311
|
+
|
|
312
|
+
#ifdef RYU_DEBUG
|
|
313
|
+
printf("IN=");
|
|
314
|
+
for (int32_t bit = 31; bit >= 0; --bit) {
|
|
315
|
+
printf("%u", (bits >> bit) & 1);
|
|
316
|
+
}
|
|
317
|
+
printf("\n");
|
|
318
|
+
#endif
|
|
319
|
+
|
|
320
|
+
// Decode bits into sign, mantissa, and exponent.
|
|
321
|
+
const bool ieeeSign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0;
|
|
322
|
+
const uint32_t ieeeMantissa = bits & ((1u << FLOAT_MANTISSA_BITS) - 1);
|
|
323
|
+
const uint32_t ieeeExponent = (bits >> FLOAT_MANTISSA_BITS) & ((1u << FLOAT_EXPONENT_BITS) - 1);
|
|
324
|
+
|
|
325
|
+
// Case distinction; exit early for the easy cases.
|
|
326
|
+
if (ieeeExponent == ((1u << FLOAT_EXPONENT_BITS) - 1u) || (ieeeExponent == 0 && ieeeMantissa == 0)) {
|
|
327
|
+
return copy_special_str(result, ieeeSign, ieeeExponent, ieeeMantissa);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const floating_decimal_32 v = f2d(ieeeMantissa, ieeeExponent);
|
|
331
|
+
return to_chars(v, ieeeSign, result);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
void f2s_buffered(float f, char* result) {
|
|
335
|
+
const int index = f2s_buffered_n(f, result);
|
|
336
|
+
|
|
337
|
+
// Terminate the string.
|
|
338
|
+
result[index] = '\0';
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
char* f2s(float f) {
|
|
342
|
+
char* const result = (char*) malloc(16);
|
|
343
|
+
f2s_buffered(f, result);
|
|
344
|
+
return result;
|
|
345
|
+
}
|