Get rid of outcome

This commit is contained in:
Sergey Pepyakin 2019-04-05 13:25:17 +02:00
parent d813c912a5
commit 0994150ba2
1 changed files with 46 additions and 130 deletions

View File

@ -148,15 +148,6 @@ impl PartialEq<StackValueType> for ValueType {
} }
} }
/// Instruction outcome.
#[derive(Debug, Clone)]
enum Outcome {
/// Continue with next instruction.
NextInstruction,
/// Unreachable instruction reached.
Unreachable,
}
// TODO: This is going to be a compiler. // TODO: This is going to be a compiler.
pub struct FunctionReader; pub struct FunctionReader;
@ -206,20 +197,12 @@ impl FunctionReader {
loop { loop {
let instruction = &body[context.position]; let instruction = &body[context.position];
let outcome = FunctionReader::read_instruction(context, instruction).map_err(|err| {
FunctionReader::read_instruction(context, instruction).map_err(|err| { Error(format!(
Error(format!( "At instruction {:?}(@{}): {}",
"At instruction {:?}(@{}): {}", instruction, context.position, err
instruction, context.position, err ))
)) })?;
})?;
match outcome {
Outcome::NextInstruction => (),
Outcome::Unreachable => {
make_top_frame_polymorphic(&mut context.value_stack, &mut context.frame_stack)
}
}
context.position += 1; context.position += 1;
if context.position == body_len { if context.position == body_len {
@ -231,7 +214,7 @@ impl FunctionReader {
fn read_instruction( fn read_instruction(
context: &mut FunctionValidationContext, context: &mut FunctionValidationContext,
instruction: &Instruction, instruction: &Instruction,
) -> Result<Outcome, Error> { ) -> Result<(), Error> {
context.step(instruction) context.step(instruction)
} }
} }
@ -673,7 +656,7 @@ impl<'a> FunctionValidationContext<'a> {
self.sink.into_inner() self.sink.into_inner()
} }
fn step(&mut self, instruction: &Instruction) -> Result<Outcome, Error> { fn step(&mut self, instruction: &Instruction) -> Result<(), Error> {
use self::Instruction::*; use self::Instruction::*;
match *instruction { match *instruction {
@ -682,7 +665,7 @@ impl<'a> FunctionValidationContext<'a> {
Unreachable => { Unreachable => {
self.sink.emit(isa::InstructionInternal::Unreachable); self.sink.emit(isa::InstructionInternal::Unreachable);
return Ok(Outcome::Unreachable); make_top_frame_polymorphic(&mut self.value_stack, &mut self.frame_stack);
} }
Block(block_type) => { Block(block_type) => {
@ -803,22 +786,13 @@ impl<'a> FunctionValidationContext<'a> {
// Check the return type. // Check the return type.
if let BlockType::Value(value_type) = self.return_type() { if let BlockType::Value(value_type) = self.return_type() {
tee_value( tee_value(&mut self.value_stack, &self.frame_stack, value_type.into())?;
&mut self.value_stack,
&self.frame_stack,
value_type.into(),
)?;
} }
// Emit the return instruction. // Emit the return instruction.
let drop_keep = drop_keep_return( let drop_keep =
&self.locals, drop_keep_return(&self.locals, &self.value_stack, &self.frame_stack);
&self.value_stack, self.sink.emit(isa::InstructionInternal::Return(drop_keep));
&self.frame_stack,
);
self
.sink
.emit(isa::InstructionInternal::Return(drop_keep));
} }
pop_label(&mut self.value_stack, &mut self.frame_stack)?; pop_label(&mut self.value_stack, &mut self.frame_stack)?;
@ -834,7 +808,7 @@ impl<'a> FunctionValidationContext<'a> {
let target = require_target(depth, &self.value_stack, &self.frame_stack); let target = require_target(depth, &self.value_stack, &self.frame_stack);
self.sink.emit_br(target); self.sink.emit_br(target);
return Ok(Outcome::Unreachable); make_top_frame_polymorphic(&mut self.value_stack, &mut self.frame_stack);
} }
BrIf(depth) => { BrIf(depth) => {
Validator::validate_br_if(self, depth)?; Validator::validate_br_if(self, depth)?;
@ -850,28 +824,21 @@ impl<'a> FunctionValidationContext<'a> {
let target = require_target(*depth, &self.value_stack, &self.frame_stack); let target = require_target(*depth, &self.value_stack, &self.frame_stack);
targets.push(target); targets.push(target);
} }
let default_target = let default_target = require_target(default, &self.value_stack, &self.frame_stack);
require_target(default, &self.value_stack, &self.frame_stack);
self.sink.emit_br_table(&targets, default_target); self.sink.emit_br_table(&targets, default_target);
return Ok(Outcome::Unreachable); make_top_frame_polymorphic(&mut self.value_stack, &mut self.frame_stack);
} }
Return => { Return => {
if let BlockType::Value(value_type) = self.return_type() { if let BlockType::Value(value_type) = self.return_type() {
tee_value( tee_value(&mut self.value_stack, &self.frame_stack, value_type.into())?;
&mut self.value_stack,
&self.frame_stack,
value_type.into(),
)?;
} }
let drop_keep = let drop_keep =
drop_keep_return(&self.locals, &self.value_stack, &self.frame_stack); drop_keep_return(&self.locals, &self.value_stack, &self.frame_stack);
self self.sink.emit(isa::InstructionInternal::Return(drop_keep));
.sink
.emit(isa::InstructionInternal::Return(drop_keep));
return Ok(Outcome::Unreachable); make_top_frame_polymorphic(&mut self.value_stack, &mut self.frame_stack);
} }
Call(index) => { Call(index) => {
@ -880,8 +847,7 @@ impl<'a> FunctionValidationContext<'a> {
} }
CallIndirect(index, _reserved) => { CallIndirect(index, _reserved) => {
Validator::validate_call_indirect(self, index)?; Validator::validate_call_indirect(self, index)?;
self self.sink
.sink
.emit(isa::InstructionInternal::CallIndirect(index)); .emit(isa::InstructionInternal::CallIndirect(index));
} }
@ -913,15 +879,11 @@ impl<'a> FunctionValidationContext<'a> {
} }
GetGlobal(index) => { GetGlobal(index) => {
Validator::validate_get_global(self, index)?; Validator::validate_get_global(self, index)?;
self self.sink.emit(isa::InstructionInternal::GetGlobal(index));
.sink
.emit(isa::InstructionInternal::GetGlobal(index));
} }
SetGlobal(index) => { SetGlobal(index) => {
Validator::validate_set_global(self, index)?; Validator::validate_set_global(self, index)?;
self self.sink.emit(isa::InstructionInternal::SetGlobal(index));
.sink
.emit(isa::InstructionInternal::SetGlobal(index));
} }
I32Load(align, offset) => { I32Load(align, offset) => {
@ -942,118 +904,80 @@ impl<'a> FunctionValidationContext<'a> {
} }
I32Load8S(align, offset) => { I32Load8S(align, offset) => {
Validator::validate_load(self, align, 1, ValueType::I32)?; Validator::validate_load(self, align, 1, ValueType::I32)?;
self self.sink.emit(isa::InstructionInternal::I32Load8S(offset));
.sink
.emit(isa::InstructionInternal::I32Load8S(offset));
} }
I32Load8U(align, offset) => { I32Load8U(align, offset) => {
Validator::validate_load(self, align, 1, ValueType::I32)?; Validator::validate_load(self, align, 1, ValueType::I32)?;
self self.sink.emit(isa::InstructionInternal::I32Load8U(offset));
.sink
.emit(isa::InstructionInternal::I32Load8U(offset));
} }
I32Load16S(align, offset) => { I32Load16S(align, offset) => {
Validator::validate_load(self, align, 2, ValueType::I32)?; Validator::validate_load(self, align, 2, ValueType::I32)?;
self self.sink.emit(isa::InstructionInternal::I32Load16S(offset));
.sink
.emit(isa::InstructionInternal::I32Load16S(offset));
} }
I32Load16U(align, offset) => { I32Load16U(align, offset) => {
Validator::validate_load(self, align, 2, ValueType::I32)?; Validator::validate_load(self, align, 2, ValueType::I32)?;
self self.sink.emit(isa::InstructionInternal::I32Load16U(offset));
.sink
.emit(isa::InstructionInternal::I32Load16U(offset));
} }
I64Load8S(align, offset) => { I64Load8S(align, offset) => {
Validator::validate_load(self, align, 1, ValueType::I64)?; Validator::validate_load(self, align, 1, ValueType::I64)?;
self self.sink.emit(isa::InstructionInternal::I64Load8S(offset));
.sink
.emit(isa::InstructionInternal::I64Load8S(offset));
} }
I64Load8U(align, offset) => { I64Load8U(align, offset) => {
Validator::validate_load(self, align, 1, ValueType::I64)?; Validator::validate_load(self, align, 1, ValueType::I64)?;
self self.sink.emit(isa::InstructionInternal::I64Load8U(offset));
.sink
.emit(isa::InstructionInternal::I64Load8U(offset));
} }
I64Load16S(align, offset) => { I64Load16S(align, offset) => {
Validator::validate_load(self, align, 2, ValueType::I64)?; Validator::validate_load(self, align, 2, ValueType::I64)?;
self self.sink.emit(isa::InstructionInternal::I64Load16S(offset));
.sink
.emit(isa::InstructionInternal::I64Load16S(offset));
} }
I64Load16U(align, offset) => { I64Load16U(align, offset) => {
Validator::validate_load(self, align, 2, ValueType::I64)?; Validator::validate_load(self, align, 2, ValueType::I64)?;
self self.sink.emit(isa::InstructionInternal::I64Load16U(offset));
.sink
.emit(isa::InstructionInternal::I64Load16U(offset));
} }
I64Load32S(align, offset) => { I64Load32S(align, offset) => {
Validator::validate_load(self, align, 4, ValueType::I64)?; Validator::validate_load(self, align, 4, ValueType::I64)?;
self self.sink.emit(isa::InstructionInternal::I64Load32S(offset));
.sink
.emit(isa::InstructionInternal::I64Load32S(offset));
} }
I64Load32U(align, offset) => { I64Load32U(align, offset) => {
Validator::validate_load(self, align, 4, ValueType::I64)?; Validator::validate_load(self, align, 4, ValueType::I64)?;
self self.sink.emit(isa::InstructionInternal::I64Load32U(offset));
.sink
.emit(isa::InstructionInternal::I64Load32U(offset));
} }
I32Store(align, offset) => { I32Store(align, offset) => {
Validator::validate_store(self, align, 4, ValueType::I32)?; Validator::validate_store(self, align, 4, ValueType::I32)?;
self self.sink.emit(isa::InstructionInternal::I32Store(offset));
.sink
.emit(isa::InstructionInternal::I32Store(offset));
} }
I64Store(align, offset) => { I64Store(align, offset) => {
Validator::validate_store(self, align, 8, ValueType::I64)?; Validator::validate_store(self, align, 8, ValueType::I64)?;
self self.sink.emit(isa::InstructionInternal::I64Store(offset));
.sink
.emit(isa::InstructionInternal::I64Store(offset));
} }
F32Store(align, offset) => { F32Store(align, offset) => {
Validator::validate_store(self, align, 4, ValueType::F32)?; Validator::validate_store(self, align, 4, ValueType::F32)?;
self self.sink.emit(isa::InstructionInternal::F32Store(offset));
.sink
.emit(isa::InstructionInternal::F32Store(offset));
} }
F64Store(align, offset) => { F64Store(align, offset) => {
Validator::validate_store(self, align, 8, ValueType::F64)?; Validator::validate_store(self, align, 8, ValueType::F64)?;
self self.sink.emit(isa::InstructionInternal::F64Store(offset));
.sink
.emit(isa::InstructionInternal::F64Store(offset));
} }
I32Store8(align, offset) => { I32Store8(align, offset) => {
Validator::validate_store(self, align, 1, ValueType::I32)?; Validator::validate_store(self, align, 1, ValueType::I32)?;
self self.sink.emit(isa::InstructionInternal::I32Store8(offset));
.sink
.emit(isa::InstructionInternal::I32Store8(offset));
} }
I32Store16(align, offset) => { I32Store16(align, offset) => {
Validator::validate_store(self, align, 2, ValueType::I32)?; Validator::validate_store(self, align, 2, ValueType::I32)?;
self self.sink.emit(isa::InstructionInternal::I32Store16(offset));
.sink
.emit(isa::InstructionInternal::I32Store16(offset));
} }
I64Store8(align, offset) => { I64Store8(align, offset) => {
Validator::validate_store(self, align, 1, ValueType::I64)?; Validator::validate_store(self, align, 1, ValueType::I64)?;
self self.sink.emit(isa::InstructionInternal::I64Store8(offset));
.sink
.emit(isa::InstructionInternal::I64Store8(offset));
} }
I64Store16(align, offset) => { I64Store16(align, offset) => {
Validator::validate_store(self, align, 2, ValueType::I64)?; Validator::validate_store(self, align, 2, ValueType::I64)?;
self self.sink.emit(isa::InstructionInternal::I64Store16(offset));
.sink
.emit(isa::InstructionInternal::I64Store16(offset));
} }
I64Store32(align, offset) => { I64Store32(align, offset) => {
Validator::validate_store(self, align, 4, ValueType::I64)?; Validator::validate_store(self, align, 4, ValueType::I64)?;
self self.sink.emit(isa::InstructionInternal::I64Store32(offset));
.sink
.emit(isa::InstructionInternal::I64Store32(offset));
} }
CurrentMemory(_) => { CurrentMemory(_) => {
@ -1569,31 +1493,23 @@ impl<'a> FunctionValidationContext<'a> {
I32ReinterpretF32 => { I32ReinterpretF32 => {
Validator::validate_cvtop(self, ValueType::F32, ValueType::I32)?; Validator::validate_cvtop(self, ValueType::F32, ValueType::I32)?;
self self.sink.emit(isa::InstructionInternal::I32ReinterpretF32);
.sink
.emit(isa::InstructionInternal::I32ReinterpretF32);
} }
I64ReinterpretF64 => { I64ReinterpretF64 => {
Validator::validate_cvtop(self, ValueType::F64, ValueType::I64)?; Validator::validate_cvtop(self, ValueType::F64, ValueType::I64)?;
self self.sink.emit(isa::InstructionInternal::I64ReinterpretF64);
.sink
.emit(isa::InstructionInternal::I64ReinterpretF64);
} }
F32ReinterpretI32 => { F32ReinterpretI32 => {
Validator::validate_cvtop(self, ValueType::I32, ValueType::F32)?; Validator::validate_cvtop(self, ValueType::I32, ValueType::F32)?;
self self.sink.emit(isa::InstructionInternal::F32ReinterpretI32);
.sink
.emit(isa::InstructionInternal::F32ReinterpretI32);
} }
F64ReinterpretI64 => { F64ReinterpretI64 => {
Validator::validate_cvtop(self, ValueType::I64, ValueType::F64)?; Validator::validate_cvtop(self, ValueType::I64, ValueType::F64)?;
self self.sink.emit(isa::InstructionInternal::F64ReinterpretI64);
.sink
.emit(isa::InstructionInternal::F64ReinterpretI64);
} }
} }
Ok(Outcome::NextInstruction) Ok(())
} }
} }