Merge branch 'master' into feat-c-api-wasi-unordered-imports

This commit is contained in:
Ivan Enderlin
2021-02-02 12:17:01 +01:00
18 changed files with 499 additions and 48 deletions

View File

@@ -3,7 +3,7 @@ name: Run Benchmarks and upload results
on: on:
push: push:
branches: branches:
- master - benchmark # TODO: change it back to master once we really track the results. We commented this as speed.wasmer.io is failing
jobs: jobs:
run_benchmark: run_benchmark:

View File

@@ -43,14 +43,14 @@ jobs:
- build: linux-x64 - build: linux-x64
os: ubuntu-18.04 os: ubuntu-18.04
rust: 1.48 rust: 1.48
llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/10.x/linux-amd64.tar.gz' llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/11.x/linux-amd64.tar.gz'
artifact_name: 'wasmer-linux-amd64' artifact_name: 'wasmer-linux-amd64'
cross_compilation_artifact_name: 'cross_compiled_from_linux' cross_compilation_artifact_name: 'cross_compiled_from_linux'
run_integration_tests: true run_integration_tests: true
- build: macos-x64 - build: macos-x64
os: macos-latest os: macos-latest
rust: 1.48 rust: 1.48
llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/10.x/darwin-amd64.tar.gz' llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/11.x/darwin-amd64.tar.gz'
artifact_name: 'wasmer-darwin-amd64' artifact_name: 'wasmer-darwin-amd64'
cross_compilation_artifact_name: 'cross_compiled_from_mac' cross_compilation_artifact_name: 'cross_compiled_from_mac'
run_integration_tests: true run_integration_tests: true
@@ -62,7 +62,7 @@ jobs:
- build: windows-x64 - build: windows-x64
os: windows-latest os: windows-latest
rust: 1.48 rust: 1.48
# llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/10.x/windows-amd64.tar.gz' # llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/11.x/windows-amd64.tar.gz'
artifact_name: 'wasmer-windows-amd64' artifact_name: 'wasmer-windows-amd64'
cross_compilation_artifact_name: 'cross_compiled_from_win' cross_compilation_artifact_name: 'cross_compiled_from_win'
run_integration_tests: true run_integration_tests: true
@@ -70,7 +70,7 @@ jobs:
os: [self-hosted, linux, ARM64] os: [self-hosted, linux, ARM64]
random_sccache_port: true random_sccache_port: true
rust: 1.48 rust: 1.48
llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/10.x/linux-aarch64.tar.gz' llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/11.x/linux-aarch64.tar.gz'
artifact_name: 'wasmer-linux-aarch64' artifact_name: 'wasmer-linux-aarch64'
run_integration_tests: false run_integration_tests: false
env: env:
@@ -108,9 +108,9 @@ jobs:
mkdir ${{ env.LLVM_DIR }} mkdir ${{ env.LLVM_DIR }}
tar xf llvm.tar.gz --strip-components=1 -C ${{ env.LLVM_DIR }} tar xf llvm.tar.gz --strip-components=1 -C ${{ env.LLVM_DIR }}
echo "${{ env.LLVM_DIR }}/bin" >> $GITHUB_PATH echo "${{ env.LLVM_DIR }}/bin" >> $GITHUB_PATH
echo "LLVM_SYS_100_PREFIX=${{ env.LLVM_DIR }}" >> $GITHUB_ENV echo "LLVM_SYS_110_PREFIX=${{ env.LLVM_DIR }}" >> $GITHUB_ENV
env: env:
LLVM_DIR: ${{ github.workspace }}/llvm-10 LLVM_DIR: ${{ github.workspace }}/llvm-11
- name: Set up dependencies for Mac OS - name: Set up dependencies for Mac OS
run: | run: |
brew install automake brew install automake

View File

