Rename to compiler.
This commit is contained in:
parent
b13c730604
commit
05527b05db
|
@ -152,17 +152,14 @@ impl PartialEq<StackValueType> for ValueType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This is going to be a compiler.
|
pub struct Compiler {
|
||||||
|
|
||||||
pub struct FunctionReader {
|
|
||||||
/// A sink used to emit optimized code.
|
/// A sink used to emit optimized code.
|
||||||
sink: Sink,
|
sink: Sink,
|
||||||
// TODO: to be moved to the compiler.
|
|
||||||
label_stack: Vec<BlockFrameType>,
|
label_stack: Vec<BlockFrameType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FunctionReader {
|
impl Compiler {
|
||||||
pub fn read_function(
|
pub fn compile(
|
||||||
module: &ModuleContext,
|
module: &ModuleContext,
|
||||||
func: &Func,
|
func: &Func,
|
||||||
body: &FuncBody,
|
body: &FuncBody,
|
||||||
|
@ -186,23 +183,22 @@ impl FunctionReader {
|
||||||
&mut context.frame_stack,
|
&mut context.frame_stack,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut function_reader = FunctionReader {
|
let mut compiler = Compiler {
|
||||||
sink: Sink::with_instruction_capacity(ins_size_estimate),
|
sink: Sink::with_instruction_capacity(ins_size_estimate),
|
||||||
label_stack: Vec::new(),
|
label_stack: Vec::new(),
|
||||||
};
|
};
|
||||||
let end_label = function_reader.sink.new_label();
|
let end_label = compiler.sink.new_label();
|
||||||
function_reader
|
compiler
|
||||||
.label_stack
|
.label_stack
|
||||||
.push(BlockFrameType::Block { end_label });
|
.push(BlockFrameType::Block { end_label });
|
||||||
|
compiler.compile_function_body(&mut context, body.code().elements())?;
|
||||||
function_reader.read_function_body(&mut context, body.code().elements())?;
|
|
||||||
|
|
||||||
assert!(context.frame_stack.is_empty());
|
assert!(context.frame_stack.is_empty());
|
||||||
|
|
||||||
Ok(function_reader.sink.into_inner())
|
Ok(compiler.sink.into_inner())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_function_body(
|
fn compile_function_body(
|
||||||
&mut self,
|
&mut self,
|
||||||
context: &mut FunctionValidationContext,
|
context: &mut FunctionValidationContext,
|
||||||
body: &[Instruction],
|
body: &[Instruction],
|
||||||
|
@ -215,7 +211,7 @@ impl FunctionReader {
|
||||||
loop {
|
loop {
|
||||||
let instruction = &body[context.position];
|
let instruction = &body[context.position];
|
||||||
|
|
||||||
self.read_instruction(context, instruction).map_err(|err| {
|
self.compile_instruction(context, instruction).map_err(|err| {
|
||||||
Error(format!(
|
Error(format!(
|
||||||
"At instruction {:?}(@{}): {}",
|
"At instruction {:?}(@{}): {}",
|
||||||
instruction, context.position, err
|
instruction, context.position, err
|
||||||
|
@ -229,7 +225,7 @@ impl FunctionReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_instruction(
|
fn compile_instruction(
|
||||||
&mut self,
|
&mut self,
|
||||||
context: &mut FunctionValidationContext,
|
context: &mut FunctionValidationContext,
|
||||||
instruction: &Instruction,
|
instruction: &Instruction,
|
||||||
|
@ -462,96 +458,96 @@ impl FunctionReader {
|
||||||
self.sink.emit(isa::InstructionInternal::SetGlobal(index));
|
self.sink.emit(isa::InstructionInternal::SetGlobal(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
I32Load(align, offset) => {
|
I32Load(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I32Load(offset));
|
self.sink.emit(isa::InstructionInternal::I32Load(offset));
|
||||||
}
|
}
|
||||||
I64Load(align, offset) => {
|
I64Load(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I64Load(offset));
|
self.sink.emit(isa::InstructionInternal::I64Load(offset));
|
||||||
}
|
}
|
||||||
F32Load(align, offset) => {
|
F32Load(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::F32Load(offset));
|
self.sink.emit(isa::InstructionInternal::F32Load(offset));
|
||||||
}
|
}
|
||||||
F64Load(align, offset) => {
|
F64Load(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::F64Load(offset));
|
self.sink.emit(isa::InstructionInternal::F64Load(offset));
|
||||||
}
|
}
|
||||||
I32Load8S(align, offset) => {
|
I32Load8S(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I32Load8S(offset));
|
self.sink.emit(isa::InstructionInternal::I32Load8S(offset));
|
||||||
}
|
}
|
||||||
I32Load8U(align, offset) => {
|
I32Load8U(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I32Load8U(offset));
|
self.sink.emit(isa::InstructionInternal::I32Load8U(offset));
|
||||||
}
|
}
|
||||||
I32Load16S(align, offset) => {
|
I32Load16S(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I32Load16S(offset));
|
self.sink.emit(isa::InstructionInternal::I32Load16S(offset));
|
||||||
}
|
}
|
||||||
I32Load16U(align, offset) => {
|
I32Load16U(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I32Load16U(offset));
|
self.sink.emit(isa::InstructionInternal::I32Load16U(offset));
|
||||||
}
|
}
|
||||||
I64Load8S(align, offset) => {
|
I64Load8S(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I64Load8S(offset));
|
self.sink.emit(isa::InstructionInternal::I64Load8S(offset));
|
||||||
}
|
}
|
||||||
I64Load8U(align, offset) => {
|
I64Load8U(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I64Load8U(offset));
|
self.sink.emit(isa::InstructionInternal::I64Load8U(offset));
|
||||||
}
|
}
|
||||||
I64Load16S(align, offset) => {
|
I64Load16S(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I64Load16S(offset));
|
self.sink.emit(isa::InstructionInternal::I64Load16S(offset));
|
||||||
}
|
}
|
||||||
I64Load16U(align, offset) => {
|
I64Load16U(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I64Load16U(offset));
|
self.sink.emit(isa::InstructionInternal::I64Load16U(offset));
|
||||||
}
|
}
|
||||||
I64Load32S(align, offset) => {
|
I64Load32S(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I64Load32S(offset));
|
self.sink.emit(isa::InstructionInternal::I64Load32S(offset));
|
||||||
}
|
}
|
||||||
I64Load32U(align, offset) => {
|
I64Load32U(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I64Load32U(offset));
|
self.sink.emit(isa::InstructionInternal::I64Load32U(offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
I32Store(align, offset) => {
|
I32Store(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I32Store(offset));
|
self.sink.emit(isa::InstructionInternal::I32Store(offset));
|
||||||
}
|
}
|
||||||
I64Store(align, offset) => {
|
I64Store(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I64Store(offset));
|
self.sink.emit(isa::InstructionInternal::I64Store(offset));
|
||||||
}
|
}
|
||||||
F32Store(align, offset) => {
|
F32Store(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::F32Store(offset));
|
self.sink.emit(isa::InstructionInternal::F32Store(offset));
|
||||||
}
|
}
|
||||||
F64Store(align, offset) => {
|
F64Store(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::F64Store(offset));
|
self.sink.emit(isa::InstructionInternal::F64Store(offset));
|
||||||
}
|
}
|
||||||
I32Store8(align, offset) => {
|
I32Store8(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I32Store8(offset));
|
self.sink.emit(isa::InstructionInternal::I32Store8(offset));
|
||||||
}
|
}
|
||||||
I32Store16(align, offset) => {
|
I32Store16(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I32Store16(offset));
|
self.sink.emit(isa::InstructionInternal::I32Store16(offset));
|
||||||
}
|
}
|
||||||
I64Store8(align, offset) => {
|
I64Store8(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I64Store8(offset));
|
self.sink.emit(isa::InstructionInternal::I64Store8(offset));
|
||||||
}
|
}
|
||||||
I64Store16(align, offset) => {
|
I64Store16(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I64Store16(offset));
|
self.sink.emit(isa::InstructionInternal::I64Store16(offset));
|
||||||
}
|
}
|
||||||
I64Store32(align, offset) => {
|
I64Store32(_, offset) => {
|
||||||
context.step(instruction)?;
|
context.step(instruction)?;
|
||||||
self.sink.emit(isa::InstructionInternal::I64Store32(offset));
|
self.sink.emit(isa::InstructionInternal::I64Store32(offset));
|
||||||
}
|
}
|
||||||
|
@ -1196,7 +1192,7 @@ impl<'a> FunctionValidationContext<'a> {
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
End => {
|
End => {
|
||||||
let (started_with, block_type) = {
|
let block_type = {
|
||||||
let top = top_label(&self.frame_stack);
|
let top = top_label(&self.frame_stack);
|
||||||
|
|
||||||
if top.started_with == StartedWith::If && top.block_type != BlockType::NoResult
|
if top.started_with == StartedWith::If && top.block_type != BlockType::NoResult
|
||||||
|
@ -1208,7 +1204,7 @@ impl<'a> FunctionValidationContext<'a> {
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
(top.started_with, top.block_type)
|
top.block_type
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.frame_stack.len() == 1 {
|
if self.frame_stack.len() == 1 {
|
||||||
|
@ -1261,18 +1257,13 @@ impl<'a> FunctionValidationContext<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
GetLocal(index) => {
|
GetLocal(index) => {
|
||||||
// We need to calculate relative depth before validation since
|
|
||||||
// it will change the value stack size.
|
|
||||||
let depth = relative_local_depth(index, &self.locals, &self.value_stack)?;
|
|
||||||
self.validate_get_local(index)?;
|
self.validate_get_local(index)?;
|
||||||
}
|
}
|
||||||
SetLocal(index) => {
|
SetLocal(index) => {
|
||||||
self.validate_set_local(index)?;
|
self.validate_set_local(index)?;
|
||||||
let depth = relative_local_depth(index, &self.locals, &self.value_stack)?;
|
|
||||||
}
|
}
|
||||||
TeeLocal(index) => {
|
TeeLocal(index) => {
|
||||||
self.validate_tee_local(index)?;
|
self.validate_tee_local(index)?;
|
||||||
let depth = relative_local_depth(index, &self.locals, &self.value_stack)?;
|
|
||||||
}
|
}
|
||||||
GetGlobal(index) => {
|
GetGlobal(index) => {
|
||||||
self.validate_get_global(index)?;
|
self.validate_get_global(index)?;
|
||||||
|
@ -1281,74 +1272,74 @@ impl<'a> FunctionValidationContext<'a> {
|
||||||
self.validate_set_global(index)?;
|
self.validate_set_global(index)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
I32Load(align, offset) => {
|
I32Load(align, _) => {
|
||||||
self.validate_load(align, 4, ValueType::I32)?;
|
self.validate_load(align, 4, ValueType::I32)?;
|
||||||
}
|
}
|
||||||
I64Load(align, offset) => {
|
I64Load(align, _) => {
|
||||||
self.validate_load(align, 8, ValueType::I64)?;
|
self.validate_load(align, 8, ValueType::I64)?;
|
||||||
}
|
}
|
||||||
F32Load(align, offset) => {
|
F32Load(align, _) => {
|
||||||
self.validate_load(align, 4, ValueType::F32)?;
|
self.validate_load(align, 4, ValueType::F32)?;
|
||||||
}
|
}
|
||||||
F64Load(align, offset) => {
|
F64Load(align, _) => {
|
||||||
self.validate_load(align, 8, ValueType::F64)?;
|
self.validate_load(align, 8, ValueType::F64)?;
|
||||||
}
|
}
|
||||||
I32Load8S(align, offset) => {
|
I32Load8S(align, _) => {
|
||||||
self.validate_load(align, 1, ValueType::I32)?;
|
self.validate_load(align, 1, ValueType::I32)?;
|
||||||
}
|
}
|
||||||
I32Load8U(align, offset) => {
|
I32Load8U(align, _) => {
|
||||||
self.validate_load(align, 1, ValueType::I32)?;
|
self.validate_load(align, 1, ValueType::I32)?;
|
||||||
}
|
}
|
||||||
I32Load16S(align, offset) => {
|
I32Load16S(align, _) => {
|
||||||
self.validate_load(align, 2, ValueType::I32)?;
|
self.validate_load(align, 2, ValueType::I32)?;
|
||||||
}
|
}
|
||||||
I32Load16U(align, offset) => {
|
I32Load16U(align, _) => {
|
||||||
self.validate_load(align, 2, ValueType::I32)?;
|
self.validate_load(align, 2, ValueType::I32)?;
|
||||||
}
|
}
|
||||||
I64Load8S(align, offset) => {
|
I64Load8S(align, _) => {
|
||||||
self.validate_load(align, 1, ValueType::I64)?;
|
self.validate_load(align, 1, ValueType::I64)?;
|
||||||
}
|
}
|
||||||
I64Load8U(align, offset) => {
|
I64Load8U(align, _) => {
|
||||||
self.validate_load(align, 1, ValueType::I64)?;
|
self.validate_load(align, 1, ValueType::I64)?;
|
||||||
}
|
}
|
||||||
I64Load16S(align, offset) => {
|
I64Load16S(align, _) => {
|
||||||
self.validate_load(align, 2, ValueType::I64)?;
|
self.validate_load(align, 2, ValueType::I64)?;
|
||||||
}
|
}
|
||||||
I64Load16U(align, offset) => {
|
I64Load16U(align, _) => {
|
||||||
self.validate_load(align, 2, ValueType::I64)?;
|
self.validate_load(align, 2, ValueType::I64)?;
|
||||||
}
|
}
|
||||||
I64Load32S(align, offset) => {
|
I64Load32S(align, _) => {
|
||||||
self.validate_load(align, 4, ValueType::I64)?;
|
self.validate_load(align, 4, ValueType::I64)?;
|
||||||
}
|
}
|
||||||
I64Load32U(align, offset) => {
|
I64Load32U(align, _) => {
|
||||||
self.validate_load(align, 4, ValueType::I64)?;
|
self.validate_load(align, 4, ValueType::I64)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
I32Store(align, offset) => {
|
I32Store(align, _) => {
|
||||||
self.validate_store(align, 4, ValueType::I32)?;
|
self.validate_store(align, 4, ValueType::I32)?;
|
||||||
}
|
}
|
||||||
I64Store(align, offset) => {
|
I64Store(align, _) => {
|
||||||
self.validate_store(align, 8, ValueType::I64)?;
|
self.validate_store(align, 8, ValueType::I64)?;
|
||||||
}
|
}
|
||||||
F32Store(align, offset) => {
|
F32Store(align, _) => {
|
||||||
self.validate_store(align, 4, ValueType::F32)?;
|
self.validate_store(align, 4, ValueType::F32)?;
|
||||||
}
|
}
|
||||||
F64Store(align, offset) => {
|
F64Store(align, _) => {
|
||||||
self.validate_store(align, 8, ValueType::F64)?;
|
self.validate_store(align, 8, ValueType::F64)?;
|
||||||
}
|
}
|
||||||
I32Store8(align, offset) => {
|
I32Store8(align, _) => {
|
||||||
self.validate_store(align, 1, ValueType::I32)?;
|
self.validate_store(align, 1, ValueType::I32)?;
|
||||||
}
|
}
|
||||||
I32Store16(align, offset) => {
|
I32Store16(align, _) => {
|
||||||
self.validate_store(align, 2, ValueType::I32)?;
|
self.validate_store(align, 2, ValueType::I32)?;
|
||||||
}
|
}
|
||||||
I64Store8(align, offset) => {
|
I64Store8(align, _) => {
|
||||||
self.validate_store(align, 1, ValueType::I64)?;
|
self.validate_store(align, 1, ValueType::I64)?;
|
||||||
}
|
}
|
||||||
I64Store16(align, offset) => {
|
I64Store16(align, _) => {
|
||||||
self.validate_store(align, 2, ValueType::I64)?;
|
self.validate_store(align, 2, ValueType::I64)?;
|
||||||
}
|
}
|
||||||
I64Store32(align, offset) => {
|
I64Store32(align, _) => {
|
||||||
self.validate_store(align, 4, ValueType::I64)?;
|
self.validate_store(align, 4, ValueType::I64)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1359,16 +1350,16 @@ impl<'a> FunctionValidationContext<'a> {
|
||||||
self.validate_grow_memory()?;
|
self.validate_grow_memory()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
I32Const(v) => {
|
I32Const(_) => {
|
||||||
self.validate_const(ValueType::I32)?;
|
self.validate_const(ValueType::I32)?;
|
||||||
}
|
}
|
||||||
I64Const(v) => {
|
I64Const(_) => {
|
||||||
self.validate_const(ValueType::I64)?;
|
self.validate_const(ValueType::I64)?;
|
||||||
}
|
}
|
||||||
F32Const(v) => {
|
F32Const(_) => {
|
||||||
self.validate_const(ValueType::F32)?;
|
self.validate_const(ValueType::F32)?;
|
||||||
}
|
}
|
||||||
F64Const(v) => {
|
F64Const(_) => {
|
||||||
self.validate_const(ValueType::F64)?;
|
self.validate_const(ValueType::F64)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ use hashbrown::HashSet;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use self::context::ModuleContextBuilder;
|
use self::context::ModuleContextBuilder;
|
||||||
use self::func::FunctionReader;
|
use self::func::Compiler;
|
||||||
use common::stack;
|
use common::stack;
|
||||||
use isa;
|
use isa;
|
||||||
use memory_units::Pages;
|
use memory_units::Pages;
|
||||||
|
@ -266,7 +266,7 @@ pub fn validate_module(module: Module) -> Result<ValidatedModule, Error> {
|
||||||
.get(index as usize)
|
.get(index as usize)
|
||||||
.ok_or(Error(format!("Missing body for function {}", index)))?;
|
.ok_or(Error(format!("Missing body for function {}", index)))?;
|
||||||
let code =
|
let code =
|
||||||
FunctionReader::read_function(&context, function, function_body).map_err(|e| {
|
Compiler::compile(&context, function, function_body).map_err(|e| {
|
||||||
let Error(ref msg) = e;
|
let Error(ref msg) = e;
|
||||||
Error(format!(
|
Error(format!(
|
||||||
"Function #{} reading/validation error: {}",
|
"Function #{} reading/validation error: {}",
|
||||||
|
|
Loading…
Reference in New Issue