Merge branch 'master' into doc-runtime-c-api-exports-1

This commit is contained in:
Ivan Enderlin
2019-08-22 13:29:54 +02:00
committed by GitHub
306 changed files with 39046 additions and 7928 deletions

View File

@ -8,17 +8,17 @@ use std::ptr;
use std::slice;
thread_local! {
static LAST_ERROR: RefCell<Option<Box<Error>>> = RefCell::new(None);
static LAST_ERROR: RefCell<Option<Box<dyn Error>>> = RefCell::new(None);
}
pub(crate) fn update_last_error<E: Error + 'static>(err: E) {
pub fn update_last_error<E: Error + 'static>(err: E) {
LAST_ERROR.with(|prev| {
*prev.borrow_mut() = Some(Box::new(err));
});
}
/// Retrieve the most recent error, clearing it in the process.
pub(crate) fn take_last_error() -> Option<Box<Error>> {
pub(crate) fn take_last_error() -> Option<Box<dyn Error>> {
LAST_ERROR.with(|prev| prev.borrow_mut().take())
}
@ -89,8 +89,8 @@ pub unsafe extern "C" fn wasmer_last_error_message(buffer: *mut c_char, length:
}
#[derive(Debug)]
pub(crate) struct CApiError {
pub(crate) msg: String,
pub struct CApiError {
pub msg: String,
}
impl Display for CApiError {

View File

@ -436,6 +436,7 @@ pub unsafe extern "C" fn wasmer_export_func_call(
tag: wasmer_value_tag::WASM_F64,
value: wasmer_value { F64: x },
},
Value::V128(_) => unimplemented!("returning V128 type"),
};
results[0] = ret;
}

View File

@ -10,9 +10,10 @@ use crate::{
};
use libc::c_uint;
use std::{ffi::c_void, ptr, slice, sync::Arc};
use wasmer_runtime::Module;
use wasmer_runtime::{Global, Memory, Module, Table};
use wasmer_runtime_core::{
export::{Context, Export, FuncPointer},
import::ImportObject,
module::ImportName,
types::{FuncSig, Type},
};
@ -25,6 +26,9 @@ pub struct wasmer_import_t {
pub value: wasmer_import_export_value,
}
#[repr(C)]
pub struct wasmer_import_object_t;
#[repr(C)]
#[derive(Clone)]
pub struct wasmer_import_func_t;
@ -37,6 +41,83 @@ pub struct wasmer_import_descriptor_t;
#[derive(Clone)]
pub struct wasmer_import_descriptors_t;
/// Creates a new empty import object.
/// See also `wasmer_import_object_append`
#[allow(clippy::cast_ptr_alignment)]
#[no_mangle]
pub unsafe extern "C" fn wasmer_import_object_new() -> *mut wasmer_import_object_t {
let import_object = Box::new(ImportObject::new());
Box::into_raw(import_object) as *mut wasmer_import_object_t
}
/// Extends an existing import object with new imports
#[allow(clippy::cast_ptr_alignment)]
#[no_mangle]
pub unsafe extern "C" fn wasmer_import_object_extend(
import_object: *mut wasmer_import_object_t,
imports: *mut wasmer_import_t,
imports_len: c_uint,
) -> wasmer_result_t {
let import_object: &mut ImportObject = &mut *(import_object as *mut ImportObject);
let mut extensions: Vec<(String, String, Export)> = Vec::new();
let imports: &[wasmer_import_t] = slice::from_raw_parts(imports, imports_len as usize);
for import in imports {
let module_name = slice::from_raw_parts(
import.module_name.bytes,
import.module_name.bytes_len as usize,
);
let module_name = if let Ok(s) = std::str::from_utf8(module_name) {
s
} else {
update_last_error(CApiError {
msg: "error converting module name to string".to_string(),
});
return wasmer_result_t::WASMER_ERROR;
};
let import_name = slice::from_raw_parts(
import.import_name.bytes,
import.import_name.bytes_len as usize,
);
let import_name = if let Ok(s) = std::str::from_utf8(import_name) {
s
} else {
update_last_error(CApiError {
msg: "error converting import_name to string".to_string(),
});
return wasmer_result_t::WASMER_ERROR;
};
let export = match import.tag {
wasmer_import_export_kind::WASM_MEMORY => {
let mem = import.value.memory as *mut Memory;
Export::Memory((&*mem).clone())
}
wasmer_import_export_kind::WASM_FUNCTION => {
let func_export = import.value.func as *mut Export;
(&*func_export).clone()
}
wasmer_import_export_kind::WASM_GLOBAL => {
let global = import.value.global as *mut Global;
Export::Global((&*global).clone())
}
wasmer_import_export_kind::WASM_TABLE => {
let table = import.value.table as *mut Table;
Export::Table((&*table).clone())
}
};
let extension = (module_name.to_string(), import_name.to_string(), export);
extensions.push(extension)
}
import_object.extend(extensions);
return wasmer_result_t::WASMER_OK;
}
/// Gets import descriptors for the given module
///
/// The caller owns the object and should call `wasmer_import_descriptors_destroy` to free it.
@ -352,6 +433,14 @@ pub extern "C" fn wasmer_import_func_destroy(func: *mut wasmer_import_func_t) {
}
}
/// Frees memory of the given ImportObject
#[no_mangle]
pub extern "C" fn wasmer_import_object_destroy(import_object: *mut wasmer_import_object_t) {
if !import_object.is_null() {
unsafe { Box::from_raw(import_object as *mut ImportObject) };
}
}
struct NamedImportDescriptor {
module: String,
name: String,

View File

@ -3,15 +3,19 @@
use crate::{
error::{update_last_error, CApiError},
export::{wasmer_exports_t, wasmer_import_export_kind, NamedExport, NamedExports},
import::wasmer_import_t,
import::{wasmer_import_object_t, wasmer_import_t},
memory::wasmer_memory_t,
module::wasmer_module_t,
value::{wasmer_value, wasmer_value_t, wasmer_value_tag},
wasmer_result_t,
};
use libc::{c_char, c_int, c_void};
use std::{collections::HashMap, ffi::CStr, slice};
use wasmer_runtime::{Ctx, Global, ImportObject, Instance, Memory, Table, Value};
use wasmer_runtime_core::{export::Export, import::Namespace};
use wasmer_runtime::{Ctx, Global, Instance, Memory, Module, Table, Value};
use wasmer_runtime_core::{
export::Export,
import::{ImportObject, Namespace},
};
#[repr(C)]
pub struct wasmer_instance_t;
@ -108,6 +112,45 @@ pub unsafe extern "C" fn wasmer_instantiate(
wasmer_result_t::WASMER_OK
}
/// Given:
/// * A prepared `wasmer` import-object
/// * A compiled wasmer module
///
/// Instantiates a wasmer instance
#[no_mangle]
pub unsafe extern "C" fn wasmer_module_import_instantiate(
instance: *mut *mut wasmer_instance_t,
module: *const wasmer_module_t,
import_object: *const wasmer_import_object_t,
) -> wasmer_result_t {
let import_object: &ImportObject = &*(import_object as *const ImportObject);
let module: &Module = &*(module as *const Module);
let new_instance: Instance = match module.instantiate(import_object) {
Ok(instance) => instance,
Err(error) => {
update_last_error(error);
return wasmer_result_t::WASMER_ERROR;
}
};
*instance = Box::into_raw(Box::new(new_instance)) as *mut wasmer_instance_t;
return wasmer_result_t::WASMER_OK;
}
/// Extracts the instance's context and returns it.
#[allow(clippy::cast_ptr_alignment)]
#[no_mangle]
pub unsafe extern "C" fn wasmer_instance_context_get(
instance: *mut wasmer_instance_t,
) -> *const wasmer_instance_context_t {
let instance_ref = &*(instance as *const Instance);
let ctx: *const Ctx = instance_ref.context() as *const _;
ctx as *const wasmer_instance_context_t
}
/// Calls an instances exported function by `name` with the provided parameters.
/// Results are set using the provided `results` pointer.
///
@ -173,6 +216,7 @@ pub unsafe extern "C" fn wasmer_instance_call(
tag: wasmer_value_tag::WASM_F64,
value: wasmer_value { F64: x },
},
Value::V128(_) => unimplemented!("calling function with V128 parameter"),
};
results[0] = ret;
}

View File

@ -80,8 +80,13 @@
//!
//! [wasmer_h]: ./wasmer.h
//! [wasmer_hh]: ./wasmer.hh
#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)]
#![deny(
dead_code,
unused_imports,
unused_variables,
unused_unsafe,
unreachable_patterns
)]
extern crate wasmer_runtime;
extern crate wasmer_runtime_core;
@ -118,6 +123,6 @@ pub struct wasmer_limit_option_t {
#[repr(C)]
pub struct wasmer_byte_array {
bytes: *const u8,
bytes_len: u32,
pub bytes: *const u8,
pub bytes_len: u32,
}

View File

@ -51,7 +51,7 @@ impl From<wasmer_value_t> for Value {
tag: wasmer_value_tag::WASM_F64,
value: wasmer_value { F64 },
} => Value::F64(F64),
_ => panic!("not implemented"),
_ => unreachable!("unknown WASM type"),
}
}
}
@ -76,6 +76,7 @@ impl From<Value> for wasmer_value_t {
tag: wasmer_value_tag::WASM_F64,
value: wasmer_value { F64: x },
},
Value::V128(_) => unimplemented!("V128 not supported in C API"),
}
}
}
@ -88,7 +89,7 @@ impl From<Type> for wasmer_value_tag {
Type::I64 => wasmer_value_tag::WASM_I64,
Type::F32 => wasmer_value_tag::WASM_F32,
Type::F64 => wasmer_value_tag::WASM_F64,
_ => panic!("not implemented"),
Type::V128 => unreachable!("V128 not supported in C API"),
}
}
}
@ -101,7 +102,7 @@ impl From<wasmer_value_tag> for Type {
wasmer_value_tag::WASM_I64 => Type::I64,
wasmer_value_tag::WASM_F32 => Type::F32,
wasmer_value_tag::WASM_F64 => Type::F64,
_ => panic!("not implemented"),
_ => unreachable!("unknown WASM type"),
}
}
}
@ -113,6 +114,7 @@ impl From<&wasmer_runtime::wasm::Type> for wasmer_value_tag {
Type::I64 => wasmer_value_tag::WASM_I64,
Type::F32 => wasmer_value_tag::WASM_F32,
Type::F64 => wasmer_value_tag::WASM_F64,
Type::V128 => unimplemented!("V128 not supported in C API"),
}
}
}