Skip to content

Commit

Permalink
Try #2053:
Browse files Browse the repository at this point in the history
  • Loading branch information
bors[bot] authored Feb 2, 2021
2 parents 63acc46 + e5d5303 commit bcbaa74
Show file tree
Hide file tree
Showing 9 changed files with 379 additions and 75 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
- [#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.
- [#2040](https://github.com/wasmerio/wasmer/pull/2040) Add `InstanceHandle::vmoffsets` to expose the offsets of the `vmctx` region.
Expand Down
40 changes: 26 additions & 14 deletions lib/c-api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,23 +61,21 @@ macro_rules! map_feature_as_c_define {
}

fn main() {
if !running_self() {
return;
}

let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let out_dir = env::var("OUT_DIR").unwrap();

if building_c_api_headers() {
build_wasm_c_api_headers(&crate_dir, &out_dir);
build_wasmer_c_api_headers(&crate_dir, &out_dir);
}

build_wasm_c_api_headers(&crate_dir, &out_dir);
build_wasmer_c_api_headers(&crate_dir, &out_dir);
build_inline_c_env_vars();
}

/// Check whether we should build the C API headers.
///
/// For the moment, it's always enabled, unless if the `DOCS_RS`
/// environment variable is present.
fn building_c_api_headers() -> bool {
env::var("DOCS_RS").is_err()
/// Check whether we should build the C API headers or set `inline-c` up.
fn running_self() -> bool {
env::var("DOCS_RS").is_err() && env::var("_CBINDGEN_IS_RUNNING").is_err()
}

/// Build the header files for the `wasm_c_api` API.
Expand Down Expand Up @@ -274,7 +272,7 @@ fn add_wasmer_version(pre_header: &mut String) {

/// Create a fresh new `Builder`, already pre-configured.
fn new_builder(language: Language, crate_dir: &str, include_guard: &str, header: &str) -> Builder {
Builder::new()
let builder = Builder::new()
.with_config(cbindgen::Config {
sort_by: cbindgen::SortKey::Name,
cpp_compat: true,
Expand All @@ -290,7 +288,12 @@ fn new_builder(language: Language, crate_dir: &str, include_guard: &str, header:
.with_define("feature", "jit", JIT_FEATURE_AS_C_DEFINE)
.with_define("feature", "compiler", COMPILER_FEATURE_AS_C_DEFINE)
.with_define("feature", "wasi", WASI_FEATURE_AS_C_DEFINE)
.with_define("feature", "emscripten", EMSCRIPTEN_FEATURE_AS_C_DEFINE)
.with_define("feature", "emscripten", EMSCRIPTEN_FEATURE_AS_C_DEFINE);

#[cfg(feature = "system-libffi")]
let builder = builder.with_parse_expand_features(&["system-libffi"]);

builder
}

/// Exclude types and functions from the `deprecated` API.
Expand Down Expand Up @@ -458,8 +461,8 @@ fn exclude_items_from_wasm_c_api(builder: Builder) -> Builder {
.exclude_item("wasi_env_set_memory")
.exclude_item("wasi_env_t")
.exclude_item("wasi_get_imports")
.exclude_item("wasi_get_imports_inner")
.exclude_item("wasi_get_start_function")
.exclude_item("wasi_get_unordered_imports")
.exclude_item("wasi_get_wasi_version")
.exclude_item("wasi_version_t")
.exclude_item("wasm_config_set_compiler")
Expand All @@ -471,6 +474,15 @@ fn exclude_items_from_wasm_c_api(builder: Builder) -> Builder {
.exclude_item("wasm_cpu_features_t")
.exclude_item("wasm_module_name")
.exclude_item("wasm_module_set_name")
.exclude_item("wasm_named_extern_module")
.exclude_item("wasm_named_extern_name")
.exclude_item("wasm_named_extern_t")
.exclude_item("wasm_named_extern_unwrap")
.exclude_item("wasm_named_extern_vec_copy")
.exclude_item("wasm_named_extern_vec_delete")
.exclude_item("wasm_named_extern_vec_new")
.exclude_item("wasm_named_extern_vec_new_empty")
.exclude_item("wasm_named_extern_vec_new_uninitialized")
.exclude_item("wasm_target_delete")
.exclude_item("wasm_target_new")
.exclude_item("wasm_target_t")
Expand Down
67 changes: 67 additions & 0 deletions lib/c-api/src/wasm_c_api/externals/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ pub struct wasm_extern_t {

wasm_declare_boxed_vec!(extern);

/// Copy a `wasm_extern_t`.
#[no_mangle]
pub unsafe extern "C" fn wasm_extern_copy(r#extern: &wasm_extern_t) -> Box<wasm_extern_t> {
Box::new(r#extern.clone())
}

/// Delete an extern.
#[no_mangle]
pub unsafe extern "C" fn wasm_extern_delete(_extern: Option<Box<wasm_extern_t>>) {}

#[no_mangle]
pub unsafe extern "C" fn wasm_func_as_extern(
func: Option<&wasm_func_t>,
Expand Down Expand Up @@ -125,3 +135,60 @@ pub unsafe extern "C" fn wasm_extern_as_table(
None
}
}

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

#[test]
fn test_extern_copy() {
(assert_c! {
#include "tests/wasmer_wasm.h"

int main() {
wasm_engine_t* engine = wasm_engine_new();
wasm_store_t* store = wasm_store_new(engine);

wasm_byte_vec_t wat;
wasmer_byte_vec_new_from_string(
&wat,
"(module\n"
" (func (export \"function\")))"
);
wasm_byte_vec_t wasm;
wat2wasm(&wat, &wasm);

wasm_module_t* module = wasm_module_new(store, &wasm);
assert(module);

wasm_extern_vec_t imports = WASM_EMPTY_VEC;
wasm_trap_t* traps = NULL;

wasm_instance_t* instance = wasm_instance_new(store, module, &imports, &traps);
assert(instance);

wasm_extern_vec_t exports;
wasm_instance_exports(instance, &exports);

assert(exports.size == 1);

wasm_extern_t* function = exports.data[0];
assert(wasm_extern_kind(function) == WASM_EXTERN_FUNC);

wasm_extern_t* function_copy = wasm_extern_copy(function);
assert(wasm_extern_kind(function_copy) == WASM_EXTERN_FUNC);

wasm_extern_delete(function_copy);
wasm_instance_delete(instance);
wasm_module_delete(module);
wasm_byte_vec_delete(&wasm);
wasm_byte_vec_delete(&wat);
wasm_store_delete(store);
wasm_engine_delete(engine);

return 0;
}
})
.success();
}
}
2 changes: 1 addition & 1 deletion lib/c-api/src/wasm_c_api/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ int main() {
#[no_mangle]
pub unsafe extern "C" fn [<wasm_ $name _vec_copy>](
out_ptr: &mut [<wasm_ $name _vec_t>],
in_ptr: & [<wasm _$name _vec_t>])
in_ptr: & [<wasm_ $name _vec_t>])
{
*out_ptr = in_ptr.clone();
}
Expand Down
16 changes: 2 additions & 14 deletions lib/c-api/src/wasm_c_api/types/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,8 @@ impl From<ExportType> for wasm_exporttype_t {

impl From<&ExportType> for wasm_exporttype_t {
fn from(other: &ExportType) -> Self {
let name = {
let mut heap_str: Box<str> = other.name().to_string().into_boxed_str();
let char_ptr = heap_str.as_mut_ptr();
let str_len = heap_str.bytes().len();
let name_inner = wasm_name_t {
size: str_len,
data: char_ptr,
};
Box::leak(heap_str);

Box::new(name_inner)
};

let extern_type = Box::new(other.ty().into());
let name: Box<wasm_name_t> = Box::new(other.name().to_string().into());
let extern_type: Box<wasm_externtype_t> = Box::new(other.ty().into());

wasm_exporttype_t { name, extern_type }
}
Expand Down
32 changes: 4 additions & 28 deletions lib/c-api/src/wasm_c_api/types/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,37 +50,13 @@ impl From<ImportType> for wasm_importtype_t {

impl From<&ImportType> for wasm_importtype_t {
fn from(other: &ImportType) -> Self {
let module = {
let mut heap_str: Box<str> = other.module().to_string().into_boxed_str();
let char_ptr = heap_str.as_mut_ptr();
let str_len = heap_str.bytes().len();
let module_inner = wasm_name_t {
size: str_len,
data: char_ptr,
};
Box::leak(heap_str);

Box::new(module_inner)
};

let name = {
let mut heap_str: Box<str> = other.name().to_string().into_boxed_str();
let char_ptr = heap_str.as_mut_ptr();
let str_len = heap_str.bytes().len();
let name_inner = wasm_name_t {
size: str_len,
data: char_ptr,
};
Box::leak(heap_str);

Box::new(name_inner)
};

let extern_type = Box::new(other.ty().into());
let module: Box<wasm_name_t> = Box::new(other.module().to_string().into());
let name: Box<wasm_name_t> = Box::new(other.name().to_string().into());
let extern_type: Box<wasm_externtype_t> = Box::new(other.ty().into());

wasm_importtype_t {
name,
module,
name,
extern_type,
}
}
Expand Down
13 changes: 13 additions & 0 deletions lib/c-api/src/wasm_c_api/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,19 @@ wasm_declare_vec!(byte);
#[allow(non_camel_case_types)]
pub type wasm_name_t = wasm_byte_vec_t;

impl From<String> for wasm_name_t {
fn from(string: String) -> Self {
let mut boxed_str: Box<str> = string.into_boxed_str();
let data = boxed_str.as_mut_ptr();
let size = boxed_str.bytes().len();
let wasm_name = Self { data, size };

Box::leak(boxed_str);

wasm_name
}
}

// opaque type over `ExternRef`?
#[allow(non_camel_case_types)]
pub struct wasm_ref_t;
Expand Down
Loading

0 comments on commit bcbaa74

Please sign in to comment.