get rid of duplicate BlockFrame

This commit is contained in:
Svyatoslav Nikolsky
2017-06-23 09:20:58 +03:00
parent a8852a9791
commit 673392cad4
2 changed files with 41 additions and 66 deletions

View File

@ -13,6 +13,7 @@ use interpreter::value::{
RuntimeValue, TryInto, WrapInto, TryTruncateInto, ExtendInto,
ArithmeticOps, Integer, Float, LittleEndianConvert, TransmuteInto,
};
use interpreter::validator::{BlockFrame, BlockFrameType};
use interpreter::variable::VariableInstance;
/// Index of default linear memory.
@ -66,38 +67,6 @@ pub enum InstructionOutcome<'a> {
Return,
}
/// Control stack frame.
#[derive(Debug, Clone)]
pub struct BlockFrame {
/// Frame type.
frame_type: BlockFrameType,
/// A label for reference to block instruction.
begin_position: usize,
/// A label for reference from branch instructions.
branch_position: usize,
/// A label for reference from end instructions.
end_position: usize,
/// A limit integer value, which is an index into the value stack indicating where to reset it to on a branch to that label.
value_limit: usize,
/// A signature, which is a block signature type indicating the number and types of result values of the region.
signature: BlockType,
}
/// Type of block frame.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum BlockFrameType {
/// Function frame.
Function,
/// Usual block frame.
Block,
/// Loop frame (branching to the beginning of block).
Loop,
/// True-subblock of if expression.
IfTrue,
/// False-subblock of if expression.
IfFalse,
}
/// Function run result.
enum RunResult<'a> {
/// Function has returned (optional) value.
@ -1095,7 +1064,7 @@ impl<'a> FunctionContext<'a> {
&mut self.frame_stack
}
pub fn push_frame(&mut self, frame_type: BlockFrameType, signature: BlockType) -> Result<(), Error> {
pub fn push_frame(&mut self, frame_type: BlockFrameType, block_type: BlockType) -> Result<(), Error> {
let begin_position = self.position;
let branch_position = match frame_type {
BlockFrameType::Function => usize::MAX,
@ -1115,11 +1084,11 @@ impl<'a> FunctionContext<'a> {
};
self.frame_stack.push(BlockFrame {
frame_type: frame_type,
block_type: block_type,
begin_position: begin_position,
branch_position: branch_position,
end_position: end_position,
value_limit: self.value_stack.len(),
signature: signature,
value_stack_len: self.value_stack.len(),
})
}
@ -1130,15 +1099,15 @@ impl<'a> FunctionContext<'a> {
pub fn pop_frame(&mut self, is_branch: bool) -> Result<(), Error> {
let frame = self.frame_stack.pop()?;
if frame.value_limit > self.value_stack.len() {
if frame.value_stack_len > self.value_stack.len() {
return Err(Error::Stack("invalid stack len".into()));
}
let frame_value = match frame.signature {
let frame_value = match frame.block_type {
BlockType::Value(_) if frame.frame_type != BlockFrameType::Loop || !is_branch => Some(self.value_stack.pop()?),
_ => None,
};
self.value_stack.resize(frame.value_limit, RuntimeValue::I32(0));
self.value_stack.resize(frame.value_stack_len, RuntimeValue::I32(0));
self.position = if is_branch { frame.branch_position } else { frame.end_position };
if let Some(frame_value) = frame_value {
self.value_stack.push(frame_value)?;

View File

@ -8,8 +8,6 @@ use interpreter::module::ItemIndex;
use interpreter::stack::StackWithLimit;
use interpreter::variable::VariableType;
use interpreter::runner::BlockFrameType;
/// Constant from wabt' validator.cc to skip alignment validation (not a part of spec).
const NATURAL_ALIGNMENT: u32 = 0xFFFFFFFF;
@ -19,14 +17,14 @@ pub struct FunctionValidationContext<'a> {
module: &'a Module,
/// Module imports.
imports: &'a ModuleImports,
/// Position.
/// Current instruction position.
position: usize,
/// Local variables.
locals: &'a [ValueType],
/// Value stack.
value_stack: StackWithLimit<StackValueType>,
/// Frame stack.
frame_stack: StackWithLimit<ValidationFrame>,
frame_stack: StackWithLimit<BlockFrame>,
/// Function return type. None if validating expression.
return_type: Option<BlockType>,
/// Labels positions.
@ -44,17 +42,36 @@ pub enum StackValueType {
Specific(ValueType),
}
/// Function validation frame.
/// Control stack frame.
#[derive(Debug, Clone)]
pub struct ValidationFrame {
/// Frame type
pub struct BlockFrame {
/// Frame type.
pub frame_type: BlockFrameType,
/// Return type.
/// A signature, which is a block signature type indicating the number and types of result values of the region.
pub block_type: BlockType,
/// Value stack len.
/// A label for reference to block instruction.
pub begin_position: usize,
/// A label for reference from branch instructions.
pub branch_position: usize,
/// A label for reference from end instructions.
pub end_position: usize,
/// A limit integer value, which is an index into the value stack indicating where to reset it to on a branch to that label.
pub value_stack_len: usize,
/// Frame instruction position.
pub position: usize,
}
/// Type of block frame.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum BlockFrameType {
/// Function frame.
Function,
/// Usual block frame.
Block,
/// Loop frame (branching to the beginning of block).
Loop,
/// True-subblock of if expression.
IfTrue,
/// False-subblock of if expression.
IfFalse,
}
/// Function validator.
@ -103,19 +120,6 @@ impl Validator {
//body = new_body;
//position = 0;
},
/*InstructionOutcome::ValidateBlock2(is_loop, block_type, new_body, new_body2) => {
let need_pop_value = match block_type {
BlockType::NoResult => false,
BlockType::Value(_) => true,
};
context.push_label(is_loop, block_type)?;
context.push_label(is_loop, block_type)?;
block_stack.push_back((body, position + 1, false));
block_stack.push_back((new_body2, 0, need_pop_value));
body = new_body;
position = 0;
},*/
}
}
}
@ -643,11 +647,13 @@ impl<'a> FunctionValidationContext<'a> {
}
pub fn push_label(&mut self, frame_type: BlockFrameType, block_type: BlockType) -> Result<(), Error> {
self.frame_stack.push(ValidationFrame {
self.frame_stack.push(BlockFrame {
frame_type: frame_type,
block_type: block_type,
begin_position: self.position,
branch_position: self.position,
end_position: self.position,
value_stack_len: self.value_stack.len(),
position: self.position,
})
}
@ -672,7 +678,7 @@ impl<'a> FunctionValidationContext<'a> {
_ => return Err(Error::Validation(format!("Expected block to return {:?} while it has returned {:?}", frame.block_type, actual_value_type))),
}
if !self.frame_stack.is_empty() {
self.labels.insert(frame.position, self.position);
self.labels.insert(frame.begin_position, self.position);
}
if is_else {
self.push_label(BlockFrameType::IfFalse, frame.block_type)?;
@ -683,7 +689,7 @@ impl<'a> FunctionValidationContext<'a> {
Ok(InstructionOutcome::ValidateNextInstruction)
}
pub fn require_label(&self, idx: u32) -> Result<&ValidationFrame, Error> {
pub fn require_label(&self, idx: u32) -> Result<&BlockFrame, Error> {
self.frame_stack.get(idx as usize)
}