mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-14 17:31:20 +00:00
Add C API module_instantiate function
This commit is contained in:
@ -398,6 +398,78 @@ pub unsafe extern "C" fn wasmer_compile(
|
|||||||
wasmer_result_t::WASMER_OK
|
wasmer_result_t::WASMER_OK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new Instance from the given module and imports.
|
||||||
|
///
|
||||||
|
/// Returns `wasmer_result_t::WASMER_OK` upon success.
|
||||||
|
///
|
||||||
|
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
|
||||||
|
/// and `wasmer_last_error_message` to get an error message.
|
||||||
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasmer_module_instantiate(
|
||||||
|
module: *mut wasmer_module_t,
|
||||||
|
mut instance: *mut *mut wasmer_instance_t,
|
||||||
|
imports: *mut wasmer_import_t,
|
||||||
|
imports_len: c_int,
|
||||||
|
) -> wasmer_result_t {
|
||||||
|
let imports: &[wasmer_import_t] = slice::from_raw_parts(imports, imports_len as usize);
|
||||||
|
let mut import_object = ImportObject::new();
|
||||||
|
let mut namespaces = HashMap::new();
|
||||||
|
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 namespace = namespaces
|
||||||
|
.entry(module_name)
|
||||||
|
.or_insert_with(|| Namespace::new());
|
||||||
|
|
||||||
|
let export = match import.tag {
|
||||||
|
wasmer_import_export_kind::WASM_MEMORY => import.value.memory as *mut Export,
|
||||||
|
wasmer_import_export_kind::WASM_FUNCTION => import.value.func as *mut Export,
|
||||||
|
wasmer_import_export_kind::WASM_GLOBAL => import.value.global as *mut Export,
|
||||||
|
wasmer_import_export_kind::WASM_TABLE => import.value.table as *mut Export,
|
||||||
|
};
|
||||||
|
namespace.insert(import_name, unsafe { (&*export).clone() });
|
||||||
|
}
|
||||||
|
for (module_name, namespace) in namespaces.into_iter() {
|
||||||
|
import_object.register(module_name, namespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
let module = unsafe { &*(module as *mut Module) };
|
||||||
|
let new_instance = if let Ok(res) = module.instantiate(&import_object) {
|
||||||
|
res
|
||||||
|
} else {
|
||||||
|
update_last_error(CApiError {
|
||||||
|
msg: "error instantiating from module".to_string(),
|
||||||
|
});
|
||||||
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
|
};
|
||||||
|
unsafe { *instance = Box::into_raw(Box::new(new_instance)) as *mut wasmer_instance_t };
|
||||||
|
wasmer_result_t::WASMER_OK
|
||||||
|
}
|
||||||
|
|
||||||
/// Frees memory for the given Module
|
/// Frees memory for the given Module
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -19,6 +19,32 @@ int main()
|
|||||||
printf("Compile result: %d\n", compile_result);
|
printf("Compile result: %d\n", compile_result);
|
||||||
assert(compile_result == WASMER_OK);
|
assert(compile_result == WASMER_OK);
|
||||||
|
|
||||||
|
wasmer_import_t imports[] = {};
|
||||||
|
wasmer_instance_t *instance = NULL;
|
||||||
|
wasmer_result_t instantiate_result = wasmer_module_instantiate(module, &instance, imports, 0);
|
||||||
|
printf("Instantiate result: %d\n", compile_result);
|
||||||
|
assert(instantiate_result == WASMER_OK);
|
||||||
|
|
||||||
|
wasmer_value_t param_one;
|
||||||
|
param_one.tag = WASM_I32;
|
||||||
|
param_one.value.I32 = 7;
|
||||||
|
wasmer_value_t param_two;
|
||||||
|
param_two.tag = WASM_I32;
|
||||||
|
param_two.value.I32 = 8;
|
||||||
|
wasmer_value_t params[] = {param_one, param_two};
|
||||||
|
|
||||||
|
wasmer_value_t result_one;
|
||||||
|
wasmer_value_t results[] = {result_one};
|
||||||
|
|
||||||
|
wasmer_result_t call_result = wasmer_instance_call(instance, "sum", params, 2, results, 1);
|
||||||
|
printf("Call result: %d\n", call_result);
|
||||||
|
printf("Result: %d\n", results[0].value.I32);
|
||||||
|
assert(results[0].value.I32 == 15);
|
||||||
|
assert(call_result == WASMER_OK);
|
||||||
|
|
||||||
|
printf("Destroy instance\n");
|
||||||
|
wasmer_instance_destroy(instance);
|
||||||
|
|
||||||
printf("Destroy module\n");
|
printf("Destroy module\n");
|
||||||
wasmer_module_destroy(module);
|
wasmer_module_destroy(module);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -345,6 +345,17 @@ wasmer_result_t wasmer_memory_new(wasmer_memory_t **memory, wasmer_limits_t limi
|
|||||||
*/
|
*/
|
||||||
void wasmer_module_destroy(wasmer_module_t *module);
|
void wasmer_module_destroy(wasmer_module_t *module);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Instance from the given module and imports.
|
||||||
|
* Returns `wasmer_result_t::WASMER_OK` upon success.
|
||||||
|
* Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
|
||||||
|
* and `wasmer_last_error_message` to get an error message.
|
||||||
|
*/
|
||||||
|
wasmer_result_t wasmer_module_instantiate(wasmer_module_t *module,
|
||||||
|
wasmer_instance_t **instance,
|
||||||
|
wasmer_import_t *imports,
|
||||||
|
int imports_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees memory for the given Table
|
* Frees memory for the given Table
|
||||||
*/
|
*/
|
||||||
|
@ -278,6 +278,15 @@ wasmer_result_t wasmer_memory_new(wasmer_memory_t **memory, wasmer_limits_t limi
|
|||||||
/// Frees memory for the given Module
|
/// Frees memory for the given Module
|
||||||
void wasmer_module_destroy(wasmer_module_t *module);
|
void wasmer_module_destroy(wasmer_module_t *module);
|
||||||
|
|
||||||
|
/// Creates a new Instance from the given module and imports.
|
||||||
|
/// Returns `wasmer_result_t::WASMER_OK` upon success.
|
||||||
|
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
|
||||||
|
/// and `wasmer_last_error_message` to get an error message.
|
||||||
|
wasmer_result_t wasmer_module_instantiate(wasmer_module_t *module,
|
||||||
|
wasmer_instance_t **instance,
|
||||||
|
wasmer_import_t *imports,
|
||||||
|
int imports_len);
|
||||||
|
|
||||||
/// Frees memory for the given Table
|
/// Frees memory for the given Table
|
||||||
void wasmer_table_destroy(wasmer_table_t *table);
|
void wasmer_table_destroy(wasmer_table_t *table);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user