waffle/src/backend/lower.rs
2022-11-01 20:43:47 -07:00

156 lines
5 KiB
Rust

/*
use crate::backend::binaryen;
use crate::entity::EntityRef;
use crate::ir::*;
use crate::Operator;
use fxhash::FxHashMap;
use wasmparser::Type;
/// Creates a body expression for a function. Returns that expression,
/// and new locals (as their types) that were created as temporaries
/// and need to be appended to `body.locals`.
pub(crate) fn generate_body(
body: &FunctionBody,
into_mod: &mut binaryen::Module,
) -> (Vec<Type>, binaryen::Expression) {
let mut ctx = ElabCtx::new(body, into_mod);
// For each block, generate an expr.
let mut block_exprs: FxHashMap<Block, binaryen::Expression> = FxHashMap::default();
for (block_id, block) in body.blocks.entries() {
let exprs = block
.insts
.iter()
.flat_map(|&inst| {
let inst = body.resolve_alias(inst);
ctx.elaborate_value(into_mod, inst)
})
.collect::<Vec<binaryen::Expression>>();
block_exprs.insert(block_id, binaryen::Expression::block(into_mod, &exprs[..]));
}
// Combine blocks into a single body expression, using the
// relooper/stackifier support built into Binaryen.
let mut relooper = binaryen::Relooper::new(into_mod);
let mut entry = None;
let mut relooper_blocks: FxHashMap<Block, binaryen::RelooperBlock> = FxHashMap::default();
for (block_id, block_expr) in block_exprs {}
let index_var = ctx.new_local(Type::I32);
let expr = relooper.construct(entry.unwrap(), index_var.index());
(ctx.new_locals, expr)
}
#[derive(Clone, Debug)]
struct ElabCtx<'a> {
body: &'a FunctionBody,
op_result_locals: FxHashMap<(Value, usize), Local>,
block_param_locals: FxHashMap<(Block, usize), Local>,
new_locals: Vec<Type>,
}
impl<'a> ElabCtx<'a> {
fn new(body: &'a FunctionBody, into_mod: &mut binaryen::Module) -> ElabCtx<'a> {
todo!()
}
fn elaborate_value(
&mut self,
into_mod: &binaryen::Module,
value: Value,
) -> Option<binaryen::Expression> {
/*
let value = self.body.resolve_alias(value);
match &self.body.values[value] {
&ValueDef::Operator(op, ref args, ref tys) => {
// Get expressions for each arg.
let args = args.iter().map(|&arg| self.get_val_local(arg));
// Create `get_local` expressions for each arg.
let binaryen_args = args
.map(|arg_local| into_mod.expr_local_get(arg_local, self.local_ty(arg_local)))
.collect::<Vec<_>>();
// Create operator.
let expr = self.create_binaryen_op(op, binaryen_args, tys);
// Set local(s) as appropriate.
if tys.len() == 0 {
// Nothing. Create a `drop` expr that wraps the actual operator.
Some(into_mod.expr_drop(expr))
} else if tys.len() == 1 {
// Set value directly.
let local = self.get_val_local(value);
Some(into_mod.expr_local_set(local, expr))
} else {
todo!("support multivalue")
}
}
_ => None,
}
*/
todo!()
}
fn get_val_local(&self, value: Value) -> Local {
match &self.body.values[value] {
&ValueDef::Arg(idx, _) => Local::new(idx),
&ValueDef::BlockParam(block, idx, _) => {
self.block_param_locals.get(&(block, idx)).copied().unwrap()
}
&ValueDef::Operator(..) => self.op_result_locals.get(&(value, 0)).copied().unwrap(),
&ValueDef::PickOutput(value, idx, _) => {
self.op_result_locals.get(&(value, idx)).copied().unwrap()
}
&ValueDef::Alias(val) => self.get_val_local(val),
&ValueDef::Placeholder(_) => unreachable!(),
}
}
fn new_local(&mut self, ty: Type) -> Local {
let index = Local::new(self.body.locals.len() + self.new_locals.len());
self.new_locals.push(ty);
index
}
fn create_binaryen_op(
&mut self,
op: Operator,
args: Vec<binaryen::Expression>,
tys: &[Type],
) -> binaryen::Expression {
todo!()
}
fn local_ty(&self, local: Local) -> Type {
self.body
.locals
.get(local)
.copied()
.unwrap_or_else(|| self.new_locals[local.index() - self.body.locals.len()])
}
}
pub(crate) fn create_new_func(
module: &Module,
sig: Signature,
body: &FunctionBody,
into_mod: &mut binaryen::Module,
body_expr: binaryen::Expression,
new_locals: Vec<Type>,
) {
// Create param types.
let sig = module.signature(sig);
let _func = binaryen::Function::create(
into_mod,
sig.params.iter().copied(),
sig.returns.iter().copied(),
body.locals
.values()
.copied()
.skip(body.n_params)
.chain(new_locals.into_iter()),
body_expr,
);
}
*/