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

feat(c-api) Implement wasi_get_unordered_imports #2053

Merged
merged 26 commits into from
Feb 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
dc0cf7d
feat(c-api) Implement `wasi_get_unordered_imports`.
Hywan Jan 25, 2021
00bf74c
chore(c-api) Reorder field for the sake of consistency.
Hywan Jan 25, 2021
0ad4d31
chore(c-api) Update headers.
Hywan Jan 25, 2021
ffd07bc
feat(c-api) Expand macros of the crate when generating C bindings.
Hywan Jan 25, 2021
8b29156
fixup
Hywan Jan 25, 2021
5de7d71
chore(c-api) Update headers.
Hywan Jan 25, 2021
5abac74
feat(c-api) Rename `wasm_named_extern_extern` to `wasm_named_extern_u…
Hywan Jan 26, 2021
79b5d5c
chore(c-api) Exclude more functions from Wasm C API for the Wasmer C …
Hywan Jan 26, 2021
18761ca
feat(c-api) Implement `wasm_extern_copy`.
Hywan Jan 26, 2021
1042dad
chore(c-api) Update headers.
Hywan Jan 26, 2021
5fc3e9f
chore(c-api) Update headers.
Hywan Jan 26, 2021
83c69a5
feat(c-api) Implement `From<String>` for `wasm_name_t`.
Hywan Jan 28, 2021
e379fd7
chore(c-api) Merge `_CBINDGEN_IS_RUNNING` with `DOCS_RS`.
Hywan Jan 28, 2021
37aee2d
chore(c-api) Simplify code.
Hywan Jan 28, 2021
b640a8c
doc(changelog) Add #2053.
Hywan Jan 28, 2021
0861b73
Fix rebase.
Hywan Feb 1, 2021
bbbbe53
test(c-api) Move a doctest into a test.
Hywan Feb 1, 2021
b1dc041
chore(c-api) Make type explicit for the sake of simplicity.
Hywan Feb 1, 2021
9e63ba9
fix(c-api) Fix memory leak and owernship in WASI.
Hywan Feb 1, 2021
8ab82cf
doc(c-api) Fix documentation.
Hywan Feb 1, 2021
d48bc1e
chore(c-api) Update headers.
Hywan Feb 1, 2021
9a835a4
doc(c-api) Remove incorrect link.
Hywan Feb 1, 2021
98bff43
chore(c-api) Remove useless `unsafe` keywords.
Hywan Feb 1, 2021
995a2d4
feat(c-api) No longer expand with `cbindgen`: drop dependency to Rust…
Hywan Feb 2, 2021
e5d5303
Merge branch 'master' into feat-c-api-wasi-unordered-imports
Hywan Feb 2, 2021
698a26c
fix(c-api) Restore a bug with `wasi_get_imports`.
Hywan Feb 2, 2021
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 @@ -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