Introduce StartedWith

This commit is contained in:
Sergey Pepyakin 2019-04-05 13:38:12 +02:00
parent 0994150ba2
commit 5c183c4da0
1 changed files with 28 additions and 0 deletions

View File

@ -19,6 +19,8 @@ const DEFAULT_FRAME_STACK_LIMIT: usize = 16384;
/// Control stack frame. /// Control stack frame.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct BlockFrame { struct BlockFrame {
/// The opcode that started this block frame.
started_with: StartedWith,
/// Frame type. /// Frame type.
frame_type: BlockFrameType, frame_type: BlockFrameType,
/// A signature, which is a block signature type indicating the number and types of result /// A signature, which is a block signature type indicating the number and types of result
@ -35,6 +37,17 @@ struct BlockFrame {
polymorphic_stack: bool, polymorphic_stack: bool,
} }
/// An opcode that opened the particular frame.
///
/// We need that to ensure proper combinations with `End` instruction.
#[derive(Debug, Clone)]
enum StartedWith {
Block,
If,
Else,
Loop,
}
/// Type of block frame. /// Type of block frame.
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
enum BlockFrameType { enum BlockFrameType {
@ -172,6 +185,7 @@ impl FunctionReader {
let end_label = context.sink.new_label(); let end_label = context.sink.new_label();
push_label( push_label(
StartedWith::Block,
BlockFrameType::Block { end_label }, BlockFrameType::Block { end_label },
result_ty, result_ty,
context.position, context.position,
@ -610,6 +624,14 @@ impl Validator {
} }
} }
// # Refactoring plan
//
// So the main goal is to extract compilation logic out of validation. There are some complications
// though. For example, compilation logic is intertwined with the validation and shares the same data.
//
// ## Make BlockFrame independendt of labels.
// ## Remove sink from `FunctionValidationContext`
/// Function validation context. /// Function validation context.
struct FunctionValidationContext<'a> { struct FunctionValidationContext<'a> {
/// Wasm module /// Wasm module
@ -671,6 +693,7 @@ impl<'a> FunctionValidationContext<'a> {
Block(block_type) => { Block(block_type) => {
let end_label = self.sink.new_label(); let end_label = self.sink.new_label();
push_label( push_label(
StartedWith::Block,
BlockFrameType::Block { end_label }, BlockFrameType::Block { end_label },
block_type, block_type,
self.position, self.position,
@ -684,6 +707,7 @@ impl<'a> FunctionValidationContext<'a> {
self.sink.resolve_label(header); self.sink.resolve_label(header);
push_label( push_label(
StartedWith::Loop,
BlockFrameType::Loop { header }, BlockFrameType::Loop { header },
block_type, block_type,
self.position, self.position,
@ -703,6 +727,7 @@ impl<'a> FunctionValidationContext<'a> {
ValueType::I32.into(), ValueType::I32.into(),
)?; )?;
push_label( push_label(
StartedWith::If,
BlockFrameType::IfTrue { if_not, end_label }, BlockFrameType::IfTrue { if_not, end_label },
block_type, block_type,
self.position, self.position,
@ -747,6 +772,7 @@ impl<'a> FunctionValidationContext<'a> {
// frame. // frame.
pop_label(&mut self.value_stack, &mut self.frame_stack)?; pop_label(&mut self.value_stack, &mut self.frame_stack)?;
push_label( push_label(
StartedWith::Else,
BlockFrameType::IfFalse { end_label }, BlockFrameType::IfFalse { end_label },
block_type, block_type,
self.position, self.position,
@ -1577,6 +1603,7 @@ fn tee_value(
} }
fn push_label( fn push_label(
started_with: StartedWith,
frame_type: BlockFrameType, frame_type: BlockFrameType,
block_type: BlockType, block_type: BlockType,
position: usize, position: usize,
@ -1584,6 +1611,7 @@ fn push_label(
frame_stack: &mut StackWithLimit<BlockFrame>, frame_stack: &mut StackWithLimit<BlockFrame>,
) -> Result<(), Error> { ) -> Result<(), Error> {
Ok(frame_stack.push(BlockFrame { Ok(frame_stack.push(BlockFrame {
started_with,
frame_type: frame_type, frame_type: frame_type,
block_type: block_type, block_type: block_type,
begin_position: position, begin_position: position,