diff --git a/src/backend/mod.rs b/src/backend/mod.rs index b421174..4fc8632 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -171,7 +171,7 @@ impl<'a> WasmFuncBackend<'a> { } func.instruction(&wasm_encoder::Instruction::Return); } - WasmBlock::ReturnCall { func: f,values } => { + WasmBlock::ReturnCall { func: f, values } => { for &value in &values[..] { self.lower_value(value, func); } @@ -181,7 +181,10 @@ impl<'a> WasmFuncBackend<'a> { for &value in &values[..] { self.lower_value(value, func); } - func.instruction(&wasm_encoder::Instruction::ReturnCallIndirect { ty: sig.index() as u32, table: table.index() as u32 }); + func.instruction(&wasm_encoder::Instruction::ReturnCallIndirect { + ty: sig.index() as u32, + table: table.index() as u32, + }); } WasmBlock::Unreachable => { func.instruction(&wasm_encoder::Instruction::Unreachable); diff --git a/src/backend/stackify.rs b/src/backend/stackify.rs index f26b583..8147e97 100644 --- a/src/backend/stackify.rs +++ b/src/backend/stackify.rs @@ -9,10 +9,10 @@ //! //! for more details on how this algorithm works. -use crate::{Func, Signature, Table}; use crate::cfg::CFGInfo; use crate::entity::EntityRef; use crate::ir::{Block, BlockTarget, FunctionBody, Terminator, Type, Value}; +use crate::{Func, Signature, Table}; use std::collections::HashSet; use std::convert::TryFrom; @@ -31,9 +31,13 @@ pub enum WasmBlock<'a> { header: Block, }, /// A leaf node: one CFG block. - Leaf { block: Block }, + Leaf { + block: Block, + }, /// A translated unconditional branch. - Br { target: WasmLabel }, + Br { + target: WasmLabel, + }, /// A translated conditional. If { cond: Value, @@ -52,9 +56,18 @@ pub enum WasmBlock<'a> { to: &'a [(Type, Value)], }, /// A function return instruction. - Return { values: &'a [Value] }, - ReturnCall { func: Func,values: &'a [Value] }, - ReturnCallIndirect { sig: Signature,table: Table,values: &'a [Value] }, + Return { + values: &'a [Value], + }, + ReturnCall { + func: Func, + values: &'a [Value], + }, + ReturnCallIndirect { + sig: Signature, + table: Table, + values: &'a [Value], + }, /// An unreachable instruction. Unreachable, } @@ -445,11 +458,20 @@ impl<'a, 'b> Context<'a, 'b> { into.push(WasmBlock::Unreachable); } &Terminator::ReturnCall { func, ref args } => { - into.push(WasmBlock::ReturnCall { func: func, values: args }); - } - &Terminator::ReturnCallIndirect { sig, table, ref args } => { - into.push(WasmBlock::ReturnCallIndirect { sig, table, values: args }) + into.push(WasmBlock::ReturnCall { + func: func, + values: args, + }); } + &Terminator::ReturnCallIndirect { + sig, + table, + ref args, + } => into.push(WasmBlock::ReturnCallIndirect { + sig, + table, + values: args, + }), } } } diff --git a/src/frontend.rs b/src/frontend.rs index d9a3a13..257000a 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -1233,13 +1233,27 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> { wasmparser::Operator::ReturnCall { function_index } => { let sig = self.module.funcs[Func::new(*function_index as usize)].sig(); let retvals = self.pop_n(self.module.signatures[sig].params.len()); - self.emit_term(Terminator::ReturnCall { func: Func::new(*function_index as usize), args: retvals }); + self.emit_term(Terminator::ReturnCall { + func: Func::new(*function_index as usize), + args: retvals, + }); self.reachable = false; } - wasmparser::Operator::ReturnCallIndirect { type_index, table_index } => { + wasmparser::Operator::ReturnCallIndirect { + type_index, + table_index, + } => { // let sig = self.module.funcs[Func::new(*function_index as usize)].sig(); - let retvals = self.pop_n(self.module.signatures[Signature::new(*type_index as usize)].params.len()); - self.emit_term(Terminator::ReturnCallIndirect { sig: Signature::new(*type_index as usize), table: Table::new(*table_index as usize),args: retvals }); + let retvals = self.pop_n( + self.module.signatures[Signature::new(*type_index as usize)] + .params + .len(), + ); + self.emit_term(Terminator::ReturnCallIndirect { + sig: Signature::new(*type_index as usize), + table: Table::new(*table_index as usize), + args: retvals, + }); self.reachable = false; } @@ -1659,7 +1673,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> { } } - fn emit_term(&mut self, t: Terminator){ + fn emit_term(&mut self, t: Terminator) { log::trace!( "emit_term: cur_block {} reachable {} terminator {:?}", self.cur_block, @@ -1668,8 +1682,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> { ); if self.reachable { // let values = values.to_vec(); - self.body - .set_terminator(self.cur_block,t); + self.body.set_terminator(self.cur_block, t); self.reachable = false; } } diff --git a/src/interp.rs b/src/interp.rs index c08bebb..b329d3b 100644 --- a/src/interp.rs +++ b/src/interp.rs @@ -227,33 +227,37 @@ impl InterpContext { } match &body.blocks[frame.cur_block].terminator { - &Terminator::ReturnCallIndirect { sig, table, ref args } => { + &Terminator::ReturnCallIndirect { + sig, + table, + ref args, + } => { let args = args - .iter() - .map(|&arg| { - let arg = body.resolve_alias(arg); - let multivalue = frame.values.get(&arg).unwrap(); - assert_eq!(multivalue.len(), 1); - multivalue[0] - }) - .collect::>(); - let idx = args.last().unwrap().as_u32().unwrap() as usize; - let func = self.tables[table].elements[idx]; - let result = self.call(module, func, &args[..args.len() - 1]); - return result; + .iter() + .map(|&arg| { + let arg = body.resolve_alias(arg); + let multivalue = frame.values.get(&arg).unwrap(); + assert_eq!(multivalue.len(), 1); + multivalue[0] + }) + .collect::>(); + let idx = args.last().unwrap().as_u32().unwrap() as usize; + let func = self.tables[table].elements[idx]; + let result = self.call(module, func, &args[..args.len() - 1]); + return result; } &Terminator::ReturnCall { func, ref args } => { let args = args - .iter() - .map(|&arg| { - let arg = body.resolve_alias(arg); - let multivalue = frame.values.get(&arg).unwrap(); - assert_eq!(multivalue.len(), 1); - multivalue[0] - }) - .collect::>(); - let result = self.call(module, func, &args[..]); - return result; + .iter() + .map(|&arg| { + let arg = body.resolve_alias(arg); + let multivalue = frame.values.get(&arg).unwrap(); + assert_eq!(multivalue.len(), 1); + multivalue[0] + }) + .collect::>(); + let result = self.call(module, func, &args[..]); + return result; } &Terminator::None => { return InterpResult::Trap(frame.func, frame.cur_block, u32::MAX) diff --git a/src/ir/func.rs b/src/ir/func.rs index 4d06cae..651961f 100644 --- a/src/ir/func.rs +++ b/src/ir/func.rs @@ -1,11 +1,11 @@ use super::{Block, FunctionBodyDisplay, Local, Module, Signature, Type, Value, ValueDef}; -use crate::{Func, Table}; use crate::backend::WasmFuncBackend; use crate::cfg::CFGInfo; use crate::entity::{EntityRef, EntityVec, PerEntity}; use crate::frontend::parse_body; use crate::ir::SourceLoc; use crate::pool::{ListPool, ListRef}; +use crate::{Func, Table}; use anyhow::Result; use fxhash::FxHashMap; use std::collections::HashSet; @@ -539,7 +539,7 @@ pub enum Terminator { }, ReturnCall { func: Func, - args: Vec, + args: Vec, }, ReturnCallIndirect { sig: Signature, @@ -595,8 +595,7 @@ impl std::fmt::Display for Terminator { f, "return_call {}({})", func, - args - .iter() + args.iter() .map(|val| format!("{}", val)) .collect::>() .join(", ") @@ -604,9 +603,9 @@ impl std::fmt::Display for Terminator { Terminator::ReturnCallIndirect { sig, table, args } => write!( f, "return_call_indirect ({};{})({})", - sig,table, - args - .iter() + sig, + table, + args.iter() .map(|val| format!("{}", val)) .collect::>() .join(", ") @@ -641,8 +640,8 @@ impl Terminator { } Terminator::None => {} Terminator::Unreachable => {} - Terminator::ReturnCall { func, args } =>{}, - Terminator::ReturnCallIndirect { sig, table, args } => {}, + Terminator::ReturnCall { func, args } => {} + Terminator::ReturnCallIndirect { sig, table, args } => {} } } @@ -670,8 +669,8 @@ impl Terminator { } Terminator::None => {} Terminator::Unreachable => {} - Terminator::ReturnCall { func, args } =>{}, - Terminator::ReturnCallIndirect { sig, table, args } => {}, + Terminator::ReturnCall { func, args } => {} + Terminator::ReturnCallIndirect { sig, table, args } => {} } } @@ -752,15 +751,19 @@ impl Terminator { } } &Terminator::ReturnCall { func, ref args } => { - for value in args{ + for value in args { f(*value); } } - &Terminator::ReturnCallIndirect { sig, table, ref args } => { - for value in args{ + &Terminator::ReturnCallIndirect { + sig, + table, + ref args, + } => { + for value in args { f(*value); } - }, + } _ => {} } } @@ -780,15 +783,19 @@ impl Terminator { } } &mut Terminator::ReturnCall { func, ref mut args } => { - for value in args{ + for value in args { f(value); } } - &mut Terminator::ReturnCallIndirect { sig, table, ref mut args } => { - for value in args{ + &mut Terminator::ReturnCallIndirect { + sig, + table, + ref mut args, + } => { + for value in args { f(value); } - }, + } _ => {} } } diff --git a/src/op_traits.rs b/src/op_traits.rs index d0d81e4..087e9c1 100644 --- a/src/op_traits.rs +++ b/src/op_traits.rs @@ -24,7 +24,7 @@ pub fn op_inputs( } &Operator::Select => { - let Some(op_stack) = op_stack else{ + let Some(op_stack) = op_stack else { anyhow::bail!("selects cannot be typed with no stack"); }; let val_ty = op_stack[op_stack.len() - 2].0; @@ -246,7 +246,7 @@ pub fn op_outputs( } &Operator::Select => { - let Some(op_stack) = op_stack else{ + let Some(op_stack) = op_stack else { anyhow::bail!("selects cannot be typed with no stack"); }; let val_ty = op_stack[op_stack.len() - 2].0; diff --git a/src/ops.rs b/src/ops.rs index f63a0bd..dbbc798 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -579,9 +579,9 @@ impl<'a, 'b> std::convert::TryFrom<&'b wasmparser::Operator<'a>> for Operator { dst_mem: Memory::from(dst_mem), src_mem: Memory::from(src_mem), }), - &wasmparser::Operator::MemoryFill { mem } => { - Ok(Operator::MemoryFill { mem: Memory::from(mem) }) - } + &wasmparser::Operator::MemoryFill { mem } => Ok(Operator::MemoryFill { + mem: Memory::from(mem), + }), _ => Err(()), } } diff --git a/src/passes.rs b/src/passes.rs index be8a888..838c428 100644 --- a/src/passes.rs +++ b/src/passes.rs @@ -5,7 +5,7 @@ pub mod dom_pass; pub mod empty_blocks; pub mod maxssa; pub mod remove_phis; +pub mod reorder_funs; pub mod resolve_aliases; pub mod ssa; pub mod trace; -pub mod reorder_funs; \ No newline at end of file diff --git a/src/passes/reorder_funs.rs b/src/passes/reorder_funs.rs index 139413a..bc394f8 100644 --- a/src/passes/reorder_funs.rs +++ b/src/passes/reorder_funs.rs @@ -1,6 +1,9 @@ use std::collections::BTreeMap; -use crate::{ExportKind, Func, FuncDecl, FunctionBody, ImportKind, Module, Operator, ValueDef, entity::EntityRef, Terminator}; +use crate::{ + entity::EntityRef, ExportKind, Func, FuncDecl, FunctionBody, ImportKind, Module, Operator, + Terminator, ValueDef, +}; pub fn reorder_funcs_in_body(b: &mut FunctionBody, f: &BTreeMap) { for v in b.values.values_mut() { @@ -10,8 +13,8 @@ pub fn reorder_funcs_in_body(b: &mut FunctionBody, f: &BTreeMap) { } } } - for k in b.blocks.values_mut(){ - if let Terminator::ReturnCall { func, args } = &mut k.terminator{ + for k in b.blocks.values_mut() { + if let Terminator::ReturnCall { func, args } = &mut k.terminator { *func = *f.get(&*func).unwrap(); } } @@ -56,11 +59,11 @@ pub fn fixup_orders(m: &mut Module) { } } let mut i = 0; - for v in a{ + for v in a { fs.insert(v, Func::new(i)); i += 1; } - for v in b{ + for v in b { fs.insert(v, Func::new(i)); i += 1; }