@@ -9,6 +9,7 @@
### Added ### Added
- [#2053](https://github.com/wasmerio/wasmer/pull/2053) Implement the non-standard `wasi_get_unordered_imports` function in the C API. - [#2053](https://github.com/wasmerio/wasmer/pull/2053) Implement the non-standard `wasi_get_unordered_imports` function in the C API.
- [#2072](https://github.com/wasmerio/wasmer/pull/2072) Add `wasm_config_set_target`, along with `wasm_target_t`, `wasm_triple_t` and `wasm_cpu_features_t` in the unstable C API.
- [#2059](https://github.com/wasmerio/wasmer/pull/2059) Ability to capture `stdout` and `stderr` with WASI in the C API. - [#2059](https://github.com/wasmerio/wasmer/pull/2059) Ability to capture `stdout` and `stderr` with WASI in the C API.
- [#2040](https://github.com/wasmerio/wasmer/pull/2040) Add `InstanceHandle::vmoffsets` to expose the offsets of the `vmctx` region. - [#2040](https://github.com/wasmerio/wasmer/pull/2040) Add `InstanceHandle::vmoffsets` to expose the offsets of the `vmctx` region.
- [#2026](https://github.com/wasmerio/wasmer/pull/2010) Expose trap code of a `RuntimeError`, if it's a `Trap`. - [#2026](https://github.com/wasmerio/wasmer/pull/2010) Expose trap code of a `RuntimeError`, if it's a `Trap`.
@@ -19,6 +20,7 @@
- [#2056](https://github.com/wasmerio/wasmer/pull/2056) Change back to depend on the `enumset` crate instead of `wasmer_enumset` - [#2056](https://github.com/wasmerio/wasmer/pull/2056) Change back to depend on the `enumset` crate instead of `wasmer_enumset`
### Fixed ### Fixed
- [#2084](https://github.com/wasmerio/wasmer/pull/2084) Avoid calling the function environment finalizer more than once when the environment has been cloned in the C API.
- [#2069](https://github.com/wasmerio/wasmer/pull/2069) Use the new documentation for `include/README.md` in the Wasmer package. - [#2069](https://github.com/wasmerio/wasmer/pull/2069) Use the new documentation for `include/README.md` in the Wasmer package.
- [#2042](https://github.com/wasmerio/wasmer/pull/2042) Parse more exotic environment variables in `wasmer run`. - [#2042](https://github.com/wasmerio/wasmer/pull/2042) Parse more exotic environment variables in `wasmer run`.
- [#2041](https://github.com/wasmerio/wasmer/pull/2041) Documentation diagrams now have a solid white background rather than a transparent background. - [#2041](https://github.com/wasmerio/wasmer/pull/2041) Documentation diagrams now have a solid white background rather than a transparent background.

15
Cargo.lock generated
View File

@@ -971,9 +971,9 @@ dependencies = [
[[package]] [[package]]
name = "inkwell" name = "inkwell"
version = "0.1.0-llvm10sample" version = "0.1.0-beta.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e079c12273d96e41481454a37ad968e607e1ce51b39b9facd3a802a12df6e9dc" checksum = "f5fe0be1e47c0c0f3da4397693e08f5d78329ae095c25d529e12ade78420fb41"
dependencies = [ dependencies = [
"either", "either",
"inkwell_internals", "inkwell_internals",
@@ -986,9 +986,9 @@ dependencies = [
[[package]] [[package]]
name = "inkwell_internals" name = "inkwell_internals"
version = "0.2.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b22cf4eda09069b48204cce4b7cd9a25311da813780e95a038524f2210fab44e" checksum = "c2e1f71330ccec54ee62533ae88574c4169b67fb4b95cbb1196a1322582abd11"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1128,15 +1128,15 @@ dependencies = [
[[package]] [[package]]
name = "llvm-sys" name = "llvm-sys"
version = "100.2.0" version = "110.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9109e19fbfac3458f2970189719fa19f1007c6fd4e08c44fdebf4be0ddbe261d" checksum = "b0062a0c6635fb5d57c6ebba072dcae50e41651030363cf06d220b0d016840f2"
dependencies = [ dependencies = [
"cc", "cc",
"lazy_static", "lazy_static",
"libc", "libc",
"regex", "regex",
"semver 0.9.0", "semver 0.11.0",
] ]
[[package]] [[package]]
@@ -2321,6 +2321,7 @@ version = "1.0.1"
dependencies = [ dependencies = [
"cbindgen", "cbindgen",
"cfg-if 1.0.0", "cfg-if 1.0.0",
"enumset",
"inline-c", "inline-c",
"lazy_static", "lazy_static",
"libc", "libc",

View File

@@ -163,7 +163,7 @@ build-docs:
build-docs-capi: build-docs-capi:
cd lib/c-api/doc/deprecated/ && doxygen doxyfile cd lib/c-api/doc/deprecated/ && doxygen doxyfile
cargo doc --manifest-path lib/c-api/Cargo.toml --no-deps --features wat,jit,object-file,native,cranelift,wasi cargo doc --manifest-path lib/c-api/Cargo.toml --no-deps --features wat,jit,object-file,native,cranelift,wasi $(capi_default_features)
# We use cranelift as the default backend for the capi for now # We use cranelift as the default backend for the capi for now
build-capi: build-capi-cranelift build-capi: build-capi-cranelift

View File

@@ -27,6 +27,7 @@ wasmer-engine-native = { version = "1.0.1", path = "../engine-native", optional
wasmer-engine-object-file = { version = "1.0.1", path = "../engine-object-file", optional = true } wasmer-engine-object-file = { version = "1.0.1", path = "../engine-object-file", optional = true }
wasmer-wasi = { version = "1.0.1", path = "../wasi", optional = true } wasmer-wasi = { version = "1.0.1", path = "../wasi", optional = true }
wasmer-types = { version = "1.0.1", path = "../wasmer-types" } wasmer-types = { version = "1.0.1", path = "../wasmer-types" }
enumset = "1.0"
cfg-if = "1.0" cfg-if = "1.0"
lazy_static = "1.4" lazy_static = "1.4"
libc = { version = "^0.2", default-features = false } libc = { version = "^0.2", default-features = false }

View File

@@ -467,6 +467,11 @@ fn exclude_items_from_wasm_c_api(builder: Builder) -> Builder {
.exclude_item("wasi_version_t") .exclude_item("wasi_version_t")
.exclude_item("wasm_config_set_compiler") .exclude_item("wasm_config_set_compiler")
.exclude_item("wasm_config_set_engine") .exclude_item("wasm_config_set_engine")
.exclude_item("wasm_config_set_target")
.exclude_item("wasm_cpu_features_add")
.exclude_item("wasm_cpu_features_delete")
.exclude_item("wasm_cpu_features_new")
.exclude_item("wasm_cpu_features_t")
.exclude_item("wasm_module_name") .exclude_item("wasm_module_name")
.exclude_item("wasm_module_set_name") .exclude_item("wasm_module_set_name")
.exclude_item("wasm_named_extern_module") .exclude_item("wasm_named_extern_module")
@@ -478,6 +483,13 @@ fn exclude_items_from_wasm_c_api(builder: Builder) -> Builder {
.exclude_item("wasm_named_extern_vec_new") .exclude_item("wasm_named_extern_vec_new")
.exclude_item("wasm_named_extern_vec_new_empty") .exclude_item("wasm_named_extern_vec_new_empty")
.exclude_item("wasm_named_extern_vec_new_uninitialized") .exclude_item("wasm_named_extern_vec_new_uninitialized")
.exclude_item("wasm_target_delete")
.exclude_item("wasm_target_new")
.exclude_item("wasm_target_t")
.exclude_item("wasm_triple_delete")
.exclude_item("wasm_triple_new")
.exclude_item("wasm_triple_new_from_host")
.exclude_item("wasm_triple_t")
.exclude_item("wasmer_compiler_t") .exclude_item("wasmer_compiler_t")
.exclude_item("wasmer_engine_t") .exclude_item("wasmer_engine_t")
.exclude_item("wat2wasm") .exclude_item("wat2wasm")

View File

@@ -1,3 +1,5 @@
pub use super::unstable::engine::wasm_config_set_target;
use super::unstable::target_lexicon::wasm_target_t;
use crate::error::{update_last_error, CApiError}; use crate::error::{update_last_error, CApiError};
use cfg_if::cfg_if; use cfg_if::cfg_if;
use std::sync::Arc; use std::sync::Arc;
@@ -93,6 +95,7 @@ pub struct wasm_config_t {
engine: wasmer_engine_t, engine: wasmer_engine_t,
#[cfg(feature = "compiler")] #[cfg(feature = "compiler")]
compiler: wasmer_compiler_t, compiler: wasmer_compiler_t,
pub(super) target: Option<Box<wasm_target_t>>,
} }
/// Create a new default Wasmer configuration. /// Create a new default Wasmer configuration.
@@ -396,7 +399,7 @@ pub unsafe extern "C" fn wasm_engine_delete(_engine: Option<Box<wasm_engine_t>>)
/// cbindgen:ignore /// cbindgen:ignore
#[no_mangle] #[no_mangle]
pub extern "C" fn wasm_engine_new_with_config( pub extern "C" fn wasm_engine_new_with_config(
config: Box<wasm_config_t>, config: Option<Box<wasm_config_t>>,
) -> Option<Box<wasm_engine_t>> { ) -> Option<Box<wasm_engine_t>> {
#[allow(dead_code)] #[allow(dead_code)]
fn return_with_error<M>(msg: M) -> Option<Box<wasm_engine_t>> fn return_with_error<M>(msg: M) -> Option<Box<wasm_engine_t>>
@@ -408,7 +411,9 @@ pub extern "C" fn wasm_engine_new_with_config(
}); });
return None; return None;
}; }
let config = config?;
cfg_if! { cfg_if! {
if #[cfg(feature = "compiler")] { if #[cfg(feature = "compiler")] {
@@ -447,7 +452,13 @@ pub extern "C" fn wasm_engine_new_with_config(
wasmer_engine_t::JIT => { wasmer_engine_t::JIT => {
cfg_if! { cfg_if! {
if #[cfg(feature = "jit")] { if #[cfg(feature = "jit")] {
Arc::new(JIT::new(compiler_config).engine()) let mut builder = JIT::new(compiler_config);
if let Some(target) = config.target {
builder = builder.target(target.inner);
}
Arc::new(builder.engine())
} else { } else {
return return_with_error("Wasmer has not been compiled with the `jit` feature."); return return_with_error("Wasmer has not been compiled with the `jit` feature.");
} }
@@ -456,7 +467,13 @@ pub extern "C" fn wasm_engine_new_with_config(
wasmer_engine_t::NATIVE => { wasmer_engine_t::NATIVE => {
cfg_if! { cfg_if! {
if #[cfg(feature = "native")] { if #[cfg(feature = "native")] {
Arc::new(Native::new(compiler_config).engine()) let mut builder = Native::new(compiler_config);
if let Some(target) = config.target {
builder = builder.target(target.inner);
}
Arc::new(builder.engine())
} else { } else {
return return_with_error("Wasmer has not been compiled with the `native` feature."); return return_with_error("Wasmer has not been compiled with the `native` feature.");
} }
@@ -467,7 +484,13 @@ pub extern "C" fn wasm_engine_new_with_config(
// There are currently no uses of the object-file engine + compiler from the C API. // There are currently no uses of the object-file engine + compiler from the C API.
// So we run in headless mode. // So we run in headless mode.
if #[cfg(feature = "object-file")] { if #[cfg(feature = "object-file")] {
Arc::new(ObjectFile::headless().engine()) let mut builder = ObjectFile::headless();
if let Some(target) = config.target {
builder = builder.target(target.inner);
}
Arc::new(builder.engine())
} else { } else {
return return_with_error("Wasmer has not been compiled with the `object-file` feature."); return return_with_error("Wasmer has not been compiled with the `object-file` feature.");
} }
@@ -480,7 +503,13 @@ pub extern "C" fn wasm_engine_new_with_config(
wasmer_engine_t::JIT => { wasmer_engine_t::JIT => {
cfg_if! { cfg_if! {
if #[cfg(feature = "jit")] { if #[cfg(feature = "jit")] {
Arc::new(JIT::headless().engine()) let mut builder = JIT::headless();
if let Some(target) = config.target {
builder = builder.target(target.inner);
}
Arc::new(builder.engine())
} else { } else {
return return_with_error("Wasmer has not been compiled with the `jit` feature."); return return_with_error("Wasmer has not been compiled with the `jit` feature.");
} }
@@ -489,7 +518,13 @@ pub extern "C" fn wasm_engine_new_with_config(
wasmer_engine_t::NATIVE => { wasmer_engine_t::NATIVE => {
cfg_if! { cfg_if! {
if #[cfg(feature = "native")] { if #[cfg(feature = "native")] {
Arc::new(Native::headless().engine()) let mut builder = Native::headless();
if let Some(target) = config.target {
builder = builder.target(target.inner);
}
Arc::new(builder.engine())
} else { } else {
return return_with_error("Wasmer has not been compiled with the `native` feature."); return return_with_error("Wasmer has not been compiled with the `native` feature.");
} }
@@ -498,7 +533,13 @@ pub extern "C" fn wasm_engine_new_with_config(
wasmer_engine_t::OBJECT_FILE => { wasmer_engine_t::OBJECT_FILE => {
cfg_if! { cfg_if! {
if #[cfg(feature = "object-file")] { if #[cfg(feature = "object-file")] {
Arc::new(ObjectFile::headless().engine()) let mut builder = ObjectFile::headless();
if let Some(target) = config.target {
builder = builder.target(target.inner);
}
Arc::new(builder.engine())
} else { } else {
return return_with_error("Wasmer has not been compiled with the `object-file` feature."); return return_with_error("Wasmer has not been compiled with the `object-file` feature.");
} }

View File

@@ -105,8 +105,8 @@ pub unsafe extern "C" fn wasm_func_new_with_env(
#[repr(C)] #[repr(C)]
struct WrapperEnv { struct WrapperEnv {
env: *mut c_void, env: *mut c_void,
finalizer: Option<wasm_env_finalizer_t>, finalizer: Arc<Option<wasm_env_finalizer_t>>,
}; }
// Only relevant when using multiple threads in the C API; // Only relevant when using multiple threads in the C API;
// Synchronization will be done via the C API / on the C side. // Synchronization will be done via the C API / on the C side.
@@ -115,11 +115,16 @@ pub unsafe extern "C" fn wasm_func_new_with_env(
impl Drop for WrapperEnv { impl Drop for WrapperEnv {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(finalizer) = self.finalizer { if let Some(finalizer) = Arc::get_mut(&mut self.finalizer)
.map(Option::take)
.flatten()
{
if !self.env.is_null() {
unsafe { (finalizer)(self.env as _) } unsafe { (finalizer)(self.env as _) }
} }
} }
} }
}
let inner_callback = move |env: &WrapperEnv, args: &[Val]| -> Result<Vec<Val>, RuntimeError> { let inner_callback = move |env: &WrapperEnv, args: &[Val]| -> Result<Vec<Val>, RuntimeError> {
let processed_args: wasm_val_vec_t = args let processed_args: wasm_val_vec_t = args
@@ -160,7 +165,10 @@ pub unsafe extern "C" fn wasm_func_new_with_env(
let function = Function::new_with_env( let function = Function::new_with_env(
&store.inner, &store.inner,
func_sig, func_sig,
WrapperEnv { env, finalizer }, WrapperEnv {
env,
finalizer: Arc::new(finalizer),
},
inner_callback, inner_callback,
); );

View File

@@ -467,16 +467,19 @@ macro_rules! wasm_declare_own {
#[macro_export] #[macro_export]
macro_rules! c_try { macro_rules! c_try {
($expr:expr) => {{ ($expr:expr; otherwise $return:expr) => {{
let res: Result<_, _> = $expr; let res: Result<_, _> = $expr;
match res { match res {
Ok(val) => val, Ok(val) => val,
Err(err) => { Err(err) => {
crate::error::update_last_error(err); crate::error::update_last_error(err);
return None; return $return;
} }
} }
}}; }};
($expr:expr) => {{
c_try!($expr; otherwise None)
}};
($expr:expr, $e:expr) => {{ ($expr:expr, $e:expr) => {{
let opt: Option<_> = $expr; let opt: Option<_> = $expr;
c_try!(opt.ok_or_else(|| $e)) c_try!(opt.ok_or_else(|| $e))

View File

@@ -0,0 +1,49 @@
//! Unstable non-standard Wasmer-specific types for the
//! `wasm_engine_t` and siblings.
use super::super::engine::wasm_config_t;
use super::target_lexicon::wasm_target_t;
/// Unstable non-standard Wasmer-specific API to update the
/// configuration to specify a particular target for the engine.
///
/// # Example
///
/// ```rust
/// # use inline_c::assert_c;
/// # fn main() {
/// # (assert_c! {
/// # #include "tests/wasmer_wasm.h"
/// #
/// int main() {
/// // Create the configuration.
/// wasm_config_t* config = wasm_config_new();
///
/// // Set the target.
/// {
/// wasm_triple_t* triple = wasm_triple_new_from_host();
/// wasm_cpu_features_t* cpu_features = wasm_cpu_features_new();
/// wasm_target_t* target = wasm_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]
pub extern "C" fn wasm_config_set_target(config: &mut wasm_config_t, target: Box<wasm_target_t>) {
config.target = Some(target);
}

View File

@@ -1 +1,3 @@
pub mod engine;
pub mod module; pub mod module;
pub mod target_lexicon;

View File

@@ -0,0 +1,314 @@
//! Unstable non-standard Wasmer-specific API that contains everything
//! to create a target with a triple and CPU features.
//!
//! This is useful for cross-compilation.
//!
//! # Example
//!
//! ```rust
//! # use inline_c::assert_c;
//! # fn main() {
//! # (assert_c! {
//! # #include "tests/wasmer_wasm.h"
//! #
//! int main() {
//! // Declare the target triple.
//! wasm_triple_t* triple;
//!
//! {
//! wasm_name_t triple_name;
//! wasm_name_new_from_string(&triple_name, "x86_64-apple-darwin");
//!
//! triple = wasm_triple_new(&triple_name);
//!
//! wasm_name_delete(&triple_name);
//! }
//!
//! assert(triple);
//!
//! // Declare the target CPU features.
//! wasm_cpu_features_t* cpu_features = wasm_cpu_features_new();
//!
//! {
//! wasm_name_t cpu_feature_name;
//! wasm_name_new_from_string(&cpu_feature_name, "sse2");
//!
//! wasm_cpu_features_add(cpu_features, &cpu_feature_name);
//!
//! wasm_name_delete(&cpu_feature_name);
//! }
//!
//! assert(cpu_features);
//!
//! // Create the target!
//! wasm_target_t* target = wasm_target_new(triple, cpu_features);
//! assert(target);
//!
//! wasm_target_delete(target);
//!
//! return 0;
//! }
//! # })
//! # .success();
//! # }
//! ```
use super::super::types::wasm_name_t;
use crate::error::CApiError;
use enumset::EnumSet;
use std::slice;
use std::str::{self, FromStr};
use wasmer_compiler::{CpuFeature, Target, Triple};
/// Unstable non-standard Wasmer-specific API to represent a triple +
/// CPU features pair.
///
/// # Example
///
/// See the module's documentation.
#[derive(Debug)]
#[allow(non_camel_case_types)]
pub struct wasm_target_t {
pub(crate) inner: Target,
}
/// Creates a new [`wasm_target_t`].
///
/// It takes ownership of `triple` and `cpu_features`.
///
/// # Example
///
/// See the module's documentation.
#[no_mangle]
pub extern "C" fn wasm_target_new(
triple: Option<Box<wasm_triple_t>>,
cpu_features: Option<Box<wasm_cpu_features_t>>,
) -> Option<Box<wasm_target_t>> {
let triple = triple?;
let cpu_features = cpu_features?;
Some(Box::new(wasm_target_t {
inner: Target::new(triple.inner.clone(), cpu_features.inner.clone()),
}))
}
/// Delete a [`wasm_target_t`].
///
/// # Example
///
/// See the module's documentation.
#[no_mangle]
pub extern "C" fn wasm_target_delete(_target: Option<Box<wasm_target_t>>) {}
/// Unstable non-standard Wasmer-specific API to represent a target
/// “triple”.
///
/// Historically such things had three fields, though they have added
/// additional fields over time.
///
/// # Example
///
/// ```rust
/// # use inline_c::assert_c;
/// # fn main() {
/// # (assert_c! {
/// # #include "tests/wasmer_wasm.h"
/// #
/// int main() {
/// wasm_name_t triple_name;
/// wasm_name_new_from_string(&triple_name, "x86_64-apple-darwin");
///
/// wasm_triple_t* triple = wasm_triple_new(&triple_name);
/// assert(triple);
///
/// wasm_triple_delete(triple);
/// wasm_name_delete(&triple_name);
///
/// return 0;
/// }
/// # })
/// # .success();
/// # }
/// ```
///
/// See also [`wasm_triple_new_from_host`].
#[allow(non_camel_case_types)]
pub struct wasm_triple_t {
inner: Triple,
}
/// Create a new [`wasm_triple_t`] based on a triple string.
///
/// # Example
///
/// See [`wasm_triple_t`] or [`wasm_triple_new_from_host`].
#[no_mangle]
pub unsafe extern "C" fn wasm_triple_new(
triple: Option<&wasm_name_t>,
) -> Option<Box<wasm_triple_t>> {
let triple = triple?;
let triple = c_try!(str::from_utf8(slice::from_raw_parts(
triple.data,
triple.size
)));
Some(Box::new(wasm_triple_t {
inner: c_try!(Triple::from_str(triple).map_err(|e| CApiError { msg: e.to_string() })),
}))
}
/// Create the [`wasm_triple_t`] for the current host.
///
/// # Example
///
/// ```rust
/// # use inline_c::assert_c;
/// # fn main() {
/// # (assert_c! {
/// # #include "tests/wasmer_wasm.h"
/// #
/// int main() {
/// wasm_triple_t* triple = wasm_triple_new_from_host();
/// assert(triple);
///
/// wasm_triple_delete(triple);
///
/// return 0;
/// }
/// # })
/// # .success();
/// # }
/// ```
///
/// See also [`wasm_triple_new`].
#[no_mangle]
pub extern "C" fn wasm_triple_new_from_host() -> Box<wasm_triple_t> {
Box::new(wasm_triple_t {
inner: Triple::host(),
})
}
/// Delete a [`wasm_triple_t`].
///
/// # Example
///
/// See [`wasm_triple_t`].
#[no_mangle]
pub extern "C" fn wasm_triple_delete(_triple: Option<Box<wasm_triple_t>>) {}
/// Unstable non-standard Wasmer-specific API to represent a set of
/// CPU features.
///
/// CPU features are identified by their stringified names. The
/// reference is the GCC options:
///
/// * <https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html>,
/// * <https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html>,
/// * <https://gcc.gnu.org/onlinedocs/gcc/AArch64-Options.html>.
///
/// At the time of writing this documentation (it might be outdated in
/// the future), the supported features are the following:
///
/// * `sse2`,
/// * `sse3`,
/// * `ssse3`,
/// * `sse4.1`,
/// * `sse4.2`,
/// * `popcnt`,
/// * `avx`,
/// * `bmi`,
/// * `bmi2`,
/// * `avx2`,
/// * `avx512dq`,
/// * `avx512vl`,
/// * `lzcnt`.
///
/// # Example
///
/// ```rust
/// # use inline_c::assert_c;
/// # fn main() {
/// # (assert_c! {
/// # #include "tests/wasmer_wasm.h"
/// #
/// int main() {
/// // Create a new CPU feature set.
/// wasm_cpu_features_t* cpu_features = wasm_cpu_features_new();
///
/// // Create a new feature name, here `sse2`, and add it to the set.
/// {
/// wasm_name_t cpu_feature_name;
/// wasm_name_new_from_string(&cpu_feature_name, "sse2");
///
/// wasm_cpu_features_add(cpu_features, &cpu_feature_name);
///
/// wasm_name_delete(&cpu_feature_name);
/// }
///
/// wasm_cpu_features_delete(cpu_features);
///
/// return 0;
/// }
/// # })
/// # .success();
/// # }
/// ```
#[allow(non_camel_case_types)]
pub struct wasm_cpu_features_t {
inner: EnumSet<CpuFeature>,
}
/// Create a new [`wasm_cpu_features_t`].
///
/// # Example
///
/// See [`wasm_cpu_features_t`].
#[no_mangle]
pub extern "C" fn wasm_cpu_features_new() -> Box<wasm_cpu_features_t> {
Box::new(wasm_cpu_features_t {
inner: CpuFeature::set(),
})
}
/// Delete a [`wasm_cpu_features_t`].
///
/// # Example
///
/// See [`wasm_cpu_features_t`].
#[no_mangle]
pub extern "C" fn wasm_cpu_features_delete(_cpu_features: Option<Box<wasm_cpu_features_t>>) {}
/// Add a new CPU feature into the set represented by
/// [`wasm_cpu_features_t`].
///
/// # Example
///
/// See [`wasm_cpu_features_t`].
#[no_mangle]
pub unsafe extern "C" fn wasm_cpu_features_add(
cpu_features: Option<&mut wasm_cpu_features_t>,
feature: Option<&wasm_name_t>,
) -> bool {
let cpu_features = match cpu_features {
Some(cpu_features) => cpu_features,
_ => return false,
};
let feature = match feature {
Some(feature) => feature,
_ => return false,
};
let feature = c_try!(
str::from_utf8(slice::from_raw_parts(
feature.data,
feature.size + 1,
));
otherwise false
);
cpu_features.inner.insert(c_try!(
CpuFeature::from_str(feature);
otherwise false
));
true
}

View File

@@ -204,7 +204,7 @@ pub extern "C" fn wasi_env_delete(_state: Option<Box<wasi_env_t>>) {}
/// This function is deprecated. You may safely remove all calls to it and everything /// This function is deprecated. You may safely remove all calls to it and everything
/// will continue to work. /// will continue to work.
/// ///
/// cbindgen:prefix=DEPRECATED("This function is longer necessary. You may safely remove all calls to it and everything will continue to work.") /// cbindgen:prefix=DEPRECATED("This function is no longer necessary. You may safely remove all calls to it and everything will continue to work.")
#[no_mangle] #[no_mangle]
pub extern "C" fn wasi_env_set_instance( pub extern "C" fn wasi_env_set_instance(
_env: &mut wasi_env_t, _env: &mut wasi_env_t,

View File

@@ -134,10 +134,16 @@ typedef struct wasi_config_t wasi_config_t;
typedef struct wasi_env_t wasi_env_t; typedef struct wasi_env_t wasi_env_t;
#endif #endif
typedef struct wasm_cpu_features_t wasm_cpu_features_t;
#if defined(WASMER_WASI_ENABLED) #if defined(WASMER_WASI_ENABLED)
typedef struct wasm_named_extern_t wasm_named_extern_t; typedef struct wasm_named_extern_t wasm_named_extern_t;
#endif #endif
typedef struct wasm_target_t wasm_target_t;
typedef struct wasm_triple_t wasm_triple_t;
#if defined(WASMER_WASI_ENABLED) #if defined(WASMER_WASI_ENABLED)
typedef struct { typedef struct {
uintptr_t size; uintptr_t size;
@@ -206,7 +212,7 @@ intptr_t wasi_env_read_stdout(wasi_env_t *env, char *buffer, uintptr_t buffer_le
#endif #endif
#if defined(WASMER_WASI_ENABLED) #if defined(WASMER_WASI_ENABLED)
DEPRECATED("This function is longer necessary. You may safely remove all calls to it and everything will continue to work.") DEPRECATED("This function is no longer necessary. You may safely remove all calls to it and everything will continue to work.")
bool wasi_env_set_instance(wasi_env_t *_env, bool wasi_env_set_instance(wasi_env_t *_env,
const wasm_instance_t *_instance); const wasm_instance_t *_instance);
#endif #endif
@@ -245,6 +251,14 @@ void wasm_config_set_compiler(wasm_config_t *config, wasmer_compiler_t compiler)
void wasm_config_set_engine(wasm_config_t *config, wasmer_engine_t engine); void wasm_config_set_engine(wasm_config_t *config, wasmer_engine_t engine);
void wasm_config_set_target(wasm_config_t *config, wasm_target_t *target);
bool wasm_cpu_features_add(wasm_cpu_features_t *cpu_features, const wasm_name_t *feature);
void wasm_cpu_features_delete(wasm_cpu_features_t *_cpu_features);
wasm_cpu_features_t *wasm_cpu_features_new(void);
void wasm_module_name(const wasm_module_t *module, wasm_name_t *out); void wasm_module_name(const wasm_module_t *module, wasm_name_t *out);
bool wasm_module_set_name(wasm_module_t *module, const wasm_name_t *name); bool wasm_module_set_name(wasm_module_t *module, const wasm_name_t *name);
@@ -284,6 +298,16 @@ void wasm_named_extern_vec_new_empty(wasm_named_extern_vec_t *out);
void wasm_named_extern_vec_new_uninitialized(wasm_named_extern_vec_t *out, uintptr_t length); void wasm_named_extern_vec_new_uninitialized(wasm_named_extern_vec_t *out, uintptr_t length);
#endif #endif
void wasm_target_delete(wasm_target_t *_target);
wasm_target_t *wasm_target_new(wasm_triple_t *triple, wasm_cpu_features_t *cpu_features);
void wasm_triple_delete(wasm_triple_t *_triple);
wasm_triple_t *wasm_triple_new(const wasm_name_t *triple);
wasm_triple_t *wasm_triple_new_from_host(void);
int wasmer_last_error_length(void); int wasmer_last_error_length(void);
int wasmer_last_error_message(char *buffer, int length); int wasmer_last_error_message(char *buffer, int length);

View File

@@ -24,9 +24,9 @@ itertools = "0.9"
rayon = "1.5" rayon = "1.5"
[dependencies.inkwell] [dependencies.inkwell]
version = "=0.1.0-llvm10sample" version = "=0.1.0-beta.2"
default-features = false default-features = false
features = ["llvm10-0", "target-x86", "target-aarch64"] features = ["llvm11-0", "target-x86", "target-aarch64"]
[build-dependencies] [build-dependencies]
cc = "1.0" cc = "1.0"

View File

@@ -5674,13 +5674,7 @@ impl<'a> FuncGen<'a> {
); );
self.emit_call_sysv( self.emit_call_sysv(
|this| { |this| {
let label = this.assembler.get_label(); this.assembler.emit_call_register(GPR::RAX);
let after = this.assembler.get_label();
this.assembler.emit_jmp(Condition::None, after);
this.assembler.emit_label(label);
this.assembler.emit_host_redirection(GPR::RAX);
this.assembler.emit_label(after);
this.assembler.emit_call_label(label);
}, },
// [vmctx, memory_index] // [vmctx, memory_index]
iter::once(Location::Imm32(memory_index.index() as u32)), iter::once(Location::Imm32(memory_index.index() as u32)),
@@ -5719,13 +5713,7 @@ impl<'a> FuncGen<'a> {
self.emit_call_sysv( self.emit_call_sysv(
|this| { |this| {
let label = this.assembler.get_label(); this.assembler.emit_call_register(GPR::RAX);
let after = this.assembler.get_label();
this.assembler.emit_jmp(Condition::None, after);
this.assembler.emit_label(label);
this.assembler.emit_host_redirection(GPR::RAX);
this.assembler.emit_label(after);
this.assembler.emit_call_label(label);
}, },
// [vmctx, val, memory_index] // [vmctx, val, memory_index]
iter::once(param_pages) iter::once(param_pages)

View File

@@ -205,6 +205,8 @@ pub trait Emitter {
fn emit_call_label(&mut self, label: Self::Label); fn emit_call_label(&mut self, label: Self::Label);
fn emit_call_location(&mut self, loc: Location); fn emit_call_location(&mut self, loc: Location);
fn emit_call_register(&mut self, reg: GPR);
fn emit_bkpt(&mut self); fn emit_bkpt(&mut self);
fn emit_host_redirection(&mut self, target: GPR); fn emit_host_redirection(&mut self, target: GPR);
@@ -1389,6 +1391,10 @@ impl Emitter for Assembler {
} }
} }
fn emit_call_register(&mut self, reg: GPR) {
dynasm!(self ; call Rq(reg as u8));
}
fn emit_bkpt(&mut self) { fn emit_bkpt(&mut self) {
dynasm!(self ; int 0x3); dynasm!(self ; int 0x3);
} }