Skip to content

Commit

Permalink
Add foundational emscripten functions and types to C API
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark McCaskey committed Dec 13, 2019
1 parent 22dcbcc commit f1c95a8
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 13 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

6 changes: 6 additions & 0 deletions lib/runtime-c-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,19 @@ 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"]
cranelift-backend = ["wasmer-runtime/cranelift", "wasmer-runtime/default-backend-cranelift"]
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"
21 changes: 16 additions & 5 deletions lib/runtime-c-api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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());
Expand All @@ -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());
Expand Down
58 changes: 58 additions & 0 deletions lib/runtime-c-api/src/import/emscripten.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//! Functions and types for dealing with Emscripten imports
use super::*;
use crate::module::wasmer_module_t;
use std::ptr;
use wasmer_emscripten::EmscriptenGlobals;
use wasmer_runtime::Module;

/// Type used to construct an import_object_t with Emscripten imports.
#[repr(C)]
pub struct wasmer_emscripten_globals_t;

/// Create a `wasmer_emscripten_globals_t` from a Wasm module.
#[no_mangle]
pub unsafe extern "C" fn wasmer_emscripten_get_emscripten_globals(
module: *const wasmer_module_t,
) -> *mut wasmer_emscripten_globals_t {
if module.is_null() {
return ptr::null_mut();
}
let module = &*(module as *const Module);
match EmscriptenGlobals::new(module) {
Ok(globals) => Box::into_raw(Box::new(globals)) as *mut wasmer_emscripten_globals_t,
Err(msg) => {
update_last_error(CApiError { msg });
return ptr::null_mut();
}
}
}

/// Destroy `wasmer_emscrpten_globals_t` created by
/// `wasmer_emscripten_get_emscripten_globals`.
#[no_mangle]
pub unsafe extern "C" fn wasmer_emscripten_destroy_emscripten_globals(
globals: *mut wasmer_emscripten_globals_t,
) {
if globals.is_null() {
return;
}
let _ = Box::from_raw(globals);
}

/// 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`.
#[no_mangle]
pub unsafe extern "C" fn wasmer_emscripten_generate_import_object(
globals: *mut wasmer_emscripten_globals_t,
) -> *mut wasmer_import_object_t {
if globals.is_null() {
return ptr::null_mut();
}
// TODO: figure out if we should be using UnsafeCell here or something
let g = &mut *(globals as *mut EmscriptenGlobals);
let import_object = Box::new(wasmer_emscripten::generate_emscripten_env(g));

Box::into_raw(import_object) as *mut wasmer_import_object_t
}
9 changes: 9 additions & 0 deletions lib/runtime-c-api/src/import/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down Expand Up @@ -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()
Expand Down
41 changes: 37 additions & 4 deletions lib/runtime-c-api/wasmer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
*/
Expand Down Expand Up @@ -153,10 +166,6 @@ typedef struct {

typedef struct {

} wasmer_import_object_t;

typedef struct {

} wasmer_table_t;

/**
Expand Down Expand Up @@ -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
*/
Expand Down
33 changes: 29 additions & 4 deletions lib/runtime-c-api/wasmer.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -128,10 +139,6 @@ struct wasmer_import_func_t {

};

struct wasmer_import_object_t {

};

struct wasmer_table_t {

};
Expand Down Expand Up @@ -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_);

Expand Down

0 comments on commit f1c95a8

Please sign in to comment.