Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test+doc(c-api): Test and document the C A PI #1851

Merged
merged 20 commits into from
Dec 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

### Changed

- [#1851](https://github.com/wasmerio/wasmer/pull/1851) Improve test suite and documentation of the Wasmer C API
- [#1874](https://github.com/wasmerio/wasmer/pull/1874) Set `CompilerConfig` to be owned (following wasm-c-api)
- [#1880](https://github.com/wasmerio/wasmer/pull/1880) Remove cmake dependency for tests

Expand Down
206 changes: 193 additions & 13 deletions lib/c-api/src/wasm_c_api/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,76 @@ pub struct wasm_config_t {
compiler: wasmer_compiler_t,
}

/// Create a new Wasmer configuration.
/// Create a new default Wasmer configuration.
///
/// # 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();
///
/// // 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::new(wasm_config_t::default())
}

/// Configure the compiler to use.
/// Updates the configuration to specify a particular compiler to use.
Hywan marked this conversation as resolved.
Show resolved Hide resolved
///
/// This is a Wasmer-specific function.
///
/// # Example
///
/// ```rust,no_run
/// # 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();
///
/// // Use the Cranelift compiler.
/// wasm_config_set_compiler(config, CRANELIFT);
///
/// // 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(
Expand All @@ -97,7 +158,40 @@ pub extern "C" fn wasm_config_set_compiler(
config.compiler = compiler;
}

/// Configure the engine to use.
/// Updates the configuration to specify a particular engine to use.
Hywan marked this conversation as resolved.
Show resolved Hide resolved
///
/// This is a Wasmer-specific function.
///
/// # Example
///
/// ```rust,no_run
/// # 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();
///
/// // Use the JIT engine.
/// wasm_config_set_engine(config, JIT);
///
/// // 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;
Expand Down Expand Up @@ -132,33 +226,53 @@ fn get_default_compiler_config() -> Box<dyn CompilerConfig> {

cfg_if! {
if #[cfg(all(feature = "jit", feature = "compiler"))] {
/// Creates a new JIT 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: Arc<dyn Engine + Send + Sync> = Arc::new(JIT::new(compiler_config).engine());
Box::new(wasm_engine_t { inner: engine })
}
}
else if #[cfg(feature = "jit")] {
// Headless JIT
} else if #[cfg(feature = "jit")] {
/// Creates a new headless JIT engine.
///
/// # Example
///
/// See `wasm_engine_delete`.
///
/// cbindgen:ignore
#[no_mangle]
pub extern "C" fn wasm_engine_new() -> Box<wasm_engine_t> {
let engine: Arc<dyn Engine + Send + Sync> = Arc::new(JIT::headless().engine());
Box::new(wasm_engine_t { inner: engine })
}
}
else if #[cfg(all(feature = "native", feature = "compiler"))] {
} else if #[cfg(all(feature = "native", feature = "compiler"))] {
/// Creates a new native 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 mut compiler_config: Box<dyn CompilerConfig> = get_default_compiler_config();
let engine: Arc<dyn Engine + Send + Sync> = Arc::new(Native::new(compiler_config).engine());
Box::new(wasm_engine_t { inner: engine })
}
}
else if #[cfg(feature = "native")] {
} else if #[cfg(feature = "native")] {
/// Creates a new headless native engine.
///
/// # Example
///
/// See `wasm_engine_delete`.
///
/// cbindgen:ignore
#[no_mangle]
pub extern "C" fn wasm_engine_new() -> Box<wasm_engine_t> {
Expand All @@ -169,26 +283,70 @@ cfg_if! {
// There are currently no uses of the object-file engine + compiler from the C API.
// So if we get here, we default to headless mode regardless of if `compiler` is enabled.
else if #[cfg(feature = "object-file")] {
/// Creates a new headless object-file engine.
///
/// # Example
///
/// See `wasm_engine_delete`.
///
/// cbindgen:ignore
#[no_mangle]
pub extern "C" fn wasm_engine_new() -> Box<wasm_engine_t> {
let engine: Arc<dyn Engine + Send + Sync> = Arc::new(ObjectFile::headless().engine());
Box::new(wasm_engine_t { inner: engine })
}
}
else {
} 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!("The JITEngine is not attached; You might want to recompile `wasmer_c_api` with `--feature jit`");
unimplemented!("No engine attached; You might want to recompile `wasmer_c_api` with for example `--feature jit`");
}
}
}

/// Deletes an engine.
///
/// # Example
///
/// ```rust
/// # use inline_c::assert_c;
/// # fn main() {
/// # (assert_c! {
/// # #include "tests/wasmer_wasm.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(
Expand Down Expand Up @@ -305,3 +463,25 @@ pub extern "C" fn wasm_engine_new_with_config(
}
}
}

#[cfg(test)]
mod tests {
use inline_c::assert_c;

#[test]
fn test_engine_new() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this test really useful? It seems redundant with the examples from the documentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially wanted to improve this test, but our C API doesn't offer enough features. Let's keep this as is, and I'll improve it later.

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

int main() {
wasm_engine_t* engine = wasm_engine_new();
assert(engine);

wasm_engine_delete(engine);

return 0;
}
})
.success();
}
}
Loading