Skip to content

Commit

Permalink
Update wasmi requirement from 0.10 to 0.14 (#5)
Browse files Browse the repository at this point in the history
* Update wasmi requirement from 0.10 to 0.14

Updates the requirements on [wasmi](https://github.com/paritytech/wasmi) to permit the latest version.
- [Release notes](https://github.com/paritytech/wasmi/releases)
- [Changelog](https://github.com/paritytech/wasmi/blob/master/CHANGELOG.md)
- [Commits](wasmi-labs/wasmi@v0.10.0...v0.14.0)

---
updated-dependencies:
- dependency-name: wasmi
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* Fix compiler errors

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jeron Aldaron Lau <aldaronlau@gmail.com>
  • Loading branch information
dependabot[bot] and AldaronLau committed Aug 13, 2022
1 parent 7da6ce7 commit 9907bba
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 104 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ homepage = "https://ardaku.org"
repository = "https://github.com/ardaku/ardaku"

[dependencies.wasmi]
version = "0.10"
version = "0.14"
default-features = false
154 changes: 51 additions & 103 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
#![no_std]

use wasmi::{
FuncInstance, FuncRef, ImportsBuilder, Module, ModuleImportResolver,
ModuleInstance, Signature, Trap, ValueType, Externals, RuntimeArgs, RuntimeValue, ExternVal, MemoryRef
};
use core::num::NonZeroU32;
use core::mem::MaybeUninit;
use wasmi::core::Trap;
use wasmi::{Caller, Extern, Func, Linker, Memory, Module, Store};

/// An Ardaku event.
#[repr(u32)]
Expand Down Expand Up @@ -43,116 +41,66 @@ pub enum Error {
Crash(Trap),
/// Application does not export "ardaku" memory.
MissingMemory,
/// "start" function not exported
MissingStart,
}

struct State<S: System> {
memory: MaybeUninit<Memory>,
system: S,
memory: MemoryRef,
service_log: Option<NonZeroU32>,
}

impl<S: System> Externals for State<S> {
fn invoke_index(
&mut self,
_index: usize, // Always 0
args: RuntimeArgs,
) -> core::result::Result<Option<RuntimeValue>, Trap> {
let size: u32 = args.nth(0);
let data: u32 = args.nth(1);
let _done: u32 = args.nth(2); // No async events yet
/// Asynchronous Request
fn ar<S>(mut caller: Caller<'_, State<S>>, size: u32, data: u32) -> u32
where
S: System + 'static,
{
let state = caller.host_data_mut();
let memory = unsafe { state.memory.assume_init_mut() };

// FIXME: Needs some refactoring
self.memory.with_direct_access_mut(|memory: &mut [u8]| {
for i in 0..size {
let ptr: usize = (data + i * 16).try_into().unwrap();

// WASM is little-endian
let channel_id = u32::from_le_bytes(
memory[ptr..][..4].try_into().unwrap()
);
let channel_id_new = u32::from_le_bytes(
memory[ptr+4..][..4].try_into().unwrap()
);
let message_size: usize = u32::from_le_bytes(
memory[ptr+8..][..4].try_into().unwrap()
).try_into().unwrap();
let message_data_ptr: usize = u32::from_le_bytes(
memory[ptr+12..][..4].try_into().unwrap()
).try_into().unwrap();

let message = &memory[message_data_ptr..][..message_size];

// Check for special case; channel_id == 0
if channel_id == 0 {
match message {
b"log" => self.service_log = NonZeroU32::new(channel_id_new),
_ => { /* ignore unknown services */ },
}
} else if let Some(log) = self.service_log {
if log.get() == channel_id {
self.system.write(message);
if channel_id_new != channel_id {
self.service_log = NonZeroU32::new(channel_id_new);
}
}
}
}
});

// Currently there are no async events to return.
let ready: u32 = 0;
Ok(Some(ready.into()))
}
}

struct ArdakuResolver;

impl ModuleImportResolver for ArdakuResolver {
fn resolve_func(
&self,
field_name: &str,
_signature: &Signature,
) -> core::result::Result<FuncRef, wasmi::Error> {
let func_ref = match field_name {
"event" => FuncInstance::alloc_host(
Signature::new(
&[ValueType::I32, ValueType::I32, ValueType::I32][..],
Some(ValueType::I32),
),
0, // index 0
),
_ => {
return Err(wasmi::Error::Trap(wasmi::Trap::new(
wasmi::TrapKind::UnexpectedSignature,
)));
}
};
Ok(func_ref)
}
todo!("{:?}", (size, data));
}

/// Start an Ardaku application. `exe` must be a .wasm file.
pub fn start<S: System>(system: S, exe: &[u8]) -> Result<()> {
let resolver = ArdakuResolver;
let module = Module::from_buffer(&exe).map_err(|_| Error::InvalidWasm)?;
let imports = ImportsBuilder::default().with_resolver("ardaku", &resolver);

let instance = ModuleInstance::new(&module, &imports)
pub fn start<S>(system: S, exe: &[u8]) -> Result<()>
where
S: System + 'static,
{
let engine = wasmi::Engine::default();
let module = Module::new(&engine, exe).map_err(|_| Error::InvalidWasm)?;
let mut store = Store::new(
&engine,
State {
system,
memory: MaybeUninit::uninit(),
},
);
let async_request = Func::wrap(&mut store, ar);
let mut linker = <Linker<State<S>>>::new();
linker
.define("daku", "ar", async_request)
.map_err(|_| Error::LinkerFailed)?;

let memory = match instance
.not_started_instance()
.export_by_name("ardaku")
let instance = linker
.instantiate(&mut store, &module)
.map_err(|_| Error::InvalidWasm)?
.ensure_no_start(&mut store)
.map_err(|_| Error::InvalidWasm)?;
let memory = instance
.get_export(&mut store, "memory")
.ok_or(Error::MissingMemory)?
{
ExternVal::Memory(mem) => mem,
_ => return Err(Error::MissingMemory),
};

let mut state = State { system, service_log: None, memory };

instance.run_start(&mut state)
.map_err(|t| Error::Crash(t))?;
.into_memory()
.ok_or(Error::MissingMemory)?;
store.state_mut().memory = MaybeUninit::new(memory);

let start = instance
.get_export(&store, "start")
.and_then(Extern::into_func)
.ok_or(Error::MissingStart)?
.typed::<(), (), _>(&mut store)
.map_err(|_| Error::MissingStart)?;

// And finally we can call the wasm!
start.call(&mut store, ()).map_err(Error::Crash)?;

Ok(())
}

0 comments on commit 9907bba

Please sign in to comment.