mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-03 11:18:31 +00:00
Merge pull request #5443 from wasmerio/run-500-enable-c_api-backends-to-be-used-in-wasmers-implementation
Enable multiple backends supported by the api crate to be used in the c-api as well
This commit is contained in:
18
.github/workflows/test.yaml
vendored
18
.github/workflows/test.yaml
vendored
@@ -493,6 +493,11 @@ jobs:
|
|||||||
build-cmd: "make build-capi && make build-capi-headless && make package-capi && make tar-capi",
|
build-cmd: "make build-capi && make build-capi-headless && make package-capi && make tar-capi",
|
||||||
name: "Build and test C-API",
|
name: "Build and test C-API",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: capi-v8,
|
||||||
|
build-cmd: "make test-capi-v8",
|
||||||
|
name: "Build and test C-API with v8",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: wasmer,
|
key: wasmer,
|
||||||
build-cmd: "make build-wasmer && make package-wasmer && make tar-wasmer",
|
build-cmd: "make build-wasmer && make package-wasmer && make tar-wasmer",
|
||||||
@@ -511,6 +516,10 @@ jobs:
|
|||||||
target: x86_64-unknown-linux-gnu,
|
target: x86_64-unknown-linux-gnu,
|
||||||
exe: "",
|
exe: "",
|
||||||
llvm_url: "https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-linux-amd64.tar.xz",
|
llvm_url: "https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-linux-amd64.tar.xz",
|
||||||
|
# Unfortunately, building a shared lib of the c_api with the v8
|
||||||
|
# backend does not work, due to unsupported relocations to hidden
|
||||||
|
# symbols in wee8.
|
||||||
|
supports_v8: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
build: macos-x64,
|
build: macos-x64,
|
||||||
@@ -518,6 +527,7 @@ jobs:
|
|||||||
target: x86_64-apple-darwin,
|
target: x86_64-apple-darwin,
|
||||||
exe: "",
|
exe: "",
|
||||||
llvm_url: "https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-amd64.tar.xz",
|
llvm_url: "https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-amd64.tar.xz",
|
||||||
|
supports_v8: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
build: macos-arm,
|
build: macos-arm,
|
||||||
@@ -525,6 +535,7 @@ jobs:
|
|||||||
target: aarch64-apple-darwin,
|
target: aarch64-apple-darwin,
|
||||||
exe: "",
|
exe: "",
|
||||||
llvm_url: "https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-aarch64.tar.xz",
|
llvm_url: "https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-aarch64.tar.xz",
|
||||||
|
supports_v8: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
build: windows-x64,
|
build: windows-x64,
|
||||||
@@ -533,11 +544,13 @@ jobs:
|
|||||||
exe: ".exe",
|
exe: ".exe",
|
||||||
# For now, disable LLVM in `windows-x64.`
|
# For now, disable LLVM in `windows-x64.`
|
||||||
# llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-windows-amd64.tar.xz'
|
# llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-windows-amd64.tar.xz'
|
||||||
|
supports_v8: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
build: windows-gnu,
|
build: windows-gnu,
|
||||||
target: x86_64-pc-windows-gnu,
|
target: x86_64-pc-windows-gnu,
|
||||||
os: ubuntu-22.04,
|
os: ubuntu-22.04,
|
||||||
|
supports_v8: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
build: linux-musl,
|
build: linux-musl,
|
||||||
@@ -545,6 +558,7 @@ jobs:
|
|||||||
os: ubuntu-22.04,
|
os: ubuntu-22.04,
|
||||||
exe: "",
|
exe: "",
|
||||||
container: "alpine:latest",
|
container: "alpine:latest",
|
||||||
|
supports_v8: false
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
container: ${{ matrix.metadata.container }}
|
container: ${{ matrix.metadata.container }}
|
||||||
@@ -684,6 +698,10 @@ jobs:
|
|||||||
TARGET: ${{ matrix.metadata.target }}
|
TARGET: ${{ matrix.metadata.target }}
|
||||||
TARGET_DIR: target/${{ matrix.metadata.target }}/release
|
TARGET_DIR: target/${{ matrix.metadata.target }}/release
|
||||||
CARGO_TARGET: ${{ matrix.metadata.target }}
|
CARGO_TARGET: ${{ matrix.metadata.target }}
|
||||||
|
- name: Test C-API (v8)
|
||||||
|
shell: bash
|
||||||
|
run: ${{ matrix.build-what.build-cmd }}
|
||||||
|
if: ${{ matrix.build-what.key == 'capi-v8' && matrix.metadata.supports_v8 == true }}
|
||||||
- name: Build Wasmer
|
- name: Build Wasmer
|
||||||
shell: bash
|
shell: bash
|
||||||
if: ${{ matrix.build-what.key == 'wasmer' && matrix.metadata.build != 'windows-gnu' }}
|
if: ${{ matrix.build-what.key == 'wasmer' && matrix.metadata.build != 'windows-gnu' }}
|
||||||
|
|||||||
20
Makefile
20
Makefile
@@ -559,7 +559,7 @@ build-docs-capi:
|
|||||||
|
|
||||||
build-capi:
|
build-capi:
|
||||||
RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET_FLAG) --manifest-path lib/c-api/Cargo.toml --release \
|
RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET_FLAG) --manifest-path lib/c-api/Cargo.toml --release \
|
||||||
--no-default-features --features wat,compiler,wasi,middlewares,webc_runner $(capi_compiler_features) --locked
|
--no-default-features --features wat,sys-default,compiler,wasi,middlewares,webc_runner $(capi_compiler_features) --locked
|
||||||
|
|
||||||
build-capi-singlepass:
|
build-capi-singlepass:
|
||||||
RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET_FLAG) --manifest-path lib/c-api/Cargo.toml --release \
|
RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET_FLAG) --manifest-path lib/c-api/Cargo.toml --release \
|
||||||
@@ -585,9 +585,21 @@ build-capi-llvm-universal:
|
|||||||
RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET_FLAG) --manifest-path lib/c-api/Cargo.toml --release \
|
RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET_FLAG) --manifest-path lib/c-api/Cargo.toml --release \
|
||||||
--no-default-features --features wat,compiler,llvm,wasi,middlewares,webc_runner --locked
|
--no-default-features --features wat,compiler,llvm,wasi,middlewares,webc_runner --locked
|
||||||
|
|
||||||
|
build-capi-v8:
|
||||||
|
RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET_FLAG) --manifest-path lib/c-api/Cargo.toml --release \
|
||||||
|
--no-default-features --features wat,v8-default,wasi --locked
|
||||||
|
|
||||||
|
build-capi-wamr:
|
||||||
|
RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET_FLAG) --manifest-path lib/c-api/Cargo.toml --release \
|
||||||
|
--no-default-features --features wat,wamr-default,wasi --locked
|
||||||
|
|
||||||
|
build-capi-wasmi:
|
||||||
|
RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET_FLAG) --manifest-path lib/c-api/Cargo.toml --release \
|
||||||
|
--no-default-features --features wat,wasmi-default,wasi --locked
|
||||||
|
|
||||||
build-capi-jsc:
|
build-capi-jsc:
|
||||||
RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET_FLAG) --manifest-path lib/c-api/Cargo.toml --release \
|
RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET_FLAG) --manifest-path lib/c-api/Cargo.toml --release \
|
||||||
--no-default-features --features wat,jsc,wasi --locked
|
--no-default-features --features wat,jsc-default,wasi --locked
|
||||||
|
|
||||||
# Headless (we include the minimal to be able to run)
|
# Headless (we include the minimal to be able to run)
|
||||||
|
|
||||||
@@ -703,6 +715,10 @@ test-capi-ci: $(foreach compiler_engine,$(capi_compilers_engines),test-capi-crat
|
|||||||
# compilers first
|
# compilers first
|
||||||
test-capi: build-capi package-capi test-capi-ci
|
test-capi: build-capi package-capi test-capi-ci
|
||||||
|
|
||||||
|
test-capi-v8: build-capi-v8 package-capi test-capi-integration-v8
|
||||||
|
test-capi-wasmi: build-capi-wasmi package-capi test-capi-integration-wasmi
|
||||||
|
test-capi-wamr: build-capi-wamr package-capi test-capi-integration-wamr
|
||||||
|
|
||||||
test-capi-jsc: build-capi-jsc package-capi test-capi-integration-jsc
|
test-capi-jsc: build-capi-jsc package-capi test-capi-integration-jsc
|
||||||
|
|
||||||
test-capi-crate-%:
|
test-capi-crate-%:
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ js = ["wasm-bindgen", "js-sys"]
|
|||||||
js-default = ["js", "std", "wasm-types-polyfill"]
|
js-default = ["js", "std", "wasm-types-polyfill"]
|
||||||
|
|
||||||
wasm-types-polyfill = ["wasmparser"]
|
wasm-types-polyfill = ["wasmparser"]
|
||||||
|
wat = ["dep:wat", "wasmparser"]
|
||||||
|
|
||||||
jsc = ["rusty_jsc", "wasm-types-polyfill", "wasmparser"]
|
jsc = ["rusty_jsc", "wasm-types-polyfill", "wasmparser"]
|
||||||
jsc-default = ["jsc"]
|
jsc-default = ["jsc"]
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
#[cfg(feature = "wamr")]
|
#[cfg(feature = "wamr")]
|
||||||
fn build_wamr() {
|
fn build_wamr() {
|
||||||
use bindgen::callbacks::ParseCallbacks;
|
use bindgen::callbacks::ParseCallbacks;
|
||||||
const WAMR_ZIP: &str = "https://github.com/bytecodealliance/wasm-micro-runtime/archive/0e4dffc47922bb6fcdcaed7de2a6edfe8c48a7cd.zip";
|
const WAMR_ZIP: &str =
|
||||||
const ZIP_NAME: &str = "wasm-micro-runtime-0e4dffc47922bb6fcdcaed7de2a6edfe8c48a7cd";
|
"https://github.com/bytecodealliance/wasm-micro-runtime/archive/refs/tags/WAMR-2.2.0.zip";
|
||||||
|
const ZIP_NAME: &str = "wasm-micro-runtime-WAMR-2.2.0";
|
||||||
|
|
||||||
use cmake::Config;
|
use cmake::Config;
|
||||||
use std::{env, path::PathBuf};
|
use std::{env, path::PathBuf};
|
||||||
@@ -36,24 +37,27 @@ fn build_wamr() {
|
|||||||
|
|
||||||
// Cleanup tmp data from prior builds
|
// Cleanup tmp data from prior builds
|
||||||
let wamr_dir = PathBuf::from(&crate_root).join("third_party/wamr");
|
let wamr_dir = PathBuf::from(&crate_root).join("third_party/wamr");
|
||||||
let zip_dir = PathBuf::from(&crate_root)
|
if !wamr_dir.exists() {
|
||||||
.join("third_party")
|
let zip_dir = PathBuf::from(&crate_root).join("third_party");
|
||||||
.join(ZIP_NAME);
|
let _ = std::fs::remove_dir_all(&wamr_dir);
|
||||||
let _ = std::fs::remove_dir_all(&wamr_dir);
|
let _ = std::fs::remove_dir_all(&zip_dir);
|
||||||
let _ = std::fs::remove_dir_all(&zip_dir);
|
|
||||||
|
|
||||||
// Fetch & extract wasm-micro-runtime source
|
// Fetch & extract wasm-micro-runtime source
|
||||||
let zip = ureq::get(WAMR_ZIP).call().expect("failed to download wamr");
|
let zip = ureq::get(WAMR_ZIP).call().expect("failed to download wamr");
|
||||||
let mut zip_data = Vec::new();
|
let mut zip_data = Vec::new();
|
||||||
zip.into_reader()
|
zip.into_reader()
|
||||||
.read_to_end(&mut zip_data)
|
.read_to_end(&mut zip_data)
|
||||||
.expect("failed to download wamr");
|
.expect("failed to download wamr");
|
||||||
zip::read::ZipArchive::new(std::io::Cursor::new(zip_data))
|
zip::read::ZipArchive::new(std::io::Cursor::new(zip_data))
|
||||||
.expect("failed to open wamr zip file")
|
.expect("failed to open wamr zip file")
|
||||||
.extract(&zip_dir)
|
.extract(&zip_dir)
|
||||||
.expect("failed to extract wamr zip file");
|
.expect("failed to extract wamr zip file");
|
||||||
let _ = std::fs::remove_dir_all(&wamr_dir);
|
let _ = std::fs::remove_dir_all(&wamr_dir);
|
||||||
std::fs::rename(zip_dir.join(ZIP_NAME), &wamr_dir).expect("failed to rename wamr dir");
|
std::fs::rename(zip_dir.join(ZIP_NAME), &wamr_dir)
|
||||||
|
.expect(&format!("failed to rename wamr dir: {zip_dir:?}"));
|
||||||
|
} else {
|
||||||
|
println!("cargo::rerun-if-changed={}", wamr_dir.display());
|
||||||
|
}
|
||||||
|
|
||||||
let wamr_platform_dir = wamr_dir.join("product-mini/platforms").join(target_os);
|
let wamr_platform_dir = wamr_dir.join("product-mini/platforms").join(target_os);
|
||||||
let mut dst = Config::new(wamr_platform_dir.as_path());
|
let mut dst = Config::new(wamr_platform_dir.as_path());
|
||||||
@@ -83,7 +87,7 @@ fn build_wamr() {
|
|||||||
.define("WAMR_BUILD_LIBC_WASI", "0")
|
.define("WAMR_BUILD_LIBC_WASI", "0")
|
||||||
.define("WAMR_BUILD_LIBC_BUILTIN", "0")
|
.define("WAMR_BUILD_LIBC_BUILTIN", "0")
|
||||||
.define("WAMR_BUILD_SHARED_MEMORY", "1")
|
.define("WAMR_BUILD_SHARED_MEMORY", "1")
|
||||||
.define("WAMR_BUILD_MULTI_MODULE", "0")
|
.define("WAMR_BUILD_MULTI_MODULE", "1")
|
||||||
.define("WAMR_DISABLE_HW_BOUND_CHECK", "1")
|
.define("WAMR_DISABLE_HW_BOUND_CHECK", "1")
|
||||||
.define("WAMR_BUILD_TARGET", target_arch);
|
.define("WAMR_BUILD_TARGET", target_arch);
|
||||||
|
|
||||||
@@ -216,7 +220,7 @@ fn build_wamr() {
|
|||||||
"cargo:rustc-link-search=native={}",
|
"cargo:rustc-link-search=native={}",
|
||||||
dst.join("build").display()
|
dst.join("build").display()
|
||||||
);
|
);
|
||||||
println!("cargo:rustc-link-lib=wamr");
|
println!("cargo:rustc-link-lib=static=wamr");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "v8")]
|
#[cfg(feature = "v8")]
|
||||||
@@ -297,8 +301,17 @@ fn build_v8() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let header_path = v8_header_path.join("wasm.h");
|
let header_path = v8_header_path.join("wasm.h");
|
||||||
|
let mut args = vec![];
|
||||||
|
if cfg!(target_os = "macos") {
|
||||||
|
args.push("-I/usr/local/include");
|
||||||
|
args.push("-I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1");
|
||||||
|
args.push("-I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include");
|
||||||
|
args.push("-I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include");
|
||||||
|
args.push("-I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks");
|
||||||
|
}
|
||||||
let bindings = bindgen::Builder::default()
|
let bindings = bindgen::Builder::default()
|
||||||
.header(header_path.display().to_string())
|
.header(header_path.display().to_string())
|
||||||
|
.clang_args(args)
|
||||||
.derive_default(true)
|
.derive_default(true)
|
||||||
.derive_debug(true)
|
.derive_debug(true)
|
||||||
.parse_callbacks(Box::new(Wee8Renamer {}))
|
.parse_callbacks(Box::new(Wee8Renamer {}))
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//! Data types, functions and traits for the `sys` runtime.
|
//! Data types, functions and traits for the `js` backend.
|
||||||
|
|
||||||
pub(crate) mod entities;
|
pub(crate) mod entities;
|
||||||
pub(crate) mod error;
|
pub(crate) mod error;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//! Data types, functions and traits for the `sys` runtime.
|
//! Data types, functions and traits for the `jsc` backend.
|
||||||
|
|
||||||
pub(crate) mod entities;
|
pub(crate) mod entities;
|
||||||
pub(crate) mod error;
|
pub(crate) mod error;
|
||||||
|
|||||||
@@ -59,3 +59,93 @@ pub enum BackendKind {
|
|||||||
/// The `jsc` runtime.
|
/// The `jsc` runtime.
|
||||||
Jsc,
|
Jsc,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for BackendKind {
|
||||||
|
fn default() -> Self {
|
||||||
|
#[cfg(feature = "sys-default")]
|
||||||
|
{
|
||||||
|
#[cfg(feature = "cranelift")]
|
||||||
|
{
|
||||||
|
return Self::Cranelift;
|
||||||
|
}
|
||||||
|
#[cfg(feature = "singlepass")]
|
||||||
|
{
|
||||||
|
return Self::Singlepass;
|
||||||
|
}
|
||||||
|
#[cfg(feature = "llvm")]
|
||||||
|
{
|
||||||
|
return Self::LLVM;
|
||||||
|
}
|
||||||
|
return Self::Headless;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "wamr-default")]
|
||||||
|
{
|
||||||
|
return Self::Wamr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "wasmi-default")]
|
||||||
|
{
|
||||||
|
return Self::Wasmi;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "v8-default")]
|
||||||
|
{
|
||||||
|
return Self::V8;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "js-default")]
|
||||||
|
{
|
||||||
|
return Self::Js;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "jsc-default")]
|
||||||
|
{
|
||||||
|
return Self::Jsc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "sys")]
|
||||||
|
{
|
||||||
|
#[cfg(feature = "cranelift")]
|
||||||
|
{
|
||||||
|
return Self::Cranelift;
|
||||||
|
}
|
||||||
|
#[cfg(feature = "singlepass")]
|
||||||
|
{
|
||||||
|
return Self::Singlepass;
|
||||||
|
}
|
||||||
|
#[cfg(feature = "llvm")]
|
||||||
|
{
|
||||||
|
return Self::LLVM;
|
||||||
|
}
|
||||||
|
return Self::Headless;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "wamr")]
|
||||||
|
{
|
||||||
|
return Self::Wamr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "wasmi")]
|
||||||
|
{
|
||||||
|
return Self::Wasmi;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "v8")]
|
||||||
|
{
|
||||||
|
return Self::V8;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "js")]
|
||||||
|
{
|
||||||
|
return Self::Js;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "jsc")]
|
||||||
|
{
|
||||||
|
return Self::Jsc;
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("No runtime enabled!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ pub fn get_default_compiler_config() -> Option<Box<dyn wasmer_compiler::Compiler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the default engine for the Sys engine
|
/// Returns the default engine for the Sys engine
|
||||||
pub(crate) fn default_engine() -> Engine {
|
pub fn default_engine() -> Engine {
|
||||||
#[allow(unreachable_code, unused_mut)]
|
#[allow(unreachable_code, unused_mut)]
|
||||||
fn get_engine() -> Engine {
|
fn get_engine() -> Engine {
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
|
|||||||
@@ -33,12 +33,28 @@ impl Memory {
|
|||||||
let mut store_mut = store.as_store_mut();
|
let mut store_mut = store.as_store_mut();
|
||||||
let v8_store = store_mut.inner.store.as_v8();
|
let v8_store = store_mut.inner.store.as_v8();
|
||||||
|
|
||||||
|
let max_requested = ty.maximum.unwrap_or(Pages::max_value());
|
||||||
|
|
||||||
|
let min = ty.minimum.0;
|
||||||
|
let max = max_requested.0;
|
||||||
|
|
||||||
|
if max < min {
|
||||||
|
return Err(MemoryError::InvalidMemory {
|
||||||
|
reason: format!("the maximum ({max} pages) is less than the minimum ({min} pages)",),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let max_allowed = Pages::max_value();
|
||||||
|
if max_requested > max_allowed {
|
||||||
|
return Err(MemoryError::MaximumMemoryTooLarge {
|
||||||
|
max_requested,
|
||||||
|
max_allowed,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let limits = Box::into_raw(Box::new(wasm_limits_t {
|
let limits = Box::into_raw(Box::new(wasm_limits_t {
|
||||||
min: ty.minimum.0,
|
min,
|
||||||
max: match ty.maximum {
|
max,
|
||||||
Some(v) => v.0,
|
|
||||||
None => wasm_limits_max_default,
|
|
||||||
},
|
|
||||||
shared: ty.shared,
|
shared: ty.shared,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ impl Module {
|
|||||||
let off = usize::from_ne_bytes(off.try_into().unwrap());
|
let off = usize::from_ne_bytes(off.try_into().unwrap());
|
||||||
let name_bytes = &binary[8..(8 + off)];
|
let name_bytes = &binary[8..(8 + off)];
|
||||||
let name = String::from_utf8_lossy(name_bytes).to_string();
|
let name = String::from_utf8_lossy(name_bytes).to_string();
|
||||||
let mod_bytes = &binary[off..];
|
let mod_bytes = &binary[(8 + off)..];
|
||||||
let module = ModuleHandle::deserialize(engine, mod_bytes)?;
|
let module = ModuleHandle::deserialize(engine, mod_bytes)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@@ -275,7 +275,12 @@ impl Module {
|
|||||||
|
|
||||||
wasm_module_imports(module as *const _, &mut imports as *mut _);
|
wasm_module_imports(module as *const _, &mut imports as *mut _);
|
||||||
|
|
||||||
let imports = std::slice::from_raw_parts(imports.data, imports.size).to_vec();
|
let imports =
|
||||||
|
if imports.data.is_null() || !imports.data.is_aligned() || imports.size == 0 {
|
||||||
|
vec![]
|
||||||
|
} else {
|
||||||
|
std::slice::from_raw_parts(imports.data, imports.size).to_vec()
|
||||||
|
};
|
||||||
let mut wasmer_imports = vec![];
|
let mut wasmer_imports = vec![];
|
||||||
|
|
||||||
for i in imports.into_iter() {
|
for i in imports.into_iter() {
|
||||||
@@ -287,9 +292,17 @@ impl Module {
|
|||||||
let name = std::slice::from_raw_parts((*name).data as *const u8, (*name).size);
|
let name = std::slice::from_raw_parts((*name).data as *const u8, (*name).size);
|
||||||
let name_str = String::from_utf8_lossy(name).to_string();
|
let name_str = String::from_utf8_lossy(name).to_string();
|
||||||
let module = wasm_importtype_module(i as *const _);
|
let module = wasm_importtype_module(i as *const _);
|
||||||
let module =
|
let module_str = if module.is_null()
|
||||||
std::slice::from_raw_parts((*module).data as *const u8, (*module).size);
|
|| (*module).data.is_null()
|
||||||
let module_str = String::from_utf8_lossy(module).to_string();
|
|| !(*module).data.is_aligned()
|
||||||
|
|| (*module).size == 0
|
||||||
|
{
|
||||||
|
String::new()
|
||||||
|
} else {
|
||||||
|
let str =
|
||||||
|
std::slice::from_raw_parts((*module).data as *const u8, (*module).size);
|
||||||
|
String::from_utf8_lossy(str).to_string()
|
||||||
|
};
|
||||||
|
|
||||||
let ty = IntoWasmerExternType::into_wextt(wasm_importtype_type(i as *const _));
|
let ty = IntoWasmerExternType::into_wextt(wasm_importtype_type(i as *const _));
|
||||||
if ty.is_err() {
|
if ty.is_err() {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//! Data types, functions and traits for the `sys` runtime.
|
//! Data types, functions and traits for the `v8` backend.
|
||||||
|
|
||||||
pub(crate) mod bindings;
|
pub(crate) mod bindings;
|
||||||
pub(crate) mod entities;
|
pub(crate) mod entities;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
//! Data types, functions and traits for `wamr`'s `Instance` implementation.
|
//! Data types, functions and traits for `wamr`'s `Instance` implementation.
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::entities::external::VMExternToExtern;
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::wamr::bindings::*, vm::VMExtern, wamr::error::Trap, AsStoreMut, AsStoreRef, Exports,
|
backend::wamr::bindings::*, vm::VMExtern, wamr::error::Trap, AsStoreMut, AsStoreRef, Exports,
|
||||||
Extern, Imports, InstantiationError, Module,
|
Extern, Imports, InstantiationError, Module,
|
||||||
@@ -39,17 +40,7 @@ impl InstanceHandle {
|
|||||||
|
|
||||||
std::mem::forget(externs);
|
std::mem::forget(externs);
|
||||||
|
|
||||||
let stack_size = 2 * 1024 * 1024;
|
wasm_instance_new(store, module, &mut imports, &mut trap)
|
||||||
let heap_size = 2 * 1024 * 1024;
|
|
||||||
|
|
||||||
wasm_instance_new_with_args(
|
|
||||||
store,
|
|
||||||
module,
|
|
||||||
&mut imports,
|
|
||||||
&mut trap,
|
|
||||||
stack_size,
|
|
||||||
heap_size,
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if instance.is_null() {
|
if instance.is_null() {
|
||||||
@@ -61,29 +52,66 @@ impl InstanceHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_exports(&self, mut store: &mut impl AsStoreMut, module: &Module) -> Exports {
|
fn get_exports(&self, mut store: &mut impl AsStoreMut, module: &Module) -> Exports {
|
||||||
let mut exports = unsafe {
|
let mut c_api_externs = unsafe {
|
||||||
let mut vec = Default::default();
|
let mut vec = Default::default();
|
||||||
wasm_instance_exports(self.0, &mut vec);
|
wasm_instance_exports(self.0, &mut vec);
|
||||||
vec
|
vec
|
||||||
};
|
};
|
||||||
|
|
||||||
let wasm_exports: &[*mut wasm_extern_t] =
|
let c_api_externs: Vec<*mut wasm_extern_t> = if c_api_externs.data.is_null()
|
||||||
unsafe { std::slice::from_raw_parts(exports.data, exports.size) };
|
|| !c_api_externs.data.is_aligned()
|
||||||
|
|| c_api_externs.size == 0
|
||||||
|
{
|
||||||
|
vec![]
|
||||||
|
} else {
|
||||||
|
unsafe { std::slice::from_raw_parts(c_api_externs.data, c_api_externs.size) }.to_vec()
|
||||||
|
};
|
||||||
|
let c_api_externs = c_api_externs.to_vec();
|
||||||
|
let mut exports = unsafe {
|
||||||
|
let mut vec = Default::default();
|
||||||
|
wasm_module_exports(module.as_wamr().handle.inner, &mut vec);
|
||||||
|
vec
|
||||||
|
};
|
||||||
|
|
||||||
let exports_ty = module.exports().collect::<Vec<_>>();
|
let c_api_exports: Vec<*mut wasm_exporttype_t> =
|
||||||
let exports = exports_ty
|
if exports.data.is_null() || !exports.data.is_aligned() || exports.size == 0 {
|
||||||
.iter()
|
vec![]
|
||||||
.zip(wasm_exports.into_iter())
|
} else {
|
||||||
.map(|(export_type, wasm_export)| {
|
unsafe { std::slice::from_raw_parts(exports.data, exports.size) }.to_vec()
|
||||||
let name = export_type.name();
|
};
|
||||||
let mut store = store.as_store_mut();
|
|
||||||
let extern_type = export_type.ty();
|
|
||||||
// Annotation is here to prevent spurious IDE warnings.
|
|
||||||
|
|
||||||
let extern_ = Extern::from_vm_extern(&mut store, VMExtern::Wamr(*wasm_export));
|
// We need to use the order of the exports from the polyfill info to get the right
|
||||||
(name.to_string(), extern_)
|
// one, i.e. the from the declaration.
|
||||||
|
let module_exports = module.exports().collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let c_api_exports: Exports = c_api_exports
|
||||||
|
.into_iter()
|
||||||
|
.zip(c_api_externs.into_iter())
|
||||||
|
.map(|(export, ext)| unsafe {
|
||||||
|
let name = wasm_exporttype_name(export);
|
||||||
|
let name = std::slice::from_raw_parts((*name).data as *const u8, (*name).size);
|
||||||
|
let mut name = name.to_vec();
|
||||||
|
// Remove the '\0' at the end of the NULL-terminated string.
|
||||||
|
name.pop();
|
||||||
|
let name = String::from_utf8(name.to_vec()).unwrap_or_default();
|
||||||
|
let ext = ext.to_extern(&mut store);
|
||||||
|
(name, ext)
|
||||||
})
|
})
|
||||||
.collect::<Exports>();
|
.collect();
|
||||||
|
|
||||||
|
let mut exports = Exports::new();
|
||||||
|
|
||||||
|
for e in module_exports {
|
||||||
|
let ext: Extern = c_api_exports
|
||||||
|
.get::<Extern>(e.name())
|
||||||
|
.expect(&format!(
|
||||||
|
"c_api_exports: {c_api_exports:?} (name: {})",
|
||||||
|
e.name()
|
||||||
|
))
|
||||||
|
.clone();
|
||||||
|
exports.insert(e.name().to_string(), ext);
|
||||||
|
}
|
||||||
|
|
||||||
exports
|
exports
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,7 @@ use wasmer_types::{MemoryType, Pages, WASM_PAGE_SIZE};
|
|||||||
use crate::{
|
use crate::{
|
||||||
shared::SharedMemory,
|
shared::SharedMemory,
|
||||||
vm::{VMExtern, VMExternMemory},
|
vm::{VMExtern, VMExternMemory},
|
||||||
wamr::{
|
wamr::{bindings::*, vm::VMMemory},
|
||||||
bindings::{
|
|
||||||
wasm_limits_max_default, wasm_limits_t, wasm_memory_as_extern, wasm_memory_copy,
|
|
||||||
wasm_memory_new, wasm_memory_type, wasm_memorytype_limits, wasm_memorytype_new,
|
|
||||||
wasm_memorytype_t,
|
|
||||||
},
|
|
||||||
vm::VMMemory,
|
|
||||||
},
|
|
||||||
AsStoreMut, AsStoreRef, BackendMemory, MemoryAccessError,
|
AsStoreMut, AsStoreRef, BackendMemory, MemoryAccessError,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -34,14 +27,28 @@ unsafe impl Sync for Memory {}
|
|||||||
|
|
||||||
impl Memory {
|
impl Memory {
|
||||||
pub fn new(store: &mut impl AsStoreMut, ty: MemoryType) -> Result<Self, MemoryError> {
|
pub fn new(store: &mut impl AsStoreMut, ty: MemoryType) -> Result<Self, MemoryError> {
|
||||||
let limits = Box::into_raw(Box::new(wasm_limits_t {
|
let max_requested = ty.maximum.unwrap_or(Pages::max_value());
|
||||||
min: ty.minimum.0,
|
|
||||||
max: match ty.maximum {
|
|
||||||
Some(v) => v.0,
|
|
||||||
None => wasm_limits_max_default,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
let min = ty.minimum.0;
|
||||||
|
let max = max_requested.0;
|
||||||
|
|
||||||
|
if max < min {
|
||||||
|
return Err(MemoryError::InvalidMemory {
|
||||||
|
reason: format!("the maximum ({max} pages) is less than the minimum ({min} pages)",),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let max_allowed = Pages::max_value();
|
||||||
|
if max_requested > max_allowed {
|
||||||
|
return Err(MemoryError::MaximumMemoryTooLarge {
|
||||||
|
max_requested,
|
||||||
|
max_allowed,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let limits = Box::into_raw(Box::new(wasm_limits_t { min, max }));
|
||||||
|
|
||||||
|
eprintln!("limits: {limits:?}");
|
||||||
let memorytype = unsafe { wasm_memorytype_new(limits) };
|
let memorytype = unsafe { wasm_memorytype_new(limits) };
|
||||||
|
|
||||||
let mut store = store.as_store_mut();
|
let mut store = store.as_store_mut();
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
//! Data types, functions and traits for `wamr`'s `Module` implementation.
|
//! Data types, functions and traits for `wamr`'s `Module` implementation.
|
||||||
use std::{path::Path, sync::Arc};
|
use std::{path::Path, sync::Arc};
|
||||||
|
|
||||||
use crate::{
|
use crate::{backend::wamr::bindings::*, AsEngineRef, BackendModule, IntoBytes};
|
||||||
backend::wamr::bindings::{
|
|
||||||
wasm_byte_vec_t, wasm_module_delete, wasm_module_new, wasm_module_t,
|
|
||||||
},
|
|
||||||
AsEngineRef, BackendModule, IntoBytes,
|
|
||||||
};
|
|
||||||
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use wasmer_types::{
|
use wasmer_types::{
|
||||||
@@ -97,8 +92,25 @@ impl Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn validate(engine: &impl AsEngineRef, binary: &[u8]) -> Result<(), CompileError> {
|
pub fn validate(engine: &impl AsEngineRef, binary: &[u8]) -> Result<(), CompileError> {
|
||||||
let engine = engine.as_engine_ref();
|
let engine = engine.as_engine_ref().engine().clone();
|
||||||
unimplemented!();
|
let store = super::store::Store::new(engine);
|
||||||
|
let bytes = wasm_byte_vec_t {
|
||||||
|
size: binary.len(),
|
||||||
|
data: binary.as_ptr() as _,
|
||||||
|
num_elems: binary.len(),
|
||||||
|
size_of_elem: 1,
|
||||||
|
lock: std::ptr::null_mut(),
|
||||||
|
};
|
||||||
|
let store = store.inner;
|
||||||
|
unsafe {
|
||||||
|
if !wasm_module_validate(store, &bytes as *const _) {
|
||||||
|
return Err(CompileError::Validate(String::from(
|
||||||
|
"WAMR could not validate the given module",
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> Option<&str> {
|
pub fn name(&self) -> Option<&str> {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//! Data types, functions and traits for `wamr`.
|
//! Data types, functions and traits for the `wamr` backend.
|
||||||
|
|
||||||
pub(crate) mod bindings;
|
pub(crate) mod bindings;
|
||||||
pub(crate) mod entities;
|
pub(crate) mod entities;
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::wasmi::bindings::*, vm::VMExtern, wasmi::error::Trap, AsStoreMut, AsStoreRef, Exports,
|
backend::wasmi::bindings::*, entities::external::VMExternToExtern, vm::VMExtern,
|
||||||
Extern, Imports, InstantiationError, Module,
|
wasmi::error::Trap, AsStoreMut, AsStoreRef, Exports, Extern, Imports, InstantiationError,
|
||||||
|
Module,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq)]
|
||||||
@@ -51,29 +52,48 @@ impl InstanceHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_exports(&self, mut store: &mut impl AsStoreMut, module: &Module) -> Exports {
|
fn get_exports(&self, mut store: &mut impl AsStoreMut, module: &Module) -> Exports {
|
||||||
let mut exports = unsafe {
|
let mut c_api_externs = unsafe {
|
||||||
let mut vec = Default::default();
|
let mut vec = Default::default();
|
||||||
wasm_instance_exports(self.0, &mut vec);
|
wasm_instance_exports(self.0, &mut vec);
|
||||||
vec
|
vec
|
||||||
};
|
};
|
||||||
|
|
||||||
let wasm_exports: &[*mut wasm_extern_t] =
|
let c_api_externs: &[*mut wasm_extern_t] =
|
||||||
|
unsafe { std::slice::from_raw_parts(c_api_externs.data, c_api_externs.size) };
|
||||||
|
let c_api_externs = c_api_externs.to_vec();
|
||||||
|
let mut exports = unsafe {
|
||||||
|
let mut vec = Default::default();
|
||||||
|
wasm_module_exports(module.as_wasmi().handle.inner, &mut vec);
|
||||||
|
vec
|
||||||
|
};
|
||||||
|
|
||||||
|
let c_api_exports: &[*mut wasm_exporttype_t] =
|
||||||
unsafe { std::slice::from_raw_parts(exports.data, exports.size) };
|
unsafe { std::slice::from_raw_parts(exports.data, exports.size) };
|
||||||
|
let c_api_exports = c_api_exports.to_vec();
|
||||||
|
|
||||||
let exports_ty = module.exports().collect::<Vec<_>>();
|
// We need to use the order of the exports from the polyfill info to get the right
|
||||||
let exports = exports_ty
|
// one, i.e. the from the declaration.
|
||||||
.iter()
|
let module_exports = module.exports().collect::<Vec<_>>();
|
||||||
.zip(wasm_exports.into_iter())
|
|
||||||
.map(|(export_type, wasm_export)| {
|
|
||||||
let name = export_type.name();
|
|
||||||
let mut store = store.as_store_mut();
|
|
||||||
let extern_type = export_type.ty();
|
|
||||||
// Annotation is here to prevent spurious IDE warnings.
|
|
||||||
|
|
||||||
let extern_ = Extern::from_vm_extern(&mut store, VMExtern::Wasmi(*wasm_export));
|
let c_api_exports: Exports = c_api_exports
|
||||||
(name.to_string(), extern_)
|
.into_iter()
|
||||||
|
.zip(c_api_externs.into_iter())
|
||||||
|
.map(|(export, ext)| unsafe {
|
||||||
|
let name = wasm_exporttype_name(export);
|
||||||
|
let name = std::slice::from_raw_parts((*name).data as *const u8, (*name).size);
|
||||||
|
let name = String::from_utf8(name.to_vec()).unwrap_or_default();
|
||||||
|
let ext = ext.to_extern(&mut store);
|
||||||
|
(name, ext)
|
||||||
})
|
})
|
||||||
.collect::<Exports>();
|
.collect();
|
||||||
|
|
||||||
|
let mut exports = Exports::new();
|
||||||
|
|
||||||
|
for e in module_exports {
|
||||||
|
let ext: Extern = c_api_exports.get::<Extern>(e.name()).unwrap().clone();
|
||||||
|
exports.insert(e.name().to_string(), ext);
|
||||||
|
}
|
||||||
|
|
||||||
exports
|
exports
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,13 +27,26 @@ unsafe impl Sync for Memory {}
|
|||||||
|
|
||||||
impl Memory {
|
impl Memory {
|
||||||
pub fn new(store: &mut impl AsStoreMut, ty: MemoryType) -> Result<Self, MemoryError> {
|
pub fn new(store: &mut impl AsStoreMut, ty: MemoryType) -> Result<Self, MemoryError> {
|
||||||
let limits = Box::into_raw(Box::new(wasm_limits_t {
|
let max_requested = ty.maximum.unwrap_or(Pages::max_value());
|
||||||
min: ty.minimum.0,
|
|
||||||
max: match ty.maximum {
|
let min = ty.minimum.0;
|
||||||
Some(v) => v.0,
|
let max = max_requested.0;
|
||||||
None => wasm_limits_max_default,
|
|
||||||
},
|
if max < min {
|
||||||
}));
|
return Err(MemoryError::InvalidMemory {
|
||||||
|
reason: format!("the maximum ({max} pages) is less than the minimum ({min} pages)",),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let max_allowed = Pages::max_value();
|
||||||
|
if max_requested > max_allowed {
|
||||||
|
return Err(MemoryError::MaximumMemoryTooLarge {
|
||||||
|
max_requested,
|
||||||
|
max_allowed,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let limits = Box::into_raw(Box::new(wasm_limits_t { min, max }));
|
||||||
|
|
||||||
let memorytype = unsafe { wasm_memorytype_new(limits) };
|
let memorytype = unsafe { wasm_memorytype_new(limits) };
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//! Data types, functions and traits for `wasmi`.
|
//! Data types, functions and traits for the `wasmi` backend.
|
||||||
|
|
||||||
pub(crate) mod bindings;
|
pub(crate) mod bindings;
|
||||||
pub(crate) mod entities;
|
pub(crate) mod entities;
|
||||||
|
|||||||
@@ -66,43 +66,76 @@ wasmer-inline-c = "0.1.1"
|
|||||||
inline-c = "0.1.7"
|
inline-c = "0.1.7"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["wat", "cranelift", "compiler", "wasi", "middlewares"]
|
default = ["wat", "sys-default", "cranelift", "compiler", "wasi", "middlewares"]
|
||||||
sys = []
|
|
||||||
jsc = ["wasmer-api/jsc", "wasmer-api/std"]
|
|
||||||
wat = ["wasmer-api/wat"]
|
wat = ["wasmer-api/wat"]
|
||||||
wasi = ["wasmer-wasix"]
|
wasi = ["wasmer-wasix"]
|
||||||
middlewares = ["compiler", "wasmer-middlewares"]
|
middlewares = ["compiler", "wasmer-middlewares"]
|
||||||
|
|
||||||
|
# Enable the `sys` backend.
|
||||||
|
sys = []
|
||||||
|
|
||||||
|
# Enable the `singlepass` compiler.
|
||||||
|
singlepass = [
|
||||||
|
"dep:wasmer-compiler-singlepass",
|
||||||
|
"wasmer-api/singlepass",
|
||||||
|
"compiler",
|
||||||
|
]
|
||||||
|
# Enable the `cranelift` compiler.
|
||||||
|
cranelift = [
|
||||||
|
"dep:wasmer-compiler-cranelift",
|
||||||
|
"wasmer-api/cranelift",
|
||||||
|
"compiler",
|
||||||
|
]
|
||||||
|
# Enable the `llvm` compiler.
|
||||||
|
llvm = ["dep:wasmer-compiler-llvm", "wasmer-api/llvm", "compiler"]
|
||||||
|
|
||||||
|
# Enable the use of compiler. Implies enabling the `sys` feature.
|
||||||
compiler = [
|
compiler = [
|
||||||
|
"sys",
|
||||||
"wasmer-compiler",
|
"wasmer-compiler",
|
||||||
"wasmer-api/compiler",
|
"wasmer-api/compiler",
|
||||||
"wasmer-compiler/translator",
|
"wasmer-compiler/translator",
|
||||||
"wasmer-compiler/compiler",
|
"wasmer-compiler/compiler",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Enable the use of the headless compiler. Implies enabling the `sys` feature.
|
||||||
compiler-headless = [
|
compiler-headless = [
|
||||||
|
"sys",
|
||||||
"wasmer-artifact-load",
|
"wasmer-artifact-load",
|
||||||
"static-artifact-load",
|
"static-artifact-load",
|
||||||
"wasmer-api/compiler",
|
"wasmer-api/compiler",
|
||||||
"wasmer-compiler/translator",
|
"wasmer-compiler/translator",
|
||||||
"wasmer-compiler/compiler",
|
"wasmer-compiler/compiler",
|
||||||
]
|
]
|
||||||
singlepass = ["wasmer-compiler-singlepass", "compiler"]
|
|
||||||
cranelift = ["wasmer-compiler-cranelift", "compiler"]
|
|
||||||
llvm = ["wasmer-compiler-llvm", "compiler"]
|
|
||||||
|
|
||||||
############
|
# Enable the `jsc` backend.
|
||||||
# WARNING! #
|
jsc = ["wasmer-api/jsc", "wasmer-api/std"]
|
||||||
############
|
|
||||||
# These features are here but, for now (wasmer 6.0.0-alpha1) they do nothing.
|
|
||||||
# In the next alpha release they will be wired up to use the matching backend.
|
|
||||||
# These features are being added now to make CI easier, since we will
|
|
||||||
# nonetheless have to add them later.
|
|
||||||
|
|
||||||
v8 = []
|
# Enable the `v8` backend.
|
||||||
wasmi = []
|
v8 = ["wasmer-api/v8"]
|
||||||
wamr = []
|
|
||||||
|
|
||||||
############
|
# Enable the `wasmi` backend.
|
||||||
############
|
wasmi = ["wasmer-api/wasmi"]
|
||||||
|
|
||||||
|
# Enable the `wamr` backend.
|
||||||
|
wamr = ["wasmer-api/wamr"]
|
||||||
|
|
||||||
|
# Enable the `sys` backend and use it as default. Notice that this does not
|
||||||
|
# enable a default compiler, and users should therefore add one (or more) of
|
||||||
|
# the `singlepass`, `cranelift` and `llvm` features.
|
||||||
|
sys-default = ["sys", "wasmer-api/sys-default"]
|
||||||
|
|
||||||
|
# Enable the `jsc` backend and use it as default.
|
||||||
|
jsc-default = ["jsc", "wasmer-api/jsc-default"]
|
||||||
|
|
||||||
|
# Enable the `v8` backend and use it as default.
|
||||||
|
v8-default = ["v8", "wasmer-api/v8-default"]
|
||||||
|
|
||||||
|
# Enable the `wamr` backend and use it as default.
|
||||||
|
wamr-default = ["wamr", "wasmer-api/wamr-default"]
|
||||||
|
|
||||||
|
# Enable the `wasmi` backend and use it as default.
|
||||||
|
wasmi-default = ["wasmi", "wasmer-api/wasmi-default"]
|
||||||
|
|
||||||
wasmer-artifact-load = ["wasmer-compiler/wasmer-artifact-load"]
|
wasmer-artifact-load = ["wasmer-compiler/wasmer-artifact-load"]
|
||||||
wasmer-artifact-create = ["wasmer-compiler/wasmer-artifact-create"]
|
wasmer-artifact-create = ["wasmer-compiler/wasmer-artifact-create"]
|
||||||
|
|||||||
@@ -25,7 +25,10 @@
|
|||||||
)]
|
)]
|
||||||
// Because this crate exposes a lot of C APIs which are unsafe by definition,
|
// Because this crate exposes a lot of C APIs which are unsafe by definition,
|
||||||
// we allow unsafe without explicit safety documentation for each of them.
|
// we allow unsafe without explicit safety documentation for each of them.
|
||||||
|
//
|
||||||
|
// For the same reason, we also turn off the warning for camel_case types.
|
||||||
#![allow(clippy::missing_safety_doc)]
|
#![allow(clippy::missing_safety_doc)]
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
|||||||
@@ -1,493 +0,0 @@
|
|||||||
pub use super::unstable::engine::wasm_config_set_features;
|
|
||||||
use super::unstable::features::wasmer_features_t;
|
|
||||||
use crate::error::update_last_error;
|
|
||||||
use cfg_if::cfg_if;
|
|
||||||
|
|
||||||
#[cfg(feature = "compiler")]
|
|
||||||
pub use super::unstable::engine::{wasm_config_set_target, wasmer_is_compiler_available};
|
|
||||||
#[cfg(any(feature = "compiler", feature = "compiler-headless"))]
|
|
||||||
use super::unstable::target_lexicon::wasmer_target_t;
|
|
||||||
|
|
||||||
#[cfg(feature = "middlewares")]
|
|
||||||
pub use super::unstable::middlewares::wasm_config_push_middleware;
|
|
||||||
#[cfg(feature = "middlewares")]
|
|
||||||
use super::unstable::middlewares::wasmer_middleware_t;
|
|
||||||
|
|
||||||
#[cfg(any(feature = "compiler", feature = "compiler-headless"))]
|
|
||||||
use wasmer_compiler::{Engine, EngineBuilder};
|
|
||||||
|
|
||||||
#[cfg(not(any(feature = "compiler", feature = "compiler-headless")))]
|
|
||||||
use wasmer_api::Engine;
|
|
||||||
|
|
||||||
/// Kind of compilers that can be used by the engines.
|
|
||||||
///
|
|
||||||
/// This is a Wasmer-specific type with Wasmer-specific functions for
|
|
||||||
/// manipulating it.
|
|
||||||
#[cfg(feature = "compiler")]
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
#[repr(C)]
|
|
||||||
pub enum wasmer_compiler_t {
|
|
||||||
/// Variant to represent the Cranelift compiler. See the
|
|
||||||
/// [`wasmer_compiler_cranelift`] Rust crate.
|
|
||||||
CRANELIFT = 0,
|
|
||||||
|
|
||||||
/// Variant to represent the LLVM compiler. See the
|
|
||||||
/// [`wasmer_compiler_llvm`] Rust crate.
|
|
||||||
LLVM = 1,
|
|
||||||
|
|
||||||
/// Variant to represent the Singlepass compiler. See the
|
|
||||||
/// [`wasmer_compiler_singlepass`] Rust crate.
|
|
||||||
SINGLEPASS = 2,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "compiler")]
|
|
||||||
impl Default for wasmer_compiler_t {
|
|
||||||
fn default() -> Self {
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(feature = "cranelift")] {
|
|
||||||
Self::CRANELIFT
|
|
||||||
} else if #[cfg(feature = "llvm")] {
|
|
||||||
Self::LLVM
|
|
||||||
} else if #[cfg(feature = "singlepass")] {
|
|
||||||
Self::SINGLEPASS
|
|
||||||
} else {
|
|
||||||
compile_error!("Please enable one of the compiler backends")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Kind of engines that can be used by the store.
|
|
||||||
///
|
|
||||||
/// This is a Wasmer-specific type with Wasmer-specific functions for
|
|
||||||
/// manipulating it.
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
#[repr(C)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum wasmer_engine_t {
|
|
||||||
/// Variant to represent the Universal engine. See the
|
|
||||||
/// [`wasmer_engine_universal`] Rust crate.
|
|
||||||
UNIVERSAL = 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for wasmer_engine_t {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::UNIVERSAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A configuration holds the compiler and the engine used by the store.
|
|
||||||
///
|
|
||||||
/// cbindgen:ignore
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct wasm_config_t {
|
|
||||||
engine: wasmer_engine_t,
|
|
||||||
#[cfg(feature = "compiler")]
|
|
||||||
compiler: wasmer_compiler_t,
|
|
||||||
#[cfg(feature = "middlewares")]
|
|
||||||
pub(super) middlewares: Vec<wasmer_middleware_t>,
|
|
||||||
pub(super) nan_canonicalization: bool,
|
|
||||||
pub(super) features: Option<Box<wasmer_features_t>>,
|
|
||||||
#[cfg(any(feature = "compiler", feature = "compiler-headless"))]
|
|
||||||
pub(super) target: Option<Box<wasmer_target_t>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new default Wasmer configuration.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// # use wasmer_inline_c::assert_c;
|
|
||||||
/// # fn main() {
|
|
||||||
/// # (assert_c! {
|
|
||||||
/// # #include "tests/wasmer.h"
|
|
||||||
/// #
|
|
||||||
/// int main() {
|
|
||||||
/// // Create the configuration.
|
|
||||||
/// wasm_config_t* config = wasm_config_new();
|
|
||||||
///
|
|
||||||
/// // Create the engine.
|
|
||||||
/// wasm_engine_t* engine = wasm_engine_new_with_config(config);
|
|
||||||
///
|
|
||||||
/// // Check we have an engine!
|
|
||||||
/// assert(engine);
|
|
||||||
///
|
|
||||||
/// // Free everything.
|
|
||||||
/// wasm_engine_delete(engine);
|
|
||||||
///
|
|
||||||
/// return 0;
|
|
||||||
/// }
|
|
||||||
/// # })
|
|
||||||
/// # .success();
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// cbindgen:ignore
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_config_new() -> Box<wasm_config_t> {
|
|
||||||
Box::<wasm_config_t>::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Delete a Wasmer config object.
|
|
||||||
///
|
|
||||||
/// This function does not need to be called if `wasm_engine_new_with_config` or
|
|
||||||
/// another function that takes ownership of the `wasm_config_t` is called.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// # use wasmer_inline_c::assert_c;
|
|
||||||
/// # fn main() {
|
|
||||||
/// # (assert_c! {
|
|
||||||
/// # #include "tests/wasmer.h"
|
|
||||||
/// #
|
|
||||||
/// int main() {
|
|
||||||
/// // Create the configuration.
|
|
||||||
/// wasm_config_t* config = wasm_config_new();
|
|
||||||
///
|
|
||||||
/// // Delete the configuration
|
|
||||||
/// wasm_config_delete(config);
|
|
||||||
///
|
|
||||||
/// return 0;
|
|
||||||
/// }
|
|
||||||
/// # })
|
|
||||||
/// # .success();
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
/// cbindgen:ignore
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_config_delete(_config: Option<Box<wasm_config_t>>) {}
|
|
||||||
|
|
||||||
/// Updates the configuration to specify a particular compiler to use.
|
|
||||||
///
|
|
||||||
/// This is a Wasmer-specific function.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// # use wasmer_inline_c::assert_c;
|
|
||||||
/// # fn main() {
|
|
||||||
/// # (assert_c! {
|
|
||||||
/// # #include "tests/wasmer.h"
|
|
||||||
/// #
|
|
||||||
/// int main() {
|
|
||||||
/// // Create the configuration.
|
|
||||||
/// wasm_config_t* config = wasm_config_new();
|
|
||||||
///
|
|
||||||
/// // Use the Cranelift compiler, if available.
|
|
||||||
/// if (wasmer_is_compiler_available(CRANELIFT)) {
|
|
||||||
/// wasm_config_set_compiler(config, CRANELIFT);
|
|
||||||
/// }
|
|
||||||
/// // Or maybe LLVM?
|
|
||||||
/// else if (wasmer_is_compiler_available(LLVM)) {
|
|
||||||
/// wasm_config_set_compiler(config, LLVM);
|
|
||||||
/// }
|
|
||||||
/// // Or maybe Singlepass?
|
|
||||||
/// else if (wasmer_is_compiler_available(SINGLEPASS)) {
|
|
||||||
/// wasm_config_set_compiler(config, SINGLEPASS);
|
|
||||||
/// }
|
|
||||||
/// // OK, let's run with no particular compiler.
|
|
||||||
///
|
|
||||||
/// // Create the engine.
|
|
||||||
/// wasm_engine_t* engine = wasm_engine_new_with_config(config);
|
|
||||||
///
|
|
||||||
/// // Check we have an engine!
|
|
||||||
/// assert(engine);
|
|
||||||
///
|
|
||||||
/// // Free everything.
|
|
||||||
/// wasm_engine_delete(engine);
|
|
||||||
///
|
|
||||||
/// return 0;
|
|
||||||
/// }
|
|
||||||
/// # })
|
|
||||||
/// # .success();
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
#[cfg(feature = "compiler")]
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_config_set_compiler(
|
|
||||||
config: &mut wasm_config_t,
|
|
||||||
compiler: wasmer_compiler_t,
|
|
||||||
) {
|
|
||||||
config.compiler = compiler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Updates the configuration to specify a particular engine to use.
|
|
||||||
///
|
|
||||||
/// This is a Wasmer-specific function.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// # use wasmer_inline_c::assert_c;
|
|
||||||
/// # fn main() {
|
|
||||||
/// # (assert_c! {
|
|
||||||
/// # #include "tests/wasmer.h"
|
|
||||||
/// #
|
|
||||||
/// int main() {
|
|
||||||
/// // Create the configuration.
|
|
||||||
/// wasm_config_t* config = wasm_config_new();
|
|
||||||
///
|
|
||||||
/// // Create the engine.
|
|
||||||
/// wasm_engine_t* engine = wasm_engine_new_with_config(config);
|
|
||||||
///
|
|
||||||
/// // Check we have an engine!
|
|
||||||
/// assert(engine);
|
|
||||||
///
|
|
||||||
/// // Free everything.
|
|
||||||
/// wasm_engine_delete(engine);
|
|
||||||
///
|
|
||||||
/// return 0;
|
|
||||||
/// }
|
|
||||||
/// # })
|
|
||||||
/// # .success();
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_config_set_engine(config: &mut wasm_config_t, engine: wasmer_engine_t) {
|
|
||||||
config.engine = engine;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An engine is used by the store to drive the compilation and the
|
|
||||||
/// execution of a WebAssembly module.
|
|
||||||
///
|
|
||||||
/// cbindgen:ignore
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct wasm_engine_t {
|
|
||||||
pub(crate) inner: Engine,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "compiler")]
|
|
||||||
use wasmer_api::sys::CompilerConfig;
|
|
||||||
|
|
||||||
#[cfg(feature = "compiler")]
|
|
||||||
fn get_default_compiler_config() -> Box<dyn CompilerConfig> {
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(feature = "cranelift")] {
|
|
||||||
Box::<wasmer_compiler_cranelift::Cranelift>::default()
|
|
||||||
} else if #[cfg(feature = "llvm")] {
|
|
||||||
Box::<wasmer_compiler_llvm::LLVM>::default()
|
|
||||||
} else if #[cfg(feature = "singlepass")] {
|
|
||||||
Box::<wasmer_compiler_singlepass::Singlepass>::default()
|
|
||||||
} else {
|
|
||||||
compile_error!("Please enable one of the compiler backends")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(feature = "compiler")] {
|
|
||||||
/// Creates a new Universal engine with the default compiler.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// See [`wasm_engine_delete`].
|
|
||||||
///
|
|
||||||
/// cbindgen:ignore
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_engine_new() -> Box<wasm_engine_t> {
|
|
||||||
let compiler_config: Box<dyn CompilerConfig> = get_default_compiler_config();
|
|
||||||
let engine: Engine = EngineBuilder::new(compiler_config).engine();
|
|
||||||
Box::new(wasm_engine_t { inner: engine })
|
|
||||||
}
|
|
||||||
} else if #[cfg(feature = "compiler-headless")] {
|
|
||||||
/// Creates a new headless Universal engine.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// See [`wasm_engine_delete`].
|
|
||||||
///
|
|
||||||
/// cbindgen:ignore
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_engine_new() -> Box<wasm_engine_t> {
|
|
||||||
let engine: Engine = EngineBuilder::headless().engine();
|
|
||||||
Box::new(wasm_engine_t { inner: engine })
|
|
||||||
}
|
|
||||||
} else if #[cfg(feature = "jsc")] {
|
|
||||||
/// Creates the JavascriptCore Engine.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// See [`wasm_engine_delete`].
|
|
||||||
///
|
|
||||||
/// cbindgen:ignore
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_engine_new() -> Box<wasm_engine_t> {
|
|
||||||
let engine: Engine = Engine::default();
|
|
||||||
Box::new(wasm_engine_t { inner: engine })
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/// Creates a new unknown engine, i.e. it will panic with an error message.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// See [`wasm_engine_delete`].
|
|
||||||
///
|
|
||||||
/// cbindgen:ignore
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_engine_new() -> Box<wasm_engine_t> {
|
|
||||||
unimplemented!("No engine attached; You might want to recompile `wasmer_c_api` with for example `--feature compiler`");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Deletes an engine.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// # use wasmer_inline_c::assert_c;
|
|
||||||
/// # fn main() {
|
|
||||||
/// # (assert_c! {
|
|
||||||
/// # #include "tests/wasmer.h"
|
|
||||||
/// #
|
|
||||||
/// int main() {
|
|
||||||
/// // Create a default engine.
|
|
||||||
/// wasm_engine_t* engine = wasm_engine_new();
|
|
||||||
///
|
|
||||||
/// // Check we have an engine!
|
|
||||||
/// assert(engine);
|
|
||||||
///
|
|
||||||
/// // Free everything.
|
|
||||||
/// wasm_engine_delete(engine);
|
|
||||||
///
|
|
||||||
/// return 0;
|
|
||||||
/// }
|
|
||||||
/// # })
|
|
||||||
/// # .success();
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// cbindgen:ignore
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_engine_delete(_engine: Option<Box<wasm_engine_t>>) {}
|
|
||||||
|
|
||||||
/// Creates an engine with a particular configuration.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// See [`wasm_config_new`].
|
|
||||||
///
|
|
||||||
/// cbindgen:ignore
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_engine_new_with_config(
|
|
||||||
config: Option<Box<wasm_config_t>>,
|
|
||||||
) -> Option<Box<wasm_engine_t>> {
|
|
||||||
#[allow(dead_code)]
|
|
||||||
fn return_with_error(msg: &str) -> Option<Box<wasm_engine_t>> {
|
|
||||||
update_last_error(msg);
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
let config = config?;
|
|
||||||
//#[cfg(not(any(feature = "compiler", feature = "compiler-headless")))]
|
|
||||||
//return return_with_error("Wasmer has not been compiled with the `compiler` feature.");
|
|
||||||
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(feature = "compiler")] {
|
|
||||||
#[allow(unused_mut)]
|
|
||||||
let mut compiler_config: Box<dyn CompilerConfig> = match config.compiler {
|
|
||||||
wasmer_compiler_t::CRANELIFT => {
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(feature = "cranelift")] {
|
|
||||||
Box::<wasmer_compiler_cranelift::Cranelift>::default()
|
|
||||||
} else {
|
|
||||||
return return_with_error("Wasmer has not been compiled with the `cranelift` feature.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
wasmer_compiler_t::LLVM => {
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(feature = "llvm")] {
|
|
||||||
Box::<wasmer_compiler_llvm::LLVM>::default()
|
|
||||||
} else {
|
|
||||||
return return_with_error("Wasmer has not been compiled with the `llvm` feature.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
wasmer_compiler_t::SINGLEPASS => {
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(feature = "singlepass")] {
|
|
||||||
Box::<wasmer_compiler_singlepass::Singlepass>::default()
|
|
||||||
} else {
|
|
||||||
return return_with_error("Wasmer has not been compiled with the `singlepass` feature.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(feature = "middlewares")]
|
|
||||||
for middleware in config.middlewares {
|
|
||||||
compiler_config.push_middleware(middleware.inner);
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.nan_canonicalization {
|
|
||||||
compiler_config.canonicalize_nans(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
let inner: Engine =
|
|
||||||
{
|
|
||||||
let mut builder = EngineBuilder::new(compiler_config);
|
|
||||||
|
|
||||||
if let Some(target) = config.target {
|
|
||||||
builder = builder.set_target(Some(target.inner));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(features) = config.features {
|
|
||||||
builder = builder.set_features(Some(features.inner));
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.engine()
|
|
||||||
};
|
|
||||||
Some(Box::new(wasm_engine_t { inner }))
|
|
||||||
} else {
|
|
||||||
#[cfg(feature = "compiler-headless")]
|
|
||||||
let inner: Engine =
|
|
||||||
{
|
|
||||||
let mut builder = EngineBuilder::headless();
|
|
||||||
|
|
||||||
if let Some(target) = config.target {
|
|
||||||
builder = builder.set_target(Some(target.inner));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(features) = config.features {
|
|
||||||
builder = builder.set_features(Some(features.inner));
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.engine()
|
|
||||||
};
|
|
||||||
#[cfg(not(any(feature = "compiler-headless", feature="compiler")))]
|
|
||||||
let inner: Engine = Engine::default();
|
|
||||||
|
|
||||||
Some(Box::new(wasm_engine_t { inner }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
|
||||||
use inline_c::assert_c;
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
use wasmer_inline_c::assert_c;
|
|
||||||
|
|
||||||
#[cfg_attr(coverage, ignore)]
|
|
||||||
#[test]
|
|
||||||
fn test_engine_new() {
|
|
||||||
(assert_c! {
|
|
||||||
#include "tests/wasmer.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
wasm_engine_t* engine = wasm_engine_new();
|
|
||||||
assert(engine);
|
|
||||||
|
|
||||||
wasm_engine_delete(engine);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.success();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
38
lib/c-api/src/wasm_c_api/engine/config/jsc.rs
Normal file
38
lib/c-api/src/wasm_c_api/engine/config/jsc.rs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
use crate::{
|
||||||
|
error::update_last_error,
|
||||||
|
wasm_c_api::engine::{wasm_config_t, wasm_engine_t, wasmer_backend_t},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::wasmer_backend_config_kind_t;
|
||||||
|
|
||||||
|
/// Configuration specific for the `jsc` engine.
|
||||||
|
///
|
||||||
|
/// This is a Wasmer-specific type with Wasmer-specific functions for
|
||||||
|
/// manipulating it.
|
||||||
|
///
|
||||||
|
/// cbindgen:ignore
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub(crate) struct wasmer_jsc_engine_config_t;
|
||||||
|
|
||||||
|
/// Create a new [`wasm_engine_t`] backed by a `jsc` engine.
|
||||||
|
pub(crate) fn wasm_jsc_engine_new_with_config(config: wasm_config_t) -> Option<Box<wasm_engine_t>> {
|
||||||
|
if !matches!(config.backend, wasmer_backend_t::JSC) || !config.backend_config.inner.is_jsc() {
|
||||||
|
update_last_error("Cannot create a new `jsc` engine with a non-jsc-specific config!");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(Box::new(wasm_engine_t {
|
||||||
|
inner: wasmer_api::jsc::Engine::default().into(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
impl wasmer_backend_config_kind_t {
|
||||||
|
/// Returns `true` if the wasmer_engine_config_t is [`Jsc`].
|
||||||
|
///
|
||||||
|
/// [`Jsc`]: wasmer_engine_config_t::Jsc
|
||||||
|
#[must_use]
|
||||||
|
pub(super) fn is_jsc(&self) -> bool {
|
||||||
|
matches!(self, Self::Jsc(..))
|
||||||
|
}
|
||||||
|
}
|
||||||
145
lib/c-api/src/wasm_c_api/engine/config/mod.rs
Normal file
145
lib/c-api/src/wasm_c_api/engine/config/mod.rs
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
#[cfg(feature = "sys")]
|
||||||
|
pub(crate) mod sys;
|
||||||
|
#[cfg(feature = "sys")]
|
||||||
|
pub use sys::*;
|
||||||
|
|
||||||
|
use crate::wasm_c_api::unstable::target_lexicon::wasmer_target_t;
|
||||||
|
|
||||||
|
use super::{wasm_config_t, wasmer_backend_t};
|
||||||
|
|
||||||
|
#[cfg(feature = "jsc")]
|
||||||
|
pub(crate) mod jsc;
|
||||||
|
|
||||||
|
#[cfg(feature = "v8")]
|
||||||
|
pub(crate) mod v8;
|
||||||
|
|
||||||
|
#[cfg(feature = "wasmi")]
|
||||||
|
pub(crate) mod wasmi;
|
||||||
|
|
||||||
|
#[cfg(feature = "wamr")]
|
||||||
|
pub(crate) mod wamr;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) enum wasmer_backend_config_kind_t {
|
||||||
|
#[cfg(feature = "sys")]
|
||||||
|
Sys(sys::wasmer_sys_engine_config_t),
|
||||||
|
|
||||||
|
#[cfg(feature = "jsc")]
|
||||||
|
Jsc(jsc::wasmer_jsc_engine_config_t),
|
||||||
|
|
||||||
|
#[cfg(feature = "v8")]
|
||||||
|
V8(v8::wasmer_v8_engine_config_t),
|
||||||
|
|
||||||
|
#[cfg(feature = "wasmi")]
|
||||||
|
Wasmi(wasmi::wasmer_wasmi_engine_config_t),
|
||||||
|
|
||||||
|
#[cfg(feature = "wamr")]
|
||||||
|
Wamr(wamr::wasmer_wamr_engine_config_t),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for wasmer_backend_config_kind_t {
|
||||||
|
fn default() -> Self {
|
||||||
|
match wasmer_backend_t::default() {
|
||||||
|
#[cfg(feature = "llvm")]
|
||||||
|
super::wasmer_backend_t::LLVM => Self::Sys(sys::wasmer_sys_engine_config_t::default()),
|
||||||
|
#[cfg(feature = "cranelift")]
|
||||||
|
super::wasmer_backend_t::CRANELIFT => {
|
||||||
|
Self::Sys(sys::wasmer_sys_engine_config_t::default())
|
||||||
|
}
|
||||||
|
#[cfg(feature = "singlepass")]
|
||||||
|
super::wasmer_backend_t::SINGLEPASS => {
|
||||||
|
Self::Sys(sys::wasmer_sys_engine_config_t::default())
|
||||||
|
}
|
||||||
|
#[cfg(feature = "sys")]
|
||||||
|
super::wasmer_backend_t::HEADLESS => {
|
||||||
|
Self::Sys(sys::wasmer_sys_engine_config_t::default())
|
||||||
|
}
|
||||||
|
#[cfg(feature = "v8")]
|
||||||
|
super::wasmer_backend_t::V8 => Self::V8(v8::wasmer_v8_engine_config_t::default()),
|
||||||
|
#[cfg(feature = "wasmi")]
|
||||||
|
super::wasmer_backend_t::WASMI => {
|
||||||
|
Self::Wasmi(wasmi::wasmer_wasmi_engine_config_t::default())
|
||||||
|
}
|
||||||
|
#[cfg(feature = "wamr")]
|
||||||
|
super::wasmer_backend_t::WAMR => {
|
||||||
|
Self::Wamr(wamr::wasmer_wamr_engine_config_t::default())
|
||||||
|
}
|
||||||
|
#[cfg(feature = "jsc")]
|
||||||
|
super::wasmer_backend_t::JSC => Self::Jsc(jsc::wasmer_jsc_engine_config_t::default()),
|
||||||
|
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub(crate) struct wasmer_backend_config_t {
|
||||||
|
pub inner: wasmer_backend_config_kind_t,
|
||||||
|
pub target: Option<Box<wasmer_target_t>>,
|
||||||
|
#[cfg(feature = "middlewares")]
|
||||||
|
pub middlewares: Vec<wasmer_middleware_t>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Unstable non-standard Wasmer-specific API to update the
|
||||||
|
/// configuration to specify a particular target for the engine.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use wasmer_inline_c::assert_c;
|
||||||
|
/// # fn main() {
|
||||||
|
/// # (assert_c! {
|
||||||
|
/// # #include "tests/wasmer.h"
|
||||||
|
/// #
|
||||||
|
/// int main() {
|
||||||
|
/// // Create the configuration.
|
||||||
|
/// wasm_config_t* config = wasm_config_new();
|
||||||
|
///
|
||||||
|
/// // Set the target.
|
||||||
|
/// {
|
||||||
|
/// wasmer_triple_t* triple = wasmer_triple_new_from_host();
|
||||||
|
/// wasmer_cpu_features_t* cpu_features = wasmer_cpu_features_new();
|
||||||
|
/// wasmer_target_t* target = wasmer_target_new(triple, cpu_features);
|
||||||
|
///
|
||||||
|
/// wasm_config_sys_set_target(config, target);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// // Create the engine.
|
||||||
|
/// wasm_engine_t* engine = wasm_engine_new_with_config(config);
|
||||||
|
///
|
||||||
|
/// // Check we have an engine!
|
||||||
|
/// assert(engine);
|
||||||
|
///
|
||||||
|
/// // Free everything.
|
||||||
|
/// wasm_engine_delete(engine);
|
||||||
|
///
|
||||||
|
/// return 0;
|
||||||
|
/// }
|
||||||
|
/// # })
|
||||||
|
/// # .success();
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wasm_config_set_target(config: &mut wasm_config_t, target: Box<wasmer_target_t>) {
|
||||||
|
config.backend_config.target = Some(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Updates the configuration to add a module middleware.
|
||||||
|
///
|
||||||
|
/// This function takes ownership of `middleware`.
|
||||||
|
///
|
||||||
|
/// This is a Wasmer-specific function.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// See the documentation of the [`metering`] module.
|
||||||
|
#[no_mangle]
|
||||||
|
#[cfg(feature = "middlewares")]
|
||||||
|
pub extern "C" fn wasm_config_push_middleware(
|
||||||
|
config: &mut wasm_config_t,
|
||||||
|
middleware: Box<wasmer_middleware_t>,
|
||||||
|
) {
|
||||||
|
config.backend_config.middlewares.push(*middleware)
|
||||||
|
}
|
||||||
205
lib/c-api/src/wasm_c_api/engine/config/sys.rs
Normal file
205
lib/c-api/src/wasm_c_api/engine/config/sys.rs
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
// Necessary when a single backend is enabled.
|
||||||
|
#![allow(irrefutable_let_patterns)]
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
error::update_last_error,
|
||||||
|
wasm_c_api::engine::{
|
||||||
|
wasm_config_t, wasm_engine_t, wasmer_backend_config_kind_t, wasmer_backend_t,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "middlewares")]
|
||||||
|
pub use crate::wasm_c_api::unstable::middlewares::wasmer_middleware_t;
|
||||||
|
|
||||||
|
use cfg_if::cfg_if;
|
||||||
|
use wasmer_api::Engine;
|
||||||
|
use wasmer_compiler::EngineBuilder;
|
||||||
|
|
||||||
|
#[cfg(feature = "compiler")]
|
||||||
|
use wasmer_api::sys::CompilerConfig;
|
||||||
|
|
||||||
|
/// Configuration specific for `sys` (Cranelift, LLVM, Singlepass) engines.
|
||||||
|
///
|
||||||
|
/// This is a Wasmer-specific type with Wasmer-specific functions for manipulating it.
|
||||||
|
///
|
||||||
|
/// cbindgen:ignore
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub(crate) struct wasmer_sys_engine_config_t {
|
||||||
|
pub nan_canonicalization: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Updates the configuration to enable NaN canonicalization.
|
||||||
|
///
|
||||||
|
/// This is a Wasmer-specific function.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use wasmer_inline_c::assert_c;
|
||||||
|
/// # fn main() {
|
||||||
|
/// # (assert_c! {
|
||||||
|
/// # #include "tests/wasmer.h"
|
||||||
|
/// #
|
||||||
|
/// int main() {
|
||||||
|
/// // Create the configuration.
|
||||||
|
/// wasm_config_t* config = wasm_config_new();
|
||||||
|
///
|
||||||
|
/// // Enable NaN canonicalization.
|
||||||
|
/// wasm_config_sys_canonicalize_nans(config, true);
|
||||||
|
///
|
||||||
|
/// // Create the engine.
|
||||||
|
/// wasm_engine_t* engine = wasm_engine_new_with_config(config);
|
||||||
|
///
|
||||||
|
/// // Check we have an engine!
|
||||||
|
/// assert(engine);
|
||||||
|
///
|
||||||
|
/// // Free everything.
|
||||||
|
/// wasm_engine_delete(engine);
|
||||||
|
///
|
||||||
|
/// return 0;
|
||||||
|
/// }
|
||||||
|
/// # })
|
||||||
|
/// # .success();
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wasm_config_sys_canonicalize_nans(config: &mut wasm_config_t, enable: bool) {
|
||||||
|
if let wasmer_backend_config_kind_t::Sys(ref mut c) = config.backend_config.inner {
|
||||||
|
c.nan_canonicalization = enable;
|
||||||
|
} else {
|
||||||
|
let sys_config = wasmer_sys_engine_config_t {
|
||||||
|
nan_canonicalization: enable,
|
||||||
|
};
|
||||||
|
config.backend_config.inner = wasmer_backend_config_kind_t::Sys(sys_config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new [`wasm_engine_t`] backed by a `sys` engine.
|
||||||
|
pub fn wasm_sys_engine_new_with_config(config: wasm_config_t) -> Option<Box<wasm_engine_t>> {
|
||||||
|
if !matches!(config.backend, wasmer_backend_t::LLVM)
|
||||||
|
&& !matches!(config.backend, wasmer_backend_t::SINGLEPASS)
|
||||||
|
&& !matches!(config.backend, wasmer_backend_t::CRANELIFT)
|
||||||
|
&& !matches!(config.backend, wasmer_backend_t::HEADLESS)
|
||||||
|
&& !config.backend_config.inner.is_sys()
|
||||||
|
{
|
||||||
|
update_last_error(format!(
|
||||||
|
"Cannot create a new `sys` engine with a non-sys-specific config! {config:?}"
|
||||||
|
));
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let backend = config.backend;
|
||||||
|
#[allow(unused)]
|
||||||
|
let sys_config = match config.backend_config.inner.try_into_sys() {
|
||||||
|
Err(_) => {
|
||||||
|
update_last_error(format!(
|
||||||
|
"Could not create new `sys` engine with the selected {backend:?} backend."
|
||||||
|
));
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Ok(s) => s,
|
||||||
|
};
|
||||||
|
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(feature = "compiler")] {
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
let mut compiler_config: Box<dyn CompilerConfig> = match &backend {
|
||||||
|
wasmer_backend_t::CRANELIFT => {
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(feature = "cranelift")] {
|
||||||
|
Box::<wasmer_compiler_cranelift::Cranelift>::default()
|
||||||
|
} else {
|
||||||
|
update_last_error("Wasmer has not been compiled with the `cranelift` feature.");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
wasmer_backend_t::LLVM => {
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(feature = "llvm")] {
|
||||||
|
Box::<wasmer_compiler_llvm::LLVM>::default()
|
||||||
|
} else {
|
||||||
|
update_last_error("Wasmer has not been compiled with the `llvm` feature.");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
wasmer_backend_t::SINGLEPASS => {
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(feature = "singlepass")] {
|
||||||
|
Box::<wasmer_compiler_singlepass::Singlepass>::default()
|
||||||
|
} else {
|
||||||
|
update_last_error("Wasmer has not been compiled with the `singlepass` feature.");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => panic!("not a `sys` backend!")
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "middlewares")]
|
||||||
|
for middleware in config.backend_config.middlewares {
|
||||||
|
compiler_config.push_middleware(middleware.inner.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
if sys_config.nan_canonicalization {
|
||||||
|
compiler_config.canonicalize_nans(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
let inner: Engine =
|
||||||
|
{
|
||||||
|
let mut builder = EngineBuilder::new(compiler_config);
|
||||||
|
|
||||||
|
if let Some(target) = config.backend_config.target {
|
||||||
|
builder = builder.set_target(Some(target.inner));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(features) = config.features {
|
||||||
|
builder = builder.set_features(Some(features.inner));
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.engine().into()
|
||||||
|
};
|
||||||
|
Some(Box::new(wasm_engine_t { inner }))
|
||||||
|
} else if #[cfg(feature = "compiler-headless")] {
|
||||||
|
let inner: Engine =
|
||||||
|
{
|
||||||
|
let mut builder = EngineBuilder::headless();
|
||||||
|
|
||||||
|
if let Some(target) = config.backend_config.target {
|
||||||
|
builder = builder.set_target(Some(target.inner));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(features) = config.features {
|
||||||
|
builder = builder.set_features(Some(features.inner));
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.engine().into()
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(Box::new(wasm_engine_t { inner }))
|
||||||
|
} else {
|
||||||
|
update_last_error("No backend enabled for the `sys` engine: enable one of `compiler` or `compiler-headless`!");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl wasmer_backend_config_kind_t {
|
||||||
|
/// Returns `true` if the wasmer_engine_config_t is [`Sys`].
|
||||||
|
///
|
||||||
|
/// [`Sys`]: wasmer_engine_config_t::Sys
|
||||||
|
#[must_use]
|
||||||
|
pub(super) fn is_sys(&self) -> bool {
|
||||||
|
matches!(self, Self::Sys(..))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn try_into_sys(self) -> Result<wasmer_sys_engine_config_t, Self> {
|
||||||
|
if let Self::Sys(v) = self {
|
||||||
|
Ok(v)
|
||||||
|
} else {
|
||||||
|
Err(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
38
lib/c-api/src/wasm_c_api/engine/config/v8.rs
Normal file
38
lib/c-api/src/wasm_c_api/engine/config/v8.rs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
use crate::{
|
||||||
|
error::update_last_error,
|
||||||
|
wasm_c_api::engine::{wasm_config_t, wasm_engine_t, wasmer_backend_t},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::wasmer_backend_config_kind_t;
|
||||||
|
|
||||||
|
/// Configuration specific for the `v8` engine.
|
||||||
|
///
|
||||||
|
/// This is a Wasmer-specific type with Wasmer-specific functions for
|
||||||
|
/// manipulating it.
|
||||||
|
///
|
||||||
|
/// cbindgen:ignore
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub(crate) struct wasmer_v8_engine_config_t;
|
||||||
|
|
||||||
|
/// Create a new [`wasm_engine_t`] backed by a `v8` engine.
|
||||||
|
pub(crate) fn wasm_v8_engine_new_with_config(config: wasm_config_t) -> Option<Box<wasm_engine_t>> {
|
||||||
|
if !matches!(config.backend, wasmer_backend_t::V8) || !config.backend_config.inner.is_v8() {
|
||||||
|
update_last_error("Cannot create a new `v8` engine with a non-v8-specific config!");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(Box::new(wasm_engine_t {
|
||||||
|
inner: wasmer_api::v8::V8::default().into(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
impl wasmer_backend_config_kind_t {
|
||||||
|
/// Returns `true` if the wasmer_engine_config_t is [`V8`].
|
||||||
|
///
|
||||||
|
/// [`V8`]: wasmer_engine_config_t::V8
|
||||||
|
#[must_use]
|
||||||
|
pub(super) fn is_v8(&self) -> bool {
|
||||||
|
matches!(self, Self::V8(..))
|
||||||
|
}
|
||||||
|
}
|
||||||
40
lib/c-api/src/wasm_c_api/engine/config/wamr.rs
Normal file
40
lib/c-api/src/wasm_c_api/engine/config/wamr.rs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
use crate::{
|
||||||
|
error::update_last_error,
|
||||||
|
wasm_c_api::engine::{wasm_config_t, wasm_engine_t, wasmer_backend_t},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::wasmer_backend_config_kind_t;
|
||||||
|
|
||||||
|
/// Configuration specific for the `wamr` engine.
|
||||||
|
///
|
||||||
|
/// This is a Wasmer-specific type with Wasmer-specific functions for
|
||||||
|
/// manipulating it.
|
||||||
|
///
|
||||||
|
/// cbindgen:ignore
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub(crate) struct wasmer_wamr_engine_config_t;
|
||||||
|
|
||||||
|
/// Create a new [`wasm_engine_t`] backed by a `wamr` engine.
|
||||||
|
pub(crate) fn wasm_wamr_engine_new_with_config(
|
||||||
|
config: wasm_config_t,
|
||||||
|
) -> Option<Box<wasm_engine_t>> {
|
||||||
|
if !matches!(config.backend, wasmer_backend_t::WAMR) || !config.backend_config.inner.is_wamr() {
|
||||||
|
update_last_error("Cannot create a new `wamr` engine with a non-wamr-specific config!");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(Box::new(wasm_engine_t {
|
||||||
|
inner: wasmer_api::wamr::Wamr::default().into(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
impl wasmer_backend_config_kind_t {
|
||||||
|
/// Returns `true` if the wasmer_engine_config_t is [`WAMR`].
|
||||||
|
///
|
||||||
|
/// [`WAMR`]: wasmer_engine_config_t::WAMR
|
||||||
|
#[must_use]
|
||||||
|
pub(super) fn is_wamr(&self) -> bool {
|
||||||
|
matches!(self, Self::Wamr(..))
|
||||||
|
}
|
||||||
|
}
|
||||||
41
lib/c-api/src/wasm_c_api/engine/config/wasmi.rs
Normal file
41
lib/c-api/src/wasm_c_api/engine/config/wasmi.rs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
use crate::{
|
||||||
|
error::update_last_error,
|
||||||
|
wasm_c_api::engine::{wasm_config_t, wasm_engine_t, wasmer_backend_t},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::wasmer_backend_config_kind_t;
|
||||||
|
|
||||||
|
/// Configuration specific for the `wasmi` engine.
|
||||||
|
///
|
||||||
|
/// This is a Wasmer-specific type with Wasmer-specific functions for
|
||||||
|
/// manipulating it.
|
||||||
|
///
|
||||||
|
/// cbindgen:ignore
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub(crate) struct wasmer_wasmi_engine_config_t;
|
||||||
|
|
||||||
|
/// Create a new [`wasm_engine_t`] backed by a `wasmi` engine.
|
||||||
|
pub(crate) fn wasm_wasmi_engine_new_with_config(
|
||||||
|
config: wasm_config_t,
|
||||||
|
) -> Option<Box<wasm_engine_t>> {
|
||||||
|
if !matches!(config.backend, wasmer_backend_t::WASMI) || !config.backend_config.inner.is_wasmi()
|
||||||
|
{
|
||||||
|
update_last_error("Cannot create a new `wasmi` engine with a non-wasmi-specific config!");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(Box::new(wasm_engine_t {
|
||||||
|
inner: wasmer_api::wasmi::Wasmi::default().into(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
impl wasmer_backend_config_kind_t {
|
||||||
|
/// Returns `true` if the wasmer_engine_config_t is [`WASMI`].
|
||||||
|
///
|
||||||
|
/// [`WASMI`]: wasmer_engine_config_t::WASMI
|
||||||
|
#[must_use]
|
||||||
|
pub(super) fn is_wasmi(&self) -> bool {
|
||||||
|
matches!(self, Self::Wasmi(..))
|
||||||
|
}
|
||||||
|
}
|
||||||
306
lib/c-api/src/wasm_c_api/engine/mod.rs
Normal file
306
lib/c-api/src/wasm_c_api/engine/mod.rs
Normal file
@@ -0,0 +1,306 @@
|
|||||||
|
pub use super::unstable::engine::wasm_config_set_features;
|
||||||
|
use super::unstable::features::wasmer_features_t;
|
||||||
|
|
||||||
|
use wasmer_api::{BackendKind, Engine};
|
||||||
|
|
||||||
|
mod config;
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
pub use config::*;
|
||||||
|
|
||||||
|
/// Kind of engines that can be used by the store.
|
||||||
|
///
|
||||||
|
/// This is a Wasmer-specific type with Wasmer-specific functions for
|
||||||
|
/// manipulating it.
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
#[repr(C)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub enum wasmer_backend_t {
|
||||||
|
/// The cranelift backend.
|
||||||
|
CRANELIFT = 0,
|
||||||
|
|
||||||
|
/// The LLVM backend.
|
||||||
|
LLVM,
|
||||||
|
|
||||||
|
/// The singlepass backend.
|
||||||
|
SINGLEPASS,
|
||||||
|
|
||||||
|
/// The headless backend.
|
||||||
|
HEADLESS,
|
||||||
|
|
||||||
|
/// The V8 backend.
|
||||||
|
V8,
|
||||||
|
|
||||||
|
/// The WASMI backend.
|
||||||
|
WASMI,
|
||||||
|
|
||||||
|
/// The WAMR backend.
|
||||||
|
WAMR,
|
||||||
|
|
||||||
|
/// The JSC backend.
|
||||||
|
JSC,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<BackendKind> for wasmer_backend_t {
|
||||||
|
fn from(value: BackendKind) -> Self {
|
||||||
|
match value {
|
||||||
|
#[cfg(feature = "cranelift")]
|
||||||
|
BackendKind::Cranelift => Self::CRANELIFT,
|
||||||
|
#[cfg(feature = "llvm")]
|
||||||
|
BackendKind::LLVM => Self::LLVM,
|
||||||
|
#[cfg(feature = "singlepass")]
|
||||||
|
BackendKind::Singlepass => Self::SINGLEPASS,
|
||||||
|
#[cfg(feature = "sys")]
|
||||||
|
BackendKind::Headless => Self::HEADLESS,
|
||||||
|
#[cfg(feature = "wamr")]
|
||||||
|
BackendKind::Wamr => Self::WAMR,
|
||||||
|
#[cfg(feature = "wasmi")]
|
||||||
|
BackendKind::Wasmi => Self::WASMI,
|
||||||
|
#[cfg(feature = "v8")]
|
||||||
|
BackendKind::V8 => Self::V8,
|
||||||
|
#[cfg(feature = "jsc")]
|
||||||
|
BackendKind::Jsc => Self::JSC,
|
||||||
|
v => panic!("Unsupported backend kind {v:?}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for wasmer_backend_t {
|
||||||
|
fn default() -> Self {
|
||||||
|
// Let the `wasmer_api` crate decide which is the default engine, given the enabled
|
||||||
|
// features.
|
||||||
|
wasmer_api::BackendKind::default().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An engine is used by the store to drive the compilation and the
|
||||||
|
/// execution of a WebAssembly module.
|
||||||
|
///
|
||||||
|
/// cbindgen:ignore
|
||||||
|
#[repr(C)]
|
||||||
|
// We can let the API decide which engine is default with the given set of
|
||||||
|
// features.
|
||||||
|
//
|
||||||
|
// See the impl of `Default` for `BackendEngine` in the `wasmer` (API) crate.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct wasm_engine_t {
|
||||||
|
pub(crate) inner: Engine,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
#[allow(unreachable_code)]
|
||||||
|
pub extern "C" fn wasm_engine_new() -> Box<wasm_engine_t> {
|
||||||
|
Box::new(wasm_engine_t::default())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deletes an engine.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use wasmer_inline_c::assert_c;
|
||||||
|
/// # fn main() {
|
||||||
|
/// # (assert_c! {
|
||||||
|
/// # #include "tests/wasmer.h"
|
||||||
|
/// #
|
||||||
|
/// int main() {
|
||||||
|
/// // Create a default engine.
|
||||||
|
/// wasm_engine_t* engine = wasm_engine_new();
|
||||||
|
/// int error_length = wasmer_last_error_length();
|
||||||
|
/// if (error_length > 0) {
|
||||||
|
/// char *error_message = malloc(error_length);
|
||||||
|
/// wasmer_last_error_message(error_message, error_length);
|
||||||
|
///
|
||||||
|
/// printf("Attempted to set an immutable global: `%s`\n", error_message);
|
||||||
|
/// free(error_message);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// // Check we have an engine!
|
||||||
|
/// assert(engine);
|
||||||
|
///
|
||||||
|
/// // Free everything.
|
||||||
|
/// wasm_engine_delete(engine);
|
||||||
|
///
|
||||||
|
/// return 0;
|
||||||
|
/// }
|
||||||
|
/// # })
|
||||||
|
/// # .success();
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// cbindgen:ignore
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_engine_delete(_engine: Option<Box<wasm_engine_t>>) {}
|
||||||
|
|
||||||
|
/// Creates an engine with a particular configuration.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// See [`wasm_config_new`].
|
||||||
|
///
|
||||||
|
/// cbindgen:ignore
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wasm_engine_new_with_config(
|
||||||
|
config: Option<Box<wasm_config_t>>,
|
||||||
|
) -> Option<Box<wasm_engine_t>> {
|
||||||
|
#[allow(unused)]
|
||||||
|
let config = *(config?);
|
||||||
|
|
||||||
|
match config.backend {
|
||||||
|
#[cfg(feature = "llvm")]
|
||||||
|
wasmer_backend_t::LLVM => config::sys::wasm_sys_engine_new_with_config(config),
|
||||||
|
#[cfg(feature = "cranelift")]
|
||||||
|
wasmer_backend_t::CRANELIFT => config::sys::wasm_sys_engine_new_with_config(config),
|
||||||
|
#[cfg(feature = "singlepass")]
|
||||||
|
wasmer_backend_t::SINGLEPASS => config::sys::wasm_sys_engine_new_with_config(config),
|
||||||
|
#[cfg(feature = "sys")]
|
||||||
|
wasmer_backend_t::HEADLESS => config::sys::wasm_sys_engine_new_with_config(config),
|
||||||
|
#[cfg(feature = "v8")]
|
||||||
|
wasmer_backend_t::V8 => config::v8::wasm_v8_engine_new_with_config(config),
|
||||||
|
#[cfg(feature = "wasmi")]
|
||||||
|
wasmer_backend_t::WASMI => config::wasmi::wasm_wasmi_engine_new_with_config(config),
|
||||||
|
#[cfg(feature = "wamr")]
|
||||||
|
wasmer_backend_t::WAMR => config::wamr::wasm_wamr_engine_new_with_config(config),
|
||||||
|
#[cfg(feature = "jsc")]
|
||||||
|
wasmer_backend_t::JSC => config::jsc::wasm_jsc_engine_new_with_config(config),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A configuration holds the compiler and the engine used by the store.
|
||||||
|
///
|
||||||
|
/// cbindgen:ignore
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct wasm_config_t {
|
||||||
|
pub(super) backend: wasmer_backend_t,
|
||||||
|
pub(super) backend_config: wasmer_backend_config_t,
|
||||||
|
pub(super) features: Option<Box<wasmer_features_t>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new default Wasmer configuration.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use wasmer_inline_c::assert_c;
|
||||||
|
/// # fn main() {
|
||||||
|
/// # (assert_c! {
|
||||||
|
/// # #include "tests/wasmer.h"
|
||||||
|
/// #
|
||||||
|
/// int main() {
|
||||||
|
/// // Create the configuration.
|
||||||
|
/// wasm_config_t* config = wasm_config_new();
|
||||||
|
///
|
||||||
|
/// // Create the engine.
|
||||||
|
/// wasm_engine_t* engine = wasm_engine_new_with_config(config);
|
||||||
|
///
|
||||||
|
/// // Check we have an engine!
|
||||||
|
/// assert(engine);
|
||||||
|
///
|
||||||
|
/// // Free everything.
|
||||||
|
/// wasm_engine_delete(engine);
|
||||||
|
///
|
||||||
|
/// return 0;
|
||||||
|
/// }
|
||||||
|
/// # })
|
||||||
|
/// # .success();
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// cbindgen:ignore
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wasm_config_new() -> Box<wasm_config_t> {
|
||||||
|
Box::<wasm_config_t>::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Delete a Wasmer config object.
|
||||||
|
///
|
||||||
|
/// This function does not need to be called if `wasm_engine_new_with_config` or
|
||||||
|
/// another function that takes ownership of the `wasm_config_t` is called.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use wasmer_inline_c::assert_c;
|
||||||
|
/// # fn main() {
|
||||||
|
/// # (assert_c! {
|
||||||
|
/// # #include "tests/wasmer.h"
|
||||||
|
/// #
|
||||||
|
/// int main() {
|
||||||
|
/// // Create the configuration.
|
||||||
|
/// wasm_config_t* config = wasm_config_new();
|
||||||
|
///
|
||||||
|
/// // Delete the configuration
|
||||||
|
/// wasm_config_delete(config);
|
||||||
|
///
|
||||||
|
/// return 0;
|
||||||
|
/// }
|
||||||
|
/// # })
|
||||||
|
/// # .success();
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
/// cbindgen:ignore
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wasm_config_delete(_config: Option<Box<wasm_config_t>>) {}
|
||||||
|
|
||||||
|
/// Updates the configuration to specify a particular engine to use.
|
||||||
|
///
|
||||||
|
/// This is a Wasmer-specific function.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use wasmer_inline_c::assert_c;
|
||||||
|
/// # fn main() {
|
||||||
|
/// # (assert_c! {
|
||||||
|
/// # #include "tests/wasmer.h"
|
||||||
|
/// #
|
||||||
|
/// int main() {
|
||||||
|
/// // Create the configuration.
|
||||||
|
/// wasm_config_t* config = wasm_config_new();
|
||||||
|
///
|
||||||
|
/// // Create the engine.
|
||||||
|
/// wasm_engine_t* engine = wasm_engine_new_with_config(config);
|
||||||
|
///
|
||||||
|
/// // Check we have an engine!
|
||||||
|
/// assert(engine);
|
||||||
|
///
|
||||||
|
/// // Free everything.
|
||||||
|
/// wasm_engine_delete(engine);
|
||||||
|
///
|
||||||
|
/// return 0;
|
||||||
|
/// }
|
||||||
|
/// # })
|
||||||
|
/// # .success();
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wasm_config_set_backend(config: &mut wasm_config_t, engine: wasmer_backend_t) {
|
||||||
|
config.backend = engine;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
use inline_c::assert_c;
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
use wasmer_inline_c::assert_c;
|
||||||
|
|
||||||
|
#[cfg_attr(coverage, ignore)]
|
||||||
|
#[test]
|
||||||
|
fn test_engine_new() {
|
||||||
|
(assert_c! {
|
||||||
|
#include "tests/wasmer.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
wasm_engine_t* engine = wasm_engine_new();
|
||||||
|
assert(engine);
|
||||||
|
|
||||||
|
wasm_engine_delete(engine);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,58 +2,10 @@
|
|||||||
//! `wasm_engine_t` and siblings.
|
//! `wasm_engine_t` and siblings.
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
super::engine::{wasm_config_t, wasmer_engine_t},
|
super::engine::{wasm_config_t, wasmer_backend_t},
|
||||||
features::wasmer_features_t,
|
features::wasmer_features_t,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "compiler")]
|
|
||||||
use super::{super::engine::wasmer_compiler_t, target_lexicon::wasmer_target_t};
|
|
||||||
|
|
||||||
/// Unstable non-standard Wasmer-specific API to update the
|
|
||||||
/// configuration to specify a particular target for the engine.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// # use wasmer_inline_c::assert_c;
|
|
||||||
/// # fn main() {
|
|
||||||
/// # (assert_c! {
|
|
||||||
/// # #include "tests/wasmer.h"
|
|
||||||
/// #
|
|
||||||
/// int main() {
|
|
||||||
/// // Create the configuration.
|
|
||||||
/// wasm_config_t* config = wasm_config_new();
|
|
||||||
///
|
|
||||||
/// // Set the target.
|
|
||||||
/// {
|
|
||||||
/// wasmer_triple_t* triple = wasmer_triple_new_from_host();
|
|
||||||
/// wasmer_cpu_features_t* cpu_features = wasmer_cpu_features_new();
|
|
||||||
/// wasmer_target_t* target = wasmer_target_new(triple, cpu_features);
|
|
||||||
///
|
|
||||||
/// wasm_config_set_target(config, target);
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // Create the engine.
|
|
||||||
/// wasm_engine_t* engine = wasm_engine_new_with_config(config);
|
|
||||||
///
|
|
||||||
/// // Check we have an engine!
|
|
||||||
/// assert(engine);
|
|
||||||
///
|
|
||||||
/// // Free everything.
|
|
||||||
/// wasm_engine_delete(engine);
|
|
||||||
///
|
|
||||||
/// return 0;
|
|
||||||
/// }
|
|
||||||
/// # })
|
|
||||||
/// # .success();
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
#[no_mangle]
|
|
||||||
#[cfg(feature = "compiler")]
|
|
||||||
pub extern "C" fn wasm_config_set_target(config: &mut wasm_config_t, target: Box<wasmer_target_t>) {
|
|
||||||
config.target = Some(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unstable non-standard Wasmer-specific API to update the
|
/// Unstable non-standard Wasmer-specific API to update the
|
||||||
/// configuration to specify particular features for the engine.
|
/// configuration to specify particular features for the engine.
|
||||||
///
|
///
|
||||||
@@ -100,58 +52,6 @@ pub extern "C" fn wasm_config_set_features(
|
|||||||
config.features = Some(features);
|
config.features = Some(features);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the configuration to enable NaN canonicalization.
|
|
||||||
///
|
|
||||||
/// This is a Wasmer-specific function.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// # use wasmer_inline_c::assert_c;
|
|
||||||
/// # fn main() {
|
|
||||||
/// # (assert_c! {
|
|
||||||
/// # #include "tests/wasmer.h"
|
|
||||||
/// #
|
|
||||||
/// int main() {
|
|
||||||
/// // Create the configuration.
|
|
||||||
/// wasm_config_t* config = wasm_config_new();
|
|
||||||
///
|
|
||||||
/// // Enable NaN canonicalization.
|
|
||||||
/// wasm_config_canonicalize_nans(config, true);
|
|
||||||
///
|
|
||||||
/// // Create the engine.
|
|
||||||
/// wasm_engine_t* engine = wasm_engine_new_with_config(config);
|
|
||||||
///
|
|
||||||
/// // Check we have an engine!
|
|
||||||
/// assert(engine);
|
|
||||||
///
|
|
||||||
/// // Free everything.
|
|
||||||
/// wasm_engine_delete(engine);
|
|
||||||
///
|
|
||||||
/// return 0;
|
|
||||||
/// }
|
|
||||||
/// # })
|
|
||||||
/// # .success();
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_config_canonicalize_nans(config: &mut wasm_config_t, enable: bool) {
|
|
||||||
config.nan_canonicalization = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check whether the given compiler is available, i.e. part of this
|
|
||||||
/// compiled library.
|
|
||||||
#[no_mangle]
|
|
||||||
#[cfg(feature = "compiler")]
|
|
||||||
pub extern "C" fn wasmer_is_compiler_available(compiler: wasmer_compiler_t) -> bool {
|
|
||||||
match compiler {
|
|
||||||
wasmer_compiler_t::CRANELIFT if cfg!(feature = "cranelift") => true,
|
|
||||||
wasmer_compiler_t::LLVM if cfg!(feature = "llvm") => true,
|
|
||||||
wasmer_compiler_t::SINGLEPASS if cfg!(feature = "singlepass") => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check whether there is no compiler available in this compiled
|
/// Check whether there is no compiler available in this compiled
|
||||||
/// library.
|
/// library.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -159,11 +59,20 @@ pub extern "C" fn wasmer_is_headless() -> bool {
|
|||||||
!cfg!(feature = "compiler")
|
!cfg!(feature = "compiler")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check whether the given engine is available, i.e. part of this
|
/// Check whether the given backend is available, i.e. part of this
|
||||||
/// compiled library.
|
/// compiled library.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasmer_is_engine_available(engine: wasmer_engine_t) -> bool {
|
pub extern "C" fn wasmer_is_backend_available(backend: wasmer_backend_t) -> bool {
|
||||||
matches!(engine, wasmer_engine_t::UNIVERSAL if cfg!(feature = "compiler"))
|
match backend {
|
||||||
|
wasmer_backend_t::LLVM => cfg!(feature = "llvm"),
|
||||||
|
wasmer_backend_t::CRANELIFT => cfg!(feature = "cranelift"),
|
||||||
|
wasmer_backend_t::SINGLEPASS => cfg!(feature = "singlepass"),
|
||||||
|
wasmer_backend_t::HEADLESS => cfg!(feature = "sys"),
|
||||||
|
wasmer_backend_t::V8 => cfg!(feature = "v8"),
|
||||||
|
wasmer_backend_t::WASMI => cfg!(feature = "wasmi"),
|
||||||
|
wasmer_backend_t::WAMR => cfg!(feature = "wamr"),
|
||||||
|
wasmer_backend_t::JSC => cfg!(feature = "jsc"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -197,7 +106,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_wasmer_is_compiler_available() {
|
fn test_wasmer_is_backend_available() {
|
||||||
set_var(
|
set_var(
|
||||||
"CRANELIFT",
|
"CRANELIFT",
|
||||||
if cfg!(feature = "cranelift") {
|
if cfg!(feature = "cranelift") {
|
||||||
@@ -221,9 +130,9 @@ mod tests {
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
assert(wasmer_is_compiler_available(CRANELIFT) == (getenv("CRANELIFT")[0] == '1'));
|
assert(wasmer_is_backend_available(CRANELIFT) == (getenv("CRANELIFT")[0] == '1'));
|
||||||
assert(wasmer_is_compiler_available(LLVM) == (getenv("LLVM")[0] == '1'));
|
assert(wasmer_is_backend_available(LLVM) == (getenv("LLVM")[0] == '1'));
|
||||||
assert(wasmer_is_compiler_available(SINGLEPASS) == (getenv("SINGLEPASS")[0] == '1'));
|
assert(wasmer_is_backend_available(SINGLEPASS) == (getenv("SINGLEPASS")[0] == '1'));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -234,26 +143,4 @@ mod tests {
|
|||||||
remove_var("LLVM");
|
remove_var("LLVM");
|
||||||
remove_var("SINGLEPASS");
|
remove_var("SINGLEPASS");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_wasmer_is_engine_available() {
|
|
||||||
set_var(
|
|
||||||
"UNIVERSAL",
|
|
||||||
if cfg!(feature = "compiler") { "1" } else { "0" },
|
|
||||||
);
|
|
||||||
|
|
||||||
(assert_c! {
|
|
||||||
#include "tests/wasmer.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
assert(wasmer_is_engine_available(UNIVERSAL) == (getenv("UNIVERSAL")[0] == '1'));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.success();
|
|
||||||
|
|
||||||
remove_var("UNIVERSAL");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
pub mod metering;
|
pub mod metering;
|
||||||
|
|
||||||
use super::super::engine::wasm_config_t;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use wasmer_api::sys::ModuleMiddleware;
|
use wasmer_api::sys::ModuleMiddleware;
|
||||||
|
|
||||||
@@ -21,20 +20,3 @@ compile_error!("The `middlewares` feature requires the `compiler` feature to be
|
|||||||
pub struct wasmer_middleware_t {
|
pub struct wasmer_middleware_t {
|
||||||
pub(in crate::wasm_c_api) inner: Arc<dyn ModuleMiddleware>,
|
pub(in crate::wasm_c_api) inner: Arc<dyn ModuleMiddleware>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the configuration to add a module middleware.
|
|
||||||
///
|
|
||||||
/// This function takes ownership of `middleware`.
|
|
||||||
///
|
|
||||||
/// This is a Wasmer-specific function.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// See the documentation of the [`metering`] module.
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_config_push_middleware(
|
|
||||||
config: &mut wasm_config_t,
|
|
||||||
middleware: Box<wasmer_middleware_t>,
|
|
||||||
) {
|
|
||||||
config.middlewares.push(*middleware);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ pub mod middlewares;
|
|||||||
pub mod module;
|
pub mod module;
|
||||||
#[cfg(feature = "compiler")]
|
#[cfg(feature = "compiler")]
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
#[cfg(any(feature = "compiler", feature = "compiler-headless"))]
|
|
||||||
pub mod target_lexicon;
|
pub mod target_lexicon;
|
||||||
#[cfg(feature = "wasi")]
|
#[cfg(feature = "wasi")]
|
||||||
pub mod wasi;
|
pub mod wasi;
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ pub unsafe extern "C" fn wasmer_module_new(
|
|||||||
engine: Option<&mut wasm_engine_t>,
|
engine: Option<&mut wasm_engine_t>,
|
||||||
bytes: Option<&wasm_byte_vec_t>,
|
bytes: Option<&wasm_byte_vec_t>,
|
||||||
) -> Option<Box<wasm_module_t>> {
|
) -> Option<Box<wasm_module_t>> {
|
||||||
let engine: wasmer_api::Engine = engine?.inner.clone().into();
|
let engine: wasmer_api::Engine = engine?.inner.clone();
|
||||||
let bytes = bytes?;
|
let bytes = bytes?;
|
||||||
|
|
||||||
let module = c_try!(Module::from_binary(&engine, bytes.as_slice()));
|
let module = c_try!(Module::from_binary(&engine, bytes.as_slice()));
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ use super::super::types::wasm_name_t;
|
|||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::str::{self, FromStr};
|
use std::str::{self, FromStr};
|
||||||
use wasmer_api::sys::{CpuFeature, Target, Triple};
|
use wasmer_types::target::{CpuFeature, Target, Triple};
|
||||||
|
|
||||||
/// Unstable non-standard Wasmer-specific API to represent a triple +
|
/// Unstable non-standard Wasmer-specific API to represent a triple +
|
||||||
/// CPU features pair.
|
/// CPU features pair.
|
||||||
|
|||||||
@@ -16,30 +16,36 @@
|
|||||||
wasm_engine_t *wasm_engine_new() {
|
wasm_engine_t *wasm_engine_new() {
|
||||||
wasm_config_t *config = wasm_config_new();
|
wasm_config_t *config = wasm_config_new();
|
||||||
|
|
||||||
char *wasmer_test_compiler = getenv("WASMER_CAPI_CONFIG");
|
char *wasmer_test_backend = getenv("WASMER_CAPI_CONFIG");
|
||||||
char *wasmer_test_engine;
|
char *wasmer_test_engine;
|
||||||
|
|
||||||
strtok_r(wasmer_test_compiler, "-", &wasmer_test_engine);
|
printf("Using backend: %s\n", wasmer_test_backend);
|
||||||
printf("Using compiler: %s, engine: %s\n", wasmer_test_compiler,
|
|
||||||
wasmer_test_engine);
|
strtok_r(wasmer_test_backend, "-", &wasmer_test_engine);
|
||||||
if (strcmp(wasmer_test_compiler, "cranelift") == 0) {
|
|
||||||
assert(wasmer_is_compiler_available(CRANELIFT));
|
if (strcmp(wasmer_test_backend, "cranelift") == 0) {
|
||||||
wasm_config_set_compiler(config, CRANELIFT);
|
assert(wasmer_is_backend_available(CRANELIFT));
|
||||||
} else if (strcmp(wasmer_test_compiler, "llvm") == 0) {
|
wasm_config_set_backend(config, CRANELIFT);
|
||||||
assert(wasmer_is_compiler_available(LLVM));
|
} else if (strcmp(wasmer_test_backend, "llvm") == 0) {
|
||||||
wasm_config_set_compiler(config, LLVM);
|
assert(wasmer_is_backend_available(LLVM));
|
||||||
} else if (strcmp(wasmer_test_compiler, "singlepass") == 0) {
|
wasm_config_set_backend(config, LLVM);
|
||||||
assert(wasmer_is_compiler_available(SINGLEPASS));
|
} else if (strcmp(wasmer_test_backend, "singlepass") == 0) {
|
||||||
wasm_config_set_compiler(config, SINGLEPASS);
|
assert(wasmer_is_backend_available(SINGLEPASS));
|
||||||
} else if (wasmer_test_compiler) {
|
wasm_config_set_backend(config, SINGLEPASS);
|
||||||
printf("Compiler %s not recognized\n", wasmer_test_compiler);
|
} else if (strcmp(wasmer_test_backend, "headless") == 0) {
|
||||||
abort();
|
assert(wasmer_is_backend_available(HEADLESS));
|
||||||
}
|
wasm_config_set_backend(config, HEADLESS);
|
||||||
if (strcmp(wasmer_test_engine, "universal") == 0) {
|
} else if (strcmp(wasmer_test_backend, "v8") == 0) {
|
||||||
assert(wasmer_is_engine_available(UNIVERSAL));
|
assert(wasmer_is_backend_available(V8));
|
||||||
wasm_config_set_engine(config, UNIVERSAL);
|
wasm_config_set_backend(config, V8);
|
||||||
} else if (wasmer_test_engine) {
|
} else if (strcmp(wasmer_test_backend, "wamr") == 0) {
|
||||||
printf("Engine %s not recognized\n", wasmer_test_engine);
|
assert(wasmer_is_backend_available(WAMR));
|
||||||
|
wasm_config_set_backend(config, WAMR);
|
||||||
|
} else if (strcmp(wasmer_test_backend, "wasmi") == 0) {
|
||||||
|
assert(wasmer_is_backend_available(WASMI));
|
||||||
|
wasm_config_set_backend(config, WASMI);
|
||||||
|
} else if (wasmer_test_backend) {
|
||||||
|
printf("Compiler %s not recognized\n", wasmer_test_backend);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user