Skip to content

Commit

Permalink
Merge #2118
Browse files Browse the repository at this point in the history
2118: feat(c-api) Add an unstable non-standard API to query available engines and compilers r=Hywan a=Hywan

# Description

This patch adds 3 unstable non-standard C functions:

* `wasmer_is_headless`,
* `wasmer_is_compiler_available`,
* `wasmer_is_engine_available`.

The rest of the patch adds tests, documentations, update existing tests, small stuf like that that can now be possible thanks to this new API.

I've also released a new version of `inline-c` to remove a warning with the latest `rustc` version.

# Review

- [x] Add a short description of the the change to the CHANGELOG.md file


Co-authored-by: Ivan Enderlin <[email protected]>
  • Loading branch information
bors[bot] and Hywan authored Feb 12, 2021
2 parents 40bdfa4 + ee79348 commit 4f28b2b
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 23 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
## **[Unreleased]**

### Added
- [#2118](https://github.com/wasmerio/wasmer/pull/2118) Add an unstable non-standard C API to query available engines and compilers.

### Changed

Expand Down
19 changes: 11 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -299,11 +299,11 @@ test-capi-cranelift-native: build-capi-cranelift-native test-capi-tests
cargo test --manifest-path lib/c-api/Cargo.toml --release \
--no-default-features --features deprecated,wat,native,cranelift,wasi $(capi_default_features) -- --nocapture

test-capi-llvm-jit:
test-capi-llvm-jit: build-capi-llvm-jit test-capi-tests
cargo test --manifest-path lib/c-api/Cargo.toml --release \
--no-default-features --features deprecated,wat,jit,llvm,wasi $(capi_default_features) -- --nocapture

test-capi-llvm-native:
test-capi-llvm-native: build-capi-llvm-native test-capi-tests
cargo test --manifest-path lib/c-api/Cargo.toml --release \
--no-default-features --features deprecated,wat,native,llvm,wasi $(capi_default_features) -- --nocapture

Expand Down
5 changes: 1 addition & 4 deletions lib/c-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,9 @@ serde = { version = "1", optional = true, features = ["derive"] }
thiserror = "1"
typetag = { version = "0.1", optional = true }
paste = "1.0"
# for generating code in the same way thot the wasm-c-api does
# Commented out for now until we can find a solution to the exported function problem
# wasmer-wasm-c-api = { version = "1.0.2", path = "crates/wasm-c-api" }

[dev-dependencies]
inline-c = "0.1.4"
inline-c = "0.1.5"

[features]
default = [
Expand Down
9 changes: 8 additions & 1 deletion lib/c-api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,9 @@ fn exclude_items_from_wasm_c_api(builder: Builder) -> Builder {
.exclude_item("wasm_triple_t")
.exclude_item("wasmer_compiler_t")
.exclude_item("wasmer_engine_t")
.exclude_item("wasmer_is_compiler_available")
.exclude_item("wasmer_is_engine_available")
.exclude_item("wasmer_is_headless")
.exclude_item("wat2wasm")
}

Expand Down Expand Up @@ -525,6 +528,7 @@ fn build_inline_c_env_vars() {
let target = env::var("TARGET").unwrap();
assert_eq!(shared_object_dir.file_name(), Some(OsStr::new(&target)));
}

shared_object_dir.push(env::var("PROFILE").unwrap());

let shared_object_dir = shared_object_dir.as_path().to_string_lossy();
Expand All @@ -535,8 +539,11 @@ fn build_inline_c_env_vars() {
// * `-I`, add `include_dir` to include search path,
// * `-L`, add `shared_object_dir` to library search path,
// * `-D_DEBUG`, enable debug mode to enable `assert.h`.
// * `-D_CRT_SECURE_NO_WARNINGS`, disable security features in the
// Windows C runtime, which allows to use `getenv` without any
// warnings.
println!(
"cargo:rustc-env=INLINE_C_RS_CFLAGS=-I{I} -L{L} -D_DEBUG",
"cargo:rustc-env=INLINE_C_RS_CFLAGS=-I{I} -L{L} -D_DEBUG -D_CRT_SECURE_NO_WARNINGS",
I = include_dir,
L = shared_object_dir.clone(),
);
Expand Down
34 changes: 27 additions & 7 deletions lib/c-api/src/wasm_c_api/engine.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
pub use super::unstable::engine::wasm_config_set_target;
pub use super::unstable::engine::{
wasm_config_set_target, wasmer_is_compiler_available, wasmer_is_engine_available,
};
use super::unstable::target_lexicon::wasm_target_t;
use crate::error::{update_last_error, CApiError};
use cfg_if::cfg_if;
Expand Down Expand Up @@ -170,7 +172,7 @@ pub extern "C" fn wasm_config_delete(_config: Option<Box<wasm_config_t>>) {}
///
/// # Example
///
/// ```rust,no_run
/// ```rust
/// # use inline_c::assert_c;
/// # fn main() {
/// # (assert_c! {
Expand All @@ -180,8 +182,19 @@ pub extern "C" fn wasm_config_delete(_config: Option<Box<wasm_config_t>>) {}
/// // Create the configuration.
/// wasm_config_t* config = wasm_config_new();
///
/// // Use the Cranelift compiler.
/// wasm_config_set_compiler(config, CRANELIFT);
/// // 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);
Expand Down Expand Up @@ -213,7 +226,7 @@ pub extern "C" fn wasm_config_set_compiler(
///
/// # Example
///
/// ```rust,no_run
/// ```rust
/// # use inline_c::assert_c;
/// # fn main() {
/// # (assert_c! {
Expand All @@ -223,8 +236,15 @@ pub extern "C" fn wasm_config_set_compiler(
/// // Create the configuration.
/// wasm_config_t* config = wasm_config_new();
///
/// // Use the JIT engine.
/// wasm_config_set_engine(config, JIT);
/// // Use the JIT engine, if available.
/// if (wasmer_is_engine_available(JIT)) {
/// wasm_config_set_engine(config, JIT);
/// }
/// // Or maybe the Native engine?
/// else if (wasmer_is_engine_available(NATIVE)) {
/// wasm_config_set_engine(config, NATIVE);
/// }
/// // OK, let's do not specify any particular engine.
///
/// // Create the engine.
/// wasm_engine_t* engine = wasm_engine_new_with_config(config);
Expand Down
132 changes: 131 additions & 1 deletion lib/c-api/src/wasm_c_api/unstable/engine.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Unstable non-standard Wasmer-specific types for the
//! `wasm_engine_t` and siblings.
use super::super::engine::wasm_config_t;
use super::super::engine::{wasm_config_t, wasmer_compiler_t, wasmer_engine_t};
use super::target_lexicon::wasm_target_t;

/// Unstable non-standard Wasmer-specific API to update the
Expand Down Expand Up @@ -47,3 +47,133 @@ use super::target_lexicon::wasm_target_t;
pub extern "C" fn wasm_config_set_target(config: &mut wasm_config_t, target: Box<wasm_target_t>) {
config.target = Some(target);
}

/// Check whether the given compiler is available, i.e. part of this
/// compiled library.
#[no_mangle]
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
/// library.
#[no_mangle]
pub extern "C" fn wasmer_is_headless() -> bool {
!cfg!(feature = "compiler")
}

/// Check whether the given engine is available, i.e. part of this
/// compiled library.
#[no_mangle]
pub extern "C" fn wasmer_is_engine_available(engine: wasmer_engine_t) -> bool {
match engine {
wasmer_engine_t::JIT if cfg!(feature = "jit") => true,
wasmer_engine_t::NATIVE if cfg!(feature = "native") => true,
wasmer_engine_t::OBJECT_FILE if cfg!(feature = "object-file") => true,
_ => false,
}
}

#[cfg(test)]
mod tests {
use inline_c::assert_c;
use std::env::{remove_var, set_var};

#[test]
fn test_wasmer_is_headless() {
set_var(
"COMPILER",
if cfg!(feature = "compiler") { "0" } else { "1" },
);

(assert_c! {
#include "tests/wasmer_wasm.h"
#include <stdlib.h>

int main() {
assert(wasmer_is_headless() == (getenv("COMPILER")[0] == '1'));

return 0;
}
})
.success();

remove_var("COMPILER");
}

#[test]
fn test_wasmer_is_compiler_available() {
set_var(
"CRANELIFT",
if cfg!(feature = "cranelift") {
"1"
} else {
"0"
},
);
set_var("LLVM", if cfg!(feature = "llvm") { "1" } else { "0" });
set_var(
"SINGLEPASS",
if cfg!(feature = "singlepass") {
"1"
} else {
"0"
},
);

(assert_c! {
#include "tests/wasmer_wasm.h"
#include <stdlib.h>

int main() {
assert(wasmer_is_compiler_available(CRANELIFT) == (getenv("CRANELIFT")[0] == '1'));
assert(wasmer_is_compiler_available(LLVM) == (getenv("LLVM")[0] == '1'));
assert(wasmer_is_compiler_available(SINGLEPASS) == (getenv("SINGLEPASS")[0] == '1'));

return 0;
}
})
.success();

remove_var("CRANELIFT");
remove_var("LLVM");
remove_var("SINGLEPASS");
}

#[test]
fn test_wasmer_is_engine_available() {
set_var("JIT", if cfg!(feature = "jit") { "1" } else { "0" });
set_var("NATIVE", if cfg!(feature = "native") { "1" } else { "0" });
set_var(
"OBJECT_FILE",
if cfg!(feature = "object-file") {
"1"
} else {
"0"
},
);

(assert_c! {
#include "tests/wasmer_wasm.h"
#include <stdlib.h>

int main() {
assert(wasmer_is_engine_available(JIT) == (getenv("JIT")[0] == '1'));
assert(wasmer_is_engine_available(NATIVE) == (getenv("NATIVE")[0] == '1'));
assert(wasmer_is_engine_available(OBJECT_FILE) == (getenv("OBJECT_FILE")[0] == '1'));

return 0;
}
})
.success();

remove_var("JIT");
remove_var("NATIVE");
remove_var("OBJECT_FILE");
}
}
6 changes: 6 additions & 0 deletions lib/c-api/wasmer_wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,12 @@ wasm_triple_t *wasm_triple_new(const wasm_name_t *triple);

wasm_triple_t *wasm_triple_new_from_host(void);

bool wasmer_is_compiler_available(wasmer_compiler_t compiler);

bool wasmer_is_engine_available(wasmer_engine_t engine);

bool wasmer_is_headless(void);

int wasmer_last_error_length(void);

int wasmer_last_error_message(char *buffer, int length);
Expand Down

0 comments on commit 4f28b2b

Please sign in to comment.