diff --git a/Cargo.lock b/Cargo.lock index 0ee127d57ad..c424cd73114 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2286,6 +2286,7 @@ version = "0.11.0" dependencies = [ "cbindgen 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmer-emscripten 0.11.0", "wasmer-runtime 0.11.0", "wasmer-runtime-core 0.11.0", "wasmer-wasi 0.11.0", diff --git a/lib/runtime-c-api/Cargo.toml b/lib/runtime-c-api/Cargo.toml index 0a278b6ba2e..1b404eae6e9 100644 --- a/lib/runtime-c-api/Cargo.toml +++ b/lib/runtime-c-api/Cargo.toml @@ -32,6 +32,11 @@ path = "../wasi" version = "0.11.0" optional = true +[dependencies.wasmer-emscripten] +path = "../emscripten" +version = "0.11.0" +optional = true + [features] default = ["cranelift-backend", "wasi"] debug = ["wasmer-runtime/debug"] @@ -39,6 +44,7 @@ cranelift-backend = ["wasmer-runtime/cranelift", "wasmer-runtime/default-backend llvm-backend = ["wasmer-runtime/llvm", "wasmer-runtime/default-backend-llvm"] singlepass-backend = ["wasmer-runtime/singlepass", "wasmer-runtime/default-backend-singlepass"] wasi = ["wasmer-wasi"] +emscripten = ["wasmer-emscripten"] [build-dependencies] cbindgen = "0.9" diff --git a/lib/runtime-c-api/build.rs b/lib/runtime-c-api/build.rs index 5897001b043..b20a9acd7ec 100644 --- a/lib/runtime-c-api/build.rs +++ b/lib/runtime-c-api/build.rs @@ -12,7 +12,7 @@ fn main() { let mut out_wasmer_header_file = PathBuf::from(&out_dir); out_wasmer_header_file.push("wasmer"); - const WASMER_PRE_HEADER: &str = r#" + let mut pre_header = r#" #if !defined(WASMER_H_MACROS) #define WASMER_H_MACROS @@ -28,17 +28,27 @@ fn main() { #endif #endif -#endif // WASMER_H_MACROS -"#; +"# + .to_string(); + + #[cfg(feature = "emscripten")] + { + pre_header += "#define WASMER_EMSCRIPTEN_ENABLED\n"; + } + + // close pre header + pre_header += "#endif // WASMER_H_MACROS\n"; + // Generate the C bindings in the `OUT_DIR`. out_wasmer_header_file.set_extension("h"); Builder::new() .with_crate(crate_dir.clone()) .with_language(Language::C) .with_include_guard("WASMER_H") - .with_header(WASMER_PRE_HEADER) + .with_header(&pre_header) .with_define("target_family", "windows", "_WIN32") .with_define("target_arch", "x86_64", "ARCH_X86_64") + .with_define("feature", "emscripten", "WASMER_EMSCRIPTEN_ENABLED") .generate() .expect("Unable to generate C bindings") .write_to_file(out_wasmer_header_file.as_path()); @@ -49,9 +59,10 @@ fn main() { .with_crate(crate_dir) .with_language(Language::Cxx) .with_include_guard("WASMER_H") - .with_header(WASMER_PRE_HEADER) + .with_header(&pre_header) .with_define("target_family", "windows", "_WIN32") .with_define("target_arch", "x86_64", "ARCH_X86_64") + .with_define("feature", "emscripten", "WASMER_EMSCRIPTEN_ENABLED") .generate() .expect("Unable to generate C++ bindings") .write_to_file(out_wasmer_header_file.as_path()); diff --git a/lib/runtime-c-api/src/import/mod.rs b/lib/runtime-c-api/src/import/mod.rs index 2bca1e3902c..97886211387 100644 --- a/lib/runtime-c-api/src/import/mod.rs +++ b/lib/runtime-c-api/src/import/mod.rs @@ -61,6 +61,12 @@ mod wasi; #[cfg(feature = "wasi")] pub use self::wasi::*; +#[cfg(feature = "emscripten")] +mod emscripten; + +#[cfg(feature = "emscripten")] +pub use self::emscripten::*; + /// Gets an entry from an ImportObject at the name and namespace. /// Stores `name`, `namespace`, and `import_export_value` in `import`. /// Thus these must remain valid for the lifetime of `import`. @@ -437,6 +443,9 @@ pub unsafe extern "C" fn wasmer_import_descriptors( module: *const wasmer_module_t, import_descriptors: *mut *mut wasmer_import_descriptors_t, ) { + if module.is_null() { + return; + } let module = &*(module as *const Module); let total_imports = module.info().imported_functions.len() + module.info().imported_tables.len() diff --git a/lib/runtime-c-api/wasmer.h b/lib/runtime-c-api/wasmer.h index de921e3b04d..d313f61a9e7 100644 --- a/lib/runtime-c-api/wasmer.h +++ b/lib/runtime-c-api/wasmer.h @@ -74,6 +74,19 @@ typedef struct { } wasmer_module_t; +#if defined(WASMER_EMSCRIPTEN_ENABLED) +/** + * Type used to construct an import_object_t with Emscripten imports. + */ +typedef struct { + +} wasmer_emscripten_globals_t; +#endif + +typedef struct { + +} wasmer_import_object_t; + /** * Opaque pointer to `NamedExportDescriptor`. */ @@ -153,10 +166,6 @@ typedef struct { typedef struct { -} wasmer_import_object_t; - -typedef struct { - } wasmer_table_t; /** @@ -247,6 +256,30 @@ wasmer_result_t wasmer_compile(wasmer_module_t **module, uint8_t *wasm_bytes, uint32_t wasm_bytes_len); +#if defined(WASMER_EMSCRIPTEN_ENABLED) +/** + * Destroy `wasmer_emscrpten_globals_t` created by + * `wasmer_emscripten_get_emscripten_globals`. + */ +void wasmer_emscripten_destroy_emscripten_globals(wasmer_emscripten_globals_t *globals); +#endif + +#if defined(WASMER_EMSCRIPTEN_ENABLED) +/** + * Create a `wasmer_import_object_t` with Emscripten imports, use + * `wasmer_emscripten_get_emscripten_globals` to get a + * `wasmer_emscripten_globals_t` from a `wasmer_module_t`. + */ +wasmer_import_object_t *wasmer_emscripten_generate_import_object(wasmer_emscripten_globals_t *globals); +#endif + +#if defined(WASMER_EMSCRIPTEN_ENABLED) +/** + * Create a `wasmer_emscripten_globals_t` from a Wasm module. + */ +wasmer_emscripten_globals_t *wasmer_emscripten_get_emscripten_globals(const wasmer_module_t *module); +#endif + /** * Gets export descriptor kind */ diff --git a/lib/runtime-c-api/wasmer.hh b/lib/runtime-c-api/wasmer.hh index 09b58f86100..a81b8c77ac5 100644 --- a/lib/runtime-c-api/wasmer.hh +++ b/lib/runtime-c-api/wasmer.hh @@ -61,6 +61,17 @@ struct wasmer_module_t { }; +#if defined(WASMER_EMSCRIPTEN_ENABLED) +/// Type used to construct an import_object_t with Emscripten imports. +struct wasmer_emscripten_globals_t { + +}; +#endif + +struct wasmer_import_object_t { + +}; + /// Opaque pointer to `NamedExportDescriptor`. struct wasmer_export_descriptor_t { @@ -128,10 +139,6 @@ struct wasmer_import_func_t { }; -struct wasmer_import_object_t { - -}; - struct wasmer_table_t { }; @@ -216,6 +223,24 @@ wasmer_result_t wasmer_compile(wasmer_module_t **module, uint8_t *wasm_bytes, uint32_t wasm_bytes_len); +#if defined(WASMER_EMSCRIPTEN_ENABLED) +/// Destroy `wasmer_emscrpten_globals_t` created by +/// `wasmer_emscripten_get_emscripten_globals`. +void wasmer_emscripten_destroy_emscripten_globals(wasmer_emscripten_globals_t *globals); +#endif + +#if defined(WASMER_EMSCRIPTEN_ENABLED) +/// Create a `wasmer_import_object_t` with Emscripten imports, use +/// `wasmer_emscripten_get_emscripten_globals` to get a +/// `wasmer_emscripten_globals_t` from a `wasmer_module_t`. +wasmer_import_object_t *wasmer_emscripten_generate_import_object(wasmer_emscripten_globals_t *globals); +#endif + +#if defined(WASMER_EMSCRIPTEN_ENABLED) +/// Create a `wasmer_emscripten_globals_t` from a Wasm module. +wasmer_emscripten_globals_t *wasmer_emscripten_get_emscripten_globals(const wasmer_module_t *module); +#endif + /// Gets export descriptor kind wasmer_import_export_kind wasmer_export_descriptor_kind(wasmer_export_descriptor_t *export_);