mirror of
https://github.com/fluencelabs/marine.git
synced 2025-03-15 05:50:49 +00:00
compilable state with Exports and Memory/MemoryView
This commit is contained in:
parent
b96013535b
commit
6c94964f8e
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1883,6 +1883,7 @@ version = "0.4.0"
|
||||
name = "marine-wasm-backend-traits"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"it-memory-traits",
|
||||
"thiserror",
|
||||
"wasmer-interface-types-fl 0.21.1",
|
||||
"wasmer-runtime-core-fl",
|
||||
@ -1894,6 +1895,7 @@ dependencies = [
|
||||
name = "marine-wasmer-backend"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"it-memory-traits",
|
||||
"marine-wasm-backend-traits",
|
||||
"wasmer-interface-types-fl 0.21.1",
|
||||
"wasmer-runtime-core-fl",
|
||||
|
@ -8,6 +8,8 @@ edition = "2021"
|
||||
[dependencies]
|
||||
thiserror = "1.0.24"
|
||||
|
||||
it-memory-traits = "0.1.0"
|
||||
|
||||
wasmer-it = { package = "wasmer-interface-types-fl", version = "0.21.1" }
|
||||
wasmer-runtime = { package = "wasmer-runtime-fl", version = "=0.17.1" }
|
||||
# dynamicfunc-fat-closures allows using state inside DynamicFunc
|
||||
|
@ -1,6 +1,10 @@
|
||||
//pub mod errors;
|
||||
//pub mod it_memory_traits;
|
||||
|
||||
use std::fmt::Display;
|
||||
use std::path::PathBuf;
|
||||
use thiserror::Error;
|
||||
use it_memory_traits::{SequentialMemoryView, SequentialReader, SequentialWriter};
|
||||
|
||||
pub struct Value {}
|
||||
|
||||
@ -14,7 +18,13 @@ pub type WasmBackendResult<T> = Result<T, WasmBackendError>;
|
||||
|
||||
pub trait WasmBackend: Clone + 'static {
|
||||
type IO: ImportObject<Self>;
|
||||
type E: Export;
|
||||
type Exports: Exports<Self>;
|
||||
type MemoryExport: MemoryExport;
|
||||
type WITMemory: Memory<Self> + it_memory_traits::Memory<Self::WITMemoryView> + Clone + 'static;
|
||||
//type SR: SequentialReader;
|
||||
//type SW: SequentialWriter;
|
||||
type WITMemoryView: for<'a> SequentialMemoryView<'a,/* SR = Self::SR, SW = Self::SW*/> + 'static;
|
||||
type FunctionExport: FunctionExport;
|
||||
type M: Module<Self>;
|
||||
type I: Instance<Self>;
|
||||
type Wasi: WasiImplementation<Self>;
|
||||
@ -31,9 +41,17 @@ pub trait Module<WB: WasmBackend> {
|
||||
}
|
||||
|
||||
pub trait Instance<WB: WasmBackend> {
|
||||
fn export_iter<'a>(&'a self)
|
||||
-> Box<dyn Iterator<Item = (String, wasmer_runtime::Export)> + 'a>;
|
||||
fn exports(&self) -> &wasmer_core::instance::Exports;
|
||||
fn export_iter<'a>(
|
||||
&'a self,
|
||||
) -> Box<
|
||||
dyn Iterator<
|
||||
Item = (
|
||||
String,
|
||||
Export<<WB as WasmBackend>::MemoryExport, <WB as WasmBackend>::FunctionExport>,
|
||||
),
|
||||
> + 'a,
|
||||
>;
|
||||
fn exports(&self) -> &<WB as WasmBackend>::Exports;
|
||||
fn import_object(&self) -> &<WB as WasmBackend>::IO;
|
||||
|
||||
// maybe hide them inside impl
|
||||
@ -41,10 +59,26 @@ pub trait Instance<WB: WasmBackend> {
|
||||
fn context_mut(&mut self) -> &mut wasmer_core::vm::Ctx;
|
||||
}
|
||||
|
||||
pub trait Export {}
|
||||
pub trait Exports<WB: WasmBackend> {
|
||||
fn get<'a, T: wasmer_core::export::Exportable<'a>>(
|
||||
&'a self,
|
||||
name: &str,
|
||||
) -> wasmer_core::error::ResolveResult<T>;
|
||||
}
|
||||
|
||||
pub enum Export<M: MemoryExport, F: FunctionExport> {
|
||||
Memory(M),
|
||||
Function(F),
|
||||
Other,
|
||||
}
|
||||
|
||||
pub trait ImportObject<WB: WasmBackend>:
|
||||
Clone + Extend<(String, String, <WB as WasmBackend>::E)>
|
||||
Clone
|
||||
+ Extend<(
|
||||
String,
|
||||
String,
|
||||
Export<<WB as WasmBackend>::MemoryExport, <WB as WasmBackend>::FunctionExport>,
|
||||
)>
|
||||
{
|
||||
fn new() -> Self;
|
||||
fn extend_with_self(&mut self, other: Self);
|
||||
@ -58,10 +92,13 @@ pub trait ImportObject<WB: WasmBackend>:
|
||||
S: Into<String>,
|
||||
N: wasmer_runtime::LikeNamespace + Send + 'static;
|
||||
|
||||
|
||||
fn get_memory_env(&self) -> Option<Export<<WB as WasmBackend>::MemoryExport, <WB as WasmBackend>::FunctionExport>>;
|
||||
/*
|
||||
fn maybe_with_namespace<Func, InnerRet>(&self, namespace: &str, f: Func) -> Option<InnerRet>
|
||||
where
|
||||
Func: FnOnce(&(dyn wasmer_runtime::LikeNamespace + Send)) -> Option<InnerRet>,
|
||||
InnerRet: Sized;
|
||||
InnerRet: Sized;*/
|
||||
}
|
||||
|
||||
pub trait WasiImplementation<WB: WasmBackend> {
|
||||
@ -73,3 +110,13 @@ pub trait WasiImplementation<WB: WasmBackend> {
|
||||
mapped_dirs: Vec<(String, PathBuf)>,
|
||||
) -> Result<<WB as WasmBackend>::IO, String>;
|
||||
}
|
||||
|
||||
pub trait MemoryExport {
|
||||
}
|
||||
|
||||
pub trait FunctionExport {}
|
||||
|
||||
pub trait Memory<WB: WasmBackend> {
|
||||
fn new(export: <WB as WasmBackend>::MemoryExport) -> Self;
|
||||
fn view_from_ctx(ctx: &wasmer_runtime::Ctx, memory_index: u32) -> <WB as WasmBackend>::WITMemoryView;
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
marine-wasm-backend-traits = {path = "../wasm-backend-traits", version = "0.1.0"}
|
||||
it-memory-traits = "0.1.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"] }
|
||||
|
@ -1,22 +1,45 @@
|
||||
use marine_wasm_backend_traits::WasmBackend;
|
||||
use std::marker::PhantomData;
|
||||
use marine_wasm_backend_traits::{Export, Memory, WasmBackend};
|
||||
use marine_wasm_backend_traits::WasmBackendResult;
|
||||
use marine_wasm_backend_traits::WasmBackendError;
|
||||
use marine_wasm_backend_traits::Module;
|
||||
use marine_wasm_backend_traits::Instance;
|
||||
use marine_wasm_backend_traits::ImportObject;
|
||||
use marine_wasm_backend_traits::Export;
|
||||
use marine_wasm_backend_traits::FunctionExport;
|
||||
use marine_wasm_backend_traits::MemoryExport;
|
||||
use marine_wasm_backend_traits::Exports;
|
||||
use marine_wasm_backend_traits::WasiImplementation;
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::slice::Windows;
|
||||
use std::sync::Arc;
|
||||
use wasmer_core::fault::raw::longjmp;
|
||||
use wasmer_core::prelude::vm::Ctx;
|
||||
|
||||
mod memory_access;
|
||||
mod memory;
|
||||
|
||||
//use wasmer_it::interpreter::wasm::structures::{SequentialMemoryView, SequentialReader, SequentialWriter};
|
||||
use crate::memory::WITMemoryView;
|
||||
use crate::memory::WITMemory;
|
||||
use crate::memory_access::{WasmerSequentialReader, WasmerSequentialWriter};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct WasmerBackend {}
|
||||
pub struct WasmerBackend/*<'a>*/ {
|
||||
// _data: &'a PhantomData<i32>,
|
||||
}
|
||||
|
||||
impl WasmBackend for WasmerBackend {
|
||||
type E = WasmerExport;
|
||||
impl<'b> WasmBackend for WasmerBackend/*<'b>*/ {
|
||||
type Exports = WasmerInstance;
|
||||
type MemoryExport = WasmerMemoryExport;
|
||||
type FunctionExport = WasmerFunctionExport;
|
||||
type M = WasmerModule;
|
||||
type I = WasmerInstance;
|
||||
type IO = WasmerImportObject;
|
||||
//type SR = WasmerSequentialReader<'b>;
|
||||
//type SW = WasmerSequentialWriter<'b>;
|
||||
type WITMemory = WITMemory;
|
||||
type WITMemoryView = WITMemoryView<'static>;
|
||||
type Wasi = WasmerWasiImplementation;
|
||||
|
||||
fn compile(wasm: &[u8]) -> WasmBackendResult<WasmerModule> {
|
||||
@ -54,13 +77,14 @@ pub struct WasmerInstance {
|
||||
impl Instance<WasmerBackend> for WasmerInstance {
|
||||
fn export_iter<'a>(
|
||||
&'a self,
|
||||
) -> Box<dyn Iterator<Item = (String, wasmer_runtime::Export)> + 'a> {
|
||||
let exports = self.instance.exports();
|
||||
Box::new(exports)
|
||||
) -> Box<dyn Iterator<Item = (String, Export<WasmerMemoryExport, WasmerFunctionExport>)> + 'a>
|
||||
{
|
||||
let export_iter = self.instance.exports();
|
||||
Box::new(export_iter.map(|(name, export)| (name, export_from_wasmer_export(export))))
|
||||
}
|
||||
|
||||
fn exports(&self) -> &wasmer_core::instance::Exports {
|
||||
&self.instance.exports
|
||||
fn exports(&self) -> &Self {
|
||||
self
|
||||
}
|
||||
|
||||
fn import_object(&self) -> &WasmerImportObject {
|
||||
@ -80,15 +104,29 @@ pub struct WasmerImportObject {
|
||||
pub import_object: wasmer_runtime::ImportObject,
|
||||
}
|
||||
|
||||
impl Extend<(String, String, WasmerExport)> for WasmerImportObject {
|
||||
impl
|
||||
Extend<(
|
||||
String,
|
||||
String,
|
||||
Export<WasmerMemoryExport, WasmerFunctionExport>,
|
||||
)> for WasmerImportObject
|
||||
{
|
||||
fn extend<T>(&mut self, iter: T)
|
||||
where
|
||||
T: IntoIterator<Item = (String, String, WasmerExport)>,
|
||||
T: IntoIterator<
|
||||
Item = (
|
||||
String,
|
||||
String,
|
||||
Export<WasmerMemoryExport, WasmerFunctionExport>,
|
||||
),
|
||||
>,
|
||||
{
|
||||
self.import_object.extend(
|
||||
iter.into_iter()
|
||||
.map(|(s1, s2, export)| (s1, s2, export.export)),
|
||||
)
|
||||
self.import_object
|
||||
.extend(iter.into_iter().map(|(s1, s2, export)| match export {
|
||||
Export::Memory(memory) => (s1, s2, memory.into()),
|
||||
Export::Function(func) => (s1, s2, func.into()),
|
||||
_ => unreachable!()
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,20 +153,43 @@ impl ImportObject<WasmerBackend> for WasmerImportObject {
|
||||
self.import_object.register(name, namespace)
|
||||
}
|
||||
|
||||
fn get_memory_env(&self) -> Option<Export<WasmerMemoryExport, WasmerFunctionExport>> {
|
||||
self.import_object
|
||||
.maybe_with_namespace("env", |env| env.get_export("memory"))
|
||||
.map(|export| {
|
||||
match export {
|
||||
wasmer_runtime::Export::Memory(memory) => Export::Memory(WasmerMemoryExport {memory}),
|
||||
_ => Export::Other
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
fn maybe_with_namespace<Func, InnerRet>(&self, namespace: &str, f: Func) -> Option<InnerRet>
|
||||
where
|
||||
Func: FnOnce(&(dyn wasmer_runtime::LikeNamespace + Send)) -> Option<InnerRet>,
|
||||
InnerRet: Sized,
|
||||
{
|
||||
self.import_object.maybe_with_namespace(namespace, f)
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
pub struct WasmerExport {
|
||||
export: wasmer_runtime::Export,
|
||||
pub struct WasmerFunctionExport {
|
||||
func: wasmer_core::export::FuncPointer,
|
||||
/// A kind of context.
|
||||
ctx: wasmer_core::export::Context,
|
||||
/// The signature of the function.
|
||||
signature: Arc<wasmer_runtime::types::FuncSig>,
|
||||
}
|
||||
|
||||
impl Export for WasmerExport {}
|
||||
impl FunctionExport for WasmerFunctionExport {}
|
||||
|
||||
pub struct WasmerMemoryExport {
|
||||
memory: wasmer_runtime::Memory,
|
||||
}
|
||||
|
||||
impl MemoryExport for WasmerMemoryExport {
|
||||
}
|
||||
|
||||
pub struct WasmerWasiImplementation {}
|
||||
|
||||
@ -151,15 +212,65 @@ impl WasiImplementation<WasmerBackend> for WasmerWasiImplementation {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
pub struct WasmerExportIter {
|
||||
export_iter: Box<dyn Iterator<Item = (String, wasmer_runtime::Export)> + 'a>
|
||||
impl Exports<WasmerBackend> for WasmerInstance {
|
||||
fn get<'a, T: wasmer_core::export::Exportable<'a>>(
|
||||
&'a self,
|
||||
name: &str,
|
||||
) -> wasmer_core::error::ResolveResult<T> {
|
||||
self.instance.exports.get(name)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for WasmerExportIter<'a> {
|
||||
type Item = (String, wasmer_runtime::Export);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.export_iter.as_mut().next()
|
||||
fn export_from_wasmer_export(export: wasmer_core::export::Export) -> Export<WasmerMemoryExport, WasmerFunctionExport> {
|
||||
match export {
|
||||
wasmer_core::export::Export::Function {
|
||||
func,
|
||||
ctx,
|
||||
signature,
|
||||
} => Export::Function(WasmerFunctionExport {
|
||||
func,
|
||||
ctx,
|
||||
signature,
|
||||
}),
|
||||
wasmer_core::export::Export::Memory(memory) => {
|
||||
Export::Memory(WasmerMemoryExport{memory})
|
||||
}
|
||||
wasmer_core::export::Export::Table(_table) => {
|
||||
Export::Other
|
||||
}
|
||||
wasmer_core::export::Export::Global(_global) => {
|
||||
Export::Other
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<wasmer_runtime::Export> for WasmerMemoryExport {
|
||||
fn into(self) -> wasmer_core::export::Export {
|
||||
wasmer_runtime::Export::Memory(self.memory)
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<wasmer_runtime::Export> for WasmerFunctionExport {
|
||||
fn into(self) -> wasmer_core::export::Export {
|
||||
wasmer_runtime::Export::Function{
|
||||
func: self.func,
|
||||
ctx: self.ctx,
|
||||
signature: self.signature,
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Memory<WasmerBackend> for WITMemory {
|
||||
fn new(export: WasmerMemoryExport) -> Self {
|
||||
WITMemory(export.memory)
|
||||
}
|
||||
|
||||
fn view_from_ctx(ctx: &Ctx, memory_index: u32) -> WITMemoryView<'static> {
|
||||
let memory = unsafe {
|
||||
std::mem::transmute::<&'_ wasmer_runtime::Memory, &'static wasmer_runtime::Memory>(ctx.memory(memory_index))
|
||||
};
|
||||
|
||||
WITMemoryView(memory.view::<u8>())
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
112
crates/wasmer-backend/src/memory.rs
Normal file
112
crates/wasmer-backend/src/memory.rs
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::ops::Deref;
|
||||
//use wasmer_it::interpreter::wasm;
|
||||
use wasmer_core::memory::{Memory, MemoryView};
|
||||
use wasmer_core::vm::LocalMemory;
|
||||
//use wasmer_it::interpreter::wasm::structures::MemoryAccessError;
|
||||
use it_memory_traits::MemoryAccessError;
|
||||
//use marine_wasm_backend_traits::it_memory_traits;
|
||||
use crate::memory_access::WasmerSequentialReader;
|
||||
|
||||
use crate::memory_access::WasmerSequentialWriter;
|
||||
|
||||
pub struct WITMemoryView<'a>(pub(crate) MemoryView<'a, u8>);
|
||||
|
||||
//pub struct WITMemoryView(pub(crate) Vec<Cell<u8>>);
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct WITMemory(pub(super) Memory);
|
||||
impl std::ops::Deref for WITMemory {
|
||||
type Target = Memory;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl WITMemoryView<'_> {
|
||||
fn check_bounds(
|
||||
&self,
|
||||
offset: usize,
|
||||
size: usize,
|
||||
memory_size: usize,
|
||||
) -> Result<(), MemoryAccessError> {
|
||||
if offset + size >= memory_size {
|
||||
Err(MemoryAccessError::OutOfBounds {
|
||||
offset,
|
||||
size,
|
||||
memory_size,
|
||||
})
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s, 'v> it_memory_traits::SequentialMemoryView<'v> for WITMemoryView<'s> {
|
||||
type SR = WasmerSequentialReader<'v>;
|
||||
type SW = WasmerSequentialWriter<'v>;
|
||||
|
||||
fn sequential_writer(
|
||||
&'v self,
|
||||
offset: usize,
|
||||
size: usize,
|
||||
) -> Result<Self::SW, MemoryAccessError> {
|
||||
let view = &self.0;
|
||||
let slice = view.deref();
|
||||
|
||||
self.check_bounds(offset, size, slice.len())?;
|
||||
|
||||
let writer = WasmerSequentialWriter {
|
||||
offset,
|
||||
slice,
|
||||
current_offset: Cell::new(offset),
|
||||
};
|
||||
|
||||
Ok(writer)
|
||||
}
|
||||
|
||||
fn sequential_reader(
|
||||
&'v self,
|
||||
offset: usize,
|
||||
size: usize,
|
||||
) -> Result<Self::SR, MemoryAccessError> {
|
||||
let view = &self.0;
|
||||
let slice: &[Cell<u8>] = view.deref();
|
||||
|
||||
self.check_bounds(offset, size, slice.len())?;
|
||||
|
||||
let reader = WasmerSequentialReader {
|
||||
memory: slice,
|
||||
offset: Cell::new(offset),
|
||||
};
|
||||
|
||||
Ok(reader)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> /*wasm::structures::Memory*/it_memory_traits::Memory<WITMemoryView<'a>> for WITMemory {
|
||||
fn view(&self) -> WITMemoryView<'a> {
|
||||
let LocalMemory { base, .. } = unsafe { *self.0.vm_local_memory() };
|
||||
let length = self.0.size().bytes().0 / std::mem::size_of::<u8>();
|
||||
|
||||
unsafe { WITMemoryView(MemoryView::new(base as _, length as u32)) }
|
||||
//unsafe { WITMemoryView(vec![]) }
|
||||
}
|
||||
}
|
138
crates/wasmer-backend/src/memory_access.rs
Normal file
138
crates/wasmer-backend/src/memory_access.rs
Normal file
@ -0,0 +1,138 @@
|
||||
use std::cell::Cell;
|
||||
//use wasmer_it::interpreter::wasm::structures::{SequentialReader, SequentialWriter};
|
||||
use it_memory_traits::{SequentialReader, SequentialWriter};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! value_der {
|
||||
($self:expr, $offset:expr, @seq_start $($ids:tt),* @seq_end) => {
|
||||
[$($self.memory[$offset + $ids].get()),+]
|
||||
};
|
||||
|
||||
($self:expr, $offset:expr, 1) => {
|
||||
crate::value_der!($self, $offset, @seq_start 0 @seq_end);
|
||||
};
|
||||
|
||||
($self:expr, $offset:expr, 2) => {
|
||||
crate::value_der!($self, $offset, @seq_start 0, 1 @seq_end);
|
||||
};
|
||||
|
||||
($self:expr, $offset:expr, 4) => {
|
||||
crate::value_der!($self, $offset, @seq_start 0, 1, 2, 3 @seq_end);
|
||||
};
|
||||
|
||||
($self:expr, $offset:expr, 8) => {
|
||||
crate::value_der!($self, $offset, @seq_start 0, 1, 2, 3, 4, 5, 6, 7 @seq_end);
|
||||
};
|
||||
|
||||
($self:expr, $offset:expr, 16) => {
|
||||
crate::value_der!($self, $offset, @seq_start 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 @seq_end);
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! read_ty {
|
||||
($func_name:ident, $ty:ty, 1) => {
|
||||
fn $func_name(&self) -> $ty {
|
||||
let offset = self.offset.get();
|
||||
let result = <$ty>::from_le_bytes(crate::value_der!(self, offset, 1));
|
||||
|
||||
self.offset.set(offset + 1);
|
||||
result
|
||||
}
|
||||
};
|
||||
|
||||
($func_name:ident, $ty:ty, 2) => {
|
||||
fn $func_name(&self) -> $ty {
|
||||
let offset = self.offset.get();
|
||||
let result = <$ty>::from_le_bytes(crate::value_der!(self, offset, 2));
|
||||
|
||||
self.offset.set(offset + 2);
|
||||
result
|
||||
}
|
||||
};
|
||||
|
||||
($func_name:ident, $ty:ty, 4) => {
|
||||
fn $func_name(&self) -> $ty {
|
||||
let offset = self.offset.get();
|
||||
let result = <$ty>::from_le_bytes(crate::value_der!(self, offset, 4));
|
||||
|
||||
self.offset.set(offset + 4);
|
||||
result
|
||||
}
|
||||
};
|
||||
|
||||
($func_name:ident, $ty:ty, 8) => {
|
||||
fn $func_name(&self) -> $ty {
|
||||
let offset = self.offset.get();
|
||||
let result = <$ty>::from_le_bytes(crate::value_der!(self, offset, 8));
|
||||
|
||||
self.offset.set(offset + 8);
|
||||
result
|
||||
}
|
||||
};
|
||||
|
||||
($func_name:ident, $ty:ty, 16) => {
|
||||
fn $func_name(&self) -> $ty {
|
||||
let offset = self.offset.get();
|
||||
let result = <$ty>::from_le_bytes(crate::value_der!(self, offset, 16));
|
||||
|
||||
self.offset.set(offset + 16);
|
||||
result
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub struct WasmerSequentialReader<'s> {
|
||||
pub memory: &'s [Cell<u8>],
|
||||
pub offset: Cell<usize>,
|
||||
}
|
||||
|
||||
pub struct WasmerSequentialWriter<'s> {
|
||||
pub offset: usize,
|
||||
pub slice: &'s [Cell<u8>],
|
||||
pub current_offset: Cell<usize>,
|
||||
}
|
||||
|
||||
impl SequentialReader for WasmerSequentialReader<'_> {
|
||||
fn read_byte(&self) -> u8 {
|
||||
let offset = self.offset.get();
|
||||
let result = self.memory[offset].get();
|
||||
self.offset.set(offset + 1);
|
||||
result
|
||||
}
|
||||
|
||||
// needed because clippy suggests using an iterator which looks worse
|
||||
#[allow(clippy::needless_range_loop)]
|
||||
fn read_bytes<const COUNT: usize>(&self) -> [u8; COUNT] {
|
||||
let offset = self.offset.get();
|
||||
let mut result = [0u8; COUNT];
|
||||
for index in 0..COUNT {
|
||||
result[index] = self.memory[offset + index].get();
|
||||
}
|
||||
|
||||
self.offset.set(offset + COUNT);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl SequentialWriter for WasmerSequentialWriter<'_> {
|
||||
fn start_offset(&self) -> usize {
|
||||
self.offset
|
||||
}
|
||||
|
||||
fn write_u8(&self, value: u8) {
|
||||
let offset = self.current_offset.get();
|
||||
self.slice[offset].set(value);
|
||||
self.current_offset.set(offset + 1);
|
||||
}
|
||||
|
||||
fn write_u32(&self, value: u32) {
|
||||
self.write_bytes(&value.to_le_bytes());
|
||||
}
|
||||
|
||||
fn write_bytes(&self, bytes: &[u8]) {
|
||||
for byte in bytes {
|
||||
self.write_u8(*byte)
|
||||
}
|
||||
}
|
||||
}
|
@ -26,7 +26,7 @@ use crate::MRecordTypes;
|
||||
use crate::init_wasm_func_once;
|
||||
use crate::call_wasm_func;
|
||||
use crate::HostImportDescriptor;
|
||||
use crate::module::wit_prelude::WITMemoryView;
|
||||
//use crate::module::wit_prelude::WITMemoryView;
|
||||
|
||||
use wasmer_core::Func;
|
||||
use wasmer_core::vm::Ctx;
|
||||
@ -39,7 +39,10 @@ use it_lilo::lowerer::ILowerer;
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub(crate) fn create_host_import_func(
|
||||
use marine_wasm_backend_traits::WasmBackend;
|
||||
use marine_wasm_backend_traits::Memory;
|
||||
|
||||
pub(crate) fn create_host_import_func<WB: WasmBackend>(
|
||||
descriptor: HostImportDescriptor,
|
||||
record_types: Rc<MRecordTypes>,
|
||||
) -> DynamicFunc<'static> {
|
||||
@ -65,11 +68,13 @@ pub(crate) fn create_host_import_func(
|
||||
let func = move |ctx: &mut Ctx, inputs: &[WValue]| -> Vec<WValue> {
|
||||
let result = {
|
||||
let memory_index = 0;
|
||||
let memory = ctx.memory(memory_index);
|
||||
let memory_view = WITMemoryView(memory.view::<u8>());
|
||||
//let memory = ctx.memory(memory_index);
|
||||
//let memory_view = WITMemoryView(memory.view::<u8>());
|
||||
let memory_view = <WB as WasmBackend>::WITMemory::view_from_ctx(ctx, memory_index);
|
||||
let li_helper = LiHelper::new(record_types.clone());
|
||||
let lifter = ILifter::new(memory_view, &li_helper);
|
||||
|
||||
|
||||
match wvalues_to_ivalues(&lifter, inputs, &argument_types) {
|
||||
Ok(ivalues) => host_exported_func(ctx, ivalues),
|
||||
Err(e) => {
|
||||
@ -84,8 +89,9 @@ pub(crate) fn create_host_import_func(
|
||||
init_wasm_func_once!(allocate_func, ctx, (i32, i32), i32, ALLOCATE_FUNC_NAME, 2);
|
||||
|
||||
let memory_index = 0;
|
||||
let memory = ctx.memory(memory_index);
|
||||
let memory_view = WITMemoryView(memory.view::<u8>());
|
||||
//let memory = ctx.memory(memory_index);
|
||||
//let memory_view = WITMemoryView(memory.view::<u8>());
|
||||
let memory_view = <WB as WasmBackend>::WITMemory::view_from_ctx(ctx, memory_index);
|
||||
let lo_helper = LoHelper::new(&allocate_func);
|
||||
let t = ILowerer::new(memory_view, &lo_helper)
|
||||
.map_err(HostImportError::LowererError)
|
||||
|
@ -26,6 +26,7 @@ use marine_wasm_backend_traits::Module;
|
||||
use marine_wasm_backend_traits::Instance;
|
||||
use marine_wasm_backend_traits::ImportObject;
|
||||
use marine_wasm_backend_traits::WasiImplementation;
|
||||
use marine_wasm_backend_traits::Exports;
|
||||
|
||||
use marine_it_interfaces::MITInterfaces;
|
||||
use marine_it_parser::extract_it_from_module;
|
||||
@ -43,7 +44,7 @@ use std::sync::Arc;
|
||||
use std::rc::Rc;
|
||||
|
||||
type ITInterpreter<WB> =
|
||||
Interpreter<ITInstance<WB>, ITExport, WITFunction<WB>, WITMemory, WITMemoryView<'static>>;
|
||||
Interpreter<ITInstance<WB>, ITExport, WITFunction<WB>, <WB as WasmBackend>::WITMemory, <WB as WasmBackend>::WITMemoryView>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(super) struct ITModuleFunc<WB: WasmBackend> {
|
||||
@ -251,7 +252,7 @@ impl<WB: WasmBackend> MModule<WB> {
|
||||
let record_types = Rc::new(record_types);
|
||||
|
||||
for (import_name, descriptor) in config.host_imports {
|
||||
let host_import = create_host_import_func(descriptor, record_types.clone());
|
||||
let host_import = create_host_import_func::<WB>(descriptor, record_types.clone());
|
||||
host_closures_namespace.insert(import_name, host_import);
|
||||
}
|
||||
let mut host_closures_import_object = <WB as WasmBackend>::IO::new();
|
||||
@ -323,7 +324,7 @@ impl<WB: WasmBackend> MModule<WB> {
|
||||
}
|
||||
|
||||
// creates a closure that is represent a IT module import
|
||||
fn create_raw_import<WB: WasmBackend + 'static>(
|
||||
fn create_raw_import<WB: WasmBackend>(
|
||||
wit_instance: Arc<MaybeUninit<ITInstance<WB>>>,
|
||||
interpreter: ITInterpreter<WB>,
|
||||
import_namespace: String,
|
||||
|
@ -16,8 +16,8 @@
|
||||
|
||||
mod exports;
|
||||
mod marine_module;
|
||||
mod memory;
|
||||
mod memory_access;
|
||||
//mod memory;
|
||||
//mod memory_access;
|
||||
mod wit_function;
|
||||
mod wit_instance;
|
||||
mod type_converters;
|
||||
@ -30,8 +30,8 @@ pub use wasmer_it::IValue;
|
||||
pub use wasmer_it::from_interface_values;
|
||||
pub use wasmer_it::to_interface_value;
|
||||
|
||||
pub(crate) use memory_access::WasmerSequentialWriter;
|
||||
pub(crate) use memory_access::WasmerSequentialReader;
|
||||
//pub(crate) use memory_access::WasmerSequentialWriter;
|
||||
//pub(crate) use memory_access::WasmerSequentialReader;
|
||||
|
||||
use serde::Serialize;
|
||||
use serde::Deserialize;
|
||||
@ -56,6 +56,6 @@ pub(crate) mod wit_prelude {
|
||||
pub(super) use crate::MError;
|
||||
pub(super) use super::wit_function::WITFunction;
|
||||
|
||||
pub(crate) use super::memory::WITMemoryView;
|
||||
pub(crate) use super::memory::WITMemory;
|
||||
//pub(crate) use super::memory::WITMemoryView;
|
||||
//pub(crate) use super::memory::WITMemory;
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ use marine_wasm_backend_traits::WasmBackend;
|
||||
//use marine_wasm_backend_traits::Module;
|
||||
use marine_wasm_backend_traits::Instance;
|
||||
use marine_wasm_backend_traits::ImportObject;
|
||||
use marine_wasm_backend_traits::Exports;
|
||||
use marine_wasm_backend_traits::Memory as WBMemory;
|
||||
|
||||
use marine_it_interfaces::MITInterfaces;
|
||||
use marine_it_interfaces::ITAstType;
|
||||
@ -43,7 +45,7 @@ pub(super) struct ITInstance<WB: WasmBackend> {
|
||||
funcs: HashMap<usize, WITFunction<WB>>,
|
||||
|
||||
/// IT memories.
|
||||
memories: Vec<WITMemory>,
|
||||
memories: Vec<<WB as WasmBackend>::WITMemory>,
|
||||
|
||||
/// All record types that instance contains.
|
||||
record_types_by_id: MRecordTypes,
|
||||
@ -142,22 +144,22 @@ impl<WB: WasmBackend> ITInstance<WB> {
|
||||
.collect::<MResult<HashMap<_, _>>>()
|
||||
}
|
||||
|
||||
fn extract_memories(wasmer_instance: &<WB as WasmBackend>::I) -> Vec<WITMemory> {
|
||||
use wasmer_core::export::Export::Memory;
|
||||
fn extract_memories(wasmer_instance: &<WB as WasmBackend>::I) -> Vec<<WB as WasmBackend>::WITMemory> {
|
||||
use marine_wasm_backend_traits::Export::Memory;
|
||||
|
||||
let mut memories = wasmer_instance
|
||||
.export_iter()
|
||||
.filter_map(|(_, export)| match export {
|
||||
Memory(memory) => Some(WITMemory(memory)),
|
||||
Memory(memory) => Some(<WB as WasmBackend>::WITMemory::new(memory)),
|
||||
_ => None,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if let Some(Memory(memory)) = wasmer_instance
|
||||
.import_object()
|
||||
.maybe_with_namespace("env", |env| env.get_export("memory"))
|
||||
.import_object().get_memory_env()
|
||||
//.maybe_with_namespace("env", |env| env.get_export("memory"))
|
||||
{
|
||||
memories.push(WITMemory(memory));
|
||||
memories.push(<WB as WasmBackend>::WITMemory::new(memory));
|
||||
}
|
||||
|
||||
memories
|
||||
@ -182,7 +184,7 @@ impl<WB: WasmBackend> ITInstance<WB> {
|
||||
}
|
||||
|
||||
impl<'v, WB: WasmBackend>
|
||||
wasm::structures::Instance<ITExport, WITFunction<WB>, WITMemory, WITMemoryView<'v>>
|
||||
wasm::structures::Instance<ITExport, WITFunction<WB>, <WB as WasmBackend>::WITMemory, <WB as WasmBackend>::WITMemoryView>
|
||||
for ITInstance<WB>
|
||||
{
|
||||
fn export(&self, _export_name: &str) -> Option<&ITExport> {
|
||||
@ -197,7 +199,7 @@ impl<'v, WB: WasmBackend>
|
||||
self.funcs.get(&index.index())
|
||||
}
|
||||
|
||||
fn memory(&self, index: usize) -> Option<&WITMemory> {
|
||||
fn memory(&self, index: usize) -> Option<&<WB as WasmBackend>::WITMemory> {
|
||||
if index >= self.memories.len() {
|
||||
None
|
||||
} else {
|
||||
@ -205,13 +207,13 @@ impl<'v, WB: WasmBackend>
|
||||
}
|
||||
}
|
||||
|
||||
fn memory_view(&self, index: usize) -> Option<WITMemoryView<'static>> {
|
||||
fn memory_view(&self, index: usize) -> Option<<WB as WasmBackend>::WITMemoryView> {
|
||||
if index >= self.memories.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let memory = &self.memories[index];
|
||||
let view: WITMemoryView<'static> = memory.view();
|
||||
let view: <WB as WasmBackend>::WITMemoryView = memory.view();
|
||||
Some(view)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user