/* 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, ); } */