Add test to import function and call it

This commit is contained in:
Brandon Fish
2019-02-02 17:43:59 -06:00
parent 9120a9d1f8
commit ffb3dc083a
8 changed files with 129 additions and 1 deletions

1
Cargo.lock generated
View File

@ -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]]

View File

@ -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]

View File

@ -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, &params[..]);
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) {

View File

@ -10,3 +10,4 @@ compile_commands.json
CTestTestfile.cmake
_deps
test-instantiate
test-import-function

View File

@ -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)

View 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;
}

Binary file not shown.

View File

@ -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,