diff --git a/.github/actions/build-native-deps/action.yml b/.github/actions/build-native-deps/action.yml index 4a62d28..3e267f0 100644 --- a/.github/actions/build-native-deps/action.yml +++ b/.github/actions/build-native-deps/action.yml @@ -1,9 +1,9 @@ name: Build Native Dependencies -description: Build libsodium and zlib as needed +description: Build zlib as needed inputs: deps: - description: Space-separated list of deps to build (libsodium zlib) + description: Space-separated list of deps to build (zlib) required: true prefix: description: Install prefix @@ -27,8 +27,6 @@ inputs: description: CMake generator (Ninja, MinGW Makefiles, etc) required: false default: '' - libsodium_version: - required: true zlib_version: required: true @@ -60,16 +58,6 @@ runs: echo "prefix=$PREFIX" >> $GITHUB_OUTPUT mkdir -p "$PREFIX" - - name: Build libsodium - if: steps.cache.outputs.cache-hit != 'true' && contains(inputs.deps, 'libsodium') - shell: bash - run: | - git clone --depth 1 --branch ${{ inputs.libsodium_version }}-RELEASE https://github.com/jedisct1/libsodium.git /tmp/libsodium - cd /tmp/libsodium - ./configure CC=${{ inputs.cc }} --prefix=${{ steps.prep.outputs.prefix }} --disable-shared --enable-static - make -j$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4) - make install - - name: Build zlib if: steps.cache.outputs.cache-hit != 'true' && contains(inputs.deps, 'zlib') shell: bash diff --git a/.github/actions/build-project/action.yml b/.github/actions/build-project/action.yml index 3fb827b..5842220 100644 --- a/.github/actions/build-project/action.yml +++ b/.github/actions/build-project/action.yml @@ -142,14 +142,3 @@ runs: else ${{ inputs.strip }} --strip-unneeded build/${{ inputs.binary_name }} fi - - - name: Bundle Windows DLLs - if: runner.os == 'Windows' - shell: bash - run: | - MINGW_BIN=$(cygpath "$RUNNER_TEMP/msys64/clang64/bin") - cp "$MINGW_BIN/libssl-3-x64.dll" build/ - cp "$MINGW_BIN/libcrypto-3-x64.dll" build/ - cp "$MINGW_BIN/libsodium-26.dll" build/ - echo "Bundled DLLs:" - ls -la build/*.dll diff --git a/.github/versions.json b/.github/versions.json index cf40fe3..9ddd093 100644 --- a/.github/versions.json +++ b/.github/versions.json @@ -5,7 +5,6 @@ "node": "22" }, "dependencies": { - "libsodium": "1.0.20", "zlib": "1.3.1" }, "targets": { @@ -64,7 +63,7 @@ "rust_target": "x86_64-apple-darwin", "artifact_name": "ant-darwin-x64", "binary_name": "ant", - "deps": ["libsodium"], + "deps": [], "static_link": false, "cmake_generator": null, "extra_meson_args": null @@ -76,7 +75,7 @@ "rust_target": "aarch64-apple-darwin", "artifact_name": "ant-darwin-aarch64", "binary_name": "ant", - "deps": ["libsodium"], + "deps": [], "static_link": false, "cmake_generator": null, "extra_meson_args": null diff --git a/.github/workflows/build-platform.yml b/.github/workflows/build-platform.yml index ed57bbd..809b822 100644 --- a/.github/workflows/build-platform.yml +++ b/.github/workflows/build-platform.yml @@ -70,7 +70,7 @@ jobs: fi apt-get update apt-get install -y git ca-certificates gnupg wget software-properties-common curl \ - python3-pip ninja-build cmake pkg-config uuid-dev libsodium-dev jq + python3-pip ninja-build cmake pkg-config jq curl -fsSL https://deb.nodesource.com/setup_22.x | bash - apt-get install -y nodejs pip3 install meson tomli @@ -81,7 +81,7 @@ jobs: if: startsWith(inputs.platform, 'linux-musl') run: | apk add --no-cache git clang lld llvm meson ninja cmake pkgconf curl npm nodejs \ - musl-dev libsodium-dev libsodium-static \ + musl-dev \ util-linux-dev util-linux-static linux-headers libunwind-dev libunwind-static \ py3-tomli tar xz zstd jq bash git config --global --add safe.directory "$GITHUB_WORKSPACE" @@ -108,7 +108,7 @@ jobs: cache: true install: >- mingw-w64-clang-x86_64-toolchain mingw-w64-clang-x86_64-meson mingw-w64-clang-x86_64-ninja - mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-libsodium + mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-lld mingw-w64-clang-x86_64-nodejs git jq - name: Configure git line endings @@ -152,7 +152,6 @@ jobs: echo "deps=$DEPS_LIST" >> $GITHUB_OUTPUT # Dep versions - echo "libsodium_version=$(echo $DEPS | jq -r '.libsodium')" >> $GITHUB_OUTPUT echo "zlib_version=$(echo $DEPS | jq -r '.zlib')" >> $GITHUB_OUTPUT # === SETUP ZIG === @@ -191,7 +190,6 @@ jobs: ar: ${{ steps.llvm.outputs.ar }} ranlib: ${{ steps.llvm.outputs.ranlib }} cmake_generator: ${{ steps.config.outputs.cmake_generator }} - libsodium_version: ${{ steps.config.outputs.libsodium_version }} zlib_version: ${{ steps.config.outputs.zlib_version }} # === BUILD PROJECT === diff --git a/BUILDING.md b/BUILDING.md index 5712d82..ed20ae4 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -87,12 +87,7 @@ The following tools are required to build Ant regardless of platform: - **[Zig](https://ziglang.org/)** >= 0.15 (builds the package manager component) - **Git** -System libraries required: - -- **libsodium** -- **libuuid** (Linux/macOS) - -The remaining dependencies are vendored as Meson subprojects under `vendor/` +Dependencies are vendored as Meson subprojects under `vendor/` and are fetched automatically: - aklomp-base64 0.5.2 @@ -127,7 +122,7 @@ Installation via package manager: ```bash sudo apt-get install python3 python3-pip gcc-14 g++-14 ninja-build cmake \ - pkg-config uuid-dev libsodium-dev nodejs npm + pkg-config nodejs npm pip3 install meson ``` @@ -135,14 +130,14 @@ Installation via package manager: ```bash sudo dnf install python3 gcc gcc-c++ ninja-build cmake pkgconf \ - libuuid-devel libsodium-devel nodejs npm + nodejs npm pip3 install meson ``` - Alpine (musl): ```sh apk add clang lld llvm meson ninja cmake pkgconf nodejs npm \ - musl-dev libsodium-dev libsodium-static \ + musl-dev \ util-linux-dev util-linux-static linux-headers libunwind-dev libunwind-static ``` @@ -167,7 +162,7 @@ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh - Install remaining tools via [Homebrew](https://brew.sh): ```bash - brew install meson ninja llvm libsodium node + brew install meson ninja llvm node ``` - Rust and Zig: @@ -378,7 +373,6 @@ Ant on Windows is built using the MSYS2 MINGW64 toolchain. ```bash pacman -S mingw-w64-x86_64-toolchain mingw-w64-x86_64-meson \ mingw-w64-x86_64-ninja mingw-w64-x86_64-cmake \ - mingw-w64-x86_64-libsodium \ mingw-w64-x86_64-lld mingw-w64-x86_64-nodejs git ``` 3. Install Rust via [rustup](https://rustup.rs/) (select the @@ -407,16 +401,6 @@ To verify: ./build/ant.exe --version ``` -> [!WARNING] -> Windows builds require bundling the following DLLs alongside `ant.exe`: -> -> - `libssl-3-x64.dll` -> - `libcrypto-3-x64.dll` -> - `libsodium-26.dll` -> -> These are found in the MSYS2 MINGW64 bin directory -> (`/mingw64/bin/` or equivalent). - ## Meson build options Configure options are set via `meson setup` or `meson configure`: diff --git a/flake.lock b/flake.lock deleted file mode 100644 index 088a973..0000000 --- a/flake.lock +++ /dev/null @@ -1,61 +0,0 @@ -{ - "nodes": { - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1774273680, - "narHash": "sha256-a++tZ1RQsDb1I0NHrFwdGuRlR5TORvCEUksM459wKUA=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "fdc7b8f7b30fdbedec91b71ed82f36e1637483ed", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/flake.nix b/flake.nix deleted file mode 100644 index 5a6fcbb..0000000 --- a/flake.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ description = "ant dev shell"; - -inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - flake-utils.url = "github:numtide/flake-utils"; -}; - -outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachDefaultSystem (system: -let pkgs = nixpkgs.legacyPackages.${system}; in { - devShells.default = pkgs.mkShell { - packages = with pkgs; [ pkg-config libossp_uuid libsodium ]; - - shellHook = '' - export CC="ccache clang" - export MACOSX_DEPLOYMENT_TARGET="15.0" - ''; - }; -}); } diff --git a/include/modules/crypto.h b/include/modules/crypto.h index 60ef3f4..25fd7f0 100644 --- a/include/modules/crypto.h +++ b/include/modules/crypto.h @@ -1,10 +1,11 @@ #ifndef CRYPTO_H #define CRYPTO_H +#include #include "types.h" void init_crypto_module(void); -int ensure_crypto_init(void); +int crypto_fill_random(void *buf, size_t len); ant_value_t crypto_library(ant_t *js); diff --git a/maidfile.toml b/maidfile.toml index d74fe6d..26d015e 100644 --- a/maidfile.toml +++ b/maidfile.toml @@ -1,3 +1,6 @@ +[env] +CC = "ccache clang" + [tasks.build] path = "build" script = "meson compile" diff --git a/meson/deps/meson.build b/meson/deps/meson.build index cc3f53a..e3330d2 100644 --- a/meson/deps/meson.build +++ b/meson/deps/meson.build @@ -8,6 +8,15 @@ boringssl_opts.add_cmake_defines({ 'INSTALL_ENABLED': '0', }) +if host_machine.system() == 'darwin' + deployment_flag = '-mmacosx-version-min=15.0' + boringssl_opts.add_cmake_defines({ + 'CMAKE_EXE_LINKER_FLAGS': deployment_flag, + 'CMAKE_SHARED_LINKER_FLAGS': deployment_flag, + 'CMAKE_MODULE_LINKER_FLAGS': deployment_flag, + }) +endif + boringssl_warning_flag = cc.get_argument_syntax() == 'msvc' ? '/W0' : '-w' boringssl_opts.append_compile_args('c', boringssl_warning_flag) boringssl_opts.append_compile_args('cpp', boringssl_warning_flag) @@ -21,10 +30,7 @@ crypto_dep = boringssl_sub.dependency('crypto') meson.override_dependency('ssl', ssl_dep) meson.override_dependency('crypto', crypto_dep) -libsodium_dep = dependency('libsodium', required: true, static: is_static) - if host_machine.system() == 'windows' - uuid_dep = cc.find_library('rpcrt4', required: true) secur32_dep = cc.find_library('secur32', required: true) ntdll_dep = cc.find_library('ntdll', required: true) crypt32_dep = cc.find_library('crypt32', required: true) @@ -33,11 +39,9 @@ if host_machine.system() == 'windows' iphlpapi_dep = cc.find_library('iphlpapi', required: true) win_deps = [secur32_dep, ntdll_dep, crypt32_dep, userenv_dep, ws2_32_dep, iphlpapi_dep] elif host_machine.system() == 'darwin' - uuid_dep = dependency('uuid', required: true) security_dep = dependency('appleframeworks', modules: ['Security', 'CoreFoundation'], required: true) win_deps = [] else - uuid_dep = dependency('uuid', required: true, static: is_static) win_deps = [] endif @@ -218,10 +222,9 @@ pkg_zig_dir = src_root / 'src' / 'pkg' pkg_build_dir = meson.current_build_dir() ant_deps = [ - libffi_dep, uuid_dep, crprintf_dep, + libffi_dep, crprintf_dep, argtable3_dep, llhttp, pcre2_dep, libuv_dep, base64_dep, - argtable3_dep, tlsuv_dep, libsodium_dep, - yyjson_dep, minicoro_dep, uuidv7_dep, + yyjson_dep, minicoro_dep, uuidv7_dep, tlsuv_dep, uriparser_dep, utf8proc_dep, ssl_dep, crypto_dep, zlib_dep, brotli_common_dep, brotli_dec_dep, brotli_enc_dep, uthash_dep, lmdb_dep, wamr_dep, diff --git a/meson/meson.build b/meson/meson.build index fb46ed0..e80a6c6 100644 --- a/meson/meson.build +++ b/meson/meson.build @@ -24,6 +24,12 @@ add_project_arguments( language: 'c' ) +if host_machine.system() == 'darwin' + deployment_flag = '-mmacosx-version-min=15.0' + add_project_arguments(deployment_flag, language: ['c', 'cpp']) + add_project_link_arguments(deployment_flag, language: ['c', 'cpp']) +endif + if host_machine.system() == 'linux' add_project_arguments('-fno-pie', language: ['c', 'cpp']) add_project_link_arguments('-no-pie', language: ['c', 'cpp']) diff --git a/src/modules/crypto.c b/src/modules/crypto.c index 3426559..69ea55a 100644 --- a/src/modules/crypto.c +++ b/src/modules/crypto.c @@ -1,19 +1,14 @@ -#include #include #include +#include #include +#include #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wimplicit-int-conversion" #include #pragma GCC diagnostic pop -#ifdef _WIN32 -#include -#else -#include -#endif - #include "ant.h" #include "base64.h" #include "errors.h" @@ -37,6 +32,58 @@ typedef struct { bool finalized; } ant_hash_state_t; +int crypto_fill_random(void *buf, size_t len) { + if (len == 0) return 0; + if (len > (size_t)INT_MAX) return -1; + return RAND_bytes((uint8_t *)buf, (int)len) == 1 ? 0 : -1; +} + +static inline ant_value_t crypto_random_error(ant_t *js) { + return js_mkerr(js, "secure random generation failed"); +} + +static ant_value_t crypto_format_uuid_v4(ant_t *js, const uint8_t uuid[16]) { + static char lut[256][2]; + static bool lut_init = false; + char uuid_str[36]; + + if (!lut_init) { + static const char hex[] = "0123456789abcdef"; + for (int i = 0; i < 256; i++) { + lut[i][0] = hex[(unsigned)i >> 4]; + lut[i][1] = hex[(unsigned)i & 0x0f]; + } + lut_init = true; + } + + memcpy(uuid_str + 0, lut[uuid[0]], 2); + memcpy(uuid_str + 2, lut[uuid[1]], 2); + memcpy(uuid_str + 4, lut[uuid[2]], 2); + memcpy(uuid_str + 6, lut[uuid[3]], 2); + + uuid_str[8] = '-'; + memcpy(uuid_str + 9, lut[uuid[4]], 2); + memcpy(uuid_str + 11, lut[uuid[5]], 2); + + uuid_str[13] = '-'; + memcpy(uuid_str + 14, lut[uuid[6]], 2); + memcpy(uuid_str + 16, lut[uuid[7]], 2); + + uuid_str[18] = '-'; + memcpy(uuid_str + 19, lut[uuid[8]], 2); + memcpy(uuid_str + 21, lut[uuid[9]], 2); + + uuid_str[23] = '-'; + memcpy(uuid_str + 24, lut[uuid[10]], 2); + memcpy(uuid_str + 26, lut[uuid[11]], 2); + memcpy(uuid_str + 28, lut[uuid[12]], 2); + memcpy(uuid_str + 30, lut[uuid[13]], 2); + memcpy(uuid_str + 32, lut[uuid[14]], 2); + memcpy(uuid_str + 34, lut[uuid[15]], 2); + + return js_mkstr(js, uuid_str, sizeof(uuid_str)); +} + static ant_value_t crypto_make_buffer(ant_t *js, const uint8_t *data, size_t len) { ArrayBufferData *buffer = create_array_buffer_data(len); if (!buffer) return js_mkerr(js, "Failed to allocate Buffer"); @@ -230,16 +277,6 @@ static ant_value_t crypto_digest_result( return crypto_make_buffer(js, digest, digest_len); } -int ensure_crypto_init(void) { - static int crypto_initialized = 0; - - if (!crypto_initialized) { - if (sodium_init() < 0) return -1; - crypto_initialized = 1; - } - return 0; -} - int uuidv7_new(uint8_t *uuid_out) { static uint8_t uuid_prev[16] = {0}; static uint8_t rand_bytes[256] = {0}; @@ -250,7 +287,7 @@ int uuidv7_new(uint8_t *uuid_out) { uint64_t unix_ts_ms = (uint64_t)tp.tv_sec * 1000 + tp.tv_nsec / 1000000; if (n_rand_consumed > sizeof(rand_bytes) - 10) { - randombytes_buf(rand_bytes, sizeof(rand_bytes)); + if (crypto_fill_random(rand_bytes, sizeof(rand_bytes)) < 0) return -1; n_rand_consumed = 0; } @@ -263,11 +300,8 @@ int uuidv7_new(uint8_t *uuid_out) { // crypto.random() static ant_value_t js_crypto_random(ant_t *js, ant_value_t *args, int nargs) { - if (ensure_crypto_init() < 0) { - return js_mkerr(js, "libsodium initialization failed"); - } - - unsigned int value = randombytes_random(); + unsigned int value = 0; + if (crypto_fill_random(&value, sizeof(value)) < 0) return crypto_random_error(js); return js_mknum((double)value); } @@ -276,13 +310,8 @@ static ant_value_t js_crypto_random_bytes(ant_t *js, ant_value_t *args, int narg if (nargs < 1) { return js_mkerr(js, "randomBytes requires a length argument"); } - - if (ensure_crypto_init() < 0) { - return js_mkerr(js, "libsodium initialization failed"); - } - + int length = (int)js_getnum(args[0]); - if (length <= 0 || length > 65536) { return js_mkerr(js, "invalid length"); } @@ -292,7 +321,11 @@ static ant_value_t js_crypto_random_bytes(ant_t *js, ant_value_t *args, int narg return js_mkerr(js, "memory allocation failed"); } - randombytes_buf(random_bytes, length); + if (crypto_fill_random(random_bytes, (size_t)length) < 0) { + free(random_bytes); + return crypto_random_error(js); + } + ant_value_t array = crypto_make_buffer(js, random_bytes, (size_t)length); free(random_bytes); @@ -301,45 +334,24 @@ static ant_value_t js_crypto_random_bytes(ant_t *js, ant_value_t *args, int narg // crypto.randomUUID() static ant_value_t js_crypto_random_uuid(ant_t *js, ant_value_t *args, int nargs) { - if (ensure_crypto_init() < 0) { - return js_mkerr(js, "libsodium initialization failed"); - } - - char uuid_str[37]; - -#ifdef _WIN32 - UUID uuid; - UuidCreate(&uuid); - snprintf(uuid_str, sizeof(uuid_str), - "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - uuid.Data1, uuid.Data2, uuid.Data3, - uuid.Data4[0], uuid.Data4[1], uuid.Data4[2], uuid.Data4[3], - uuid.Data4[4], uuid.Data4[5], uuid.Data4[6], uuid.Data4[7]); -#else - uuid_t uuid; - uuid_generate_random(uuid); - uuid_unparse_lower(uuid, uuid_str); -#endif - - return js_mkstr(js, uuid_str, strlen(uuid_str)); + uint8_t uuid[16]; + if (crypto_fill_random(uuid, sizeof(uuid)) < 0) return crypto_random_error(js); + + uuid[6] = (uint8_t)((uuid[6] & 0x0f) | 0x40); + uuid[8] = (uint8_t)((uuid[8] & 0x3f) | 0x80); + + return crypto_format_uuid_v4(js, uuid); } // crypto.randomUUIDv7() static ant_value_t js_crypto_random_uuidv7(ant_t *js, ant_value_t *args, int nargs) { - if (ensure_crypto_init() < 0) { - return js_mkerr(js, "libsodium initialization failed"); - } - uint8_t uuid[16]; char uuid_str[37]; int result = uuidv7_new(uuid); - if (result < 0) { - return js_mkerr(js, "UUIDv7 generation failed"); - } + if (result < 0) return js_mkerr(js, "UUIDv7 generation failed"); uuidv7_to_string(uuid, uuid_str); - return js_mkstr(js, uuid_str, strlen(uuid_str)); } @@ -348,11 +360,7 @@ static ant_value_t js_crypto_get_random_values(ant_t *js, ant_value_t *args, int if (nargs < 1) { return js_mkerr(js, "getRandomValues requires a TypedArray argument"); } - - if (ensure_crypto_init() < 0) { - return js_mkerr(js, "libsodium initialization failed"); - } - + TypedArrayData *ta_data = buffer_get_typedarray_data(args[0]); if (!ta_data || !ta_data->buffer) { return js_mkerr(js, "argument must be a TypedArray"); @@ -363,14 +371,13 @@ static ant_value_t js_crypto_get_random_values(ant_t *js, ant_value_t *args, int } uint8_t *ptr = ta_data->buffer->data + ta_data->byte_offset; - randombytes_buf(ptr, ta_data->byte_length); + if (crypto_fill_random(ptr, ta_data->byte_length) < 0) return crypto_random_error(js); return args[0]; } static ant_value_t js_crypto_random_fill_sync(ant_t *js, ant_value_t *args, int nargs) { if (nargs < 1) return js_mkerr(js, "randomFillSync requires a target"); - if (ensure_crypto_init() < 0) return js_mkerr(js, "libsodium initialization failed"); uint8_t *bytes = NULL; size_t len = 0; @@ -396,7 +403,7 @@ static ant_value_t js_crypto_random_fill_sync(ant_t *js, ant_value_t *args, int return js_mkerr(js, "randomFillSync range is out of bounds"); } - randombytes_buf(bytes + offset, size); + if (crypto_fill_random(bytes + offset, size) < 0) return crypto_random_error(js); return args[0]; } diff --git a/src/modules/math.c b/src/modules/math.c index c36544e..139c476 100644 --- a/src/modules/math.c +++ b/src/modules/math.c @@ -1,4 +1,3 @@ -#include #include #include "ant.h" @@ -21,68 +20,68 @@ enum { static const double math_random_scale = 1.0 / (double)(UINT64_C(1) << MATH_RANDOM_MANTISSA_BITS); -static ant_value_t builtin_Math_abs(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_abs(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(fabs(x)); } -static ant_value_t builtin_Math_acos(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_acos(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(acos(x)); } -static ant_value_t builtin_Math_acosh(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_acosh(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(acosh(x)); } -static ant_value_t builtin_Math_asin(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_asin(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(asin(x)); } -static ant_value_t builtin_Math_asinh(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_asinh(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(asinh(x)); } -static ant_value_t builtin_Math_atan(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_atan(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(atan(x)); } -static ant_value_t builtin_Math_atanh(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_atanh(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(atanh(x)); } -static ant_value_t builtin_Math_atan2(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_atan2(ant_params_t) { double y = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); double x = (nargs < 2) ? JS_NAN : js_to_number(js, args[1]); if (isnan(y) || isnan(x)) return tov(JS_NAN); return tov(atan2(y, x)); } -static ant_value_t builtin_Math_cbrt(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_cbrt(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(cbrt(x)); } -static ant_value_t builtin_Math_ceil(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_ceil(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(ceil(x)); } -static ant_value_t builtin_Math_clz32(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_clz32(ant_params_t) { if (nargs < 1) return tov(32); uint32_t n = js_to_uint32(js_to_number(js, args[0])); if (n == 0) return tov(32); @@ -93,43 +92,43 @@ static ant_value_t builtin_Math_clz32(ant_t *js, ant_value_t *args, int nargs) { return tov((double)lz); } -static ant_value_t builtin_Math_cos(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_cos(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(cos(x)); } -static ant_value_t builtin_Math_cosh(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_cosh(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(cosh(x)); } -static ant_value_t builtin_Math_exp(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_exp(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(exp(x)); } -static ant_value_t builtin_Math_expm1(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_expm1(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(expm1(x)); } -static ant_value_t builtin_Math_floor(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_floor(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(floor(x)); } -static ant_value_t builtin_Math_fround(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_fround(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov((double)(float)x); } -static ant_value_t builtin_Math_hypot(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_hypot(ant_params_t) { if (nargs == 0) return tov(0.0); double acc = 0.0; bool saw_nan = false; @@ -143,38 +142,38 @@ static ant_value_t builtin_Math_hypot(ant_t *js, ant_value_t *args, int nargs) { return tov(acc); } -static ant_value_t builtin_Math_imul(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_imul(ant_params_t) { if (nargs < 2) return tov(0); int32_t a = js_to_int32(js_to_number(js, args[0])); int32_t b = js_to_int32(js_to_number(js, args[1])); return tov((double)((int32_t)((uint32_t)a * (uint32_t)b))); } -static ant_value_t builtin_Math_log(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_log(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(log(x)); } -static ant_value_t builtin_Math_log1p(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_log1p(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(log1p(x)); } -static ant_value_t builtin_Math_log10(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_log10(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(log10(x)); } -static ant_value_t builtin_Math_log2(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_log2(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(log2(x)); } -static ant_value_t builtin_Math_max(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_max(ant_params_t) { if (nargs == 0) return tov(JS_NEG_INF); double max_val = js_to_number(js, args[0]); if (isnan(max_val)) return tov(JS_NAN); @@ -182,14 +181,12 @@ static ant_value_t builtin_Math_max(ant_t *js, ant_value_t *args, int nargs) { double v = js_to_number(js, args[i]); if (isnan(v)) return tov(JS_NAN); if (v > max_val) { max_val = v; continue; } - if (v == 0.0 && max_val == 0.0 && !signbit(v) && signbit(max_val)) { - max_val = v; - } + if (v == 0.0 && max_val == 0.0 && !signbit(v) && signbit(max_val)) max_val = v; } return tov(max_val); } -static ant_value_t builtin_Math_min(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_min(ant_params_t) { if (nargs == 0) return tov(JS_INF); double min_val = js_to_number(js, args[0]); if (isnan(min_val)) return tov(JS_NAN); @@ -209,32 +206,31 @@ static ant_value_t builtin_Math_min(ant_t *js, ant_value_t *args, int nargs) { return tov(min_val); } -static ant_value_t builtin_Math_pow(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_pow(ant_params_t) { double base = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); double exp = (nargs < 2) ? JS_NAN : js_to_number(js, args[1]); if (isnan(base) || isnan(exp)) return tov(JS_NAN); return tov(pow(base, exp)); } -static ant_value_t builtin_Math_random(ant_t *js, ant_value_t *args, int nargs) { - if (ensure_crypto_init() < 0) { - return js_mkerr(js, "libsodium initialization failed"); +static ant_value_t builtin_Math_random(ant_params_t) { + uint64_t r = 0; + if (crypto_fill_random(&r, sizeof(r)) < 0) { + return js_mkerr(js, "secure random generation failed"); } - - uint64_t r = 0; randombytes_buf(&r, sizeof(r)); - uint64_t fraction = r >> MATH_RANDOM_DISCARD_BITS; + uint64_t fraction = r >> MATH_RANDOM_DISCARD_BITS; return tov((double)fraction * math_random_scale); } -static ant_value_t builtin_Math_round(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_round(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x) || isinf(x) || x == 0.0) return tov(x); if (x < 0.0 && x >= -0.5) return tov(-0.0); return tov(floor(x + 0.5)); } -static ant_value_t builtin_Math_sign(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_sign(ant_params_t) { double v = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(v)) return tov(JS_NAN); if (v > 0) return tov(1.0); @@ -242,37 +238,37 @@ static ant_value_t builtin_Math_sign(ant_t *js, ant_value_t *args, int nargs) { return tov(v); } -static ant_value_t builtin_Math_sin(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_sin(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(sin(x)); } -static ant_value_t builtin_Math_sinh(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_sinh(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(sinh(x)); } -static ant_value_t builtin_Math_sqrt(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_sqrt(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(sqrt(x)); } -static ant_value_t builtin_Math_tan(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_tan(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(tan(x)); } -static ant_value_t builtin_Math_tanh(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_tanh(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(tanh(x)); } -static ant_value_t builtin_Math_trunc(ant_t *js, ant_value_t *args, int nargs) { +static ant_value_t builtin_Math_trunc(ant_params_t) { double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); if (isnan(x)) return tov(JS_NAN); return tov(trunc(x));