WIP: just got result from greeting(but with second unexpected output)

This commit is contained in:
Valery Antopol 2021-11-08 10:15:12 +03:00
parent 1efd1413d7
commit 611d024b23
16 changed files with 802 additions and 350 deletions

573
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -11,5 +11,5 @@ name = "marine_it_interfaces"
path = "src/lib.rs"
[dependencies]
wasmer-it = { package = "wasmer-interface-types-fl", version = "0.20.2" }
wasmer-it = { package = "wasmer-interface-types-fl", version = "0.20.1", path = "../../../interface-types/wasmer-it" }
multimap = "0.8.1"

View File

@ -17,7 +17,7 @@ marine-module-interface = { path = "../module-interface", version = "0.1.6" }
anyhow = "1.0.31"
walrus = "0.18.0"
wasmer-core = { package = "wasmer-runtime-core-fl", version = "=0.17.1"}
wasmer-it = { package = "wasmer-interface-types-fl", version = "0.20.2" }
wasmer-it = { package = "wasmer-interface-types-fl", version = "0.20.1", path = "../../../interface-types/wasmer-it" }
nom = "5.1"
itertools = "0.10.0"

View File

@ -16,7 +16,7 @@ marine-it-interfaces = { path = "../it-interfaces", version = "0.4.1" }
anyhow = "1.0.31"
walrus = "0.18.0"
wasmer-core = { package = "wasmer-runtime-core-fl", version = "=0.17.1"}
wasmer-it = { package = "wasmer-interface-types-fl", version = "0.20.2" }
wasmer-it = { package = "wasmer-interface-types-fl", version = "0.20.1", path = "../../../interface-types/wasmer-it" }
nom = "5.1"
itertools = "0.10.0"

View File

@ -23,7 +23,9 @@ marine-utils = { path = "../crates/utils", version = "0.2.0" }
#wasmer-runtime = { package = "wasmer-runtime-fl", version = "=0.17.1" }
# dynamicfunc-fat-closures allows using state inside DynamicFunc
#wasmer-core = { package = "wasmer-runtime-core-fl", version = "=0.17.1", features = ["dynamicfunc-fat-closures"] }
wasmer-it = { package = "wasmer-interface-types-fl", version = "0.20.2" }
#wasmer-it = { package = "wasmer-interface-types-fl", version = "0.20.2" }
wasmer-it = { package = "wasmer-interface-types-fl", version = "0.20.1", path = "../../interface-types/wasmer-it" }
it-utils = { path = "../../interface-types/crates/utils", version = "0.1.0" }
it-lilo = "0.1.0"
#wasmer-wasi = { package = "wasmer-wasi-fl", version = "0.17.1" }
@ -34,6 +36,7 @@ boolinator = "2.4.0"
once_cell = "1.7.2"
semver = "0.11.0"
serde = "1.0.118"
serde_json = "1.0.68"
log = "0.4.8"
paste = "1.0.5"

View File

@ -5,11 +5,13 @@
<title>hello-wasm example</title>
</head>
<body>
<script type="module">
import init, {greet} from "./pkg/marine_web_runtime.js";
<script type="module" src="index.js">
import init, {greet, test_read_memory, test_write_memory} from "./pkg/marine_web_runtime.js";
init()
.then(() => {
greet("WebAssembly")
greet("WebAssembly 2");
test_read_memory();
test_write_memory();
});
</script>
</body>

View File

