mirror of
https://github.com/fluencelabs/interface-types
synced 2024-12-03 14:50:21 +00:00
add dup and swap2 instructions
This commit is contained in:
parent
c2f2a23c38
commit
52c28b80bc
4
.gitignore
vendored
4
.gitignore
vendored
@ -1 +1,3 @@
|
||||
/target
|
||||
.idea
|
||||
/target
|
||||
|
||||
|
@ -256,6 +256,10 @@ fn instruction<'input, E: ParseError<&'input [u8]>>(
|
||||
)
|
||||
}
|
||||
|
||||
0x34 => (input, Instruction::Dup),
|
||||
|
||||
0x35 => (input, Instruction::Swap2),
|
||||
|
||||
_ => return Err(Err::Error(make_error(input, ErrorKind::ParseTo))),
|
||||
})
|
||||
}
|
||||
|
@ -67,6 +67,8 @@ mod keyword {
|
||||
custom_keyword!(string_size = "string.size");
|
||||
custom_keyword!(record_lift = "record.lift");
|
||||
custom_keyword!(record_lower = "record.lower");
|
||||
custom_keyword!(dup = "dup");
|
||||
custom_keyword!(swap2 = "swap2");
|
||||
}
|
||||
|
||||
impl Parse<'_> for InterfaceType {
|
||||
@ -326,6 +328,14 @@ impl<'a> Parse<'a> for Instruction {
|
||||
Ok(Instruction::RecordLower {
|
||||
type_index: parser.parse()?,
|
||||
})
|
||||
} else if lookahead.peek::<keyword::dup>() {
|
||||
parser.parse::<keyword::dup>()?;
|
||||
|
||||
Ok(Instruction::Dup)
|
||||
} else if lookahead.peek::<keyword::swap2>() {
|
||||
parser.parse::<keyword::swap2>()?;
|
||||
|
||||
Ok(Instruction::Swap2)
|
||||
} else {
|
||||
Err(lookahead.error())
|
||||
}
|
||||
|
@ -342,6 +342,8 @@ where
|
||||
0x26_u8.to_bytes(writer)?;
|
||||
(*type_index as u64).to_bytes(writer)?
|
||||
}
|
||||
Instruction::Dup => 0x34_u8.to_bytes(writer)?,
|
||||
Instruction::Swap2 => 0x35_u8.to_bytes(writer)?,
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -140,6 +140,8 @@ impl ToString for &Instruction {
|
||||
Instruction::StringSize => "string.size".into(),
|
||||
Instruction::RecordLift { type_index } => format!("record.lift {}", type_index),
|
||||
Instruction::RecordLower { type_index } => format!("record.lower {}", type_index),
|
||||
Instruction::Dup => "dup".into(),
|
||||
Instruction::Swap2 => "swap2".into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,6 +54,8 @@ executable_instruction!(
|
||||
)
|
||||
})?;
|
||||
|
||||
|
||||
|
||||
for output in outputs.into_iter() {
|
||||
runtime.stack.push(output)
|
||||
}
|
||||
|
22
src/interpreter/instructions/dup.rs
Normal file
22
src/interpreter/instructions/dup.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use crate::{
|
||||
errors::{InstructionError, InstructionErrorKind},
|
||||
interpreter::Instruction,
|
||||
};
|
||||
|
||||
executable_instruction!(
|
||||
dup(instruction: Instruction) -> _ {
|
||||
move |runtime| -> _ {
|
||||
let value = runtime.stack.peek1().ok_or_else(|| {
|
||||
InstructionError::new(
|
||||
instruction,
|
||||
InstructionErrorKind::StackIsTooSmall { needed: 1 },
|
||||
)
|
||||
})?;
|
||||
|
||||
let value = value.clone();
|
||||
runtime.stack.push(value);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
);
|
@ -3,6 +3,8 @@ mod call_core;
|
||||
mod numbers;
|
||||
mod records;
|
||||
mod strings;
|
||||
mod dup;
|
||||
mod swap2;
|
||||
|
||||
use crate::{
|
||||
errors::{InstructionError, InstructionErrorKind, InstructionResult, WasmValueNativeCastError},
|
||||
@ -14,6 +16,8 @@ pub(crate) use numbers::*;
|
||||
pub(crate) use records::*;
|
||||
use std::convert::TryFrom;
|
||||
pub(crate) use strings::*;
|
||||
pub(crate) use dup::dup;
|
||||
pub(crate) use swap2::swap2;
|
||||
|
||||
/// Represents all the possible WIT instructions.
|
||||
#[derive(PartialEq, Debug, Clone, Copy)]
|
||||
@ -146,6 +150,12 @@ pub enum Instruction {
|
||||
/// The type index of the record.
|
||||
type_index: u32,
|
||||
},
|
||||
|
||||
/// The `dup` instructions.
|
||||
Dup,
|
||||
|
||||
/// The `swap` instructions.
|
||||
Swap2,
|
||||
}
|
||||
|
||||
/// Just a short helper to map the error of a cast from an
|
||||
|
22
src/interpreter/instructions/swap2.rs
Normal file
22
src/interpreter/instructions/swap2.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use crate::{
|
||||
errors::{InstructionError, InstructionErrorKind},
|
||||
interpreter::Instruction,
|
||||
};
|
||||
|
||||
executable_instruction!(
|
||||
swap2(instruction: Instruction) -> _ {
|
||||
move |runtime| -> _ {
|
||||
let mut values = runtime.stack.pop(2).ok_or_else(|| {
|
||||
InstructionError::new(
|
||||
instruction,
|
||||
InstructionErrorKind::StackIsTooSmall { needed: 1 },
|
||||
)
|
||||
})?;
|
||||
|
||||
runtime.stack.push(values.remove(1));
|
||||
runtime.stack.push(values.remove(0));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
);
|
@ -162,6 +162,7 @@ where
|
||||
invocation_inputs: &[InterfaceValue],
|
||||
wasm_instance: &mut Instance,
|
||||
) -> InterpreterResult<Stack<InterfaceValue>> {
|
||||
println!("into interpreter run");
|
||||
let mut runtime = Runtime {
|
||||
invocation_inputs,
|
||||
stack: Stack::new(),
|
||||
@ -243,7 +244,9 @@ where
|
||||
}
|
||||
Instruction::RecordLower { type_index } => {
|
||||
instructions::record_lower(*type_index, *instruction)
|
||||
}
|
||||
},
|
||||
Instruction::Dup => instructions::dup(*instruction),
|
||||
Instruction::Swap2 => instructions::swap2(*instruction),
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user