mirror of
https://github.com/fluencelabs/marine.git
synced 2025-03-15 05:50:49 +00:00
WIP: just got result from greeting(but with second unexpected output)
This commit is contained in:
parent
1efd1413d7
commit
611d024b23
573
Cargo.lock
generated
573
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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>
|
||||
|
@ -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) {
|
||||
@ -8,4 +34,19 @@ 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];
|
||||
}
|
@ -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),
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
pub struct Exports {
|
||||
some_export: DynFunc<'static>
|
||||
}
|
||||
|
||||
impl Exports {
|
||||
pub fn get(&self, _name: &str) -> Result<DynFunc<'_>, String> {
|
||||
Ok(self.some_export)
|
||||
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>
|
||||
exports: Vec<Export>,
|
||||
}
|
||||
|
||||
impl Exports {
|
||||
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}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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(),
|
||||
|
@ -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> std::ops::Deref for WITMemoryView<'a> {
|
||||
type Target = [std::cell::Cell<u8>];
|
||||
impl<'a> WITMemoryView<'a> {
|
||||
pub fn new(memory: &'a WasmMemory) -> Self {
|
||||
crate::js_log("WITMemoryView::new called");
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.data.deref()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(super) struct WITMemory {
|
||||
memory: i32,
|
||||
}
|
||||
|
||||
impl wasm::structures::MemoryView for WITMemoryView<'_> {}
|
||||
|
||||
impl<'a> wasm::structures::Memory<WITMemoryView<'a>> for WITMemory {
|
||||
fn view(&self) -> WITMemoryView<'a> {
|
||||
WITMemoryView {
|
||||
data: Vec::new(),
|
||||
data3: <_>::default()
|
||||
Self {
|
||||
slice: MemSlice2 {
|
||||
slice_ref: memory
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<'a> std::ops::Deref for WITMemoryView<'a> {
|
||||
type Target = MemSlice2<'a>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
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 {
|
||||
}
|
||||
|
||||
impl WITMemory {
|
||||
pub fn new(_module_name: String) -> Self {
|
||||
js_log("created WITMemory");
|
||||
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
impl wasm::structures::Memory<WITMemoryView<'static>> for WITMemory {
|
||||
fn view(&self) -> WITMemoryView<'static> {
|
||||
crate::js_log("got memory view");
|
||||
WITMemoryView::new(&MEMORY_CONTAINTER)
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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()}
|
||||
}
|
||||
}
|
@ -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(|_| ()),*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user