mirror of
https://github.com/fluencelabs/wasmer
synced 2024-12-12 22:05:33 +00:00
Merge #616
616: runtime-c-api: create the import object separately from instance instantiation r=bjfish a=YaronWittenstein Creating an `import object` separately from the `wasmer` instance, let's us build the import object incrementally and support the use-case of having import functions (a.k.a `vmcalls`) implemented in 2 programming languages (Rust and Golang for example) and consumed by the same `wasmer` instance. Co-authored-by: Yaron Wittenstein <yaron.wittenstein@gmail.com> Co-authored-by: Brandon Fish <bjfish@users.noreply.github.com>
This commit is contained in:
commit
9489af4207
@ -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,
|
||||
|
@ -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,32 @@ 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]
|
||||
|
1
lib/runtime-c-api/tests/.gitignore
vendored
1
lib/runtime-c-api/tests/.gitignore
vendored
@ -24,3 +24,4 @@ test-module-serialize
|
||||
test-tables
|
||||
test-validate
|
||||
test-context
|
||||
test-module-import-instantiate
|
||||
|
@ -15,6 +15,7 @@ add_executable(test-module-serialize test-module-serialize.c)
|
||||
add_executable(test-tables test-tables.c)
|
||||
add_executable(test-validate test-validate.c)
|
||||
add_executable(test-context test-context.c)
|
||||
add_executable(test-module-import-instantiate test-module-import-instantiate.c)
|
||||
|
||||
find_library(
|
||||
WASMER_LIB NAMES libwasmer_runtime_c_api.dylib libwasmer_runtime_c_api.so libwasmer_runtime_c_api.dll
|
||||
@ -92,3 +93,7 @@ add_test(test-validate test-validate)
|
||||
target_link_libraries(test-context general ${WASMER_LIB})
|
||||
target_compile_options(test-context PRIVATE ${COMPILER_OPTIONS})
|
||||
add_test(test-context test-context)
|
||||
|
||||
target_link_libraries(test-module-import-instantiate general ${WASMER_LIB})
|
||||
target_compile_options(test-module-import-instantiate PRIVATE ${COMPILER_OPTIONS})
|
||||
add_test(test-module-import-instantiate test-module-import-instantiate)
|
||||
|
Binary file not shown.
@ -1,7 +1,12 @@
|
||||
(module
|
||||
(func $inc (import "env" "inc"))
|
||||
(func $mul (import "env" "mul"))
|
||||
(func $get (import "env" "get") (result i32))
|
||||
|
||||
(func (export "inc_and_get") (result i32)
|
||||
call $inc
|
||||
call $get)
|
||||
|
||||
(func (export "mul_and_get") (result i32)
|
||||
call $mul
|
||||
call $get))
|
||||
|
@ -34,6 +34,11 @@ void inc_counter(wasmer_instance_context_t *ctx) {
|
||||
data->value = data->value + data->amount;
|
||||
}
|
||||
|
||||
void mul_counter(wasmer_instance_context_t *ctx) {
|
||||
counter_data* data = (counter_data*)wasmer_instance_context_data_get(ctx);
|
||||
data->value = data->value * data->amount;
|
||||
}
|
||||
|
||||
int32_t get_counter(wasmer_instance_context_t *ctx) {
|
||||
counter_data* data = (counter_data*)wasmer_instance_context_data_get(ctx);
|
||||
return data->value;
|
||||
@ -90,12 +95,17 @@ int main()
|
||||
wasmer_import_func_t *inc_func = wasmer_import_func_new((void (*)(void *)) inc_counter, inc_params_sig, 0, inc_returns_sig, 0);
|
||||
wasmer_import_t inc_import = create_import("env", "inc", inc_func);
|
||||
|
||||
wasmer_value_tag mul_params_sig[] = {};
|
||||
wasmer_value_tag mul_returns_sig[] = {};
|
||||
wasmer_import_func_t *mul_func = wasmer_import_func_new((void (*)(void *)) mul_counter, mul_params_sig, 0, mul_returns_sig, 0);
|
||||
wasmer_import_t mul_import = create_import("env", "mul", mul_func);
|
||||
|
||||
wasmer_value_tag get_params_sig[] = {};
|
||||
wasmer_value_tag get_returns_sig[] = {WASM_I32};
|
||||
wasmer_import_func_t *get_func = wasmer_import_func_new((void (*)(void *)) get_counter, get_params_sig, 0, get_returns_sig, 1);
|
||||
wasmer_import_t get_import = create_import("env", "get", get_func);
|
||||
|
||||
wasmer_import_t imports[] = {inc_import, get_import};
|
||||
wasmer_import_t imports[] = {inc_import, mul_import, get_import};
|
||||
|
||||
// Read the wasm file
|
||||
wasm_file_t wasm_file = read_wasm_file("assets/inc.wasm");
|
||||
@ -103,8 +113,9 @@ int main()
|
||||
// Instantiate instance
|
||||
printf("Instantiating\n");
|
||||
wasmer_instance_t *instance = NULL;
|
||||
wasmer_result_t compile_result = wasmer_instantiate(&instance, wasm_file.bytes, wasm_file.bytes_len, imports, 2);
|
||||
printf("Compile result: %d\n", compile_result);
|
||||
wasmer_result_t instantiate_res = wasmer_instantiate(&instance, wasm_file.bytes, wasm_file.bytes_len, imports, 3);
|
||||
printf("Compile result: %d\n", instantiate_res);
|
||||
assert(instantiate_res == WASMER_OK);
|
||||
|
||||
// Init counter
|
||||
counter_data *counter = init_counter(2, 5);
|
||||
|
149
lib/runtime-c-api/tests/test-module-import-instantiate.c
Normal file
149
lib/runtime-c-api/tests/test-module-import-instantiate.c
Normal file
@ -0,0 +1,149 @@
|
||||
#include <stdio.h>
|
||||
#include "../wasmer.h"
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
int32_t amount;
|
||||
int32_t value;
|
||||
} counter_data;
|
||||
|
||||
typedef struct {
|
||||
uint8_t* bytes;
|
||||
long bytes_len;
|
||||
} wasm_file_t;
|
||||
|
||||
wasm_file_t read_wasm_file(const char* file_name) {
|
||||
wasm_file_t wasm_file;
|
||||
|
||||
FILE *file = fopen(file_name, "r");
|
||||
fseek(file, 0, SEEK_END);
|
||||
wasm_file.bytes_len = ftell(file);
|
||||
|
||||
wasm_file.bytes = malloc(wasm_file.bytes_len);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
fread(wasm_file.bytes, 1, wasm_file.bytes_len, file);
|
||||
fclose(file);
|
||||
|
||||
return wasm_file;
|
||||
}
|
||||
|
||||
void inc_counter(wasmer_instance_context_t *ctx) {
|
||||
counter_data* data = (counter_data*)wasmer_instance_context_data_get(ctx);
|
||||
data->value = data->value + data->amount;
|
||||
}
|
||||
|
||||
void mul_counter(wasmer_instance_context_t *ctx) {
|
||||
counter_data* data = (counter_data*)wasmer_instance_context_data_get(ctx);
|
||||
data->value = data->value * data->amount;
|
||||
}
|
||||
|
||||
int32_t get_counter(wasmer_instance_context_t *ctx) {
|
||||
counter_data* data = (counter_data*)wasmer_instance_context_data_get(ctx);
|
||||
return data->value;
|
||||
}
|
||||
|
||||
counter_data *init_counter(int32_t value, int32_t amount) {
|
||||
counter_data* counter = malloc(sizeof(counter_data));
|
||||
counter->value = value;
|
||||
counter->amount = amount;
|
||||
return counter;
|
||||
}
|
||||
|
||||
wasmer_import_t create_import(char* module_name, char* import_name, wasmer_import_func_t *func) {
|
||||
wasmer_import_t import;
|
||||
wasmer_byte_array module_name_bytes;
|
||||
wasmer_byte_array import_name_bytes;
|
||||
|
||||
module_name_bytes.bytes = (const uint8_t *) module_name;
|
||||
module_name_bytes.bytes_len = strlen(module_name);
|
||||
|
||||
import_name_bytes.bytes = (const uint8_t *) import_name;
|
||||
import_name_bytes.bytes_len = strlen(import_name);
|
||||
|
||||
import.module_name = module_name_bytes;
|
||||
import.import_name = import_name_bytes;
|
||||
|
||||
import.tag = WASM_FUNCTION;
|
||||
import.value.func = func;
|
||||
|
||||
return import;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// Prepare Imports
|
||||
wasmer_value_tag inc_params_sig[] = {};
|
||||
wasmer_value_tag inc_returns_sig[] = {};
|
||||
wasmer_import_func_t *inc_func = wasmer_import_func_new((void (*)(void *)) inc_counter, inc_params_sig, 0, inc_returns_sig, 0);
|
||||
wasmer_import_t inc_import = create_import("env", "inc", inc_func);
|
||||
|
||||
wasmer_value_tag mul_params_sig[] = {};
|
||||
wasmer_value_tag mul_returns_sig[] = {};
|
||||
wasmer_import_func_t *mul_func = wasmer_import_func_new((void (*)(void *)) mul_counter, mul_params_sig, 0, mul_returns_sig, 0);
|
||||
wasmer_import_t mul_import = create_import("env", "mul", mul_func);
|
||||
|
||||
wasmer_value_tag get_params_sig[] = {};
|
||||
wasmer_value_tag get_returns_sig[] = {WASM_I32};
|
||||
wasmer_import_func_t *get_func = wasmer_import_func_new((void (*)(void *)) get_counter, get_params_sig, 0, get_returns_sig, 1);
|
||||
wasmer_import_t get_import = create_import("env", "get", get_func);
|
||||
|
||||
// Read the wasm file
|
||||
wasm_file_t wasm_file = read_wasm_file("assets/inc.wasm");
|
||||
|
||||
// Compile module
|
||||
wasmer_module_t *module = NULL;
|
||||
wasmer_result_t compile_res = wasmer_compile(&module, wasm_file.bytes, wasm_file.bytes_len);
|
||||
assert(compile_res == WASMER_OK);
|
||||
|
||||
// Prepare Import Object
|
||||
wasmer_import_object_t *import_object = wasmer_import_object_new();
|
||||
|
||||
// First, we import `inc_counter` and `mul_counter`
|
||||
wasmer_import_t imports[] = {inc_import, mul_import};
|
||||
wasmer_result_t extend_res = wasmer_import_object_extend(import_object, imports, 2);
|
||||
assert(extend_res == WASMER_OK);
|
||||
|
||||
// Now, we'll import `inc_counter` and `mul_counter`
|
||||
wasmer_import_t more_imports[] = {get_import};
|
||||
wasmer_result_t extend_res2 = wasmer_import_object_extend(import_object, more_imports, 1);
|
||||
assert(extend_res2 == WASMER_OK);
|
||||
|
||||
// Same `wasmer_import_object_extend` as the first, doesn't affect anything
|
||||
wasmer_result_t extend_res3 = wasmer_import_object_extend(import_object, imports, 2);
|
||||
assert(extend_res3 == WASMER_OK);
|
||||
|
||||
// Instantiate instance
|
||||
printf("Instantiating\n");
|
||||
wasmer_instance_t *instance = NULL;
|
||||
wasmer_result_t instantiate_res = wasmer_module_import_instantiate(&instance, module, import_object);
|
||||
printf("Compile result: %d\n", instantiate_res);
|
||||
assert(instantiate_res == WASMER_OK);
|
||||
|
||||
// Init counter
|
||||
counter_data *counter = init_counter(2, 5);
|
||||
wasmer_instance_context_data_set(instance, counter);
|
||||
|
||||
wasmer_value_t result_one;
|
||||
wasmer_value_t params[] = {};
|
||||
wasmer_value_t results[] = {result_one};
|
||||
|
||||
wasmer_result_t call1_result = wasmer_instance_call(instance, "inc_and_get", params, 0, results, 1);
|
||||
printf("Call result: %d\n", call1_result);
|
||||
printf("Result: %d\n", results[0].value.I32);
|
||||
|
||||
wasmer_result_t call2_result = wasmer_instance_call(instance, "mul_and_get", params, 0, results, 1);
|
||||
printf("Call result: %d\n", call2_result);
|
||||
printf("Result: %d\n", results[0].value.I32);
|
||||
|
||||
// Clear resources
|
||||
wasmer_import_func_destroy(inc_func);
|
||||
wasmer_import_func_destroy(mul_func);
|
||||
wasmer_import_func_destroy(get_func);
|
||||
wasmer_instance_destroy(instance);
|
||||
free(counter);
|
||||
free(wasm_file.bytes);
|
||||
|
||||
return 0;
|
||||
}
|
@ -95,11 +95,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
|
||||
} wasmer_instance_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
} wasmer_instance_context_t;
|
||||
} wasmer_import_object_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@ -119,6 +115,14 @@ typedef struct {
|
||||
wasmer_import_export_value value;
|
||||
} wasmer_import_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
} wasmer_instance_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
} wasmer_instance_context_t;
|
||||
|
||||
typedef struct {
|
||||
bool has_some;
|
||||
uint32_t some;
|
||||
@ -392,6 +396,24 @@ wasmer_result_t wasmer_import_func_returns(const wasmer_import_func_t *func,
|
||||
wasmer_result_t wasmer_import_func_returns_arity(const wasmer_import_func_t *func,
|
||||
uint32_t *result);
|
||||
|
||||
/**
|
||||
* Frees memory of the given ImportObject
|
||||
*/
|
||||
void wasmer_import_object_destroy(wasmer_import_object_t *import_object);
|
||||
|
||||
/**
|
||||
* Extends an existing import object with new imports
|
||||
*/
|
||||
wasmer_result_t wasmer_import_object_extend(wasmer_import_object_t *import_object,
|
||||
wasmer_import_t *imports,
|
||||
unsigned int imports_len);
|
||||
|
||||
/**
|
||||
* Creates a new empty import object.
|
||||
* See also `wasmer_import_object_append`
|
||||
*/
|
||||
wasmer_import_object_t *wasmer_import_object_new(void);
|
||||
|
||||
/**
|
||||
* Calls an instances exported function by `name` with the provided parameters.
|
||||
* Results are set using the provided `results` pointer.
|
||||
@ -531,6 +553,16 @@ wasmer_result_t wasmer_module_deserialize(wasmer_module_t **module,
|
||||
*/
|
||||
void wasmer_module_destroy(wasmer_module_t *module);
|
||||
|
||||
/**
|
||||
* Given:
|
||||
* A prepared `wasmer svm` import-object
|
||||
* A compiled wasmer module
|
||||
* Instantiates a wasmer instance
|
||||
*/
|
||||
wasmer_result_t wasmer_module_import_instantiate(wasmer_instance_t **instance,
|
||||
const wasmer_module_t *module,
|
||||
const wasmer_import_object_t *import_object);
|
||||
|
||||
/**
|
||||
* Creates a new Instance from the given module and imports.
|
||||
* Returns `wasmer_result_t::WASMER_OK` upon success.
|
||||
|
@ -91,11 +91,7 @@ struct wasmer_import_func_t {
|
||||
|
||||
};
|
||||
|
||||
struct wasmer_instance_t {
|
||||
|
||||
};
|
||||
|
||||
struct wasmer_instance_context_t {
|
||||
struct wasmer_import_object_t {
|
||||
|
||||
};
|
||||
|
||||
@ -117,6 +113,14 @@ struct wasmer_import_t {
|
||||
wasmer_import_export_value value;
|
||||
};
|
||||
|
||||
struct wasmer_instance_t {
|
||||
|
||||
};
|
||||
|
||||
struct wasmer_instance_context_t {
|
||||
|
||||
};
|
||||
|
||||
struct wasmer_limit_option_t {
|
||||
bool has_some;
|
||||
uint32_t some;
|
||||
@ -318,6 +322,18 @@ wasmer_result_t wasmer_import_func_returns(const wasmer_import_func_t *func,
|
||||
wasmer_result_t wasmer_import_func_returns_arity(const wasmer_import_func_t *func,
|
||||
uint32_t *result);
|
||||
|
||||
/// Frees memory of the given ImportObject
|
||||
void wasmer_import_object_destroy(wasmer_import_object_t *import_object);
|
||||
|
||||
/// Extends an existing import object with new imports
|
||||
wasmer_result_t wasmer_import_object_extend(wasmer_import_object_t *import_object,
|
||||
wasmer_import_t *imports,
|
||||
unsigned int imports_len);
|
||||
|
||||
/// Creates a new empty import object.
|
||||
/// See also `wasmer_import_object_append`
|
||||
wasmer_import_object_t *wasmer_import_object_new();
|
||||
|
||||
/// Calls an instances exported function by `name` with the provided parameters.
|
||||
/// Results are set using the provided `results` pointer.
|
||||
/// Returns `wasmer_result_t::WASMER_OK` upon success.
|
||||
@ -421,6 +437,14 @@ wasmer_result_t wasmer_module_deserialize(wasmer_module_t **module,
|
||||
/// Frees memory for the given Module
|
||||
void wasmer_module_destroy(wasmer_module_t *module);
|
||||
|
||||
/// Given:
|
||||
/// A prepared `wasmer svm` import-object
|
||||
/// A compiled wasmer module
|
||||
/// Instantiates a wasmer instance
|
||||
wasmer_result_t wasmer_module_import_instantiate(wasmer_instance_t **instance,
|
||||
const wasmer_module_t *module,
|
||||
const wasmer_import_object_t *import_object);
|
||||
|
||||
/// 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`
|
||||
|
Loading…
Reference in New Issue
Block a user