diff --git a/.appveyor.yml b/.appveyor.yml
deleted file mode 100644
index 18cff7054..000000000
--- a/.appveyor.yml
+++ /dev/null
@@ -1,78 +0,0 @@
-version: "{build} ~ {branch}"
-
-os: Visual Studio 2017
-
-branches:
- only:
- - staging
- - trying
- - master
-
-environment:
- matrix:
- - CHANNEL: stable
- ARCH: x86_64
- ABI: msvc
- TARGET: x86_64-pc-windows-msvc
-
-cache:
- - 'C:\Users\appveyor\.cargo'
- - target
-
-install:
- # Install LLVM
- - mkdir C:\projects\deps
- - cd C:\projects\deps
- - appveyor DownloadFile https://github.com/wasmerio/windows-llvm-build/releases/download/v8.0.0/llvm-8.0.0-install.zip -FileName llvm-8.0.0-install.zip
- - 7z x llvm-8.0.0-install.zip
- - C:\projects\deps\llvm-8.0.0-install\bin\llvm-config.exe --version
- - set "LLVM_SYS_80_PREFIX=C:\projects\deps\llvm-8.0.0-install"
- - cd "%APPVEYOR_BUILD_FOLDER%"
-
- # Install Rust
- # uncomment these lines if the cache is cleared, or if we must re-install rust for some reason
- - appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
- - rustup-init.exe -yv --default-host %target%
- - set PATH=%PATH%;%USERPROFILE%\.cargo\bin
- - rustup default stable-%target%
- - rustup update
- - rustc -vV
- - cargo -vV
-
- # Install InnoSetup
- - appveyor-retry appveyor DownloadFile https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2017-08-22-is.exe
- - 2017-08-22-is.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-
- - set PATH="C:\Program Files (x86)\Inno Setup 5";%PATH%
-# uncomment to RDP to appveyor
-# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
-
-build_script:
- - cargo build --release --verbose --features backend-llvm
- - cargo build --release --manifest-path lib/runtime-c-api/Cargo.toml
-
-test_script:
- - cargo test --manifest-path lib/spectests/Cargo.toml --release --features clif -- --nocapture
-
-before_deploy:
- - appveyor PushArtifact target\release\wasmer_runtime_c_api.dll
- - git submodule init
- - git submodule update
- - cargo build --release --manifest-path wapm-cli/Cargo.toml --features "telemetry update-notifications"
- - cd ./src/installer
- - iscc wasmer.iss
- - copy /y .\WasmerInstaller.exe ..\..\WasmerInstaller-%APPVEYOR_REPO_TAG_NAME%.exe
- - appveyor PushArtifact ..\..\WasmerInstaller-%APPVEYOR_REPO_TAG_NAME%.exe
- - cd ..\..\
-
-matrix:
- fast_finish: true
-
-deploy:
- description: 'WasmerInstaller'
- artifact: /.*\.exe/
- auth_token:
- secure: BbreGNDJy20922za7OhJG5TERzfX+dJSBQwttNTJkLvszbqMov6hhAtRb3P45hpf
- provider: GitHub
- on:
- branch: master
- appveyor_repo_tag: true
diff --git a/.azure/install-cmake.yml b/.azure/install-cmake.yml
new file mode 100644
index 000000000..707905b55
--- /dev/null
+++ b/.azure/install-cmake.yml
@@ -0,0 +1,43 @@
+# This template installs CMake (if doesn't exist in the systems)
+
+steps:
+ - bash: |
+ set -ex
+ if [ -x "`command -v cmake`" ]; then
+ echo `command -v cmake` `cmake --version` installed
+ else
+ curl -O https://cmake.org/files/v3.4/cmake-3.4.1-Darwin-x86_64.tar.gz
+ tar xf cmake-3.4.1-Darwin-x86_64.tar.gz
+ export CMAKE_BIN_PATH="`pwd`/cmake-3.4.1-Darwin-x86_64/CMake.app/Contents/bin"
+ echo "##vso[task.prependpath]$CMAKE_BIN_PATH"
+ fi
+ displayName: "Install CMake (macOS)"
+ condition: eq(variables['Agent.OS'], 'Darwin')
+
+ - bash: |
+ set -ex
+ if [ -x "`command -v cmake`" ]; then
+ echo `command -v cmake` `cmake --version` installed
+ else
+ curl -O https://cmake.org/files/v3.4/cmake-3.4.1-Linux-x86_64.tar.gz
+ tar xf cmake-3.4.1-Linux-x86_64.tar.gz
+ export CMAKE_BIN_PATH="`pwd`/cmake-3.4.1-Linux-x86_64/CMake.app/Contents/bin"
+ echo "##vso[task.prependpath]$CMAKE_BIN_PATH"
+ fi
+ displayName: "Install CMake (Linux)"
+ condition: eq(variables['Agent.OS'], 'Linux')
+
+ - bash: |
+ set -ex
+ if [ -x "`command -v cmake`" ]; then
+ echo `command -v cmake` `cmake --version` installed
+ else
+ chocolatey install cmake --installargs 'ADD_CMAKE_TO_PATH=System'
+ fi
+ displayName: "Install CMake (Windows)"
+ condition: eq(variables['Agent.OS'], 'Windows_NT')
+
+ - bash: |
+ set -ex
+ cmake --version
+ displayName: CMake version
diff --git a/.azure/install-innosetup.yml b/.azure/install-innosetup.yml
new file mode 100644
index 000000000..bd7e2980e
--- /dev/null
+++ b/.azure/install-innosetup.yml
@@ -0,0 +1,18 @@
+# This template installs InnoSetup
+
+steps:
+ - bash: |
+ set -ex
+ if [ -x "`command -v iscc`" ]; then
+ echo `command -v iscc` `iscc -?` installed
+ else
+ choco install innosetup -y
+ fi
+ displayName: Install InnoSetup - Windows
+ condition: eq(variables['Agent.OS'], 'Windows_NT')
+
+ # - bash: |
+ # set -ex
+ # iscc
+ # displayName: InnoSetup
+ # condition: eq(variables['Agent.OS'], 'Windows_NT')
diff --git a/.azure/install-llvm.yml b/.azure/install-llvm.yml
new file mode 100644
index 000000000..5b01ee7b9
--- /dev/null
+++ b/.azure/install-llvm.yml
@@ -0,0 +1,53 @@
+# This template installs LLVM (if doesn't exist in the systems)
+
+steps:
+ - bash: |
+ set -ex
+ if [ -x "`command -v llvm-config`" ]; then
+ echo `command -v llvm-config` `llvm-config --version` installed
+ else
+ curl -O https://releases.llvm.org/8.0.0/clang+llvm-8.0.0-x86_64-apple-darwin.tar.xz
+ tar xf clang+llvm-8.0.0-x86_64-apple-darwin.tar.xz
+ export LLVM_PATH="`pwd`/clang+llvm-8.0.0-x86_64-apple-darwin/"
+ echo "##vso[task.prependpath]$LLVM_PATH/bin"
+ echo "##vso[task.setvariable variable=LLVM_SYS_80_PREFIX]$LLVM_PATH"
+ fi
+ displayName: "Install LLVM (macOS)"
+ condition: eq(variables['Agent.OS'], 'Darwin')
+
+ - bash: |
+ set -ex
+ if [ -x "`command -v llvm-config`" ]; then
+ echo `command -v llvm-config` `llvm-config --version` installed
+ else
+ curl -O https://releases.llvm.org/8.0.0/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz
+ tar xf clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz
+ export LLVM_PATH="`pwd`/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04/"
+ echo "##vso[task.prependpath]$LLVM_PATH/bin"
+ echo "##vso[task.setvariable variable=LLVM_SYS_80_PREFIX]$LLVM_PATH"
+ fi
+ displayName: "Install LLVM (Linux)"
+ condition: eq(variables['Agent.OS'], 'Linux')
+
+ - bash: |
+ set -ex
+ curl -OL https://github.com/wasmerio/windows-llvm-build/releases/download/v8.0.0/llvm-8.0.0-install.zip
+ 7z x llvm-8.0.0-install.zip
+ llvm=`pwd`/llvm-8.0.0-install
+ echo "##vso[task.prependpath]$llvm/bin"
+ echo "##vso[task.setvariable variable=LLVM_SYS_80_PREFIX;]$llvm"
+ displayName: "Install LLVM (Windows)"
+ condition: eq(variables['Agent.OS'], 'Windows_NT')
+
+ # Just to make sure the paths and vars are set properly
+ - powershell: |
+ Write-Host "##vso[task.prependpath]$pwd/llvm-8.0.0-install/bin"
+ Write-Host "##vso[task.setvariable variable=LLVM_SYS_80_PREFIX;]$pwd/llvm-8.0.0-install/"
+ displayName: Install LLVM (Windows)
+ condition: eq(variables['Agent.OS'], 'Windows_NT')
+
+ - bash: |
+ set -ex
+ env
+ llvm-config --version
+ displayName: LLVM version
diff --git a/.azure/install-rust.yml b/.azure/install-rust.yml
new file mode 100644
index 000000000..243cb7bf9
--- /dev/null
+++ b/.azure/install-rust.yml
@@ -0,0 +1,52 @@
+# This template installs Rust (if doesn't exist in the systems)
+# Also installs the desired Rust toolchain
+
+# Template inspired by Tokio and wasm-bindgen templates
+# Tokio template: https://github.com/tokio-rs/tokio/blob/master/ci/azure-install-rust.yml
+# Wasm-bindgen template: https://github.com/rustwasm/wasm-bindgen/blob/master/ci/azure-install-rust.yml
+
+steps:
+ # - bash: |
+ # set -ex
+ # brew install openssl@1.1 curl
+ # brew link openssl@1.1 --force
+ # echo "##vso[task.prependpath]/usr/local/opt/openssl/bin"
+ # echo "##vso[task.setvariable variable=LDFLAGS;]-L/usr/local/opt/openssl/lib"
+ # echo "##vso[task.setvariable variable=CPPFLAGS;]-I/usr/local/opt/openssl/include"
+ # displayName: "Fix Cargo SSL (macOS)"
+ # condition: eq(variables['Agent.OS'], 'Darwin')
+ - bash: |
+ set -ex
+ if [ -x "`command -v rustup`" ]; then
+ echo `command -v rustup` `rustup -V` installed
+ else
+ curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain $RUST_TOOLCHAIN
+ echo "##vso[task.prependpath]$HOME/.cargo/bin"
+ fi
+ displayName: "Install Rust (Linux, macOS)"
+ condition: ne(variables['Agent.OS'], 'Windows_NT')
+
+ # - bash: |
+ # set -ex
+ # if [ -x "`command -v rustup`" ]; then
+ # echo `command -v rustup` `rustup -V` installed
+ # else
+ # choco install rust -y
+ # # curl -sSf -o rustup-init.exe https://win.rustup.rs
+ # # ./rustup-init.exe -y --default-toolchain $RUST_TOOLCHAIN
+ # # echo "##vso[task.prependpath]$USERPROFILE/.cargo/bin"
+ # fi
+ # displayName: "Install Rust (Windows)"
+ # condition: eq(variables['Agent.OS'], 'Windows_NT')
+
+ - bash: |
+ set -ex
+ rustup update --no-self-update $RUST_TOOLCHAIN
+ rustup default $RUST_TOOLCHAIN
+
+ rustc -Vv
+ cargo -V
+ displayName: Install Rust
+
+ - bash: echo "##vso[task.setvariable variable=RUSTC_VERSION;]`rustc --version`"
+ displayName: Set rustc version in env var
diff --git a/.azure/install-sccache.yml b/.azure/install-sccache.yml
new file mode 100644
index 000000000..091dcc572
--- /dev/null
+++ b/.azure/install-sccache.yml
@@ -0,0 +1,57 @@
+# This template installs sccache (Shared Compilation Cache)
+# More info: https://github.com/mozilla/sccache
+
+# Template originally from wasm-bindgen
+# https://github.com/rustwasm/wasm-bindgen/blob/master/ci/azure-install-sccache.yml
+steps:
+ - bash: |
+ set -ex
+ curl -L https://github.com/mozilla/sccache/releases/download/0.2.10/sccache-0.2.10-x86_64-unknown-linux-musl.tar.gz | tar xzf -
+ sccache=`pwd`/sccache-0.2.10-x86_64-unknown-linux-musl/sccache
+ echo "##vso[task.setvariable variable=RUSTC_WRAPPER;]$sccache"
+ displayName: Install sccache - Linux
+ condition: eq( variables['Agent.OS'], 'Linux' )
+ - bash: |
+ set -ex
+ brew install openssl@1.1
+ curl -L https://github.com/mozilla/sccache/releases/download/0.2.10/sccache-0.2.10-x86_64-apple-darwin.tar.gz | tar xzf -
+ sccache=`pwd`/sccache-0.2.10-x86_64-apple-darwin/sccache
+ echo "##vso[task.setvariable variable=RUSTC_WRAPPER;]$sccache"
+ displayName: Install sccache - Darwin
+ condition: eq( variables['Agent.OS'], 'Darwin' )
+ - powershell: |
+ Invoke-WebRequest https://github.com/mozilla/sccache/releases/download/0.2.10/sccache-0.2.10-x86_64-pc-windows-msvc.tar.gz -OutFile sccache.tar.gz
+ tar xzf sccache.tar.gz
+ Write-Host "##vso[task.setvariable variable=RUSTC_WRAPPER;]$pwd/sccache-0.2.10-x86_64-pc-windows-msvc/sccache.exe"
+ displayName: Install sccache - Windows
+ condition: eq( variables['Agent.OS'], 'Windows_NT' )
+ - bash: |
+ set -ex
+ env
+ SCCACHE_ERROR_LOG=`pwd`/sccache.log RUST_LOG=debug $RUSTC_WRAPPER --start-server
+ $RUSTC_WRAPPER -s
+ cat sccache.log
+ displayName: "start sccache"
+ condition: not(eq( variables['Agent.OS'], 'Windows_NT' ))
+ env:
+ SCCACHE_AZURE_CONNECTION_STRING: $(SCCACHE_AZURE_CONNECTION_STRING)
+ SCCACHE_AZURE_BLOB_CONTAINER: $(SCCACHE_AZURE_BLOB_CONTAINER)
+
+ # Only use Azure pipelines cache in Windows
+ - bash: |
+ set -ex
+ env
+ mkdir -p $SCCACHE_DIR
+ SCCACHE_ERROR_LOG=`pwd`/sccache.log RUST_LOG=debug $RUSTC_WRAPPER --start-server
+ $RUSTC_WRAPPER -s
+ cat sccache.log
+ displayName: "start sccache"
+ condition: eq( variables['Agent.OS'], 'Windows_NT' )
+ env:
+ SCCACHE_DIR: $(Pipeline.Workspace)/.sccache
+ - task: CacheBeta@0
+ inputs:
+ key: sccache | $(Agent.OS) | Cargo.lock
+ path: $(Pipeline.Workspace)/.sccache
+ displayName: Cache Cargo Target
+ condition: eq( variables['Agent.OS'], 'Windows_NT' )
diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index 2bd08d330..000000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,442 +0,0 @@
-run_with_build_env_vars: &run_with_build_env_vars
- environment:
- LLVM_SYS_80_PREFIX: /home/circleci/project/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04/
-
-run_install_dependencies: &run_install_dependencies
- run:
- name: install dependencies
- command: |
- sudo apt-get install -y cmake
- curl -O https://releases.llvm.org/8.0.0/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz
- tar xf clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz
-
-version: 2
-jobs:
- changelog:
- docker:
- - image: docker:stable-git
- steps:
- - checkout
- - run:
- command: ! git diff --exit-code CHANGELOG.md
-
- # Job used for testing
- lint:
- docker:
- - image: circleci/rust:latest
- <<: *run_with_build_env_vars
- steps:
- - checkout
- - run:
- name: "Pull Submodules"
- command: |
- git submodule update --init
- - restore_cache:
- keys:
- - v8-lint-{{ arch }}-{{ checksum "Cargo.lock" }}
- - <<: *run_install_dependencies
- - run:
- name: Install lint deps
- command: |
- git config --global --unset url."ssh://git@github.com".insteadOf || true
- # rustup toolchain install nightly-2019-06-10
- # rustup default nightly-2019-06-10
- rustup component add rustfmt
- rustup component add clippy || cargo install --git https://github.com/rust-lang/rust-clippy/ --force clippy
- - run:
- name: Execute lints
- command: |
- cargo fmt --all -- --check
- - save_cache:
- paths:
- - /usr/local/cargo/registry
- - target/debug/.fingerprint
- - target/debug/build
- - target/debug/deps
- key: v8-lint-{{ arch }}-{{ checksum "Cargo.lock" }}
-
- test-stable:
- docker:
- - image: circleci/rust:1.36
- <<: *run_with_build_env_vars
- steps:
- - checkout
- - run:
- name: "Pull Submodules"
- command: |
- git submodule update --init
- - restore_cache:
- keys:
- - v8-test-cargo-cache-linux-stable-{{ arch }}-{{ checksum "Cargo.lock" }}
- - <<: *run_install_dependencies
- - run:
- name: Test everything (except singlepass)
- command: |
- make cranelift
- make llvm
- make test-rest
- - run:
- name: Integration Tests
- command: make integration-tests
- - save_cache:
- paths:
- - /usr/local/cargo/registry
- - target/release/.fingerprint
- - target/release/build
- - target/release/deps
- key: v8-test-cargo-cache-linux-stable-{{ arch }}-{{ checksum "Cargo.lock" }}
-
- test:
- docker:
- - image: circleci/rust:latest
- <<: *run_with_build_env_vars
- steps:
- - checkout
- - run:
- name: "Pull Submodules"
- command: |
- git submodule update --init
- - restore_cache:
- keys:
- - v8-test-cargo-cache-linux-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}
- - <<: *run_install_dependencies
- - run: rustup default nightly-2019-06-10
- - run:
- name: Tests
- command: make test
- - run:
- name: Debug flag checked
- command: |
- cargo check --features "debug" --release
- - run:
- name: Check
- command: |
- make check
- make compile-bench-singlepass
- make compile-bench-llvm
- # TODO: add compile-bench-clif when it works
- - run:
- name: Integration Tests
- command: make integration-tests
- - save_cache:
- paths:
- - /usr/local/cargo/registry
- - target/release/.fingerprint
- - target/release/build
- - target/release/deps
- key: v8-test-cargo-cache-linux-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}
-
- test-rust-example:
- docker:
- - image: circleci/rust:latest
- <<: *run_with_build_env_vars
- steps:
- - checkout
- - run:
- name: "Check Wasmer Rust example"
- command: |
- git clone https://github.com/wasmerio/wasmer-rust-example
- rustup default stable
- rustup target add wasm32-unknown-unknown
- cd wasmer-rust-example
- cd wasm-sample-app
- cargo build --release
- cd ..
- sed -i 's/wasmer-runtime.*/wasmer-runtime = \{ path = "..\/lib\/runtime" \}/g' Cargo.toml
- cargo run
- cargo test
-
- test-macos:
- macos:
- xcode: "9.0"
- steps:
- - checkout
- - run:
- name: "Pull Submodules"
- command: |
- git submodule update --init
- - restore_cache:
- keys:
- - v8-cargo-cache-darwin-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}
- - run:
- name: Install crate dependencies
- command: |
- # Installing cmake outside of brew to improve speed
- curl -O https://cmake.org/files/v3.4/cmake-3.4.1-Darwin-x86_64.tar.gz
- tar xf cmake-3.4.1-Darwin-x86_64.tar.gz
- export PATH="`pwd`/cmake-3.4.1-Darwin-x86_64/CMake.app/Contents/bin:$PATH"
- # Installing LLVM outside of brew
- curl -O https://releases.llvm.org/8.0.0/clang+llvm-8.0.0-x86_64-apple-darwin.tar.xz
- tar xf clang+llvm-8.0.0-x86_64-apple-darwin.tar.xz
- - run:
- name: Install Rust
- command: |
- curl -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain nightly-2019-06-10
- export PATH="$HOME/.cargo/bin:$PATH"
- cargo --version
- - run:
- name: Tests
- command: |
- export PATH="$HOME/.cargo/bin:$PATH"
- export PATH="`pwd`/cmake-3.4.1-Darwin-x86_64/CMake.app/Contents/bin:$PATH"
- export LLVM_SYS_80_PREFIX="`pwd`/clang+llvm-8.0.0-x86_64-apple-darwin/"
- # We increase the ulimit for fixing cargo unclosed files in mac
- ulimit -n 8000
- sudo sysctl -w kern.maxfiles=655360 kern.maxfilesperproc=327680
- make test
- - run:
- name: Check
- command: |
- export PATH="$HOME/.cargo/bin:$PATH"
- export LLVM_SYS_80_PREFIX="`pwd`/clang+llvm-8.0.0-x86_64-apple-darwin/"
- make check
- - run:
- name: Integration Tests
- command: |
- export PATH="$HOME/.cargo/bin:$PATH"
- export PATH="`pwd`/cmake-3.4.1-Darwin-x86_64/CMake.app/Contents/bin:$PATH"
- export LLVM_SYS_80_PREFIX="`pwd`/clang+llvm-8.0.0-x86_64-apple-darwin/"
- make integration-tests
- - save_cache:
- paths:
- - ~/.cargo/registry/
- - target/release/.fingerprint
- - target/release/build
- - target/release/deps
- key: v8-cargo-cache-darwin-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}
-
- test-and-build:
- docker:
- - image: circleci/rust:latest
- steps:
- - checkout
- - run:
- name: "Pull Submodules"
- command: |
- git submodule update --init
- - run:
- name: "Pull dependencies"
- command: |
- git submodule init
- git submodule update
- - restore_cache:
- keys:
- - v8-cargo-cache-linux-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}
- - run:
- name: Install dependencies
- command: |
- sudo apt-get install -y cmake
- curl -O https://releases.llvm.org/8.0.0/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz
- tar xf clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz
- - run: rustup default nightly-2019-06-10
- - run:
- name: Tests
- command: |
- export LLVM_SYS_80_PREFIX="`pwd`/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04/"
- make test
- - run:
- name: Release Build
- command: |
- export LLVM_SYS_80_PREFIX="`pwd`/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04/"
- make release
- cargo build --release --manifest-path wapm-cli/Cargo.toml --features "telemetry update-notifications"
- mkdir -p artifacts
- VERSION=$(cargo pkgid | cut -d# -f2 | cut -d: -f2)
- # GIT_VERSION=$(git describe --exact-match --tags)
- echo "${VERSION}" >> artifacts/version
- echo "${CIRCLE_TAG}" >> artifacts/git_version
- make build-install
- cp ./wasmer.tar.gz ./artifacts/$(./scripts/binary-name.sh)
- - run:
- name: Dynamic library
- command: |
- cargo build --release --manifest-path lib/runtime-c-api/Cargo.toml
- cp target/release/libwasmer_runtime_c_api.so ./artifacts
- - persist_to_workspace:
- root: .
- paths:
- - artifacts
- - save_cache:
- paths:
- - /usr/local/cargo/registry
- - target/release/.fingerprint
- - target/release/build
- - target/release/deps
- - wapm-cli/target/release/.fingerprint
- - wapm-cli/target/release/build
- - wapm-cli/target/release/deps
- key: v8-cargo-cache-linux-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}
-
- test-and-build-macos:
- macos:
- xcode: "9.0"
- steps:
- - checkout
- - run:
- name: "Pull dependencies"
- command: |
- git submodule init
- git submodule update
- - restore_cache:
- keys:
- - v8-cargo-cache-darwin-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}
- - run:
- name: Install crate dependencies
- command: |
- # Installing cmake outside of brew to improve speed
- curl -O https://cmake.org/files/v3.4/cmake-3.4.1-Darwin-x86_64.tar.gz
- tar xf cmake-3.4.1-Darwin-x86_64.tar.gz
- export PATH="`pwd`/cmake-3.4.1-Darwin-x86_64/CMake.app/Contents/bin:$PATH"
- # Installing LLVM outside of brew
- curl -O https://releases.llvm.org/8.0.0/clang+llvm-8.0.0-x86_64-apple-darwin.tar.xz
- tar xf clang+llvm-8.0.0-x86_64-apple-darwin.tar.xz
- - run:
- name: Install Rust
- command: |
- curl -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain nightly-2019-06-10
- export PATH="$HOME/.cargo/bin:$PATH"
- cargo --version
- - run:
- name: Tests
- command: |
- export PATH="`pwd`/cmake-3.4.1-Darwin-x86_64/CMake.app/Contents/bin:$PATH"
- export PATH="$HOME/.cargo/bin:$PATH"
- export LLVM_SYS_80_PREFIX="`pwd`/clang+llvm-8.0.0-x86_64-apple-darwin/"
- # We increase the ulimit for fixing cargo unclosed files in mac
- ulimit -n 8000
- sudo sysctl -w kern.maxfiles=655360 kern.maxfilesperproc=327680
-
- make test
- - run:
- name: Release Build
- command: |
- export PATH="`pwd`/cmake-3.4.1-Darwin-x86_64/CMake.app/Contents/bin:$PATH"
- export PATH="$HOME/.cargo/bin:$PATH"
- export LLVM_SYS_80_PREFIX="`pwd`/clang+llvm-8.0.0-x86_64-apple-darwin/"
- make release
- cargo build --release --manifest-path wapm-cli/Cargo.toml --features "telemetry update-notifications"
- mkdir -p artifacts
- make build-install
- cp ./wasmer.tar.gz ./artifacts/$(./scripts/binary-name.sh)
- # VERSION=$(cargo pkgid | cut -d# -f2 | cut -d: -f2)
- # echo "${VERSION}" >> artifacts/version
- - run:
- name: Generate dynamic library for the runtime C API
- command: |
- export PATH="$HOME/.cargo/bin:$PATH"
- cargo build --release --manifest-path lib/runtime-c-api/Cargo.toml
- install_name_tool -id "@rpath/libwasmer_runtime_c_api.dylib" target/release/libwasmer_runtime_c_api.dylib
- cp target/release/libwasmer_runtime_c_api.dylib ./artifacts
- - persist_to_workspace:
- root: .
- paths:
- - artifacts
- - save_cache:
- paths:
- - ~/.cargo/registry/
- - target/release/.fingerprint
- - target/release/build
- - target/release/deps
- - wapm-cli/target/release/.fingerprint
- - wapm-cli/target/release/build
- - wapm-cli/target/release/deps
- key: v8-cargo-cache-darwin-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}
-
- publish-github-release:
- docker:
- - image: cibuilds/github
- steps:
- - attach_workspace:
- at: .
- - run:
- name: "Publish Release on GitHub"
- command: |
- # go get github.com/tcnksm/ghr
- # VERSION=$(git log -1 --pretty=%B)
- # VERSION=$(./artifacts/ --version)
- VERSION=$(cat ./artifacts/version)
- # VERSION_TAG=${CIRCLE_TAG}
- VERSION_TAG=$(cat ./artifacts/git_version)
- LATEST_VERSION_PUBLISHED_ON_CRATES=$(curl -s https://raw.githubusercontent.com/rust-lang/crates.io-index/master/wa/sm/wasmer-runtime | tail -n 1 | sed 's/.*"vers":"\([^"]*\)".*/\1/')
- if ( [ $VERSION_TAG -ne $LATEST_VERSION_PUBLISHED_ON_CRATES ] ) then { echo "Could not detect version published to crates.io; make sure we've published the crates before publishing the Wasmer binary"; exit 1; } else { true; } fi
- rm ./artifacts/version
- rm ./artifacts/git_version
- # VERSION_TAG=$(git describe --exact-match --tags)
- #if [ "$VERSION" == "$VERSION_TAG" ]; then
- # echo "Versions match, publishing to Github"
- ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} ${VERSION} ./artifacts/ || true
- #else
- # echo "Versions don't match. Wasmer output version (wasmer --version) is ${VERSION} while Git tag is ${VERSION_TAG}"
- # exit 1
- #fi
- trigger-benchmark-build:
- docker:
- - image: circleci/rust:latest
- steps:
- - run:
- name: "Trigger Benchmark Build"
- command: |
- if [[ -z "${CIRCLE_API_USER_TOKEN}" ]]; then
- echo "CIRCLE_API_USER_TOKEN environment variable not set"
- exit 1
- else
- echo "Triggering benchmark build"
- curl -u ${CIRCLE_API_USER_TOKEN} \
- -d build_parameters[CIRCLE_JOB]=bench \
- https://circleci.com/api/v1.1/project/github/wasmerio/wasmer-bench/tree/master
- fi
-workflows:
- version: 2
- main:
- jobs:
- - changelog
- - lint
- - test:
- filters:
- branches:
- only:
- - trying
- - staging
- - test-rust-example:
- filters:
- branches:
- only:
- - trying
- - staging
- - test-macos:
- filters:
- branches:
- only:
- - trying
- - staging
- - test-and-build:
- filters:
- branches:
- only:
- - master
- - test-and-build-macos:
- filters:
- branches:
- only:
- - master
- - test-stable:
- filters:
- branches:
- only:
- - trying
- - staging
- - publish-github-release:
- requires:
- - lint
- - test-and-build
- - test-and-build-macos
- filters:
- branches:
- only: master
- - trigger-benchmark-build:
- requires:
- - test-and-build
- - lint
- filters:
- branches:
- only: master
diff --git a/.dockerignore b/.dockerignore
index e861ea7b6..29fd6ce6b 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -2,5 +2,6 @@
**
!lib/**
!src/**
+!examples/**
!Cargo.toml
!Cargo.lock
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
index 3426f1dee..4cc803e80 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,2 +1,3 @@
lib/emscripten/emtests/* linguist-vendored
lib/spectests/spectests/* linguist-vendored
+CHANGELOG.md merge=union
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index f10837c34..847de4fd8 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -8,7 +8,6 @@ lib/llvm-backend @nlewycky @losfair
# Runtime
lib/runtime-core @Hywan @bjfish
-lib/runtime-abi @MarkMcCaskey
lib/runtime @MarkMcCaskey @Hywan @bjfish
lib/runtime-c-api @bjfish @Hywan
lib/win-exception-handler @bjfish @losfair
diff --git a/.github/ISSUE_TEMPLATE/---bug-report.md b/.github/ISSUE_TEMPLATE/---bug-report.md
index 7a7e83e12..470f5ea9b 100644
--- a/.github/ISSUE_TEMPLATE/---bug-report.md
+++ b/.github/ISSUE_TEMPLATE/---bug-report.md
@@ -7,37 +7,44 @@ assignees: ''
---
-Thanks for the bug report!
+
### Describe the bug
+
-```bash
+```sh
echo "`wasmer -V` | `rustc -V` | `uname -m`"
```
-### Steps to reproduce
+### Steps to reproduce
+
### Expected behavior
-
-A clear and concise description of what you expected to happen.
+
### Actual behavior
+
### Additional context
-
-Add any other context about the problem here.
+
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 000000000..b29669d33
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,15 @@
+
+
+# Description
+
+
+# Review
+
+- [ ] Add a short description of the the change to the CHANGELOG.md file
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 000000000..4dbbd44d8
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,65 @@
+arch:
+ - arm64
+
+language: rust
+rust:
+ - nightly-2019-08-15
+
+cache:
+ directories:
+ - /home/travis/.sccache/
+ - /home/travis/.cargo/bin/
+
+script:
+ # Sccache
+ # - curl -L https://github.com/mozilla/sccache/releases/download/0.2.10/sccache-0.2.10-x86_64-unknown-linux-musl.tar.gz | tar xzf -
+ # - export RUSTC_WRAPPER=`pwd`/sccache-0.2.10-x86_64-unknown-linux-musl/sccache
+ - test -f /home/travis/.cargo/bin/sccache || cargo install sccache
+ - export RUSTC_WRAPPER=/home/travis/.cargo/bin/sccache
+ - mkdir -p /home/travis/.sccache/
+ - export SCCACHE_DIR="/home/travis/.sccache/"
+ - SCCACHE_ERROR_LOG=`pwd`/sccache.log RUST_LOG=debug $RUSTC_WRAPPER --start-server
+ - $RUSTC_WRAPPER -s
+
+ # Tests
+ - make spectests-singlepass
+
+before_deploy:
+ # Release
+ - make release-singlepass
+ - make wapm
+ - make build-install
+ - mkdir -p artifacts
+ - cp ./wasmer.tar.gz ./artifacts/$(./scripts/binary-name.sh)
+
+# before_deploy:
+# # Set up git user name and tag this commit
+# - git config --local user.name "Syrus Akbary"
+# - git config --local user.email "syrus@wasmer.io"
+# - export TRAVIS_TAG="0.10.2"
+# # - git tag $TRAVIS_TAG
+
+deploy:
+ provider: releases
+ file_glob: true
+ file: artifacts/*
+ api_key: $GITHUB_OAUTH_TOKEN
+ # This is set to the previous artifacts are not deleted by travis
+ skip_cleanup: true
+ on:
+ tags: true
+ # branch: feature/singlepass-aarch64
+
+addons:
+ apt:
+ packages:
+ - cmake
+
+branches:
+ only:
+ - master
+ - staging
+ - trying
+ # Making sure Travis runs on new Tags
+ - /^\d+\.\d+(\.\d+)?(-\S*)?$/
+ - /^v\d+\.\d+(\.\d+)?(-\S*)?$/
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 62aa45ac7..4b5b8a80a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,13 +1,113 @@
# Changelog
-All PRs to the Wasmer repository must add to this file.
-
-Blocks of changes will separated by version increments.
-
## **[Unreleased]**
+- [#1029](https://github.com/wasmerio/wasmer/pull/1029) Add the “floating” `WasiVersion::Latest` version.
+- [#1006](https://github.com/wasmerio/wasmer/pull/1006) Fix minor panic issue when `wasmer::compile_with` called with llvm backend
+- [#1009](https://github.com/wasmerio/wasmer/pull/1009) Enable LLVM verifier for all tests, add new llvm-backend-tests crate.
+- [#1022](https://github.com/wasmerio/wasmer/pull/1022) Add caching support for Singlepass backend.
+- [#1004](https://github.com/wasmerio/wasmer/pull/1004) Add the Auto backend to enable to adapt backend usage depending on wasm file executed.
+
+## 0.11.0 - 2019-11-22
+
+- [#713](https://github.com/wasmerio/wasmer/pull/713) Add AArch64 support for singlepass.
+- [#995](https://github.com/wasmerio/wasmer/pull/995) Detect when a global is read without being initialized (emit a proper error instead of panicking)
+- [#996](https://github.com/wasmerio/wasmer/pull/997) Refactored spectests, emtests and wasitests to use default compiler logic
+- [#992](https://github.com/wasmerio/wasmer/pull/992) Updates WAPM version to 0.4.1, fix arguments issue introduced in #990
+- [#990](https://github.com/wasmerio/wasmer/pull/990) Default wasmer CLI to `run`. Wasmer will now attempt to parse unrecognized command line options as if they were applied to the run command: `wasmer mywasm.wasm --dir=.` now works!
+- [#987](https://github.com/wasmerio/wasmer/pull/987) Fix `runtime-c-api` header files when compiled by gnuc.
+- [#957](https://github.com/wasmerio/wasmer/pull/957) Change the meaning of `wasmer_wasi::is_wasi_module` to detect any type of WASI module, add support for new wasi snapshot_preview1
+- [#934](https://github.com/wasmerio/wasmer/pull/934) Simplify float expressions in the LLVM backend.
+
+## 0.10.2 - 2019-11-18
+
+- [#968](https://github.com/wasmerio/wasmer/pull/968) Added `--invoke` option to the command
+- [#964](https://github.com/wasmerio/wasmer/pull/964) Enable cross-compilation for specific target
+- [#971](https://github.com/wasmerio/wasmer/pull/971) In LLVM backend, use unaligned loads and stores for non-atomic accesses to wasmer memory.
+- [#960](https://github.com/wasmerio/wasmer/pull/960) Fix `runtime-c-api` header files when compiled by clang.
+- [#925](https://github.com/wasmerio/wasmer/pull/925) Host functions can be closures with a captured environment.
+- [#917](https://github.com/wasmerio/wasmer/pull/917) Host functions (aka imported functions) may not have `&mut vm::Ctx` as first argument, i.e. the presence of the `&mut vm::Ctx` argument is optional.
+- [#915](https://github.com/wasmerio/wasmer/pull/915) All backends share the same definition of `Trampoline` (defined in `wasmer-runtime-core`).
+
+## 0.10.1 - 2019-11-11
+
+- [#952](https://github.com/wasmerio/wasmer/pull/952) Use C preprocessor to properly hide trampoline functions on Windows and non-x86_64 targets.
+
+## 0.10.0 - 2019-11-11
+
+Special thanks to [@newpavlov](https://github.com/newpavlov) and [@Maxgy](https://github.com/Maxgy) for their contributions!
+
+- [#942](https://github.com/wasmerio/wasmer/pull/942) Deny missing docs in runtime core and add missing docs
+- [#939](https://github.com/wasmerio/wasmer/pull/939) Fix bug causing attempts to append to files with WASI to delete the contents of the file
+- [#940](https://github.com/wasmerio/wasmer/pull/940) Update supported Rust version to 1.38+
+- [#923](https://github.com/wasmerio/wasmer/pull/923) Fix memory leak in the C API caused by an incorrect cast in `wasmer_trampoline_buffer_destroy`
+- [#921](https://github.com/wasmerio/wasmer/pull/921) In LLVM backend, annotate all memory accesses with TBAA metadata.
+- [#883](https://github.com/wasmerio/wasmer/pull/883) Allow floating point operations to have arbitrary inputs, even including SNaNs.
+- [#856](https://github.com/wasmerio/wasmer/pull/856) Expose methods in the runtime C API to get a WASI import object
+
+## 0.9.0 - 2019-10-23
+
+Special thanks to @alocquet for their contributions!
+
+- [#898](https://github.com/wasmerio/wasmer/pull/898) State tracking is now disabled by default in the LLVM backend. It can be enabled with `--track-state`.
+- [#861](https://github.com/wasmerio/wasmer/pull/861) Add descriptions to `unimplemented!` macro in various places
+- [#897](https://github.com/wasmerio/wasmer/pull/897) Removes special casing of stdin, stdout, and stderr in WASI. Closing these files now works. Removes `stdin`, `stdout`, and `stderr` from `WasiFS`, replaced by the methods `stdout`, `stdout_mut`, and so on.
+- [#863](https://github.com/wasmerio/wasmer/pull/863) Fix min and max for cases involving NaN and negative zero when using the LLVM backend.
+
+## 0.8.0 - 2019-10-02
+
+Special thanks to @jdanford for their contributions!
+
+- [#850](https://github.com/wasmerio/wasmer/pull/850) New `WasiStateBuilder` API. small, add misc. breaking changes to existing API (for example, changing the preopen dirs arg on `wasi::generate_import_object` from `Vec` to `Vec`)
+- [#852](https://github.com/wasmerio/wasmer/pull/852) Make minor grammar/capitalization fixes to README.md
+- [#841](https://github.com/wasmerio/wasmer/pull/841) Slightly improve rustdoc documentation and small updates to outdated info in readme files
+- [#836](https://github.com/wasmerio/wasmer/pull/836) Update Cranelift fork version to `0.44.0`
+- [#839](https://github.com/wasmerio/wasmer/pull/839) Change supported version to stable Rust 1.37+
+- [#834](https://github.com/wasmerio/wasmer/pull/834) Fix panic when unwraping `wasmer` arguments
+- [#835](https://github.com/wasmerio/wasmer/pull/835) Add parallel execution example (independent instances created from the same `ImportObject` and `Module` run with rayon)
+- [#834](https://github.com/wasmerio/wasmer/pull/834) Fix panic when parsing numerical arguments for no-ABI targets run with the wasmer binary
+- [#833](https://github.com/wasmerio/wasmer/pull/833) Add doc example of using ImportObject's new `maybe_with_namespace` method
+- [#832](https://github.com/wasmerio/wasmer/pull/832) Delete unused runtime ABI
+- [#809](https://github.com/wasmerio/wasmer/pull/809) Fix bugs leading to panics in `LocalBacking`.
+- [#831](https://github.com/wasmerio/wasmer/pull/831) Add support for atomic operations, excluding wait and notify, to singlepass.
+- [#822](https://github.com/wasmerio/wasmer/pull/822) Update Cranelift fork version to `0.43.1`
+- [#829](https://github.com/wasmerio/wasmer/pull/829) Fix deps on `make bench-*` commands; benchmarks don't compile other backends now
+- [#807](https://github.com/wasmerio/wasmer/pull/807) Implement Send for `Instance`, breaking change on `ImportObject`, remove method `get_namespace` replaced with `with_namespace` and `maybe_with_namespace`
+- [#817](https://github.com/wasmerio/wasmer/pull/817) Add document for tracking features across backends and language integrations, [docs/feature_matrix.md]
+- [#823](https://github.com/wasmerio/wasmer/issues/823) Improved Emscripten / WASI integration
+- [#821](https://github.com/wasmerio/wasmer/issues/821) Remove patch version on most deps Cargo manifests. This gives Wasmer library users more control over which versions of the deps they use.
+- [#820](https://github.com/wasmerio/wasmer/issues/820) Remove null-pointer checks in `WasmPtr` from runtime-core, re-add them in Emscripten
+- [#803](https://github.com/wasmerio/wasmer/issues/803) Add method to `Ctx` to invoke functions by their `TableIndex`
+- [#790](https://github.com/wasmerio/wasmer/pull/790) Fix flaky test failure with LLVM, switch to large code model.
+- [#788](https://github.com/wasmerio/wasmer/pull/788) Use union merge on the changelog file.
+- [#785](https://github.com/wasmerio/wasmer/pull/785) Include Apache license file for spectests.
+- [#786](https://github.com/wasmerio/wasmer/pull/786) In the LLVM backend, lower atomic wasm operations to atomic machine instructions.
+- [#784](https://github.com/wasmerio/wasmer/pull/784) Fix help string for wasmer run.
+
+## 0.7.0 - 2019-09-12
+
Special thanks to @YaronWittenstein @penberg for their contributions.
+- [#776](https://github.com/wasmerio/wasmer/issues/776) Allow WASI preopened fds to be closed
+- [#774](https://github.com/wasmerio/wasmer/issues/774) Add more methods to the `WasiFile` trait
+- [#772](https://github.com/wasmerio/wasmer/issues/772) [#770](https://github.com/wasmerio/wasmer/issues/770) Handle more internal failures by passing back errors
+- [#756](https://github.com/wasmerio/wasmer/issues/756) Allow NULL parameter and 0 arity in `wasmer_export_func_call` C API
+- [#747](https://github.com/wasmerio/wasmer/issues/747) Return error instead of panicking on traps when using the Wasmer binary
+- [#741](https://github.com/wasmerio/wasmer/issues/741) Add validate Wasm fuzz target
+- [#733](https://github.com/wasmerio/wasmer/issues/733) Remove dependency on compiler backends for `middleware-common`
+- [#732](https://github.com/wasmerio/wasmer/issues/732) [#731](https://github.com/wasmerio/wasmer/issues/731) WASI bug fixes and improvements
+- [#726](https://github.com/wasmerio/wasmer/issues/726) Add serialization and deserialization for Wasi State
+- [#716](https://github.com/wasmerio/wasmer/issues/716) Improve portability of install script
+- [#714](https://github.com/wasmerio/wasmer/issues/714) Add Code of Conduct
+- [#708](https://github.com/wasmerio/wasmer/issues/708) Remove unconditional dependency on Cranelift in the C API
+- [#703](https://github.com/wasmerio/wasmer/issues/703) Fix compilation on AArch64 Linux
+- [#702](https://github.com/wasmerio/wasmer/issues/702) Add SharedMemory to Wasmer. Add `--enable-threads` flag, add partial implementation of atomics to LLVM backend.
+- [#698](https://github.com/wasmerio/wasmer/issues/698) [#690](https://github.com/wasmerio/wasmer/issues/690) [#687](https://github.com/wasmerio/wasmer/issues/690) Fix panics in Emscripten
+- [#689](https://github.com/wasmerio/wasmer/issues/689) Replace `wasmer_runtime_code::memory::Atomic` with `std::sync::atomic` atomics, changing its interface
+- [#680](https://github.com/wasmerio/wasmer/issues/680) [#673](https://github.com/wasmerio/wasmer/issues/673) [#669](https://github.com/wasmerio/wasmer/issues/669) [#660](https://github.com/wasmerio/wasmer/issues/660) [#659](https://github.com/wasmerio/wasmer/issues/659) Misc. runtime and singlepass fixes
+- [#677](https://github.com/wasmerio/wasmer/issues/677) [#675](https://github.com/wasmerio/wasmer/issues/675) [#674](https://github.com/wasmerio/wasmer/issues/674) LLVM backend fixes and improvements
+- [#671](https://github.com/wasmerio/wasmer/issues/671) Implement fs polling in `wasi::poll_oneoff` for Unix-like platforms
+- [#656](https://github.com/wasmerio/wasmer/issues/656) Move CI to Azure Pipelines
- [#650](https://github.com/wasmerio/wasmer/issues/650) Implement `wasi::path_rename`, improve WASI FS public api, and allow open files to exist even when the underlying file is deleted
- [#643](https://github.com/wasmerio/wasmer/issues/643) Implement `wasi::path_symlink` and improve WASI FS public api IO error reporting
- [#608](https://github.com/wasmerio/wasmer/issues/608) Implement wasi syscalls `fd_allocate`, `fd_sync`, `fd_pread`, `path_link`, `path_filestat_set_times`; update WASI fs API in a WIP way; reduce coupling of WASI code to host filesystem; make debug messages from WASI more readable; improve rights-checking when calling syscalls; implement reference counting on inodes; misc bug fixes and improvements
@@ -81,7 +181,7 @@ Special thanks to @YaronWittenstein @penberg for their contributions.
- [#493](https://github.com/wasmerio/wasmer/pull/493) `wasmer_module_instantiate` has better error messages in the runtime C API
- [#474](https://github.com/wasmerio/wasmer/pull/474) Set the install name of the dylib to `@rpath`
- [#490](https://github.com/wasmerio/wasmer/pull/490) Add MiddlewareChain and StreamingCompiler to runtime
-- [#487](https://github.com/wasmerio/wasmer/pull/487) Fix stack offset check in singlepass backend
+- [#487](https://github.com/wasmerio/wasmer/pull/487) Fix stack offset check in singlepass backend
- [#450](https://github.com/wasmerio/wasmer/pull/450) Added Metering
- [#481](https://github.com/wasmerio/wasmer/pull/481) Added context trampoline into runtime
- [#484](https://github.com/wasmerio/wasmer/pull/484) Fix bugs in emscripten socket syscalls
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1c2f0d31e..1685f4722 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -3,12 +3,15 @@
Thank you for your interest in contributing to Wasmer. This document outlines some recommendations on how to contribute.
## Issues & Feature Requests
+
Please use the issue template and provide a failing example if possible to help us recreate the issue.
## Pull Requests
-For large changes, please try reaching the Wasmer using Github Issues or Spectrum Chat to ensure we can accept the change once it is ready.
+
+For large changes, please try reaching communicating with the Wasmer maintainers via GitHub Issues or Spectrum Chat to ensure we can accept the change once it is ready.
We recommend trying the following commands before sending a pull request to ensure code quality:
+
- `cargo fmt --all` Ensures all code is correctly formatted.
- Run `cargo test` in the crates that you are modifying.
- Run `cargo build --all` (nightly) or `cargo build --all --exclude wasmer-singlepass-backend`
@@ -17,17 +20,14 @@ A comprehensive CI test suite will be run by a Wasmer team member after the PR h
### Common Build Issues
-**LLVM Dependency**
+#### LLVM Dependency
-The LLVM backend requires LLVM to be installed to compile.
+`Didn't find usable system-wide LLVM`
-So, you may run into the following error:
-```
-Didn't find usable system-wide LLVM.
-No suitable version of LLVM was found system-wide or pointed
-```
+Building Wasmer with the LLVM backend requires LLVM to be installed
-**Singlepass Nightly Only**
+#### Singlepass Nightly Only
-The singlepass crate depends on nightly so you may need to add the `+nightly` cargo flag to compile this crate.
`error[E0554]: #![feature] may not be used on the stable release channel`
+
+Building Wasmer with the singlepass backend requires the nightly version of Rust
diff --git a/Cargo.lock b/Cargo.lock
index d2888b979..bbdc62b68 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,5 +1,10 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
+[[package]]
+name = "adler32"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "aho-corasick"
version = "0.7.6"
@@ -13,14 +18,9 @@ name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
-[[package]]
-name = "approx"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
[[package]]
name = "arrayref"
version = "0.3.5"
@@ -40,7 +40,7 @@ version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -68,9 +68,17 @@ dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "base64"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "bincode"
-version = "1.1.4"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -78,28 +86,6 @@ dependencies = [
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
]
-[[package]]
-name = "bindgen"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cexpr 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "bitflags"
version = "1.1.0"
@@ -131,6 +117,16 @@ name = "byteorder"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "bytes"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "c2-chacha"
version = "0.2.2"
@@ -140,30 +136,14 @@ dependencies = [
"ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
-[[package]]
-name = "capstone"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "capstone-sys 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "capstone-sys"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "cargo_toml"
-version = "0.6.4"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -192,39 +172,11 @@ name = "cc"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-[[package]]
-name = "cexpr"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "cfg-if"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-[[package]]
-name = "cgmath"
-version = "0.16.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "clang-sys"
-version = "0.28.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
- "libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "clap"
version = "2.33.0"
@@ -255,63 +207,110 @@ dependencies = [
"cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
-[[package]]
-name = "colored"
-version = "1.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "winconsole 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "constant_time_eq"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "cranelift-bforest"
-version = "0.31.0"
+name = "cookie"
+version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cranelift-entity 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "cookie_store"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "publicsuffix 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "core-foundation"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "cranelift-bforest"
+version = "0.44.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cranelift-entity 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cranelift-codegen"
-version = "0.31.0"
+version = "0.44.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cranelift-bforest 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cranelift-codegen-meta 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cranelift-entity 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-bforest 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-codegen-meta 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-codegen-shared 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-entity 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cranelift-codegen-meta"
-version = "0.31.0"
+version = "0.44.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cranelift-entity 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-codegen-shared 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-entity 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "cranelift-codegen-shared"
+version = "0.44.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "cranelift-entity"
-version = "0.31.0"
+version = "0.44.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cranelift-native"
-version = "0.31.0"
+version = "0.44.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cranelift-codegen 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-codegen 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
"raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "crc32fast"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -331,8 +330,8 @@ dependencies = [
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -352,21 +351,21 @@ dependencies = [
[[package]]
name = "crossbeam-deque"
-version = "0.6.3"
+version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-epoch"
-version = "0.7.2"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -380,6 +379,14 @@ dependencies = [
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "crossbeam-queue"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "crossbeam-utils"
version = "0.6.6"
@@ -389,6 +396,16 @@ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "crossbeam-utils"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "csv"
version = "1.1.1"
@@ -409,6 +426,15 @@ dependencies = [
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "ctor"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "digest"
version = "0.8.1"
@@ -417,28 +443,32 @@ dependencies = [
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "dtoa"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "dynasm"
-version = "0.3.2"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
+ "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dynasmrt"
-version = "0.3.1"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -447,24 +477,19 @@ version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "enum-methods"
-version = "0.0.8"
+name = "encoding_rs"
+version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "env_logger"
-version = "0.6.2"
+name = "erased-serde"
+version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -474,7 +499,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -486,6 +511,15 @@ dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "error-chain"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "failure"
version = "0.1.5"
@@ -507,7 +541,31 @@ dependencies = [
]
[[package]]
-name = "field-offset"
+name = "flate2"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
+ "miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "foreign-types"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -517,11 +575,31 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "fxhash"
-version = "0.2.1"
+name = "fuchsia-zircon"
+version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "fuchsia-zircon-sys"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "futures"
+version = "0.1.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "futures-cpupool"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -544,6 +622,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -564,6 +643,16 @@ dependencies = [
"wasi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "ghost"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "glob"
version = "0.2.11"
@@ -584,6 +673,23 @@ dependencies = [
"scroll 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "h2"
+version = "0.1.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "heck"
version = "0.3.1"
@@ -598,46 +704,155 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "humantime"
-version = "1.2.0"
+name = "http"
+version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "http-body"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "httparse"
+version = "1.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "hyper"
+version = "0.12.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-threadpool 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "hyper-tls"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "idna"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "idna"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "indexmap"
-version = "1.1.0"
+version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
+ "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "inkwell"
version = "0.1.0"
-source = "git+https://github.com/wasmerio/inkwell?branch=llvm8-0#8c386c8eeccaea68681710e3822c40153a8030a3"
+source = "git+https://github.com/TheDan64/inkwell?rev=781620e9fa30e51a6e03bd0d49b5f5bb7a782520#781620e9fa30e51a6e03bd0d49b5f5bb7a782520"
dependencies = [
"either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "enum-methods 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "inkwell_internal_macros 0.1.0 (git+https://github.com/wasmerio/inkwell?branch=llvm8-0)",
- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "inkwell_internals 0.1.0 (git+https://github.com/TheDan64/inkwell?rev=781620e9fa30e51a6e03bd0d49b5f5bb7a782520)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"llvm-sys 80.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "inkwell_internal_macros"
+name = "inkwell_internals"
version = "0.1.0"
-source = "git+https://github.com/wasmerio/inkwell?branch=llvm8-0#8c386c8eeccaea68681710e3822c40153a8030a3"
+source = "git+https://github.com/TheDan64/inkwell?rev=781620e9fa30e51a6e03bd0d49b5f5bb7a782520#781620e9fa30e51a6e03bd0d49b5f5bb7a782520"
dependencies = [
- "cargo_toml 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cargo_toml 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "reqwest 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "inventory"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "ctor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ghost 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "inventory-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "inventory-impl"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "iovec"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "itertools"
version = "0.8.0"
@@ -679,15 +894,6 @@ name = "libc"
version = "0.2.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
-[[package]]
-name = "libloading"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "llvm-sys"
version = "80.1.1"
@@ -716,6 +922,16 @@ dependencies = [
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "matches"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "md5"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "memchr"
version = "2.2.1"
@@ -724,22 +940,13 @@ dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
]
-[[package]]
-name = "memmap"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "memmap"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -750,6 +957,20 @@ dependencies = [
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "mime"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "mime_guess"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "minifb"
version = "0.11.2"
@@ -765,6 +986,70 @@ dependencies = [
"x11-dl 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "miniz_oxide"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "mio"
+version = "0.6.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "miow"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "native-tls"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl 0.10.26 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)",
+ "schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "security-framework 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "security-framework-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "net2"
+version = "0.2.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "nix"
version = "0.15.0"
@@ -782,15 +1067,6 @@ name = "nodrop"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-[[package]]
-name = "nom"
-version = "4.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "num"
version = "0.1.42"
@@ -820,14 +1096,6 @@ dependencies = [
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
-[[package]]
-name = "num-traits"
-version = "0.1.43"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "num-traits"
version = "0.2.8"
@@ -844,6 +1112,41 @@ dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "once_cell"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "openssl"
+version = "0.10.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "openssl-probe"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "openssl-sys"
+version = "0.9.53"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "orbclient"
version = "0.3.27"
@@ -855,7 +1158,7 @@ dependencies = [
[[package]]
name = "owning_ref"
-version = "0.3.3"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -871,6 +1174,24 @@ dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "parallel"
+version = "0.1.0"
+dependencies = [
+ "rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasmer-runtime 0.11.0",
+ "wasmer-runtime-core 0.11.0",
+]
+
+[[package]]
+name = "parallel-guest"
+version = "0.1.0"
+dependencies = [
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "md5 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "parking_lot"
version = "0.9.0"
@@ -892,12 +1213,17 @@ dependencies = [
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "peeking_take_while"
-version = "0.1.2"
+name = "percent-encoding"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "percent-encoding"
+version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -919,6 +1245,16 @@ name = "ppv-lite86"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "proc-macro-error"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "proc-macro2"
version = "0.4.30"
@@ -936,14 +1272,16 @@ dependencies = [
]
[[package]]
-name = "quick-error"
-version = "1.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "quote"
-version = "0.3.15"
+name = "publicsuffix"
+version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
[[package]]
name = "quote"
@@ -961,18 +1299,6 @@ dependencies = [
"proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
-[[package]]
-name = "rand"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "rand"
version = "0.6.5"
@@ -988,7 +1314,7 @@ dependencies = [
"rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1073,7 +1399,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1086,7 +1412,7 @@ dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1127,22 +1453,22 @@ dependencies = [
[[package]]
name = "rayon"
-version = "1.1.0"
+version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rayon-core"
-version = "1.5.0"
+version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1194,13 +1520,41 @@ name = "remove_dir_all"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "rgb"
-version = "0.8.14"
+name = "reqwest"
+version = "0.9.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cookie_store 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flate2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-threadpool 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
[[package]]
name = "rustc-demangle"
@@ -1228,6 +1582,15 @@ dependencies = [
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "schannel"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "scopeguard"
version = "1.0.0"
@@ -1274,6 +1637,25 @@ dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "security-framework"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
+ "security-framework-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "security-framework-sys"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "semver"
version = "0.9.0"
@@ -1333,8 +1715,19 @@ dependencies = [
]
[[package]]
-name = "shlex"
-version = "0.1.1"
+name = "serde_urlencoded"
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "slab"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1342,11 +1735,24 @@ name = "smallvec"
version = "0.6.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "smallvec"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "stable_deref_trait"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "string"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "strsim"
version = "0.8.0"
@@ -1354,32 +1760,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "structopt"
-version = "0.2.18"
+version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "structopt-derive 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "structopt-derive"
-version = "0.2.18"
+version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "syn"
-version = "0.11.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro-error 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1402,14 +1799,6 @@ dependencies = [
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
-[[package]]
-name = "synom"
-version = "0.11.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "synstructure"
version = "0.10.2"
@@ -1421,14 +1810,9 @@ dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
-[[package]]
-name = "take_mut"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
[[package]]
name = "target-lexicon"
-version = "0.4.0"
+version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1446,15 +1830,7 @@ dependencies = [
"rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "termcolor"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1480,7 +1856,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1493,11 +1869,126 @@ dependencies = [
]
[[package]]
-name = "toml"
-version = "0.4.10"
+name = "tokio"
+version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-threadpool 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-buf"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-current-thread"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-executor"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-io"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-reactor"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-sync"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-tcp"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-threadpool"
+version = "0.1.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-timer"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1508,11 +1999,70 @@ dependencies = [
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "try-lock"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "try_from"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "typenum"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "typetag"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "inventory 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
+ "typetag-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "typetag-impl"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unicase"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "unicode-segmentation"
version = "1.3.0"
@@ -1523,11 +2073,6 @@ name = "unicode-width"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-[[package]]
-name = "unicode-xid"
-version = "0.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
[[package]]
name = "unicode-xid"
version = "0.1.0"
@@ -1538,6 +2083,26 @@ name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "url"
+version = "1.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "url"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "user32-sys"
version = "0.1.3"
@@ -1547,6 +2112,19 @@ dependencies = [
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "uuid"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "vcpkg"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "vec_map"
version = "0.8.1"
@@ -1557,6 +2135,11 @@ name = "version_check"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "version_check"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "void"
version = "1.0.2"
@@ -1589,10 +2172,20 @@ version = "2.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "want"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "wasi"
version = "0.5.0"
@@ -1600,108 +2193,112 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "wasmer"
-version = "0.6.0"
+version = "0.11.0"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
+ "structopt 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmer-clif-backend 0.6.0",
- "wasmer-dev-utils 0.6.0",
- "wasmer-emscripten 0.6.0",
- "wasmer-emscripten-tests 0.6.0",
+ "wasmer-clif-backend 0.11.0",
+ "wasmer-dev-utils 0.11.0",
+ "wasmer-emscripten 0.11.0",
+ "wasmer-emscripten-tests 0.11.0",
"wasmer-kernel-loader 0.1.0",
- "wasmer-llvm-backend 0.6.0",
- "wasmer-middleware-common 0.6.0",
- "wasmer-runtime 0.6.0",
- "wasmer-runtime-core 0.6.0",
- "wasmer-singlepass-backend 0.6.0",
- "wasmer-wasi 0.6.0",
- "wasmer-wasi-framebuffer 0.6.0",
- "wasmer-wasi-tests 0.6.0",
+ "wasmer-llvm-backend 0.11.0",
+ "wasmer-middleware-common 0.11.0",
+ "wasmer-middleware-common-tests 0.11.0",
+ "wasmer-runtime 0.11.0",
+ "wasmer-runtime-core 0.11.0",
+ "wasmer-singlepass-backend 0.11.0",
+ "wasmer-wasi 0.11.0",
+ "wasmer-wasi-framebuffer 0.11.0",
+ "wasmer-wasi-tests 0.11.0",
]
[[package]]
name = "wasmer-clif-backend"
-version = "0.6.0"
+version = "0.11.0"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "cranelift-codegen 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cranelift-entity 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cranelift-native 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-codegen 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-entity 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-native 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
- "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmer-clif-fork-frontend 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmer-clif-fork-wasm 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmer-runtime-core 0.6.0",
- "wasmer-win-exception-handler 0.6.0",
- "wasmparser 0.35.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasmer-clif-fork-frontend 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasmer-clif-fork-wasm 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasmer-runtime-core 0.11.0",
+ "wasmer-win-exception-handler 0.11.0",
+ "wasmparser 0.39.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasmer-clif-fork-frontend"
-version = "0.33.0"
+version = "0.44.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cranelift-codegen 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-codegen 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasmer-clif-fork-wasm"
-version = "0.33.0"
+version = "0.44.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cranelift-codegen 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cranelift-entity 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-codegen 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-entity 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmer-clif-fork-frontend 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmparser 0.35.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasmer-clif-fork-frontend 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasmparser 0.39.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasmer-dev-utils"
-version = "0.6.0"
+version = "0.11.0"
dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasmer-emscripten"
-version = "0.6.0"
+version = "0.11.0"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "getrandom 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmer-runtime-core 0.6.0",
+ "wasmer-runtime-core 0.11.0",
]
[[package]]
name = "wasmer-emscripten-tests"
-version = "0.6.0"
+version = "0.11.0"
dependencies = [
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmer-clif-backend 0.6.0",
- "wasmer-dev-utils 0.6.0",
- "wasmer-emscripten 0.6.0",
- "wasmer-llvm-backend 0.6.0",
- "wasmer-runtime-core 0.6.0",
- "wasmer-singlepass-backend 0.6.0",
+ "wasmer-clif-backend 0.11.0",
+ "wasmer-dev-utils 0.11.0",
+ "wasmer-emscripten 0.11.0",
+ "wasmer-llvm-backend 0.11.0",
+ "wasmer-runtime 0.11.0",
+ "wasmer-singlepass-backend 0.11.0",
]
[[package]]
@@ -1709,17 +2306,17 @@ name = "wasmer-kernel-loader"
version = "0.1.0"
dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmer-runtime-core 0.6.0",
+ "wasmer-runtime-core 0.11.0",
]
[[package]]
name = "wasmer-llvm-backend"
-version = "0.6.0"
+version = "0.11.0"
dependencies = [
- "capstone 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"goblin 0.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "inkwell 0.1.0 (git+https://github.com/wasmerio/inkwell?branch=llvm8-0)",
+ "inkwell 0.1.0 (git+https://github.com/TheDan64/inkwell?rev=781620e9fa30e51a6e03bd0d49b5f5bb7a782520)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1728,61 +2325,78 @@ dependencies = [
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmer-runtime-core 0.6.0",
- "wasmparser 0.35.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasmer-runtime-core 0.11.0",
+ "wasmparser 0.39.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "wasmer-llvm-backend-tests"
+version = "0.10.2"
+dependencies = [
+ "wabt 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasmer-llvm-backend 0.11.0",
+ "wasmer-runtime 0.11.0",
+ "wasmer-runtime-core 0.11.0",
]
[[package]]
name = "wasmer-middleware-common"
-version = "0.6.0"
+version = "0.11.0"
+dependencies = [
+ "wasmer-runtime-core 0.11.0",
+]
+
+[[package]]
+name = "wasmer-middleware-common-tests"
+version = "0.11.0"
dependencies = [
"criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmer-clif-backend 0.6.0",
- "wasmer-llvm-backend 0.6.0",
- "wasmer-runtime-core 0.6.0",
- "wasmer-singlepass-backend 0.6.0",
+ "wasmer-clif-backend 0.11.0",
+ "wasmer-llvm-backend 0.11.0",
+ "wasmer-middleware-common 0.11.0",
+ "wasmer-runtime-core 0.11.0",
+ "wasmer-singlepass-backend 0.11.0",
]
[[package]]
name = "wasmer-runtime"
-version = "0.6.0"
+version = "0.11.0"
dependencies = [
"criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmer-clif-backend 0.6.0",
- "wasmer-llvm-backend 0.6.0",
- "wasmer-runtime-core 0.6.0",
- "wasmer-singlepass-backend 0.6.0",
+ "wasmer-clif-backend 0.11.0",
+ "wasmer-llvm-backend 0.11.0",
+ "wasmer-runtime-core 0.11.0",
+ "wasmer-singlepass-backend 0.11.0",
]
[[package]]
name = "wasmer-runtime-c-api"
-version = "0.6.0"
+version = "0.11.0"
dependencies = [
"cbindgen 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmer-runtime 0.6.0",
- "wasmer-runtime-core 0.6.0",
+ "wasmer-runtime 0.11.0",
+ "wasmer-runtime-core 0.11.0",
+ "wasmer-wasi 0.11.0",
]
[[package]]
name = "wasmer-runtime-core"
-version = "0.6.0"
+version = "0.11.0"
dependencies = [
- "bincode 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"blake2b_simd 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "field-offset 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "indexmap 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1794,101 +2408,107 @@ dependencies = [
"serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmparser 0.35.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasmparser 0.39.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "wasmer-runtime-core-tests"
+version = "0.11.0"
+dependencies = [
+ "wabt 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasmer-clif-backend 0.11.0",
+ "wasmer-llvm-backend 0.11.0",
+ "wasmer-runtime-core 0.11.0",
+ "wasmer-singlepass-backend 0.11.0",
]
[[package]]
name = "wasmer-singlepass-backend"
-version = "0.6.0"
+version = "0.11.0"
dependencies = [
+ "bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "dynasm 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "dynasmrt 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "dynasm 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "dynasmrt 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmer-runtime-core 0.6.0",
- "wasmparser 0.35.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasmer-runtime-core 0.11.0",
]
[[package]]
name = "wasmer-spectests"
-version = "0.6.0"
+version = "0.11.0"
dependencies = [
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmer-clif-backend 0.6.0",
- "wasmer-llvm-backend 0.6.0",
- "wasmer-runtime-core 0.6.0",
- "wasmer-singlepass-backend 0.6.0",
+ "wasmer-clif-backend 0.11.0",
+ "wasmer-llvm-backend 0.11.0",
+ "wasmer-runtime 0.11.0",
+ "wasmer-singlepass-backend 0.11.0",
]
[[package]]
name = "wasmer-wasi"
-version = "0.6.0"
+version = "0.11.0"
dependencies = [
+ "bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"generational-arena 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "getrandom 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmer-runtime-core 0.6.0",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasmer-runtime-core 0.11.0",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasmer-wasi-framebuffer"
-version = "0.6.0"
+version = "0.11.0"
dependencies = [
"minifb 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmer-runtime-core 0.6.0",
- "wasmer-wasi 0.6.0",
+ "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
+ "typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasmer-runtime-core 0.11.0",
+ "wasmer-wasi 0.11.0",
]
[[package]]
name = "wasmer-wasi-tests"
-version = "0.6.0"
+version = "0.11.0"
dependencies = [
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmer-clif-backend 0.6.0",
- "wasmer-dev-utils 0.6.0",
- "wasmer-llvm-backend 0.6.0",
- "wasmer-runtime-core 0.6.0",
- "wasmer-singlepass-backend 0.6.0",
- "wasmer-wasi 0.6.0",
+ "wasmer-clif-backend 0.11.0",
+ "wasmer-dev-utils 0.11.0",
+ "wasmer-llvm-backend 0.11.0",
+ "wasmer-runtime 0.11.0",
+ "wasmer-singlepass-backend 0.11.0",
+ "wasmer-wasi 0.11.0",
]
[[package]]
name = "wasmer-win-exception-handler"
-version = "0.6.0"
+version = "0.11.0"
dependencies = [
- "bindgen 0.51.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cmake 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmer-runtime-core 0.6.0",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasmer-runtime-core 0.11.0",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasmparser"
-version = "0.35.3"
+version = "0.39.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-[[package]]
-name = "which"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "winapi"
version = "0.2.8"
@@ -1896,7 +2516,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
-version = "0.3.7"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1918,7 +2538,7 @@ name = "winapi-util"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1927,23 +2547,20 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "wincolor"
-version = "1.0.2"
+name = "winreg"
+version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "winconsole"
-version = "0.10.0"
+name = "ws2_32-sys"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cgmath 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rgb 0.8.14 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1957,117 +2574,149 @@ dependencies = [
]
[metadata]
+"checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
-"checksum approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08abcc3b4e9339e33a3d0a5ed15d84a687350c05689d825e0f6655eef9e76a94"
"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
"checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba"
"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
"checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875"
"checksum backtrace 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "1371048253fa3bac6704bfd6bbfc922ee9bdcee8881330d40f308b81cc5adc55"
"checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b"
-"checksum bincode 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9f04a5e50dc80b3d5d35320889053637d15011aed5e66b66b37ae798c65da6f7"
-"checksum bindgen 0.51.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18270cdd7065ec045a6bb4bdcd5144d14a78b3aedb3bc5111e688773ac8b9ad0"
+"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
+"checksum bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ab639324e3ee8774d296864fbc0dbbb256cf1a41c490b94cba90c082915f92"
"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
"checksum blake2b_simd 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bf775a81bb2d464e20ff170ac20316c7b08a43d11dbc72f0f82e8e8d3d6d0499"
"checksum bstr 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94cdf78eb7e94c566c1f5dbe2abf8fc70a548fc902942a48c4b3a98b48ca9ade"
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
+"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101"
-"checksum capstone 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "031ba51c39151a1d6336ec859646153187204b0147c7b3f6fe2de636f1b8dbb3"
-"checksum capstone-sys 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fae25eddcb80e24f98c35952c37a91ff7f8d0f60dbbdafb9763e8d5cc566b8d7"
-"checksum cargo_toml 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "097f5ce64ba566a83d9d914fd005de1e5937fdd57d8c5d99a7593040955d75a9"
+"checksum cargo_toml 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7877b00aaf997d7ed66a81281d3a8b9f9da5361df05b72785b985349979a0f3"
"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427"
"checksum cbindgen 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e7e19db9a3892c88c74cbbdcd218196068a928f1b60e736c448b13a1e81f277"
"checksum cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "b548a4ee81fccb95919d4e22cfea83c7693ebfd78f0495493178db20b3139da7"
-"checksum cexpr 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7fa24eb00d5ffab90eaeaf1092ac85c04c64aaf358ea6f84505b8116d24c6af"
"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
-"checksum cgmath 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64a4b57c8f4e3a2e9ac07e0f6abc9c24b6fc9e1b54c3478cfb598f3d0023e51c"
-"checksum clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853"
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum cmake 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "3c84c596dcf125d6781f58e3f4254677ec2a6d8aa56e8501ac277100990b3229"
-"checksum colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6cdb90b60f2927f8d76139c72dbde7e10c3a2bc47c8594c9c7a66529f2687c03"
"checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120"
-"checksum cranelift-bforest 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "409f92af3dd276e112b72873a3ef02613e3c5f55b81d5d5d04f3157d4f8b8c54"
-"checksum cranelift-codegen 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b303542a56fba4cbaeea099fb30ed078b50de0e765fd69f7f5f410adbe31d95b"
-"checksum cranelift-codegen-meta 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0fee15ed430092a6d14b7c6d627540bef732509b8097ae31e4e35526edaa129c"
-"checksum cranelift-entity 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "739222c3740e4a8d6f0375bd95caba9b6c11afcba9f0e1d4f944d6bd99f84600"
-"checksum cranelift-native 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce451162d18b7d82118e23ea7e12f7d8b98557549404bd71215548de79eb0736"
+"checksum cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5"
+"checksum cookie_store 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46750b3f362965f197996c4448e4a0935e791bf7d6631bfce9ee0af3d24c919c"
+"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d"
+"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
+"checksum cranelift-bforest 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fff04f4ad82c9704a22e753c6268cc6a89add76f094b837cefbba1c665411451"
+"checksum cranelift-codegen 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ff4a221ec1b95df4b1d20a99fec4fe92a28bebf3a815f2eca72b26f9a627485"
+"checksum cranelift-codegen-meta 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd47f665e2ee8f177b97d1f5ce2bd70f54d3b793abb26d92942bfaa4a381fe9f"
+"checksum cranelift-codegen-shared 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05bb95945fd940bd5fc2616b063ce69e55de3d9449a32fa40f6bb99a927085bf"
+"checksum cranelift-entity 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e8753f15d9bde04988834705d437b6f6e4b4da0527968b8d40d7342262d43052"
+"checksum cranelift-native 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd16b58e95af9ee837218cf41e70306becc1fc7d7dada55dac42df5130a4a4ba"
+"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
"checksum criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394"
"checksum criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76f9212ddf2f4a9eb2d401635190600656a1f88a932ef53d06e7fa4c7e02fb8e"
-"checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13"
-"checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9"
+"checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca"
+"checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac"
"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
+"checksum crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfd6515864a82d2f877b42813d4553292c6659498c9a2aa31bab5a15243c2700"
"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
+"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4"
"checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d"
"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c"
+"checksum ctor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8ce37ad4184ab2ce004c33bf6379185d3b1c95801cab51026bd271bf68eedc"
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
-"checksum dynasm 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f36d49ab6f8ecc642d2c6ee10fda04ba68003ef0277300866745cdde160e6b40"
-"checksum dynasmrt 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a4c408a211e7f5762829f5e46bdff0c14bc3b1517a21a4bb781c716bf88b0c68"
+"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
+"checksum dynasm 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "42a814e1edeb85dd2a3c6fc0d6bf76d02ca5695d438c70ecee3d90774f3259c5"
+"checksum dynasmrt 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8a393aaeb4441a48bcf47b5b6155971f82cc1eb77e22855403ccc0415ac8328d"
"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
-"checksum enum-methods 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7798e7da2d4cb0d6d6fc467e8d6b5bf247e9e989f786dde1732d79899c32bb10"
-"checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3"
+"checksum encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)" = "87240518927716f79692c2ed85bfe6e98196d18c6401ec75355760233a7e12e9"
+"checksum erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3beee4bc16478a1b26f2e80ad819a52d24745e292f521a63c16eea5f74b7eb60"
"checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e"
"checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067"
+"checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9"
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
-"checksum field-offset 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64e9bc339e426139e02601fa69d101e96a92aee71b58bc01697ec2a63a5c9e68"
+"checksum flate2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ad3c5233c9a940c8719031b423d7e6c16af66e031cb0420b0896f5245bf181d3"
+"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
+"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
-"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
+"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
+"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
+"checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef"
+"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
"checksum gdi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e3eb92c1107527888f86b6ebb0b7f82794777dbf172a932998660a0a2e26c11"
"checksum generational-arena 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4024f96ffa0ebaaf36aa589cd41f2fd69f3a5e6fd02c86e11e12cdf41d5b46a3"
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum getrandom 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "6171a6cc63fbabbe27c2b5ee268e8b7fe5dc1eb0dd2dfad537c1dfed6f69117e"
+"checksum ghost 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a36606a68532b5640dc86bb1f33c64b45c4682aad4c50f3937b317ea387f3d6"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
"checksum goblin 0.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "e3fa261d919c1ae9d1e4533c4a2f99e10938603c4208d56c05bec7a872b661b0"
+"checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
-"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114"
-"checksum indexmap 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4d6d89e0948bf10c08b9ecc8ac5b83f07f857ebe2c0cbe38de15b4e4f510356"
-"checksum inkwell 0.1.0 (git+https://github.com/wasmerio/inkwell?branch=llvm8-0)" = ""
-"checksum inkwell_internal_macros 0.1.0 (git+https://github.com/wasmerio/inkwell?branch=llvm8-0)" = ""
+"checksum http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0"
+"checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d"
+"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
+"checksum hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)" = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6"
+"checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f"
+"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
+"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
+"checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2"
+"checksum inkwell 0.1.0 (git+https://github.com/TheDan64/inkwell?rev=781620e9fa30e51a6e03bd0d49b5f5bb7a782520)" = ""
+"checksum inkwell_internals 0.1.0 (git+https://github.com/TheDan64/inkwell?rev=781620e9fa30e51a6e03bd0d49b5f5bb7a782520)" = ""
+"checksum inventory 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f4cece20baea71d9f3435e7bbe9adf4765f091c5fe404975f844006964a71299"
+"checksum inventory-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2869bf972e998977b1cb87e60df70341d48e48dca0823f534feb91ea44adaf9"
+"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
-"checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753"
"checksum llvm-sys 80.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2110cd4daf9cd8e39dd3b933b1a2a2ac7315e91f7c92b3a20beab526c63b5978"
"checksum lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc"
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
+"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
+"checksum md5 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e6bcd6433cff03a4bfc3d9834d504467db1f1cf6d0ea765d37d330249ed629d"
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
-"checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
"checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f"
+"checksum mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "dd1d63acd1b78403cc0c325605908475dd9b9a3acbf65ed8bcab97e27014afcf"
+"checksum mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a0ed03949aef72dbdf3116a383d7b38b4768e6f960528cd6a6044aa9ed68599"
"checksum minifb 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "85c2cedede43aad485232acf318a3e191ee5a3c2250ca8a3556b849a48e8b901"
+"checksum miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6f3f74f726ae935c3f514300cc6773a0c9492abc5e972d42ba0c0ebb88757625"
+"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f"
+"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
+"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e"
+"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
"checksum nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229"
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
-"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e"
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
"checksum num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "76bd5272412d173d6bf9afdf98db8612bbabc9a7a830b7bfc9c188911716132e"
-"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
+"checksum once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "891f486f630e5c5a4916c7e16c4b24a53e78c860b646e9f8e005e4f16847bfed"
+"checksum openssl 0.10.26 (registry+https://github.com/rust-lang/crates.io-index)" = "3a3cc5799d98e1088141b8e01ff760112bbd9f19d850c124500566ca6901a585"
+"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
+"checksum openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)" = "465d16ae7fc0e313318f7de5cecf57b2fbe7511fd213978b457e1c96ff46736f"
"checksum orbclient 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)" = "f8b18f57ab94fbd058e30aa57f712ec423c0bb7403f8493a6c58eef0c36d9402"
-"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
+"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
"checksum page_size 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f89ef58b3d32420dbd1a43d2f38ae92f6239ef12bb556ab09ca55445f5a67242"
"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252"
"checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b"
-"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
+"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
+"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
"checksum pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c1d2cfa5a714db3b5f24f0915e74fcdf91d09d496ba61329705dda7774d2af"
"checksum plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b"
+"checksum proc-macro-error 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aeccfe4d5d8ea175d5f0e4a2ad0637e0f4121d63bd99d356fb1f39ab2e7c6097"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c5c2380ae88876faae57698be9e9775e3544decad214599c3a6266cca6ac802"
-"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
-"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
+"checksum publicsuffix 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9bf259a81de2b2eb9850ec990ec78e6a25319715584fd7652b9b26f96fcb1510"
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
-"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c"
"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
@@ -2084,8 +2733,8 @@ dependencies = [
"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
"checksum rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03b418169fb9c46533f326efd6eed2576699c44ca92d3052a066214a8d828929"
"checksum raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "30a9d219c32c9132f7be513c18be77c9881c7107d2ab5569d205a6a0f0e6dc7d"
-"checksum rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4b0186e22767d5b9738a05eab7c6ac90b15db17e5b5f9bd87976dd7d89a10a4"
-"checksum rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe0df8435ac0c397d467b6cad6d25543d06e8a019ef3f6af3c384597515bd2"
+"checksum rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43739f8831493b276363637423d3622d4bd6394ab6f0a9c4a552e208aeb7fddd"
+"checksum rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8bf17de6f23b05473c437eb958b9c850bfc8af0961fe17b4cc92d5a627b4791"
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
"checksum ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d813022b2e00774a48eaf43caaa3c20b45f040ba8cbf398e2e8911a06668dbe6"
@@ -2093,16 +2742,19 @@ dependencies = [
"checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9"
"checksum regex-syntax 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b143cceb2ca5e56d5671988ef8b15615733e7ee16cd348e064333b251b89343f"
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
-"checksum rgb 0.8.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2089e4031214d129e201f8c3c8c2fe97cd7322478a0d1cdf78e7029b0042efdb"
+"checksum reqwest 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)" = "2c2064233e442ce85c77231ebd67d9eca395207dec2127fe0bbedde4bd29a650"
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"
"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421"
+"checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021"
"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
"checksum scroll 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f84d114ef17fd144153d608fba7c446b0145d038985e7a8cc5d08bb0ce20383"
"checksum scroll_derive 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1aa96c45e7f5a91cb7fabe7b279f02fea7126239fc40b732316e8b6a2d0fcb"
"checksum sdl2 0.32.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d051a07231e303f5f719da78cb6f7394f6d5b54f733aef5b0b447804a83edd7b"
"checksum sdl2-sys 0.32.6 (registry+https://github.com/rust-lang/crates.io-index)" = "34e71125077d297d57e4c1acfe8981b5bdfbf5a20e7b589abfdcb33bf1127f86"
+"checksum security-framework 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8ef2429d7cefe5fd28bd1d2ed41c944547d4ff84776f5935b456da44593a16df"
+"checksum security-framework-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e31493fc37615debb8c5090a7aeb4a9730bc61e77ab10b9af59f1a202284f895"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "fec2851eb56d010dc9a21b89ca53ee75e6528bab60c11e89d38390904982da9f"
@@ -2110,51 +2762,70 @@ dependencies = [
"checksum serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "45af0182ff64abaeea290235eb67da3825a576c5d53e642c4d5b652e12e6effc"
"checksum serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "cb4dc18c61206b08dc98216c98faa0232f4337e1e1b8574551d5bad29ea1b425"
"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704"
-"checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
+"checksum serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a"
+"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7"
+"checksum smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86"
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
+"checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d"
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
-"checksum structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7"
-"checksum structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107"
-"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
+"checksum structopt 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "30b3a3e93f5ad553c38b3301c8a0a0cec829a36783f6a0c467fc4bf553a5f5bf"
+"checksum structopt-derive 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea692d40005b3ceba90a9fe7a78fa8d4b82b0ce627eebbffc329aab850f3410e"
"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
"checksum syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "158521e6f544e7e3dcfc370ac180794aa38cb34a1b1e07609376d4adcf429b93"
-"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
-"checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"
-"checksum target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1b0ab4982b8945c35cc1c46a83a9094c414f6828a099ce5dcaa8ee2b04642dcb"
+"checksum target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7975cb2c6f37d77b190bc5004a2bb015971464756fde9514651a525ada2a741a"
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
-"checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
"checksum tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4574b75faccaacddb9b284faecdf0b544b80b6b294f3d062d325c5726a209c20"
-"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
+"checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6"
+"checksum tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46"
+"checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443"
+"checksum tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ca6df436c42b0c3330a82d855d2ef017cd793090ad550a6bc2184f4b933532ab"
+"checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926"
+"checksum tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6732fe6b53c8d11178dcb77ac6d9682af27fc6d4cb87789449152e5377377146"
+"checksum tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76"
+"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119"
+"checksum tokio-threadpool 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c32ffea4827978e9aa392d2f743d973c1dfa3730a2ed3f22ce1e6984da848c"
+"checksum tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1739638e364e558128461fc1ad84d997702c8e31c2e6b18fb99842268199e827"
"checksum toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724"
+"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
+"checksum try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "283d3b89e1368717881a9d51dad843cc435380d8109c9e47d38780a324698d8b"
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
+"checksum typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ebb2c484029d695fb68a06d80e1536c68d491b3e0cf874c66abed255e831cfe"
+"checksum typetag-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b63fd4799e4d0ec5cf0b055ebb8e2c3a657bbf76a84f6edc77ca60780e000204"
+"checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
+"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
+"checksum unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf"
"checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9"
"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
-"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
+"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
+"checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61"
"checksum user32-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e6b719983b952c04198829b51653c06af36f0e44c967fcc1a2bb397ceafbf80a"
+"checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a"
+"checksum vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
+"checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum wabt 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "94b5f5d6984ca42df66280baa8a15ac188a173ddaf4580b574a98931c01920e7"
"checksum wabt-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b064c81821100adb4b71923cecfc67fef083db21c3bbd454b0162c7ffe63eeaa"
"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e"
+"checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230"
"checksum wasi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd5442abcac6525a045cc8c795aedb60da7a2e5e89c7bf18a0d5357849bb23c7"
-"checksum wasmer-clif-fork-frontend 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bd6bec1587a3b11222f4ff129fd119785713c41de413f54f99d3c03743812f4"
-"checksum wasmer-clif-fork-wasm 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8f323e612fe2549391255a09f89c927d7feb0ec4bf0c2cad9e3c089bdca42fc"
-"checksum wasmparser 0.35.3 (registry+https://github.com/rust-lang/crates.io-index)" = "099aaf77635ffad3d9ab57253c29b16a46e93755c3e54cfe33fb8cf4b54f760b"
-"checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164"
+"checksum wasmer-clif-fork-frontend 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0cf2f552a9c1fda0555087170424bd8fedc63a079a97bb5638a4ef9b0d9656aa"
+"checksum wasmer-clif-fork-wasm 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0073b512e1af5948d34be7944b74c747bbe735ccff2e2f28c26ed4c90725de8e"
+"checksum wasmparser 0.39.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c702914acda5feeeffbc29e4d953e5b9ce79d8b98da4dbf18a77086e116c5470"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
-"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770"
+"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-"checksum wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9"
-"checksum winconsole 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ef84b96d10db72dd980056666d7f1e7663ce93d82fa33b63e71c966f4cf5032"
+"checksum winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9"
+"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
"checksum x11-dl 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "326c500cdc166fd7c70dd8c8a829cd5c0ce7be5a5d98c25817de2b9bdc67faf8"
diff --git a/Cargo.toml b/Cargo.toml
index e91dcf459..eb6019280 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,12 +1,13 @@
[package]
name = "wasmer"
-version = "0.6.0"
+version = "0.11.0"
authors = ["The Wasmer Engineering Team "]
edition = "2018"
repository = "https://github.com/wasmerio/wasmer"
publish = true
description = "High-Performance WebAssembly JIT interpreter"
license = "MIT"
+default-run = "wasmer"
include = [
"examples/**/*",
"src/**/*",
@@ -19,15 +20,14 @@ include = [
]
[dependencies]
-byteorder = "1.3.2"
-errno = "0.2.4"
-structopt = "0.2.18"
+byteorder = "1.3"
+errno = "0.2"
+structopt = "0.3"
wabt = "0.9.1"
-wasmer-clif-backend = { path = "lib/clif-backend" }
+wasmer-clif-backend = { path = "lib/clif-backend", optional = true }
wasmer-singlepass-backend = { path = "lib/singlepass-backend", optional = true }
wasmer-middleware-common = { path = "lib/middleware-common" }
wasmer-runtime = { path = "lib/runtime" }
-# wasmer-runtime-abi = { path = "lib/runtime-abi", optional = true }
wasmer-runtime-core = { path = "lib/runtime-core" }
wasmer-emscripten = { path = "lib/emscripten" }
wasmer-llvm-backend = { path = "lib/llvm-backend", optional = true }
@@ -35,6 +35,7 @@ wasmer-wasi = { path = "lib/wasi", optional = true }
wasmer-kernel-loader = { path = "lib/kernel-loader", optional = true }
wasmer-dev-utils = { path = "lib/dev-utils", optional = true }
wasmer-wasi-tests = { path = "lib/wasi-tests", optional = true }
+wasmer-middleware-common-tests = { path = "lib/middleware-common-tests", optional = true }
wasmer-emscripten-tests = { path = "lib/emscripten-tests", optional = true }
wasmer-wasi-framebuffer = { path = "lib/wasi-framebuffer", optional = true }
@@ -43,13 +44,14 @@ members = [
"lib/clif-backend",
"lib/singlepass-backend",
"lib/runtime",
- # "lib/runtime-abi",
"lib/runtime-core",
+ "lib/runtime-core-tests",
"lib/emscripten",
"lib/spectests",
"lib/win-exception-handler",
"lib/runtime-c-api",
"lib/llvm-backend",
+ "lib/llvm-backend-tests",
"lib/wasi",
"lib/middleware-common",
"lib/kernel-loader",
@@ -58,43 +60,56 @@ members = [
"lib/wasi-framebuffer",
"lib/wasi-tests",
"lib/emscripten-tests",
- "examples/plugin-for-example"
+ "lib/middleware-common-tests",
+ "examples/parallel",
+ "examples/plugin-for-example",
+ "examples/parallel-guest",
]
[build-dependencies]
wabt = "0.9.1"
-glob = "0.3.0"
-rustc_version = "0.2.3"
+glob = "0.3"
+rustc_version = "0.2"
+
+[dev-dependencies]
+serde = { version = "1", features = ["derive"] } # used by the plugin example
+typetag = "0.1" # used by the plugin example
[features]
-default = ["fast-tests", "wasi", "backend-cranelift"]
+default = ["fast-tests", "wasi"]
"loader-kernel" = ["wasmer-kernel-loader"]
debug = ["wasmer-runtime-core/debug"]
trace = ["wasmer-runtime-core/trace"]
+docs = ["wasmer-runtime/docs"]
extra-debug = ["wasmer-clif-backend/debug", "wasmer-runtime-core/debug"]
# This feature will allow cargo test to run much faster
fast-tests = []
backend-cranelift = [
+ "wasmer-clif-backend",
"wasmer-runtime-core/backend-cranelift",
"wasmer-runtime/cranelift",
- "wasmer-middleware-common/clif"
+ "wasmer-middleware-common-tests/clif",
]
backend-llvm = [
"wasmer-llvm-backend",
"wasmer-runtime-core/backend-llvm",
"wasmer-runtime/llvm",
- "wasmer-middleware-common/llvm"
+ "wasmer-middleware-common-tests/llvm",
]
backend-singlepass = [
"wasmer-singlepass-backend",
"wasmer-runtime-core/backend-singlepass",
"wasmer-runtime/singlepass",
- "wasmer-middleware-common/singlepass"
+ "wasmer-middleware-common-tests/singlepass",
]
wasi = ["wasmer-wasi"]
-# vfs = ["wasmer-runtime-abi"]
experimental-framebuffer = ["wasmer-wasi-framebuffer"]
+managed = ["backend-singlepass", "wasmer-runtime-core/managed"]
[[example]]
name = "plugin"
crate-type = ["bin"]
+
+[[example]]
+name = "callback"
+crate-type = ["bin"]
diff --git a/Dockerfile b/Dockerfile
index 43fcda359..73507be30 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM circleci/rust:1.33.0-stretch as wasmer-build-env
+FROM circleci/rust:1.38.0-stretch as wasmer-build-env
RUN sudo apt-get update && \
sudo apt-get install -y --no-install-recommends \
cmake \
@@ -17,9 +17,9 @@ FROM wasmer-build-env AS wasmer-build
WORKDIR /home/circleci/wasmer
COPY . /home/circleci/wasmer
RUN sudo chmod -R 777 .
-RUN cargo build --release
+RUN cargo build --release --features backend-cranelift
FROM debian:stretch AS wasmer
WORKDIR /root/
COPY --from=wasmer-build /home/circleci/wasmer/target/release/wasmer .
-ENTRYPOINT ["./wasmer"]
\ No newline at end of file
+ENTRYPOINT ["./wasmer"]
diff --git a/Makefile b/Makefile
index a12d14fe5..4acde7925 100644
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,15 @@
-.PHONY: spectests emtests clean build install lint precommit
+.PHONY: spectests emtests clean build install lint precommit docs examples
# Generate files
generate-spectests:
- WASMER_RUNTIME_GENERATE_SPECTESTS=1 cargo build -p wasmer-runtime-core --release
+ WASMER_RUNTIME_GENERATE_SPECTESTS=1 cargo build -p wasmer-runtime-core --release \
+ && echo "formatting" \
+ && cargo fmt
generate-emtests:
- WASM_EMSCRIPTEN_GENERATE_EMTESTS=1 cargo build -p wasmer-emscripten-tests --release
+ WASM_EMSCRIPTEN_GENERATE_EMTESTS=1 cargo build -p wasmer-emscripten-tests --release \
+ && echo "formatting" \
+ && cargo fmt
generate-wasitests: wasitests-setup
WASM_WASI_GENERATE_WASITESTS=1 cargo build -p wasmer-wasi-tests --release -vv \
@@ -21,7 +25,7 @@ generate: generate-spectests generate-emtests generate-wasitests
# Spectests
spectests-singlepass:
- cargo test --manifest-path lib/spectests/Cargo.toml --release --features singlepass -- --nocapture
+ cargo test --manifest-path lib/spectests/Cargo.toml --release --features singlepass -- --nocapture --test-threads 1
spectests-cranelift:
cargo test --manifest-path lib/spectests/Cargo.toml --release --features clif -- --nocapture
@@ -50,13 +54,13 @@ emtests: emtests-unit emtests-singlepass emtests-cranelift emtests-llvm
# Middleware tests
middleware-singlepass:
- cargo test --manifest-path lib/middleware-common/Cargo.toml --release --features singlepass
+ cargo test --manifest-path lib/middleware-common-tests/Cargo.toml --release --features singlepass
middleware-cranelift:
- cargo test --manifest-path lib/middleware-common/Cargo.toml --release --features clif
+ cargo test --manifest-path lib/middleware-common-tests/Cargo.toml --release --features clif
middleware-llvm:
- cargo test --manifest-path lib/middleware-common/Cargo.toml --release --features llvm
+ cargo test --manifest-path lib/middleware-common-tests/Cargo.toml --release --features llvm
middleware: middleware-singlepass middleware-cranelift middleware-llvm
@@ -70,12 +74,13 @@ wasitests-singlepass: wasitests-setup
cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features singlepass -- --test-threads=1
wasitests-cranelift: wasitests-setup
- cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features clif -- --test-threads=1
+ cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features clif -- --test-threads=1 --nocapture
wasitests-llvm: wasitests-setup
cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features llvm -- --test-threads=1
-wasitests-unit:
+wasitests-unit: wasitests-setup
+ cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features clif -- --test-threads=1 --nocapture
cargo test --manifest-path lib/wasi/Cargo.toml --release
wasitests: wasitests-unit wasitests-singlepass wasitests-cranelift wasitests-llvm
@@ -84,22 +89,43 @@ wasitests: wasitests-unit wasitests-singlepass wasitests-cranelift wasitests-llv
# Backends
singlepass: spectests-singlepass emtests-singlepass middleware-singlepass wasitests-singlepass
cargo test -p wasmer-singlepass-backend --release
+ cargo test -p wasmer-runtime-core-tests --release --no-default-features --features backend-singlepass
cranelift: spectests-cranelift emtests-cranelift middleware-cranelift wasitests-cranelift
cargo test -p wasmer-clif-backend --release
+ cargo test -p wasmer-runtime-core-tests --release
llvm: spectests-llvm emtests-llvm wasitests-llvm
cargo test -p wasmer-llvm-backend --release
+ cargo test -p wasmer-llvm-backend-tests --release
+ cargo test -p wasmer-runtime-core-tests --release --no-default-features --features backend-llvm
# All tests
capi:
- cargo build --release
+ cargo build --release --features backend-cranelift
cargo build -p wasmer-runtime-c-api --release
+
+test-capi: capi
cargo test -p wasmer-runtime-c-api --release
-test-rest: capi
- cargo test --release --all --exclude wasmer-runtime-c-api --exclude wasmer-emscripten --exclude wasmer-spectests --exclude wasmer-wasi --exclude wasmer-middleware-common --exclude wasmer-singlepass-backend --exclude wasmer-clif-backend --exclude wasmer-llvm-backend --exclude wasmer-wasi-tests --exclude wasmer-emscripten-tests
+capi-test: test-capi
+
+test-rest:
+ cargo test --release \
+ --all \
+ --exclude wasmer-runtime-c-api \
+ --exclude wasmer-emscripten \
+ --exclude wasmer-spectests \
+ --exclude wasmer-wasi \
+ --exclude wasmer-middleware-common \
+ --exclude wasmer-middleware-common-tests \
+ --exclude wasmer-singlepass-backend \
+ --exclude wasmer-clif-backend \
+ --exclude wasmer-llvm-backend \
+ --exclude wasmer-wasi-tests \
+ --exclude wasmer-emscripten-tests \
+ --exclude wasmer-runtime-core-tests
circleci-clean:
@if [ ! -z "${CIRCLE_JOB}" ]; then rm -f /home/circleci/project/target/debug/deps/libcranelift_wasm* && rm -f /Users/distiller/project/target/debug/deps/libcranelift_wasm*; fi;
@@ -108,12 +134,16 @@ test: spectests emtests middleware wasitests circleci-clean test-rest
# Integration tests
-integration-tests: release-clif
+integration-tests: release-clif examples
echo "Running Integration Tests"
./integration_tests/lua/test.sh
./integration_tests/nginx/test.sh
./integration_tests/cowsay/test.sh
+examples:
+ cargo run --example plugin
+ cargo run --example callback
+
# Utils
lint:
@@ -122,22 +152,82 @@ lint:
precommit: lint test
debug:
- cargo build --release --features backend-singlepass,debug,trace
+ cargo build --release --features backend-cranelift,backend-singlepass,debug,trace
install:
cargo install --path .
-check:
- cargo check --release --features backend-singlepass,backend-llvm,loader-kernel
+# Checks
+check-bench-singlepass:
+ cargo check --benches --all --no-default-features --features "backend-singlepass" \
+ --exclude wasmer-clif-backend --exclude wasmer-llvm-backend --exclude wasmer-kernel-loader
+check-bench-clif:
+ cargo check --benches --all --no-default-features --features "backend-cranelift" \
+ --exclude wasmer-singlepass-backend --exclude wasmer-llvm-backend --exclude wasmer-kernel-loader \
+ --exclude wasmer-middleware-common-tests
+check-bench-llvm:
+ cargo check --benches --all --no-default-features --features "backend-llvm" \
+ --exclude wasmer-singlepass-backend --exclude wasmer-clif-backend --exclude wasmer-kernel-loader
+check-bench: check-bench-singlepass check-bench-llvm
+
+# TODO: We wanted `--workspace --exclude wasmer-runtime`, but can't due
+# to https://github.com/rust-lang/cargo/issues/6745 .
+NOT_RUNTIME_CRATES = -p wasmer-clif-backend -p wasmer-singlepass-backend -p wasmer-middleware-common -p wasmer-runtime-core -p wasmer-emscripten -p wasmer-llvm-backend -p wasmer-wasi -p wasmer-kernel-loader -p wasmer-dev-utils -p wasmer-wasi-tests -p wasmer-middleware-common-tests -p wasmer-emscripten-tests
+RUNTIME_CHECK = cargo check --manifest-path lib/runtime/Cargo.toml --no-default-features
+check: check-bench
+ cargo check $(NOT_RUNTIME_CRATES)
+ cargo check --release $(NOT_RUNTIME_CRATES)
+ cargo check --all-features $(NOT_RUNTIME_CRATES)
+ cargo check --release --all-features $(NOT_RUNTIME_CRATES)
+ # wasmer-runtime doesn't work with all backends enabled at once.
+ #
+ # We test using manifest-path directly so as to disable the default.
+ # `--no-default-features` only disables the default features in the
+ # current package, not the package specified by `-p`. This is
+ # intentional.
+ #
+ # Test default features, test 'debug' feature only in non-release
+ # builds, test as many combined features as possible with each backend
+ # as default, and test a minimal set of features with only one backend
+ # at a time.
+ cargo check --manifest-path lib/runtime/Cargo.toml
+ cargo check --release --manifest-path lib/runtime/Cargo.toml
+
+ $(RUNTIME_CHECK) \
+ --features=cranelift,cache,debug,llvm,singlepass,default-backend-singlepass
+ $(RUNTIME_CHECK) --release \
+ --features=cranelift,cache,llvm,singlepass,default-backend-singlepass
+ $(RUNTIME_CHECK) \
+ --features=cranelift,cache,debug,llvm,singlepass,default-backend-cranelift
+ $(RUNTIME_CHECK) --release \
+ --features=cranelift,cache,llvm,singlepass,default-backend-cranelift
+ $(RUNTIME_CHECK) \
+ --features=cranelift,cache,debug,llvm,singlepass,default-backend-llvm
+ $(RUNTIME_CHECK) --release \
+ --features=cranelift,cache,llvm,singlepass,default-backend-llvm
+ $(RUNTIME_CHECK) \
+ --features=singlepass,default-backend-singlepass,debug
+ $(RUNTIME_CHECK) --release \
+ --features=singlepass,default-backend-singlepass
+ $(RUNTIME_CHECK) \
+ --features=cranelift,default-backend-cranelift,debug
+ $(RUNTIME_CHECK) --release \
+ --features=cranelift,default-backend-cranelift
+ $(RUNTIME_CHECK) \
+ --features=llvm,default-backend-llvm,debug
+ $(RUNTIME_CHECK) --release \
+ --features=llvm,default-backend-llvm
+
+# Release
release:
- cargo build --release --features backend-singlepass,backend-llvm,loader-kernel
+ cargo build --release --features backend-singlepass,backend-cranelift,backend-llvm,loader-kernel
# Only one backend (cranelift)
release-clif:
- # If you are in OS-X, you will need mingw-w64 for cross compiling to windows
+ # If you are on macOS, you will need mingw-w64 for cross compiling to Windows
# brew install mingw-w64
- cargo build --release
+ cargo build --release --features backend-cranelift
release-singlepass:
cargo build --release --features backend-singlepass
@@ -146,20 +236,15 @@ release-llvm:
cargo build --release --features backend-llvm
bench-singlepass:
- cargo bench --all --no-default-features --features "backend-singlepass"
+ cargo bench --all --no-default-features --features "backend-singlepass" \
+ --exclude wasmer-clif-backend --exclude wasmer-llvm-backend --exclude wasmer-kernel-loader
bench-clif:
- cargo bench --all --no-default-features --features "backend-cranelift"
+ cargo bench --all --no-default-features --features "backend-cranelift" \
+ --exclude wasmer-singlepass-backend --exclude wasmer-llvm-backend --exclude wasmer-kernel-loader \
+ --exclude wasmer-middleware-common-tests
bench-llvm:
- cargo bench --all --no-default-features --features "backend-llvm"
-
-# compile but don't run the benchmarks
-compile-bench-singlepass:
- cargo bench --all --no-run --no-default-features --features "backend-singlepass"
-compile-bench-clif:
- cargo bench --all --no-run --no-default-features --features "backend-cranelift"
-compile-bench-llvm:
- cargo bench --all --no-run --no-default-features --features "backend-llvm"
-
+ cargo bench --all --no-default-features --features "backend-llvm" \
+ --exclude wasmer-singlepass-backend --exclude wasmer-clif-backend --exclude wasmer-kernel-loader
# Build utils
build-install:
@@ -178,4 +263,10 @@ publish-release:
# cargo install cargo-deps
# must install graphviz for `dot`
dep-graph:
- cargo deps --optional-deps --filter wasmer-wasi wasmer-wasi-tests wasmer-kernel-loader wasmer-dev-utils wasmer-llvm-backend wasmer-emscripten wasmer-emscripten-tests wasmer-runtime-core wasmer-runtime wasmer-middleware-common wasmer-singlepass-backend wasmer-clif-backend wasmer --manifest-path Cargo.toml | dot -Tpng > wasmer_depgraph.png
+ cargo deps --optional-deps --filter wasmer-wasi wasmer-wasi-tests wasmer-kernel-loader wasmer-dev-utils wasmer-llvm-backend wasmer-emscripten wasmer-emscripten-tests wasmer-runtime-core wasmer-runtime wasmer-middleware-common wasmer-middleware-common-tests wasmer-singlepass-backend wasmer-clif-backend wasmer --manifest-path Cargo.toml | dot -Tpng > wasmer_depgraph.png
+
+docs:
+ cargo doc --features=backend-singlepass,backend-cranelift,backend-llvm,docs,wasi,managed
+
+wapm:
+ cargo build --release --manifest-path wapm-cli/Cargo.toml --features "telemetry update-notifications"
diff --git a/README.md b/README.md
index 5afafdf0e..0391bbd9b 100644
--- a/README.md
+++ b/README.md
@@ -5,42 +5,53 @@
-
-
+
+
+
+
+
-
+
-
+
## Introduction
-[Wasmer](https://wasmer.io/) is a standalone JIT WebAssembly runtime, aiming to be fully compatible with [WASI](https://github.com/WebAssembly/WASI) and [Emscripten](https://emscripten.org/).
+[Wasmer](https://wasmer.io/) is a standalone WebAssembly runtime for running WebAssembly [outside of the browser](https://webassembly.org/docs/non-web/), supporting [WASI](https://github.com/WebAssembly/WASI) and [Emscripten](https://emscripten.org/). Wasmer can be used standalone (via the CLI) and embedded in different languages, running in x86 and [ARM devices](https://medium.com/wasmer/running-webassembly-on-arm-7d365ed0e50c).
-Install Wasmer with:
+Install the Wasmer and [WAPM](https://wapm.io) cli with:
```sh
curl https://get.wasmer.io -sSfL | sh
```
-> Note: *Wasmer is also available on Windows. Download the [`WasmerInstaller.exe` from the Github Releases](https://github.com/wasmerio/wasmer/releases) page.*
+> Note: *Wasmer is also [available on Windows](https://github.com/wasmerio/wasmer/releases)*
-Wasmer runtime can also be embedded in different languages, so you can use WebAssembly anywhere ✨:
+### Languages
-* [**🦀 Rust**](https://github.com/wasmerio/wasmer-rust-example)
-* [**🔗 C/C++**](https://github.com/wasmerio/wasmer-c-api)
-* [**#️⃣ C#**](https://github.com/migueldeicaza/WasmerSharp)
-* [**🐘 PHP**](https://github.com/wasmerio/php-ext-wasm)
-* [**🐍 Python**](https://github.com/wasmerio/python-ext-wasm)
-* [**💎 Ruby**](https://github.com/wasmerio/ruby-ext-wasm)
-* [**🐹 Go**](https://github.com/wasmerio/go-ext-wasm)
-* [**R**](https://github.com/dirkschumacher/wasmr)
+Wasmer runtime can be used as a library embedded in different languages, so you can use WebAssembly anywhere:
+
+| | Language | Author(s) | Maintenance | Release | Stars |
+|-|-|-|-|-|-|
+|  | [**Rust**](https://github.com/wasmerio/wasmer-rust-example) | Wasmer | actively developed |  |  |
+|  | [**C/C++**](https://github.com/wasmerio/wasmer-c-api) | Wasmer | actively developed |  |  |
+|  | [**Python**](https://github.com/wasmerio/python-ext-wasm) | Wasmer | actively developed |  |  |
+|  | [**Go**](https://github.com/wasmerio/go-ext-wasm) | Wasmer | actively developed |  |  |
+|  | [**PHP**](https://github.com/wasmerio/php-ext-wasm) | Wasmer | actively developed |  |  |
+|  | [**Ruby**](https://github.com/wasmerio/ruby-ext-wasm) | Wasmer | actively developed |  |  |
+|  | [**Postgres**](https://github.com/wasmerio/postgres-ext-wasm) | Wasmer | actively developed |  |  |
+|  | [**JavaScript**](https://github.com/wasmerio/wasmer-js) | Wasmer | actively developed |  |  |
+|  | [**C#/.Net**](https://github.com/migueldeicaza/WasmerSharp) | [Miguel de Icaza](https://github.com/migueldeicaza) | actively developed |  |  |
+|  | [**R**](https://github.com/dirkschumacher/wasmr) | [Dirk Schumacher](https://github.com/dirkschumacher) | actively developed | |  |
+|  | [**Swift**](https://github.com/markmals/swift-ext-wasm) | [Mark Malström](https://github.com/markmals/) | passively maintained | |  |
+| ❓ | [your language is missing?](https://github.com/wasmerio/wasmer/issues/new?assignees=&labels=%F0%9F%8E%89+enhancement&template=---feature-request.md&title=) | | | |
### Usage
@@ -51,28 +62,15 @@ Once installed, you will be able to run any WebAssembly files (_including Lua, P
```sh
# Run Lua
-wasmer run examples/lua.wasm
+wasmer examples/lua.wasm
```
*You can find more `wasm/wat` examples in the [examples](./examples) directory.*
-#### With WAPM
+### Docs
-Installing Wasmer through `wasmer.io` includes
-[`wapm`](https://github.com/wasmerio/wapm-cli), the [WebAssembly Package Manager](https://wapm.io/).
+Wasmer documentation lives on [docs.wasmer.io](https://docs.wasmer.io).
-Wapm allows you to easily download, run, and distribute WebAssembly binaries.
-
-```sh
-# Install cowsay globally
-wapm install -g cowsay
-
-# Run cowsay
-wapm run cowsay "Hello, world!"
-```
-
-For more information about wapm, check out the [website](https://www.wapm.io)
-and this [example program](https://github.com/wapm-packages/rust-wasi-example).
## Code Structure
@@ -80,7 +78,7 @@ Wasmer is structured into different directories:
- [`src`](./src): code related to the Wasmer executable itself
- [`lib`](./lib): modularized libraries that Wasmer uses under the hood
-- [`examples`](./examples): some useful examples to getting started with Wasmer
+- [`examples`](./examples): some useful examples for getting started with Wasmer
## Dependencies
@@ -111,7 +109,7 @@ If you have [Homebrew](https://brew.sh/) installed:
brew install cmake
```
-Or, in case you have [MacPorts](https://www.macports.org/install.php):
+Or, if you have [MacPorts](https://www.macports.org/install.php):
```sh
sudo port install cmake
@@ -129,6 +127,7 @@ sudo port install cmake
```sh
sudo apt install cmake pkg-config libssl-dev
```
+
@@ -141,6 +140,7 @@ sudo apt install cmake pkg-config libssl-dev
```sh
pkg install cmake
```
+
@@ -150,40 +150,40 @@ pkg install cmake
#### Windows (MSVC)
-Windows support is _experimental_. WASI is fully supported, but Emscripten support is on the works (this means
+Windows support is _experimental_. WASI is fully supported, but Emscripten support is in the works (this means
nginx and Lua do not work on Windows - you can track the progress on [this issue](https://github.com/wasmerio/wasmer/issues/176)).
1. Install [Visual Studio](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community&rel=15)
2. Install [Rust for Windows](https://win.rustup.rs)
-3. Install [Python for Windows](https://www.python.org/downloads/release/python-2714/). The Windows x86-64 MSI installer is fine.
- Make sure to enable "Add python.exe to Path" during installation.
-
-4. Install [Git for Windows](https://git-scm.com/download/win). Allow it to add `git.exe` to your PATH (default
+3. Install [Git for Windows](https://git-scm.com/download/win). Allow it to add `git.exe` to your PATH (default
settings for the installer are fine).
-5. Install [CMake](https://cmake.org/download/). Ensure CMake is in your PATH.
+4. Install [CMake](https://cmake.org/download/). Ensure CMake is in your PATH.
-6. Install [LLVM 8.0](https://prereleases.llvm.org/win-snapshots/LLVM-8.0.0-r351033-win64.exe)
-
-
+5. Install [LLVM 8.0](https://prereleases.llvm.org/win-snapshots/LLVM-8.0.0-r351033-win64.exe)
+
+
## Building
-[](https://blog.rust-lang.org/2019/07/04/Rust-1.36.0.html)
+
+[](https://blog.rust-lang.org/2019/09/26/Rust-1.38.0.html)
Wasmer is built with [Cargo](https://crates.io/), the Rust package manager.
The Singlepass backend requires nightly, so if you want to use it,
Set Rust Nightly:
+
```
rustup default nightly
```
-Otherwise an up to date (see badge above) verison of stable Rust will work.
+Otherwise an up to date (see badge above) version of stable Rust will work.
And install Wasmer
+
```sh
# checkout code
git clone https://github.com/wasmerio/wasmer.git
@@ -225,11 +225,10 @@ Each integration can be tested separately:
* Spec tests: `make spectests`
* Emscripten: `make emtests`
-* WASI: `make wasi`
+* WASI: `make wasitests`
* Middleware: `make middleware`
* C API: `make capi`
-
## Benchmarking
Benchmarks can be run with:
@@ -250,8 +249,8 @@ Below are some of the goals of this project (in order of priority):
- [x] It should be 100% compatible with the [WebAssembly spec tests](https://github.com/wasmerio/wasmer/tree/master/lib/spectests/spectests)
- [x] It should be fast _(partially achieved)_
- [x] Support WASI - released in [0.3.0](https://github.com/wasmerio/wasmer/releases/tag/0.3.0)
-- [x] Support Emscripten calls _(in the works)_
-- [ ] Support Go js ABI calls
+- [x] Support Emscripten calls
+- [ ] Support Go JS ABI calls _(in the works)_
## Architecture
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
new file mode 100644
index 000000000..2409dadda
--- /dev/null
+++ b/azure-pipelines.yml
@@ -0,0 +1,271 @@
+name: $(Build.SourceBranch)-$(date:yyyyMMdd)$(rev:.r)
+
+# The Different jobs (lint, test, build to run)
+jobs:
+ - job: changelog
+ steps:
+ - bash: |
+ git --no-pager diff --name-only HEAD $(git merge-base HEAD master) --exit-code CHANGELOG.md
+ displayName: Changelog Updated
+
+ - job: lint
+ pool:
+ vmImage: "macos-10.14"
+ steps:
+ - checkout: self
+ submodules: true
+ - template: .azure/install-rust.yml
+ - script: |
+ rustup component add rustfmt
+ rustup component add clippy || cargo install --git https://github.com/rust-lang/rust-clippy/ --force clippy
+ displayName: Lint dependencies
+ - script: cargo fmt --all -- --check
+ displayName: Lint
+ variables:
+ rust_toolchain: '1.38.0'
+
+ - job: Test
+ strategy:
+ matrix:
+ linux:
+ imageName: "ubuntu-16.04"
+ rust_toolchain: nightly-2019-08-15
+ mac:
+ imageName: "macos-10.14"
+ rust_toolchain: nightly-2019-08-15
+ # By default schannel checks revocation of certificates unlike some other SSL
+ # backends, but we've historically had problems on CI where a revocation
+ # server goes down presumably. See #43333 for more info
+ CARGO_HTTP_CHECK_REVOKE: false
+ windows:
+ imageName: "vs2017-win2016"
+ rust_toolchain: '1.38.0'
+ pool:
+ vmImage: $(imageName)
+ condition: in(variables['Build.SourceBranch'], 'refs/heads/master', 'refs/heads/staging', 'refs/heads/trying')
+ steps:
+ - checkout: self
+ submodules: true
+ - template: .azure/install-rust.yml
+ - template: .azure/install-llvm.yml
+ - template: .azure/install-sccache.yml
+ - template: .azure/install-cmake.yml
+ - bash: |
+ hostname
+ uname -a
+ displayName: System info (*nix)
+ condition: and(succeeded(), not(eq(variables['Agent.OS'], 'Windows_NT')))
+ - bash: |
+ cat /proc/cpuinfo
+ cat /proc/meminfo
+ displayName: System info - Extended (Linux)
+ condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
+ - bash: |
+ sysctl -a | grep machdep.cpu
+ displayName: System info - Extended (Mac)
+ condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin'))
+ - bash: make test
+ displayName: Tests (*nix)
+ condition: and(succeeded(), not(eq(variables['Agent.OS'], 'Windows_NT')))
+ - bash: make spectests-cranelift
+ displayName: Tests (Windows)
+ condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
+
+ - job: Check
+ pool:
+ vmImage: "ubuntu-16.04"
+ variables:
+ rust_toolchain: nightly-2019-08-15
+ condition: in(variables['Build.SourceBranch'], 'refs/heads/master', 'refs/heads/staging', 'refs/heads/trying')
+ steps:
+ - checkout: self
+ submodules: true
+ - template: .azure/install-rust.yml
+ - template: .azure/install-llvm.yml
+ - template: .azure/install-sccache.yml
+ - template: .azure/install-cmake.yml
+ - bash: make check
+ displayName: Check with Flags
+ condition: and(succeeded(), not(eq(variables['Agent.OS'], 'Windows_NT')))
+
+ - job: Build_CLI
+ strategy:
+ matrix:
+ linux:
+ imageName: "ubuntu-16.04"
+ rust_toolchain: nightly-2019-08-15
+ mac:
+ imageName: "macos-10.14"
+ rust_toolchain: nightly-2019-08-15
+ MACOSX_DEPLOYMENT_TARGET: 10.10
+ windows:
+ imageName: "vs2017-win2016"
+ rust_toolchain: '1.38.0'
+ # RUSTFLAGS: -Ctarget-feature=+crt-static
+ pool:
+ vmImage: $(imageName)
+ condition: |
+ or(
+ in(variables['Build.SourceBranch'], 'refs/heads/master', 'refs/heads/staging', 'refs/heads/trying'),
+ startsWith(variables['Build.SourceBranch'], 'refs/tags')
+ )
+ steps:
+ - checkout: self
+ submodules: true
+ - template: .azure/install-rust.yml
+ - template: .azure/install-llvm.yml
+ - template: .azure/install-sccache.yml
+ - template: .azure/install-cmake.yml
+ - template: .azure/install-innosetup.yml
+ - bash: |
+ mkdir -p artifacts
+ displayName: Create Artifacts Dir
+ - bash: make release
+ displayName: Build (*nix)
+ condition: and(succeeded(), not(eq(variables['Agent.OS'], 'Windows_NT')))
+ - bash: make release-llvm
+ displayName: Build (Windows)
+ condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
+ - bash: |
+ make wapm
+ displayName: Build WAPM
+ condition: |
+ startsWith(variables['Build.SourceBranch'], 'refs/tags')
+ - bash: |
+ make build-install
+ cp ./wasmer.tar.gz ./artifacts/$(./scripts/binary-name.sh)
+ displayName: Build Distribution (*nix)
+ condition: |
+ and(
+ succeeded(),
+ startsWith(variables['Build.SourceBranch'], 'refs/tags'),
+ not(eq(variables['Agent.OS'], 'Windows_NT'))
+ )
+ - bash: |
+ cd ./src/installer
+ iscc wasmer.iss
+ cp WasmerInstaller.exe ../../artifacts/wasmer-windows.exe
+ displayName: Build Distribution (Windows)
+ condition: |
+ and(
+ succeeded(),
+ startsWith(variables['Build.SourceBranch'], 'refs/tags'),
+ eq(variables['Agent.OS'], 'Windows_NT')
+ )
+ - publish: $(System.DefaultWorkingDirectory)/artifacts
+ artifact: cli-$(Agent.OS)
+
+ - job: Build_Library
+ strategy:
+ matrix:
+ linux:
+ imageName: "ubuntu-16.04"
+ rust_toolchain: nightly-2019-08-15
+ mac:
+ imageName: "macos-10.14"
+ rust_toolchain: nightly-2019-08-15
+ MACOSX_DEPLOYMENT_TARGET: 10.10
+ windows:
+ imageName: "vs2017-win2016"
+ rust_toolchain: '1.38.0'
+ # RUSTFLAGS: -Ctarget-feature=+crt-static
+ pool:
+ vmImage: $(imageName)
+ condition: |
+ or(
+ in(variables['Build.SourceBranch'], 'refs/heads/master', 'refs/heads/staging', 'refs/heads/trying'),
+ startsWith(variables['Build.SourceBranch'], 'refs/tags')
+ )
+ steps:
+ - checkout: self
+ submodules: true
+ - template: .azure/install-rust.yml
+ # - template: .azure/install-llvm.yml
+ - template: .azure/install-sccache.yml
+ - template: .azure/install-cmake.yml
+ - bash: |
+ mkdir -p artifacts
+ displayName: Create Artifacts Dir
+ - bash: |
+ make capi
+ make test-capi
+ cp target/release/libwasmer_runtime_c_api.so ./artifacts
+ displayName: Build c-api (Linux)
+ condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
+ - bash: |
+ make capi
+ make test-capi
+ install_name_tool -id "@rpath/libwasmer_runtime_c_api.dylib" target/release/libwasmer_runtime_c_api.dylib
+ cp target/release/libwasmer_runtime_c_api.dylib ./artifacts
+ displayName: Build c-api (Darwin)
+ condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin'))
+ - bash: |
+ make capi
+ # Tests are failing on Windows, comment for now
+ # make test-capi
+ cp target/release/wasmer_runtime_c_api.dll ./artifacts
+ displayName: Build c-api (Windows)
+ condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
+ - publish: $(System.DefaultWorkingDirectory)/artifacts
+ artifact: library-$(Agent.OS)
+
+ - job: Publish
+ dependsOn:
+ - Build_CLI
+ - Build_Library
+ condition: |
+ startsWith(variables['Build.SourceBranch'], 'refs/tags')
+ steps:
+ # - download: current
+ - task: DownloadPipelineArtifact@1
+ inputs:
+ targetPath: $(Build.ArtifactStagingDirectory)
+ - bash: |
+ ls $ARTIFACT_STAGING_DIRECTORY
+ displayName: List Artifacts
+ env:
+ ARTIFACT_STAGING_DIRECTORY: $(Build.ArtifactStagingDirectory)
+ - script: VERSION_TAG=`git describe --tags` && echo "##vso[task.setvariable variable=VERSION_TAG]$VERSION_TAG"
+ displayName: Set the tag name as an environment variable
+ - task: GithubRelease@0
+ displayName: "Create GitHub Release"
+ condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags'))
+ inputs:
+ gitHubConnection: 'wasmer'
+ repositoryName: 'wasmerio/wasmer'
+ action: 'create'
+ target: '$(Build.SourceVersion)'
+ title: '$(VERSION_TAG)'
+ addChangeLog: false
+ tagSource: 'auto'
+ # TODO: automate it all by getting the release notes from somewhere else and using the `releaseNotesFile` key
+ isDraft: false
+ isPreRelease: false
+ assets: '$(Build.ArtifactStagingDirectory)/**'
+
+ - job: Docs
+ pool:
+ vmImage: "ubuntu-16.04"
+ variables:
+ rust_toolchain: nightly-2019-08-15
+ steps:
+ - checkout: self
+ submodules: true
+ - template: .azure/install-rust.yml
+ - template: .azure/install-llvm.yml
+ - template: .azure/install-sccache.yml
+ - template: .azure/install-cmake.yml
+ - bash: |
+ make docs
+ displayName: Build documentation
+
+# We only run the pipelines on PRs to Master
+pr:
+ - master
+
+# Otherwise, we test in any of this branches (master or bors related)
+trigger:
+ - master
+ - staging
+ - trying
+ - refs/tags/*
diff --git a/bors.toml b/bors.toml
index 5fadbdfa0..1003d9678 100644
--- a/bors.toml
+++ b/bors.toml
@@ -1,10 +1,5 @@
status = [
- "ci/circleci: lint",
- "ci/circleci: test",
- "ci/circleci: test-macos",
- "ci/circleci: test-stable",
- "ci/circleci: test-rust-example",
- "continuous-integration/appveyor/branch"
+ "wasmerio.wasmer"
]
required_approvals = 1
timeout_sec = 7200
diff --git a/docs/assets/languages/c.svg b/docs/assets/languages/c.svg
new file mode 100755
index 000000000..e2492e6b5
--- /dev/null
+++ b/docs/assets/languages/c.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/docs/assets/languages/cpp.svg b/docs/assets/languages/cpp.svg
new file mode 100755
index 000000000..84035b8b6
--- /dev/null
+++ b/docs/assets/languages/cpp.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/docs/assets/languages/csharp.svg b/docs/assets/languages/csharp.svg
new file mode 100755
index 000000000..28c059f1e
--- /dev/null
+++ b/docs/assets/languages/csharp.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/docs/assets/languages/go.svg b/docs/assets/languages/go.svg
new file mode 100755
index 000000000..e9eda28d1
--- /dev/null
+++ b/docs/assets/languages/go.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/docs/assets/languages/js.svg b/docs/assets/languages/js.svg
new file mode 100755
index 000000000..6a186f383
--- /dev/null
+++ b/docs/assets/languages/js.svg
@@ -0,0 +1,8 @@
+
+
diff --git a/docs/assets/languages/php.svg b/docs/assets/languages/php.svg
new file mode 100755
index 000000000..8d883e309
--- /dev/null
+++ b/docs/assets/languages/php.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/docs/assets/languages/postgres.svg b/docs/assets/languages/postgres.svg
new file mode 100644
index 000000000..65149a5fd
--- /dev/null
+++ b/docs/assets/languages/postgres.svg
@@ -0,0 +1,22 @@
+
+
+
+
\ No newline at end of file
diff --git a/docs/assets/languages/python.svg b/docs/assets/languages/python.svg
new file mode 100755
index 000000000..9b7eee497
--- /dev/null
+++ b/docs/assets/languages/python.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/docs/assets/languages/r.svg b/docs/assets/languages/r.svg
new file mode 100644
index 000000000..b464dd337
--- /dev/null
+++ b/docs/assets/languages/r.svg
@@ -0,0 +1,14 @@
+
diff --git a/docs/assets/languages/ruby.svg b/docs/assets/languages/ruby.svg
new file mode 100755
index 000000000..4e5ef4b60
--- /dev/null
+++ b/docs/assets/languages/ruby.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/docs/assets/languages/rust.svg b/docs/assets/languages/rust.svg
new file mode 100755
index 000000000..4d04ee684
--- /dev/null
+++ b/docs/assets/languages/rust.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/docs/assets/languages/swift.svg b/docs/assets/languages/swift.svg
new file mode 100644
index 000000000..c04de9bce
--- /dev/null
+++ b/docs/assets/languages/swift.svg
@@ -0,0 +1,10 @@
+
+
diff --git a/docs/debugging.md b/docs/debugging.md
new file mode 100644
index 000000000..8d49d5217
--- /dev/null
+++ b/docs/debugging.md
@@ -0,0 +1,50 @@
+# Debugging Wasmer
+
+## When is this document useful?
+
+If you're developing wasmer or running into issues, this document will explain to useful techniques and common errors.
+
+## Tracing syscalls
+
+To trace syscalls, compile with the `debug` feature (`cargo build --features "debug"`). For even more verbose messages, use the `trace` flag.
+
+## Tracing calls
+
+TODO: did we disable tracing calls? if not talk about how to enable it
+TODO: someone with more context on the backends mention which backends this works for
+
+If you'd like to see all calls and you're using emscripten, you can use a symbol map to get better error output with the `em-symbol-map` flag.
+
+## Common things that can go wrong
+
+### Missing imports
+
+If, when attempting to run a wasm module, you get an error about missing imports there are a number of things that could be going wrong.
+
+The most likely is that we haven't implemented those imports for your ABI. If you're targeting emscripten, this is probably the issue.
+
+However if that's not the case, then there's a chance that you're using an unsupported ABI (let us know!) or that the wasm is invalid for the detected ABI. (TODO: link to wasm contracts or something)
+
+### Hitting `undefined`
+
+If this happens it's because wasmer does not have full support for whatever feature you tried to use. Running with tracing on can help clarify the issue if it's not clear from the message.
+
+To fix this, file an issue letting us know that wasmer is missing a feature that's important to you. If you'd like, you can try to implement it yourself and send us a PR.
+
+### No output
+
+If you're seeing no output from running the wasm module then it may be that:
+- this is the intended behavior of the wasm module
+- or it's very slow to compile (try compiling with a faster backend like cranelift (the default) or singlepass (requires nightly))
+
+### Segfault
+
+If you're seeing a segfault while developing wasmer, chances are that it's a cache issue. We reset the cache on every version bump, but if you're running it from source then the cache may become invalid, which can lead to segfaults.
+
+To fix this delete the cache with `wasmer cache clean` or run the command with the `disable-cache` flag (`wasmer run some.wasm --disable-cache`)
+
+If you're seeing a segfault with a released version of wasmer, please file an issue so we can ship an updated version as soon as possible.
+
+### Something else
+
+If none of this has helped with your issue, let us know and we'll do our best to help.
diff --git a/docs/feature_matrix.md b/docs/feature_matrix.md
new file mode 100644
index 000000000..18d303270
--- /dev/null
+++ b/docs/feature_matrix.md
@@ -0,0 +1,42 @@
+# Feature Table
+
+## Compiler Backend
+
+| | Singlepass | Cranelift | LLVM |
+| - | :-: | :-: | :-: |
+| Caching | ✅ | ✅ | ✅ |
+| Emscripten | ✅ | ✅ | ✅ |
+| Metering | ✅ | ⬜ | ✅ |
+| Multi-value return | ⬜ | ⬜ | ⬜ |
+| OSR | 🔄 | ⬜ | 🔄 |
+| SIMD | ⬜ | ⬜ | ✅ |
+| WASI | ✅ | ✅ | ✅ |
+| WASMER_BACKTRACE | ✅ | ⬜ | ⬜ |
+
+## Operating System
+| | GNU Linux | Mac OSX | Windows NT |
+| - | :-: | :-: | :-: |
+| Cranelift Backend | ✅ | ✅ | ✅ |
+| LLVM Backend | ✅ | ✅ | ✅ |
+| Singlepass Backend | ✅ | ✅ | [#347](https://github.com/wasmerio/wasmer/issues/347) |
+| WASI | ✅ | ✅ | ✅* |
+
+* `poll_fd` is not fully implemented for Windows yet
+
+## Language integration
+
+TODO: define a set of features that are relevant and mark them here
+
+Current ideas:
+
+- Callbacks
+- Metering
+- Caching
+
+> TODO: expand this table, it's focused on new features that we haven't implemented yet and doesn't list all language integrations
+
+| | Rust | C / C++ | Go | Python | Ruby |
+| - | :-: | :-: | :-: | :-: | :-: |
+| Terminate in host call | ✅ | ⬜ | ⬜ | ⬜ | ⬜ |
+| WASI | ✅ | ✅ | 🔄 | ⬜ | ⬜ |
+| WASI FS API | ✅ | ⬜ | ⬜ | ⬜ | ⬜ |
diff --git a/examples/callback-guest/README.md b/examples/callback-guest/README.md
new file mode 100644
index 000000000..6439ef00d
--- /dev/null
+++ b/examples/callback-guest/README.md
@@ -0,0 +1,5 @@
+# Call back guest
+
+This is part of the `callback` example. This Wasm module passes host imports and its own functions to the Wasm host to execute.
+
+See `examples/callback.rs` for the host
diff --git a/examples/callback-guest/callback-guest.rs b/examples/callback-guest/callback-guest.rs
new file mode 100644
index 000000000..129ad05c8
--- /dev/null
+++ b/examples/callback-guest/callback-guest.rs
@@ -0,0 +1,24 @@
+extern "C" {
+ fn call_guest_fn(f: u32) -> u32;
+ fn call_guest_fn2(f: u32) -> u32;
+ fn host_callback() -> u32;
+}
+
+#[no_mangle]
+fn test_callback() -> u32 {
+ 42
+}
+
+#[no_mangle]
+fn test_callback2() -> u32 {
+ 45
+}
+
+fn main() {
+ unsafe { call_guest_fn(test_callback as usize as u32) };
+ unsafe { call_guest_fn(host_callback as usize as u32) };
+ unsafe { call_guest_fn(test_callback2 as usize as u32) };
+ unsafe { call_guest_fn2(test_callback2 as usize as u32) };
+ unsafe { call_guest_fn2(test_callback as usize as u32) };
+ unsafe { call_guest_fn2(host_callback as usize as u32) };
+}
diff --git a/examples/callback-guest/callback-guest.wasm b/examples/callback-guest/callback-guest.wasm
new file mode 100755
index 000000000..055582975
Binary files /dev/null and b/examples/callback-guest/callback-guest.wasm differ
diff --git a/examples/callback.rs b/examples/callback.rs
new file mode 100644
index 000000000..e5969fec9
--- /dev/null
+++ b/examples/callback.rs
@@ -0,0 +1,46 @@
+/// This example demonstrates the use of callbacks: calling functions (Host and Wasm)
+/// passed to us from the Wasm via hostcall
+use wasmer_runtime::{compile_with, compiler_for_backend, func, imports, Backend, Ctx};
+use wasmer_runtime_core::{structures::TypedIndex, types::TableIndex};
+
+static WASM: &'static str = "examples/callback-guest/callback-guest.wasm";
+
+/// This function matches our arbitrarily decided callback signature
+/// in this example we'll only call functions that take no arguments and return one value
+fn host_callback(_ctx: &mut Ctx) -> u32 {
+ 55
+}
+
+fn call_guest_fn(ctx: &mut Ctx, guest_fn: u32) -> u32 {
+ // We get a TableIndex from our raw value passed in
+ let guest_fn_typed = TableIndex::new(guest_fn as usize);
+ // and use it to call the corresponding function
+ let result = ctx.call_with_table_index(guest_fn_typed, &[]).unwrap();
+
+ println!("Guest fn {} returned {:?}", guest_fn, result);
+
+ 0
+}
+
+fn main() {
+ let wasm_bytes =
+ std::fs::read(WASM).expect(&format!("Could not read in WASM plugin at {}", WASM));
+
+ let imports = imports! {
+ "env" => {
+ "call_guest_fn" => func!(call_guest_fn),
+ "call_guest_fn2" => func!(call_guest_fn),
+ "host_callback" => func!(host_callback),
+ },
+ };
+
+ let compiler = compiler_for_backend(Backend::default()).unwrap();
+ let module = compile_with(&wasm_bytes[..], compiler.as_ref()).unwrap();
+ let instance = module
+ .instantiate(&imports)
+ .expect("failed to instantiate wasm module");
+
+ let entry_point = instance.func::<(u32, u32), u32>("main").unwrap();
+
+ entry_point.call(0, 0).expect("START");
+}
diff --git a/examples/fib.wat b/examples/fib.wat
new file mode 100644
index 000000000..a797fdae4
--- /dev/null
+++ b/examples/fib.wat
@@ -0,0 +1,20 @@
+(module
+ (func $main (result i32)
+ (call $fib (i32.const 40))
+ )
+
+ (func $fib (param $n i32) (result i32)
+ (if (i32.eq (get_local $n) (i32.const 0))
+ (then (return (i32.const 1)))
+ )
+ (if (i32.eq (get_local $n) (i32.const 1))
+ (then (return (i32.const 1)))
+ )
+ (i32.add
+ (call $fib (i32.sub (get_local $n) (i32.const 1)))
+ (call $fib (i32.sub (get_local $n) (i32.const 2)))
+ )
+ )
+
+ (export "main" (func $main))
+)
diff --git a/examples/hello_world/Cargo.toml b/examples/hello_world/Cargo.toml
new file mode 100644
index 000000000..a71d719ed
--- /dev/null
+++ b/examples/hello_world/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "hello_world"
+version = "0.1.0"
+authors = ["losfair "]
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/examples/hello_world/src/main.rs b/examples/hello_world/src/main.rs
new file mode 100644
index 000000000..ca24b9cea
--- /dev/null
+++ b/examples/hello_world/src/main.rs
@@ -0,0 +1,7 @@
+fn main() {
+ for i in 0..8 {
+ let s = format!("Hello, {}", i);
+ println!("{}", s);
+ }
+ panic!("OK");
+}
diff --git a/examples/iterative_hash/src/main.rs b/examples/iterative_hash/src/main.rs
index f25672047..66ed10405 100644
--- a/examples/iterative_hash/src/main.rs
+++ b/examples/iterative_hash/src/main.rs
@@ -1,7 +1,13 @@
use blake2::{Blake2b, Digest};
+use std::time::{Duration, SystemTime};
fn main() {
let mut data: Vec = b"test".to_vec();
+ let now = SystemTime::now();
+
+ let mut last_millis: u128 = 0;
+ let mut round_count: usize = 0;
+ let mut record_count: usize = 0;
for i in 0.. {
let mut hasher = Blake2b::new();
@@ -9,8 +15,15 @@ fn main() {
let out = hasher.result();
data = out.to_vec();
- if i % 1000000 == 0 {
- println!("Round {}: {:?}", i, data);
+ if i != 0 && i % 1000 == 0 {
+ let millis = now.elapsed().unwrap().as_millis();
+ let diff = millis - last_millis;
+ if diff >= 100 {
+ record_count += 1;
+ println!("{}", ((i - round_count) as u128) * 1000000 / diff );
+ last_millis = millis;
+ round_count = i;
+ }
}
}
}
diff --git a/examples/many_params.wat b/examples/many_params.wat
new file mode 100644
index 000000000..db5e4bb9b
--- /dev/null
+++ b/examples/many_params.wat
@@ -0,0 +1,57 @@
+;; Test case for correctness of reading state with the presence of parameters passed on (machine) stack.
+;; Usage: Run with a backend with support for OSR. Interrupt execution randomly.
+;; Should see the stack frame for `$foo` to have locals `[0] = 1, [1] = 2, [2] = 3, [3] = 4, [4] = 5, [5] = 6, [6] = 7, [7] = 8` with high probability.
+;; If the logic for reading stack parameters is broken, it's likely to see `[0] = 1, [1] = 2, [2] = 3, [3] = 4, [4] = 5, [5] = ?, [6] = ?, [7] = ?`.
+
+(module
+ (import "wasi_unstable" "proc_exit" (func $__wasi_proc_exit (param i32)))
+ (func $long_running
+ (local $count i32)
+ (loop
+ (if (i32.eq (get_local $count) (i32.const 1000000)) (then (return)))
+ (set_local $count (i32.add (i32.const 1) (get_local $count)))
+ (br 0)
+ )
+ (unreachable)
+ )
+
+ (func $foo (param i32) (param i64) (param i32) (param i32) (param i32) (param i64) (param i64) (param i64) (result i32)
+ (set_local 2 (i32.const 3))
+ (call $long_running)
+ (i32.add
+ (i32.mul (i32.const 2) (get_local 0))
+ (i32.add
+ (i32.mul (i32.const 3) (i32.wrap/i64 (get_local 1)))
+ (i32.add
+ (i32.mul (i32.const 5) (get_local 2))
+ (i32.add
+ (i32.mul (i32.const 7) (get_local 3))
+ (i32.add
+ (i32.mul (i32.const 11) (get_local 4))
+ (i32.add
+ (i32.mul (i32.const 13) (i32.wrap/i64 (get_local 5)))
+ (i32.add
+ (i32.mul (i32.const 17) (i32.wrap/i64 (get_local 6)))
+ (i32.mul (i32.const 19) (i32.wrap/i64 (get_local 7)))
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ (func $_start (export "_start")
+ (local $count i32)
+ (loop
+ (if (i32.eq (get_local $count) (i32.const 10000)) (then (return)))
+ (set_local $count (i32.add (i32.const 1) (get_local $count)))
+ (call $foo (i32.const 1) (i64.const 2) (i32.const 30) (i32.const 4) (i32.const 5) (i64.const 6) (i64.const 7) (i64.const 8))
+ (if (i32.ne (i32.const 455))
+ (then unreachable)
+ )
+ (br 0)
+ )
+ (unreachable)
+ )
+)
diff --git a/examples/parallel-guest.wasm b/examples/parallel-guest.wasm
new file mode 100755
index 000000000..0f8d24dc7
Binary files /dev/null and b/examples/parallel-guest.wasm differ
diff --git a/examples/parallel-guest/Cargo.toml b/examples/parallel-guest/Cargo.toml
new file mode 100644
index 000000000..14e94e4e9
--- /dev/null
+++ b/examples/parallel-guest/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "parallel-guest"
+version = "0.1.0"
+authors = ["The Wasmer Engineering Team "]
+license = "MIT"
+edition = "2018"
+publish = false
+
+[dependencies]
+md5 = "0.6"
+lazy_static = "1"
diff --git a/examples/parallel-guest/src/main.rs b/examples/parallel-guest/src/main.rs
new file mode 100644
index 000000000..ead45932d
--- /dev/null
+++ b/examples/parallel-guest/src/main.rs
@@ -0,0 +1,82 @@
+#[macro_use]
+extern crate lazy_static;
+
+extern "C" {
+ fn get_hashed_password(ptr: u32, len: u32) -> u32;
+ fn print_char(c: u32);
+}
+
+fn print_str(s: &str) {
+ for c in s.chars() {
+ unsafe { print_char(c as u32) };
+ }
+ unsafe { print_char(b'\n' as u32) };
+}
+
+fn load_hashed_password() -> Option {
+ let mut buffer = String::with_capacity(32);
+ for _ in 0..32 {
+ buffer.push(0 as char);
+ }
+ let result =
+ unsafe { get_hashed_password(buffer.as_mut_ptr() as u32, buffer.capacity() as u32) };
+
+ if result == 0 {
+ Some(buffer)
+ } else {
+ None
+ }
+}
+
+lazy_static! {
+ static ref HASHED_PASSWORD: String = load_hashed_password().unwrap();
+}
+
+static PASSWORD_CHARS: &'static [u8] = b"abcdefghijklmnopqrstuvwxyz0123456789";
+
+// for simplicty we define a scheme for mapping numbers onto passwords
+fn num_to_password(mut num: u64) -> String {
+ let mut extra_zero = num == 0;
+ let mut out = String::new();
+ while num > 0 {
+ out.push(PASSWORD_CHARS[num as usize % PASSWORD_CHARS.len()] as char);
+ extra_zero = extra_zero || num == PASSWORD_CHARS.len() as u64;
+ num /= PASSWORD_CHARS.len() as u64;
+ }
+
+ if extra_zero {
+ out.push(PASSWORD_CHARS[0] as char);
+ }
+
+ out
+}
+
+#[repr(C)]
+struct RetStr {
+ ptr: u32,
+ len: u32,
+}
+
+// returns a (pointer, len) to the password or null
+#[no_mangle]
+fn check_password(from: u64, to: u64) -> u64 {
+ for i in from..to {
+ let password = num_to_password(i);
+ let digest = md5::compute(&password);
+
+ let hash_as_str = format!("{:x}", digest);
+ if hash_as_str == *HASHED_PASSWORD {
+ let ret = RetStr {
+ ptr: password.as_ptr() as usize as u32,
+ len: password.len() as u32,
+ };
+ // leak the data so ending the function doesn't corrupt it, if we cared the host could free it after
+ std::mem::forget(password);
+ return unsafe { std::mem::transmute(ret) };
+ }
+ }
+
+ return 0;
+}
+
+fn main() {}
diff --git a/examples/parallel/Cargo.toml b/examples/parallel/Cargo.toml
new file mode 100644
index 000000000..2353cf232
--- /dev/null
+++ b/examples/parallel/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "parallel"
+version = "0.1.0"
+authors = ["The Wasmer Engineering Team "]
+edition = "2018"
+repository = "https://github.com/wasmerio/wasmer"
+publish = false
+license = "MIT"
+
+[dependencies]
+rayon = "1.2"
+time = "0.1"
+wasmer-runtime = { path = "../../lib/runtime" }
+wasmer-runtime-core = { path = "../../lib/runtime-core" }
diff --git a/examples/parallel/README.md b/examples/parallel/README.md
new file mode 100644
index 000000000..fd4d1ad70
--- /dev/null
+++ b/examples/parallel/README.md
@@ -0,0 +1,5 @@
+# Parallel Wasmer example
+
+This example shows executing independent code from multiple threads on an "embarassingly parallel" problem
+
+This is a toy example of cracking md5 hashes. This is not a benchmark. This example is not optimized, it will compare poorly to an implementation that is.
diff --git a/examples/parallel/src/main.rs b/examples/parallel/src/main.rs
new file mode 100644
index 000000000..b68b0eaeb
--- /dev/null
+++ b/examples/parallel/src/main.rs
@@ -0,0 +1,137 @@
+use rayon::prelude::*;
+use wasmer_runtime::{compile_with, compiler_for_backend, func, imports, instantiate, Backend};
+use wasmer_runtime_core::{
+ memory::ptr::{Array, WasmPtr},
+ vm::Ctx,
+};
+
+static PLUGIN_LOCATION: &'static str = "../parallel-guest.wasm";
+
+fn get_hashed_password(ctx: &mut Ctx, ptr: WasmPtr, len: u32) -> u32 {
+ // "hard" password - 7 characters
+ //let password = b"2ab96390c7dbe3439de74d0c9b0b1767";
+ // "easy" password - 5 characters
+ let password = b"ab56b4d92b40713acc5af89985d4b786";
+ let memory = ctx.memory(0);
+ if let Some(writer) = ptr.deref(memory, 0, len) {
+ for (i, byte) in password.iter().enumerate() {
+ writer[i].set(*byte)
+ }
+
+ 0
+ } else {
+ u32::max_value()
+ }
+}
+
+#[repr(C)]
+struct RetStr {
+ ptr: u32,
+ len: u32,
+}
+
+fn print_char(_cxt: &mut Ctx, c: u32) {
+ print!("{}", c as u8 as char);
+}
+
+fn main() {
+ let wasm_bytes = std::fs::read(PLUGIN_LOCATION).expect(&format!(
+ "Could not read in WASM plugin at {}",
+ PLUGIN_LOCATION
+ ));
+
+ let imports = imports! {
+ "env" => {
+ "get_hashed_password" => func!(get_hashed_password),
+ "print_char" => func!(print_char),
+ },
+ };
+ let compiler = compiler_for_backend(Backend::default()).unwrap();
+ let module = compile_with(&wasm_bytes[..], compiler.as_ref()).unwrap();
+
+ println!("Parallel");
+ let start_ts = time::SteadyTime::now();
+ for outer in 0..1000u64 {
+ let start = outer * 1000;
+ let end = start + 1000;
+ let out = (start..=end)
+ .into_par_iter()
+ .filter_map(|i| {
+ let instance = module
+ .clone()
+ .instantiate(&imports)
+ .expect("failed to instantiate wasm module");
+ let check_password = instance.func::<(u64, u64), u64>("check_password").unwrap();
+ let j = i * 10000;
+ let result = check_password.call(j, j + 10000).unwrap();
+ print!(".");
+ use std::io::Write;
+ std::io::stdout().flush().unwrap();
+ if result != 0 {
+ let res: RetStr = unsafe { std::mem::transmute(result) };
+
+ let ctx = instance.context();
+ let memory = ctx.memory(0);
+ let wasm_ptr: WasmPtr = WasmPtr::new(res.ptr);
+ let password_str = wasm_ptr
+ .get_utf8_string(memory, res.len)
+ .unwrap()
+ .to_string();
+ Some(password_str)
+ } else {
+ None
+ }
+ })
+ .find_first(|_: &String| true);
+ if out.is_some() {
+ let end_ts = time::SteadyTime::now();
+ let delta = end_ts - start_ts;
+ println!(
+ "Password cracked: \"{}\" in {}.{:03}",
+ out.unwrap(),
+ delta.num_seconds(),
+ (delta.num_milliseconds() % 1000),
+ );
+ break;
+ }
+ }
+
+ println!("Serial:");
+ let start_ts = time::SteadyTime::now();
+ let instance =
+ instantiate(&wasm_bytes[..], &imports).expect("failed to instantiate wasm module");
+
+ let check_password = instance.func::<(u64, u64), u64>("check_password").unwrap();
+
+ let mut out: Option = None;
+ for i in (0..=u64::max_value()).step_by(10000) {
+ let result = check_password.call(i, i + 10000).unwrap();
+ print!(".");
+ use std::io::Write;
+ std::io::stdout().flush().unwrap();
+ if result != 0 {
+ out = Some(unsafe { std::mem::transmute(result) });
+ break;
+ }
+ }
+ println!("");
+
+ if let Some(res) = out {
+ let ctx = instance.context();
+ let memory = ctx.memory(0);
+ let wasm_ptr: WasmPtr = WasmPtr::new(res.ptr);
+
+ let password_str = wasm_ptr.get_utf8_string(memory, res.len).unwrap();
+
+ let end_ts = time::SteadyTime::now();
+ let delta = end_ts - start_ts;
+ println!(
+ "Password cracked: \"{}\" in {}.{:03}",
+ password_str,
+ delta.num_seconds(),
+ (delta.num_milliseconds() % 1000),
+ );
+ } else {
+ println!("Password not found!");
+ }
+}
diff --git a/examples/plugin.rs b/examples/plugin.rs
index c4f1d2de3..1f50108af 100644
--- a/examples/plugin.rs
+++ b/examples/plugin.rs
@@ -1,8 +1,9 @@
+use serde::{Deserialize, Serialize};
use wasmer_runtime::{func, imports, instantiate};
use wasmer_runtime_core::vm::Ctx;
use wasmer_wasi::{
generate_import_object,
- state::{self, WasiFile},
+ state::{self, WasiFile, WasiFsError},
types,
};
@@ -13,7 +14,7 @@ fn it_works(_ctx: &mut Ctx) -> i32 {
5
}
-#[derive(Debug)]
+#[derive(Debug, Serialize, Deserialize)]
pub struct LoggingWrapper {
pub wasm_module_name: String,
}
@@ -86,6 +87,8 @@ impl std::io::Write for LoggingWrapper {
}
// the WasiFile methods aren't relevant for a write-only Stdout-like implementation
+// we must use typetag and serde so that our trait objects can be safely Serialized and Deserialized
+#[typetag::serde]
impl WasiFile for LoggingWrapper {
fn last_accessed(&self) -> u64 {
0
@@ -99,6 +102,16 @@ impl WasiFile for LoggingWrapper {
fn size(&self) -> u64 {
0
}
+ fn set_len(&mut self, _len: u64) -> Result<(), WasiFsError> {
+ Ok(())
+ }
+ fn unlink(&mut self) -> Result<(), WasiFsError> {
+ Ok(())
+ }
+ fn bytes_available(&self) -> Result {
+ // return an arbitrary amount
+ Ok(1024)
+ }
}
/// Called by the program when it wants to set itself up
diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml
index 5c37cb47e..8d6a38140 100644
--- a/fuzz/Cargo.toml
+++ b/fuzz/Cargo.toml
@@ -10,6 +10,10 @@ cargo-fuzz = true
[dependencies]
wasmer-runtime = { path = "../lib/runtime" }
+wasmer-runtime-core = { path = "../lib/runtime-core" }
+wasmer = { path = "../" }
+wasmer-llvm-backend = { path = "../lib/llvm-backend" }
+wasmer-singlepass-backend = { path = "../lib/singlepass-backend" }
libfuzzer-sys = { git = "https://github.com/rust-fuzz/libfuzzer-sys.git" }
# Prevent this from interfering with workspaces
@@ -19,3 +23,11 @@ members = ["."]
[[bin]]
name = "simple_instantiate"
path = "fuzz_targets/simple_instantiate.rs"
+
+[[bin]]
+name = "validate_wasm"
+path = "fuzz_targets/validate_wasm.rs"
+
+[[bin]]
+name = "compile_wasm"
+path = "fuzz_targets/compile_wasm.rs"
diff --git a/fuzz/README.md b/fuzz/README.md
index cac0a320a..36f7e0c4c 100644
--- a/fuzz/README.md
+++ b/fuzz/README.md
@@ -10,12 +10,20 @@ $ cargo install cargo-fuzz
`cargo-fuzz` is documented in the [Rust Fuzz Book](https://rust-fuzz.github.io/book/cargo-fuzz.html).
-## Running a fuzzer
+## Running a fuzzer (simple_instantiate, validate_wasm, compile_wasm)
Once `cargo-fuzz` is installed, you can run the `simple_instantiate` fuzzer with
```sh
cargo fuzz run simple_instantiate
```
+or the `validate_wasm` fuzzer
+```sh
+cargo fuzz run validate_wasm
+```
+or the `compile_wasm` fuzzer
+```sh
+cargo fuzz run compile_wasm
+```
You should see output that looks something like this:
@@ -39,7 +47,7 @@ The fuzzer works best when it has examples of small Wasm files to start with. Us
```sh
mkdir spec-test-corpus
-for i in lib/spectests/spectests/*.wast; do wast2json $i -o spec-test-corpus/$(basename $i).json; done
+for i in lib/spectests/spectests/*.wast; do wast2json --enable-all $i -o spec-test-corpus/$(basename $i).json; done
mv spec-test-corpus/*.wasm fuzz/corpus/simple_instantiate/
rm -r spec-test-corpus
```
diff --git a/fuzz/fuzz_targets/compile_wasm.rs b/fuzz/fuzz_targets/compile_wasm.rs
new file mode 100644
index 000000000..e36d8c396
--- /dev/null
+++ b/fuzz/fuzz_targets/compile_wasm.rs
@@ -0,0 +1,25 @@
+#![no_main]
+#[macro_use]
+extern crate libfuzzer_sys;
+extern crate wasmer_runtime;
+extern crate wasmer_runtime_core;
+extern crate wasmer_llvm_backend;
+extern crate wasmer_singlepass_backend;
+
+use wasmer_runtime::{compile, compile_with};
+use wasmer_runtime_core::backend::Compiler;
+
+fn get_llvm_compiler() -> impl Compiler {
+ use wasmer_llvm_backend::LLVMCompiler;
+ LLVMCompiler::new()
+}
+fn get_singlepass_compiler() -> impl Compiler {
+ use wasmer_singlepass_backend::SinglePassCompiler;
+ SinglePassCompiler::new()
+}
+
+fuzz_target!(|data: &[u8]| {
+ let _ = compile_with(data, &get_llvm_compiler());
+ let _ = compile(data);
+ let _ = compile_with(data, &get_singlepass_compiler());
+});
diff --git a/fuzz/fuzz_targets/simple_instantiate.rs b/fuzz/fuzz_targets/simple_instantiate.rs
index 831bbb1a5..e4912546d 100644
--- a/fuzz/fuzz_targets/simple_instantiate.rs
+++ b/fuzz/fuzz_targets/simple_instantiate.rs
@@ -1,11 +1,9 @@
#![no_main]
-#[macro_use] extern crate libfuzzer_sys;
+#[macro_use]
+extern crate libfuzzer_sys;
extern crate wasmer_runtime;
-use wasmer_runtime::{
- instantiate,
- imports,
-};
+use wasmer_runtime::{imports, instantiate};
fuzz_target!(|data: &[u8]| {
let import_object = imports! {};
diff --git a/fuzz/fuzz_targets/validate_wasm.rs b/fuzz/fuzz_targets/validate_wasm.rs
new file mode 100644
index 000000000..f386105ec
--- /dev/null
+++ b/fuzz/fuzz_targets/validate_wasm.rs
@@ -0,0 +1,20 @@
+#![no_main]
+#[macro_use]
+extern crate libfuzzer_sys;
+
+extern crate wasmer;
+extern crate wasmer_runtime_core;
+
+use wasmer_runtime_core::backend::Features;
+
+fuzz_target!(|data: &[u8]| {
+ let _ = wasmer::utils::is_wasm_binary(data);
+ let _ = wasmer_runtime_core::validate_and_report_errors_with_features(
+ &data,
+ Features {
+ // Modify these values to explore additional parts of wasmer.
+ simd: false,
+ threads: false,
+ },
+ );
+});
diff --git a/install.sh b/install.sh
index b937505d6..e6c874e2a 100755
--- a/install.sh
+++ b/install.sh
@@ -1,8 +1,8 @@
#!/bin/sh
# This install script is intended to download and install the latest available
-# release of the wasmer.
-# Installer script inspired from:
+# release of Wasmer.
+# Installer script inspired by:
# 1) https://raw.githubusercontent.com/golang/dep/master/install.sh
# 2) https://sh.rustup.rs
# 3) https://yarnpkg.com/install.sh
@@ -22,7 +22,6 @@
set -e
-
reset="\033[0m"
red="\033[31m"
green="\033[32m"
@@ -209,9 +208,11 @@ initArch() {
printf "$cyan> Using WASMER_ARCH ($WASMER_ARCH).$reset\n"
ARCH="$WASMER_ARCH"
fi
+ # If you modify this list, please also modify scripts/binary-name.sh
case $ARCH in
amd64) ARCH="amd64";;
x86_64) ARCH="amd64";;
+ aarch64) ARCH="arm64";;
# i386) ARCH="386";;
*) printf "$red> The system architecture (${ARCH}) is not supported by this installation script.$reset\n"; exit 1;;
esac
@@ -257,10 +258,10 @@ wasmer_install() {
printf "${reset}Installing Wasmer and WAPM!$reset\n"
if [ "$WASMER_INSTALL_LOG" = "$WASMER_VERBOSE" ]; then
printf "
-${magenta1} ww
-${magenta1} wwwww
-${magenta1} ww wwwwww w
-${magenta1} wwwww wwwwwwwww
+${magenta1} ww
+${magenta1} wwwww
+${magenta1} ww wwwwww w
+${magenta1} wwwww wwwwwwwww
${magenta1}ww wwwwww w wwwwwww
${magenta1}wwwww wwwwwwwwww wwwww
${magenta1}wwwwww w wwwwwww wwwww
@@ -269,10 +270,10 @@ ${magenta1}wwwwwwwwwwwwwww wwwww wwwww
${magenta1}wwwwwwwwwwwwwww wwwww wwwww
${magenta1}wwwwwwwwwwwwwww wwwww wwwww
${magenta1}wwwwwwwwwwwwwww wwwww wwww
-${magenta1}wwwwwwwwwwwwwww wwwww
-${magenta1} wwwwwwwwwwww wwww
-${magenta1} wwwwwwww
-${magenta1} wwww
+${magenta1}wwwwwwwwwwwwwww wwwww
+${magenta1} wwwwwwwwwwww wwww
+${magenta1} wwwwwwww
+${magenta1} wwww
${reset}
"
fi
diff --git a/integration_tests/cowsay/README.md b/integration_tests/cowsay/README.md
index f44e6e680..660e457e7 100644
--- a/integration_tests/cowsay/README.md
+++ b/integration_tests/cowsay/README.md
@@ -1,9 +1,8 @@
# `cowsay` integration test
-
This starts Wasmer with the Cowsay WASI Wasm file. The test makes assertions on
the output of Wasmer. Run test with:
-```bash
+```sh
./integration_tests/cowsay/test.sh
```
diff --git a/lib/clif-backend/Cargo.toml b/lib/clif-backend/Cargo.toml
index d0bf64d7b..1dea62a24 100644
--- a/lib/clif-backend/Cargo.toml
+++ b/lib/clif-backend/Cargo.toml
@@ -1,41 +1,43 @@
[package]
name = "wasmer-clif-backend"
-version = "0.6.0"
+version = "0.11.0"
description = "Wasmer runtime Cranelift compiler backend"
license = "MIT"
authors = ["The Wasmer Engineering Team "]
repository = "https://github.com/wasmerio/wasmer"
+keywords = ["wasm", "webassembly", "compiler", "JIT", "AOT"]
+categories = ["wasm"]
edition = "2018"
readme = "README.md"
[dependencies]
-wasmer-runtime-core = { path = "../runtime-core", version = "0.6.0" }
-cranelift-native = { version = "0.31" }
-cranelift-codegen = { version = "0.31" }
-cranelift-entity = { version = "0.31" }
-cranelift-frontend = { package = "wasmer-clif-fork-frontend", version = "0.33" }
-cranelift-wasm = { package = "wasmer-clif-fork-wasm", version = "0.33" }
-target-lexicon = "0.4.0"
-wasmparser = "0.35.1"
+wasmer-runtime-core = { path = "../runtime-core", version = "0.11.0" }
+cranelift-native = "0.44.0"
+cranelift-codegen = "0.44.0"
+cranelift-entity = "0.44.0"
+cranelift-frontend = { package = "wasmer-clif-fork-frontend", version = "0.44.0" }
+cranelift-wasm = { package = "wasmer-clif-fork-wasm", version = "0.44.0" }
+target-lexicon = "0.8.1"
+wasmparser = "0.39.1"
byteorder = "1.3.2"
nix = "0.15.0"
libc = "0.2.60"
-rayon = "1.1.0"
+rayon = "1.1"
# Dependencies for caching.
[dependencies.serde]
-version = "1.0.99"
+version = "1.0"
features = ["rc"]
[dependencies.serde_derive]
-version = "1.0.98"
+version = "1.0"
[dependencies.serde_bytes]
-version = "0.11.2"
+version = "0.11"
[dependencies.serde-bench]
version = "0.0.7"
[target.'cfg(windows)'.dependencies]
-winapi = { version = "0.3.7", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] }
-wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.6.0" }
+winapi = { version = "0.3", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] }
+wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.11.0" }
[features]
debug = ["wasmer-runtime-core/debug"]
diff --git a/lib/clif-backend/README.md b/lib/clif-backend/README.md
index 2f29f4543..9c82c761d 100644
--- a/lib/clif-backend/README.md
+++ b/lib/clif-backend/README.md
@@ -1,21 +1,21 @@
-
+
-
-
+
+
-
+
-
+
@@ -36,7 +36,7 @@ This crate represents the Cranelift backend integration for Wasmer.
If you are using the `wasmer` CLI, you can specify the backend with:
-```bash
+```sh
wasmer run program.wasm --backend=cranelift
```
diff --git a/lib/clif-backend/src/code.rs b/lib/clif-backend/src/code.rs
index f5e4b3b7a..d86d19b4f 100644
--- a/lib/clif-backend/src/code.rs
+++ b/lib/clif-backend/src/code.rs
@@ -54,6 +54,10 @@ impl ModuleCodeGenerator
}
}
+ fn new_with_target(_: Option, _: Option, _: Option) -> Self {
+ unimplemented!("cross compilation is not available for clif backend")
+ }
+
fn backend_id() -> Backend {
Backend::Cranelift
}
@@ -128,166 +132,6 @@ impl ModuleCodeGenerator
.state
.initialize(&builder.func.signature, exit_block);
- #[cfg(feature = "debug")]
- {
- use cranelift_codegen::cursor::{Cursor, FuncCursor};
- use cranelift_codegen::ir::InstBuilder;
- let entry_ebb = func.layout.entry_block().unwrap();
- let ebb = func.dfg.make_ebb();
- func.layout.insert_ebb(ebb, entry_ebb);
- let mut pos = FuncCursor::new(&mut func).at_first_insertion_point(ebb);
- let params = pos.func.dfg.ebb_params(entry_ebb).to_vec();
-
- let new_ebb_params: Vec<_> = params
- .iter()
- .map(|¶m| {
- pos.func
- .dfg
- .append_ebb_param(ebb, pos.func.dfg.value_type(param))
- })
- .collect();
-
- let start_debug = {
- let signature = pos.func.import_signature(ir::Signature {
- call_conv: self.target_config().default_call_conv,
- params: vec![
- ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext),
- ir::AbiParam::new(ir::types::I32),
- ],
- returns: vec![],
- });
-
- let name = ir::ExternalName::testcase("strtdbug");
-
- pos.func.import_function(ir::ExtFuncData {
- name,
- signature,
- colocated: false,
- })
- };
-
- let end_debug = {
- let signature = pos.func.import_signature(ir::Signature {
- call_conv: self.target_config().default_call_conv,
- params: vec![ir::AbiParam::special(
- ir::types::I64,
- ir::ArgumentPurpose::VMContext,
- )],
- returns: vec![],
- });
-
- let name = ir::ExternalName::testcase("enddbug");
-
- pos.func.import_function(ir::ExtFuncData {
- name,
- signature,
- colocated: false,
- })
- };
-
- let i32_print = {
- let signature = pos.func.import_signature(ir::Signature {
- call_conv: self.target_config().default_call_conv,
- params: vec![
- ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext),
- ir::AbiParam::new(ir::types::I32),
- ],
- returns: vec![],
- });
-
- let name = ir::ExternalName::testcase("i32print");
-
- pos.func.import_function(ir::ExtFuncData {
- name,
- signature,
- colocated: false,
- })
- };
-
- let i64_print = {
- let signature = pos.func.import_signature(ir::Signature {
- call_conv: self.target_config().default_call_conv,
- params: vec![
- ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext),
- ir::AbiParam::new(ir::types::I64),
- ],
- returns: vec![],
- });
-
- let name = ir::ExternalName::testcase("i64print");
-
- pos.func.import_function(ir::ExtFuncData {
- name,
- signature,
- colocated: false,
- })
- };
-
- let f32_print = {
- let signature = pos.func.import_signature(ir::Signature {
- call_conv: self.target_config().default_call_conv,
- params: vec![
- ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext),
- ir::AbiParam::new(ir::types::F32),
- ],
- returns: vec![],
- });
-
- let name = ir::ExternalName::testcase("f32print");
-
- pos.func.import_function(ir::ExtFuncData {
- name,
- signature,
- colocated: false,
- })
- };
-
- let f64_print = {
- let signature = pos.func.import_signature(ir::Signature {
- call_conv: self.target_config().default_call_conv,
- params: vec![
- ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext),
- ir::AbiParam::new(ir::types::F64),
- ],
- returns: vec![],
- });
-
- let name = ir::ExternalName::testcase("f64print");
-
- pos.func.import_function(ir::ExtFuncData {
- name,
- signature,
- colocated: false,
- })
- };
-
- let vmctx = pos
- .func
- .special_param(ir::ArgumentPurpose::VMContext)
- .expect("missing vmctx parameter");
-
- let func_index = pos.ins().iconst(
- ir::types::I32,
- func_index.index() as i64 + self.module.info.imported_functions.len() as i64,
- );
-
- pos.ins().call(start_debug, &[vmctx, func_index]);
-
- for param in new_ebb_params.iter().cloned() {
- match pos.func.dfg.value_type(param) {
- ir::types::I32 => pos.ins().call(i32_print, &[vmctx, param]),
- ir::types::I64 => pos.ins().call(i64_print, &[vmctx, param]),
- ir::types::F32 => pos.ins().call(f32_print, &[vmctx, param]),
- ir::types::F64 => pos.ins().call(f64_print, &[vmctx, param]),
- _ => unimplemented!(),
- };
- }
-
- pos.ins().call(end_debug, &[vmctx]);
-
- pos.ins().jump(entry_ebb, new_ebb_params.as_slice());
- }
-
self.functions.push(func_env);
Ok(self.functions.last_mut().unwrap())
}
@@ -851,7 +695,9 @@ impl FuncEnvironment for FunctionEnvironment {
}
/// Generates a call IR with `callee` and `call_args` and inserts it at `pos`
- /// TODO: add support for imported functions
+ ///
+ /// It's about generating code that calls a local or imported function; in
+ /// WebAssembly: `(call $foo)`.
fn translate_call(
&mut self,
mut pos: FuncCursor,
@@ -923,20 +769,31 @@ impl FuncEnvironment for FunctionEnvironment {
readonly: true,
});
- let imported_vmctx_addr = pos.func.create_global_value(ir::GlobalValueData::Load {
- base: imported_func_struct_addr,
- offset: (vm::ImportedFunc::offset_vmctx() as i32).into(),
- global_type: ptr_type,
- readonly: true,
- });
+ let imported_func_ctx_addr =
+ pos.func.create_global_value(ir::GlobalValueData::Load {
+ base: imported_func_struct_addr,
+ offset: (vm::ImportedFunc::offset_func_ctx() as i32).into(),
+ global_type: ptr_type,
+ readonly: true,
+ });
+
+ let imported_func_ctx_vmctx_addr =
+ pos.func.create_global_value(ir::GlobalValueData::Load {
+ base: imported_func_ctx_addr,
+ offset: (vm::FuncCtx::offset_vmctx() as i32).into(),
+ global_type: ptr_type,
+ readonly: true,
+ });
let imported_func_addr = pos.ins().global_value(ptr_type, imported_func_addr);
- let imported_vmctx_addr = pos.ins().global_value(ptr_type, imported_vmctx_addr);
+ let imported_func_ctx_vmctx_addr = pos
+ .ins()
+ .global_value(ptr_type, imported_func_ctx_vmctx_addr);
let sig_ref = pos.func.dfg.ext_funcs[callee].signature;
let mut args = Vec::with_capacity(call_args.len() + 1);
- args.push(imported_vmctx_addr);
+ args.push(imported_func_ctx_vmctx_addr);
args.extend(call_args.iter().cloned());
Ok(pos
@@ -1117,7 +974,18 @@ impl FunctionCodeGenerator for CraneliftFunctionCodeGenerator {
fn feed_local(&mut self, ty: WpType, n: usize) -> Result<(), CodegenError> {
let mut next_local = self.next_local;
- cranelift_wasm::declare_locals(&mut self.builder(), n as u32, ty, &mut next_local)?;
+ let mut builder = FunctionBuilder::new(
+ &mut self.func,
+ &mut self.func_translator.func_ctx,
+ &mut self.position,
+ );
+ cranelift_wasm::declare_locals(
+ &mut builder,
+ n as u32,
+ ty,
+ &mut next_local,
+ &mut self.func_env,
+ )?;
self.next_local = next_local;
Ok(())
}
diff --git a/lib/clif-backend/src/lib.rs b/lib/clif-backend/src/lib.rs
index eed22d39e..06bffc791 100644
--- a/lib/clif-backend/src/lib.rs
+++ b/lib/clif-backend/src/lib.rs
@@ -1,5 +1,10 @@
+//! The Wasmer Cranelift Backend crate is used to compile wasm binary code via parse events from the
+//! Wasmer runtime common parser code into machine code.
+//!
+
#![deny(
dead_code,
+ missing_docs,
nonstandard_style,
unused_imports,
unused_mut,
@@ -7,6 +12,9 @@
unused_unsafe,
unreachable_patterns
)]
+#![doc(html_favicon_url = "https://wasmer.io/static/icons/favicon.ico")]
+#![doc(html_logo_url = "https://avatars3.githubusercontent.com/u/44205449?s=200&v=4")]
+
mod cache;
mod code;
mod libcalls;
@@ -31,7 +39,7 @@ extern crate serde;
fn get_isa() -> Box {
let flags = {
let mut builder = settings::builder();
- builder.set("opt_level", "best").unwrap();
+ builder.set("opt_level", "speed_and_size").unwrap();
builder.set("jump_tables_enabled", "false").unwrap();
if cfg!(not(test)) {
@@ -39,7 +47,7 @@ fn get_isa() -> Box {
}
let flags = settings::Flags::new(builder);
- debug_assert_eq!(flags.opt_level(), settings::OptLevel::Best);
+ debug_assert_eq!(flags.opt_level(), settings::OptLevel::SpeedAndSize);
flags
};
isa::lookup(Triple::host()).unwrap().finish(flags)
@@ -50,6 +58,8 @@ pub const VERSION: &str = env!("CARGO_PKG_VERSION");
use wasmer_runtime_core::codegen::SimpleStreamingCompilerGen;
+/// Streaming compiler implementation for the Cranelift backed. Compiles web assembly binary into
+/// machine code.
pub type CraneliftCompiler = SimpleStreamingCompilerGen<
code::CraneliftModuleCodeGenerator,
code::CraneliftFunctionCodeGenerator,
diff --git a/lib/clif-backend/src/relocation.rs b/lib/clif-backend/src/relocation.rs
index 50a032095..a86bdeec9 100644
--- a/lib/clif-backend/src/relocation.rs
+++ b/lib/clif-backend/src/relocation.rs
@@ -105,7 +105,7 @@ impl binemit::RelocSink for RelocSink {
_ebb_offset: binemit::CodeOffset,
) {
// This should use the `offsets` field of `ir::Function`.
- unimplemented!();
+ unimplemented!("RelocSink::reloc_ebb");
}
fn reloc_external(
&mut self,
@@ -146,7 +146,7 @@ impl binemit::RelocSink for RelocSink {
DYNAMIC_MEM_GROW => VmCallKind::DynamicMemoryGrow,
DYNAMIC_MEM_SIZE => VmCallKind::DynamicMemorySize,
- _ => unimplemented!(),
+ _ => unimplemented!("reloc_external VmCall::Local {}", index),
})),
IMPORT_NAMESPACE => RelocationType::VmCall(VmCall::Import(match index {
STATIC_MEM_GROW => VmCallKind::StaticMemoryGrow,
@@ -157,10 +157,10 @@ impl binemit::RelocSink for RelocSink {
DYNAMIC_MEM_GROW => VmCallKind::DynamicMemoryGrow,
DYNAMIC_MEM_SIZE => VmCallKind::DynamicMemorySize,
- _ => unimplemented!(),
+ _ => unimplemented!("reloc_external VmCall::Import {}", index),
})),
SIG_NAMESPACE => RelocationType::Signature(SigIndex::new(index as usize)),
- _ => unimplemented!(),
+ _ => unimplemented!("reloc_external SigIndex {}", index),
};
self.external_relocs.push(ExternalRelocation {
reloc,
@@ -202,13 +202,18 @@ impl binemit::RelocSink for RelocSink {
}
}
}
+
+ fn reloc_constant(&mut self, _: u32, _: cranelift_codegen::binemit::Reloc, _: u32) {
+ unimplemented!("RelocSink::reloc_constant")
+ }
+
fn reloc_jt(
&mut self,
_offset: binemit::CodeOffset,
_reloc: binemit::Reloc,
_jt: ir::JumpTable,
) {
- unimplemented!();
+ unimplemented!("RelocSink::reloc_jt");
}
}
diff --git a/lib/clif-backend/src/resolver.rs b/lib/clif-backend/src/resolver.rs
index 4e4f807df..efc038d58 100644
--- a/lib/clif-backend/src/resolver.rs
+++ b/lib/clif-backend/src/resolver.rs
@@ -1,29 +1,31 @@
-use crate::{cache::BackendCache, trampoline::Trampolines};
use crate::{
+ cache::BackendCache,
libcalls,
relocation::{
ExternalRelocation, LibCall, LocalRelocation, LocalTrapSink, Reloc, RelocSink,
RelocationType, TrapSink, VmCall, VmCallKind,
},
signal::HandlerData,
+ trampoline::Trampolines,
+};
+use byteorder::{ByteOrder, LittleEndian};
+use cranelift_codegen::{
+ binemit::{Stackmap, StackmapSink},
+ ir, isa, Context,
};
use rayon::prelude::*;
-
-use byteorder::{ByteOrder, LittleEndian};
-use cranelift_codegen::{ir, isa, Context};
use std::{
mem,
ptr::{write_unaligned, NonNull},
sync::Arc,
};
-
-use wasmer_runtime_core::cache::Error as CacheError;
use wasmer_runtime_core::{
self,
backend::{
sys::{Memory, Protect},
SigRegistry,
},
+ cache::Error as CacheError,
error::{CompileError, CompileResult},
module::ModuleInfo,
structures::{Map, SliceMap, TypedIndex},
@@ -58,6 +60,11 @@ pub struct FuncResolverBuilder {
import_len: usize,
}
+pub struct NoopStackmapSink {}
+impl StackmapSink for NoopStackmapSink {
+ fn add_stackmap(&mut self, _: u32, _: Stackmap) {}
+}
+
impl FuncResolverBuilder {
pub fn new_from_backend_cache(
backend_cache: BackendCache,
@@ -109,12 +116,13 @@ impl FuncResolverBuilder {
ctx.func = func.to_owned();
let mut reloc_sink = RelocSink::new();
let mut local_trap_sink = LocalTrapSink::new();
-
+ let mut stackmap_sink = NoopStackmapSink {};
ctx.compile_and_emit(
isa,
&mut code_buf,
&mut reloc_sink,
&mut local_trap_sink,
+ &mut stackmap_sink,
)
.map_err(|e| CompileError::InternalError { msg: e.to_string() })?;
ctx.clear();
@@ -241,25 +249,17 @@ impl FuncResolverBuilder {
#[cfg(not(target_os = "windows"))]
LibCall::Probestack => __rust_probestack as isize,
},
- RelocationType::Intrinsic(ref name) => match name.as_str() {
- "i32print" => i32_print as isize,
- "i64print" => i64_print as isize,
- "f32print" => f32_print as isize,
- "f64print" => f64_print as isize,
- "strtdbug" => start_debug as isize,
- "enddbug" => end_debug as isize,
- _ => Err(CompileError::InternalError {
- msg: format!("unexpected intrinsic: {}", name),
- })?,
- },
+ RelocationType::Intrinsic(ref name) => Err(CompileError::InternalError {
+ msg: format!("unexpected intrinsic: {}", name),
+ })?,
RelocationType::VmCall(vmcall) => match vmcall {
VmCall::Local(kind) => match kind {
- VmCallKind::StaticMemoryGrow => vmcalls::local_static_memory_grow as _,
- VmCallKind::StaticMemorySize => vmcalls::local_static_memory_size as _,
-
- VmCallKind::SharedStaticMemoryGrow => unimplemented!(),
- VmCallKind::SharedStaticMemorySize => unimplemented!(),
-
+ VmCallKind::StaticMemoryGrow | VmCallKind::SharedStaticMemoryGrow => {
+ vmcalls::local_static_memory_grow as _
+ }
+ VmCallKind::StaticMemorySize | VmCallKind::SharedStaticMemorySize => {
+ vmcalls::local_static_memory_size as _
+ }
VmCallKind::DynamicMemoryGrow => {
vmcalls::local_dynamic_memory_grow as _
}
@@ -268,16 +268,12 @@ impl FuncResolverBuilder {
}
},
VmCall::Import(kind) => match kind {
- VmCallKind::StaticMemoryGrow => {
+ VmCallKind::StaticMemoryGrow | VmCallKind::SharedStaticMemoryGrow => {
vmcalls::imported_static_memory_grow as _
}
- VmCallKind::StaticMemorySize => {
+ VmCallKind::StaticMemorySize | VmCallKind::SharedStaticMemorySize => {
vmcalls::imported_static_memory_size as _
}
-
- VmCallKind::SharedStaticMemoryGrow => unimplemented!(),
- VmCallKind::SharedStaticMemorySize => unimplemented!(),
-
VmCallKind::DynamicMemoryGrow => {
vmcalls::imported_dynamic_memory_grow as _
}
@@ -366,28 +362,3 @@ impl FuncResolver {
fn round_up(n: usize, multiple: usize) -> usize {
(n + multiple - 1) & !(multiple - 1)
}
-
-extern "C" fn i32_print(_ctx: &mut vm::Ctx, n: i32) {
- eprint!(" i32: {},", n);
-}
-extern "C" fn i64_print(_ctx: &mut vm::Ctx, n: i64) {
- eprint!(" i64: {},", n);
-}
-extern "C" fn f32_print(_ctx: &mut vm::Ctx, n: f32) {
- eprint!(" f32: {},", n);
-}
-extern "C" fn f64_print(_ctx: &mut vm::Ctx, n: f64) {
- eprint!(" f64: {},", n);
-}
-extern "C" fn start_debug(ctx: &mut vm::Ctx, func_index: u32) {
- if let Some(symbol_map) = unsafe { ctx.borrow_symbol_map() } {
- if let Some(fn_name) = symbol_map.get(&func_index) {
- eprint!("func ({} ({})), args: [", fn_name, func_index);
- return;
- }
- }
- eprint!("func ({}), args: [", func_index);
-}
-extern "C" fn end_debug(_ctx: &mut vm::Ctx) {
- eprintln!(" ]");
-}
diff --git a/lib/clif-backend/src/signal/mod.rs b/lib/clif-backend/src/signal/mod.rs
index 3facce2ad..116da3f56 100644
--- a/lib/clif-backend/src/signal/mod.rs
+++ b/lib/clif-backend/src/signal/mod.rs
@@ -1,12 +1,14 @@
-use crate::relocation::{TrapData, TrapSink};
-use crate::resolver::FuncResolver;
-use crate::trampoline::Trampolines;
+use crate::{
+ relocation::{TrapData, TrapSink},
+ resolver::FuncResolver,
+ trampoline::Trampolines,
+};
use libc::c_void;
use std::{any::Any, cell::Cell, ptr::NonNull, sync::Arc};
use wasmer_runtime_core::{
backend::RunnableModule,
module::ModuleInfo,
- typed_func::{Wasm, WasmTrapInfo},
+ typed_func::{Trampoline, Wasm, WasmTrapInfo},
types::{LocalFuncIndex, SigIndex},
vm,
};
@@ -59,7 +61,7 @@ impl RunnableModule for Caller {
fn get_trampoline(&self, _: &ModuleInfo, sig_index: SigIndex) -> Option {
unsafe extern "C" fn invoke(
- trampoline: unsafe extern "C" fn(*mut vm::Ctx, NonNull, *const u64, *mut u64),
+ trampoline: Trampoline,
ctx: *mut vm::Ctx,
func: NonNull,
args: *const u64,
diff --git a/lib/clif-backend/src/signal/unix.rs b/lib/clif-backend/src/signal/unix.rs
index 39f3aa893..79b6619d3 100644
--- a/lib/clif-backend/src/signal/unix.rs
+++ b/lib/clif-backend/src/signal/unix.rs
@@ -98,7 +98,10 @@ pub fn call_protected(
},
Ok(SIGSEGV) | Ok(SIGBUS) => WasmTrapInfo::MemoryOutOfBounds,
Ok(SIGFPE) => WasmTrapInfo::IllegalArithmetic,
- _ => unimplemented!(),
+ _ => unimplemented!(
+ "WasmTrapInfo::Unknown signal:{:?}",
+ Signal::from_c_int(signum)
+ ),
}))
} else {
let signal = match Signal::from_c_int(signum) {
diff --git a/lib/clif-backend/src/signal/windows.rs b/lib/clif-backend/src/signal/windows.rs
index d755cd575..363119c6e 100644
--- a/lib/clif-backend/src/signal/windows.rs
+++ b/lib/clif-backend/src/signal/windows.rs
@@ -1,24 +1,30 @@
-use crate::relocation::{TrapCode, TrapData};
-use crate::signal::{CallProtError, HandlerData};
-use crate::trampoline::Trampoline;
-use std::cell::Cell;
-use std::ffi::c_void;
-use std::ptr::{self, NonNull};
-use wasmer_runtime_core::typed_func::WasmTrapInfo;
-use wasmer_runtime_core::vm::Ctx;
-use wasmer_runtime_core::vm::Func;
+use crate::{
+ relocation::{TrapCode, TrapData},
+ signal::{CallProtError, HandlerData},
+};
+use std::{
+ cell::Cell,
+ ffi::c_void,
+ ptr::{self, NonNull},
+};
+use wasmer_runtime_core::{
+ typed_func::{Trampoline, WasmTrapInfo},
+ vm::{Ctx, Func},
+};
use wasmer_win_exception_handler::CallProtectedData;
pub use wasmer_win_exception_handler::_call_protected;
-use winapi::shared::minwindef::DWORD;
-use winapi::um::minwinbase::{
- EXCEPTION_ACCESS_VIOLATION, EXCEPTION_ARRAY_BOUNDS_EXCEEDED, EXCEPTION_BREAKPOINT,
- EXCEPTION_DATATYPE_MISALIGNMENT, EXCEPTION_FLT_DENORMAL_OPERAND, EXCEPTION_FLT_DIVIDE_BY_ZERO,
- EXCEPTION_FLT_INEXACT_RESULT, EXCEPTION_FLT_INVALID_OPERATION, EXCEPTION_FLT_OVERFLOW,
- EXCEPTION_FLT_STACK_CHECK, EXCEPTION_FLT_UNDERFLOW, EXCEPTION_GUARD_PAGE,
- EXCEPTION_ILLEGAL_INSTRUCTION, EXCEPTION_INT_DIVIDE_BY_ZERO, EXCEPTION_INT_OVERFLOW,
- EXCEPTION_INVALID_HANDLE, EXCEPTION_IN_PAGE_ERROR, EXCEPTION_NONCONTINUABLE_EXCEPTION,
- EXCEPTION_POSSIBLE_DEADLOCK, EXCEPTION_PRIV_INSTRUCTION, EXCEPTION_SINGLE_STEP,
- EXCEPTION_STACK_OVERFLOW,
+use winapi::{
+ shared::minwindef::DWORD,
+ um::minwinbase::{
+ EXCEPTION_ACCESS_VIOLATION, EXCEPTION_ARRAY_BOUNDS_EXCEEDED, EXCEPTION_BREAKPOINT,
+ EXCEPTION_DATATYPE_MISALIGNMENT, EXCEPTION_FLT_DENORMAL_OPERAND,
+ EXCEPTION_FLT_DIVIDE_BY_ZERO, EXCEPTION_FLT_INEXACT_RESULT,
+ EXCEPTION_FLT_INVALID_OPERATION, EXCEPTION_FLT_OVERFLOW, EXCEPTION_FLT_STACK_CHECK,
+ EXCEPTION_FLT_UNDERFLOW, EXCEPTION_GUARD_PAGE, EXCEPTION_ILLEGAL_INSTRUCTION,
+ EXCEPTION_INT_DIVIDE_BY_ZERO, EXCEPTION_INT_OVERFLOW, EXCEPTION_INVALID_HANDLE,
+ EXCEPTION_IN_PAGE_ERROR, EXCEPTION_NONCONTINUABLE_EXCEPTION, EXCEPTION_POSSIBLE_DEADLOCK,
+ EXCEPTION_PRIV_INSTRUCTION, EXCEPTION_SINGLE_STEP, EXCEPTION_STACK_OVERFLOW,
+ },
};
thread_local! {
@@ -110,5 +116,5 @@ pub fn call_protected(
pub unsafe fn trigger_trap() -> ! {
// TODO
- unimplemented!();
+ unimplemented!("windows::trigger_trap");
}
diff --git a/lib/clif-backend/src/trampoline.rs b/lib/clif-backend/src/trampoline.rs
index 7f22c62a5..fcd1ff83d 100644
--- a/lib/clif-backend/src/trampoline.rs
+++ b/lib/clif-backend/src/trampoline.rs
@@ -1,17 +1,16 @@
-use crate::cache::TrampolineCache;
+use crate::{cache::TrampolineCache, resolver::NoopStackmapSink};
use cranelift_codegen::{
binemit::{NullTrapSink, Reloc, RelocSink},
cursor::{Cursor, FuncCursor},
ir::{self, InstBuilder},
isa, Context,
};
-use std::collections::HashMap;
-use std::{iter, mem, ptr::NonNull};
+use std::{collections::HashMap, iter, mem};
use wasmer_runtime_core::{
backend::sys::{Memory, Protect},
module::{ExportIndex, ModuleInfo},
+ typed_func::Trampoline,
types::{FuncSig, SigIndex, Type},
- vm,
};
struct NullRelocSink {}
@@ -19,11 +18,14 @@ struct NullRelocSink {}
impl RelocSink for NullRelocSink {
fn reloc_ebb(&mut self, _: u32, _: Reloc, _: u32) {}
fn reloc_external(&mut self, _: u32, _: Reloc, _: &ir::ExternalName, _: i64) {}
+
+ fn reloc_constant(&mut self, _: u32, _: Reloc, _: u32) {
+ unimplemented!("RelocSink::reloc_constant")
+ }
+
fn reloc_jt(&mut self, _: u32, _: Reloc, _: ir::JumpTable) {}
}
-pub type Trampoline = unsafe extern "C" fn(*mut vm::Ctx, NonNull, *const u64, *mut u64);
-
pub struct Trampolines {
memory: Memory,
offsets: HashMap,
@@ -89,12 +91,13 @@ impl Trampolines {
ctx.func = trampoline_func;
let mut code_buf = Vec::new();
-
+ let mut stackmap_sink = NoopStackmapSink {};
ctx.compile_and_emit(
isa,
&mut code_buf,
&mut NullRelocSink {},
&mut NullTrapSink {},
+ &mut stackmap_sink,
)
.expect("unable to compile trampolines");
ctx.clear();
diff --git a/lib/dev-utils/Cargo.toml b/lib/dev-utils/Cargo.toml
index 96fb6aeed..81fb49757 100644
--- a/lib/dev-utils/Cargo.toml
+++ b/lib/dev-utils/Cargo.toml
@@ -1,11 +1,12 @@
[package]
name = "wasmer-dev-utils"
-version = "0.6.0"
+version = "0.11.0"
description = "Wasmer runtime core library"
license = "MIT"
authors = ["The Wasmer Engineering Team "]
edition = "2018"
repository = "https://github.com/wasmerio/wasmer"
+publish = false
[dependencies]
libc = "0.2.60"
diff --git a/lib/dev-utils/src/lib.rs b/lib/dev-utils/src/lib.rs
index 76ae6804f..2a470bba4 100644
--- a/lib/dev-utils/src/lib.rs
+++ b/lib/dev-utils/src/lib.rs
@@ -1,2 +1,5 @@
+#![doc(html_favicon_url = "https://wasmer.io/static/icons/favicon.ico")]
+#![doc(html_logo_url = "https://avatars3.githubusercontent.com/u/44205449?s=200&v=4")]
+
pub mod file_descriptor;
pub mod stdio;
diff --git a/lib/emscripten-tests/Cargo.toml b/lib/emscripten-tests/Cargo.toml
index 71546fbeb..2439b4295 100644
--- a/lib/emscripten-tests/Cargo.toml
+++ b/lib/emscripten-tests/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "wasmer-emscripten-tests"
-version = "0.6.0"
+version = "0.11.0"
description = "Tests for our Emscripten implementation"
license = "MIT"
authors = ["The Wasmer Engineering Team "]
@@ -9,20 +9,20 @@ publish = false
build = "build/mod.rs"
[dependencies]
-wasmer-emscripten = { path = "../emscripten", version = "0.6.0" }
-wasmer-runtime-core = { path = "../runtime-core", version = "0.6.0" }
-wasmer-clif-backend = { path = "../clif-backend", version = "0.6.0" }
-wasmer-llvm-backend = { path = "../llvm-backend", version = "0.6.0", optional = true }
-wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.6.0", optional = true }
+wasmer-emscripten = { path = "../emscripten", version = "0.11.0" }
+wasmer-runtime = { path = "../runtime", version = "0.11.0", default-features = false }
+wasmer-clif-backend = { path = "../clif-backend", version = "0.11.0", optional = true}
+wasmer-llvm-backend = { path = "../llvm-backend", version = "0.11.0", optional = true, features = ["test"] }
+wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.11.0", optional = true }
[dev-dependencies]
wabt = "0.9.1"
-wasmer-dev-utils = { path = "../dev-utils", version = "0.6.0"}
+wasmer-dev-utils = { path = "../dev-utils", version = "0.11.0"}
[build-dependencies]
-glob = "0.3.0"
+glob = "0.3"
[features]
-clif = []
-llvm = ["wasmer-llvm-backend"]
-singlepass = ["wasmer-singlepass-backend"]
+clif = ["wasmer-clif-backend", "wasmer-runtime/default-backend-cranelift"]
+singlepass = ["wasmer-singlepass-backend", "wasmer-runtime/default-backend-singlepass"]
+llvm = ["wasmer-llvm-backend", "wasmer-runtime/default-backend-llvm"]
diff --git a/lib/emscripten-tests/emtests/ignores.txt b/lib/emscripten-tests/emtests/ignores.txt
index 16ff1a2a7..af8f21b00 100644
--- a/lib/emscripten-tests/emtests/ignores.txt
+++ b/lib/emscripten-tests/emtests/ignores.txt
@@ -29,6 +29,7 @@ test_i16_emcc_intrinsic
test_i64
test_i64_7z
test_i64_varargs
+test_indirectbr_many
test_llvm_intrinsics
test_longjmp_exc
test_lower_intrinsics
diff --git a/lib/emscripten-tests/src/lib.rs b/lib/emscripten-tests/src/lib.rs
index 1da0abc73..59bcf90eb 100644
--- a/lib/emscripten-tests/src/lib.rs
+++ b/lib/emscripten-tests/src/lib.rs
@@ -3,40 +3,13 @@ mod tests {
use std::sync::Arc;
use wabt::wat2wasm;
use wasmer_emscripten::is_emscripten_module;
- use wasmer_runtime_core::backend::Compiler;
- use wasmer_runtime_core::compile_with;
-
- #[cfg(feature = "clif")]
- fn get_compiler() -> impl Compiler {
- use wasmer_clif_backend::CraneliftCompiler;
- CraneliftCompiler::new()
- }
-
- #[cfg(feature = "llvm")]
- fn get_compiler() -> impl Compiler {
- use wasmer_llvm_backend::LLVMCompiler;
- LLVMCompiler::new()
- }
-
- #[cfg(feature = "singlepass")]
- fn get_compiler() -> impl Compiler {
- use wasmer_singlepass_backend::SinglePassCompiler;
- SinglePassCompiler::new()
- }
-
- #[cfg(not(any(feature = "llvm", feature = "clif", feature = "singlepass")))]
- fn get_compiler() -> impl Compiler {
- panic!("compiler not specified, activate a compiler via features");
- use wasmer_clif_backend::CraneliftCompiler;
- CraneliftCompiler::new()
- }
+ use wasmer_runtime::compile;
#[test]
fn should_detect_emscripten_files() {
const WAST_BYTES: &[u8] = include_bytes!("tests/is_emscripten_true.wast");
let wasm_binary = wat2wasm(WAST_BYTES.to_vec()).expect("Can't convert to wasm");
- let module =
- compile_with(&wasm_binary[..], &get_compiler()).expect("WASM can't be compiled");
+ let module = compile(&wasm_binary[..]).expect("WASM can't be compiled");
let module = Arc::new(module);
assert!(is_emscripten_module(&module));
}
@@ -45,8 +18,7 @@ mod tests {
fn should_detect_non_emscripten_files() {
const WAST_BYTES: &[u8] = include_bytes!("tests/is_emscripten_false.wast");
let wasm_binary = wat2wasm(WAST_BYTES.to_vec()).expect("Can't convert to wasm");
- let module =
- compile_with(&wasm_binary[..], &get_compiler()).expect("WASM can't be compiled");
+ let module = compile(&wasm_binary[..]).expect("WASM can't be compiled");
let module = Arc::new(module);
assert!(!is_emscripten_module(&module));
}
diff --git a/lib/emscripten-tests/tests/emtests/_common.rs b/lib/emscripten-tests/tests/emtests/_common.rs
index 1e5dfba6e..2e6c590d9 100644
--- a/lib/emscripten-tests/tests/emtests/_common.rs
+++ b/lib/emscripten-tests/tests/emtests/_common.rs
@@ -5,39 +5,12 @@ macro_rules! assert_emscripten_output {
EmscriptenGlobals,
generate_emscripten_env,
};
- use wasmer_runtime_core::{
- backend::Compiler,
- };
+ use wasmer_runtime::compile;
use wasmer_dev_utils::stdio::StdioCapturer;
- #[cfg(feature = "clif")]
- fn get_compiler() -> impl Compiler {
- use wasmer_clif_backend::CraneliftCompiler;
- CraneliftCompiler::new()
- }
-
- #[cfg(feature = "llvm")]
- fn get_compiler() -> impl Compiler {
- use wasmer_llvm_backend::LLVMCompiler;
- LLVMCompiler::new()
- }
-
- #[cfg(feature = "singlepass")]
- fn get_compiler() -> impl Compiler {
- use wasmer_singlepass_backend::SinglePassCompiler;
- SinglePassCompiler::new()
- }
-
- #[cfg(not(any(feature = "llvm", feature = "clif", feature = "singlepass")))]
- fn get_compiler() -> impl Compiler {
- panic!("compiler not specified, activate a compiler via features");
- use wasmer_clif_backend::CraneliftCompiler;
- CraneliftCompiler::new()
- }
-
let wasm_bytes = include_bytes!($file);
- let module = wasmer_runtime_core::compile_with(&wasm_bytes[..], &get_compiler())
+ let module = compile(&wasm_bytes[..])
.expect("WASM can't be compiled");
// let module = compile(&wasm_bytes[..])
diff --git a/lib/emscripten-tests/tests/emtests/test_indirectbr_many.rs b/lib/emscripten-tests/tests/emtests/test_indirectbr_many.rs
index fba25e6b2..a96fe2138 100644
--- a/lib/emscripten-tests/tests/emtests/test_indirectbr_many.rs
+++ b/lib/emscripten-tests/tests/emtests/test_indirectbr_many.rs
@@ -1,4 +1,5 @@
#[test]
+#[ignore]
fn test_test_indirectbr_many() {
assert_emscripten_output!(
"../../emtests/test_indirectbr_many.wasm",
diff --git a/lib/emscripten/Cargo.toml b/lib/emscripten/Cargo.toml
index 7ffaf2d7e..dffbe0942 100644
--- a/lib/emscripten/Cargo.toml
+++ b/lib/emscripten/Cargo.toml
@@ -1,21 +1,23 @@
[package]
name = "wasmer-emscripten"
-version = "0.6.0"
+version = "0.11.0"
description = "Wasmer runtime emscripten implementation library"
license = "MIT"
authors = ["The Wasmer Engineering Team "]
repository = "https://github.com/wasmerio/wasmer"
+keywords = ["wasm", "webassembly", "ABI", "emscripten", "posix"]
+categories = ["wasm"]
edition = "2018"
[dependencies]
-byteorder = "1.3.2"
-lazy_static = "1.3.0"
+byteorder = "1.3"
+lazy_static = "1.4"
libc = "0.2.60"
-time = "0.1.42"
-wasmer-runtime-core = { path = "../runtime-core", version = "0.6.0" }
+time = "0.1"
+wasmer-runtime-core = { path = "../runtime-core", version = "0.11.0" }
[target.'cfg(windows)'.dependencies]
-rand = "0.7.0"
+getrandom = "0.1"
[features]
debug = ["wasmer-runtime-core/debug"]
diff --git a/lib/emscripten/src/env/mod.rs b/lib/emscripten/src/env/mod.rs
index 88fba54a6..a61a2bb9f 100644
--- a/lib/emscripten/src/env/mod.rs
+++ b/lib/emscripten/src/env/mod.rs
@@ -12,14 +12,14 @@ pub use self::windows::*;
use libc::c_char;
-use crate::{allocate_on_stack, EmscriptenData};
+use crate::{
+ allocate_on_stack,
+ ptr::{Array, WasmPtr},
+ EmscriptenData,
+};
use std::os::raw::c_int;
-use wasmer_runtime_core::{
- memory::ptr::{Array, WasmPtr},
- types::ValueType,
- vm::Ctx,
-};
+use wasmer_runtime_core::{types::ValueType, vm::Ctx};
pub fn call_malloc(ctx: &mut Ctx, size: u32) -> u32 {
get_emscripten_data(ctx)
diff --git a/lib/emscripten/src/env/unix/mod.rs b/lib/emscripten/src/env/unix/mod.rs
index 0e62e8e2f..951650495 100644
--- a/lib/emscripten/src/env/unix/mod.rs
+++ b/lib/emscripten/src/env/unix/mod.rs
@@ -9,11 +9,9 @@ use std::mem;
use std::os::raw::c_char;
use crate::env::{call_malloc, call_malloc_with_cast, EmAddrInfo, EmSockAddr};
+use crate::ptr::{Array, WasmPtr};
use crate::utils::{copy_cstr_into_wasm, copy_terminated_array_of_cstrs};
-use wasmer_runtime_core::{
- memory::ptr::{Array, WasmPtr},
- vm::Ctx,
-};
+use wasmer_runtime_core::vm::Ctx;
// #[no_mangle]
/// emscripten: _getenv // (name: *const char) -> *const c_char;
diff --git a/lib/emscripten/src/env/windows/mod.rs b/lib/emscripten/src/env/windows/mod.rs
index d6ba0b0da..025a01bd7 100644
--- a/lib/emscripten/src/env/windows/mod.rs
+++ b/lib/emscripten/src/env/windows/mod.rs
@@ -6,8 +6,9 @@ use std::mem;
use std::os::raw::c_char;
use crate::env::{call_malloc, EmAddrInfo};
+use crate::ptr::WasmPtr;
use crate::utils::{copy_cstr_into_wasm, read_string_from_wasm};
-use wasmer_runtime_core::{memory::ptr::WasmPtr, vm::Ctx};
+use wasmer_runtime_core::vm::Ctx;
extern "C" {
#[link_name = "_putenv"]
diff --git a/lib/emscripten/src/exception.rs b/lib/emscripten/src/exception.rs
index 09f04a798..09ae286f8 100644
--- a/lib/emscripten/src/exception.rs
+++ b/lib/emscripten/src/exception.rs
@@ -10,22 +10,22 @@ pub fn ___cxa_allocate_exception(ctx: &mut Ctx, size: u32) -> u32 {
pub fn ___cxa_current_primary_exception(_ctx: &mut Ctx) -> u32 {
debug!("emscripten::___cxa_current_primary_exception");
- unimplemented!()
+ unimplemented!("emscripten::___cxa_current_primary_exception")
}
pub fn ___cxa_decrement_exception_refcount(_ctx: &mut Ctx, _a: u32) {
debug!("emscripten::___cxa_decrement_exception_refcount({})", _a);
- unimplemented!()
+ unimplemented!("emscripten::___cxa_decrement_exception_refcount({})", _a)
}
pub fn ___cxa_increment_exception_refcount(_ctx: &mut Ctx, _a: u32) {
debug!("emscripten::___cxa_increment_exception_refcount({})", _a);
- unimplemented!()
+ unimplemented!("emscripten::___cxa_increment_exception_refcount({})", _a)
}
pub fn ___cxa_rethrow_primary_exception(_ctx: &mut Ctx, _a: u32) {
debug!("emscripten::___cxa_rethrow_primary_exception({})", _a);
- unimplemented!()
+ unimplemented!("emscripten::___cxa_rethrow_primary_exception({})", _a)
}
/// emscripten: ___cxa_throw
diff --git a/lib/emscripten/src/io/mod.rs b/lib/emscripten/src/io/mod.rs
index 6666cd5af..bad5935fe 100644
--- a/lib/emscripten/src/io/mod.rs
+++ b/lib/emscripten/src/io/mod.rs
@@ -15,13 +15,13 @@ use wasmer_runtime_core::vm::Ctx;
/// getprotobyname
pub fn getprotobyname(_ctx: &mut Ctx, _name_ptr: i32) -> i32 {
debug!("emscripten::getprotobyname");
- unimplemented!()
+ unimplemented!("emscripten::getprotobyname")
}
/// getprotobynumber
pub fn getprotobynumber(_ctx: &mut Ctx, _one: i32) -> i32 {
debug!("emscripten::getprotobynumber");
- unimplemented!()
+ unimplemented!("emscripten::getprotobynumber")
}
/// sigdelset
@@ -53,11 +53,11 @@ pub fn sigfillset(ctx: &mut Ctx, set: i32) -> i32 {
/// tzset
pub fn tzset(_ctx: &mut Ctx) {
debug!("emscripten::tzset - stub");
- //unimplemented!()
+ //unimplemented!("emscripten::tzset - stub")
}
/// strptime
pub fn strptime(_ctx: &mut Ctx, _one: i32, _two: i32, _three: i32) -> i32 {
debug!("emscripten::strptime");
- unimplemented!()
+ unimplemented!("emscripten::strptime")
}
diff --git a/lib/emscripten/src/io/windows.rs b/lib/emscripten/src/io/windows.rs
index a3c6f70aa..a7d6dc60b 100644
--- a/lib/emscripten/src/io/windows.rs
+++ b/lib/emscripten/src/io/windows.rs
@@ -36,11 +36,11 @@ pub fn printf(_ctx: &mut Ctx, memory_offset: i32, extra: i32) -> i32 {
/// chroot
pub fn chroot(_ctx: &mut Ctx, _name_ptr: i32) -> i32 {
debug!("emscripten::chroot");
- unimplemented!()
+ unimplemented!("emscripten::chroot")
}
/// getpwuid
pub fn getpwuid(_ctx: &mut Ctx, _uid: i32) -> i32 {
debug!("emscripten::getpwuid");
- unimplemented!()
+ unimplemented!("emscripten::getpwuid")
}
diff --git a/lib/emscripten/src/lib.rs b/lib/emscripten/src/lib.rs
index c09f9b772..1c9b8a1f7 100644
--- a/lib/emscripten/src/lib.rs
+++ b/lib/emscripten/src/lib.rs
@@ -7,6 +7,9 @@
unused_unsafe,
unreachable_patterns
)]
+#![doc(html_favicon_url = "https://wasmer.io/static/icons/favicon.ico")]
+#![doc(html_logo_url = "https://avatars3.githubusercontent.com/u/44205449?s=200&v=4")]
+
#[macro_use]
extern crate wasmer_runtime_core;
@@ -59,6 +62,7 @@ mod math;
mod memory;
mod process;
mod pthread;
+mod ptr;
mod signal;
mod storage;
mod syscalls;
@@ -107,7 +111,7 @@ pub struct EmscriptenData<'a> {
pub dyn_call_iii: Option>,
pub dyn_call_iiii: Option>,
pub dyn_call_iifi: Option>,
- pub dyn_call_v: Option>,
+ pub dyn_call_v: Option>,
pub dyn_call_vi: Option>,
pub dyn_call_vii: Option>,
pub dyn_call_viii: Option>,
@@ -164,7 +168,7 @@ pub struct EmscriptenData<'a> {
pub temp_ret_0: i32,
pub stack_save: Option>,
- pub stack_restore: Option>,
+ pub stack_restore: Option>,
pub set_threw: Option>,
pub mapped_dirs: HashMap,
}
@@ -470,11 +474,7 @@ impl EmscriptenGlobals {
let (memory_min, memory_max, shared) = get_emscripten_memory_size(&module)?;
// Memory initialization
- let memory_type = MemoryDescriptor {
- minimum: memory_min,
- maximum: memory_max,
- shared: shared,
- };
+ let memory_type = MemoryDescriptor::new(memory_min, memory_max, shared)?;
let memory = Memory::new(memory_type).unwrap();
let table_type = TableDescriptor {
@@ -731,8 +731,9 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
"___syscall345" => func!(crate::syscalls::___syscall345),
// Process
- "abort" => func!(crate::process::em_abort),
+ "abort" => func!(crate::process::_abort),
"_abort" => func!(crate::process::_abort),
+ "_prctl" => func!(crate::process::_prctl),
"abortStackOverflow" => func!(crate::process::abort_stack_overflow),
"_llvm_trap" => func!(crate::process::_llvm_trap),
"_fork" => func!(crate::process::_fork),
@@ -825,6 +826,9 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
"_gmtime" => func!(crate::time::_gmtime),
// Math
+ "sqrt" => func!(crate::math::sqrt),
+ "floor" => func!(crate::math::floor),
+ "fabs" => func!(crate::math::fabs),
"f64-rem" => func!(crate::math::f64_rem),
"_llvm_copysign_f32" => func!(crate::math::_llvm_copysign_f32),
"_llvm_copysign_f64" => func!(crate::math::_llvm_copysign_f64),
diff --git a/lib/emscripten/src/math.rs b/lib/emscripten/src/math.rs
index 3aea6f8b7..914411ee9 100644
--- a/lib/emscripten/src/math.rs
+++ b/lib/emscripten/src/math.rs
@@ -88,6 +88,21 @@ pub fn log(_ctx: &mut Ctx, value: f64) -> f64 {
value.ln()
}
+// emscripten: global.Math sqrt
+pub fn sqrt(_ctx: &mut Ctx, value: f64) -> f64 {
+ value.sqrt()
+}
+
+// emscripten: global.Math floor
+pub fn floor(_ctx: &mut Ctx, value: f64) -> f64 {
+ value.floor()
+}
+
+// emscripten: global.Math fabs
+pub fn fabs(_ctx: &mut Ctx, value: f64) -> f64 {
+ value.abs()
+}
+
// emscripten: asm2wasm.f64-to-int
pub fn f64_to_int(_ctx: &mut Ctx, value: f64) -> i32 {
debug!("emscripten::f64_to_int {}", value);
diff --git a/lib/emscripten/src/process.rs b/lib/emscripten/src/process.rs
index cd083e943..a776734b4 100644
--- a/lib/emscripten/src/process.rs
+++ b/lib/emscripten/src/process.rs
@@ -1,11 +1,10 @@
-use libc::{abort, c_char, c_int, exit, EAGAIN};
+use libc::{abort, c_int, exit, EAGAIN};
#[cfg(not(target_os = "windows"))]
type PidT = libc::pid_t;
#[cfg(target_os = "windows")]
type PidT = c_int;
-use std::ffi::CStr;
use wasmer_runtime_core::vm::Ctx;
pub fn abort_with_message(ctx: &mut Ctx, message: &str) {
@@ -21,6 +20,12 @@ pub fn _abort(_ctx: &mut Ctx) {
}
}
+pub fn _prctl(ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
+ debug!("emscripten::_prctl");
+ abort_with_message(ctx, "missing function: prctl");
+ -1
+}
+
pub fn _fork(_ctx: &mut Ctx) -> PidT {
debug!("emscripten::_fork");
// unsafe {
@@ -45,18 +50,6 @@ pub fn _exit(_ctx: &mut Ctx, status: c_int) {
unsafe { exit(status) }
}
-pub fn em_abort(ctx: &mut Ctx, message: u32) {
- debug!("emscripten::em_abort {}", message);
- let message_addr = emscripten_memory_pointer!(ctx.memory(0), message) as *mut c_char;
- unsafe {
- let message = CStr::from_ptr(message_addr)
- .to_str()
- .unwrap_or("Unexpected abort");
-
- abort_with_message(ctx, message);
- }
-}
-
pub fn _kill(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
debug!("emscripten::_kill");
-1
diff --git a/lib/emscripten/src/ptr.rs b/lib/emscripten/src/ptr.rs
new file mode 100644
index 000000000..34cd68364
--- /dev/null
+++ b/lib/emscripten/src/ptr.rs
@@ -0,0 +1,116 @@
+//! This is a wrapper around the `WasmPtr` abstraction that does not allow deref of address 0
+//! This is a common assumption in Emscripten code
+
+// this is a wrapper with extra logic around the runtime-core `WasmPtr`, so we
+// don't want to warn about unusued code here
+#![allow(dead_code)]
+
+use std::{cell::Cell, fmt};
+pub use wasmer_runtime_core::memory::ptr::Array;
+use wasmer_runtime_core::{
+ memory::{ptr, Memory},
+ types::{ValueType, WasmExternType},
+};
+
+#[repr(transparent)]
+pub struct WasmPtr(ptr::WasmPtr);
+
+unsafe impl ValueType for WasmPtr {}
+impl Copy for WasmPtr {}
+
+impl Clone for WasmPtr {
+ fn clone(&self) -> Self {
+ Self(self.0.clone())
+ }
+}
+
+impl fmt::Debug for WasmPtr {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{:?}", self.0)
+ }
+}
+
+unsafe impl WasmExternType for WasmPtr {
+ type Native = as WasmExternType>::Native;
+
+ fn to_native(self) -> Self::Native {
+ self.0.to_native()
+ }
+ fn from_native(n: Self::Native) -> Self {
+ Self(ptr::WasmPtr::from_native(n))
+ }
+}
+
+impl PartialEq for WasmPtr {
+ fn eq(&self, other: &Self) -> bool {
+ self.0 == other.0
+ }
+}
+
+impl Eq for WasmPtr {}
+
+impl WasmPtr {
+ #[inline(always)]
+ pub fn new(offset: u32) -> Self {
+ Self(ptr::WasmPtr::new(offset))
+ }
+
+ #[inline(always)]
+ pub fn offset(self) -> u32 {
+ self.0.offset()
+ }
+}
+
+impl WasmPtr {
+ #[inline(always)]
+ pub fn deref<'a>(self, memory: &'a Memory) -> Option<&'a Cell> {
+ if self.0.offset() == 0 {
+ None
+ } else {
+ self.0.deref(memory)
+ }
+ }
+
+ #[inline(always)]
+ pub unsafe fn deref_mut<'a>(self, memory: &'a Memory) -> Option<&'a mut Cell> {
+ if self.0.offset() == 0 {
+ None
+ } else {
+ self.0.deref_mut(memory)
+ }
+ }
+}
+
+impl WasmPtr {
+ #[inline(always)]
+ pub fn deref<'a>(self, memory: &'a Memory, index: u32, length: u32) -> Option<&'a [Cell]> {
+ if self.0.offset() == 0 {
+ None
+ } else {
+ self.0.deref(memory, index, length)
+ }
+ }
+
+ #[inline]
+ pub unsafe fn deref_mut<'a>(
+ self,
+ memory: &'a Memory,
+ index: u32,
+ length: u32,
+ ) -> Option<&'a mut [Cell]> {
+ if self.0.offset() == 0 {
+ None
+ } else {
+ self.0.deref_mut(memory, index, length)
+ }
+ }
+
+ #[inline(always)]
+ pub fn get_utf8_string<'a>(self, memory: &'a Memory, str_len: u32) -> Option<&'a str> {
+ if self.0.offset() == 0 {
+ None
+ } else {
+ self.0.get_utf8_string(memory, str_len)
+ }
+ }
+}
diff --git a/lib/emscripten/src/syscalls/mod.rs b/lib/emscripten/src/syscalls/mod.rs
index b098bd152..ba5965fde 100644
--- a/lib/emscripten/src/syscalls/mod.rs
+++ b/lib/emscripten/src/syscalls/mod.rs
@@ -10,7 +10,10 @@ pub use self::unix::*;
#[cfg(windows)]
pub use self::windows::*;
-use crate::utils::{copy_stat_into_wasm, get_cstr_path, get_current_directory};
+use crate::{
+ ptr::{Array, WasmPtr},
+ utils::{copy_stat_into_wasm, get_cstr_path, get_current_directory},
+};
use super::varargs::VarArgs;
use byteorder::{ByteOrder, LittleEndian};
@@ -40,10 +43,7 @@ use libc::{
write,
// ENOTTY,
};
-use wasmer_runtime_core::{
- memory::ptr::{Array, WasmPtr},
- vm::Ctx,
-};
+use wasmer_runtime_core::vm::Ctx;
use super::env;
use std::cell::Cell;
diff --git a/lib/emscripten/src/syscalls/unix.rs b/lib/emscripten/src/syscalls/unix.rs
index 000a3e319..62d807c02 100644
--- a/lib/emscripten/src/syscalls/unix.rs
+++ b/lib/emscripten/src/syscalls/unix.rs
@@ -1,4 +1,4 @@
-use crate::varargs::VarArgs;
+use crate::{ptr::WasmPtr, varargs::VarArgs};
#[cfg(target_os = "macos")]
use libc::size_t;
/// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32
@@ -7,6 +7,7 @@ use libc::{
accept,
access,
bind,
+ c_char,
c_int,
c_ulong,
c_void,
@@ -111,7 +112,7 @@ fn translate_ioctl(wasm_ioctl: u32) -> c_ulong {
#[allow(unused_imports)]
use std::ffi::CStr;
-use wasmer_runtime_core::{memory::ptr::WasmPtr, vm::Ctx};
+use wasmer_runtime_core::vm::Ctx;
use crate::env::EmSockAddr;
use crate::utils::{self, get_cstr_path};
@@ -259,7 +260,7 @@ pub fn ___syscall194(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
ftruncate64(_fd, _length)
}
#[cfg(target_os = "macos")]
- unimplemented!()
+ unimplemented!("emscripten::___syscall194 (ftruncate64) {}", _which)
}
/// lchown
@@ -1063,14 +1064,14 @@ pub fn ___syscall220(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 {
let upper_bound = std::cmp::min((*dirent).d_reclen, 255) as usize;
let mut i = 0;
while i < upper_bound {
- *(dirp.add(pos + 11 + i) as *mut i8) = (*dirent).d_name[i] as _;
+ *(dirp.add(pos + 11 + i) as *mut c_char) = (*dirent).d_name[i] as c_char;
i += 1;
}
// We set the termination string char
- *(dirp.add(pos + 11 + i) as *mut i8) = 0 as i8;
+ *(dirp.add(pos + 11 + i) as *mut c_char) = 0 as c_char;
debug!(
" => file {}",
- CStr::from_ptr(dirp.add(pos + 11) as *const i8)
+ CStr::from_ptr(dirp.add(pos + 11) as *const c_char)
.to_str()
.unwrap()
);
@@ -1111,6 +1112,6 @@ pub fn ___syscall324(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
}
#[cfg(target_os = "macos")]
{
- unimplemented!()
+ unimplemented!("emscripten::___syscall324 (fallocate) {}", _which)
}
}
diff --git a/lib/emscripten/src/syscalls/windows.rs b/lib/emscripten/src/syscalls/windows.rs
index f6a867356..b5ed6cc83 100644
--- a/lib/emscripten/src/syscalls/windows.rs
+++ b/lib/emscripten/src/syscalls/windows.rs
@@ -2,7 +2,6 @@ use crate::utils::{copy_cstr_into_wasm, get_cstr_path};
use crate::varargs::VarArgs;
use libc::mkdir;
use libc::open;
-use rand::Rng;
use std::env;
use std::ffi::CString;
use std::fs::File;
@@ -39,7 +38,8 @@ pub fn ___syscall5(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int {
let ptr = tmp_dir_c_str.as_ptr() as *const i8;
let mut urandom_file = File::create(tmp_dir).unwrap();
// create some random bytes and put them into the file
- let random_bytes = rand::thread_rng().gen::<[u8; 32]>();
+ let mut random_bytes = [0u8; 32];
+ getrandom::getrandom(&mut random_bytes).unwrap();
let _ = urandom_file.write_all(&random_bytes).unwrap();
// put the file path string into wasm memory
let urandom_file_offset = unsafe { copy_cstr_into_wasm(ctx, ptr) };
@@ -66,13 +66,13 @@ pub fn ___syscall5(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int {
/// link
pub fn ___syscall9(_ctx: &mut Ctx, _which: c_int, mut _varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall9 (link) {}", _which);
- unimplemented!()
+ unimplemented!("emscripten::___syscall9 (link) {}", _which);
}
/// ftruncate64
pub fn ___syscall194(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall194 - stub");
- unimplemented!()
+ unimplemented!("emscripten::___syscall194 - stub")
}
// chown
@@ -86,13 +86,13 @@ pub fn ___syscall212(_ctx: &mut Ctx, which: c_int, mut _varargs: VarArgs) -> c_i
/// access
pub fn ___syscall33(_ctx: &mut Ctx, _which: c_int, mut _varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall33 (access) {}", _which);
- unimplemented!()
+ unimplemented!("emscripten::___syscall33 (access) {}", _which);
}
/// nice
pub fn ___syscall34(_ctx: &mut Ctx, _which: c_int, mut _varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall34 (nice) {}", _which);
- unimplemented!()
+ unimplemented!("emscripten::___syscall34 (nice) {}", _which);
}
// mkdir
@@ -113,19 +113,19 @@ pub fn ___syscall39(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int
/// dup
pub fn ___syscall41(_ctx: &mut Ctx, _which: c_int, _varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall41 (dup) {}", _which);
- unimplemented!()
+ unimplemented!("emscripten::___syscall41 (dup) {}", _which);
}
/// getrusage
pub fn ___syscall77(_ctx: &mut Ctx, _which: c_int, _varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall77 (getrusage) {}", _which);
- unimplemented!()
+ unimplemented!("emscripten::___syscall77 (getrusage) {}", _which);
}
/// symlink
pub fn ___syscall83(_ctx: &mut Ctx, _which: c_int, _varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall83 (symlink) {}", _which);
- unimplemented!()
+ unimplemented!("emscripten::___syscall83 (symlink) {}", _which);
}
/// readlink
@@ -143,38 +143,38 @@ pub fn ___syscall132(_ctx: &mut Ctx, _which: c_int, mut _varargs: VarArgs) -> c_
/// lchown
pub fn ___syscall198(_ctx: &mut Ctx, _which: c_int, _varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall198 (lchown) {}", _which);
- unimplemented!()
+ unimplemented!("emscripten::___syscall198 (lchown) {}", _which);
}
/// getgid32
pub fn ___syscall200(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall200 (getgid32)");
- unimplemented!();
+ unimplemented!("emscripten::___syscall200 (getgid32)");
}
// geteuid32
pub fn ___syscall201(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall201 (geteuid32)");
- unimplemented!();
+ unimplemented!("emscripten::___syscall201 (geteuid32)");
}
// getegid32
pub fn ___syscall202(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
// gid_t
debug!("emscripten::___syscall202 (getegid32)");
- unimplemented!();
+ unimplemented!("emscripten::___syscall202 (getegid32)");
}
/// getgroups
pub fn ___syscall205(_ctx: &mut Ctx, _which: c_int, _varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall205 (getgroups) {}", _which);
- unimplemented!()
+ unimplemented!("emscripten::___syscall205 (getgroups) {}", _which);
}
/// madvise
pub fn ___syscall219(_ctx: &mut Ctx, _which: c_int, _varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall212 (chown) {}", _which);
- unimplemented!()
+ unimplemented!("emscripten::___syscall212 (chown) {}", _which);
}
/// dup3
@@ -194,7 +194,7 @@ pub fn ___syscall54(_ctx: &mut Ctx, which: c_int, mut _varargs: VarArgs) -> c_in
/// fchmod
pub fn ___syscall94(_ctx: &mut Ctx, _which: c_int, _varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall118 (fchmod) {}", _which);
- unimplemented!()
+ unimplemented!("emscripten::___syscall118 (fchmod) {}", _which);
}
// socketcall
@@ -209,7 +209,7 @@ pub fn ___syscall102(_ctx: &mut Ctx, which: c_int, mut _varargs: VarArgs) -> c_i
/// fsync
pub fn ___syscall118(_ctx: &mut Ctx, _which: c_int, _varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall118 (fsync) {}", _which);
- unimplemented!()
+ unimplemented!("emscripten::___syscall118 (fsync) {}", _which);
}
// pread
@@ -247,7 +247,7 @@ pub fn ___syscall142(_ctx: &mut Ctx, which: c_int, mut _varargs: VarArgs) -> c_i
/// fdatasync
pub fn ___syscall148(_ctx: &mut Ctx, _which: c_int, _varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall148 (fdatasync) {}", _which);
- unimplemented!();
+ unimplemented!("emscripten::___syscall148 (fdatasync) {}", _which);
}
// setpgid
@@ -300,11 +300,11 @@ pub fn ___syscall221(_ctx: &mut Ctx, _which: c_int, mut _varargs: VarArgs) -> c_
/// fchown
pub fn ___syscall207(_ctx: &mut Ctx, _which: c_int, _varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall207 (fchown) {}", _which);
- unimplemented!()
+ unimplemented!("emscripten::___syscall207 (fchown) {}", _which)
}
/// fallocate
pub fn ___syscall324(_ctx: &mut Ctx, _which: c_int, _varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall324 (fallocate) {}", _which);
- unimplemented!()
+ unimplemented!("emscripten::___syscall324 (fallocate) {}", _which)
}
diff --git a/lib/emscripten/src/utils.rs b/lib/emscripten/src/utils.rs
index 2585af43f..e1c403565 100644
--- a/lib/emscripten/src/utils.rs
+++ b/lib/emscripten/src/utils.rs
@@ -24,7 +24,9 @@ pub fn is_emscripten_module(module: &Module) -> bool {
.namespace_table
.get(import_name.namespace_index);
let field = module.info().name_table.get(import_name.name_index);
- if (field == "_emscripten_memcpy_big" || field == "emscripten_memcpy_big")
+ if (field == "_emscripten_memcpy_big"
+ || field == "emscripten_memcpy_big"
+ || field == "__map_file")
&& namespace == "env"
{
return true;
diff --git a/lib/kernel-loader/src/lib.rs b/lib/kernel-loader/src/lib.rs
index 51ca6c7da..37f51a424 100644
--- a/lib/kernel-loader/src/lib.rs
+++ b/lib/kernel-loader/src/lib.rs
@@ -1,3 +1,6 @@
+#![doc(html_favicon_url = "https://wasmer.io/static/icons/favicon.ico")]
+#![doc(html_logo_url = "https://avatars3.githubusercontent.com/u/44205449?s=200&v=4")]
+
pub mod service;
use service::{ImportInfo, LoadProfile, RunProfile, ServiceContext, TableEntryRequest};
diff --git a/lib/kernel-net/src/lib.rs b/lib/kernel-net/src/lib.rs
index 4686867a7..cc6f91820 100644
--- a/lib/kernel-net/src/lib.rs
+++ b/lib/kernel-net/src/lib.rs
@@ -1,5 +1,7 @@
#![cfg(all(target_arch = "wasm32", target_os = "wasi"))]
#![feature(wasi_ext)]
+#![doc(html_favicon_url = "https://wasmer.io/static/icons/favicon.ico")]
+#![doc(html_logo_url = "https://avatars3.githubusercontent.com/u/44205449?s=200&v=4")]
use std::cell::RefCell;
use std::fs::File;
diff --git a/lib/llvm-backend-tests/Cargo.toml b/lib/llvm-backend-tests/Cargo.toml
new file mode 100644
index 000000000..bb6b24b51
--- /dev/null
+++ b/lib/llvm-backend-tests/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+name = "wasmer-llvm-backend-tests"
+version = "0.10.2"
+authors = ["Nick Lewycky "]
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+wabt = "0.9.1"
+wasmer-runtime-core = { path = "../runtime-core", version = "0.11.0" }
+wasmer-runtime = { path = "../runtime", version = "0.11.0" }
+wasmer-llvm-backend = { path = "../llvm-backend", version = "0.11.0", features = ["test"] }
+
+[features]
diff --git a/lib/llvm-backend-tests/src/lib.rs b/lib/llvm-backend-tests/src/lib.rs
new file mode 100644
index 000000000..ea79b7872
--- /dev/null
+++ b/lib/llvm-backend-tests/src/lib.rs
@@ -0,0 +1,7 @@
+pub use wabt::wat2wasm;
+use wasmer_llvm_backend::LLVMCompiler;
+use wasmer_runtime_core::backend::Compiler;
+
+pub fn get_compiler() -> impl Compiler {
+ LLVMCompiler::new()
+}
diff --git a/lib/llvm-backend-tests/tests/compile.rs b/lib/llvm-backend-tests/tests/compile.rs
new file mode 100644
index 000000000..17071a44a
--- /dev/null
+++ b/lib/llvm-backend-tests/tests/compile.rs
@@ -0,0 +1,40 @@
+use wasmer_llvm_backend_tests::{get_compiler, wat2wasm};
+use wasmer_runtime::imports;
+use wasmer_runtime_core::compile_with;
+
+#[test]
+fn crash_return_with_float_on_stack() {
+ const MODULE: &str = r#"
+(module
+ (type (;0;) (func))
+ (type (;1;) (func (param f64) (result f64)))
+ (func $_start (type 0))
+ (func $fmod (type 1) (param f64) (result f64)
+ local.get 0
+ f64.const 0x0p+0 (;=0;)
+ f64.mul
+ return)
+)
+"#;
+ let wasm_binary = wat2wasm(MODULE.as_bytes()).expect("WAST not valid or malformed");
+ let module = compile_with(&wasm_binary, &get_compiler()).unwrap();
+ module.instantiate(&imports! {}).unwrap();
+}
+
+#[test]
+fn crash_select_with_mismatched_pending() {
+ const MODULE: &str = r#"
+ (module
+ (func (param f64)
+ f64.const 0x0p+0 (;=0;)
+ local.get 0
+ f64.add
+ f64.const 0x0p+0 (;=0;)
+ i32.const 0
+ select
+ drop))
+"#;
+ let wasm_binary = wat2wasm(MODULE.as_bytes()).expect("WAST not valid or malformed");
+ let module = compile_with(&wasm_binary, &get_compiler()).unwrap();
+ module.instantiate(&imports! {}).unwrap();
+}
diff --git a/lib/llvm-backend/Cargo.toml b/lib/llvm-backend/Cargo.toml
index 886df698b..b9fa7e6a7 100644
--- a/lib/llvm-backend/Cargo.toml
+++ b/lib/llvm-backend/Cargo.toml
@@ -1,40 +1,44 @@
[package]
name = "wasmer-llvm-backend"
-version = "0.6.0"
+version = "0.11.0"
+license = "MIT"
authors = ["The Wasmer Engineering Team "]
+repository = "https://github.com/wasmerio/wasmer"
+keywords = ["wasm", "webassembly", "compiler", "JIT", "llvm"]
+categories = ["wasm"]
edition = "2018"
readme = "README.md"
[dependencies]
-wasmer-runtime-core = { path = "../runtime-core", version = "0.6.0" }
-wasmparser = "0.35.1"
-smallvec = "0.6.10"
+wasmer-runtime-core = { path = "../runtime-core", version = "0.11.0" }
+wasmparser = "0.39.1"
+smallvec = "0.6"
goblin = "0.0.24"
libc = "0.2.60"
-capstone = { version = "0.6.0", optional = true }
+byteorder = "1"
[dependencies.inkwell]
-git = "https://github.com/wasmerio/inkwell"
-branch = "llvm8-0"
+git = "https://github.com/TheDan64/inkwell"
+rev = "781620e9fa30e51a6e03bd0d49b5f5bb7a782520"
default-features = false
features = ["llvm8-0", "target-x86"]
[target.'cfg(unix)'.dependencies]
-nix = "0.15.0"
+nix = "0.15"
[target.'cfg(windows)'.dependencies]
-winapi = { version = "0.3.7", features = ["memoryapi"] }
+winapi = { version = "0.3", features = ["memoryapi"] }
[build-dependencies]
cc = "1.0"
-lazy_static = "1.3.0"
-regex = "1.2.1"
+lazy_static = "1.4"
+regex = "1.2"
semver = "0.9"
-rustc_version = "0.2.3"
+rustc_version = "0.2"
[dev-dependencies]
wabt = "0.9.1"
[features]
debug = ["wasmer-runtime-core/debug"]
-disasm = ["capstone"]
+test = []
diff --git a/lib/llvm-backend/README.md b/lib/llvm-backend/README.md
index 08dc5c5d9..584b37585 100644
--- a/lib/llvm-backend/README.md
+++ b/lib/llvm-backend/README.md
@@ -1,21 +1,21 @@
-
+
-
-
+
+
-
+
-
+
@@ -36,7 +36,7 @@ This crate represents the LLVM backend integration for Wasmer.
If you are using the `wasmer` CLI, you can specify the backend with:
-```bash
+```sh
wasmer run program.wasm --backend=llvm
```
diff --git a/lib/llvm-backend/cpp/object_loader.cpp b/lib/llvm-backend/cpp/object_loader.cpp
index bf034a308..c4fc6d936 100644
--- a/lib/llvm-backend/cpp/object_loader.cpp
+++ b/lib/llvm-backend/cpp/object_loader.cpp
@@ -1,161 +1,196 @@
#include "object_loader.hh"
#include
#include
+#include
extern "C" void __register_frame(uint8_t *);
extern "C" void __deregister_frame(uint8_t *);
-struct MemoryManager : llvm::RuntimeDyld::MemoryManager {
-public:
- MemoryManager(callbacks_t callbacks) : callbacks(callbacks) {}
+MemoryManager::~MemoryManager() {
+ deregisterEHFrames();
+ // Deallocate all of the allocated memory.
+ callbacks.dealloc_memory(code_section.base, code_section.size);
+ callbacks.dealloc_memory(read_section.base, read_section.size);
+ callbacks.dealloc_memory(readwrite_section.base, readwrite_section.size);
+}
+void unwinding_setjmp(jmp_buf stack_out, void (*func)(void *), void *userdata) {
+ if (setjmp(stack_out)) {
- virtual ~MemoryManager() override {
- deregisterEHFrames();
- // Deallocate all of the allocated memory.
- callbacks.dealloc_memory(code_section.base, code_section.size);
- callbacks.dealloc_memory(read_section.base, read_section.size);
- callbacks.dealloc_memory(readwrite_section.base, readwrite_section.size);
+ } else {
+ func(userdata);
}
+}
- virtual uint8_t *allocateCodeSection(uintptr_t size, unsigned alignment,
- unsigned section_id,
- llvm::StringRef section_name) override {
- return allocate_bump(code_section, code_bump_ptr, size, alignment);
+[[noreturn]] void unwinding_longjmp(jmp_buf stack_in) { longjmp(stack_in, 42); }
+
+struct UnwindPoint {
+ UnwindPoint *prev;
+ jmp_buf stack;
+ std::function *f;
+ std::unique_ptr exception;
+};
+
+static thread_local UnwindPoint *unwind_state = nullptr;
+
+static void unwind_payload(void *_point) {
+ UnwindPoint *point = (UnwindPoint *)_point;
+ (*point->f)();
+}
+
+void catch_unwind(std::function &&f) {
+ UnwindPoint current;
+ current.prev = unwind_state;
+ current.f = &f;
+ unwind_state = ¤t;
+
+ unwinding_setjmp(current.stack, unwind_payload, (void *)¤t);
+
+ unwind_state = current.prev;
+ if (current.exception) {
+ throw std::move(current.exception);
}
+}
- virtual uint8_t *allocateDataSection(uintptr_t size, unsigned alignment,
- unsigned section_id,
- llvm::StringRef section_name,
- bool read_only) override {
- // Allocate from the read-only section or the read-write section, depending
- // on if this allocation should be read-only or not.
- if (read_only) {
- return allocate_bump(read_section, read_bump_ptr, size, alignment);
- } else {
- return allocate_bump(readwrite_section, readwrite_bump_ptr, size,
- alignment);
+void unsafe_unwind(WasmException *exception) {
+ UnwindPoint *state = unwind_state;
+ if (state) {
+ state->exception.reset(exception);
+ unwinding_longjmp(state->stack);
+ } else {
+ abort();
+ }
+}
+
+uint8_t *MemoryManager::allocateCodeSection(uintptr_t size, unsigned alignment,
+ unsigned section_id,
+ llvm::StringRef section_name) {
+ return allocate_bump(code_section, code_bump_ptr, size, alignment);
+}
+
+uint8_t *MemoryManager::allocateDataSection(uintptr_t size, unsigned alignment,
+ unsigned section_id,
+ llvm::StringRef section_name,
+ bool read_only) {
+ // Allocate from the read-only section or the read-write section, depending
+ // on if this allocation should be read-only or not.
+ uint8_t *ret;
+ if (read_only) {
+ ret = allocate_bump(read_section, read_bump_ptr, size, alignment);
+ } else {
+ ret = allocate_bump(readwrite_section, readwrite_bump_ptr, size, alignment);
+ }
+ if (section_name.equals(llvm::StringRef("__llvm_stackmaps")) ||
+ section_name.equals(llvm::StringRef(".llvm_stackmaps"))) {
+ stack_map_ptr = ret;
+ stack_map_size = size;
+ }
+ return ret;
+}
+
+void MemoryManager::reserveAllocationSpace(uintptr_t code_size,
+ uint32_t code_align,
+ uintptr_t read_data_size,
+ uint32_t read_data_align,
+ uintptr_t read_write_data_size,
+ uint32_t read_write_data_align) {
+ auto aligner = [](uintptr_t ptr, size_t align) {
+ if (ptr == 0) {
+ return align;
}
- }
+ return (ptr + align - 1) & ~(align - 1);
+ };
+ uint8_t *code_ptr_out = nullptr;
+ size_t code_size_out = 0;
+ auto code_result =
+ callbacks.alloc_memory(aligner(code_size, 4096), PROTECT_READ_WRITE,
+ &code_ptr_out, &code_size_out);
+ assert(code_result == RESULT_OK);
+ code_section = Section{code_ptr_out, code_size_out};
+ code_bump_ptr = (uintptr_t)code_ptr_out;
+ code_start_ptr = (uintptr_t)code_ptr_out;
+ this->code_size = code_size;
- virtual void reserveAllocationSpace(uintptr_t code_size, uint32_t code_align,
- uintptr_t read_data_size,
- uint32_t read_data_align,
- uintptr_t read_write_data_size,
- uint32_t read_write_data_align) override {
- auto aligner = [](uintptr_t ptr, size_t align) {
- if (ptr == 0) {
- return align;
- }
- return (ptr + align - 1) & ~(align - 1);
- };
+ uint8_t *read_ptr_out = nullptr;
+ size_t read_size_out = 0;
+ auto read_result =
+ callbacks.alloc_memory(aligner(read_data_size, 4096), PROTECT_READ_WRITE,
+ &read_ptr_out, &read_size_out);
+ assert(read_result == RESULT_OK);
+ read_section = Section{read_ptr_out, read_size_out};
+ read_bump_ptr = (uintptr_t)read_ptr_out;
- uint8_t *code_ptr_out = nullptr;
- size_t code_size_out = 0;
- auto code_result =
- callbacks.alloc_memory(aligner(code_size, 4096), PROTECT_READ_WRITE,
- &code_ptr_out, &code_size_out);
- assert(code_result == RESULT_OK);
- code_section = Section{code_ptr_out, code_size_out};
- code_bump_ptr = (uintptr_t)code_ptr_out;
+ uint8_t *readwrite_ptr_out = nullptr;
+ size_t readwrite_size_out = 0;
+ auto readwrite_result = callbacks.alloc_memory(
+ aligner(read_write_data_size, 4096), PROTECT_READ_WRITE,
+ &readwrite_ptr_out, &readwrite_size_out);
+ assert(readwrite_result == RESULT_OK);
+ readwrite_section = Section{readwrite_ptr_out, readwrite_size_out};
+ readwrite_bump_ptr = (uintptr_t)readwrite_ptr_out;
+}
- uint8_t *read_ptr_out = nullptr;
- size_t read_size_out = 0;
- auto read_result = callbacks.alloc_memory(aligner(read_data_size, 4096),
- PROTECT_READ_WRITE, &read_ptr_out,
- &read_size_out);
- assert(read_result == RESULT_OK);
- read_section = Section{read_ptr_out, read_size_out};
- read_bump_ptr = (uintptr_t)read_ptr_out;
+bool MemoryManager::needsToReserveAllocationSpace() { return true; }
- uint8_t *readwrite_ptr_out = nullptr;
- size_t readwrite_size_out = 0;
- auto readwrite_result = callbacks.alloc_memory(
- aligner(read_write_data_size, 4096), PROTECT_READ_WRITE,
- &readwrite_ptr_out, &readwrite_size_out);
- assert(readwrite_result == RESULT_OK);
- readwrite_section = Section{readwrite_ptr_out, readwrite_size_out};
- readwrite_bump_ptr = (uintptr_t)readwrite_ptr_out;
- }
-
- /* Turn on the `reserveAllocationSpace` callback. */
- virtual bool needsToReserveAllocationSpace() override { return true; }
-
- virtual void registerEHFrames(uint8_t *addr, uint64_t LoadAddr,
- size_t size) override {
+void MemoryManager::registerEHFrames(uint8_t *addr, uint64_t LoadAddr,
+ size_t size) {
// We don't know yet how to do this on Windows, so we hide this on compilation
// so we can compile and pass spectests on unix systems
#ifndef _WIN32
- eh_frame_ptr = addr;
- eh_frame_size = size;
- eh_frames_registered = true;
- callbacks.visit_fde(addr, size, __register_frame);
+ eh_frame_ptr = addr;
+ eh_frame_size = size;
+ eh_frames_registered = true;
+ callbacks.visit_fde(addr, size, __register_frame);
#endif
- }
+}
- virtual void deregisterEHFrames() override {
+void MemoryManager::deregisterEHFrames() {
// We don't know yet how to do this on Windows, so we hide this on compilation
// so we can compile and pass spectests on unix systems
#ifndef _WIN32
- if (eh_frames_registered) {
- callbacks.visit_fde(eh_frame_ptr, eh_frame_size, __deregister_frame);
- }
-#endif
+ if (eh_frames_registered) {
+ callbacks.visit_fde(eh_frame_ptr, eh_frame_size, __deregister_frame);
}
+#endif
+}
- virtual bool finalizeMemory(std::string *ErrMsg = nullptr) override {
- auto code_result =
- callbacks.protect_memory(code_section.base, code_section.size,
- mem_protect_t::PROTECT_READ_EXECUTE);
- if (code_result != RESULT_OK) {
- return false;
- }
-
- auto read_result = callbacks.protect_memory(
- read_section.base, read_section.size, mem_protect_t::PROTECT_READ);
- if (read_result != RESULT_OK) {
- return false;
- }
-
- // The readwrite section is already mapped as read-write.
-
+bool MemoryManager::finalizeMemory(std::string *ErrMsg) {
+ auto code_result =
+ callbacks.protect_memory(code_section.base, code_section.size,
+ mem_protect_t::PROTECT_READ_EXECUTE);
+ if (code_result != RESULT_OK) {
return false;
}
- virtual void
- notifyObjectLoaded(llvm::RuntimeDyld &RTDyld,
- const llvm::object::ObjectFile &Obj) override {}
-
-private:
- struct Section {
- uint8_t *base;
- size_t size;
- };
-
- uint8_t *allocate_bump(Section §ion, uintptr_t &bump_ptr, size_t size,
- size_t align) {
- auto aligner = [](uintptr_t &ptr, size_t align) {
- ptr = (ptr + align - 1) & ~(align - 1);
- };
-
- // Align the bump pointer to the requires alignment.
- aligner(bump_ptr, align);
-
- auto ret_ptr = bump_ptr;
- bump_ptr += size;
-
- assert(bump_ptr <= (uintptr_t)section.base + section.size);
-
- return (uint8_t *)ret_ptr;
+ auto read_result = callbacks.protect_memory(
+ read_section.base, read_section.size, mem_protect_t::PROTECT_READ);
+ if (read_result != RESULT_OK) {
+ return false;
}
- Section code_section, read_section, readwrite_section;
- uintptr_t code_bump_ptr, read_bump_ptr, readwrite_bump_ptr;
- uint8_t *eh_frame_ptr;
- size_t eh_frame_size;
- bool eh_frames_registered = false;
+ // The readwrite section is already mapped as read-write.
- callbacks_t callbacks;
-};
+ return false;
+}
+
+void MemoryManager::notifyObjectLoaded(llvm::RuntimeDyld &RTDyld,
+ const llvm::object::ObjectFile &Obj) {}
+
+uint8_t *MemoryManager::allocate_bump(Section §ion, uintptr_t &bump_ptr,
+ size_t size, size_t align) {
+ auto aligner = [](uintptr_t &ptr, size_t align) {
+ ptr = (ptr + align - 1) & ~(align - 1);
+ };
+
+ // Align the bump pointer to the requires alignment.
+ aligner(bump_ptr, align);
+
+ auto ret_ptr = bump_ptr;
+ bump_ptr += size;
+
+ assert(bump_ptr <= (uintptr_t)section.base + section.size);
+
+ return (uint8_t *)ret_ptr;
+}
struct SymbolLookup : llvm::JITSymbolResolver {
public:
@@ -218,3 +253,19 @@ void *WasmModule::get_func(llvm::StringRef name) const {
auto symbol = runtime_dyld->getSymbol(name);
return (void *)symbol.getAddress();
}
+
+uint8_t *WasmModule::get_stack_map_ptr() const {
+ return memory_manager->get_stack_map_ptr();
+}
+
+size_t WasmModule::get_stack_map_size() const {
+ return memory_manager->get_stack_map_size();
+}
+
+uint8_t *WasmModule::get_code_ptr() const {
+ return memory_manager->get_code_ptr();
+}
+
+size_t WasmModule::get_code_size() const {
+ return memory_manager->get_code_size();
+}
diff --git a/lib/llvm-backend/cpp/object_loader.hh b/lib/llvm-backend/cpp/object_loader.hh
index 7a410b2dc..bc9b9ab67 100644
--- a/lib/llvm-backend/cpp/object_loader.hh
+++ b/lib/llvm-backend/cpp/object_loader.hh
@@ -1,7 +1,12 @@
+#pragma once
+
#include
#include
#include
+#include
#include
+#include
+#include
#include
#include
@@ -48,11 +53,92 @@ typedef struct {
size_t data, vtable;
} box_any_t;
-struct WasmException {
-public:
- virtual std::string description() const noexcept = 0;
+enum WasmTrapType {
+ Unreachable = 0,
+ IncorrectCallIndirectSignature = 1,
+ MemoryOutOfBounds = 2,
+ CallIndirectOOB = 3,
+ IllegalArithmetic = 4,
+ Unknown,
};
+extern "C" void callback_trampoline(void *, void *);
+
+struct MemoryManager : llvm::RuntimeDyld::MemoryManager {
+public:
+ MemoryManager(callbacks_t callbacks) : callbacks(callbacks) {}
+ virtual ~MemoryManager() override;
+
+ inline uint8_t *get_stack_map_ptr() const { return stack_map_ptr; }
+ inline size_t get_stack_map_size() const { return stack_map_size; }
+ inline uint8_t *get_code_ptr() const { return (uint8_t *)code_start_ptr; }
+ inline size_t get_code_size() const { return code_size; }
+
+ virtual uint8_t *allocateCodeSection(uintptr_t size, unsigned alignment,
+ unsigned section_id,
+ llvm::StringRef section_name) override;
+ virtual uint8_t *allocateDataSection(uintptr_t size, unsigned alignment,
+ unsigned section_id,
+ llvm::StringRef section_name,
+ bool read_only) override;
+ virtual void reserveAllocationSpace(uintptr_t code_size, uint32_t code_align,
+ uintptr_t read_data_size,
+ uint32_t read_data_align,
+ uintptr_t read_write_data_size,
+ uint32_t read_write_data_align) override;
+ /* Turn on the `reserveAllocationSpace` callback. */
+ virtual bool needsToReserveAllocationSpace() override;
+ virtual void registerEHFrames(uint8_t *addr, uint64_t LoadAddr,
+ size_t size) override;
+ virtual void deregisterEHFrames() override;
+ virtual bool finalizeMemory(std::string *ErrMsg = nullptr) override;
+ virtual void notifyObjectLoaded(llvm::RuntimeDyld &RTDyld,
+ const llvm::object::ObjectFile &Obj) override;
+
+private:
+ struct Section {
+ uint8_t *base;
+ size_t size;
+ };
+
+ uint8_t *allocate_bump(Section §ion, uintptr_t &bump_ptr, size_t size,
+ size_t align);
+
+ Section code_section, read_section, readwrite_section;
+ uintptr_t code_start_ptr;
+ size_t code_size;
+ uintptr_t code_bump_ptr, read_bump_ptr, readwrite_bump_ptr;
+ uint8_t *eh_frame_ptr;
+ size_t eh_frame_size;
+ bool eh_frames_registered = false;
+
+ callbacks_t callbacks;
+
+ uint8_t *stack_map_ptr = nullptr;
+ size_t stack_map_size = 0;
+};
+
+struct WasmErrorSink {
+ WasmTrapType *trap_out;
+ box_any_t *user_error;
+};
+
+struct WasmException : std::exception {
+public:
+ virtual std::string description() const noexcept { return "unknown"; }
+
+ virtual const char *what() const noexcept override {
+ return "wasm exception";
+ }
+
+ virtual void write_error(WasmErrorSink &out) const noexcept {
+ *out.trap_out = WasmTrapType::Unknown;
+ }
+};
+
+void catch_unwind(std::function &&f);
+[[noreturn]] void unsafe_unwind(WasmException *exception);
+
struct UncatchableException : WasmException {
public:
virtual std::string description() const noexcept override {
@@ -70,6 +156,10 @@ public:
// The parts of a `Box`.
box_any_t error_data;
+
+ virtual void write_error(WasmErrorSink &out) const noexcept override {
+ *out.user_error = error_data;
+ }
};
struct BreakpointException : UncatchableException {
@@ -81,20 +171,35 @@ public:
}
uintptr_t callback;
+
+ virtual void write_error(WasmErrorSink &out) const noexcept override {
+ puts("CB TRAMPOLINE");
+ callback_trampoline(out.user_error, (void *)callback);
+ }
+};
+
+struct WasmModule {
+public:
+ WasmModule(const uint8_t *object_start, size_t object_size,
+ callbacks_t callbacks);
+
+ void *get_func(llvm::StringRef name) const;
+ uint8_t *get_stack_map_ptr() const;
+ size_t get_stack_map_size() const;
+ uint8_t *get_code_ptr() const;
+ size_t get_code_size() const;
+
+ bool _init_failed = false;
+
+private:
+ std::unique_ptr memory_manager;
+ std::unique_ptr object_file;
+ std::unique_ptr runtime_dyld;
};
struct WasmTrap : UncatchableException {
public:
- enum Type {
- Unreachable = 0,
- IncorrectCallIndirectSignature = 1,
- MemoryOutOfBounds = 2,
- CallIndirectOOB = 3,
- IllegalArithmetic = 4,
- Unknown,
- };
-
- WasmTrap(Type type) : type(type) {}
+ WasmTrap(WasmTrapType type) : type(type) {}
virtual std::string description() const noexcept override {
std::ostringstream ss;
@@ -103,27 +208,31 @@ public:
return ss.str();
}
- Type type;
+ WasmTrapType type;
+
+ virtual void write_error(WasmErrorSink &out) const noexcept override {
+ *out.trap_out = type;
+ }
private:
- friend std::ostream &operator<<(std::ostream &out, const Type &ty) {
+ friend std::ostream &operator<<(std::ostream &out, const WasmTrapType &ty) {
switch (ty) {
- case Type::Unreachable:
+ case WasmTrapType::Unreachable:
out << "unreachable";
break;
- case Type::IncorrectCallIndirectSignature:
+ case WasmTrapType::IncorrectCallIndirectSignature:
out << "incorrect call_indirect signature";
break;
- case Type::MemoryOutOfBounds:
+ case WasmTrapType::MemoryOutOfBounds:
out << "memory access out-of-bounds";
break;
- case Type::CallIndirectOOB:
+ case WasmTrapType::CallIndirectOOB:
out << "call_indirect out-of-bounds";
break;
- case Type::IllegalArithmetic:
+ case WasmTrapType::IllegalArithmetic:
out << "illegal arithmetic operation";
break;
- case Type::Unknown:
+ case WasmTrapType::Unknown:
default:
out << "unknown";
break;
@@ -145,23 +254,7 @@ public:
uint64_t values[1];
};
-struct WasmModule {
-public:
- WasmModule(const uint8_t *object_start, size_t object_size,
- callbacks_t callbacks);
-
- void *get_func(llvm::StringRef name) const;
-
- bool _init_failed = false;
-
-private:
- std::unique_ptr memory_manager;
- std::unique_ptr object_file;
- std::unique_ptr runtime_dyld;
-};
-
extern "C" {
-void callback_trampoline(void *, void *);
result_t module_load(const uint8_t *mem_ptr, size_t mem_size,
callbacks_t callbacks, WasmModule **module_out) {
@@ -174,42 +267,40 @@ result_t module_load(const uint8_t *mem_ptr, size_t mem_size,
return RESULT_OK;
}
-[[noreturn]] void throw_trap(WasmTrap::Type ty) { throw WasmTrap(ty); }
+[[noreturn]] void throw_trap(WasmTrapType ty) {
+ unsafe_unwind(new WasmTrap(ty));
+}
void module_delete(WasmModule *module) { delete module; }
// Throw a fat pointer that's assumed to be `*mut dyn Any` on the rust
// side.
[[noreturn]] void throw_any(size_t data, size_t vtable) {
- throw UserException(data, vtable);
+ unsafe_unwind(new UserException(data, vtable));
}
// Throw a pointer that's assumed to be codegen::BreakpointHandler on the
// rust side.
[[noreturn]] void throw_breakpoint(uintptr_t callback) {
- throw BreakpointException(callback);
+ unsafe_unwind(new BreakpointException(callback));
}
bool invoke_trampoline(trampoline_t trampoline, void *ctx, void *func,
- void *params, void *results, WasmTrap::Type *trap_out,
+ void *params, void *results, WasmTrapType *trap_out,
box_any_t *user_error, void *invoke_env) noexcept {
try {
- trampoline(ctx, func, params, results);
+ catch_unwind([trampoline, ctx, func, params, results]() {
+ trampoline(ctx, func, params, results);
+ });
return true;
- } catch (const WasmTrap &e) {
- *trap_out = e.type;
- return false;
- } catch (const UserException &e) {
- *user_error = e.error_data;
- return false;
- } catch (const BreakpointException &e) {
- callback_trampoline(user_error, (void *)e.callback);
- return false;
- } catch (const WasmException &e) {
- *trap_out = WasmTrap::Type::Unknown;
+ } catch (std::unique_ptr &e) {
+ WasmErrorSink sink;
+ sink.trap_out = trap_out;
+ sink.user_error = user_error;
+ e->write_error(sink);
return false;
} catch (...) {
- *trap_out = WasmTrap::Type::Unknown;
+ *trap_out = WasmTrapType::Unknown;
return false;
}
}
@@ -217,4 +308,20 @@ bool invoke_trampoline(trampoline_t trampoline, void *ctx, void *func,
void *get_func_symbol(WasmModule *module, const char *name) {
return module->get_func(llvm::StringRef(name));
}
+
+const uint8_t *llvm_backend_get_stack_map_ptr(const WasmModule *module) {
+ return module->get_stack_map_ptr();
+}
+
+size_t llvm_backend_get_stack_map_size(const WasmModule *module) {
+ return module->get_stack_map_size();
+}
+
+const uint8_t *llvm_backend_get_code_ptr(const WasmModule *module) {
+ return module->get_code_ptr();
+}
+
+size_t llvm_backend_get_code_size(const WasmModule *module) {
+ return module->get_code_size();
+}
}
diff --git a/lib/llvm-backend/src/backend.rs b/lib/llvm-backend/src/backend.rs
index 92f0f06a1..a5d262035 100644
--- a/lib/llvm-backend/src/backend.rs
+++ b/lib/llvm-backend/src/backend.rs
@@ -1,20 +1,24 @@
-use crate::intrinsics::Intrinsics;
-use crate::structs::{Callbacks, LLVMModule, LLVMResult, MemProtect};
+use super::stackmap::StackmapRegistry;
+use crate::{
+ intrinsics::Intrinsics,
+ structs::{Callbacks, LLVMModule, LLVMResult, MemProtect},
+};
use inkwell::{
memory_buffer::MemoryBuffer,
module::Module,
- targets::{CodeModel, FileType, InitializationConfig, RelocMode, Target, TargetMachine},
- OptimizationLevel,
+ targets::{FileType, TargetMachine},
};
use libc::c_char;
use std::{
any::Any,
+ cell::RefCell,
ffi::{c_void, CString},
fs::File,
io::Write,
mem,
ops::Deref,
ptr::{self, NonNull},
+ rc::Rc,
slice, str,
sync::{Arc, Once},
};
@@ -25,8 +29,9 @@ use wasmer_runtime_core::{
},
cache::Error as CacheError,
module::ModuleInfo,
+ state::ModuleStateMap,
structures::TypedIndex,
- typed_func::{Wasm, WasmTrapInfo},
+ typed_func::{Trampoline, Wasm, WasmTrapInfo},
types::{LocalFuncIndex, SigIndex},
vm, vmcalls,
};
@@ -40,6 +45,10 @@ extern "C" {
) -> LLVMResult;
fn module_delete(module: *mut LLVMModule);
fn get_func_symbol(module: *mut LLVMModule, name: *const c_char) -> *const vm::Func;
+ fn llvm_backend_get_stack_map_ptr(module: *const LLVMModule) -> *const u8;
+ fn llvm_backend_get_stack_map_size(module: *const LLVMModule) -> usize;
+ fn llvm_backend_get_code_ptr(module: *const LLVMModule) -> *const u8;
+ fn llvm_backend_get_code_size(module: *const LLVMModule) -> usize;
fn throw_trap(ty: i32) -> !;
fn throw_breakpoint(ty: i64) -> !;
@@ -52,7 +61,7 @@ extern "C" {
#[allow(improper_ctypes)]
fn invoke_trampoline(
- trampoline: unsafe extern "C" fn(*mut vm::Ctx, NonNull, *const u64, *mut u64),
+ trampoline: Trampoline,
vmctx_ptr: *mut vm::Ctx,
func_ptr: NonNull,
params: *const u64,
@@ -63,6 +72,8 @@ extern "C" {
) -> bool;
}
+static SIGNAL_HANDLER_INSTALLED: Once = Once::new();
+
fn get_callbacks() -> Callbacks {
extern "C" fn alloc_memory(
size: usize,
@@ -154,33 +165,20 @@ pub struct LLVMBackend {
module: *mut LLVMModule,
#[allow(dead_code)]
buffer: Arc,
+ msm: Option,
+ local_func_id_to_offset: Vec,
}
impl LLVMBackend {
- pub fn new(module: Module, _intrinsics: Intrinsics) -> (Self, LLVMCache) {
- Target::initialize_x86(&InitializationConfig {
- asm_parser: true,
- asm_printer: true,
- base: true,
- disassembler: true,
- info: true,
- machine_code: true,
- });
- let triple = TargetMachine::get_default_triple().to_string();
- let target = Target::from_triple(&triple).unwrap();
- let target_machine = target
- .create_target_machine(
- &triple,
- &TargetMachine::get_host_cpu_name().to_string(),
- &TargetMachine::get_host_cpu_features().to_string(),
- OptimizationLevel::Aggressive,
- RelocMode::PIC,
- CodeModel::Default,
- )
- .unwrap();
-
+ pub fn new(
+ module: Rc>,
+ _intrinsics: Intrinsics,
+ _stackmaps: &StackmapRegistry,
+ _module_info: &ModuleInfo,
+ target_machine: &TargetMachine,
+ ) -> (Self, LLVMCache) {
let memory_buffer = target_machine
- .write_to_memory_buffer(&module, FileType::Object)
+ .write_to_memory_buffer(&module.borrow_mut(), FileType::Object)
.unwrap();
let mem_buf_slice = memory_buffer.as_slice();
@@ -204,22 +202,134 @@ impl LLVMBackend {
)
};
- static SIGNAL_HANDLER_INSTALLED: Once = Once::new();
-
- SIGNAL_HANDLER_INSTALLED.call_once(|| unsafe {
- crate::platform::install_signal_handler();
- });
-
if res != LLVMResult::OK {
panic!("failed to load object")
}
let buffer = Arc::new(Buffer::LlvmMemory(memory_buffer));
+ #[cfg(all(any(target_os = "linux", target_os = "macos"), target_arch = "x86_64"))]
+ {
+ use super::stackmap::{self, StkMapRecord, StkSizeRecord};
+ use std::collections::BTreeMap;
+
+ let stackmaps = _stackmaps;
+ let module_info = _module_info;
+
+ let raw_stackmap = unsafe {
+ std::slice::from_raw_parts(
+ llvm_backend_get_stack_map_ptr(module),
+ llvm_backend_get_stack_map_size(module),
+ )
+ };
+ if raw_stackmap.len() > 0 {
+ let map = stackmap::StackMap::parse(raw_stackmap).unwrap();
+
+ let (code_ptr, code_size) = unsafe {
+ (
+ llvm_backend_get_code_ptr(module),
+ llvm_backend_get_code_size(module),
+ )
+ };
+ let mut msm = ModuleStateMap {
+ local_functions: Default::default(),
+ total_size: code_size,
+ };
+
+ let num_local_functions =
+ module_info.func_assoc.len() - module_info.imported_functions.len();
+ let mut local_func_id_to_addr: Vec = Vec::with_capacity(num_local_functions);
+
+ // All local functions.
+ for index in module_info.imported_functions.len()..module_info.func_assoc.len() {
+ let name = if cfg!(target_os = "macos") {
+ format!("_fn{}", index)
+ } else {
+ format!("fn{}", index)
+ };
+
+ let c_str = CString::new(name).unwrap();
+ let ptr = unsafe { get_func_symbol(module, c_str.as_ptr()) };
+
+ assert!(!ptr.is_null());
+ local_func_id_to_addr.push(ptr as usize);
+ }
+
+ let mut addr_to_size_record: BTreeMap = BTreeMap::new();
+
+ for record in &map.stk_size_records {
+ addr_to_size_record.insert(record.function_address as usize, record);
+ }
+
+ let mut map_records: BTreeMap = BTreeMap::new();
+
+ for record in &map.stk_map_records {
+ map_records.insert(record.patchpoint_id as usize, record);
+ }
+
+ for ((start_id, start_entry), (end_id, end_entry)) in stackmaps
+ .entries
+ .iter()
+ .enumerate()
+ .step_by(2)
+ .zip(stackmaps.entries.iter().enumerate().skip(1).step_by(2))
+ {
+ if let Some(map_record) = map_records.get(&start_id) {
+ assert_eq!(start_id, map_record.patchpoint_id as usize);
+ assert!(start_entry.is_start);
+ assert!(!end_entry.is_start);
+
+ let end_record = map_records.get(&end_id);
+
+ let addr = local_func_id_to_addr[start_entry.local_function_id];
+ let size_record = *addr_to_size_record
+ .get(&addr)
+ .expect("size_record not found");
+
+ start_entry.populate_msm(
+ module_info,
+ code_ptr as usize,
+ &map,
+ size_record,
+ map_record,
+ end_record.map(|x| (end_entry, *x)),
+ &mut msm,
+ );
+ } else {
+ // The record is optimized out.
+ }
+ }
+
+ let code_ptr = unsafe { llvm_backend_get_code_ptr(module) } as usize;
+ let code_len = unsafe { llvm_backend_get_code_size(module) } as usize;
+
+ let local_func_id_to_offset: Vec = local_func_id_to_addr
+ .iter()
+ .map(|&x| {
+ assert!(x >= code_ptr && x < code_ptr + code_len);
+ x - code_ptr
+ })
+ .collect();
+
+ return (
+ Self {
+ module,
+ buffer: Arc::clone(&buffer),
+ msm: Some(msm),
+ local_func_id_to_offset,
+ },
+ LLVMCache { buffer },
+ );
+ }
+ }
+
+ // Stackmap is not supported on this platform, or this module contains no functions so no stackmaps.
(
Self {
module,
buffer: Arc::clone(&buffer),
+ msm: None,
+ local_func_id_to_offset: vec![],
},
LLVMCache { buffer },
)
@@ -237,8 +347,6 @@ impl LLVMBackend {
return Err("failed to load object".to_string());
}
- static SIGNAL_HANDLER_INSTALLED: Once = Once::new();
-
SIGNAL_HANDLER_INSTALLED.call_once(|| {
crate::platform::install_signal_handler();
});
@@ -249,6 +357,8 @@ impl LLVMBackend {
Self {
module,
buffer: Arc::clone(&buffer),
+ msm: None,
+ local_func_id_to_offset: vec![],
},
LLVMCache { buffer },
))
@@ -281,12 +391,7 @@ impl RunnableModule for LLVMBackend {
}
fn get_trampoline(&self, _: &ModuleInfo, sig_index: SigIndex) -> Option {
- let trampoline: unsafe extern "C" fn(
- *mut vm::Ctx,
- NonNull,
- *const u64,
- *mut u64,
- ) = unsafe {
+ let trampoline: Trampoline = unsafe {
let name = if cfg!(target_os = "macos") {
format!("_trmp{}", sig_index.index())
} else {
@@ -300,9 +405,30 @@ impl RunnableModule for LLVMBackend {
mem::transmute(symbol)
};
+ SIGNAL_HANDLER_INSTALLED.call_once(|| unsafe {
+ crate::platform::install_signal_handler();
+ });
+
Some(unsafe { Wasm::from_raw_parts(trampoline, invoke_trampoline, None) })
}
+ fn get_code(&self) -> Option<&[u8]> {
+ Some(unsafe {
+ std::slice::from_raw_parts(
+ llvm_backend_get_code_ptr(self.module),
+ llvm_backend_get_code_size(self.module),
+ )
+ })
+ }
+
+ fn get_local_function_offsets(&self) -> Option> {
+ Some(self.local_func_id_to_offset.clone())
+ }
+
+ fn get_module_state_map(&self) -> Option {
+ self.msm.clone()
+ }
+
unsafe fn do_early_trap(&self, data: Box) -> ! {
throw_any(Box::leak(data))
}
@@ -329,33 +455,3 @@ impl CacheGen for LLVMCache {
Ok(([].as_ref().into(), memory))
}
}
-
-#[cfg(feature = "disasm")]
-unsafe fn disass_ptr(ptr: *const u8, size: usize, inst_count: usize) {
- use capstone::arch::BuildsCapstone;
- let mut cs = capstone::Capstone::new() // Call builder-pattern
- .x86() // X86 architecture
- .mode(capstone::arch::x86::ArchMode::Mode64) // 64-bit mode
- .detail(true) // Generate extra instruction details
- .build()
- .expect("Failed to create Capstone object");
-
- // Get disassembled instructions
- let insns = cs
- .disasm_count(
- std::slice::from_raw_parts(ptr, size),
- ptr as u64,
- inst_count,
- )
- .expect("Failed to disassemble");
-
- println!("count = {}", insns.len());
- for insn in insns.iter() {
- println!(
- "0x{:x}: {:6} {}",
- insn.address(),
- insn.mnemonic().unwrap_or(""),
- insn.op_str().unwrap_or("")
- );
- }
-}
diff --git a/lib/llvm-backend/src/code.rs b/lib/llvm-backend/src/code.rs
index 1f78ccc5b..c0f6e07dd 100644
--- a/lib/llvm-backend/src/code.rs
+++ b/lib/llvm-backend/src/code.rs
@@ -1,19 +1,34 @@
+use crate::{
+ backend::LLVMBackend,
+ intrinsics::{tbaa_label, CtxType, GlobalCache, Intrinsics, MemoryCache},
+ read_info::{blocktype_to_type, type_to_type},
+ stackmap::{StackmapEntry, StackmapEntryKind, StackmapRegistry, ValueSemantic},
+ state::{ControlFrame, ExtraInfo, IfElseState, State},
+ trampolines::generate_trampolines,
+};
use inkwell::{
builder::Builder,
context::Context,
module::{Linkage, Module},
passes::PassManager,
+ targets::{CodeModel, InitializationConfig, RelocMode, Target, TargetMachine},
types::{BasicType, BasicTypeEnum, FunctionType, PointerType, VectorType},
values::{
BasicValue, BasicValueEnum, FloatValue, FunctionValue, IntValue, PhiValue, PointerValue,
VectorValue,
},
- AddressSpace, AtomicOrdering, AtomicRMWBinOp, FloatPredicate, IntPredicate,
+ AddressSpace, AtomicOrdering, AtomicRMWBinOp, FloatPredicate, IntPredicate, OptimizationLevel,
};
use smallvec::SmallVec;
-use std::sync::{Arc, RwLock};
+use std::{
+ cell::RefCell,
+ collections::HashMap,
+ mem::ManuallyDrop,
+ rc::Rc,
+ sync::{Arc, RwLock},
+};
use wasmer_runtime_core::{
- backend::{Backend, CacheGen, Token},
+ backend::{Backend, CacheGen, CompilerConfig, Token},
cache::{Artifact, Error as CacheError},
codegen::*,
memory::MemoryType,
@@ -25,13 +40,12 @@ use wasmer_runtime_core::{
};
use wasmparser::{BinaryReaderError, MemoryImmediate, Operator, Type as WpType};
-use crate::backend::LLVMBackend;
-use crate::intrinsics::{CtxType, GlobalCache, Intrinsics, MemoryCache};
-use crate::read_info::{blocktype_to_type, type_to_type};
-use crate::state::{ControlFrame, IfElseState, State};
-use crate::trampolines::generate_trampolines;
-
-fn func_sig_to_llvm(context: &Context, intrinsics: &Intrinsics, sig: &FuncSig) -> FunctionType {
+fn func_sig_to_llvm<'ctx>(
+ context: &'ctx Context,
+ intrinsics: &Intrinsics<'ctx>,
+ sig: &FuncSig,
+ type_to_llvm: fn(intrinsics: &Intrinsics<'ctx>, ty: Type) -> BasicTypeEnum<'ctx>,
+) -> FunctionType<'ctx> {
let user_param_types = sig.params().iter().map(|&ty| type_to_llvm(intrinsics, ty));
let param_types: Vec<_> = std::iter::once(intrinsics.ctx_ptr_ty.as_basic_type_enum())
@@ -54,7 +68,7 @@ fn func_sig_to_llvm(context: &Context, intrinsics: &Intrinsics, sig: &FuncSig) -
}
}
-fn type_to_llvm(intrinsics: &Intrinsics, ty: Type) -> BasicTypeEnum {
+fn type_to_llvm<'ctx>(intrinsics: &Intrinsics<'ctx>, ty: Type) -> BasicTypeEnum<'ctx> {
match ty {
Type::I32 => intrinsics.i32_ty.as_basic_type_enum(),
Type::I64 => intrinsics.i64_ty.as_basic_type_enum(),
@@ -64,14 +78,22 @@ fn type_to_llvm(intrinsics: &Intrinsics, ty: Type) -> BasicTypeEnum {
}
}
+fn type_to_llvm_int_only<'ctx>(intrinsics: &Intrinsics<'ctx>, ty: Type) -> BasicTypeEnum<'ctx> {
+ match ty {
+ Type::I32 | Type::F32 => intrinsics.i32_ty.as_basic_type_enum(),
+ Type::I64 | Type::F64 => intrinsics.i64_ty.as_basic_type_enum(),
+ Type::V128 => intrinsics.i128_ty.as_basic_type_enum(),
+ }
+}
+
// Create a vector where each lane contains the same value.
-fn splat_vector(
- builder: &Builder,
- intrinsics: &Intrinsics,
- value: BasicValueEnum,
- vec_ty: VectorType,
+fn splat_vector<'ctx>(
+ builder: &Builder<'ctx>,
+ intrinsics: &Intrinsics<'ctx>,
+ value: BasicValueEnum<'ctx>,
+ vec_ty: VectorType<'ctx>,
name: &str,
-) -> VectorValue {
+) -> VectorValue<'ctx> {
// Use insert_element to insert the element into an undef vector, then use
// shuffle vector to copy that lane to all lanes.
builder.build_shuffle_vector(
@@ -85,18 +107,18 @@ fn splat_vector(
// Convert floating point vector to integer and saturate when out of range.
// TODO: generalize to non-vectors using FloatMathType, IntMathType, etc. for
// https://github.com/WebAssembly/nontrapping-float-to-int-conversions/blob/master/proposals/nontrapping-float-to-int-conversion/Overview.md
-fn trunc_sat(
- builder: &Builder,
- intrinsics: &Intrinsics,
- fvec_ty: VectorType,
- ivec_ty: VectorType,
+fn trunc_sat<'ctx>(
+ builder: &Builder<'ctx>,
+ intrinsics: &Intrinsics<'ctx>,
+ fvec_ty: VectorType<'ctx>,
+ ivec_ty: VectorType<'ctx>,
lower_bound: u64, // Exclusive (lowest representable value)
upper_bound: u64, // Exclusive (greatest representable value)
int_min_value: u64,
int_max_value: u64,
- value: IntValue,
+ value: IntValue<'ctx>,
name: &str,
-) -> IntValue {
+) -> IntValue<'ctx> {
// a) Compare vector with itself to identify NaN lanes.
// b) Compare vector with splat of inttofp(upper_bound) to identify
// lanes that need to saturate to max.
@@ -204,11 +226,11 @@ fn trunc_sat(
.into_int_value()
}
-fn trap_if_not_representable_as_int(
- builder: &Builder,
- intrinsics: &Intrinsics,
- context: &Context,
- function: &FunctionValue,
+fn trap_if_not_representable_as_int<'ctx>(
+ builder: &Builder<'ctx>,
+ intrinsics: &Intrinsics<'ctx>,
+ context: &'ctx Context,
+ function: &FunctionValue<'ctx>,
lower_bound: u64, // Inclusive (not a trapping value)
upper_bound: u64, // Inclusive (not a trapping value)
value: FloatValue,
@@ -240,8 +262,8 @@ fn trap_if_not_representable_as_int(
"out_of_bounds",
);
- let failure_block = context.append_basic_block(function, "conversion_failure_block");
- let continue_block = context.append_basic_block(function, "conversion_success_block");
+ let failure_block = context.append_basic_block(*function, "conversion_failure_block");
+ let continue_block = context.append_basic_block(*function, "conversion_success_block");
builder.build_conditional_branch(out_of_bounds, &failure_block, &continue_block);
builder.position_at_end(&failure_block);
@@ -254,11 +276,11 @@ fn trap_if_not_representable_as_int(
builder.position_at_end(&continue_block);
}
-fn trap_if_zero_or_overflow(
- builder: &Builder,
- intrinsics: &Intrinsics,
- context: &Context,
- function: &FunctionValue,
+fn trap_if_zero_or_overflow<'ctx>(
+ builder: &Builder<'ctx>,
+ intrinsics: &Intrinsics<'ctx>,
+ context: &'ctx Context,
+ function: &FunctionValue<'ctx>,
left: IntValue,
right: IntValue,
) {
@@ -305,8 +327,8 @@ fn trap_if_zero_or_overflow(
.unwrap()
.into_int_value();
- let shouldnt_trap_block = context.append_basic_block(function, "shouldnt_trap_block");
- let should_trap_block = context.append_basic_block(function, "should_trap_block");
+ let shouldnt_trap_block = context.append_basic_block(*function, "shouldnt_trap_block");
+ let should_trap_block = context.append_basic_block(*function, "should_trap_block");
builder.build_conditional_branch(should_trap, &should_trap_block, &shouldnt_trap_block);
builder.position_at_end(&should_trap_block);
builder.build_call(
@@ -318,11 +340,11 @@ fn trap_if_zero_or_overflow(
builder.position_at_end(&shouldnt_trap_block);
}
-fn trap_if_zero(
- builder: &Builder,
- intrinsics: &Intrinsics,
- context: &Context,
- function: &FunctionValue,
+fn trap_if_zero<'ctx>(
+ builder: &Builder<'ctx>,
+ intrinsics: &Intrinsics<'ctx>,
+ context: &'ctx Context,
+ function: &FunctionValue<'ctx>,
value: IntValue,
) {
let int_type = value.get_type();
@@ -347,8 +369,8 @@ fn trap_if_zero(
.unwrap()
.into_int_value();
- let shouldnt_trap_block = context.append_basic_block(function, "shouldnt_trap_block");
- let should_trap_block = context.append_basic_block(function, "should_trap_block");
+ let shouldnt_trap_block = context.append_basic_block(*function, "shouldnt_trap_block");
+ let should_trap_block = context.append_basic_block(*function, "should_trap_block");
builder.build_conditional_branch(should_trap, &should_trap_block, &shouldnt_trap_block);
builder.position_at_end(&should_trap_block);
builder.build_call(
@@ -360,12 +382,161 @@ fn trap_if_zero(
builder.position_at_end(&shouldnt_trap_block);
}
+fn v128_into_int_vec<'ctx>(
+ builder: &Builder<'ctx>,
+ intrinsics: &Intrinsics<'ctx>,
+ value: BasicValueEnum<'ctx>,
+ info: ExtraInfo,
+ int_vec_ty: VectorType<'ctx>,
+) -> (VectorValue<'ctx>, ExtraInfo) {
+ let (value, info) = if info.has_pending_f32_nan() {
+ let value = builder.build_bitcast(value, intrinsics.f32x4_ty, "");
+ (
+ canonicalize_nans(builder, intrinsics, value),
+ info.strip_pending(),
+ )
+ } else if info.has_pending_f64_nan() {
+ let value = builder.build_bitcast(value, intrinsics.f64x2_ty, "");
+ (
+ canonicalize_nans(builder, intrinsics, value),
+ info.strip_pending(),
+ )
+ } else {
+ (value, info)
+ };
+ (
+ builder
+ .build_bitcast(value, int_vec_ty, "")
+ .into_vector_value(),
+ info,
+ )
+}
+
+fn v128_into_i8x16<'ctx>(
+ builder: &Builder<'ctx>,
+ intrinsics: &Intrinsics<'ctx>,
+ value: BasicValueEnum<'ctx>,
+ info: ExtraInfo,
+) -> (VectorValue<'ctx>, ExtraInfo) {
+ v128_into_int_vec(builder, intrinsics, value, info, intrinsics.i8x16_ty)
+}
+
+fn v128_into_i16x8<'ctx>(
+ builder: &Builder<'ctx>,
+ intrinsics: &Intrinsics<'ctx>,
+ value: BasicValueEnum<'ctx>,
+ info: ExtraInfo,
+) -> (VectorValue<'ctx>, ExtraInfo) {
+ v128_into_int_vec(builder, intrinsics, value, info, intrinsics.i16x8_ty)
+}
+
+fn v128_into_i32x4<'ctx>(
+ builder: &Builder<'ctx>,
+ intrinsics: &Intrinsics<'ctx>,
+ value: BasicValueEnum<'ctx>,
+ info: ExtraInfo,
+) -> (VectorValue<'ctx>, ExtraInfo) {
+ v128_into_int_vec(builder, intrinsics, value, info, intrinsics.i32x4_ty)
+}
+
+fn v128_into_i64x2<'ctx>(
+ builder: &Builder<'ctx>,
+ intrinsics: &Intrinsics<'ctx>,
+ value: BasicValueEnum<'ctx>,
+ info: ExtraInfo,
+) -> (VectorValue<'ctx>, ExtraInfo) {
+ v128_into_int_vec(builder, intrinsics, value, info, intrinsics.i64x2_ty)
+}
+
+// If the value is pending a 64-bit canonicalization, do it now.
+// Return a f32x4 vector.
+fn v128_into_f32x4<'ctx>(
+ builder: &Builder<'ctx>,
+ intrinsics: &Intrinsics<'ctx>,
+ value: BasicValueEnum<'ctx>,
+ info: ExtraInfo,
+) -> (VectorValue<'ctx>, ExtraInfo) {
+ let (value, info) = if info.has_pending_f64_nan() {
+ let value = builder.build_bitcast(value, intrinsics.f64x2_ty, "");
+ (
+ canonicalize_nans(builder, intrinsics, value),
+ info.strip_pending(),
+ )
+ } else {
+ (value, info)
+ };
+ (
+ builder
+ .build_bitcast(value, intrinsics.f32x4_ty, "")
+ .into_vector_value(),
+ info,
+ )
+}
+
+// If the value is pending a 32-bit canonicalization, do it now.
+// Return a f64x2 vector.
+fn v128_into_f64x2<'ctx>(
+ builder: &Builder<'ctx>,
+ intrinsics: &Intrinsics<'ctx>,
+ value: BasicValueEnum<'ctx>,
+ info: ExtraInfo,
+) -> (VectorValue<'ctx>, ExtraInfo) {
+ let (value, info) = if info.has_pending_f32_nan() {
+ let value = builder.build_bitcast(value, intrinsics.f32x4_ty, "");
+ (
+ canonicalize_nans(builder, intrinsics, value),
+ info.strip_pending(),
+ )
+ } else {
+ (value, info)
+ };
+ (
+ builder
+ .build_bitcast(value, intrinsics.f64x2_ty, "")
+ .into_vector_value(),
+ info,
+ )
+}
+
+fn apply_pending_canonicalization<'ctx>(
+ builder: &Builder<'ctx>,
+ intrinsics: &Intrinsics<'ctx>,
+ value: BasicValueEnum<'ctx>,
+ info: ExtraInfo,
+) -> BasicValueEnum<'ctx> {
+ if info.has_pending_f32_nan() {
+ if value.get_type().is_vector_type()
+ || value.get_type() == intrinsics.i128_ty.as_basic_type_enum()
+ {
+ let ty = value.get_type();
+ let value = builder.build_bitcast(value, intrinsics.f32x4_ty, "");
+ let value = canonicalize_nans(builder, intrinsics, value);
+ builder.build_bitcast(value, ty, "")
+ } else {
+ canonicalize_nans(builder, intrinsics, value)
+ }
+ } else if info.has_pending_f64_nan() {
+ if value.get_type().is_vector_type()
+ || value.get_type() == intrinsics.i128_ty.as_basic_type_enum()
+ {
+ let ty = value.get_type();
+ let value = builder.build_bitcast(value, intrinsics.f64x2_ty, "");
+ let value = canonicalize_nans(builder, intrinsics, value);
+ builder.build_bitcast(value, ty, "")
+ } else {
+ canonicalize_nans(builder, intrinsics, value)
+ }
+ } else {
+ value
+ }
+}
+
// Replaces any NaN with the canonical QNaN, otherwise leaves the value alone.
-fn canonicalize_nans(
- builder: &Builder,
- intrinsics: &Intrinsics,
- value: BasicValueEnum,
-) -> BasicValueEnum {
+fn canonicalize_nans<'ctx>(
+ builder: &Builder<'ctx>,
+ intrinsics: &Intrinsics<'ctx>,
+ value: BasicValueEnum<'ctx>,
+) -> BasicValueEnum<'ctx> {
let f_ty = value.get_type();
let canonicalized = if f_ty.is_vector_type() {
let value = value.into_vector_value();
@@ -399,62 +570,110 @@ fn canonicalize_nans(
canonicalized
}
-fn resolve_memory_ptr(
- builder: &Builder,
- intrinsics: &Intrinsics,
- context: &Context,
- function: &FunctionValue,
- state: &mut State,
- ctx: &mut CtxType,
+fn resolve_memory_ptr<'ctx>(
+ builder: &Builder<'ctx>,
+ intrinsics: &Intrinsics<'ctx>,
+ context: &'ctx Context,
+ module: Rc>>,
+ function: &FunctionValue<'ctx>,
+ state: &mut State<'ctx>,
+ ctx: &mut CtxType<'static, 'ctx>,
memarg: &MemoryImmediate,
- ptr_ty: PointerType,
+ ptr_ty: PointerType<'ctx>,
value_size: usize,
-) -> Result {
- // Ignore alignment hint for the time being.
- let imm_offset = intrinsics.i64_ty.const_int(memarg.offset as u64, false);
- let value_size_v = intrinsics.i64_ty.const_int(value_size as u64, false);
- let var_offset_i32 = state.pop1()?.into_int_value();
- let var_offset =
- builder.build_int_z_extend(var_offset_i32, intrinsics.i64_ty, &state.var_name());
- let effective_offset = builder.build_int_add(var_offset, imm_offset, &state.var_name());
- let end_offset = builder.build_int_add(effective_offset, value_size_v, &state.var_name());
- let memory_cache = ctx.memory(MemoryIndex::new(0), intrinsics);
-
- let mem_base_int = match memory_cache {
+) -> Result, BinaryReaderError> {
+ // Look up the memory base (as pointer) and bounds (as unsigned integer).
+ let memory_cache = ctx.memory(MemoryIndex::new(0), intrinsics, module.clone());
+ let (mem_base, mem_bound, minimum, _maximum) = match memory_cache {
MemoryCache::Dynamic {
ptr_to_base_ptr,
ptr_to_bounds,
+ minimum,
+ maximum,
} => {
let base = builder
.build_load(ptr_to_base_ptr, "base")
.into_pointer_value();
let bounds = builder.build_load(ptr_to_bounds, "bounds").into_int_value();
+ tbaa_label(
+ &module,
+ intrinsics,
+ "dynamic_memory_base",
+ base.as_instruction_value().unwrap(),
+ Some(0),
+ );
+ tbaa_label(
+ &module,
+ intrinsics,
+ "dynamic_memory_bounds",
+ bounds.as_instruction_value().unwrap(),
+ Some(0),
+ );
+ (base, bounds, minimum, maximum)
+ }
+ MemoryCache::Static {
+ base_ptr,
+ bounds,
+ minimum,
+ maximum,
+ } => (base_ptr, bounds, minimum, maximum),
+ };
+ let mem_base = builder
+ .build_bitcast(mem_base, intrinsics.i8_ptr_ty, &state.var_name())
+ .into_pointer_value();
- let base_as_int = builder.build_ptr_to_int(base, intrinsics.i64_ty, "base_as_int");
+ // Compute the offset over the memory_base.
+ let imm_offset = intrinsics.i64_ty.const_int(memarg.offset as u64, false);
+ let var_offset_i32 = state.pop1()?.into_int_value();
+ let var_offset =
+ builder.build_int_z_extend(var_offset_i32, intrinsics.i64_ty, &state.var_name());
+ let effective_offset = builder.build_int_add(var_offset, imm_offset, &state.var_name());
- let base_in_bounds_1 = builder.build_int_compare(
+ if let MemoryCache::Dynamic { .. } = memory_cache {
+ // If the memory is dynamic, do a bounds check. For static we rely on
+ // the size being a multiple of the page size and hitting a guard page.
+ let value_size_v = intrinsics.i64_ty.const_int(value_size as u64, false);
+ let ptr_in_bounds = if effective_offset.is_const() {
+ let load_offset_end = effective_offset.const_add(value_size_v);
+ let ptr_in_bounds = load_offset_end.const_int_compare(
IntPredicate::ULE,
- end_offset,
- bounds,
- "base_in_bounds_1",
+ intrinsics.i64_ty.const_int(minimum.bytes().0 as u64, false),
);
- let base_in_bounds_2 = builder.build_int_compare(
- IntPredicate::ULT,
- effective_offset,
- end_offset,
- "base_in_bounds_2",
- );
- let base_in_bounds =
- builder.build_and(base_in_bounds_1, base_in_bounds_2, "base_in_bounds");
+ if ptr_in_bounds.get_zero_extended_constant() == Some(1) {
+ Some(ptr_in_bounds)
+ } else {
+ None
+ }
+ } else {
+ None
+ }
+ .unwrap_or_else(|| {
+ let load_offset_end =
+ builder.build_int_add(effective_offset, value_size_v, &state.var_name());
- let base_in_bounds = builder
+ builder.build_int_compare(
+ IntPredicate::ULE,
+ load_offset_end,
+ mem_bound,
+ &state.var_name(),
+ )
+ });
+ if !ptr_in_bounds.is_constant_int()
+ || ptr_in_bounds.get_zero_extended_constant().unwrap() != 1
+ {
+ // LLVM may have folded this into 'i1 true' in which case we know
+ // the pointer is in bounds. LLVM may also have folded it into a
+ // constant expression, not known to be either true or false yet.
+ // If it's false, unknown-but-constant, or not-a-constant, emit a
+ // runtime bounds check. LLVM may yet succeed at optimizing it away.
+ let ptr_in_bounds = builder
.build_call(
intrinsics.expect_i1,
&[
- base_in_bounds.as_basic_value_enum(),
+ ptr_in_bounds.as_basic_value_enum(),
intrinsics.i1_ty.const_int(1, false).as_basic_value_enum(),
],
- "base_in_bounds_expect",
+ "ptr_in_bounds_expect",
)
.try_as_basic_value()
.left()
@@ -462,10 +681,10 @@ fn resolve_memory_ptr(
.into_int_value();
let in_bounds_continue_block =
- context.append_basic_block(function, "in_bounds_continue_block");
- let not_in_bounds_block = context.append_basic_block(function, "not_in_bounds_block");
+ context.append_basic_block(*function, "in_bounds_continue_block");
+ let not_in_bounds_block = context.append_basic_block(*function, "not_in_bounds_block");
builder.build_conditional_branch(
- base_in_bounds,
+ ptr_in_bounds,
&in_bounds_continue_block,
¬_in_bounds_block,
);
@@ -477,27 +696,106 @@ fn resolve_memory_ptr(
);
builder.build_unreachable();
builder.position_at_end(&in_bounds_continue_block);
-
- base_as_int
}
- MemoryCache::Static {
- base_ptr,
- bounds: _,
- } => builder.build_ptr_to_int(base_ptr, intrinsics.i64_ty, "base_as_int"),
- };
+ }
- let effective_address_int =
- builder.build_int_add(mem_base_int, effective_offset, &state.var_name());
- Ok(builder.build_int_to_ptr(effective_address_int, ptr_ty, &state.var_name()))
+ let ptr = unsafe { builder.build_gep(mem_base, &[effective_offset], &state.var_name()) };
+ Ok(builder
+ .build_bitcast(ptr, ptr_ty, &state.var_name())
+ .into_pointer_value())
}
-fn trap_if_misaligned(
- builder: &Builder,
- intrinsics: &Intrinsics,
- context: &Context,
- function: &FunctionValue,
+fn emit_stack_map<'ctx>(
+ _module_info: &ModuleInfo,
+ intrinsics: &Intrinsics<'ctx>,
+ builder: &Builder<'ctx>,
+ local_function_id: usize,
+ target: &mut StackmapRegistry,
+ kind: StackmapEntryKind,
+ locals: &[PointerValue],
+ state: &State<'ctx>,
+ _ctx: &mut CtxType<'_, 'ctx>,
+ opcode_offset: usize,
+) {
+ let stackmap_id = target.entries.len();
+
+ let mut params = Vec::with_capacity(2 + locals.len() + state.stack.len());
+
+ params.push(
+ intrinsics
+ .i64_ty
+ .const_int(stackmap_id as u64, false)
+ .as_basic_value_enum(),
+ );
+ params.push(intrinsics.i32_ty.const_int(0, false).as_basic_value_enum());
+
+ let locals: Vec<_> = locals.iter().map(|x| x.as_basic_value_enum()).collect();
+ let mut value_semantics: Vec =
+ Vec::with_capacity(locals.len() + state.stack.len());
+
+ params.extend_from_slice(&locals);
+ value_semantics.extend((0..locals.len()).map(ValueSemantic::WasmLocal));
+
+ params.extend(state.stack.iter().map(|x| x.0));
+ value_semantics.extend((0..state.stack.len()).map(ValueSemantic::WasmStack));
+
+ // FIXME: Information needed for Abstract -> Runtime state transform is not fully preserved
+ // to accelerate compilation and reduce memory usage. Check this again when we try to support
+ // "full" LLVM OSR.
+
+ assert_eq!(params.len(), value_semantics.len() + 2);
+
+ builder.build_call(intrinsics.experimental_stackmap, ¶ms, &state.var_name());
+
+ target.entries.push(StackmapEntry {
+ kind,
+ local_function_id,
+ local_count: locals.len(),
+ stack_count: state.stack.len(),
+ opcode_offset,
+ value_semantics,
+ is_start: true,
+ });
+}
+
+fn finalize_opcode_stack_map<'ctx>(
+ intrinsics: &Intrinsics<'ctx>,
+ builder: &Builder<'ctx>,
+ local_function_id: usize,
+ target: &mut StackmapRegistry,
+ kind: StackmapEntryKind,
+ opcode_offset: usize,
+) {
+ let stackmap_id = target.entries.len();
+ builder.build_call(
+ intrinsics.experimental_stackmap,
+ &[
+ intrinsics
+ .i64_ty
+ .const_int(stackmap_id as u64, false)
+ .as_basic_value_enum(),
+ intrinsics.i32_ty.const_int(0, false).as_basic_value_enum(),
+ ],
+ "opcode_stack_map_end",
+ );
+ target.entries.push(StackmapEntry {
+ kind,
+ local_function_id,
+ local_count: 0,
+ stack_count: 0,
+ opcode_offset,
+ value_semantics: vec![],
+ is_start: false,
+ });
+}
+
+fn trap_if_misaligned<'ctx>(
+ builder: &Builder<'ctx>,
+ intrinsics: &Intrinsics<'ctx>,
+ context: &'ctx Context,
+ function: &FunctionValue<'ctx>,
memarg: &MemoryImmediate,
- ptr: PointerValue,
+ ptr: PointerValue<'ctx>,
) {
let align = match memarg.flags & 3 {
0 => {
@@ -529,8 +827,8 @@ fn trap_if_misaligned(
.unwrap()
.into_int_value();
- let continue_block = context.append_basic_block(function, "aligned_access_continue_block");
- let not_aligned_block = context.append_basic_block(function, "misaligned_trap_block");
+ let continue_block = context.append_basic_block(*function, "aligned_access_continue_block");
+ let not_aligned_block = context.append_basic_block(*function, "misaligned_trap_block");
builder.build_conditional_branch(aligned, &continue_block, ¬_aligned_block);
builder.position_at_end(¬_aligned_block);
@@ -564,34 +862,45 @@ pub unsafe extern "C" fn callback_trampoline(
}
}
-pub struct LLVMModuleCodeGenerator {
- context: Option,
- builder: Option,
- intrinsics: Option,
- functions: Vec,
- signatures: Map,
+pub struct LLVMModuleCodeGenerator<'ctx> {
+ context: Option<&'ctx Context>,
+ builder: Option>,
+ intrinsics: Option>,
+ functions: Vec>,
+ signatures: Map>,
signatures_raw: Map,
function_signatures: Option>>,
+ llvm_functions: Rc>>>,
func_import_count: usize,
- personality_func: FunctionValue,
- module: Module,
+ personality_func: ManuallyDrop>,
+ module: ManuallyDrop>>>,
+ stackmaps: Rc>,
+ track_state: bool,
+ target_machine: TargetMachine,
}
-pub struct LLVMFunctionCodeGenerator {
- context: Option,
- builder: Option,
- intrinsics: Option,
- state: State,
- function: FunctionValue,
+pub struct LLVMFunctionCodeGenerator<'ctx> {
+ context: Option<&'ctx Context>,
+ builder: Option>,
+ alloca_builder: Option>,
+ intrinsics: Option>,
+ state: State<'ctx>,
+ llvm_functions: Rc>>>,
+ function: FunctionValue<'ctx>,
func_sig: FuncSig,
- signatures: Map,
- locals: Vec, // Contains params and locals
+ signatures: Map>,
+ locals: Vec>, // Contains params and locals
num_params: usize,
- ctx: Option>,
+ ctx: Option>,
unreachable_depth: usize,
+ stackmaps: Rc>,
+ index: usize,
+ opcode_offset: usize,
+ track_state: bool,
+ module: Rc>>,
}
-impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
+impl<'ctx> FunctionCodeGenerator for LLVMFunctionCodeGenerator<'ctx> {
fn feed_return(&mut self, _ty: WpType) -> Result<(), CodegenError> {
Ok(())
}
@@ -600,12 +909,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
Ok(())
}
- fn feed_local(&mut self, ty: WpType, n: usize) -> Result<(), CodegenError> {
+ fn feed_local(&mut self, ty: WpType, count: usize) -> Result<(), CodegenError> {
let param_len = self.num_params;
- let mut local_idx = 0;
- // let (count, ty) = local?;
- let count = n;
let wasmer_ty = type_to_type(ty)?;
let intrinsics = self.intrinsics.as_ref().unwrap();
@@ -620,14 +926,22 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
};
let builder = self.builder.as_ref().unwrap();
+ let alloca_builder = self.alloca_builder.as_ref().unwrap();
- for _ in 0..count {
- let alloca = builder.build_alloca(ty, &format!("local{}", param_len + local_idx));
-
+ for local_idx in 0..count {
+ let alloca =
+ alloca_builder.build_alloca(ty, &format!("local{}", param_len + local_idx));
builder.build_store(alloca, default_value);
-
+ if local_idx == 0 {
+ alloca_builder.position_before(
+ &alloca
+ .as_instruction()
+ .unwrap()
+ .get_next_instruction()
+ .unwrap(),
+ );
+ }
self.locals.push(alloca);
- local_idx += 1;
}
Ok(())
}
@@ -637,7 +951,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
.context
.as_ref()
.unwrap()
- .append_basic_block(&self.function, "start_of_code");
+ .append_basic_block(self.function, "start_of_code");
let entry_end_inst = self
.builder
.as_ref()
@@ -652,12 +966,40 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
cache_builder.position_before(&entry_end_inst);
let module_info =
unsafe { ::std::mem::transmute::<&ModuleInfo, &'static ModuleInfo>(module_info) };
- let function = unsafe {
- ::std::mem::transmute::<&FunctionValue, &'static FunctionValue>(&self.function)
- };
- let ctx = CtxType::new(module_info, function, cache_builder);
+ let ctx = CtxType::new(module_info, &self.function, cache_builder);
self.ctx = Some(ctx);
+
+ {
+ let state = &mut self.state;
+ let builder = self.builder.as_ref().unwrap();
+ let intrinsics = self.intrinsics.as_ref().unwrap();
+
+ if self.track_state {
+ let mut stackmaps = self.stackmaps.borrow_mut();
+ emit_stack_map(
+ &module_info,
+ &intrinsics,
+ &builder,
+ self.index,
+ &mut *stackmaps,
+ StackmapEntryKind::FunctionHeader,
+ &self.locals,
+ &state,
+ self.ctx.as_mut().unwrap(),
+ ::std::usize::MAX,
+ );
+ finalize_opcode_stack_map(
+ &intrinsics,
+ &builder,
+ self.index,
+ &mut *stackmaps,
+ StackmapEntryKind::FunctionHeader,
+ ::std::usize::MAX,
+ );
+ }
+ }
+
Ok(())
}
@@ -672,9 +1014,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
let signatures = &self.signatures;
let mut ctx = self.ctx.as_mut().unwrap();
+ let mut opcode_offset: Option = None;
let op = match event {
- Event::Wasm(x) => x,
- Event::WasmOwned(ref x) => x,
+ Event::Wasm(x) => {
+ opcode_offset = Some(self.opcode_offset);
+ self.opcode_offset += 1;
+ x
+ }
Event::Internal(x) => {
match x {
InternalEvent::FunctionBegin(_) | InternalEvent::FunctionEnd => {
@@ -693,22 +1039,39 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
InternalEvent::GetInternal(idx) => {
if state.reachable {
let idx = idx as usize;
- let field_ptr = ctx.internal_field(idx, intrinsics, builder);
+ let field_ptr =
+ ctx.internal_field(idx, intrinsics, self.module.clone(), builder);
let result = builder.build_load(field_ptr, "get_internal");
+ tbaa_label(
+ &self.module,
+ intrinsics,
+ "internal",
+ result.as_instruction_value().unwrap(),
+ Some(idx as u32),
+ );
state.push1(result);
}
}
InternalEvent::SetInternal(idx) => {
if state.reachable {
let idx = idx as usize;
- let field_ptr = ctx.internal_field(idx, intrinsics, builder);
+ let field_ptr =
+ ctx.internal_field(idx, intrinsics, self.module.clone(), builder);
let v = state.pop1()?;
- builder.build_store(field_ptr, v);
+ let store = builder.build_store(field_ptr, v);
+ tbaa_label(
+ &self.module,
+ intrinsics,
+ "internal",
+ store,
+ Some(idx as u32),
+ );
}
}
}
return Ok(());
}
+ Event::WasmOwned(ref x) => x,
};
if !state.reachable {
@@ -745,7 +1108,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
offset: -1isize as usize,
})?;
- let end_block = context.append_basic_block(&function, "end");
+ let end_block = context.append_basic_block(function, "end");
builder.position_at_end(&end_block);
let phis = if let Ok(wasmer_ty) = blocktype_to_type(ty) {
@@ -762,8 +1125,8 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
builder.position_at_end(¤t_block);
}
Operator::Loop { ty } => {
- let loop_body = context.append_basic_block(&function, "loop_body");
- let loop_next = context.append_basic_block(&function, "loop_outer");
+ let loop_body = context.append_basic_block(function, "loop_body");
+ let loop_next = context.append_basic_block(function, "loop_outer");
builder.build_unconditional_branch(&loop_body);
@@ -779,6 +1142,38 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
};
builder.position_at_end(&loop_body);
+
+ if self.track_state {
+ if let Some(offset) = opcode_offset {
+ let mut stackmaps = self.stackmaps.borrow_mut();
+ emit_stack_map(
+ &info,
+ intrinsics,
+ builder,
+ self.index,
+ &mut *stackmaps,
+ StackmapEntryKind::Loop,
+ &self.locals,
+ state,
+ ctx,
+ offset,
+ );
+ let signal_mem = ctx.signal_mem();
+ let iv = builder
+ .build_store(signal_mem, context.i8_type().const_int(0 as u64, false));
+ // Any 'store' can be made volatile.
+ iv.set_volatile(true).unwrap();
+ finalize_opcode_stack_map(
+ intrinsics,
+ builder,
+ self.index,
+ &mut *stackmaps,
+ StackmapEntryKind::Loop,
+ offset,
+ );
+ }
+ }
+
state.push_loop(loop_body, loop_next, phis);
}
Operator::Br { relative_depth } => {
@@ -795,13 +1190,16 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
frame.phis().len()
};
- let values = state.peekn(value_len)?;
+ let values = state.peekn_extra(value_len)?;
+ let values = values.iter().map(|(v, info)| {
+ apply_pending_canonicalization(builder, intrinsics, *v, *info)
+ });
// For each result of the block we're branching to,
// pop a value off the value stack and load it into
// the corresponding phi.
- for (phi, value) in frame.phis().iter().zip(values.iter()) {
- phi.add_incoming(&[(value, ¤t_block)]);
+ for (phi, value) in frame.phis().iter().zip(values) {
+ phi.add_incoming(&[(&value, ¤t_block)]);
}
builder.build_unconditional_branch(frame.br_dest());
@@ -824,13 +1222,16 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
frame.phis().len()
};
- let param_stack = state.peekn(value_len)?;
+ let param_stack = state.peekn_extra(value_len)?;
+ let param_stack = param_stack.iter().map(|(v, info)| {
+ apply_pending_canonicalization(builder, intrinsics, *v, *info)
+ });
- for (phi, value) in frame.phis().iter().zip(param_stack.iter()) {
- phi.add_incoming(&[(value, ¤t_block)]);
+ for (phi, value) in frame.phis().iter().zip(param_stack) {
+ phi.add_incoming(&[(&value, ¤t_block)]);
}
- let else_block = context.append_basic_block(&function, "else");
+ let else_block = context.append_basic_block(function, "else");
let cond_value = builder.build_int_compare(
IntPredicate::NE,
@@ -854,7 +1255,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
let default_frame = state.frame_at_depth(default_depth)?;
let args = if default_frame.is_loop() {
- &[]
+ Vec::new()
} else {
let res_len = default_frame.phis().len();
state.peekn(res_len)?
@@ -896,9 +1297,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
message: "not currently in a block",
offset: -1isize as usize,
})?;
- let if_then_block = context.append_basic_block(&function, "if_then");
- let if_else_block = context.append_basic_block(&function, "if_else");
- let end_block = context.append_basic_block(&function, "if_end");
+ let if_then_block = context.append_basic_block(function, "if_then");
+ let if_else_block = context.append_basic_block(function, "if_else");
+ let end_block = context.append_basic_block(function, "if_end");
let end_phis = {
builder.position_at_end(&end_block);
@@ -933,16 +1334,19 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
Operator::Else => {
if state.reachable {
let frame = state.frame_at_depth(0)?;
- builder.build_unconditional_branch(frame.code_after());
let current_block = builder.get_insert_block().ok_or(BinaryReaderError {
message: "not currently in a block",
offset: -1isize as usize,
})?;
for phi in frame.phis().to_vec().iter().rev() {
- let value = state.pop1()?;
+ let (value, info) = state.pop1_extra()?;
+ let value =
+ apply_pending_canonicalization(builder, intrinsics, value, info);
phi.add_incoming(&[(&value, ¤t_block)])
}
+ let frame = state.frame_at_depth(0)?;
+ builder.build_unconditional_branch(frame.code_after());
}
let (if_else_block, if_else_state) = if let ControlFrame::IfElse {
@@ -970,12 +1374,14 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
})?;
if state.reachable {
- builder.build_unconditional_branch(frame.code_after());
-
for phi in frame.phis().iter().rev() {
- let value = state.pop1()?;
+ let (value, info) = state.pop1_extra()?;
+ let value =
+ apply_pending_canonicalization(builder, intrinsics, value, info);
phi.add_incoming(&[(&value, ¤t_block)]);
}
+
+ builder.build_unconditional_branch(frame.code_after());
}
if let ControlFrame::IfElse {
@@ -1009,7 +1415,11 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
BasicTypeEnum::FloatType(float_ty) => {
float_ty.const_float(0.0).as_basic_value_enum()
}
- _ => unimplemented!(),
+ _ => {
+ return Err(CodegenError {
+ message: "Operator::End phi type unimplemented".to_string(),
+ });
+ }
};
state.push1(placeholder_value);
phi.as_instruction().erase_from_basic_block();
@@ -1017,29 +1427,58 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
}
}
Operator::Return => {
- let frame = state.outermost_frame()?;
let current_block = builder.get_insert_block().ok_or(BinaryReaderError {
message: "not currently in a block",
offset: -1isize as usize,
})?;
- builder.build_unconditional_branch(frame.br_dest());
-
- let phis = frame.phis().to_vec();
-
- for phi in phis.iter() {
- let arg = state.pop1()?;
+ let frame = state.outermost_frame()?;
+ for phi in frame.phis().to_vec().iter() {
+ let (arg, info) = state.pop1_extra()?;
+ let arg = apply_pending_canonicalization(builder, intrinsics, arg, info);
phi.add_incoming(&[(&arg, ¤t_block)]);
}
+ let frame = state.outermost_frame()?;
+ builder.build_unconditional_branch(frame.br_dest());
+
state.reachable = false;
}
Operator::Unreachable => {
// Emit an unreachable instruction.
- // If llvm cannot prove that this is never touched,
+ // If llvm cannot prove that this is never reached,
// it will emit a `ud2` instruction on x86_64 arches.
+ // Comment out this `if` block to allow spectests to pass.
+ // TODO: fix this
+ if let Some(offset) = opcode_offset {
+ if self.track_state {
+ let mut stackmaps = self.stackmaps.borrow_mut();
+ emit_stack_map(
+ &info,
+ intrinsics,
+ builder,
+ self.index,
+ &mut *stackmaps,
+ StackmapEntryKind::Trappable,
+ &self.locals,
+ state,
+ ctx,
+ offset,
+ );
+ builder.build_call(intrinsics.trap, &[], "trap");
+ finalize_opcode_stack_map(
+ intrinsics,
+ builder,
+ self.index,
+ &mut *stackmaps,
+ StackmapEntryKind::Trappable,
+ offset,
+ );
+ }
+ }
+
builder.build_call(
intrinsics.throw_trap,
&[intrinsics.trap_unreachable],
@@ -1064,21 +1503,41 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
// Generate const values.
Operator::I32Const { value } => {
let i = intrinsics.i32_ty.const_int(value as u64, false);
- state.push1(i);
+ let info = if is_f32_arithmetic(value as u32) {
+ ExtraInfo::arithmetic_f32()
+ } else {
+ Default::default()
+ };
+ state.push1_extra(i, info);
}
Operator::I64Const { value } => {
let i = intrinsics.i64_ty.const_int(value as u64, false);
- state.push1(i);
+ let info = if is_f64_arithmetic(value as u64) {
+ ExtraInfo::arithmetic_f64()
+ } else {
+ Default::default()
+ };
+ state.push1_extra(i, info);
}
Operator::F32Const { value } => {
let bits = intrinsics.i32_ty.const_int(value.bits() as u64, false);
+ let info = if is_f32_arithmetic(value.bits()) {
+ ExtraInfo::arithmetic_f32()
+ } else {
+ Default::default()
+ };
let f = builder.build_bitcast(bits, intrinsics.f32_ty, "f");
- state.push1(f);
+ state.push1_extra(f, info);
}
Operator::F64Const { value } => {
let bits = intrinsics.i64_ty.const_int(value.bits(), false);
+ let info = if is_f64_arithmetic(value.bits()) {
+ ExtraInfo::arithmetic_f64()
+ } else {
+ Default::default()
+ };
let f = builder.build_bitcast(bits, intrinsics.f64_ty, "f");
- state.push1(f);
+ state.push1_extra(f, info);
}
Operator::V128Const { value } => {
let mut hi: [u8; 8] = Default::default();
@@ -1087,11 +1546,31 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
lo.copy_from_slice(&value.bytes()[8..16]);
let packed = [u64::from_le_bytes(hi), u64::from_le_bytes(lo)];
let i = intrinsics.i128_ty.const_int_arbitrary_precision(&packed);
- state.push1(i);
+ let mut quad1: [u8; 4] = Default::default();
+ let mut quad2: [u8; 4] = Default::default();
+ let mut quad3: [u8; 4] = Default::default();
+ let mut quad4: [u8; 4] = Default::default();
+ quad1.copy_from_slice(&value.bytes()[0..4]);
+ quad2.copy_from_slice(&value.bytes()[4..8]);
+ quad3.copy_from_slice(&value.bytes()[8..12]);
+ quad4.copy_from_slice(&value.bytes()[12..16]);
+ let mut info: ExtraInfo = Default::default();
+ if is_f32_arithmetic(u32::from_le_bytes(quad1))
+ && is_f32_arithmetic(u32::from_le_bytes(quad2))
+ && is_f32_arithmetic(u32::from_le_bytes(quad3))
+ && is_f32_arithmetic(u32::from_le_bytes(quad4))
+ {
+ info |= ExtraInfo::arithmetic_f32();
+ }
+ if is_f64_arithmetic(packed[0]) && is_f64_arithmetic(packed[1]) {
+ info |= ExtraInfo::arithmetic_f64();
+ }
+ state.push1_extra(i, info);
}
Operator::I8x16Splat => {
- let v = state.pop1()?.into_int_value();
+ let (v, i) = state.pop1_extra()?;
+ let v = v.into_int_value();
let v = builder.build_int_truncate(v, intrinsics.i8_ty, "");
let res = splat_vector(
builder,
@@ -1101,10 +1580,11 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
&state.var_name(),
);
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ state.push1_extra(res, i);
}
Operator::I16x8Splat => {
- let v = state.pop1()?.into_int_value();
+ let (v, i) = state.pop1_extra()?;
+ let v = v.into_int_value();
let v = builder.build_int_truncate(v, intrinsics.i16_ty, "");
let res = splat_vector(
builder,
@@ -1114,10 +1594,10 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
&state.var_name(),
);
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ state.push1_extra(res, i);
}
Operator::I32x4Splat => {
- let v = state.pop1()?;
+ let (v, i) = state.pop1_extra()?;
let res = splat_vector(
builder,
intrinsics,
@@ -1126,10 +1606,10 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
&state.var_name(),
);
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ state.push1_extra(res, i);
}
Operator::I64x2Splat => {
- let v = state.pop1()?;
+ let (v, i) = state.pop1_extra()?;
let res = splat_vector(
builder,
intrinsics,
@@ -1138,10 +1618,10 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
&state.var_name(),
);
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ state.push1_extra(res, i);
}
Operator::F32x4Splat => {
- let v = state.pop1()?;
+ let (v, i) = state.pop1_extra()?;
let res = splat_vector(
builder,
intrinsics,
@@ -1150,10 +1630,12 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
&state.var_name(),
);
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ // The spec is unclear, we interpret splat as preserving NaN
+ // payload bits.
+ state.push1_extra(res, i);
}
Operator::F64x2Splat => {
- let v = state.pop1()?;
+ let (v, i) = state.pop1_extra()?;
let res = splat_vector(
builder,
intrinsics,
@@ -1162,46 +1644,74 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
&state.var_name(),
);
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ // The spec is unclear, we interpret splat as preserving NaN
+ // payload bits.
+ state.push1_extra(res, i);
}
// Operate on locals.
Operator::GetLocal { local_index } => {
let pointer_value = locals[local_index as usize];
let v = builder.build_load(pointer_value, &state.var_name());
+ tbaa_label(
+ &self.module,
+ intrinsics,
+ "local",
+ v.as_instruction_value().unwrap(),
+ Some(local_index),
+ );
state.push1(v);
}
Operator::SetLocal { local_index } => {
let pointer_value = locals[local_index as usize];
- let v = state.pop1()?;
- builder.build_store(pointer_value, v);
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
+ let store = builder.build_store(pointer_value, v);
+ tbaa_label(&self.module, intrinsics, "local", store, Some(local_index));
}
Operator::TeeLocal { local_index } => {
let pointer_value = locals[local_index as usize];
- let v = state.peek1()?;
- builder.build_store(pointer_value, v);
+ let (v, i) = state.peek1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
+ let store = builder.build_store(pointer_value, v);
+ tbaa_label(&self.module, intrinsics, "local", store, Some(local_index));
}
Operator::GetGlobal { global_index } => {
let index = GlobalIndex::new(global_index as usize);
- let global_cache = ctx.global_cache(index, intrinsics);
+ let global_cache = ctx.global_cache(index, intrinsics, self.module.clone());
match global_cache {
GlobalCache::Const { value } => {
state.push1(value);
}
GlobalCache::Mut { ptr_to_value } => {
let value = builder.build_load(ptr_to_value, "global_value");
+ tbaa_label(
+ &self.module,
+ intrinsics,
+ "global",
+ value.as_instruction_value().unwrap(),
+ Some(global_index),
+ );
state.push1(value);
}
}
}
Operator::SetGlobal { global_index } => {
- let value = state.pop1()?;
+ let (value, info) = state.pop1_extra()?;
+ let value = apply_pending_canonicalization(builder, intrinsics, value, info);
let index = GlobalIndex::new(global_index as usize);
- let global_cache = ctx.global_cache(index, intrinsics);
+ let global_cache = ctx.global_cache(index, intrinsics, self.module.clone());
match global_cache {
GlobalCache::Mut { ptr_to_value } => {
- builder.build_store(ptr_to_value, value);
+ let store = builder.build_store(ptr_to_value, value);
+ tbaa_label(
+ &self.module,
+ intrinsics,
+ "global",
+ store,
+ Some(global_index),
+ );
}
GlobalCache::Const { value: _ } => {
return Err(CodegenError {
@@ -1212,7 +1722,26 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
}
Operator::Select => {
- let (v1, v2, cond) = state.pop3()?;
+ let ((v1, i1), (v2, i2), (cond, _)) = state.pop3_extra()?;
+ // We don't bother canonicalizing 'cond' here because we only
+ // compare it to zero, and that's invariant under
+ // canonicalization.
+
+ // If the pending bits of v1 and v2 are the same, we can pass
+ // them along to the result. Otherwise, apply pending
+ // canonicalizations now.
+ let (v1, i1, v2, i2) = if i1.has_pending_f32_nan() != i2.has_pending_f32_nan()
+ || i1.has_pending_f64_nan() != i2.has_pending_f64_nan()
+ {
+ (
+ apply_pending_canonicalization(builder, intrinsics, v1, i1),
+ i1.strip_pending(),
+ apply_pending_canonicalization(builder, intrinsics, v2, i2),
+ i2.strip_pending(),
+ )
+ } else {
+ (v1, i1, v2, i2)
+ };
let cond_value = builder.build_int_compare(
IntPredicate::NE,
cond.into_int_value(),
@@ -1220,7 +1749,19 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
&state.var_name(),
);
let res = builder.build_select(cond_value, v1, v2, &state.var_name());
- state.push1(res);
+ let info = {
+ let mut info = i1.strip_pending() & i2.strip_pending();
+ if i1.has_pending_f32_nan() {
+ debug_assert!(i2.has_pending_f32_nan());
+ info |= ExtraInfo::pending_f32_nan();
+ }
+ if i1.has_pending_f64_nan() {
+ debug_assert!(i2.has_pending_f64_nan());
+ info |= ExtraInfo::pending_f64_nan();
+ }
+ info
+ };
+ state.push1_extra(res, info);
}
Operator::Call { function_index } => {
let func_index = FuncIndex::new(function_index as usize);
@@ -1228,45 +1769,129 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
let llvm_sig = signatures[sigindex];
let func_sig = &info.signatures[sigindex];
- let call_site = match func_index.local_or_import(info) {
- LocalOrImport::Local(local_func_index) => {
- let params: Vec<_> = [ctx.basic()]
- .iter()
- .chain(state.peekn(func_sig.params().len())?.iter())
- .map(|v| *v)
+ let (params, func_ptr) = match func_index.local_or_import(info) {
+ LocalOrImport::Local(_) => {
+ let params: Vec<_> = std::iter::once(ctx.basic())
+ .chain(
+ state
+ .peekn_extra(func_sig.params().len())?
+ .iter()
+ .enumerate()
+ .map(|(i, (v, info))| match func_sig.params()[i] {
+ Type::F32 => builder.build_bitcast(
+ apply_pending_canonicalization(
+ builder, intrinsics, *v, *info,
+ ),
+ intrinsics.i32_ty,
+ &state.var_name(),
+ ),
+ Type::F64 => builder.build_bitcast(
+ apply_pending_canonicalization(
+ builder, intrinsics, *v, *info,
+ ),
+ intrinsics.i64_ty,
+ &state.var_name(),
+ ),
+ Type::V128 => apply_pending_canonicalization(
+ builder, intrinsics, *v, *info,
+ ),
+ _ => *v,
+ }),
+ )
.collect();
- let func_ptr =
- ctx.local_func(local_func_index, llvm_sig, intrinsics, builder);
+ let func_ptr = self.llvm_functions.borrow_mut()[&func_index];
- builder.build_call(func_ptr, ¶ms, &state.var_name())
+ (params, func_ptr.as_global_value().as_pointer_value())
}
LocalOrImport::Import(import_func_index) => {
let (func_ptr_untyped, ctx_ptr) =
- ctx.imported_func(import_func_index, intrinsics);
- let params: Vec<_> = [ctx_ptr.as_basic_value_enum()]
- .iter()
- .chain(state.peekn(func_sig.params().len())?.iter())
- .map(|v| *v)
+ ctx.imported_func(import_func_index, intrinsics, self.module.clone());
+
+ let params: Vec<_> = std::iter::once(ctx_ptr.as_basic_value_enum())
+ .chain(
+ state
+ .peekn_extra(func_sig.params().len())?
+ .iter()
+ .enumerate()
+ .map(|(i, (v, info))| match func_sig.params()[i] {
+ Type::F32 => builder.build_bitcast(
+ apply_pending_canonicalization(
+ builder, intrinsics, *v, *info,
+ ),
+ intrinsics.i32_ty,
+ &state.var_name(),
+ ),
+ Type::F64 => builder.build_bitcast(
+ apply_pending_canonicalization(
+ builder, intrinsics, *v, *info,
+ ),
+ intrinsics.i64_ty,
+ &state.var_name(),
+ ),
+ Type::V128 => apply_pending_canonicalization(
+ builder, intrinsics, *v, *info,
+ ),
+ _ => *v,
+ }),
+ )
.collect();
let func_ptr_ty = llvm_sig.ptr_type(AddressSpace::Generic);
-
let func_ptr = builder.build_pointer_cast(
func_ptr_untyped,
func_ptr_ty,
"typed_func_ptr",
);
- builder.build_call(func_ptr, ¶ms, &state.var_name())
+ (params, func_ptr)
}
};
state.popn(func_sig.params().len())?;
+ if self.track_state {
+ if let Some(offset) = opcode_offset {
+ let mut stackmaps = self.stackmaps.borrow_mut();
+ emit_stack_map(
+ &info,
+ intrinsics,
+ builder,
+ self.index,
+ &mut *stackmaps,
+ StackmapEntryKind::Call,
+ &self.locals,
+ state,
+ ctx,
+ offset,
+ )
+ }
+ }
+ let call_site = builder.build_call(func_ptr, ¶ms, &state.var_name());
+ if self.track_state {
+ if let Some(offset) = opcode_offset {
+ let mut stackmaps = self.stackmaps.borrow_mut();
+ finalize_opcode_stack_map(
+ intrinsics,
+ builder,
+ self.index,
+ &mut *stackmaps,
+ StackmapEntryKind::Call,
+ offset,
+ )
+ }
+ }
if let Some(basic_value) = call_site.try_as_basic_value().left() {
match func_sig.returns().len() {
- 1 => state.push1(basic_value),
+ 1 => state.push1(match func_sig.returns()[0] {
+ Type::F32 => {
+ builder.build_bitcast(basic_value, intrinsics.f32_ty, "ret_cast")
+ }
+ Type::F64 => {
+ builder.build_bitcast(basic_value, intrinsics.f64_ty, "ret_cast")
+ }
+ _ => basic_value,
+ }),
count @ _ => {
// This is a multi-value return.
let struct_value = basic_value.into_struct_value();
@@ -1283,8 +1908,12 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
Operator::CallIndirect { index, table_index } => {
let sig_index = SigIndex::new(index as usize);
let expected_dynamic_sigindex = ctx.dynamic_sigindex(sig_index, intrinsics);
- let (table_base, table_bound) =
- ctx.table(TableIndex::new(table_index as usize), intrinsics, builder);
+ let (table_base, table_bound) = ctx.table(
+ TableIndex::new(table_index as usize),
+ intrinsics,
+ self.module.clone(),
+ builder,
+ );
let func_index = state.pop1()?.into_int_value();
// We assume the table has the `anyfunc` element type.
@@ -1353,9 +1982,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
.into_int_value();
let in_bounds_continue_block =
- context.append_basic_block(&function, "in_bounds_continue_block");
+ context.append_basic_block(function, "in_bounds_continue_block");
let not_in_bounds_block =
- context.append_basic_block(&function, "not_in_bounds_block");
+ context.append_basic_block(function, "not_in_bounds_block");
builder.build_conditional_branch(
index_in_bounds,
&in_bounds_continue_block,
@@ -1394,9 +2023,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
.unwrap()
.into_int_value();
- let continue_block = context.append_basic_block(&function, "continue_block");
+ let continue_block = context.append_basic_block(function, "continue_block");
let sigindices_notequal_block =
- context.append_basic_block(&function, "sigindices_notequal_block");
+ context.append_basic_block(function, "sigindices_notequal_block");
builder.build_conditional_branch(
sigindices_equal,
&continue_block,
@@ -1415,10 +2044,27 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
let wasmer_fn_sig = &info.signatures[sig_index];
let fn_ty = signatures[sig_index];
- let pushed_args = state.popn_save(wasmer_fn_sig.params().len())?;
+ let pushed_args = state.popn_save_extra(wasmer_fn_sig.params().len())?;
let args: Vec<_> = std::iter::once(ctx_ptr)
- .chain(pushed_args.into_iter())
+ .chain(pushed_args.into_iter().enumerate().map(|(i, (v, info))| {
+ match wasmer_fn_sig.params()[i] {
+ Type::F32 => builder.build_bitcast(
+ apply_pending_canonicalization(builder, intrinsics, v, info),
+ intrinsics.i32_ty,
+ &state.var_name(),
+ ),
+ Type::F64 => builder.build_bitcast(
+ apply_pending_canonicalization(builder, intrinsics, v, info),
+ intrinsics.i64_ty,
+ &state.var_name(),
+ ),
+ Type::V128 => {
+ apply_pending_canonicalization(builder, intrinsics, v, info)
+ }
+ _ => v,
+ }
+ }))
.collect();
let typed_func_ptr = builder.build_pointer_cast(
@@ -1427,15 +2073,58 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
"typed_func_ptr",
);
+ if self.track_state {
+ if let Some(offset) = opcode_offset {
+ let mut stackmaps = self.stackmaps.borrow_mut();
+ emit_stack_map(
+ &info,
+ intrinsics,
+ builder,
+ self.index,
+ &mut *stackmaps,
+ StackmapEntryKind::Call,
+ &self.locals,
+ state,
+ ctx,
+ offset,
+ )
+ }
+ }
let call_site = builder.build_call(typed_func_ptr, &args, "indirect_call");
+ if self.track_state {
+ if let Some(offset) = opcode_offset {
+ let mut stackmaps = self.stackmaps.borrow_mut();
+ finalize_opcode_stack_map(
+ intrinsics,
+ builder,
+ self.index,
+ &mut *stackmaps,
+ StackmapEntryKind::Call,
+ offset,
+ )
+ }
+ }
match wasmer_fn_sig.returns() {
[] => {}
[_] => {
let value = call_site.try_as_basic_value().left().unwrap();
- state.push1(value);
+ state.push1(match wasmer_fn_sig.returns()[0] {
+ Type::F32 => {
+ builder.build_bitcast(value, intrinsics.f32_ty, "ret_cast")
+ }
+ Type::F64 => {
+ builder.build_bitcast(value, intrinsics.f64_ty, "ret_cast")
+ }
+ _ => value,
+ });
+ }
+ _ => {
+ return Err(CodegenError {
+ message: "Operator::CallIndirect multi-value returns unimplemented"
+ .to_string(),
+ });
}
- _ => unimplemented!("multi-value returns"),
}
}
@@ -1444,67 +2133,55 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
* https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#integer-arithmetic-instructions
***************************/
Operator::I32Add | Operator::I64Add => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let res = builder.build_int_add(v1, v2, &state.var_name());
state.push1(res);
}
Operator::I8x16Add => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i8x16_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i8x16_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i8x16(builder, intrinsics, v2, i2);
let res = builder.build_int_add(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I16x8Add => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i16x8_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i16x8_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i16x8(builder, intrinsics, v2, i2);
let res = builder.build_int_add(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32x4Add => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i32x4(builder, intrinsics, v2, i2);
let res = builder.build_int_add(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I64x2Add => {
- let (v1, v2) = state.pop2()?;
- let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
- let v1 = builder
- .build_bitcast(v1, intrinsics.i64x2_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i64x2_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i64x2(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i64x2(builder, intrinsics, v2, i2);
let res = builder.build_int_add(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I8x16AddSaturateS => {
- let (v1, v2) = state.pop2()?;
- let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
- let v1 = builder.build_bitcast(v1, intrinsics.i8x16_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.i8x16_ty, "");
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i8x16(builder, intrinsics, v2, i2);
let res = builder
- .build_call(intrinsics.sadd_sat_i8x16, &[v1, v2], &state.var_name())
+ .build_call(
+ intrinsics.sadd_sat_i8x16,
+ &[v1.as_basic_value_enum(), v2.as_basic_value_enum()],
+ &state.var_name(),
+ )
.try_as_basic_value()
.left()
.unwrap();
@@ -1512,12 +2189,15 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I16x8AddSaturateS => {
- let (v1, v2) = state.pop2()?;
- let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
- let v1 = builder.build_bitcast(v1, intrinsics.i16x8_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.i16x8_ty, "");
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i16x8(builder, intrinsics, v2, i2);
let res = builder
- .build_call(intrinsics.sadd_sat_i16x8, &[v1, v2], &state.var_name())
+ .build_call(
+ intrinsics.sadd_sat_i16x8,
+ &[v1.as_basic_value_enum(), v2.as_basic_value_enum()],
+ &state.var_name(),
+ )
.try_as_basic_value()
.left()
.unwrap();
@@ -1525,12 +2205,15 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I8x16AddSaturateU => {
- let (v1, v2) = state.pop2()?;
- let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
- let v1 = builder.build_bitcast(v1, intrinsics.i8x16_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.i8x16_ty, "");
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i8x16(builder, intrinsics, v2, i2);
let res = builder
- .build_call(intrinsics.uadd_sat_i8x16, &[v1, v2], &state.var_name())
+ .build_call(
+ intrinsics.uadd_sat_i8x16,
+ &[v1.as_basic_value_enum(), v2.as_basic_value_enum()],
+ &state.var_name(),
+ )
.try_as_basic_value()
.left()
.unwrap();
@@ -1538,12 +2221,15 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I16x8AddSaturateU => {
- let (v1, v2) = state.pop2()?;
- let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
- let v1 = builder.build_bitcast(v1, intrinsics.i16x8_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.i16x8_ty, "");
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i16x8(builder, intrinsics, v2, i2);
let res = builder
- .build_call(intrinsics.uadd_sat_i16x8, &[v1, v2], &state.var_name())
+ .build_call(
+ intrinsics.uadd_sat_i16x8,
+ &[v1.as_basic_value_enum(), v2.as_basic_value_enum()],
+ &state.var_name(),
+ )
.try_as_basic_value()
.left()
.unwrap();
@@ -1551,70 +2237,55 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I32Sub | Operator::I64Sub => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let res = builder.build_int_sub(v1, v2, &state.var_name());
state.push1(res);
}
Operator::I8x16Sub => {
- let (v1, v2) = state.pop2()?;
- let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
- let v1 = builder
- .build_bitcast(v1, intrinsics.i8x16_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i8x16_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i8x16(builder, intrinsics, v2, i2);
let res = builder.build_int_sub(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I16x8Sub => {
- let (v1, v2) = state.pop2()?;
- let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
- let v1 = builder
- .build_bitcast(v1, intrinsics.i16x8_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i16x8_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i16x8(builder, intrinsics, v2, i2);
let res = builder.build_int_sub(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32x4Sub => {
- let (v1, v2) = state.pop2()?;
- let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
- let v1 = builder
- .build_bitcast(v1, intrinsics.i32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i32x4(builder, intrinsics, v2, i2);
let res = builder.build_int_sub(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I64x2Sub => {
- let (v1, v2) = state.pop2()?;
- let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
- let v1 = builder
- .build_bitcast(v1, intrinsics.i64x2_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i64x2_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i64x2(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i64x2(builder, intrinsics, v2, i2);
let res = builder.build_int_sub(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I8x16SubSaturateS => {
- let (v1, v2) = state.pop2()?;
- let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
- let v1 = builder.build_bitcast(v1, intrinsics.i8x16_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.i8x16_ty, "");
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i8x16(builder, intrinsics, v2, i2);
let res = builder
- .build_call(intrinsics.ssub_sat_i8x16, &[v1, v2], &state.var_name())
+ .build_call(
+ intrinsics.ssub_sat_i8x16,
+ &[v1.as_basic_value_enum(), v2.as_basic_value_enum()],
+ &state.var_name(),
+ )
.try_as_basic_value()
.left()
.unwrap();
@@ -1622,12 +2293,15 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I16x8SubSaturateS => {
- let (v1, v2) = state.pop2()?;
- let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
- let v1 = builder.build_bitcast(v1, intrinsics.i16x8_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.i16x8_ty, "");
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i16x8(builder, intrinsics, v2, i2);
let res = builder
- .build_call(intrinsics.ssub_sat_i16x8, &[v1, v2], &state.var_name())
+ .build_call(
+ intrinsics.ssub_sat_i16x8,
+ &[v1.as_basic_value_enum(), v2.as_basic_value_enum()],
+ &state.var_name(),
+ )
.try_as_basic_value()
.left()
.unwrap();
@@ -1635,12 +2309,15 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I8x16SubSaturateU => {
- let (v1, v2) = state.pop2()?;
- let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
- let v1 = builder.build_bitcast(v1, intrinsics.i8x16_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.i8x16_ty, "");
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i8x16(builder, intrinsics, v2, i2);
let res = builder
- .build_call(intrinsics.usub_sat_i8x16, &[v1, v2], &state.var_name())
+ .build_call(
+ intrinsics.usub_sat_i8x16,
+ &[v1.as_basic_value_enum(), v2.as_basic_value_enum()],
+ &state.var_name(),
+ )
.try_as_basic_value()
.left()
.unwrap();
@@ -1648,12 +2325,15 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I16x8SubSaturateU => {
- let (v1, v2) = state.pop2()?;
- let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
- let v1 = builder.build_bitcast(v1, intrinsics.i16x8_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.i16x8_ty, "");
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i16x8(builder, intrinsics, v2, i2);
let res = builder
- .build_call(intrinsics.usub_sat_i16x8, &[v1, v2], &state.var_name())
+ .build_call(
+ intrinsics.usub_sat_i16x8,
+ &[v1.as_basic_value_enum(), v2.as_basic_value_enum()],
+ &state.var_name(),
+ )
.try_as_basic_value()
.left()
.unwrap();
@@ -1661,52 +2341,41 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I32Mul | Operator::I64Mul => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let res = builder.build_int_mul(v1, v2, &state.var_name());
state.push1(res);
}
Operator::I8x16Mul => {
- let (v1, v2) = state.pop2()?;
- let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
- let v1 = builder
- .build_bitcast(v1, intrinsics.i8x16_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i8x16_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i8x16(builder, intrinsics, v2, i2);
let res = builder.build_int_mul(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I16x8Mul => {
- let (v1, v2) = state.pop2()?;
- let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
- let v1 = builder
- .build_bitcast(v1, intrinsics.i16x8_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i16x8_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i16x8(builder, intrinsics, v2, i2);
let res = builder.build_int_mul(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32x4Mul => {
- let (v1, v2) = state.pop2()?;
- let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
- let v1 = builder
- .build_bitcast(v1, intrinsics.i32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i32x4(builder, intrinsics, v2, i2);
let res = builder.build_int_mul(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32DivS | Operator::I64DivS => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
trap_if_zero_or_overflow(builder, intrinsics, context, &function, v1, v2);
@@ -1715,7 +2384,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I32DivU | Operator::I64DivU => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
trap_if_zero(builder, intrinsics, context, &function, v2);
@@ -1724,7 +2395,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I32RemS | Operator::I64RemS => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let int_type = v1.get_type();
let (min_value, neg_one_value) = if int_type == intrinsics.i32_ty {
@@ -1769,7 +2442,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I32RemU | Operator::I64RemU => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
trap_if_zero(builder, intrinsics, context, &function, v2);
@@ -1778,25 +2453,34 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I32And | Operator::I64And | Operator::V128And => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let res = builder.build_and(v1, v2, &state.var_name());
state.push1(res);
}
Operator::I32Or | Operator::I64Or | Operator::V128Or => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let res = builder.build_or(v1, v2, &state.var_name());
state.push1(res);
}
Operator::I32Xor | Operator::I64Xor | Operator::V128Xor => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let res = builder.build_xor(v1, v2, &state.var_name());
state.push1(res);
}
Operator::V128Bitselect => {
- let (v1, v2, cond) = state.pop3()?;
+ let ((v1, i1), (v2, i2), (cond, cond_info)) = state.pop3_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
+ let cond = apply_pending_canonicalization(builder, intrinsics, cond, cond_info);
let v1 = builder
.build_bitcast(v1, intrinsics.i1x128_ty, "")
.into_vector_value();
@@ -1811,17 +2495,18 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I32Shl | Operator::I64Shl => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
// TODO: missing 'and' of v2?
let res = builder.build_left_shift(v1, v2, &state.var_name());
state.push1(res);
}
Operator::I8x16Shl => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i8x16_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let v2 = v2.into_int_value();
let v2 = builder.build_and(v2, intrinsics.i32_ty.const_int(7, false), "");
let v2 = builder.build_int_truncate(v2, intrinsics.i8_ty, "");
@@ -1837,10 +2522,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I16x8Shl => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i16x8_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let v2 = v2.into_int_value();
let v2 = builder.build_and(v2, intrinsics.i32_ty.const_int(15, false), "");
let v2 = builder.build_int_truncate(v2, intrinsics.i16_ty, "");
@@ -1856,10 +2540,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I32x4Shl => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i32x4(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let v2 = v2.into_int_value();
let v2 = builder.build_and(v2, intrinsics.i32_ty.const_int(31, false), "");
let v2 = splat_vector(
@@ -1874,10 +2557,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I64x2Shl => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i64x2_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i64x2(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let v2 = v2.into_int_value();
let v2 = builder.build_and(v2, intrinsics.i32_ty.const_int(63, false), "");
let v2 = builder.build_int_z_extend(v2, intrinsics.i64_ty, "");
@@ -1893,17 +2575,18 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I32ShrS | Operator::I64ShrS => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
// TODO: check wasm spec, is this missing v2 mod LaneBits?
let res = builder.build_right_shift(v1, v2, true, &state.var_name());
state.push1(res);
}
Operator::I8x16ShrS => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i8x16_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let v2 = v2.into_int_value();
let v2 = builder.build_and(v2, intrinsics.i32_ty.const_int(7, false), "");
let v2 = builder.build_int_truncate(v2, intrinsics.i8_ty, "");
@@ -1919,10 +2602,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I16x8ShrS => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i16x8_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let v2 = v2.into_int_value();
let v2 = builder.build_and(v2, intrinsics.i32_ty.const_int(15, false), "");
let v2 = builder.build_int_truncate(v2, intrinsics.i16_ty, "");
@@ -1938,10 +2620,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I32x4ShrS => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i32x4(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let v2 = v2.into_int_value();
let v2 = builder.build_and(v2, intrinsics.i32_ty.const_int(31, false), "");
let v2 = splat_vector(
@@ -1956,10 +2637,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I64x2ShrS => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i64x2_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i64x2(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let v2 = v2.into_int_value();
let v2 = builder.build_and(v2, intrinsics.i32_ty.const_int(63, false), "");
let v2 = builder.build_int_z_extend(v2, intrinsics.i64_ty, "");
@@ -1975,16 +2655,17 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I32ShrU | Operator::I64ShrU => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let res = builder.build_right_shift(v1, v2, false, &state.var_name());
state.push1(res);
}
Operator::I8x16ShrU => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i8x16_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let v2 = v2.into_int_value();
let v2 = builder.build_and(v2, intrinsics.i32_ty.const_int(7, false), "");
let v2 = builder.build_int_truncate(v2, intrinsics.i8_ty, "");
@@ -2000,10 +2681,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I16x8ShrU => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i16x8_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let v2 = v2.into_int_value();
let v2 = builder.build_and(v2, intrinsics.i32_ty.const_int(15, false), "");
let v2 = builder.build_int_truncate(v2, intrinsics.i16_ty, "");
@@ -2019,10 +2699,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I32x4ShrU => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i32x4(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let v2 = v2.into_int_value();
let v2 = builder.build_and(v2, intrinsics.i32_ty.const_int(31, false), "");
let v2 = splat_vector(
@@ -2037,10 +2716,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I64x2ShrU => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i64x2_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i64x2(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let v2 = v2.into_int_value();
let v2 = builder.build_and(v2, intrinsics.i32_ty.const_int(63, false), "");
let v2 = builder.build_int_z_extend(v2, intrinsics.i64_ty, "");
@@ -2056,7 +2734,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I32Rotl => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let lhs = builder.build_left_shift(v1, v2, &state.var_name());
let rhs = {
@@ -2068,7 +2748,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I64Rotl => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let lhs = builder.build_left_shift(v1, v2, &state.var_name());
let rhs = {
@@ -2080,7 +2762,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I32Rotr => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let lhs = builder.build_right_shift(v1, v2, false, &state.var_name());
let rhs = {
@@ -2092,7 +2776,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I64Rotr => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let lhs = builder.build_right_shift(v1, v2, false, &state.var_name());
let rhs = {
@@ -2104,90 +2790,84 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I32Clz => {
- let input = state.pop1()?;
- let ensure_defined_zero = intrinsics
- .i1_ty
- .const_int(1 as u64, false)
- .as_basic_value_enum();
+ let (input, info) = state.pop1_extra()?;
+ let input = apply_pending_canonicalization(builder, intrinsics, input, info);
+ let is_zero_undef = intrinsics.i1_zero.as_basic_value_enum();
let res = builder
.build_call(
intrinsics.ctlz_i32,
- &[input, ensure_defined_zero],
+ &[input, is_zero_undef],
&state.var_name(),
)
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ state.push1_extra(res, ExtraInfo::arithmetic_f32());
}
Operator::I64Clz => {
- let input = state.pop1()?;
- let ensure_defined_zero = intrinsics
- .i1_ty
- .const_int(1 as u64, false)
- .as_basic_value_enum();
+ let (input, info) = state.pop1_extra()?;
+ let input = apply_pending_canonicalization(builder, intrinsics, input, info);
+ let is_zero_undef = intrinsics.i1_zero.as_basic_value_enum();
let res = builder
.build_call(
intrinsics.ctlz_i64,
- &[input, ensure_defined_zero],
+ &[input, is_zero_undef],
&state.var_name(),
)
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ state.push1_extra(res, ExtraInfo::arithmetic_f64());
}
Operator::I32Ctz => {
- let input = state.pop1()?;
- let ensure_defined_zero = intrinsics
- .i1_ty
- .const_int(1 as u64, false)
- .as_basic_value_enum();
+ let (input, info) = state.pop1_extra()?;
+ let input = apply_pending_canonicalization(builder, intrinsics, input, info);
+ let is_zero_undef = intrinsics.i1_zero.as_basic_value_enum();
let res = builder
.build_call(
intrinsics.cttz_i32,
- &[input, ensure_defined_zero],
+ &[input, is_zero_undef],
&state.var_name(),
)
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ state.push1_extra(res, ExtraInfo::arithmetic_f32());
}
Operator::I64Ctz => {
- let input = state.pop1()?;
- let ensure_defined_zero = intrinsics
- .i1_ty
- .const_int(1 as u64, false)
- .as_basic_value_enum();
+ let (input, info) = state.pop1_extra()?;
+ let input = apply_pending_canonicalization(builder, intrinsics, input, info);
+ let is_zero_undef = intrinsics.i1_zero.as_basic_value_enum();
let res = builder
.build_call(
intrinsics.cttz_i64,
- &[input, ensure_defined_zero],
+ &[input, is_zero_undef],
&state.var_name(),
)
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ state.push1_extra(res, ExtraInfo::arithmetic_f64());
}
Operator::I32Popcnt => {
- let input = state.pop1()?;
+ let (input, info) = state.pop1_extra()?;
+ let input = apply_pending_canonicalization(builder, intrinsics, input, info);
let res = builder
.build_call(intrinsics.ctpop_i32, &[input], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ state.push1_extra(res, ExtraInfo::arithmetic_f32());
}
Operator::I64Popcnt => {
- let input = state.pop1()?;
+ let (input, info) = state.pop1_extra()?;
+ let input = apply_pending_canonicalization(builder, intrinsics, input, info);
let res = builder
.build_call(intrinsics.ctpop_i64, &[input], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ state.push1_extra(res, ExtraInfo::arithmetic_f64());
}
Operator::I32Eqz => {
let input = state.pop1()?.into_int_value();
@@ -2198,7 +2878,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
&state.var_name(),
);
let res = builder.build_int_z_extend(cond, intrinsics.i32_ty, &state.var_name());
- state.push1(res);
+ state.push1_extra(res, ExtraInfo::arithmetic_f32());
}
Operator::I64Eqz => {
let input = state.pop1()?.into_int_value();
@@ -2209,132 +2889,160 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
&state.var_name(),
);
let res = builder.build_int_z_extend(cond, intrinsics.i32_ty, &state.var_name());
- state.push1(res);
+ state.push1_extra(res, ExtraInfo::arithmetic_f64());
}
/***************************
* Floating-Point Arithmetic instructions.
* https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#floating-point-arithmetic-instructions
***************************/
- Operator::F32Add | Operator::F64Add => {
- let (v1, v2) = state.pop2()?;
- let v1 = canonicalize_nans(builder, intrinsics, v1);
- let v2 = canonicalize_nans(builder, intrinsics, v2);
+ Operator::F32Add => {
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
let res = builder.build_float_add(v1, v2, &state.var_name());
- state.push1(res);
+ state.push1_extra(
+ res,
+ (i1.strip_pending() & i2.strip_pending()) | ExtraInfo::pending_f32_nan(),
+ );
+ }
+ Operator::F64Add => {
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
+ let res = builder.build_float_add(v1, v2, &state.var_name());
+ state.push1_extra(
+ res,
+ (i1.strip_pending() & i2.strip_pending()) | ExtraInfo::pending_f64_nan(),
+ );
}
Operator::F32x4Add => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder.build_bitcast(v1, intrinsics.f32x4_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.f32x4_ty, "");
- let v1 = canonicalize_nans(builder, intrinsics, v1);
- let v2 = canonicalize_nans(builder, intrinsics, v2);
- let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, i1) = v128_into_f32x4(builder, intrinsics, v1, i1);
+ let (v2, i2) = v128_into_f32x4(builder, intrinsics, v2, i2);
let res = builder.build_float_add(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ state.push1_extra(
+ res,
+ (i1.strip_pending() & i2.strip_pending()) | ExtraInfo::pending_f32_nan(),
+ );
}
Operator::F64x2Add => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder.build_bitcast(v1, intrinsics.f64x2_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.f64x2_ty, "");
- let v1 = canonicalize_nans(builder, intrinsics, v1);
- let v2 = canonicalize_nans(builder, intrinsics, v2);
- let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, i1) = v128_into_f64x2(builder, intrinsics, v1, i1);
+ let (v2, i2) = v128_into_f64x2(builder, intrinsics, v2, i2);
let res = builder.build_float_add(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ state.push1_extra(
+ res,
+ (i1.strip_pending() & i2.strip_pending()) | ExtraInfo::pending_f64_nan(),
+ );
}
- Operator::F32Sub | Operator::F64Sub => {
- let (v1, v2) = state.pop2()?;
- let v1 = canonicalize_nans(builder, intrinsics, v1);
- let v2 = canonicalize_nans(builder, intrinsics, v2);
+ Operator::F32Sub => {
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
let res = builder.build_float_sub(v1, v2, &state.var_name());
- state.push1(res);
+ state.push1_extra(
+ res,
+ (i1.strip_pending() & i2.strip_pending()) | ExtraInfo::pending_f32_nan(),
+ );
+ }
+ Operator::F64Sub => {
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
+ let res = builder.build_float_sub(v1, v2, &state.var_name());
+ state.push1_extra(
+ res,
+ (i1.strip_pending() & i2.strip_pending()) | ExtraInfo::pending_f64_nan(),
+ );
}
Operator::F32x4Sub => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder.build_bitcast(v1, intrinsics.f32x4_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.f32x4_ty, "");
- let v1 = canonicalize_nans(builder, intrinsics, v1);
- let v2 = canonicalize_nans(builder, intrinsics, v2);
- let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, i1) = v128_into_f32x4(builder, intrinsics, v1, i1);
+ let (v2, i2) = v128_into_f32x4(builder, intrinsics, v2, i2);
let res = builder.build_float_sub(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ state.push1_extra(
+ res,
+ (i1.strip_pending() & i2.strip_pending()) | ExtraInfo::pending_f32_nan(),
+ );
}
Operator::F64x2Sub => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder.build_bitcast(v1, intrinsics.f64x2_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.f64x2_ty, "");
- let v1 = canonicalize_nans(builder, intrinsics, v1);
- let v2 = canonicalize_nans(builder, intrinsics, v2);
- let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, i1) = v128_into_f64x2(builder, intrinsics, v1, i1);
+ let (v2, i2) = v128_into_f64x2(builder, intrinsics, v2, i2);
let res = builder.build_float_sub(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ state.push1_extra(
+ res,
+ (i1.strip_pending() & i2.strip_pending()) | ExtraInfo::pending_f64_nan(),
+ );
}
- Operator::F32Mul | Operator::F64Mul => {
- let (v1, v2) = state.pop2()?;
- let v1 = canonicalize_nans(builder, intrinsics, v1);
- let v2 = canonicalize_nans(builder, intrinsics, v2);
+ Operator::F32Mul => {
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
let res = builder.build_float_mul(v1, v2, &state.var_name());
- state.push1(res);
+ state.push1_extra(
+ res,
+ (i1.strip_pending() & i2.strip_pending()) | ExtraInfo::pending_f32_nan(),
+ );
+ }
+ Operator::F64Mul => {
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
+ let res = builder.build_float_mul(v1, v2, &state.var_name());
+ state.push1_extra(
+ res,
+ (i1.strip_pending() & i2.strip_pending()) | ExtraInfo::pending_f64_nan(),
+ );
}
Operator::F32x4Mul => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder.build_bitcast(v1, intrinsics.f32x4_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.f32x4_ty, "");
- let v1 = canonicalize_nans(builder, intrinsics, v1);
- let v2 = canonicalize_nans(builder, intrinsics, v2);
- let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, i1) = v128_into_f32x4(builder, intrinsics, v1, i1);
+ let (v2, i2) = v128_into_f32x4(builder, intrinsics, v2, i2);
let res = builder.build_float_mul(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ state.push1_extra(
+ res,
+ (i1.strip_pending() & i2.strip_pending()) | ExtraInfo::pending_f32_nan(),
+ );
}
Operator::F64x2Mul => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder.build_bitcast(v1, intrinsics.f64x2_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.f64x2_ty, "");
- let v1 = canonicalize_nans(builder, intrinsics, v1);
- let v2 = canonicalize_nans(builder, intrinsics, v2);
- let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, i1) = v128_into_f64x2(builder, intrinsics, v1, i1);
+ let (v2, i2) = v128_into_f64x2(builder, intrinsics, v2, i2);
let res = builder.build_float_mul(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ state.push1_extra(
+ res,
+ (i1.strip_pending() & i2.strip_pending()) | ExtraInfo::pending_f64_nan(),
+ );
}
- Operator::F32Div | Operator::F64Div => {
+ Operator::F32Div => {
let (v1, v2) = state.pop2()?;
- let v1 = canonicalize_nans(builder, intrinsics, v1);
- let v2 = canonicalize_nans(builder, intrinsics, v2);
let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
let res = builder.build_float_div(v1, v2, &state.var_name());
- state.push1(res);
+ state.push1_extra(res, ExtraInfo::pending_f32_nan());
+ }
+ Operator::F64Div => {
+ let (v1, v2) = state.pop2()?;
+ let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
+ let res = builder.build_float_div(v1, v2, &state.var_name());
+ state.push1_extra(res, ExtraInfo::pending_f64_nan());
}
Operator::F32x4Div => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder.build_bitcast(v1, intrinsics.f32x4_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.f32x4_ty, "");
- let v1 = canonicalize_nans(builder, intrinsics, v1);
- let v2 = canonicalize_nans(builder, intrinsics, v2);
- let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_f32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_f32x4(builder, intrinsics, v2, i2);
let res = builder.build_float_div(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ state.push1_extra(res, ExtraInfo::pending_f32_nan());
}
Operator::F64x2Div => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder.build_bitcast(v1, intrinsics.f64x2_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.f64x2_ty, "");
- let v1 = canonicalize_nans(builder, intrinsics, v1);
- let v2 = canonicalize_nans(builder, intrinsics, v2);
- let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_f64x2(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_f64x2(builder, intrinsics, v2, i2);
let res = builder.build_float_div(v1, v2, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ state.push1_extra(res, ExtraInfo::pending_f64_nan());
}
Operator::F32Sqrt => {
let input = state.pop1()?;
@@ -2343,7 +3051,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ state.push1_extra(res, ExtraInfo::pending_f32_nan());
}
Operator::F64Sqrt => {
let input = state.pop1()?;
@@ -2352,24 +3060,32 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ state.push1_extra(res, ExtraInfo::pending_f64_nan());
}
Operator::F32x4Sqrt => {
- let input = state.pop1()?.into_int_value();
- let float = builder.build_bitcast(input, intrinsics.f32x4_ty, "float");
+ let (v, i) = state.pop1_extra()?;
+ let (v, _) = v128_into_f32x4(builder, intrinsics, v, i);
let res = builder
- .build_call(intrinsics.sqrt_f32x4, &[float], &state.var_name())
+ .build_call(
+ intrinsics.sqrt_f32x4,
+ &[v.as_basic_value_enum()],
+ &state.var_name(),
+ )
.try_as_basic_value()
.left()
.unwrap();
let bits = builder.build_bitcast(res, intrinsics.i128_ty, "bits");
- state.push1(bits);
+ state.push1_extra(bits, ExtraInfo::pending_f32_nan());
}
Operator::F64x2Sqrt => {
- let input = state.pop1()?.into_int_value();
- let float = builder.build_bitcast(input, intrinsics.f64x2_ty, "float");
+ let (v, i) = state.pop1_extra()?;
+ let (v, _) = v128_into_f64x2(builder, intrinsics, v, i);
let res = builder
- .build_call(intrinsics.sqrt_f64x2, &[float], &state.var_name())
+ .build_call(
+ intrinsics.sqrt_f64x2,
+ &[v.as_basic_value_enum()],
+ &state.var_name(),
+ )
.try_as_basic_value()
.left()
.unwrap();
@@ -2377,241 +3093,689 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(bits);
}
Operator::F32Min => {
+ // This implements the same logic as LLVM's @llvm.minimum
+ // intrinsic would, but x86 lowering of that intrinsic
+ // encounters a fatal error in LLVM 8 and LLVM 9.
let (v1, v2) = state.pop2()?;
- let res = builder
- .build_call(intrinsics.minimum_f32, &[v1, v2], &state.var_name())
- .try_as_basic_value()
- .left()
- .unwrap();
- state.push1(res);
+
+ // To detect min(-0.0, 0.0), we check whether the integer
+ // representations are equal. There's one other case where that
+ // can happen: non-canonical NaNs. Here we unconditionally
+ // canonicalize the NaNs.
+ let v1 = canonicalize_nans(builder, intrinsics, v1);
+ let v2 = canonicalize_nans(builder, intrinsics, v2);
+
+ let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
+ let v1_is_nan = builder.build_float_compare(
+ FloatPredicate::UNO,
+ v1,
+ intrinsics.f32_zero,
+ "nan",
+ );
+ let v2_is_not_nan = builder.build_float_compare(
+ FloatPredicate::ORD,
+ v2,
+ intrinsics.f32_zero,
+ "notnan",
+ );
+ let v1_repr = builder
+ .build_bitcast(v1, intrinsics.i32_ty, "")
+ .into_int_value();
+ let v2_repr = builder
+ .build_bitcast(v2, intrinsics.i32_ty, "")
+ .into_int_value();
+ let repr_ne = builder.build_int_compare(IntPredicate::NE, v1_repr, v2_repr, "");
+ let float_eq = builder.build_float_compare(FloatPredicate::OEQ, v1, v2, "");
+ let min_cmp = builder.build_float_compare(FloatPredicate::OLT, v1, v2, "");
+ let negative_zero = intrinsics.f32_ty.const_float(-0.0);
+ let v2 = builder
+ .build_select(
+ builder.build_and(
+ builder.build_and(float_eq, repr_ne, ""),
+ v2_is_not_nan,
+ "",
+ ),
+ negative_zero,
+ v2,
+ "",
+ )
+ .into_float_value();
+ let res =
+ builder.build_select(builder.build_or(v1_is_nan, min_cmp, ""), v1, v2, "");
+ // Because inputs were canonicalized, we always produce
+ // canonical NaN outputs. No pending NaN cleanup.
+ state.push1_extra(res, ExtraInfo::arithmetic_f32());
}
Operator::F64Min => {
+ // This implements the same logic as LLVM's @llvm.minimum
+ // intrinsic would, but x86 lowering of that intrinsic
+ // encounters a fatal error in LLVM 8 and LLVM 9.
let (v1, v2) = state.pop2()?;
- let res = builder
- .build_call(intrinsics.minimum_f64, &[v1, v2], &state.var_name())
- .try_as_basic_value()
- .left()
- .unwrap();
- state.push1(res);
+
+ // To detect min(-0.0, 0.0), we check whether the integer
+ // representations are equal. There's one other case where that
+ // can happen: non-canonical NaNs. Here we unconditionally
+ // canonicalize the NaNs.
+ let v1 = canonicalize_nans(builder, intrinsics, v1);
+ let v2 = canonicalize_nans(builder, intrinsics, v2);
+
+ let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
+ let v1_is_nan = builder.build_float_compare(
+ FloatPredicate::UNO,
+ v1,
+ intrinsics.f64_zero,
+ "nan",
+ );
+ let v2_is_not_nan = builder.build_float_compare(
+ FloatPredicate::ORD,
+ v2,
+ intrinsics.f64_zero,
+ "notnan",
+ );
+ let v1_repr = builder
+ .build_bitcast(v1, intrinsics.i64_ty, "")
+ .into_int_value();
+ let v2_repr = builder
+ .build_bitcast(v2, intrinsics.i64_ty, "")
+ .into_int_value();
+ let repr_ne = builder.build_int_compare(IntPredicate::NE, v1_repr, v2_repr, "");
+ let float_eq = builder.build_float_compare(FloatPredicate::OEQ, v1, v2, "");
+ let min_cmp = builder.build_float_compare(FloatPredicate::OLT, v1, v2, "");
+ let negative_zero = intrinsics.f64_ty.const_float(-0.0);
+ let v2 = builder
+ .build_select(
+ builder.build_and(
+ builder.build_and(float_eq, repr_ne, ""),
+ v2_is_not_nan,
+ "",
+ ),
+ negative_zero,
+ v2,
+ "",
+ )
+ .into_float_value();
+ let res =
+ builder.build_select(builder.build_or(v1_is_nan, min_cmp, ""), v1, v2, "");
+ // Because inputs were canonicalized, we always produce
+ // canonical NaN outputs. No pending NaN cleanup.
+ state.push1_extra(res, ExtraInfo::arithmetic_f64());
}
Operator::F32x4Min => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder.build_bitcast(v1, intrinsics.f32x4_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.f32x4_ty, "");
- let res = builder
- .build_call(intrinsics.minimum_f32x4, &[v1, v2], &state.var_name())
- .try_as_basic_value()
- .left()
- .unwrap();
+ // This implements the same logic as LLVM's @llvm.minimum
+ // intrinsic would, but x86 lowering of that intrinsic
+ // encounters a fatal error in LLVM 8 and LLVM 9.
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_f32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_f32x4(builder, intrinsics, v2, i2);
+
+ // To detect min(-0.0, 0.0), we check whether the integer
+ // representations are equal. There's one other case where that
+ // can happen: non-canonical NaNs. Here we unconditionally
+ // canonicalize the NaNs. Note that this is a different
+ // canonicalization from that which may be performed in the
+ // v128_into_f32x4 function. That may canonicalize as F64x2 if
+ // previous computations may have emitted F64x2 NaNs.
+ let v1 = canonicalize_nans(builder, intrinsics, v1.as_basic_value_enum());
+ let v2 = canonicalize_nans(builder, intrinsics, v2.as_basic_value_enum());
+ let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
+
+ let v1_is_nan = builder.build_float_compare(
+ FloatPredicate::UNO,
+ v1,
+ intrinsics.f32x4_zero,
+ "nan",
+ );
+ let v2_is_not_nan = builder.build_float_compare(
+ FloatPredicate::ORD,
+ v2,
+ intrinsics.f32x4_zero,
+ "notnan",
+ );
+ let v1_repr = builder
+ .build_bitcast(v1, intrinsics.i32x4_ty, "")
+ .into_vector_value();
+ let v2_repr = builder
+ .build_bitcast(v2, intrinsics.i32x4_ty, "")
+ .into_vector_value();
+ let repr_ne = builder.build_int_compare(IntPredicate::NE, v1_repr, v2_repr, "");
+ let float_eq = builder.build_float_compare(FloatPredicate::OEQ, v1, v2, "");
+ let min_cmp = builder.build_float_compare(FloatPredicate::OLT, v1, v2, "");
+ let negative_zero = splat_vector(
+ builder,
+ intrinsics,
+ intrinsics.f32_ty.const_float(-0.0).as_basic_value_enum(),
+ intrinsics.f32x4_ty,
+ "",
+ );
+ let v2 = builder
+ .build_select(
+ builder.build_and(
+ builder.build_and(float_eq, repr_ne, ""),
+ v2_is_not_nan,
+ "",
+ ),
+ negative_zero,
+ v2,
+ "",
+ )
+ .into_vector_value();
+ let res =
+ builder.build_select(builder.build_or(v1_is_nan, min_cmp, ""), v1, v2, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ // Because inputs were canonicalized, we always produce
+ // canonical NaN outputs. No pending NaN cleanup.
+ state.push1_extra(res, ExtraInfo::arithmetic_f32());
}
Operator::F64x2Min => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder.build_bitcast(v1, intrinsics.f64x2_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.f64x2_ty, "");
- let res = builder
- .build_call(intrinsics.minimum_f64x2, &[v1, v2], &state.var_name())
- .try_as_basic_value()
- .left()
- .unwrap();
+ // This implements the same logic as LLVM's @llvm.minimum
+ // intrinsic would, but x86 lowering of that intrinsic
+ // encounters a fatal error in LLVM 8 and LLVM 9.
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_f64x2(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_f64x2(builder, intrinsics, v2, i2);
+
+ // To detect min(-0.0, 0.0), we check whether the integer
+ // representations are equal. There's one other case where that
+ // can happen: non-canonical NaNs. Here we unconditionally
+ // canonicalize the NaNs. Note that this is a different
+ // canonicalization from that which may be performed in the
+ // v128_into_f32x4 function. That may canonicalize as F64x2 if
+ // previous computations may have emitted F64x2 NaNs.
+ let v1 = canonicalize_nans(builder, intrinsics, v1.as_basic_value_enum());
+ let v2 = canonicalize_nans(builder, intrinsics, v2.as_basic_value_enum());
+ let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
+
+ let v1_is_nan = builder.build_float_compare(
+ FloatPredicate::UNO,
+ v1,
+ intrinsics.f64x2_zero,
+ "nan",
+ );
+ let v2_is_not_nan = builder.build_float_compare(
+ FloatPredicate::ORD,
+ v2,
+ intrinsics.f64x2_zero,
+ "notnan",
+ );
+ let v1_repr = builder
+ .build_bitcast(v1, intrinsics.i64x2_ty, "")
+ .into_vector_value();
+ let v2_repr = builder
+ .build_bitcast(v2, intrinsics.i64x2_ty, "")
+ .into_vector_value();
+ let repr_ne = builder.build_int_compare(IntPredicate::NE, v1_repr, v2_repr, "");
+ let float_eq = builder.build_float_compare(FloatPredicate::OEQ, v1, v2, "");
+ let min_cmp = builder.build_float_compare(FloatPredicate::OLT, v1, v2, "");
+ let negative_zero = splat_vector(
+ builder,
+ intrinsics,
+ intrinsics.f64_ty.const_float(-0.0).as_basic_value_enum(),
+ intrinsics.f64x2_ty,
+ "",
+ );
+ let v2 = builder
+ .build_select(
+ builder.build_and(
+ builder.build_and(float_eq, repr_ne, ""),
+ v2_is_not_nan,
+ "",
+ ),
+ negative_zero,
+ v2,
+ "",
+ )
+ .into_vector_value();
+ let res =
+ builder.build_select(builder.build_or(v1_is_nan, min_cmp, ""), v1, v2, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ // Because inputs were canonicalized, we always produce
+ // canonical NaN outputs. No pending NaN cleanup.
+ state.push1_extra(res, ExtraInfo::arithmetic_f64());
}
Operator::F32Max => {
+ // This implements the same logic as LLVM's @llvm.maximum
+ // intrinsic would, but x86 lowering of that intrinsic
+ // encounters a fatal error in LLVM 8 and LLVM 9.
let (v1, v2) = state.pop2()?;
- let res = builder
- .build_call(intrinsics.maximum_f32, &[v1, v2], &state.var_name())
- .try_as_basic_value()
- .left()
- .unwrap();
- state.push1(res);
+
+ // To detect min(-0.0, 0.0), we check whether the integer
+ // representations are equal. There's one other case where that
+ // can happen: non-canonical NaNs. Here we unconditionally
+ // canonicalize the NaNs.
+ let v1 = canonicalize_nans(builder, intrinsics, v1);
+ let v2 = canonicalize_nans(builder, intrinsics, v2);
+
+ let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
+ let v1_is_nan = builder.build_float_compare(
+ FloatPredicate::UNO,
+ v1,
+ intrinsics.f32_zero,
+ "nan",
+ );
+ let v2_is_not_nan = builder.build_float_compare(
+ FloatPredicate::ORD,
+ v2,
+ intrinsics.f32_zero,
+ "notnan",
+ );
+ let v1_repr = builder
+ .build_bitcast(v1, intrinsics.i32_ty, "")
+ .into_int_value();
+ let v2_repr = builder
+ .build_bitcast(v2, intrinsics.i32_ty, "")
+ .into_int_value();
+ let repr_ne = builder.build_int_compare(IntPredicate::NE, v1_repr, v2_repr, "");
+ let float_eq = builder.build_float_compare(FloatPredicate::OEQ, v1, v2, "");
+ let min_cmp = builder.build_float_compare(FloatPredicate::OGT, v1, v2, "");
+ let v2 = builder
+ .build_select(
+ builder.build_and(
+ builder.build_and(float_eq, repr_ne, ""),
+ v2_is_not_nan,
+ "",
+ ),
+ intrinsics.f32_zero,
+ v2,
+ "",
+ )
+ .into_float_value();
+ let res =
+ builder.build_select(builder.build_or(v1_is_nan, min_cmp, ""), v1, v2, "");
+ // Because inputs were canonicalized, we always produce
+ // canonical NaN outputs. No pending NaN cleanup.
+ state.push1_extra(res, ExtraInfo::arithmetic_f32());
}
Operator::F64Max => {
+ // This implements the same logic as LLVM's @llvm.maximum
+ // intrinsic would, but x86 lowering of that intrinsic
+ // encounters a fatal error in LLVM 8 and LLVM 9.
let (v1, v2) = state.pop2()?;
- let res = builder
- .build_call(intrinsics.maximum_f64, &[v1, v2], &state.var_name())
- .try_as_basic_value()
- .left()
- .unwrap();
- state.push1(res);
+
+ // To detect min(-0.0, 0.0), we check whether the integer
+ // representations are equal. There's one other case where that
+ // can happen: non-canonical NaNs. Here we unconditionally
+ // canonicalize the NaNs.
+ let v1 = canonicalize_nans(builder, intrinsics, v1);
+ let v2 = canonicalize_nans(builder, intrinsics, v2);
+
+ let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
+ let v1_is_nan = builder.build_float_compare(
+ FloatPredicate::UNO,
+ v1,
+ intrinsics.f64_zero,
+ "nan",
+ );
+ let v2_is_not_nan = builder.build_float_compare(
+ FloatPredicate::ORD,
+ v2,
+ intrinsics.f64_zero,
+ "notnan",
+ );
+ let v1_repr = builder
+ .build_bitcast(v1, intrinsics.i64_ty, "")
+ .into_int_value();
+ let v2_repr = builder
+ .build_bitcast(v2, intrinsics.i64_ty, "")
+ .into_int_value();
+ let repr_ne = builder.build_int_compare(IntPredicate::NE, v1_repr, v2_repr, "");
+ let float_eq = builder.build_float_compare(FloatPredicate::OEQ, v1, v2, "");
+ let min_cmp = builder.build_float_compare(FloatPredicate::OGT, v1, v2, "");
+ let v2 = builder
+ .build_select(
+ builder.build_and(
+ builder.build_and(float_eq, repr_ne, ""),
+ v2_is_not_nan,
+ "",
+ ),
+ intrinsics.f64_zero,
+ v2,
+ "",
+ )
+ .into_float_value();
+ let res =
+ builder.build_select(builder.build_or(v1_is_nan, min_cmp, ""), v1, v2, "");
+ // Because inputs were canonicalized, we always produce
+ // canonical NaN outputs. No pending NaN cleanup.
+ state.push1_extra(res, ExtraInfo::arithmetic_f64());
}
Operator::F32x4Max => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder.build_bitcast(v1, intrinsics.f32x4_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.f32x4_ty, "");
- let res = builder
- .build_call(intrinsics.maximum_f32x4, &[v1, v2], &state.var_name())
- .try_as_basic_value()
- .left()
- .unwrap();
+ // This implements the same logic as LLVM's @llvm.maximum
+ // intrinsic would, but x86 lowering of that intrinsic
+ // encounters a fatal error in LLVM 8 and LLVM 9.
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_f32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_f32x4(builder, intrinsics, v2, i2);
+
+ // To detect min(-0.0, 0.0), we check whether the integer
+ // representations are equal. There's one other case where that
+ // can happen: non-canonical NaNs. Here we unconditionally
+ // canonicalize the NaNs. Note that this is a different
+ // canonicalization from that which may be performed in the
+ // v128_into_f32x4 function. That may canonicalize as F64x2 if
+ // previous computations may have emitted F64x2 NaNs.
+ let v1 = canonicalize_nans(builder, intrinsics, v1.as_basic_value_enum());
+ let v2 = canonicalize_nans(builder, intrinsics, v2.as_basic_value_enum());
+ let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
+ let v1_is_nan = builder.build_float_compare(
+ FloatPredicate::UNO,
+ v1,
+ intrinsics.f32x4_zero,
+ "nan",
+ );
+ let v2_is_not_nan = builder.build_float_compare(
+ FloatPredicate::ORD,
+ v2,
+ intrinsics.f32x4_zero,
+ "notnan",
+ );
+ let v1_repr = builder
+ .build_bitcast(v1, intrinsics.i32x4_ty, "")
+ .into_vector_value();
+ let v2_repr = builder
+ .build_bitcast(v2, intrinsics.i32x4_ty, "")
+ .into_vector_value();
+ let repr_ne = builder.build_int_compare(IntPredicate::NE, v1_repr, v2_repr, "");
+ let float_eq = builder.build_float_compare(FloatPredicate::OEQ, v1, v2, "");
+ let min_cmp = builder.build_float_compare(FloatPredicate::OGT, v1, v2, "");
+ let zero = splat_vector(
+ builder,
+ intrinsics,
+ intrinsics.f32_zero.as_basic_value_enum(),
+ intrinsics.f32x4_ty,
+ "",
+ );
+ let v2 = builder
+ .build_select(
+ builder.build_and(
+ builder.build_and(float_eq, repr_ne, ""),
+ v2_is_not_nan,
+ "",
+ ),
+ zero,
+ v2,
+ "",
+ )
+ .into_vector_value();
+ let res =
+ builder.build_select(builder.build_or(v1_is_nan, min_cmp, ""), v1, v2, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ // Because inputs were canonicalized, we always produce
+ // canonical NaN outputs. No pending NaN cleanup.
+ state.push1_extra(res, ExtraInfo::arithmetic_f32());
}
Operator::F64x2Max => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder.build_bitcast(v1, intrinsics.f64x2_ty, "");
- let v2 = builder.build_bitcast(v2, intrinsics.f64x2_ty, "");
- let res = builder
- .build_call(intrinsics.maximum_f64x2, &[v1, v2], &state.var_name())
- .try_as_basic_value()
- .left()
- .unwrap();
+ // This implements the same logic as LLVM's @llvm.maximum
+ // intrinsic would, but x86 lowering of that intrinsic
+ // encounters a fatal error in LLVM 8 and LLVM 9.
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_f64x2(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_f64x2(builder, intrinsics, v2, i2);
+
+ // To detect min(-0.0, 0.0), we check whether the integer
+ // representations are equal. There's one other case where that
+ // can happen: non-canonical NaNs. Here we unconditionally
+ // canonicalize the NaNs. Note that this is a different
+ // canonicalization from that which may be performed in the
+ // v128_into_f32x4 function. That may canonicalize as F64x2 if
+ // previous computations may have emitted F64x2 NaNs.
+ let v1 = canonicalize_nans(builder, intrinsics, v1.as_basic_value_enum());
+ let v2 = canonicalize_nans(builder, intrinsics, v2.as_basic_value_enum());
+ let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
+ let v1_is_nan = builder.build_float_compare(
+ FloatPredicate::UNO,
+ v1,
+ intrinsics.f64x2_zero,
+ "nan",
+ );
+ let v2_is_not_nan = builder.build_float_compare(
+ FloatPredicate::ORD,
+ v2,
+ intrinsics.f64x2_zero,
+ "notnan",
+ );
+ let v1_repr = builder
+ .build_bitcast(v1, intrinsics.i64x2_ty, "")
+ .into_vector_value();
+ let v2_repr = builder
+ .build_bitcast(v2, intrinsics.i64x2_ty, "")
+ .into_vector_value();
+ let repr_ne = builder.build_int_compare(IntPredicate::NE, v1_repr, v2_repr, "");
+ let float_eq = builder.build_float_compare(FloatPredicate::OEQ, v1, v2, "");
+ let min_cmp = builder.build_float_compare(FloatPredicate::OGT, v1, v2, "");
+ let zero = splat_vector(
+ builder,
+ intrinsics,
+ intrinsics.f64_zero.as_basic_value_enum(),
+ intrinsics.f64x2_ty,
+ "",
+ );
+ let v2 = builder
+ .build_select(
+ builder.build_and(
+ builder.build_and(float_eq, repr_ne, ""),
+ v2_is_not_nan,
+ "",
+ ),
+ zero,
+ v2,
+ "",
+ )
+ .into_vector_value();
+ let res =
+ builder.build_select(builder.build_or(v1_is_nan, min_cmp, ""), v1, v2, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ // Because inputs were canonicalized, we always produce
+ // canonical NaN outputs. No pending NaN cleanup.
+ state.push1_extra(res, ExtraInfo::arithmetic_f64());
}
Operator::F32Ceil => {
- let input = state.pop1()?;
+ let (input, info) = state.pop1_extra()?;
let res = builder
.build_call(intrinsics.ceil_f32, &[input], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ state.push1_extra(res, info | ExtraInfo::pending_f32_nan());
}
Operator::F64Ceil => {
- let input = state.pop1()?;
+ let (input, info) = state.pop1_extra()?;
let res = builder
.build_call(intrinsics.ceil_f64, &[input], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ state.push1_extra(res, info | ExtraInfo::pending_f64_nan());
}
Operator::F32Floor => {
- let input = state.pop1()?;
+ let (input, info) = state.pop1_extra()?;
let res = builder
.build_call(intrinsics.floor_f32, &[input], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ state.push1_extra(res, info | ExtraInfo::pending_f32_nan());
}
Operator::F64Floor => {
- let input = state.pop1()?;
+ let (input, info) = state.pop1_extra()?;
let res = builder
.build_call(intrinsics.floor_f64, &[input], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ state.push1_extra(res, info | ExtraInfo::pending_f64_nan());
}
Operator::F32Trunc => {
- let input = state.pop1()?;
+ let (v, i) = state.pop1_extra()?;
let res = builder
- .build_call(intrinsics.trunc_f32, &[input], &state.var_name())
+ .build_call(
+ intrinsics.trunc_f32,
+ &[v.as_basic_value_enum()],
+ &state.var_name(),
+ )
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ state.push1_extra(res, i);
}
Operator::F64Trunc => {
- let input = state.pop1()?;
+ let (v, i) = state.pop1_extra()?;
let res = builder
- .build_call(intrinsics.trunc_f64, &[input], &state.var_name())
+ .build_call(
+ intrinsics.trunc_f64,
+ &[v.as_basic_value_enum()],
+ &state.var_name(),
+ )
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ state.push1_extra(res, i);
}
Operator::F32Nearest => {
- let input = state.pop1()?;
+ let (v, i) = state.pop1_extra()?;
let res = builder
- .build_call(intrinsics.nearbyint_f32, &[input], &state.var_name())
+ .build_call(
+ intrinsics.nearbyint_f32,
+ &[v.as_basic_value_enum()],
+ &state.var_name(),
+ )
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ state.push1_extra(res, i);
}
Operator::F64Nearest => {
- let input = state.pop1()?;
+ let (v, i) = state.pop1_extra()?;
let res = builder
- .build_call(intrinsics.nearbyint_f64, &[input], &state.var_name())
+ .build_call(
+ intrinsics.nearbyint_f64,
+ &[v.as_basic_value_enum()],
+ &state.var_name(),
+ )
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ state.push1_extra(res, i);
}
Operator::F32Abs => {
- let input = state.pop1()?;
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
let res = builder
- .build_call(intrinsics.fabs_f32, &[input], &state.var_name())
+ .build_call(
+ intrinsics.fabs_f32,
+ &[v.as_basic_value_enum()],
+ &state.var_name(),
+ )
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ // The exact NaN returned by F32Abs is fully defined. Do not
+ // adjust.
+ state.push1_extra(res, i.strip_pending());
}
Operator::F64Abs => {
- let input = state.pop1()?;
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
let res = builder
- .build_call(intrinsics.fabs_f64, &[input], &state.var_name())
+ .build_call(
+ intrinsics.fabs_f64,
+ &[v.as_basic_value_enum()],
+ &state.var_name(),
+ )
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ // The exact NaN returned by F64Abs is fully defined. Do not
+ // adjust.
+ state.push1_extra(res, i.strip_pending());
}
Operator::F32x4Abs => {
- let v = state.pop1()?.into_int_value();
- let v = builder.build_bitcast(v, intrinsics.f32x4_ty, "");
+ let (v, i) = state.pop1_extra()?;
+ let v = builder.build_bitcast(v.into_int_value(), intrinsics.f32x4_ty, "");
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
let res = builder
- .build_call(intrinsics.fabs_f32x4, &[v], &state.var_name())
+ .build_call(
+ intrinsics.fabs_f32x4,
+ &[v.as_basic_value_enum()],
+ &state.var_name(),
+ )
.try_as_basic_value()
.left()
.unwrap();
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ // The exact NaN returned by F32x4Abs is fully defined. Do not
+ // adjust.
+ state.push1_extra(res, i.strip_pending());
}
Operator::F64x2Abs => {
- let v = state.pop1()?.into_int_value();
- let v = builder.build_bitcast(v, intrinsics.f64x2_ty, "");
+ let (v, i) = state.pop1_extra()?;
+ let v = builder.build_bitcast(v.into_int_value(), intrinsics.f64x2_ty, "");
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
let res = builder
.build_call(intrinsics.fabs_f64x2, &[v], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ // The exact NaN returned by F32x4Abs is fully defined. Do not
+ // adjust.
+ state.push1_extra(res, i.strip_pending());
}
Operator::F32x4Neg => {
- let v = state.pop1()?.into_int_value();
- let v = builder
- .build_bitcast(v, intrinsics.f32x4_ty, "")
- .into_vector_value();
+ let (v, i) = state.pop1_extra()?;
+ let v = builder.build_bitcast(v.into_int_value(), intrinsics.f32x4_ty, "");
+ let v =
+ apply_pending_canonicalization(builder, intrinsics, v, i).into_vector_value();
let res = builder.build_float_neg(v, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ // The exact NaN returned by F32x4Neg is fully defined. Do not
+ // adjust.
+ state.push1_extra(res, i.strip_pending());
}
Operator::F64x2Neg => {
- let v = state.pop1()?.into_int_value();
- let v = builder
- .build_bitcast(v, intrinsics.f64x2_ty, "")
- .into_vector_value();
+ let (v, i) = state.pop1_extra()?;
+ let v = builder.build_bitcast(v.into_int_value(), intrinsics.f64x2_ty, "");
+ let v =
+ apply_pending_canonicalization(builder, intrinsics, v, i).into_vector_value();
let res = builder.build_float_neg(v, &state.var_name());
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
- state.push1(res);
+ // The exact NaN returned by F64x2Neg is fully defined. Do not
+ // adjust.
+ state.push1_extra(res, i.strip_pending());
}
Operator::F32Neg | Operator::F64Neg => {
- let input = state.pop1()?.into_float_value();
- let res = builder.build_float_neg(input, &state.var_name());
- state.push1(res);
+ let (v, i) = state.pop1_extra()?;
+ let v =
+ apply_pending_canonicalization(builder, intrinsics, v, i).into_float_value();
+ let res = builder.build_float_neg(v, &state.var_name());
+ // The exact NaN returned by F32Neg and F64Neg are fully defined.
+ // Do not adjust.
+ state.push1_extra(res, i.strip_pending());
}
Operator::F32Copysign => {
- let (mag, sgn) = state.pop2()?;
+ let ((mag, mag_info), (sgn, sgn_info)) = state.pop2_extra()?;
+ let mag = apply_pending_canonicalization(builder, intrinsics, mag, mag_info);
+ let sgn = apply_pending_canonicalization(builder, intrinsics, sgn, sgn_info);
let res = builder
.build_call(intrinsics.copysign_f32, &[mag, sgn], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ // The exact NaN returned by F32Copysign is fully defined.
+ // Do not adjust.
+ state.push1_extra(res, mag_info.strip_pending());
}
Operator::F64Copysign => {
- let (msg, sgn) = state.pop2()?;
+ let ((mag, mag_info), (sgn, sgn_info)) = state.pop2_extra()?;
+ let mag = apply_pending_canonicalization(builder, intrinsics, mag, mag_info);
+ let sgn = apply_pending_canonicalization(builder, intrinsics, sgn, sgn_info);
let res = builder
- .build_call(intrinsics.copysign_f64, &[msg, sgn], &state.var_name())
+ .build_call(intrinsics.copysign_f64, &[mag, sgn], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
- state.push1(res);
+ // The exact NaN returned by F32Copysign is fully defined.
+ // Do not adjust.
+ state.push1_extra(res, mag_info.strip_pending());
}
/***************************
@@ -2619,460 +3783,384 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
* https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#integer-comparison-instructions
***************************/
Operator::I32Eq | Operator::I64Eq => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let cond = builder.build_int_compare(IntPredicate::EQ, v1, v2, &state.var_name());
let res = builder.build_int_z_extend(cond, intrinsics.i32_ty, &state.var_name());
- state.push1(res);
+ state.push1_extra(
+ res,
+ ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64(),
+ );
}
Operator::I8x16Eq => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i8x16_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i8x16_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i8x16(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::EQ, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i8x16_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I16x8Eq => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i16x8_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i16x8_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i16x8(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::EQ, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i16x8_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32x4Eq => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i32x4(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::EQ, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i32x4_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32Ne | Operator::I64Ne => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let cond = builder.build_int_compare(IntPredicate::NE, v1, v2, &state.var_name());
let res = builder.build_int_z_extend(cond, intrinsics.i32_ty, &state.var_name());
- state.push1(res);
+ state.push1_extra(
+ res,
+ ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64(),
+ );
}
Operator::I8x16Ne => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i8x16_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i8x16_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i8x16(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::NE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i8x16_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I16x8Ne => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i16x8_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i16x8_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i16x8(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::NE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i16x8_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32x4Ne => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i32x4(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::NE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i32x4_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32LtS | Operator::I64LtS => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let cond = builder.build_int_compare(IntPredicate::SLT, v1, v2, &state.var_name());
let res = builder.build_int_z_extend(cond, intrinsics.i32_ty, &state.var_name());
- state.push1(res);
+ state.push1_extra(
+ res,
+ ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64(),
+ );
}
Operator::I8x16LtS => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i8x16_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i8x16_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i8x16(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::SLT, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i8x16_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I16x8LtS => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i16x8_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i16x8_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i16x8(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::SLT, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i16x8_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32x4LtS => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i32x4(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::SLT, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i32x4_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32LtU | Operator::I64LtU => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let cond = builder.build_int_compare(IntPredicate::ULT, v1, v2, &state.var_name());
let res = builder.build_int_z_extend(cond, intrinsics.i32_ty, &state.var_name());
state.push1(res);
}
Operator::I8x16LtU => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i8x16_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i8x16_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i8x16(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::ULT, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i8x16_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I16x8LtU => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i16x8_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i16x8_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i16x8(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::ULT, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i16x8_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32x4LtU => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i32x4(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::ULT, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i32x4_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32LeS | Operator::I64LeS => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let cond = builder.build_int_compare(IntPredicate::SLE, v1, v2, &state.var_name());
let res = builder.build_int_z_extend(cond, intrinsics.i32_ty, &state.var_name());
- state.push1(res);
+ state.push1_extra(
+ res,
+ ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64(),
+ );
}
Operator::I8x16LeS => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i8x16_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i8x16_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i8x16(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::SLE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i8x16_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I16x8LeS => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i16x8_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i16x8_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i16x8(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::SLE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i16x8_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32x4LeS => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i32x4(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::SLE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i32x4_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32LeU | Operator::I64LeU => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let cond = builder.build_int_compare(IntPredicate::ULE, v1, v2, &state.var_name());
let res = builder.build_int_z_extend(cond, intrinsics.i32_ty, &state.var_name());
- state.push1(res);
+ state.push1_extra(
+ res,
+ ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64(),
+ );
}
Operator::I8x16LeU => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i8x16_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i8x16_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i8x16(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::ULE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i8x16_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I16x8LeU => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i16x8_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i16x8_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i16x8(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::ULE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i16x8_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32x4LeU => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i32x4(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::ULE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i32x4_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32GtS | Operator::I64GtS => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let cond = builder.build_int_compare(IntPredicate::SGT, v1, v2, &state.var_name());
let res = builder.build_int_z_extend(cond, intrinsics.i32_ty, &state.var_name());
- state.push1(res);
+ state.push1_extra(
+ res,
+ ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64(),
+ );
}
Operator::I8x16GtS => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i8x16_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i8x16_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i8x16(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::SGT, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i8x16_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I16x8GtS => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i16x8_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i16x8_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i16x8(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::SGT, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i16x8_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32x4GtS => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i32x4(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::SGT, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i32x4_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32GtU | Operator::I64GtU => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let cond = builder.build_int_compare(IntPredicate::UGT, v1, v2, &state.var_name());
let res = builder.build_int_z_extend(cond, intrinsics.i32_ty, &state.var_name());
- state.push1(res);
+ state.push1_extra(
+ res,
+ ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64(),
+ );
}
Operator::I8x16GtU => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i8x16_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i8x16_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i8x16(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::UGT, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i8x16_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I16x8GtU => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i16x8_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i16x8_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i16x8(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::UGT, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i16x8_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32x4GtU => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i32x4(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::UGT, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i32x4_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32GeS | Operator::I64GeS => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let cond = builder.build_int_compare(IntPredicate::SGE, v1, v2, &state.var_name());
let res = builder.build_int_z_extend(cond, intrinsics.i32_ty, &state.var_name());
state.push1(res);
}
Operator::I8x16GeS => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i8x16_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i8x16_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i8x16(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::SGE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i8x16_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I16x8GeS => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i16x8_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i16x8_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i16x8(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::SGE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i16x8_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32x4GeS => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i32x4(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::SGE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i32x4_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32GeU | Operator::I64GeU => {
- let (v1, v2) = state.pop2()?;
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let v1 = apply_pending_canonicalization(builder, intrinsics, v1, i1);
+ let v2 = apply_pending_canonicalization(builder, intrinsics, v2, i2);
let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
let cond = builder.build_int_compare(IntPredicate::UGE, v1, v2, &state.var_name());
let res = builder.build_int_z_extend(cond, intrinsics.i32_ty, &state.var_name());
- state.push1(res);
+ state.push1_extra(
+ res,
+ ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64(),
+ );
}
Operator::I8x16GeU => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i8x16_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i8x16_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i8x16(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i8x16(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::UGE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i8x16_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I16x8GeU => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i16x8_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i16x8_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i16x8(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i16x8(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::UGE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i16x8_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::I32x4GeU => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.i32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.i32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_i32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_i32x4(builder, intrinsics, v2, i2);
let res = builder.build_int_compare(IntPredicate::UGE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i32x4_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
@@ -3089,29 +4177,24 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
let cond =
builder.build_float_compare(FloatPredicate::OEQ, v1, v2, &state.var_name());
let res = builder.build_int_z_extend(cond, intrinsics.i32_ty, &state.var_name());
- state.push1(res);
+ state.push1_extra(
+ res,
+ ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64(),
+ );
}
Operator::F32x4Eq => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.f32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.f32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_f32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_f32x4(builder, intrinsics, v2, i2);
let res = builder.build_float_compare(FloatPredicate::OEQ, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i32x4_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::F64x2Eq => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.f64x2_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.f64x2_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_f64x2(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_f64x2(builder, intrinsics, v2, i2);
let res = builder.build_float_compare(FloatPredicate::OEQ, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i64x2_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
@@ -3123,29 +4206,24 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
let cond =
builder.build_float_compare(FloatPredicate::UNE, v1, v2, &state.var_name());
let res = builder.build_int_z_extend(cond, intrinsics.i32_ty, &state.var_name());
- state.push1(res);
+ state.push1_extra(
+ res,
+ ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64(),
+ );
}
Operator::F32x4Ne => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.f32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.f32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_f32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_f32x4(builder, intrinsics, v2, i2);
let res = builder.build_float_compare(FloatPredicate::UNE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i32x4_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::F64x2Ne => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.f64x2_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.f64x2_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_f64x2(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_f64x2(builder, intrinsics, v2, i2);
let res = builder.build_float_compare(FloatPredicate::UNE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i64x2_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
@@ -3157,29 +4235,24 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
let cond =
builder.build_float_compare(FloatPredicate::OLT, v1, v2, &state.var_name());
let res = builder.build_int_z_extend(cond, intrinsics.i32_ty, &state.var_name());
- state.push1(res);
+ state.push1_extra(
+ res,
+ ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64(),
+ );
}
Operator::F32x4Lt => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.f32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.f32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_f32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_f32x4(builder, intrinsics, v2, i2);
let res = builder.build_float_compare(FloatPredicate::OLT, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i32x4_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::F64x2Lt => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.f64x2_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.f64x2_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_f64x2(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_f64x2(builder, intrinsics, v2, i2);
let res = builder.build_float_compare(FloatPredicate::OLT, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i64x2_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
@@ -3191,29 +4264,24 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
let cond =
builder.build_float_compare(FloatPredicate::OLE, v1, v2, &state.var_name());
let res = builder.build_int_z_extend(cond, intrinsics.i32_ty, &state.var_name());
- state.push1(res);
+ state.push1_extra(
+ res,
+ ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64(),
+ );
}
Operator::F32x4Le => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.f32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.f32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_f32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_f32x4(builder, intrinsics, v2, i2);
let res = builder.build_float_compare(FloatPredicate::OLE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i32x4_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::F64x2Le => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.f64x2_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.f64x2_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_f64x2(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_f64x2(builder, intrinsics, v2, i2);
let res = builder.build_float_compare(FloatPredicate::OLE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i64x2_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
@@ -3225,29 +4293,24 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
let cond =
builder.build_float_compare(FloatPredicate::OGT, v1, v2, &state.var_name());
let res = builder.build_int_z_extend(cond, intrinsics.i32_ty, &state.var_name());
- state.push1(res);
+ state.push1_extra(
+ res,
+ ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64(),
+ );
}
Operator::F32x4Gt => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.f32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.f32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_f32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_f32x4(builder, intrinsics, v2, i2);
let res = builder.build_float_compare(FloatPredicate::OGT, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i32x4_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::F64x2Gt => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.f64x2_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.f64x2_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_f64x2(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_f64x2(builder, intrinsics, v2, i2);
let res = builder.build_float_compare(FloatPredicate::OGT, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i64x2_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
@@ -3259,29 +4322,24 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
let cond =
builder.build_float_compare(FloatPredicate::OGE, v1, v2, &state.var_name());
let res = builder.build_int_z_extend(cond, intrinsics.i32_ty, &state.var_name());
- state.push1(res);
+ state.push1_extra(
+ res,
+ ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64(),
+ );
}
Operator::F32x4Ge => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.f32x4_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.f32x4_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_f32x4(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_f32x4(builder, intrinsics, v2, i2);
let res = builder.build_float_compare(FloatPredicate::OGE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i32x4_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::F64x2Ge => {
- let (v1, v2) = state.pop2()?;
- let v1 = builder
- .build_bitcast(v1, intrinsics.f64x2_ty, "")
- .into_vector_value();
- let v2 = builder
- .build_bitcast(v2, intrinsics.f64x2_ty, "")
- .into_vector_value();
+ let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
+ let (v1, _) = v128_into_f64x2(builder, intrinsics, v1, i1);
+ let (v2, _) = v128_into_f64x2(builder, intrinsics, v2, i2);
let res = builder.build_float_compare(FloatPredicate::OGE, v1, v2, "");
let res = builder.build_int_s_extend(res, intrinsics.i64x2_ty, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
@@ -3293,22 +4351,30 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
* https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#conversion-instructions
***************************/
Operator::I32WrapI64 => {
- let v1 = state.pop1()?.into_int_value();
- let res = builder.build_int_truncate(v1, intrinsics.i32_ty, &state.var_name());
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
+ let v = v.into_int_value();
+ let res = builder.build_int_truncate(v, intrinsics.i32_ty, &state.var_name());
state.push1(res);
}
Operator::I64ExtendSI32 => {
- let v1 = state.pop1()?.into_int_value();
- let res = builder.build_int_s_extend(v1, intrinsics.i64_ty, &state.var_name());
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
+ let v = v.into_int_value();
+ let res = builder.build_int_s_extend(v, intrinsics.i64_ty, &state.var_name());
state.push1(res);
}
Operator::I64ExtendUI32 => {
- let v1 = state.pop1()?.into_int_value();
- let res = builder.build_int_z_extend(v1, intrinsics.i64_ty, &state.var_name());
- state.push1(res);
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
+ let v = v.into_int_value();
+ let res = builder.build_int_z_extend(v, intrinsics.i64_ty, &state.var_name());
+ state.push1_extra(res, ExtraInfo::arithmetic_f64());
}
Operator::I32x4TruncSF32x4Sat => {
- let v = state.pop1()?.into_int_value();
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
+ let v = v.into_int_value();
let res = trunc_sat(
builder,
intrinsics,
@@ -3324,7 +4390,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I32x4TruncUF32x4Sat => {
- let v = state.pop1()?.into_int_value();
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
+ let v = v.into_int_value();
let res = trunc_sat(
builder,
intrinsics,
@@ -3340,7 +4408,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I64x2TruncSF64x2Sat => {
- let v = state.pop1()?.into_int_value();
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
+ let v = v.into_int_value();
let res = trunc_sat(
builder,
intrinsics,
@@ -3356,7 +4426,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I64x2TruncUF64x2Sat => {
- let v = state.pop1()?.into_int_value();
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
+ let v = v.into_int_value();
let res = trunc_sat(
builder,
intrinsics,
@@ -3501,39 +4573,47 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::F32DemoteF64 => {
- let v1 = state.pop1()?;
- let v1 = canonicalize_nans(builder, intrinsics, v1).into_float_value();
- let res = builder.build_float_trunc(v1, intrinsics.f32_ty, &state.var_name());
- state.push1(res);
+ let v = state.pop1()?;
+ let v = v.into_float_value();
+ let res = builder.build_float_trunc(v, intrinsics.f32_ty, &state.var_name());
+ state.push1_extra(res, ExtraInfo::pending_f32_nan());
}
Operator::F64PromoteF32 => {
- let v1 = state.pop1()?;
- let v1 = canonicalize_nans(builder, intrinsics, v1).into_float_value();
- let res = builder.build_float_ext(v1, intrinsics.f64_ty, &state.var_name());
- state.push1(res);
+ let v = state.pop1()?;
+ let v = v.into_float_value();
+ let res = builder.build_float_ext(v, intrinsics.f64_ty, &state.var_name());
+ state.push1_extra(res, ExtraInfo::pending_f64_nan());
}
Operator::F32ConvertSI32 | Operator::F32ConvertSI64 => {
- let v1 = state.pop1()?.into_int_value();
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
+ let v = v.into_int_value();
let res =
- builder.build_signed_int_to_float(v1, intrinsics.f32_ty, &state.var_name());
+ builder.build_signed_int_to_float(v, intrinsics.f32_ty, &state.var_name());
state.push1(res);
}
Operator::F64ConvertSI32 | Operator::F64ConvertSI64 => {
- let v1 = state.pop1()?.into_int_value();
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
+ let v = v.into_int_value();
let res =
- builder.build_signed_int_to_float(v1, intrinsics.f64_ty, &state.var_name());
+ builder.build_signed_int_to_float(v, intrinsics.f64_ty, &state.var_name());
state.push1(res);
}
Operator::F32ConvertUI32 | Operator::F32ConvertUI64 => {
- let v1 = state.pop1()?.into_int_value();
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
+ let v = v.into_int_value();
let res =
- builder.build_unsigned_int_to_float(v1, intrinsics.f32_ty, &state.var_name());
+ builder.build_unsigned_int_to_float(v, intrinsics.f32_ty, &state.var_name());
state.push1(res);
}
Operator::F64ConvertUI32 | Operator::F64ConvertUI64 => {
- let v1 = state.pop1()?.into_int_value();
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
+ let v = v.into_int_value();
let res =
- builder.build_unsigned_int_to_float(v1, intrinsics.f64_ty, &state.var_name());
+ builder.build_unsigned_int_to_float(v, intrinsics.f64_ty, &state.var_name());
state.push1(res);
}
Operator::F32x4ConvertSI32x4 => {
@@ -3577,24 +4657,26 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::I32ReinterpretF32 => {
- let v = state.pop1()?;
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
let ret = builder.build_bitcast(v, intrinsics.i32_ty, &state.var_name());
- state.push1(ret);
+ state.push1_extra(ret, ExtraInfo::arithmetic_f32());
}
Operator::I64ReinterpretF64 => {
- let v = state.pop1()?;
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
let ret = builder.build_bitcast(v, intrinsics.i64_ty, &state.var_name());
- state.push1(ret);
+ state.push1_extra(ret, ExtraInfo::arithmetic_f64());
}
Operator::F32ReinterpretI32 => {
- let v = state.pop1()?;
+ let (v, i) = state.pop1_extra()?;
let ret = builder.build_bitcast(v, intrinsics.f32_ty, &state.var_name());
- state.push1(ret);
+ state.push1_extra(ret, i);
}
Operator::F64ReinterpretI64 => {
- let v = state.pop1()?;
+ let (v, i) = state.pop1_extra()?;
let ret = builder.build_bitcast(v, intrinsics.f64_ty, &state.var_name());
- state.push1(ret);
+ state.push1_extra(ret, i);
}
/***************************
@@ -3651,6 +4733,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
builder,
intrinsics,
context,
+ self.module.clone(),
&function,
&mut state,
&mut ctx,
@@ -3659,6 +4742,18 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
4,
)?;
let result = builder.build_load(effective_address, &state.var_name());
+ result
+ .as_instruction_value()
+ .unwrap()
+ .set_alignment(1)
+ .unwrap();
+ tbaa_label(
+ &self.module,
+ intrinsics,
+ "memory",
+ result.as_instruction_value().unwrap(),
+ Some(0),
+ );
state.push1(result);
}
Operator::I64Load { ref memarg } => {
@@ -3666,6 +4761,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
builder,
intrinsics,
context,
+ self.module.clone(),
&function,
&mut state,
&mut ctx,
@@ -3674,6 +4770,18 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
8,
)?;
let result = builder.build_load(effective_address, &state.var_name());
+ result
+ .as_instruction_value()
+ .unwrap()
+ .set_alignment(1)
+ .unwrap();
+ tbaa_label(
+ &self.module,
+ intrinsics,
+ "memory",
+ result.as_instruction_value().unwrap(),
+ Some(0),
+ );
state.push1(result);
}
Operator::F32Load { ref memarg } => {
@@ -3681,6 +4789,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
builder,
intrinsics,
context,
+ self.module.clone(),
&function,
&mut state,
&mut ctx,
@@ -3689,6 +4798,18 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
4,
)?;
let result = builder.build_load(effective_address, &state.var_name());
+ result
+ .as_instruction_value()
+ .unwrap()
+ .set_alignment(1)
+ .unwrap();
+ tbaa_label(
+ &self.module,
+ intrinsics,
+ "memory",
+ result.as_instruction_value().unwrap(),
+ Some(0),
+ );
state.push1(result);
}
Operator::F64Load { ref memarg } => {
@@ -3696,6 +4817,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
builder,
intrinsics,
context,
+ self.module.clone(),
&function,
&mut state,
&mut ctx,
@@ -3704,6 +4826,18 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
8,
)?;
let result = builder.build_load(effective_address, &state.var_name());
+ result
+ .as_instruction_value()
+ .unwrap()
+ .set_alignment(1)
+ .unwrap();
+ tbaa_label(
+ &self.module,
+ intrinsics,
+ "memory",
+ result.as_instruction_value().unwrap(),
+ Some(0),
+ );
state.push1(result);
}
Operator::V128Load { ref memarg } => {
@@ -3711,6 +4845,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
builder,
intrinsics,
context,
+ self.module.clone(),
&function,
&mut state,
&mut ctx,
@@ -3719,6 +4854,18 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
16,
)?;
let result = builder.build_load(effective_address, &state.var_name());
+ result
+ .as_instruction_value()
+ .unwrap()
+ .set_alignment(1)
+ .unwrap();
+ tbaa_label(
+ &self.module,
+ intrinsics,
+ "memory",
+ result.as_instruction_value().unwrap(),
+ Some(0),
+ );
state.push1(result);
}
@@ -3728,6 +4875,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
builder,
intrinsics,
context,
+ self.module.clone(),
&function,
&mut state,
&mut ctx,
@@ -3735,7 +4883,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
intrinsics.i32_ptr_ty,
4,
)?;
- builder.build_store(effective_address, value);
+ let store = builder.build_store(effective_address, value);
+ store.set_alignment(1).unwrap();
+ tbaa_label(&self.module, intrinsics, "memory", store, Some(0));
}
Operator::I64Store { ref memarg } => {
let value = state.pop1()?;
@@ -3743,6 +4893,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
builder,
intrinsics,
context,
+ self.module.clone(),
&function,
&mut state,
&mut ctx,
@@ -3750,14 +4901,18 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
intrinsics.i64_ptr_ty,
8,
)?;
- builder.build_store(effective_address, value);
+ let store = builder.build_store(effective_address, value);
+ store.set_alignment(1).unwrap();
+ tbaa_label(&self.module, intrinsics, "memory", store, Some(0));
}
Operator::F32Store { ref memarg } => {
- let value = state.pop1()?;
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
let effective_address = resolve_memory_ptr(
builder,
intrinsics,
context,
+ self.module.clone(),
&function,
&mut state,
&mut ctx,
@@ -3765,14 +4920,18 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
intrinsics.f32_ptr_ty,
4,
)?;
- builder.build_store(effective_address, value);
+ let store = builder.build_store(effective_address, v);
+ store.set_alignment(1).unwrap();
+ tbaa_label(&self.module, intrinsics, "memory", store, Some(0));
}
Operator::F64Store { ref memarg } => {
- let value = state.pop1()?;
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
let effective_address = resolve_memory_ptr(
builder,
intrinsics,
context,
+ self.module.clone(),
&function,
&mut state,
&mut ctx,
@@ -3780,14 +4939,18 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
intrinsics.f64_ptr_ty,
8,
)?;
- builder.build_store(effective_address, value);
+ let store = builder.build_store(effective_address, v);
+ store.set_alignment(1).unwrap();
+ tbaa_label(&self.module, intrinsics, "memory", store, Some(0));
}
Operator::V128Store { ref memarg } => {
- let value = state.pop1()?;
+ let (v, i) = state.pop1_extra()?;
+ let v = apply_pending_canonicalization(builder, intrinsics, v, i);
let effective_address = resolve_memory_ptr(
builder,
intrinsics,
context,
+ self.module.clone(),
&function,
&mut state,
&mut ctx,
@@ -3795,14 +4958,16 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
intrinsics.i128_ptr_ty,
16,
)?;
- builder.build_store(effective_address, value);
+ let store = builder.build_store(effective_address, v);
+ store.set_alignment(1).unwrap();
+ tbaa_label(&self.module, intrinsics, "memory", store, Some(0));
}
-
Operator::I32Load8S { ref memarg } => {
let effective_address = resolve_memory_ptr(
builder,
intrinsics,
context,
+ self.module.clone(),
&function,
&mut state,
&mut ctx,
@@ -3810,11 +4975,24 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
intrinsics.i8_ptr_ty,
1,
)?;
- let narrow_result = builder
- .build_load(effective_address, &state.var_name())
- .into_int_value();
- let result =
- builder.build_int_s_extend(narrow_result, intrinsics.i32_ty, &state.var_name());
+ let narrow_result = builder.build_load(effective_address, &state.var_name());
+ narrow_result
+ .as_instruction_value()
+ .unwrap()
+ .set_alignment(1)
+ .unwrap();
+ tbaa_label(
+ &self.module,
+ intrinsics,
+ "memory",
+ narrow_result.as_instruction_value().unwrap(),
+ Some(0),
+ );
+ let result = builder.build_int_s_extend(
+ narrow_result.into_int_value(),
+ intrinsics.i32_ty,
+ &state.var_name(),
+ );
state.push1(result);
}
Operator::I32Load16S { ref memarg } => {
@@ -3822,6 +5000,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
builder,
intrinsics,
context,
+ self.module.clone(),
&function,
&mut state,
&mut ctx,
@@ -3829,11 +5008,24 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
intrinsics.i16_ptr_ty,
2,
)?;
- let narrow_result = builder
- .build_load(effective_address, &state.var_name())
- .into_int_value();
- let result =
- builder.build_int_s_extend(narrow_result, intrinsics.i32_ty, &state.var_name());
+ let narrow_result = builder.build_load(effective_address, &state.var_name());
+ narrow_result
+ .as_instruction_value()
+ .unwrap()
+ .set_alignment(1)
+ .unwrap();
+ tbaa_label(
+ &self.module,
+ intrinsics,
+ "memory",
+ narrow_result.as_instruction_value().unwrap(),
+ Some(0),
+ );
+ let result = builder.build_int_s_extend(
+ narrow_result.into_int_value(),
+ intrinsics.i32_ty,
+ &state.var_name(),
+ );
state.push1(result);
}
Operator::I64Load8S { ref memarg } => {
@@ -3841,6 +5033,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
builder,
intrinsics,
context,
+ self.module.clone(),
&function,
&mut state,
&mut ctx,
@@ -3851,6 +5044,18 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
let narrow_result = builder
.build_load(effective_address, &state.var_name())
.into_int_value();
+ narrow_result
+ .as_instruction_value()
+ .unwrap()
+ .set_alignment(1)
+ .unwrap();
+ tbaa_label(
+ &self.module,
+ intrinsics,
+ "memory",
+ narrow_result.as_instruction_value().unwrap(),
+ Some(0),
+ );
let result =
builder.build_int_s_extend(narrow_result, intrinsics.i64_ty, &state.var_name());
state.push1(result);
@@ -3860,6 +5065,7 @@ impl FunctionCodeGenerator