mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-14 17:31:20 +00:00
Add test to import function and call it
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -808,6 +808,7 @@ dependencies = [
|
||||
"cbindgen 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmer-runtime 0.1.4",
|
||||
"wasmer-runtime-core 0.1.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -10,6 +10,7 @@ readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
wasmer-runtime = { path = "../runtime", version = "0.1.2" }
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.1.2" }
|
||||
libc = "0.2"
|
||||
|
||||
[lib]
|
||||
|
@ -1,10 +1,16 @@
|
||||
extern crate wasmer_runtime;
|
||||
extern crate wasmer_runtime_core;
|
||||
|
||||
use libc::{c_char, c_int, int32_t, int64_t, uint32_t, uint8_t};
|
||||
use std::ffi::CStr;
|
||||
use std::slice;
|
||||
use std::str;
|
||||
use std::sync::Arc;
|
||||
use std::{ffi::c_void, mem, ptr};
|
||||
use wasmer_runtime::{ImportObject, Instance, Value};
|
||||
use wasmer_runtime_core::export::{Context, Export, FuncPointer};
|
||||
use wasmer_runtime_core::import::{LikeNamespace, Namespace};
|
||||
use wasmer_runtime_core::types::{FuncSig, Type};
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct wasmer_import_object_t();
|
||||
@ -12,6 +18,9 @@ pub struct wasmer_import_object_t();
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct wasmer_instance_t();
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct wasmer_instance_context_t();
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[no_mangle]
|
||||
#[repr(C)]
|
||||
@ -53,6 +62,13 @@ pub struct wasmer_value_t {
|
||||
value: wasmer_value,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone)]
|
||||
pub struct wasmer_memory_t {
|
||||
pub ptr: *mut uint8_t,
|
||||
pub len: uint32_t,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasmer_import_object_new() -> *mut wasmer_import_object_t {
|
||||
Box::into_raw(Box::new(ImportObject::new())) as *mut wasmer_import_object_t
|
||||
@ -89,6 +105,7 @@ pub unsafe extern "C" fn wasmer_instantiate(
|
||||
}
|
||||
};
|
||||
unsafe { *instance = Box::into_raw(Box::new(new_instance)) as *mut wasmer_instance_t };
|
||||
// Box::into_raw(import_object); // TODO Review is this the correct way not to drop
|
||||
wasmer_compile_result_t::WASMER_COMPILE_OK
|
||||
}
|
||||
|
||||
@ -125,6 +142,7 @@ pub unsafe extern "C" fn wasmer_instance_call(
|
||||
|
||||
let results: &mut [wasmer_value_t] = slice::from_raw_parts_mut(results, results_len as usize);
|
||||
let result = instance.call(func_name_r, ¶ms[..]);
|
||||
Box::into_raw(instance);
|
||||
match result {
|
||||
Ok(results_vec) => {
|
||||
println!("Call Res: {:?}", results_vec);
|
||||
@ -158,6 +176,53 @@ pub unsafe extern "C" fn wasmer_instance_call(
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasmer_imports_set_import_func(
|
||||
import_object: *mut wasmer_import_object_t,
|
||||
namespace: *const c_char,
|
||||
name: *const c_char,
|
||||
func: extern "C" fn(data: *mut c_void),
|
||||
) {
|
||||
let mut import_object = unsafe { Box::from_raw(import_object as *mut ImportObject) };
|
||||
let namespace_c = unsafe { CStr::from_ptr(namespace) };
|
||||
let namespace_r = namespace_c.to_str().unwrap();
|
||||
let name_c = unsafe { CStr::from_ptr(name) };
|
||||
let name_r = name_c.to_str().unwrap();
|
||||
|
||||
let export = Export::Function {
|
||||
func: unsafe { FuncPointer::new(func as _) },
|
||||
ctx: Context::Internal,
|
||||
signature: Arc::new(FuncSig::new(vec![Type::I32, Type::I32], vec![])),
|
||||
};
|
||||
|
||||
// TODO handle existing namespace
|
||||
// let maybe_namespace = import_object.get_namespace(namespace_r);
|
||||
// if let Some(n) = maybe_namespace {
|
||||
// n.insert(name_r, export);
|
||||
// } else {
|
||||
let mut namespace = Namespace::new();
|
||||
namespace.insert(name_r, export);
|
||||
import_object.register(namespace_r, namespace);
|
||||
Box::into_raw(import_object);
|
||||
// };
|
||||
}
|
||||
|
||||
//#[no_mangle]
|
||||
//pub extern "C" fn wasmer_debug_print(kind: uint8_t, thing: *mut c_void) {
|
||||
// match kind {
|
||||
// 1 => {
|
||||
// println!("wasmer import object:");
|
||||
// let import_object = unsafe { Box::from_raw(thing as *mut ImportObject) };
|
||||
// println!("after import object");
|
||||
// Box::into_raw(import_object);
|
||||
// },
|
||||
// _ => panic!("unknown kind {:?}", kind)
|
||||
// }
|
||||
//}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasmer_instance_context_memory(instance: *mut wasmer_instance_context_t) {}
|
||||
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasmer_instance_destroy(instance: *mut wasmer_instance_t) {
|
||||
|
1
lib/runtime-c-api/tests/.gitignore
vendored
1
lib/runtime-c-api/tests/.gitignore
vendored
@ -10,3 +10,4 @@ compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
test-instantiate
|
||||
test-import-function
|
@ -2,10 +2,15 @@ cmake_minimum_required (VERSION 2.6)
|
||||
project (WasmerCApiTests)
|
||||
|
||||
add_executable(test-instantiate test-instantiate.c)
|
||||
add_executable(test-import-function test-import-function.c)
|
||||
|
||||
target_link_libraries(test-instantiate
|
||||
general "${CMAKE_SOURCE_DIR}/../../../target/debug/libwasmer_runtime_c_api.dylib")
|
||||
|
||||
target_link_libraries(test-import-function
|
||||
general "${CMAKE_SOURCE_DIR}/../../../target/debug/libwasmer_runtime_c_api.dylib")
|
||||
|
||||
enable_testing()
|
||||
add_test(test-instantiate test-instantiate)
|
||||
add_test(test-import-function test-import-function)
|
||||
|
||||
|
46
lib/runtime-c-api/tests/test-import-function.c
Normal file
46
lib/runtime-c-api/tests/test-import-function.c
Normal file
@ -0,0 +1,46 @@
|
||||
#include <stdio.h>
|
||||
#include "../wasmer.h"
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static print_str_called = false;
|
||||
|
||||
void print_str(int32_t ptr, int32_t len, wasmer_instance_context_t *ctx) {
|
||||
printf("In print_str\n");
|
||||
print_str_called = true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
wasmer_import_object_t *import_object = wasmer_import_object_new();
|
||||
wasmer_imports_set_import_func(import_object, "env", "print_str", print_str);
|
||||
|
||||
// Read the wasm file bytes
|
||||
FILE *file = fopen("wasm_sample_app.wasm", "r");
|
||||
fseek(file, 0, SEEK_END);
|
||||
long len = ftell(file);
|
||||
uint8_t *bytes = malloc(len);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
fread(bytes, 1, len, file);
|
||||
fclose(file);
|
||||
|
||||
wasmer_instance_t *instance = NULL;
|
||||
wasmer_compile_result_t compile_result = wasmer_instantiate(&instance, bytes, len, import_object);
|
||||
printf("Compile result: %d\n", compile_result);
|
||||
assert(compile_result == WASMER_COMPILE_OK);
|
||||
|
||||
wasmer_value_t params[] = {};
|
||||
wasmer_value_t results[] = {};
|
||||
wasmer_call_result_t call_result = wasmer_instance_call(instance, "hello_wasm", params, 0, results, 0);
|
||||
printf("Call result: %d\n", call_result);
|
||||
assert(call_result == WASMER_CALL_OK);
|
||||
|
||||
assert(print_str_called);
|
||||
|
||||
// TODO review import object ownership, instantiate moves it
|
||||
printf("Destroy instance\n");
|
||||
//wasmer_instance_destroy(instance); // TODO error here
|
||||
printf("Destroy import object\n");
|
||||
//wasmer_import_object_destroy(import_object); // TODO error here
|
||||
return 0;
|
||||
}
|
BIN
lib/runtime-c-api/tests/wasm_sample_app.wasm
Executable file
BIN
lib/runtime-c-api/tests/wasm_sample_app.wasm
Executable file
Binary file not shown.
@ -23,6 +23,8 @@ typedef uint32_t wasmer_value_tag;
|
||||
|
||||
typedef struct wasmer_import_object_t wasmer_import_object_t;
|
||||
|
||||
typedef struct wasmer_instance_context_t wasmer_instance_context_t;
|
||||
|
||||
typedef struct wasmer_instance_t wasmer_instance_t;
|
||||
|
||||
typedef union {
|
||||
@ -41,6 +43,11 @@ void wasmer_import_object_destroy(wasmer_import_object_t *import_object);
|
||||
|
||||
wasmer_import_object_t *wasmer_import_object_new(void);
|
||||
|
||||
void wasmer_imports_set_import_func(wasmer_import_object_t *import_object,
|
||||
const char *namespace_,
|
||||
const char *name,
|
||||
void (*func)(void *data));
|
||||
|
||||
wasmer_call_result_t wasmer_instance_call(wasmer_instance_t *instance,
|
||||
const char *name,
|
||||
const wasmer_value_t *params,
|
||||
@ -48,6 +55,8 @@ wasmer_call_result_t wasmer_instance_call(wasmer_instance_t *instance,
|
||||
wasmer_value_t *results,
|
||||
int results_len);
|
||||
|
||||
void wasmer_instance_context_memory(wasmer_instance_context_t *instance);
|
||||
|
||||
void wasmer_instance_destroy(wasmer_instance_t *instance);
|
||||
|
||||
wasmer_compile_result_t wasmer_instantiate(wasmer_instance_t **instance,
|
||||
|
Reference in New Issue
Block a user