diff --git a/src/entity.rs b/src/entity.rs index f098594..7678de0 100644 --- a/src/entity.rs +++ b/src/entity.rs @@ -19,12 +19,12 @@ pub trait EntityRef: Clone + Copy + PartialEq + Eq + PartialOrd + Ord + Hash { } #[macro_export] -macro_rules! entity { +macro_rules! declare_entity { ($name:tt, $prefix:tt) => { #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct $name(u32); - impl crate::entity::EntityRef for $name { + impl $crate::entity::EntityRef for $name { fn new(value: usize) -> Self { use std::convert::TryFrom; let value = u32::try_from(value).unwrap(); @@ -41,13 +41,13 @@ macro_rules! entity { impl std::convert::From for $name { fn from(val: u32) -> Self { - ::new(val as usize) + ::new(val as usize) } } impl std::default::Default for $name { fn default() -> Self { - ::invalid() + ::invalid() } } diff --git a/src/frontend.rs b/src/frontend.rs index a84317c..f29b1cf 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -1353,6 +1353,9 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> { let pick = self .body .add_value(ValueDef::PickOutput(value, i, output_ty)); + if let Some(block) = self.cur_block { + self.body.blocks[block].insts.push(pick); + } self.op_stack.push((output_ty, pick)); log::trace!(" -> pick {}: {:?} ty {:?}", i, pick, output_ty); } diff --git a/src/ir.rs b/src/ir.rs index 052d0b7..ce29eb2 100644 --- a/src/ir.rs +++ b/src/ir.rs @@ -1,6 +1,6 @@ //! Intermediate representation for Wasm. -use crate::entity; +use crate::declare_entity; #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Type { @@ -39,14 +39,14 @@ impl std::fmt::Display for Type { } } -entity!(Signature, "sig"); -entity!(Func, "func"); -entity!(Block, "block"); -entity!(Local, "local"); -entity!(Global, "global"); -entity!(Table, "table"); -entity!(Memory, "memory"); -entity!(Value, "v"); +declare_entity!(Signature, "sig"); +declare_entity!(Func, "func"); +declare_entity!(Block, "block"); +declare_entity!(Local, "local"); +declare_entity!(Global, "global"); +declare_entity!(Table, "table"); +declare_entity!(Memory, "memory"); +declare_entity!(Value, "v"); mod module; pub use module::*; diff --git a/src/ir/func.rs b/src/ir/func.rs index 0238f20..b17e4e7 100644 --- a/src/ir/func.rs +++ b/src/ir/func.rs @@ -1,4 +1,4 @@ -use super::{Block, FunctionBodyDisplay, Local, Signature, Type, Value, ValueDef}; +use super::{Block, FunctionBodyDisplay, Local, Module, Signature, Type, Value, ValueDef}; use crate::entity::EntityVec; #[derive(Clone, Debug)] @@ -48,6 +48,27 @@ pub struct FunctionBody { } impl FunctionBody { + pub fn new(module: &Module, sig: Signature) -> FunctionBody { + let locals = EntityVec::from(module.signature(sig).params.clone()); + let n_params = locals.len(); + let rets = module.signature(sig).returns.clone(); + let mut blocks = EntityVec::default(); + let entry = blocks.push(BlockDef::default()); + let mut values = EntityVec::default(); + for (i, &arg_ty) in locals.values().enumerate() { + let value = values.push(ValueDef::BlockParam(entry, i, arg_ty)); + blocks[entry].params.push((arg_ty, value)); + } + FunctionBody { + n_params, + rets, + locals, + entry, + blocks, + values, + } + } + pub fn add_block(&mut self) -> Block { let id = self.blocks.push(BlockDef::default()); log::trace!("add_block: block {}", id); diff --git a/src/ir/module.rs b/src/ir/module.rs index d111bfc..4dcdc3c 100644 --- a/src/ir/module.rs +++ b/src/ir/module.rs @@ -1,6 +1,7 @@ use super::{Func, FuncDecl, Global, Memory, ModuleDisplay, Signature, Table, Type}; use crate::entity::EntityVec; use crate::frontend; +use crate::ir::FunctionBody; use anyhow::Result; use fxhash::FxHashSet; @@ -233,4 +234,8 @@ impl<'a> Module<'a> { { ModuleDisplay(self) } + + pub fn add_func(&mut self, sig: Signature, func: FunctionBody) -> Func { + self.funcs.push(FuncDecl::Body(sig, func)) + } } diff --git a/src/lib.rs b/src/lib.rs index ab51416..8078dd8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,8 +6,8 @@ pub use wasmparser; mod backend; -mod cfg; -mod entity; +pub mod cfg; +pub mod entity; mod frontend; mod ir; mod op_traits; diff --git a/src/passes/rpo.rs b/src/passes/rpo.rs index faa66bd..4cc3fa1 100644 --- a/src/passes/rpo.rs +++ b/src/passes/rpo.rs @@ -36,12 +36,12 @@ //! ensure that (e.g.) block 4 above is visited first when considering //! successors of block 2. -use crate::entity; +use crate::declare_entity; use crate::entity::{EntityRef, EntityVec, PerEntity}; use crate::ir::{Block, FunctionBody}; use std::collections::{HashMap, HashSet}; -entity!(RPOIndex, "rpo"); +declare_entity!(RPOIndex, "rpo"); impl RPOIndex { fn prev(self) -> RPOIndex {