Get rid of outcome
This commit is contained in:
parent
d813c912a5
commit
0994150ba2
|
@ -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(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue