mirror of
https://github.com/fluencelabs/wasmer
synced 2025-03-18 17:10:52 +00:00
feat(interface-types) The interpreter stack contains Wasm values.
This commit is contained in:
parent
2237e628ab
commit
b7b37d2e99
@ -1,26 +1,24 @@
|
||||
use crate::instructions::{
|
||||
stack::{Stack, Stackable},
|
||||
wasm, Instruction,
|
||||
wasm::{self, Value},
|
||||
Instruction,
|
||||
};
|
||||
use std::{
|
||||
convert::{TryFrom, TryInto},
|
||||
marker::PhantomData,
|
||||
};
|
||||
|
||||
type ExecutableInstruction<Instance, Export> =
|
||||
Box<dyn Fn(&mut Runtime<Instance, Export>) -> Result<(), String>>;
|
||||
use std::{convert::TryFrom, marker::PhantomData};
|
||||
|
||||
struct Runtime<'invocation, 'instance, Instance, Export>
|
||||
where
|
||||
Export: wasm::Export + 'instance,
|
||||
Instance: wasm::Instance<Export> + 'instance,
|
||||
{
|
||||
invocation_inputs: &'invocation [u64],
|
||||
stack: Stack<u64>,
|
||||
invocation_inputs: &'invocation [Value],
|
||||
stack: Stack<Value>,
|
||||
wasm_instance: &'instance Instance,
|
||||
wasm_exports: PhantomData<Export>,
|
||||
}
|
||||
|
||||
type ExecutableInstruction<Instance, Export> =
|
||||
Box<dyn Fn(&mut Runtime<Instance, Export>) -> Result<(), String>>;
|
||||
|
||||
pub struct Interpreter<Instance, Export>
|
||||
where
|
||||
Export: wasm::Export,
|
||||
@ -40,9 +38,9 @@ where
|
||||
|
||||
pub fn run(
|
||||
&self,
|
||||
invocation_inputs: &[u64],
|
||||
invocation_inputs: &[Value],
|
||||
wasm_instance: &Instance,
|
||||
) -> Result<Stack<u64>, String> {
|
||||
) -> Result<Stack<Value>, String> {
|
||||
let mut runtime = Runtime {
|
||||
invocation_inputs,
|
||||
stack: Stack::new(),
|
||||
@ -107,14 +105,10 @@ where
|
||||
|
||||
match runtime.stack.pop(inputs_cardinality) {
|
||||
Some(inputs) => {
|
||||
let inputs: Vec<wasm::Value> = inputs.iter().map(|i| wasm::Value::I32(*i as i32)).collect();
|
||||
|
||||
match export.call(&inputs) {
|
||||
Ok(outputs) => {
|
||||
for output in outputs.iter() {
|
||||
let output: i32 = output.try_into().unwrap();
|
||||
|
||||
runtime.stack.push(output as u64);
|
||||
runtime.stack.push(*output);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -129,8 +123,7 @@ where
|
||||
inputs_cardinality,
|
||||
))
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
None => Err(format!(
|
||||
"`{}` cannot call the exported function `{}` because it doesn't exist.",
|
||||
instruction_name,
|
||||
@ -170,13 +163,17 @@ where
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Interpreter;
|
||||
use crate::instructions::{stack::Stackable, wasm, Instruction};
|
||||
use crate::instructions::{
|
||||
stack::Stackable,
|
||||
wasm::{self, Type, Value},
|
||||
Instruction,
|
||||
};
|
||||
use std::{collections::HashMap, convert::TryInto};
|
||||
|
||||
struct Export {
|
||||
inputs: Vec<wasm::Type>,
|
||||
outputs: Vec<wasm::Type>,
|
||||
function: fn(arguments: &[wasm::Value]) -> Result<Vec<wasm::Value>, ()>,
|
||||
inputs: Vec<Type>,
|
||||
outputs: Vec<Type>,
|
||||
function: fn(arguments: &[Value]) -> Result<Vec<Value>, ()>,
|
||||
}
|
||||
|
||||
impl wasm::Export for Export {
|
||||
@ -188,15 +185,15 @@ mod tests {
|
||||
self.outputs.len()
|
||||
}
|
||||
|
||||
fn inputs(&self) -> &[wasm::Type] {
|
||||
fn inputs(&self) -> &[Type] {
|
||||
&self.inputs
|
||||
}
|
||||
|
||||
fn outputs(&self) -> &[wasm::Type] {
|
||||
fn outputs(&self) -> &[Type] {
|
||||
&self.outputs
|
||||
}
|
||||
|
||||
fn call(&self, arguments: &[wasm::Value]) -> Result<Vec<wasm::Value>, ()> {
|
||||
fn call(&self, arguments: &[Value]) -> Result<Vec<Value>, ()> {
|
||||
(self.function)(arguments)
|
||||
}
|
||||
}
|
||||
@ -213,13 +210,13 @@ mod tests {
|
||||
hashmap.insert(
|
||||
"sum".into(),
|
||||
Export {
|
||||
inputs: vec![wasm::Type::I32, wasm::Type::I32],
|
||||
outputs: vec![wasm::Type::I32],
|
||||
function: |arguments: &[wasm::Value]| {
|
||||
inputs: vec![Type::I32, Type::I32],
|
||||
outputs: vec![Type::I32],
|
||||
function: |arguments: &[Value]| {
|
||||
let a: i32 = (&arguments[0]).try_into().unwrap();
|
||||
let b: i32 = (&arguments[1]).try_into().unwrap();
|
||||
|
||||
Ok(vec![wasm::Value::I32(a + b)])
|
||||
Ok(vec![Value::I32(a + b)])
|
||||
},
|
||||
},
|
||||
);
|
||||
@ -255,7 +252,7 @@ mod tests {
|
||||
let interpreter: Interpreter<Instance, Export> =
|
||||
(&vec![Instruction::ArgumentGet(0)]).try_into().unwrap();
|
||||
|
||||
let invocation_inputs = vec![42];
|
||||
let invocation_inputs = vec![Value::I32(42)];
|
||||
let instance = Instance::new();
|
||||
let run = interpreter.run(&invocation_inputs, &instance);
|
||||
|
||||
@ -263,7 +260,7 @@ mod tests {
|
||||
|
||||
let stack = run.unwrap();
|
||||
|
||||
assert_eq!(stack.as_slice(), &[42]);
|
||||
assert_eq!(stack.as_slice(), &[Value::I32(42)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -271,7 +268,7 @@ mod tests {
|
||||
let interpreter: Interpreter<Instance, Export> =
|
||||
(&vec![Instruction::ArgumentGet(1)]).try_into().unwrap();
|
||||
|
||||
let invocation_inputs = vec![42];
|
||||
let invocation_inputs = vec![Value::I32(42)];
|
||||
let instance = Instance::new();
|
||||
let run = interpreter.run(&invocation_inputs, &instance);
|
||||
|
||||
@ -292,7 +289,7 @@ mod tests {
|
||||
.try_into()
|
||||
.unwrap();
|
||||
|
||||
let invocation_inputs = vec![7, 42];
|
||||
let invocation_inputs = vec![Value::I32(7), Value::I32(42)];
|
||||
let instance = Instance::new();
|
||||
let run = interpreter.run(&invocation_inputs, &instance);
|
||||
|
||||
@ -300,7 +297,7 @@ mod tests {
|
||||
|
||||
let stack = run.unwrap();
|
||||
|
||||
assert_eq!(stack.as_slice(), &[7, 42]);
|
||||
assert_eq!(stack.as_slice(), &[Value::I32(7), Value::I32(42)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -313,7 +310,7 @@ mod tests {
|
||||
.try_into()
|
||||
.unwrap();
|
||||
|
||||
let invocation_inputs = vec![3, 4];
|
||||
let invocation_inputs = vec![Value::I32(3), Value::I32(4)];
|
||||
let instance = Instance::new();
|
||||
let run = interpreter.run(&invocation_inputs, &instance);
|
||||
|
||||
@ -321,7 +318,7 @@ mod tests {
|
||||
|
||||
let stack = run.unwrap();
|
||||
|
||||
assert_eq!(stack.as_slice(), &[7]);
|
||||
assert_eq!(stack.as_slice(), &[Value::I32(7)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -8,7 +8,7 @@ pub enum Type {
|
||||
V128,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum Value {
|
||||
I32(i32),
|
||||
I64(i64),
|
||||
@ -17,6 +17,12 @@ pub enum Value {
|
||||
V128(u128),
|
||||
}
|
||||
|
||||
impl Default for Value {
|
||||
fn default() -> Self {
|
||||
Self::I32(0)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! from_x_for_value {
|
||||
($native_type:ty, $value_variant:ident) => {
|
||||
impl From<$native_type> for Value {
|
||||
|
Loading…
x
Reference in New Issue
Block a user