From aa445dd61eb89bcfdbdbfc85aa95f507c2f0a9b3 Mon Sep 17 00:00:00 2001 From: Luc Blaeser <112870813+luc-blaeser@users.noreply.github.com> Date: Tue, 8 Oct 2024 14:44:56 +0200 Subject: [PATCH] Use Custom Rust Targets for Shared Wasm Libraries (#4683) * Patch Rust for shared Wasm libraries * Get rid of `musl` * Further simplify Wasm linking * Update benchmark results * No longer need `wasm-ld` patch * Update test result * Add distinction for Linux Ocaml build * Revert "No longer need `wasm-ld` patch" This reverts commit 3d0f34ed63dfb0ca1955ee46c67cb91b0d85ce97. * Revert "Update test result" This reverts commit 8fc5c082a61ae033cc393c75748c7d52175f0359. * Use patched wasm-ld during Rust build * Table offset must be at least 1 for Rust RTS * Adjust linker test result * Use bulk memory operations * Do not need `wasm-lld` patch with shared targets * Adjust expected test result * Adjust nix build script * Fix nix build script --- .github/workflows/niv-updater-rare.yml | 2 +- .github/workflows/niv-updater-trial.yml | 2 +- .github/workflows/niv-updater.yml | 2 +- default.nix | 70 +------ nix/default.nix | 4 +- nix/sources.json | 13 -- rts/Makefile | 188 +++--------------- rts/motoko-rts/config.toml | 8 + rts/motoko-rts/src/allocator.rs | 7 - rts/motoko-rts/src/libc_declarations.rs | 19 -- rts/motoko-rts/wasm32-unknown-shared.json | 57 ++++++ rts/motoko-rts/wasm64-unknown-shared.json | 59 ++++++ rts/stubs.c | 18 -- src/codegen/compile_classical.ml | 47 +++-- src/codegen/compile_enhanced.ml | 47 +++-- src/linking/linkModule.ml | 8 +- test/bench/ok/bignum.drun-run.ok | 4 +- test/bench/ok/candid-subtype-cost.drun-run.ok | 2 +- test/bench/ok/heap-32.drun-run.ok | 4 +- test/bench/ok/heap-64.drun-run.ok | 4 +- test/ld/Makefile | 2 +- test/ld/ok/fun-ptr.linked.wat.ok | 11 +- test/ld/ok/representative.linked.wat.ok | 2 +- 23 files changed, 220 insertions(+), 360 deletions(-) create mode 100644 rts/motoko-rts/wasm32-unknown-shared.json create mode 100644 rts/motoko-rts/wasm64-unknown-shared.json delete mode 100644 rts/stubs.c diff --git a/.github/workflows/niv-updater-rare.yml b/.github/workflows/niv-updater-rare.yml index e41c58e1d3a..b0d178e0a11 100644 --- a/.github/workflows/niv-updater-rare.yml +++ b/.github/workflows/niv-updater-rare.yml @@ -23,7 +23,7 @@ jobs: uses: knl/niv-updater-action@v13 with: # might be too noisy - whitelist: 'ic-ref,musl-wasi,ic-wasm' + whitelist: 'ic-ref,ic-wasm' labels: | automerge-squash keep_updating: true diff --git a/.github/workflows/niv-updater-trial.yml b/.github/workflows/niv-updater-trial.yml index da0d9cf7e0f..1ae248ff2f2 100644 --- a/.github/workflows/niv-updater-trial.yml +++ b/.github/workflows/niv-updater-trial.yml @@ -28,7 +28,7 @@ jobs: - name: niv-updater-action uses: knl/niv-updater-action@v13 with: - whitelist: 'nixpkgs,musl-wasi,ic' + whitelist: 'nixpkgs,ic' labels: | autoclose keep_updating: true diff --git a/.github/workflows/niv-updater.yml b/.github/workflows/niv-updater.yml index c05915b764d..aa12ac38916 100644 --- a/.github/workflows/niv-updater.yml +++ b/.github/workflows/niv-updater.yml @@ -23,7 +23,7 @@ jobs: uses: knl/niv-updater-action@v13 with: # might be too noisy - blacklist: 'nixpkgs,ic-ref,musl-wasi,ic' + blacklist: 'nixpkgs,ic-ref,ic' labels: | automerge-squash keep_updating: true diff --git a/default.nix b/default.nix index 9b5bba68d5b..4fa4eb41177 100644 --- a/default.nix +++ b/default.nix @@ -23,63 +23,10 @@ let ic-ref-run = let haskellPackages = nixpkgs.haskellPackages.override { overrides = import nix/haskell-packages.nix nixpkgs subpath; }; in -let llvm_sources = nixpkgs.fetchFromGitHub { - owner = "llvm"; - repo = "llvm-project"; - rev = "llvmorg-18.1.8"; - sha256 = "sha256-iiZKMRo/WxJaBXct9GdAcAT3cz9d9pnAcO1mmR6oPNE="; - }; in -let patched-wasm-ld = stdenv.mkDerivation { - name = "wasm-ld"; - src = llvm_sources; - nativeBuildInputs = with nixpkgs; [ cmake ninja ]; - buildInputs = with nixpkgs; [ llvmPackages_18.libllvm libxml2 ]; - - patchPhase = '' - patch lld/wasm/Relocations.cpp << EOF -@@ -104,9 +104,15 @@ void scanRelocations(InputChunk *chunk) { - case R_WASM_TABLE_INDEX_SLEB64: - case R_WASM_TABLE_INDEX_REL_SLEB: - case R_WASM_TABLE_INDEX_REL_SLEB64: -- if (requiresGOTAccess(sym)) -- break; -+ if (!sym->isDefined()) { -+ error(toString(file) + ": relocation " + relocTypeToString(reloc.Type) + -+ " cannot be used against an undefined symbol \`" + toString(*sym) + -+ "\`"); -+ } - out.elemSec->addEntry(cast(sym)); -+ if (requiresGOTAccess(sym)) { -+ addGOTEntry(sym); -+ } - break; - case R_WASM_GLOBAL_INDEX_LEB: - case R_WASM_GLOBAL_INDEX_I32: -EOF - cd lld - ''; - - outputs = [ "out" ]; - }; in -# Selectively build llvm binary tools. -# Exclude wasm-ld, as this is patched separately. -let llvm_bintools = stdenv.mkDerivation { - name = "llvm_bintools"; - src = llvm_sources; - nativeBuildInputs = with nixpkgs; [ cmake ninja python3 ]; - buildInputs = with nixpkgs; [ llvmPackages_18.libllvm libxml2 ]; - - preConfigure = '' - cd llvm - ''; - - outputs = [ "out" ]; - }; in let rtsBuildInputs = with nixpkgs; [ llvmPackages_18.clang - llvm_bintools - patched-wasm-ld + llvmPackages_18.bintools rustc-nightly cargo-nightly wasmtime @@ -193,15 +140,6 @@ let ocaml_exe = name: bin: rts: $out/bin/* --help >/dev/null ''; }; - - musl-wasi-sysroot = stdenv.mkDerivation { - name = "musl-wasi-sysroot"; - src = nixpkgs.sources.musl-wasi; - phases = [ "unpackPhase" "installPhase" ]; - installPhase = '' - make SYSROOT="$out" include_dirs - ''; - }; in rec { @@ -295,8 +233,6 @@ rec { ${llvmEnv} export TOMMATHSRC=${nixpkgs.sources.libtommath} - export MUSLSRC=${nixpkgs.sources.musl-wasi}/libc-top-half/musl - export MUSL_WASI_SYSROOT=${musl-wasi-sysroot} ''; doCheck = true; @@ -383,7 +319,7 @@ rec { # extra deps for test/ld ldTestDeps = - with nixpkgs; [ patched-wasm-ld llvmPackages_18.clang ]; + with nixpkgs; [ llvmPackages_18.lld llvmPackages_18.clang ]; testDerivation = args: stdenv.mkDerivation (testDerivationArgs // args); @@ -906,8 +842,6 @@ EOF ''; ESM=nixpkgs.sources.esm; TOMMATHSRC = nixpkgs.sources.libtommath; - MUSLSRC = "${nixpkgs.sources.musl-wasi}/libc-top-half/musl"; - MUSL_WASI_SYSROOT = musl-wasi-sysroot; LOCALE_ARCHIVE = nixpkgs.lib.optionalString stdenv.isLinux "${nixpkgs.glibcLocales}/lib/locale/locale-archive"; MOTOKO_BASE = base-src; CANDID_TESTS = "${nixpkgs.sources.candid}/test"; diff --git a/nix/default.nix b/nix/default.nix index 7ccabd1fda2..632b18ee3ed 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -78,7 +78,7 @@ let }; }; - # No testing of atdgen, as it pulls in python stuff, tricky on musl + # No testing of atdgen, as it pulls in python stuff atdgen = super.ocamlPackages.atdgen.overrideAttrs { doCheck = false; }; }; } @@ -95,9 +95,7 @@ let in rec { rustc-nightly = rust-channel.rust.override { targets = [ - "wasm32-unknown-emscripten" "wasm32-wasi" - "i686-unknown-linux-gnu" ]; extensions = ["rust-src"]; }; diff --git a/nix/sources.json b/nix/sources.json index 8cd87f7c5cf..7966882127d 100644 --- a/nix/sources.json +++ b/nix/sources.json @@ -94,19 +94,6 @@ "url": "https://github.com/kritzcreek/motoko-matchers/archive/cb838c192df3328ff9ae172e2dc7338cf55e74bf.tar.gz", "url_template": "https://github.com///archive/.tar.gz" }, - "musl-wasi": { - "branch": "main", - "builtin": false, - "description": "WASI libc implementation for WebAssembly", - "homepage": "https://wasi.dev", - "owner": "WebAssembly", - "repo": "wasi-libc", - "rev": "c5264e2bbe532994d06b039005f2af91bedcc1a6", - "sha256": "1skw2jqzaidr2zbzbjw32b36xvqniwf4if8cr4kbpp8vjvh7j2lr", - "type": "tarball", - "url": "https://github.com/WebAssembly/wasi-libc/archive/c5264e2bbe532994d06b039005f2af91bedcc1a6.tar.gz", - "url_template": "https://github.com///archive/.tar.gz" - }, "nixpkgs": { "branch": "release-24.05", "description": "Nix Packages collection & NixOS", diff --git a/rts/Makefile b/rts/Makefile index fcd5e75aea9..f43531d2f79 100644 --- a/rts/Makefile +++ b/rts/Makefile @@ -23,15 +23,7 @@ TOMMATHFILES = \ s_mp_mul_digs_fast s_mp_mul_digs mp_init_multi mp_clear_multi mp_mul_2 mp_div_2 mp_div_3 mp_lshd mp_incr \ mp_decr mp_add_d mp_sub_d -MUSLFILES_32 = \ - pow pow_data sin cos tan asin acos atan atan2 exp exp_data log log_data fmod \ - floor scalbn frexp strlen strnlen memcpy memset memchr memcmp memmove \ - __math_oflow __math_uflow __math_xflow __math_divzero __math_invalid \ - __rem_pio2 __rem_pio2_large __sin __cos __tan - TOMMATHSRC ?= $(CURDIR)/../../libtommath -MUSLSRC ?= $(CURDIR)/../../wasi-libc/libc-top-half/musl -MUSL_WASI_SYSROOT ?= $(MUSLSRC)/../../sysroot # # Various libtommath flags, in particular telling it to use our own memory @@ -58,48 +50,6 @@ TOMMATH_FLAGS_64 = $(TOMMATH_FLAGS_COMMON) \ # Note: the above __STDC_IEC_559__ define is somewhat of a misnomer # as only IEEE 754 features are used. -# -# Various musl flags, in particular telling it to not have long doubles -# and exclude , which pulls in too many dependencies -# -# Note: we use a bit of magic to get rid of invocations to __fwritex (and similar) -# - the headers contain a declaration, we rename it to (__fwritex ## __COUNTER__) -# - similarly the invocation becomes __fwritex_2(...) which we inline immediately -# Be aware that upon bumps of the musl sources the number of occurrences may jump a bit -# and will need tweaks/additions below. -# Similarly we define include guards (to suppress certain headers), but those should be -# pretty stable. -# TODO: run `wasm2wat --enable-memory64 mo-rts-eop.wasm | grep -F '(import' | grep __fwritex_` expecting empty. -# -# See also https://stackoverflow.com/questions/1597007/creating-c-macro-with-and-line-token-concatenation-with-positioning-macr - -MUSL_FLAGS_32 = \ - -isystem $(MUSLSRC)/arch/wasm32 \ - -isystem $(MUSLSRC)/src/include \ - -isystem $(MUSLSRC)/src/internal \ - -isystem $(MUSLSRC)/include \ - -isystem $(MUSL_WASI_SYSROOT)/include \ - -I $(MUSLSRC)/../headers/private \ - -I $(MUSLSRC)/src/include \ - -I $(MUSLSRC)/include \ - -I musl \ - -D_ERRNO_H -DEOVERFLOW=75 -DEINVAL=22 \ - -Derrno='(*({ static int bla = 0; &bla; }))' \ - -DNL_ARGMAX=9 \ - -D'TOKENPASTE0(x, y)=x \#\# y' \ - -D'TOKENPASTE(x, y)=TOKENPASTE0(x, y)' \ - -D'__fwritex=TOKENPASTE(__fwritex_,__COUNTER__)' \ - -D'__fwritex_2(s, l, f)=(f->write((f), (s), (l)))' \ - -D'__towrite=TOKENPASTE(__towrite_,__COUNTER__)' \ - -D'__towrite_3(f)=(0)' \ - -D__wasilibc_printscan_no_long_double \ - -D__wasilibc_printscan_full_support_option='""' \ - -D__wasi__ \ - -D__NEED_va_list \ - -D__NEED_off_t \ - -D__NEED_locale_t \ - -Dsqrt=__builtin_sqrt \ - -Dfabs=__builtin_fabs # # clang flags # @@ -114,7 +64,7 @@ CLANG_FLAGS_COMMON = \ -resource-dir=$(wildcard $(WASM_CLANG_LIB)/lib/clang/*) CLANG_FLAGS_32 = $(CLANG_FLAGS_COMMON) \ - --target=wasm32-emscripten + --target=wasm32 CLANG_FLAGS_64 = $(CLANG_FLAGS_COMMON) \ --target=wasm64 @@ -136,30 +86,11 @@ _build/wasm64: _build/wasm32: mkdir -p $@ -# -# Common configuration -# - -# Arguments obtained by Emscripten 3.1.64: -# `emcc -c --target=wasm64-unknown-emscripten -fpic --verbose` -# while skipping unneeded arguments. -RTS_LL_64=$(CLANG) -cc1 -triple wasm64-unknown-emscripten -emit-obj \ - -mrelocation-model pic -pic-level 1 -mframe-pointer=none \ - -ffp-contract=on -fno-rounding-math -mconstructor-aliases \ - -target-feature +mutable-globals -fvisibility=hidden \ - -Werror=implicit-function-declaration \ - -iwithsysroot/include/fakesdl -iwithsysroot/include/compat \ - -mllvm -combiner-global-alias-analysis=false \ - -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr \ - -Wno-override-module -RTS_LL_64_DEBUG=$(RTS_LL_64) -RTS_LL_64_RELEASE=$(RTS_LL_64) -Oz - # -# Let make automatically search these directories (tommath and musl) for .c files +# Let make automatically search the tommath directory for .c files # -vpath %.c $(MUSLSRC)/src/math $(MUSLSRC)/src/stdio $(MUSLSRC)/src/string $(MUSLSRC)/src/ctype $(TOMMATHSRC) +vpath %.c $(TOMMATHSRC) # # Building the libtommath files @@ -185,20 +116,6 @@ $(TOMMATH_WASM_64_A): $(TOMMATH_WASM_64_O) llvm-ar rcs $@ $^ llvm-ranlib $@ -# -# Building the musl files -# - -MUSL_WASM_32_O=$(MUSLFILES_32:%=_build/wasm32/musl_%.o) -MUSL_WASM_32_A=_build/libmusl_wasm32.a - -_build/wasm32/musl_%.o: %.c | _build/wasm32 - $(WASM_CLANG) $(CLANG_FLAGS_32) $(MUSL_FLAGS_32) $< --output $@ - -$(MUSL_WASM_32_A): $(MUSL_WASM_32_O) - llvm-ar rcs $@ $^ - llvm-ranlib $@ - # # The rust code code of the RTS # @@ -207,6 +124,8 @@ $(MUSL_WASM_32_A): $(MUSL_WASM_32_O) RTS_RUST_FILES=$(shell ls **/*.rs) RTS_CARGO_FILES=$(shell ls **/Cargo.toml) +RTS_COMPILE_FLAGS=-C target-feature=+bulk-memory + TOMMATH_BINDINGS_RS_32=_build/wasm32/tommath_bindings.rs TOMMATH_BINDINGS_RS_64=_build/wasm64/tommath_bindings.rs @@ -245,7 +164,7 @@ TOMMATH_BIND_OPTIONS = \ $(TOMMATH_BINDINGS_RS_32): | _build/wasm32 bindgen $(TOMMATHSRC)/tommath.h \ -o $@ \ - --ctypes-prefix=libc \ + --ctypes-prefix="crate::libc_declarations" \ $(TOMMATH_BIND_OPTIONS) \ -- $(TOMMATH_FLAGS_32) @@ -266,11 +185,11 @@ $(TOMMATH_BINDINGS_RS_64): | _build/wasm64 # 32-bit Wasm builds RTS_DEPENDENCIES_32=$(TOMMATH_BINDINGS_RS_32) $(RTS_RUST_FILES) $(RTS_CARGO_FILES) | _build/wasm32 -RTS_BUILD_32=cd motoko-rts && cargo build --target=wasm32-unknown-emscripten -Zbuild-std=core,alloc +RTS_BUILD_32=cd motoko-rts && RUSTFLAGS="${RTS_COMPILE_FLAGS}" cargo build --target wasm32-unknown-shared.json -Zbuild-std=core,alloc RTS_DEBUG_BUILD_32=$(RTS_BUILD_32) RTS_RELEASE_BUILD_32=$(RTS_BUILD_32) --release -Zbuild-std-features="panic_immediate_abort,optimize_for_size" -RTS_DEBUG_TARGET_32=motoko-rts/target/wasm32-unknown-emscripten/debug/libmotoko_rts.a -RTS_RELEASE_TARGET_32=motoko-rts/target/wasm32-unknown-emscripten/release/libmotoko_rts.a +RTS_DEBUG_TARGET_32=motoko-rts/target/wasm32-unknown-shared/debug/libmotoko_rts.a +RTS_RELEASE_TARGET_32=motoko-rts/target/wasm32-unknown-shared/release/libmotoko_rts.a RTS_RUST_NON_INCREMENTAL_WASM_32_A=_build/wasm32/libmotoko_rts.a RTS_RUST_NON_INCREMENTAL_DEBUG_WASM_32_A=_build/wasm32/libmotoko_rts_debug.a @@ -297,92 +216,34 @@ $(RTS_RUST_INCREMENTAL_DEBUG_WASM_32_A): $(RTS_DEPENDENCIES_32) # 64-bit Wasm builds RTS_DEPENDENCIES_64=$(TOMMATH_BINDINGS_RS_64) $(RTS_RUST_FILES) $(RTS_CARGO_FILES) | _build/wasm64 -COMPILER_FLAGS_64=--emit=llvm-ir -RTS_BUILD_64=cd motoko-rts && RUSTFLAGS="${COMPILER_FLAGS_64}" cargo build --target=wasm64-unknown-unknown -Zbuild-std=core,alloc --features enhanced_orthogonal_persistence +RTS_BUILD_64=cd motoko-rts && RUSTFLAGS="${RTS_COMPILE_FLAGS}" cargo build --target wasm64-unknown-shared.json -Zbuild-std=core,alloc --features enhanced_orthogonal_persistence RTS_DEBUG_BUILD_64=$(RTS_BUILD_64) RTS_RELEASE_BUILD_64=$(RTS_BUILD_64) --release -Zbuild-std-features="panic_immediate_abort,optimize_for_size" -RTS_DEBUG_TARGET_64_FOLDER=motoko-rts/target/wasm64-unknown-unknown/debug -RTS_RELEASE_TARGET_64_FOLDER=motoko-rts/target/wasm64-unknown-unknown/release +RTS_DEBUG_TARGET_64=motoko-rts/target/wasm64-unknown-shared/debug/libmotoko_rts.a +RTS_RELEASE_TARGET_64=motoko-rts/target/wasm64-unknown-shared/release/libmotoko_rts.a -RTS_DEBUG_TARGET_64=$(RTS_DEBUG_TARGET_64_FOLDER)/deps/motoko_rts-*.ll -RTS_RELEASE_TARGET_64=$(RTS_RELEASE_TARGET_64_FOLDER)/deps/motoko_rts-*.ll +RTS_RUST_WASM_64_A=_build/wasm64/libmotoko_rts.a +RTS_RUST_DEBUG_WASM_64_A=_build/wasm64/libmotoko_rts_debug.a -CORE_DEBUG_TARGET_64=$(RTS_DEBUG_TARGET_64_FOLDER)/deps/core-*.ll -CORE_RELEASE_TARGET_64=$(RTS_RELEASE_TARGET_64_FOLDER)/deps/core-*.ll - -ALLOC_DEBUG_TARGET_64=$(RTS_DEBUG_TARGET_64_FOLDER)/deps/alloc-*.ll -ALLOC_RELEASE_TARGET_64=$(RTS_RELEASE_TARGET_64_FOLDER)/deps/alloc-*.ll - -COMPILER_BUILTINS_DEBUG_TARGET_64=$(RTS_DEBUG_TARGET_64_FOLDER)/deps/compiler_builtins-*.ll -COMPILER_BUILTINS_RELEASE_TARGET_64=$(RTS_RELEASE_TARGET_64_FOLDER)/deps/compiler_builtins-*.ll - -BUILD_64_FOLDER=_build/wasm64 - -RTS_RUST_LLVM_IR_64=$(BUILD_64_FOLDER)/libmotoko_rts.ll -RTS_RUST_DEBUG_LLVM_IR_64=$(BUILD_64_FOLDER)/libmotoko_rts_debug.ll - -CORE_DEBUG_LLVM_IR_64=$(BUILD_64_FOLDER)/core_debug.ll -CORE_RELEASE_LLVM_IR_64=$(BUILD_64_FOLDER)/core.ll - -ALLOC_DEBUG_LLVM_IR_64=$(BUILD_64_FOLDER)/alloc_debug.ll -ALLOC_RELEASE_LLVM_IR_64=$(BUILD_64_FOLDER)/alloc.ll - -COMPILER_BUILTINS_DEBUG_LLVM_IR_64=$(BUILD_64_FOLDER)/compiler_builtins_debug.ll -COMPILER_BUILTINS_RELEASE_LLVM_IR_64=$(BUILD_64_FOLDER)/compiler_builtins.ll - -$(RTS_RUST_LLVM_IR_64): $(RTS_DEPENDENCIES_64) - rm -rf $(RTS_RELEASE_TARGET_64_FOLDER) +$(RTS_RUST_WASM_64_A): $(RTS_DEPENDENCIES_64) $(RTS_RELEASE_BUILD_64) - cp $(CORE_RELEASE_TARGET_64) -T $(CORE_RELEASE_LLVM_IR_64) - cp $(ALLOC_RELEASE_TARGET_64) -T $(ALLOC_RELEASE_LLVM_IR_64) - cp $(COMPILER_BUILTINS_RELEASE_TARGET_64) -T $(COMPILER_BUILTINS_RELEASE_LLVM_IR_64) - cp $(RTS_RELEASE_TARGET_64) -T $@ + cp $(RTS_RELEASE_TARGET_64) $@ -$(RTS_RUST_DEBUG_LLVM_IR_64): $(RTS_DEPENDENCIES_64) - rm -rf $(RTS_DEBUG_TARGET_64_FOLDER) +$(RTS_RUST_DEBUG_WASM_64_A): $(RTS_DEPENDENCIES_64) $(RTS_DEBUG_BUILD_64) - cp $(CORE_DEBUG_TARGET_64) -T $(CORE_DEBUG_LLVM_IR_64) - cp $(ALLOC_DEBUG_TARGET_64) -T $(ALLOC_DEBUG_LLVM_IR_64) - cp $(COMPILER_BUILTINS_DEBUG_TARGET_64) -T $(COMPILER_BUILTINS_DEBUG_LLVM_IR_64) - cp $(RTS_DEBUG_TARGET_64) -T $@ - -RTS_RUST_LINKED_LLVM_BC_64=$(BUILD_64_FOLDER)/libmotoko_rts.bc -RTS_RUST_DEBUG_LINKED_LLVM_BC_64=$(BUILD_64_FOLDER)/libmotoko_rts_debug.bc - -$(RTS_RUST_LINKED_LLVM_BC_64): $(RTS_RUST_LLVM_IR_64) - $(LLVM_LINK) -o $@ \ - $(CORE_RELEASE_LLVM_IR_64) \ - $(ALLOC_RELEASE_LLVM_IR_64) \ - $(COMPILER_BUILTINS_RELEASE_LLVM_IR_64) \ - $+ - -$(RTS_RUST_DEBUG_LINKED_LLVM_BC_64): $(RTS_RUST_DEBUG_LLVM_IR_64) - $(LLVM_LINK) -o $@ \ - $(CORE_DEBUG_LLVM_IR_64) \ - $(ALLOC_DEBUG_LLVM_IR_64) \ - $(COMPILER_BUILTINS_DEBUG_LLVM_IR_64) \ - $+ - -RTS_RUST_WASM_64_O=$(BUILD_64_FOLDER)/libmotoko_rts.o -RTS_RUST_DEBUG_WASM_64_O=$(BUILD_64_FOLDER)/libmotoko_rts_debug.o - -$(RTS_RUST_WASM_64_O): $(RTS_RUST_LINKED_LLVM_BC_64) - $(RTS_LL_64_RELEASE) -o $@ $+ - -$(RTS_RUST_DEBUG_WASM_64_O): $(RTS_RUST_DEBUG_LINKED_LLVM_BC_64) - $(RTS_LL_64_DEBUG) -o $@ $+ + cp $(RTS_DEBUG_TARGET_64) $@ # # The test suite # TEST_DEPENDENCIES_32=$(TOMMATH_WASM_32_A) $(TOMMATH_BINDINGS_RS_32) -TEST_BUILD_32=cd motoko-rts-tests && cargo build --target=wasm32-wasi +TEST_BUILD_32=cd motoko-rts-tests && RUSTFLAGS="${RTS_COMPILE_FLAGS}" cargo build --target=wasm32-wasi TEST_RUN_32=wasmtime -C cache=n -W nan-canonicalization=y motoko-rts-tests/target/wasm32-wasi/debug/motoko-rts-tests.wasm TEST_DEPENDENCIES_64=$(TOMMATH_WASM_64_A) $(TOMMATH_BINDINGS_RS_64) -TEST_BUILD_64=cd motoko-rts-tests && cargo build --target=wasm64-unknown-unknown -Zbuild-std=core,alloc,std,panic_abort --features enhanced_orthogonal_persistence +TEST_BUILD_64=cd motoko-rts-tests && RUSTFLAGS="${RTS_COMPILE_FLAGS}" cargo build --target=wasm64-unknown-unknown -Zbuild-std=core,alloc,std,panic_abort --features enhanced_orthogonal_persistence TEST_RUN_64=wasmtime -C cache=n -W nan-canonicalization=y -W memory64 motoko-rts-tests/target/wasm64-unknown-unknown/debug/motoko-rts-tests.wasm .PHONY: test @@ -405,12 +266,9 @@ test64: $(TEST_DEPENDENCIES_64) # Putting it all together # -# These symbols from musl are used by the code generator directly - EXPORTED_SYMBOLS=\ __wasm_call_ctors \ __wasm_apply_data_relocs \ - memcpy \ memcmp \ tan \ asin \ @@ -424,7 +282,7 @@ EXPORTED_SYMBOLS=\ fmod \ log -WASM_A_DEPENDENCIES_32=$(TOMMATH_WASM_32_A) $(MUSL_WASM_32_A) +WASM_A_DEPENDENCIES_32=$(TOMMATH_WASM_32_A) LINKER_OPTIONS_32=\ --import-memory --shared --no-entry --gc-sections \ $(EXPORTED_SYMBOLS:%=--export=%) \ @@ -460,13 +318,13 @@ mo-rts-incremental-debug.wasm: $(RTS_RUST_INCREMENTAL_DEBUG_WASM_32_A) $(WASM_A_ $(LINKER_OPTIONS_32) \ $+ -mo-rts-eop.wasm: $(RTS_RUST_WASM_64_O) $(WASM_A_DEPENDENCIES_64) +mo-rts-eop.wasm: $(RTS_RUST_WASM_64_A) $(WASM_A_DEPENDENCIES_64) $(WASM_LD) -o $@ \ $(LINKER_OPTIONS_64) \ $+ $(WASM_OPT) $(WASM_OPT_OPTIONS) -o $@ $@ -mo-rts-eop-debug.wasm: $(RTS_RUST_DEBUG_WASM_64_O) $(WASM_A_DEPENDENCIES_64) +mo-rts-eop-debug.wasm: $(RTS_RUST_DEBUG_WASM_64_A) $(WASM_A_DEPENDENCIES_64) $(WASM_LD) -o $@ \ $(LINKER_OPTIONS_64) \ $+ diff --git a/rts/motoko-rts/config.toml b/rts/motoko-rts/config.toml index 5eaa82beb8a..ad6e8cce956 100644 --- a/rts/motoko-rts/config.toml +++ b/rts/motoko-rts/config.toml @@ -2,3 +2,11 @@ # std, and compiler_builtins and makes it easier to find symbols. [build] rustflags = ["-Crelocation-model=pic", "-Ccodegen-units=1"] + +# Use the patched wasm-ld +[target.wasm32-unknown-shared] +linker = "wasm-ld" + +# Use the patched wasm-ld +[target.wasm64-unknown-shared] +linker = "wasm-ld" diff --git a/rts/motoko-rts/src/allocator.rs b/rts/motoko-rts/src/allocator.rs index 0cfe4515689..c624d19abba 100644 --- a/rts/motoko-rts/src/allocator.rs +++ b/rts/motoko-rts/src/allocator.rs @@ -1,7 +1,6 @@ // c.f. https://os.phil-opp.com/heap-allocation/#dynamic-memory use alloc::alloc::{GlobalAlloc, Layout}; -use motoko_rts_macros::enhanced_orthogonal_persistence; //use core::ptr::null_mut; use crate::memory::{alloc_blob, ic}; use crate::types::{Bytes, TAG_BLOB_B}; @@ -41,9 +40,3 @@ unsafe impl GlobalAlloc for EphemeralAllocator { #[global_allocator] static ALLOCATOR: EphemeralAllocator = EphemeralAllocator; - -#[no_mangle] -#[enhanced_orthogonal_persistence] -fn __rust_alloc_error_handler(_size: usize, _align: usize) -> ! { - panic!("Rust allocation error"); -} diff --git a/rts/motoko-rts/src/libc_declarations.rs b/rts/motoko-rts/src/libc_declarations.rs index aa40e22876e..e5906f3150f 100644 --- a/rts/motoko-rts/src/libc_declarations.rs +++ b/rts/motoko-rts/src/libc_declarations.rs @@ -1,30 +1,11 @@ // Declarations adopted from https://github.com/rust-lang/libc/blob/main/src/wasi.rs. #![allow(non_camel_case_types)] -use motoko_rts_macros::classical_persistence; -use motoko_rts_macros::enhanced_orthogonal_persistence; - pub(crate) type c_void = core::ffi::c_void; pub(crate) type size_t = usize; pub(crate) type c_char = i8; pub(crate) type c_int = i32; -#[classical_persistence] -pub(crate) unsafe fn memcpy(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void { - libc::memcpy(dest, src, n) -} - -#[classical_persistence] -pub(crate) unsafe fn memset(dest: *mut c_void, c: c_int, n: size_t) -> *mut c_void { - libc::memset(dest, c, n) -} - -#[classical_persistence] -pub(crate) unsafe fn memcmp(cx: *const c_void, ct: *const c_void, n: size_t) -> c_int { - libc::memcmp(cx, ct, n) -} - -#[enhanced_orthogonal_persistence] extern "C" { pub(crate) fn memcpy(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; pub(crate) fn memset(dest: *mut c_void, c: c_int, n: size_t) -> *mut c_void; diff --git a/rts/motoko-rts/wasm32-unknown-shared.json b/rts/motoko-rts/wasm32-unknown-shared.json new file mode 100644 index 00000000000..b3fad659a76 --- /dev/null +++ b/rts/motoko-rts/wasm32-unknown-shared.json @@ -0,0 +1,57 @@ +{ + "arch": "wasm32", + "crt-objects-fallback": "true", + "data-layout": "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20", + "default-hidden-visibility": true, + "dll-prefix": "", + "dll-suffix": ".wasm", + "dynamic-linking": true, + "eh-frame-header": false, + "emit-debug-gdb-scripts": false, + "exe-suffix": ".wasm", + "generate-arange-section": false, + "has-thread-local": true, + "is-builtin": false, + "is-like-wasm": true, + "limit-rdylib-exports": false, + "linker": "rust-lld", + "linker-flavor": "wasm-ld", + "linker-is-gnu": false, + "lld-flavor": "wasm", + "llvm-target": "wasm32-unknown-shared", + "max-atomic-width": 64, + "only-cdylib": true, + "os": "unknown", + "panic-strategy": "abort", + "pre-link-args": { + "gcc": [ + "-Wl,-z", + "-Wl,stack-size=1048576", + "-Wl,--stack-first", + "-Wl,--allow-undefined", + "-Wl,--fatal-warnings", + "-Wl,--no-demangle", + "--target=wasm32-unknown-shared", + "-Wl,--no-entry", + "--shared", + "--experimental-pic" + ], + "wasm-ld": [ + "-z", + "stack-size=1048576", + "--stack-first", + "--allow-undefined", + "--fatal-warnings", + "--no-demangle", + "--no-entry", + "--shared", + "--experimental-pic" + ] + }, + "singlethread": true, + "target-family": [ + "wasm" + ], + "target-pointer-width": "32", + "tls-model": "local-exec" +} diff --git a/rts/motoko-rts/wasm64-unknown-shared.json b/rts/motoko-rts/wasm64-unknown-shared.json new file mode 100644 index 00000000000..63271fbd531 --- /dev/null +++ b/rts/motoko-rts/wasm64-unknown-shared.json @@ -0,0 +1,59 @@ +{ + "arch": "wasm64", + "crt-objects-fallback": "true", + "data-layout": "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20", + "default-hidden-visibility": true, + "dll-prefix": "", + "dll-suffix": ".wasm", + "dynamic-linking": true, + "eh-frame-header": false, + "emit-debug-gdb-scripts": false, + "exe-suffix": ".wasm", + "features": "+bulk-memory,+mutable-globals,+sign-ext,+nontrapping-fptoint", + "generate-arange-section": false, + "has-thread-local": true, + "is-builtin": false, + "is-like-wasm": true, + "limit-rdylib-exports": false, + "linker": "rust-lld", + "linker-flavor": "wasm-ld", + "linker-is-gnu": false, + "lld-flavor": "wasm", + "llvm-target": "wasm64-unknown-shared", + "max-atomic-width": 64, + "only-cdylib": true, + "os": "unknown", + "panic-strategy": "abort", + "pre-link-args": { + "gcc": [ + "-Wl,-z", + "-Wl,stack-size=1048576", + "-Wl,--stack-first", + "-Wl,--allow-undefined", + "-Wl,--fatal-warnings", + "-Wl,--no-demangle", + "--target=wasm64-unknown-shared", + "-Wl,--no-entry", + "--shared", + "--experimental-pic" + ], + "wasm-ld": [ + "-z", + "stack-size=1048576", + "--stack-first", + "--allow-undefined", + "--fatal-warnings", + "--no-demangle", + "--no-entry", + "-mwasm64", + "--shared", + "--experimental-pic" + ] + }, + "singlethread": true, + "target-family": [ + "wasm" + ], + "target-pointer-width": "64", + "tls-model": "local-exec" +} diff --git a/rts/stubs.c b/rts/stubs.c deleted file mode 100644 index fb56d6a29dc..00000000000 --- a/rts/stubs.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include - -__attribute__ ((noreturn)) void rts_trap(char *msg, uint32_t len); - -// Stubbery for musl. Functions below are used by some of the musl functions we -// compile. - -// musl implementation uses system calls so we provide our own implementation -void abort(void) { rts_trap("abort", 5); } - -// Functions below should not be called, so we trap when they're called. - -int wctomb(char *s, wchar_t wc) { __builtin_trap(); } - -int fputs(const char *s, void *f) { __builtin_trap(); } - -char *strerror(int e) { __builtin_trap(); } diff --git a/src/codegen/compile_classical.ml b/src/codegen/compile_classical.ml index b3468537e67..10186fa3f59 100644 --- a/src/codegen/compile_classical.ml +++ b/src/codegen/compile_classical.ml @@ -1134,7 +1134,6 @@ module RTS = struct (* The connection to the C and Rust parts of the RTS *) let system_imports env = - E.add_func_import env "rts" "memcpy" [I32Type; I32Type; I32Type] [I32Type]; (* standard libc memcpy *) E.add_func_import env "rts" "memcmp" [I32Type; I32Type; I32Type] [I32Type]; E.add_func_import env "rts" "version" [] [I32Type]; E.add_func_import env "rts" "parse_idl_header" [I32Type; I32Type; I32Type; I32Type; I32Type] []; @@ -1237,17 +1236,17 @@ module RTS = struct E.add_func_import env "rts" "blob_iter_done" [I32Type] [I32Type]; E.add_func_import env "rts" "blob_iter" [I32Type] [I32Type]; E.add_func_import env "rts" "blob_iter_next" [I32Type] [I32Type]; - E.add_func_import env "rts" "pow" [F64Type; F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "sin" [F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "cos" [F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "tan" [F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "asin" [F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "acos" [F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "atan" [F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "atan2" [F64Type; F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "exp" [F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "log" [F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "fmod" [F64Type; F64Type] [F64Type]; (* remainder, musl *) + E.add_func_import env "rts" "pow" [F64Type; F64Type] [F64Type]; + E.add_func_import env "rts" "sin" [F64Type] [F64Type]; + E.add_func_import env "rts" "cos" [F64Type] [F64Type]; + E.add_func_import env "rts" "tan" [F64Type] [F64Type]; + E.add_func_import env "rts" "asin" [F64Type] [F64Type]; + E.add_func_import env "rts" "acos" [F64Type] [F64Type]; + E.add_func_import env "rts" "atan" [F64Type] [F64Type]; + E.add_func_import env "rts" "atan2" [F64Type; F64Type] [F64Type]; + E.add_func_import env "rts" "exp" [F64Type] [F64Type]; + E.add_func_import env "rts" "log" [F64Type] [F64Type]; + E.add_func_import env "rts" "fmod" [F64Type; F64Type] [F64Type]; E.add_func_import env "rts" "float_fmt" [F64Type; I32Type; I32Type] [I32Type]; E.add_func_import env "rts" "char_to_upper" [I32Type] [I32Type]; E.add_func_import env "rts" "char_to_lower" [I32Type] [I32Type]; @@ -1413,7 +1412,7 @@ module Heap = struct (* Convenience functions related to memory *) (* Copying bytes (works on unskewed memory addresses) *) - let memcpy env = E.call_import env "rts" "memcpy" ^^ G.i Drop + let memcpy env = G.i MemoryCopy (* Comparing bytes (works on unskewed memory addresses) *) let memcmp env = E.call_import env "rts" "memcmp" @@ -10452,7 +10451,7 @@ let compile_binop env t op : SR.t * SR.t * G.t = end get_res) | Type.(Prim Float), DivOp -> G.i (Binary (Wasm.Values.F64 F64Op.Div)) - | Type.(Prim Float), ModOp -> E.call_import env "rts" "fmod" (* musl *) + | Type.(Prim Float), ModOp -> E.call_import env "rts" "fmod" | Type.(Prim (Int8|Int16|Int32)), ModOp -> G.i (Binary (Wasm.Values.I32 I32Op.RemS)) | Type.(Prim (Nat8|Nat16|Nat32 as ty)), WPowOp -> TaggedSmallWord.compile_nat_power env ty | Type.(Prim (Int8|Int16|Int32 as ty)), WPowOp -> TaggedSmallWord.compile_int_power env ty @@ -10601,7 +10600,7 @@ let compile_binop env t op : SR.t * SR.t * G.t = env "pow" BigNum.compile_unsigned_pow (powInt64_shortcut (Word64.compile_unsigned_pow env)) | Type.(Prim Nat), PowOp -> BigNum.compile_unsigned_pow env - | Type.(Prim Float), PowOp -> E.call_import env "rts" "pow" (* musl *) + | Type.(Prim Float), PowOp -> E.call_import env "rts" "pow" | Type.(Prim (Nat64|Int64)), AndOp -> G.i (Binary (Wasm.Values.I64 I64Op.And)) | Type.(Prim (Nat8|Nat16|Nat32|Int8|Int16|Int32)), AndOp -> G.i (Binary (Wasm.Values.I32 I32Op.And)) @@ -11393,48 +11392,48 @@ and compile_prim_invocation (env : E.t) ae p es at = | OtherPrim "fsin", [e] -> SR.UnboxedFloat64, compile_exp_as env ae SR.UnboxedFloat64 e ^^ - E.call_import env "rts" "sin" (* musl *) + E.call_import env "rts" "sin" | OtherPrim "fcos", [e] -> SR.UnboxedFloat64, compile_exp_as env ae SR.UnboxedFloat64 e ^^ - E.call_import env "rts" "cos" (* musl *) + E.call_import env "rts" "cos" | OtherPrim "ftan", [e] -> SR.UnboxedFloat64, compile_exp_as env ae SR.UnboxedFloat64 e ^^ - E.call_import env "rts" "tan" (* musl *) + E.call_import env "rts" "tan" | OtherPrim "fasin", [e] -> SR.UnboxedFloat64, compile_exp_as env ae SR.UnboxedFloat64 e ^^ - E.call_import env "rts" "asin" (* musl *) + E.call_import env "rts" "asin" | OtherPrim "facos", [e] -> SR.UnboxedFloat64, compile_exp_as env ae SR.UnboxedFloat64 e ^^ - E.call_import env "rts" "acos" (* musl *) + E.call_import env "rts" "acos" | OtherPrim "fatan", [e] -> SR.UnboxedFloat64, compile_exp_as env ae SR.UnboxedFloat64 e ^^ - E.call_import env "rts" "atan" (* musl *) + E.call_import env "rts" "atan" | OtherPrim "fatan2", [y; x] -> SR.UnboxedFloat64, compile_exp_as env ae SR.UnboxedFloat64 y ^^ compile_exp_as env ae SR.UnboxedFloat64 x ^^ - E.call_import env "rts" "atan2" (* musl *) + E.call_import env "rts" "atan2" | OtherPrim "fexp", [e] -> SR.UnboxedFloat64, compile_exp_as env ae SR.UnboxedFloat64 e ^^ - E.call_import env "rts" "exp" (* musl *) + E.call_import env "rts" "exp" | OtherPrim "flog", [e] -> SR.UnboxedFloat64, compile_exp_as env ae SR.UnboxedFloat64 e ^^ - E.call_import env "rts" "log" (* musl *) + E.call_import env "rts" "log" (* Other prims, nullary *) diff --git a/src/codegen/compile_enhanced.ml b/src/codegen/compile_enhanced.ml index 74e2a64be67..30c1518f333 100644 --- a/src/codegen/compile_enhanced.ml +++ b/src/codegen/compile_enhanced.ml @@ -1140,7 +1140,6 @@ module RTS = struct E.add_func_import env "rts" "set_static_variable" [I64Type; I64Type] []; E.add_func_import env "rts" "set_upgrade_instructions" [I64Type] []; E.add_func_import env "rts" "get_upgrade_instructions" [] [I64Type]; - E.add_func_import env "rts" "memcpy" [I64Type; I64Type; I64Type] [I64Type]; (* standard libc memcpy *) E.add_func_import env "rts" "memcmp" [I64Type; I64Type; I64Type] [I32Type]; E.add_func_import env "rts" "version" [] [I64Type]; E.add_func_import env "rts" "parse_idl_header" [I32Type; I64Type; I64Type; I64Type; I64Type] []; @@ -1239,17 +1238,17 @@ module RTS = struct E.add_func_import env "rts" "blob_iter_done" [I64Type] [I64Type]; E.add_func_import env "rts" "blob_iter" [I64Type] [I64Type]; E.add_func_import env "rts" "blob_iter_next" [I64Type] [I64Type]; - E.add_func_import env "rts" "pow" [F64Type; F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "sin" [F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "cos" [F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "tan" [F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "asin" [F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "acos" [F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "atan" [F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "atan2" [F64Type; F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "exp" [F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "log" [F64Type] [F64Type]; (* musl *) - E.add_func_import env "rts" "fmod" [F64Type; F64Type] [F64Type]; (* remainder, musl *) + E.add_func_import env "rts" "pow" [F64Type; F64Type] [F64Type]; + E.add_func_import env "rts" "sin" [F64Type] [F64Type]; + E.add_func_import env "rts" "cos" [F64Type] [F64Type]; + E.add_func_import env "rts" "tan" [F64Type] [F64Type]; + E.add_func_import env "rts" "asin" [F64Type] [F64Type]; + E.add_func_import env "rts" "acos" [F64Type] [F64Type]; + E.add_func_import env "rts" "atan" [F64Type] [F64Type]; + E.add_func_import env "rts" "atan2" [F64Type; F64Type] [F64Type]; + E.add_func_import env "rts" "exp" [F64Type] [F64Type]; + E.add_func_import env "rts" "log" [F64Type] [F64Type]; + E.add_func_import env "rts" "fmod" [F64Type; F64Type] [F64Type]; E.add_func_import env "rts" "float_fmt" [F64Type; I64Type; I64Type] [I64Type]; E.add_func_import env "rts" "char_to_upper" [I32Type] [I32Type]; E.add_func_import env "rts" "char_to_lower" [I32Type] [I32Type]; @@ -1377,7 +1376,7 @@ module Heap = struct (* Convenience functions related to memory *) (* Copying bytes (works on unskewed memory addresses) *) - let memcpy env = E.call_import env "rts" "memcpy" ^^ G.i Drop + let memcpy env = G.i MemoryCopy (* Comparing bytes (works on unskewed memory addresses) *) let memcmp env = E.call_import env "rts" "memcmp" ^^ G.i (Convert (Wasm_exts.Values.I64 I64Op.ExtendUI32)) @@ -10742,7 +10741,7 @@ let compile_binop env t op : SR.t * SR.t * G.t = end get_res) | Type.(Prim Float), DivOp -> G.i (Binary (Wasm_exts.Values.F64 F64Op.Div)) - | Type.(Prim Float), ModOp -> E.call_import env "rts" "fmod" (* musl *) + | Type.(Prim Float), ModOp -> E.call_import env "rts" "fmod" | Type.(Prim (Int8|Int16|Int32)), ModOp -> G.i (Binary (Wasm_exts.Values.I64 I64Op.RemS)) | Type.(Prim (Nat8|Nat16|Nat32 as ty)), WPowOp -> TaggedSmallWord.compile_nat_power env ty | Type.(Prim (Int8|Int16|Int32 as ty)), WPowOp -> TaggedSmallWord.compile_int_power env ty @@ -10861,7 +10860,7 @@ let compile_binop env t op : SR.t * SR.t * G.t = env "pow" BigNum.compile_unsigned_pow (powInt64_shortcut (Word64.compile_unsigned_pow env)) | Type.(Prim Nat), PowOp -> BigNum.compile_unsigned_pow env - | Type.(Prim Float), PowOp -> E.call_import env "rts" "pow" (* musl *) + | Type.(Prim Float), PowOp -> E.call_import env "rts" "pow" | Type.(Prim (Nat8|Nat16|Nat32|Nat64|Int8|Int16|Int32|Int64)), AndOp -> G.i (Binary (Wasm_exts.Values.I64 I64Op.And)) | Type.(Prim (Nat8|Nat16|Nat32|Nat64|Int8|Int16|Int32|Int64)), @@ -11545,48 +11544,48 @@ and compile_prim_invocation (env : E.t) ae p es at = | OtherPrim "fsin", [e] -> SR.UnboxedFloat64, compile_exp_as env ae SR.UnboxedFloat64 e ^^ - E.call_import env "rts" "sin" (* musl *) + E.call_import env "rts" "sin" | OtherPrim "fcos", [e] -> SR.UnboxedFloat64, compile_exp_as env ae SR.UnboxedFloat64 e ^^ - E.call_import env "rts" "cos" (* musl *) + E.call_import env "rts" "cos" | OtherPrim "ftan", [e] -> SR.UnboxedFloat64, compile_exp_as env ae SR.UnboxedFloat64 e ^^ - E.call_import env "rts" "tan" (* musl *) + E.call_import env "rts" "tan" | OtherPrim "fasin", [e] -> SR.UnboxedFloat64, compile_exp_as env ae SR.UnboxedFloat64 e ^^ - E.call_import env "rts" "asin" (* musl *) + E.call_import env "rts" "asin" | OtherPrim "facos", [e] -> SR.UnboxedFloat64, compile_exp_as env ae SR.UnboxedFloat64 e ^^ - E.call_import env "rts" "acos" (* musl *) + E.call_import env "rts" "acos" | OtherPrim "fatan", [e] -> SR.UnboxedFloat64, compile_exp_as env ae SR.UnboxedFloat64 e ^^ - E.call_import env "rts" "atan" (* musl *) + E.call_import env "rts" "atan" | OtherPrim "fatan2", [y; x] -> SR.UnboxedFloat64, compile_exp_as env ae SR.UnboxedFloat64 y ^^ compile_exp_as env ae SR.UnboxedFloat64 x ^^ - E.call_import env "rts" "atan2" (* musl *) + E.call_import env "rts" "atan2" | OtherPrim "fexp", [e] -> SR.UnboxedFloat64, compile_exp_as env ae SR.UnboxedFloat64 e ^^ - E.call_import env "rts" "exp" (* musl *) + E.call_import env "rts" "exp" | OtherPrim "flog", [e] -> SR.UnboxedFloat64, compile_exp_as env ae SR.UnboxedFloat64 e ^^ - E.call_import env "rts" "log" (* musl *) + E.call_import env "rts" "log" (* Other prims, nullary *) diff --git a/src/linking/linkModule.ml b/src/linking/linkModule.ml index 10410288ca3..eae560ca1d8 100644 --- a/src/linking/linkModule.ml +++ b/src/linking/linkModule.ml @@ -1005,7 +1005,13 @@ let link (em1 : extended_module) libname (em2 : extended_module) = ) end else (); - let old_table_size = read_table_size em1.module_ in + let max x y = if x >= y then x else y in + + (* Rust requires a table offset of at least 1 as elem[0] is considered invalid. + There are debug checks panicking if the element index is zero. + On the other hand, elem[0] can be used by the Motoko backend code (em1), + as correct Rust-generated Wasm code does not call elem[0]. *) + let old_table_size = max (read_table_size em1.module_) 1l in let lib_table_start = align_i32 dylink0_mem_info.table_alignment old_table_size in let uses_memory64 = uses_memory64 em1.module_ in diff --git a/test/bench/ok/bignum.drun-run.ok b/test/bench/ok/bignum.drun-run.ok index b5972e123a1..d67fe48bb37 100644 --- a/test/bench/ok/bignum.drun-run.ok +++ b/test/bench/ok/bignum.drun-run.ok @@ -1,6 +1,6 @@ ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101 ingress Completed: Reply: 0x4449444c0000 -debug.print: {cycles = 2_508_947; size = +59_652} +debug.print: {cycles = 2_498_838; size = +59_652} ingress Completed: Reply: 0x4449444c0000 -debug.print: {cycles = 105_771_809; size = +1_817_872} +debug.print: {cycles = 104_993_587; size = +1_817_872} ingress Completed: Reply: 0x4449444c0000 diff --git a/test/bench/ok/candid-subtype-cost.drun-run.ok b/test/bench/ok/candid-subtype-cost.drun-run.ok index 30e6715e698..c7570d01d72 100644 --- a/test/bench/ok/candid-subtype-cost.drun-run.ok +++ b/test/bench/ok/candid-subtype-cost.drun-run.ok @@ -1,4 +1,4 @@ ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101 ingress Completed: Reply: 0x4449444c0000 -debug.print: {cycles = 1_063_723; heap_bytes = +12_564} +debug.print: {cycles = 1_112_048; heap_bytes = +12_564} ingress Completed: Reply: 0x4449444c0000 diff --git a/test/bench/ok/heap-32.drun-run.ok b/test/bench/ok/heap-32.drun-run.ok index dcede505153..4ddac5297c5 100644 --- a/test/bench/ok/heap-32.drun-run.ok +++ b/test/bench/ok/heap-32.drun-run.ok @@ -1,5 +1,5 @@ ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101 ingress Completed: Reply: 0x4449444c0000 -debug.print: (50_227, +29_863_068, 683_152_487) -debug.print: (50_070, +32_992_212, 742_929_510) +debug.print: (50_227, +29_863_068, 683_152_843) +debug.print: (50_070, +32_992_212, 742_929_154) ingress Completed: Reply: 0x4449444c0000 diff --git a/test/bench/ok/heap-64.drun-run.ok b/test/bench/ok/heap-64.drun-run.ok index 0b08597f35c..dc218bcbcf4 100644 --- a/test/bench/ok/heap-64.drun-run.ok +++ b/test/bench/ok/heap-64.drun-run.ok @@ -1,5 +1,5 @@ ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101 ingress Completed: Reply: 0x4449444c0000 -debug.print: (49_965, +47_942_744, 936_552_900) -debug.print: (49_806, +47_960_000, 944_655_296) +debug.print: (49_965, +47_942_744, 947_303_167) +debug.print: (49_806, +47_960_000, 955_419_170) ingress Completed: Reply: 0x4449444c0000 diff --git a/test/ld/Makefile b/test/ld/Makefile index 7b784d4bb94..c5aa42ee686 100644 --- a/test/ld/Makefile +++ b/test/ld/Makefile @@ -14,7 +14,7 @@ WASM_LD?=wasm-ld-18 MO_LD?=../../src/mo-ld _out/%.lib.o: %.c | _out - $(WASM_CLANG) --compile -fpic --target=wasm64-emscripten --optimize=3 \ + $(WASM_CLANG) --compile -fpic --target=wasm64 --optimize=3 \ -fno-builtin -ffreestanding \ $< --output $@ diff --git a/test/ld/ok/fun-ptr.linked.wat.ok b/test/ld/ok/fun-ptr.linked.wat.ok index ae064349452..4f829c43650 100644 --- a/test/ld/ok/fun-ptr.linked.wat.ok +++ b/test/ld/ok/fun-ptr.linked.wat.ok @@ -46,12 +46,11 @@ memory.init 0 call $__wasm_apply_data_relocs call $link_start) - (table (;0;) 5 5 funcref) + (table (;0;) 3 3 funcref) (memory (;0;) i64 2) - (global (;0;) i64 (i64.const 4)) - (global (;1;) i64 (i64.const 3)) + (global (;0;) i64 (i64.const 2)) + (global (;1;) i64 (i64.const 1)) (global (;2;) i64 (i64.const 65792)) (start $link_start.1) - (elem (;0;) (i32.const 1) func $f0 $f1) - (elem (;1;) (i32.const 3) func $f1 $f0) - (data (;0;) "\00\00\00\00\00\00\00\00\01\00\00\00\00\00\00\00")) + (elem (;0;) (i32.const 1) func $f1 $f0) + (data (;0;) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00")) diff --git a/test/ld/ok/representative.linked.wat.ok b/test/ld/ok/representative.linked.wat.ok index b45c265749f..14c226c7d10 100644 --- a/test/ld/ok/representative.linked.wat.ok +++ b/test/ld/ok/representative.linked.wat.ok @@ -24,7 +24,7 @@ (func $link_start.1 (type 0) call $__wasm_apply_data_relocs call $link_start) - (table (;0;) 0 0 funcref) + (table (;0;) 1 1 funcref) (memory (;0;) i64 2) (global (;0;) i64 (i64.const 65536)) (start $link_start.1))