@ -1,5 +1,31 @@
export function call_export(module_name, export_name) {
window.MARINE_WASM_MODULES[module_name].exports[export_name]()
export function call_export(module_name, export_name, args) {
console.log("JS: call_export called with: ", module_name, export_name, args)
let parsed_args = JSON.parse(args);
console.log("parsed args: ", args);
let prepared_args = [];
for (let i = 0; i < parsed_args.length; i++) {
let arg = parsed_args[i];
console.log(arg)
prepared_args.push(arg["I32"])
}
console.log("prepared args: ", prepared_args);
let result = window.MARINE_WASM_MODULES[module_name].exports[export_name](...prepared_args);
console.log("got result: ", result)
let json_string = "[]";
if (result !== undefined) {
json_string = "[" + JSON.stringify(result) + "]"
}
console.log("got result_string: ", json_string)
return json_string
}
export function get_memory_size(module_name) {
console.log("called get_memory_size with name=", module_name);
let buf = new Uint8Array(window.MARINE_WASM_MODULES[module_name].exports.memory.buffer);
console.log("result=", buf.byteLength);
return buf.byteLength
}
export function write_memory(module_name, offset, bytes) {
@ -9,3 +35,18 @@ export function write_memory(module_name, offset, bytes) {
export function read_memory(module_name, offset, size) {
}
export function write_byte(module_name, offset, value) {
console.log("write_byte called with args: module_name={}, offset={}, value={}", module_name, offset, value)
let buf = new Uint8Array(window.MARINE_WASM_MODULES[module_name].exports.memory.buffer);
console.log(buf)
buf[offset] = value
}
export function read_byte(module_name, offset) {
console.log("read_byte called with args: module_name={}, offset={}", module_name, offset)
let buf = new Uint8Array(window.MARINE_WASM_MODULES[module_name].exports.memory.buffer);
console.log(buf)
console.log("read_byte returns {}", buf[offset])
return buf[offset];
}

View File

@ -34,6 +34,7 @@ use wasmer_it::ast::{Interfaces, FunctionArg};
use thiserror::Error as ThisError;
#[allow(unused)]
use wasmer_it::interpreter::wasm::structures::{LocalImport, Export,Memory,MemoryView};
use module::MModule;
pub(crate) mod marine_js;
@ -76,6 +77,8 @@ pub(crate) type MResult<T> = std::result::Result<T, MError>;
use once_cell::sync::Lazy;
use std::str::FromStr;
use crate::module::type_converters::ival_to_string;
static MINIMAL_SUPPORTED_SDK_VERSION: Lazy<semver::Version> = Lazy::new(|| {
semver::Version::from_str("0.6.0").expect("invalid minimal sdk version specified")
});
@ -102,35 +105,8 @@ pub struct JsLocalImport {
}
impl LocalImport for JsLocalImport {
fn name(&self) -> &str {
todo!()
}
fn inputs_cardinality(&self) -> usize {
todo!()
}
fn outputs_cardinality(&self) -> usize {
todo!()
}
fn arguments(&self) -> &[FunctionArg] {
todo!()
}
fn outputs(&self) -> &[IType] {
todo!()
}
fn call(&self, arguments: &[IValue]) -> Result<Vec<IValue>, ()> {
//call_export(self.module_name, self.name())
Err(())
}
}
struct JsExport {
name: String,
//name: String,
}
@ -155,7 +131,7 @@ impl Export for JsExport {
todo!()
}
fn call(&self, arguments: &[IValue]) -> Result<Vec<IValue>, ()> {
fn call(&self, _arguments: &[IValue]) -> Result<Vec<IValue>, ()> {
todo!()
}
}
@ -173,6 +149,10 @@ extern "C" {
fn log(s: &str);
}
pub fn js_log(s: &str) {
log(s)
}
#[wasm_bindgen]
pub fn greet(name: &str) {
alert(&format!("Hello, {}!", name));
@ -180,17 +160,18 @@ pub fn greet(name: &str) {
#[wasm_bindgen]
pub fn test_call_export() {
call_export("greeting", "test_export");
call_export("greeting", "test_export", "[0]");
}
#[wasm_bindgen]
pub fn test_read_memory() {
let _result = read_memory("greeting", 0, 4);
let result:u8 = read_byte("greeting", 0);
log(&result.to_string())
}
#[wasm_bindgen]
pub fn test_write_memory() {
let _result = write_memory("greeting", 0, &[0, 1, 2, 3]);
write_byte("greeting", 0, 42);
}
#[wasm_bindgen]
@ -204,6 +185,21 @@ pub fn test_it_section(bytes: &[u8]) {
log(&result)
}
#[wasm_bindgen]
pub fn test_instantiate_module(name: &str, wit_section_bytes: &[u8]) {
#[allow(unused)]
let mut module = MModule::new(
name,
wit_section_bytes,
).unwrap();
js_log("callng export");
let output = module.call("greeting", "greeting", &vec![IValue::String("wasm test".to_string())]).unwrap();
for out in output {
js_log(&format!("got output: {}", ival_to_string(&out)));
}
js_log("export call finished");
}
pub(crate) fn extract_it_from_bytes(wit_section_bytes: &[u8]) -> Result<Interfaces<'_>, MyError> {
match wasmer_it::decoders::binary::parse::<(&[u8], nom::error::ErrorKind)>(wit_section_bytes) {
Ok((remainder, it)) if remainder.is_empty() => Ok(it),

View File

@ -4,19 +4,28 @@ use wasm_bindgen::prelude::*;
use std::marker::PhantomData;
use serde::{Deserialize, Serialize};
use std::borrow::Cow;
use it_utils::{MemSlice2, ByteAccess, MemSlice3};
use marine_it_interfaces::MITInterfaces;
use crate::js_log;
use crate::module::type_converters::{itype_arg_to_wtypes, itype_to_raw_output_types};
// marine-related imports
#[wasm_bindgen(module = "/marine-js.js")]
extern {
pub fn call_export(module_name: &str, export_name: &str) -> i32;
pub fn call_export(module_name: &str, export_name: &str, args: &str) -> String;
pub fn read_memory(module_name: &str, module_offset: usize, module_len: usize) -> Vec<u8>;
pub fn write_memory(module_name: &str, module_offset: usize, data: &[u8]) -> i32;
pub fn read_byte(module_name: &str, module_offset: usize) -> u8;
pub fn write_byte(module_name: &str, module_offset: usize, value: u8);
pub fn get_memory_size(module_name: &str) -> i32;
}
pub struct Ctx {}
//pub struct Ctx {}
/*
pub struct Func<'a, Args: 'a, Rets> {
data: PhantomData<Args>,
data2: PhantomData<Rets>,
@ -26,7 +35,8 @@ pub struct Func<'a, Args: 'a, Rets> {
pub struct DynamicFunc<'a> {
data: PhantomData<&'a i32>
}
*/
#[derive(Clone)]
pub struct FuncSig {
params: Cow<'static, [WType]>,
returns: Cow<'static, [WType]>,
@ -43,17 +53,27 @@ impl FuncSig {
}
pub struct Instance {
pub exports: Exports
pub exports: Exports,
pub module_name: String,
}
impl Instance {
pub fn exports(&self) -> &Exports {
&self.exports
pub fn new(mit: &MITInterfaces, module_name: String) -> Self {
Self {
exports: Exports::new(mit),
module_name
}
}
pub fn exports(&self) -> ExportIter {
ExportIter::new(&self.exports)
}
}
pub struct DynFunc<'a> {
pub(crate) signature: FuncSig,
pub name: String,
pub module_name: String,
//pub(crate) instance_inner: &'a InstanceInner,
//func_index: FuncIndex,
data3: PhantomData<&'a i32>
@ -64,12 +84,33 @@ impl<'a> DynFunc<'_> {
&self.signature
}
pub fn call(&self, _args: &[WValue]) -> Result<Vec<WValue>, String> {
Err("not implemented".to_string())
pub fn call(&self, args: &[WValue]) -> Result<Vec<WValue>, String> {
crate::js_log(&format!("called DynFunc::call name=({}) with n args {}", self.name, args.len()));
let result = serde_json::ser::to_string(args);
if let Err(e) = result {
js_log(&format!("cannot serialize: {}", e));
return Err("cannot serialize".to_string());
}
let args = result.unwrap();
let output = call_export(&self.module_name, &self.name, &args);
js_log(&format!("DynFunc::Call got result json {}", output));
let value = serde_json::de::from_str::<serde_json::Value>(&output);
match value {
Ok(serde_json::Value::Array(values)) => {
let values = values.iter().map(|value|{
WValue::I32(value.as_i64().unwrap() as i32)
}).collect::<Vec<_>>();
Ok(values)
},
_ => {
js_log("invalid_json got");
Err("invalid json got".to_string())
}
}
}
}
/*
pub struct SigRegistry {}
pub struct ExportIndex {}
pub struct WasmTypeList {}
@ -79,21 +120,91 @@ pub struct Namespace {}
pub struct ImportObject {}
pub struct Module {}
pub struct LocalMemory {}
*/
#[allow(dead_code)]
#[derive(Clone)]
pub enum Export {
Memory(i32)
Memory,
Function(ProcessedExport)
}
impl Export {
pub fn name(&self) -> String {
match self {
Self::Memory => "memory".to_string(),
Self::Function(func) => func.name.clone()
}
}
}
pub struct Exports {
some_export: DynFunc<'static>
//some_export: DynFunc<'static>
exports: Vec<Export>,
}
impl Exports {
pub fn get(&self, _name: &str) -> Result<DynFunc<'_>, String> {
Ok(self.some_export)
pub fn new(mit: &MITInterfaces) -> Self {
let mut exports = mit
.exports()
.filter_map( |export| {
crate::js_log(&format!("processing export {} {}", export.name, export.function_type));
let fn_type = mit.type_by_idx(export.function_type).unwrap();
crate::js_log(&format!("got type {}", fn_type.to_string()));
if let wasmer_it::ast::Type::Function{arguments, output_types} = fn_type {
let arg_types = arguments.iter().map(|arg| itype_arg_to_wtypes(&arg.ty)).flatten().collect();
let output_types = output_types.iter().map(itype_to_raw_output_types).flatten().collect();
let sig = FuncSig {
params: Cow::Owned(arg_types),
returns: Cow::Owned(output_types),
};
crate::js_log(&format!("it is a function: {}", export.name.to_string()));
Some(Export::Function(ProcessedExport {
sig,
index: export.function_type,
name: export.name.to_string()
}))
} else {
crate::js_log(&format!("it is not a function"));
None
}
}).collect::<Vec<Export>>();
exports.push(Export::Memory);
crate::js_log(&format!("processed exports"));
Self {
exports
}
}
pub fn get(&self, name: &str) -> Result<DynFunc<'_>, String> {
crate::js_log(&format!("Exports.get called with name {}", name));
let export = self.exports.iter().find(|export| {
if let Export::Function(func) = export {
func.name == name
} else {
false
}
});
match export {
Some(Export::Function(function)) => {
Ok(DynFunc {
signature: function.sig.clone(),
name: function.name.clone(),
module_name: "greeting".to_string(),
data3: Default::default()
})
}
Some(_) |
None => Err(format!("cannot find export {}", name))
}
}
}
#[derive(Clone)]
pub struct ProcessedExport {
sig: FuncSig,
index: u32,
name: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum WType {
@ -134,6 +245,7 @@ pub enum WValue {
}
impl WValue {
/*
/// The `Type` of this `Value`.
pub fn ty(&self) -> WType {
match self {
@ -155,5 +267,74 @@ impl WValue {
WValue::V128(x) => x,
}
}
*/
}
/// An iterator to an instance's exports.
pub struct ExportIter<'a> {
_data: PhantomData<&'a i32>,
exports: &'a Exports,
index: usize,
}
impl<'a> ExportIter<'a> {
pub(crate) fn new(exports: &'a Exports) -> Self {
Self {
_data: PhantomData::<&'a i32>::default(),
exports,
index: 0,
}
}
}
impl<'a> Iterator for ExportIter<'a> {
type Item = (String, Export);
fn next(&mut self) -> Option<(String, Export)> {
let export = self.exports.exports.get(self.index);
self.index += 1;
export.map(|export| {
(export.name(), export.clone())
})
}
}
#[derive(Clone)]
pub struct WasmMemory {
pub module_name: &'static str,
}
impl MemSlice3 for WasmMemory {
fn len(&self) -> usize {
crate::js_log("WasmMemory::len calledx");
get_memory_size(&self.module_name) as usize
}
fn index(&self, index: usize) -> it_utils::ByteAccess {
crate::js_log(&format!("WasmMemory::index called with {}", index));
ByteAccess {
slice: MemSlice2{ slice_ref: self},
index
}
}
fn get(&self, index: usize) -> u8 {
crate::js_log(&format!("WasmMemory::get called with {}", index));
read_byte(&self.module_name, index)
}
fn set(&self, index: usize, value: u8) {
crate::js_log(&format!("WasmMemory::set called with {} {}", index, value));
write_byte(&self.module_name, index, value);
}
fn range_iter(&self, begin: usize, end: usize) -> it_utils::MemSliceIter {
crate::js_log(&format!("WasmMemory::range_iter called with {} {}", begin, end));
it_utils::MemSliceIter {
begin,
end,
slice: MemSlice2 {slice_ref: self}
}
}
}

View File

@ -19,4 +19,4 @@ mod version_checker;
//pub(crate) use prepare::prepare_module;
//pub(crate) use version_checker::check_sdk_version;
//pub(crate) use version_checker::check_it_version;
pub(crate) use version_checker::check_it_version;

View File

@ -25,7 +25,7 @@ use marine_it_interfaces::MITInterfaces;
//use marine_it_parser::extract_it_from_module;
use marine_utils::SharedString;
//use wasmer_core::Instance as WasmerInstance;
use crate::marine_js::Instance as WasmerInstance;
use crate::marine_js::{Instance as WasmerInstance};
//use wasmer_core::import::Namespace;
//use crate::marine_js::Namespace;
//use wasmer_runtime::compile;
@ -43,6 +43,7 @@ use crate::module::wit_function::WITFunction;
type ITInterpreter =
Interpreter<ITInstance, ITExport, WITFunction, WITMemory, WITMemoryView<'static>>;
use crate::js_log;
#[derive(Clone)]
pub(super) struct ITModuleFunc {
@ -60,14 +61,13 @@ pub(super) struct Callable {
impl Callable {
pub fn call(&mut self, args: &[IValue]) -> MResult<Vec<IValue>> {
use wasmer_it::interpreter::stack::Stackable;
js_log(&format!("Callable::call: start"));
let result = self
.it_module_func
.interpreter
.run(args, Arc::make_mut(&mut self.it_instance))?
.as_slice()
.to_owned();
Ok(result)
}
}
@ -110,35 +110,38 @@ pub(crate) fn extract_it_from_bytes(wit_section_bytes: &[u8]) -> Result<Interfac
Err(e) => Err(format!("ITParserError::CorruptedITSection({})", e)),
}
}
#[allow(unused)]
impl MModule {
pub(crate) fn new(
name: &str,
wit_section_bytes: &[u8],
wasmer_instance: WasmerInstance,
//wasmer_instance: WasmerInstance,
//config: MModuleConfig,
modules: &HashMap<String, MModule>,
//modules: &HashMap<String, MModule>,
) -> MResult<Self> {
//let wasmer_module = compile(wasm_bytes)?;
//crate::misc::check_sdk_version(name, &wasmer_module)?;
let it = extract_it_from_bytes(&wit_section_bytes)?;
//crate::misc::check_it_version(name, &it.version)?;
crate::misc::check_it_version(name, &it.version)?;
js_log("checked it_section");
let mit = MITInterfaces::new(it);
js_log("created mit");
let wasmer_instance = WasmerInstance::new(&mit, name.to_string());
js_log("created wasmer_instance");
let mut wit_instance = Arc::new_uninit();
js_log("created wit_instance");
//let wit_import_object = Self::adjust_wit_imports(&mit, wit_instance.clone())?;
//let raw_imports = config.raw_imports.clone();
//let (wasi_import_object, host_closures_import_object) =
// Self::create_import_objects(config, &mit, wit_import_object.clone())?;
//let wasmer_instance = Instance::new(&mit);
// let wasmer_instance = wasmer_module.instantiate(&wasi_import_object)?;
let it_instance = unsafe {
// get_mut_unchecked here is safe because currently only this modules have reference to
// it and the environment is single-threaded
*Arc::get_mut_unchecked(&mut wit_instance) =
MaybeUninit::new(ITInstance::new(&wasmer_instance, name, &mit, modules)?);
MaybeUninit::new(ITInstance::new(&wasmer_instance, /*name,*/ &mit, /*modules*/)?);
std::mem::transmute::<_, Arc<ITInstance>>(wit_instance)
};
@ -169,6 +172,7 @@ impl MModule {
) -> MResult<Vec<IValue>> {
self.export_funcs.get_mut(function_name).map_or_else(
|| {
crate::js_log(&format!("MModule::call: cannot find export {}", function_name));
Err(MError::NoSuchFunction(
module_name.to_string(),
function_name.to_string(),

View File

@ -15,37 +15,59 @@
*/
use wasmer_it::interpreter::wasm;
use std::cell::Cell;
use std::marker::PhantomData;
use wasmer_it::interpreter::wasm::structures::MemSlice2;
use crate::js_log;
use crate::marine_js::WasmMemory;
//use wasmer_core::memory::{Memory, MemoryView};
// WEB TODO: implement with js interface
pub(super) struct WITMemoryView<'a> {
data3: PhantomData<&'a i32>,
data: Vec<Cell<u8>>,
slice: MemSlice2<'a>,
}
impl<'a> WITMemoryView<'a> {
pub fn new(memory: &'a WasmMemory) -> Self {
crate::js_log("WITMemoryView::new called");
Self {
slice: MemSlice2 {
slice_ref: memory
}
}
}
}
impl<'a> std::ops::Deref for WITMemoryView<'a> {
type Target = [std::cell::Cell<u8>];
type Target = MemSlice2<'a>;
fn deref(&self) -> &Self::Target {
self.data.deref()
crate::js_log("got slice from WITMemoryView");
&self.slice
}
}
impl wasm::structures::MemoryView for WITMemoryView<'static> {}
const MEMORY_CONTAINTER: WasmMemory = WasmMemory {
module_name: "greeting",
};
#[derive(Clone)]
pub(super) struct WITMemory {
memory: i32,
}
impl wasm::structures::MemoryView for WITMemoryView<'_> {}
impl WITMemory {
pub fn new(_module_name: String) -> Self {
js_log("created WITMemory");
impl<'a> wasm::structures::Memory<WITMemoryView<'a>> for WITMemory {
fn view(&self) -> WITMemoryView<'a> {
WITMemoryView {
data: Vec::new(),
data3: <_>::default()
Self {}
}
}
impl wasm::structures::Memory<WITMemoryView<'static>> for WITMemory {
fn view(&self) -> WITMemoryView<'static> {
crate::js_log("got memory view");
WITMemoryView::new(&MEMORY_CONTAINTER)
}
}

View File

@ -19,7 +19,7 @@ mod marine_module;
mod memory;
mod wit_function;
mod wit_instance;
mod type_converters;
pub mod type_converters;
pub use wit_instance::MRecordTypes;
pub use wasmer_it::IType;

View File

@ -17,7 +17,7 @@
/// Contains converters of types and values between Wasmer and wasmer_interface_types.
use super::{WType, WValue, IType, IValue};
pub(super) fn wtype_to_itype(ty: &WType) -> IType {
pub(crate) fn wtype_to_itype(ty: &WType) -> IType {
match ty {
WType::I32 => IType::I32,
WType::I64 => IType::I64,
@ -26,8 +26,8 @@ pub(super) fn wtype_to_itype(ty: &WType) -> IType {
WType::V128 => unimplemented!(),
}
}
pub(super) fn itype_to_wtype(ty: &IType) -> WType {
/*
pub(crate) fn itype_to_wtype(ty: &IType) -> WType {
match ty {
IType::S8 => WType::I32,
IType::S16 => WType::I32,
@ -48,13 +48,17 @@ pub(super) fn itype_to_wtype(ty: &IType) -> WType {
}
}
*/
pub(super) fn ival_to_wval(value: &IValue) -> WValue {
match value {
IValue::I32(v) => WValue::I32(*v),
IValue::I64(v) => WValue::I64(*v),
IValue::F32(v) => WValue::F32(*v),
IValue::F64(v) => WValue::F64(*v),
_ => unimplemented!(),
_ => {
crate::js_log(&format!("called ival_to_wval with unknown value"));
unimplemented!()
},
}
}
@ -67,3 +71,68 @@ pub(super) fn wval_to_ival(value: &WValue) -> IValue {
_ => unimplemented!(),
}
}
pub fn itype_arg_to_wtypes(arg: &IType) -> Vec<WType> {
match arg {
IType::Boolean
| IType::S8
| IType::S16
| IType::S32
| IType::I32
| IType::U8
| IType::U16
| IType::U32 => vec![WType::I32],
IType::S64 | IType::U64 | IType::I64 => vec![WType::I64],
IType::F32 => vec![WType::F32],
IType::F64 => vec![WType::F64],
IType::String => vec![WType::I32, WType::I32],
_ => {
crate::js_log("itype_arg_to_wtypes got unexpected type");
unimplemented!();
}
}
}
pub fn itype_to_raw_output_types(ty: &IType) -> Vec<WType> {
match ty {
IType::Boolean
| IType::S8
| IType::S16
| IType::S32
| IType::I32
| IType::U8
| IType::U16
| IType::U32 => vec![WType::I32],
IType::I64 | IType::U64 | IType::S64 => vec![WType::I64],
IType::F32 => vec![WType::F32],
IType::F64 => vec![WType::F64],
| IType::String
| IType::Record(..) => vec![],
_ => {
crate::js_log("itype_to_raw_output_types got unexpected type");
unimplemented!();
}
}
}
pub fn ival_to_string(val: &IValue) -> String {
match val {
IValue::Boolean(val) => {val.to_string()}
IValue::S8(val) => {val.to_string()}
IValue::S16(val) => {val.to_string()}
IValue::S32(val) => {val.to_string()}
IValue::S64(val) => {val.to_string()}
IValue::U8(val) => {val.to_string()}
IValue::U16(val) => {val.to_string()}
IValue::U32(val) => {val.to_string()}
IValue::U64(val) => {val.to_string()}
IValue::F32(val) => {val.to_string()}
IValue::F64(val) => {val.to_string()}
IValue::String(val) => {val.to_string()}
IValue::ByteArray(_) => {"some byte array".to_string()}
IValue::Array(_) => {"some array".to_string()}
IValue::I32(val) => {val.to_string()}
IValue::I64(val) => {val.to_string()}
IValue::Record(_) => {"some record".to_string()}
}
}

View File

@ -14,9 +14,9 @@
* limitations under the License.
*/
use super::marine_module::MModule;
//use super::marine_module::MModule;
use super::{IType, IFunctionArg, IValue, WValue};
use super::marine_module::Callable;
//use super::marine_module::Callable;
use crate::MResult;
//use crate::marine_js;
@ -31,11 +31,11 @@ use crate::marine_js::DynFunc;
enum WITFunctionInner {
Export {
func: Rc<DynFunc<'static>>,
},
},/*
Import {
// TODO: use dyn Callable here
callable: Rc<Callable>,
},
},*/
}
/// Represents all import and export functions that could be called from IT context by call-core.
@ -52,6 +52,7 @@ impl WITFunction {
pub(super) fn from_export(dyn_func: DynFunc<'static>, name: String) -> MResult<Self> {
use super::type_converters::wtype_to_itype;
let signature = dyn_func.signature();
let arguments = signature
.params()
@ -82,7 +83,7 @@ impl WITFunction {
inner,
})
}
/*
/// Creates function from a module import.
pub(super) fn from_import(
wit_module: &MModule,
@ -104,6 +105,7 @@ impl WITFunction {
inner,
})
}
*/
}
impl wasm::structures::LocalImport for WITFunction {
@ -129,16 +131,16 @@ impl wasm::structures::LocalImport for WITFunction {
fn call(&self, arguments: &[IValue]) -> std::result::Result<Vec<IValue>, ()> {
use super::type_converters::{ival_to_wval, wval_to_ival};
crate::js_log(&format!("called WITFunction::call with n argts {}", arguments.len()));
match &self.inner {
WITFunctionInner::Export { func, .. } => func
.as_ref()
.call(&arguments.iter().map(ival_to_wval).collect::<Vec<WValue>>())
.map(|result| result.iter().map(wval_to_ival).collect())
.map_err(|_| ()),
.map_err(|_| ()),/*
WITFunctionInner::Import { callable, .. } => Rc::make_mut(&mut callable.clone())
.call(arguments)
.map_err(|_| ()),
.map_err(|_| ()),*/
}
}
}

View File

@ -15,19 +15,18 @@
*/
use super::wit_prelude::*;
use super::marine_module::MModule;
//use super::marine_module::MModule;
use super::IRecordType;
use crate::MResult;
use crate::{js_log, MResult};
use marine_it_interfaces::MITInterfaces;
use marine_it_interfaces::ITAstType;
use wasmer_it::interpreter::wasm;
use wasmer_it::interpreter::wasm::structures::{LocalImportIndex, TypedIndex};
use wasmer_it::interpreter::wasm::structures::{LocalImportIndex, Memory, MemSlice2, TypedIndex};
//use wasmer_core::Instance as WasmerInstance;
use crate::marine_js::{Instance as WasmerInstance, DynFunc};
use std::collections::HashMap;
use std::cell::Cell;
use std::rc::Rc;
pub type MRecordTypes = HashMap<u64, Rc<IRecordType>>;
@ -48,15 +47,15 @@ pub(super) struct ITInstance {
impl ITInstance {
pub(super) fn new(
wasmer_instance: &WasmerInstance,
module_name: &str,
//module_name: &str,
wit: &MITInterfaces<'_>,
modules: &HashMap<String, MModule>,
//modules: &HashMap<String, MModule>,
) -> MResult<Self> {
let mut exports = Self::extract_raw_exports(wasmer_instance, wit)?;
let imports = Self::extract_imports(module_name, modules, wit, exports.len())?;
let exports = Self::extract_raw_exports(wasmer_instance, wit)?;
//let imports = Self::extract_imports("test", &<_>::default(), wit, exports.len())?;
let memories = Self::extract_memories(wasmer_instance);
exports.extend(imports);
//exports.extend(imports);
let funcs = exports;
let record_types_by_id = Self::extract_record_types(wit);
@ -94,6 +93,7 @@ impl ITInstance {
.collect()
}
/*
/// Extracts only those imports that don't have implementations.
fn extract_imports(
module_name: &str,
@ -138,14 +138,16 @@ impl ITInstance {
.collect::<MResult<HashMap<_, _>>>()
}
*/
fn extract_memories(wasmer_instance: &WasmerInstance) -> Vec<WITMemory> {
//use wasmer_core::export::Export::Memory;
use crate::marine_js::Export::Memory;
let mut memories = wasmer_instance
let memories = wasmer_instance
.exports()
.filter_map(|(_, export)| match export {
Memory(memory) => Some(WITMemory{memory}),
Memory => Some(WITMemory::new(wasmer_instance.module_name.clone())),
_ => None,
})
.collect::<Vec<_>>();
@ -178,19 +180,23 @@ impl ITInstance {
}
}
impl wasm::structures::Instance<ITExport, WITFunction, WITMemory, WITMemoryView<'_>>
impl wasm::structures::Instance<ITExport, WITFunction, WITMemory, WITMemoryView<'static>>
for ITInstance
{
fn export(&self, _export_name: &str) -> Option<&ITExport> {
js_log(&format!("called ITInstance::export with {}", _export_name));
// exports aren't used in this version of IT
None
}
fn local_or_import<I: TypedIndex + LocalImportIndex>(&self, index: I) -> Option<&WITFunction> {
js_log(&format!("called ITInstance::local_or_import with {}", index.index()));
js_log(&format!("ITInstance::export funcs size {}", self.funcs.len()));
self.funcs.get(&index.index())
}
fn memory(&self, index: usize) -> Option<&WITMemory> {
js_log(&format!("called ITInstance::memory with {}", index));
if index >= self.memories.len() {
None
} else {
@ -198,26 +204,29 @@ impl wasm::structures::Instance<ITExport, WITFunction, WITMemory, WITMemoryView<
}
}
fn memory_slice(&self, index: usize) -> Option<&[Cell<u8>]> {
fn memory_slice(&self, index: usize) -> Option<MemSlice2> {
//use wasmer_core::vm::LocalMemory;
use crate::marine_js::LocalMemory;
//use crate::marine_js::LocalMemory;
js_log(&format!("called ITInstance::memory_slice with {}", index));
if index >= self.memories.len() {
return None;
}
let memory = &self.memories[index];
let LocalMemory { base, .. } = unsafe { *memory.0.vm_local_memory() };
/* let LocalMemory { base, .. } = unsafe { *memory.0.vm_local_memory() };
let length = memory.0.size().bytes().0 / std::mem::size_of::<u8>();
let mut_slice: &mut [u8] = unsafe { std::slice::from_raw_parts_mut(base, length) };
let cell_slice: &Cell<[u8]> = Cell::from_mut(mut_slice);
let slice = cell_slice.as_slice_of_cells();
*/
Some(slice)
Some(*memory.view())
//Some(memory.view().boxed_copy())
}
fn wit_record_by_id(&self, index: u64) -> Option<&Rc<IRecordType>> {
js_log(&format!("called ITInstance::wit_record_by_id with {}", index));
self.record_types_by_id.get(&index)
}
}