Refactor some messy code

This commit is contained in:
Rerumu 2022-04-25 18:07:40 -04:00
parent e7b36a7d94
commit 5e955efcbd
2 changed files with 84 additions and 98 deletions

View File

@ -29,6 +29,22 @@ fn new_limit_max(limits: &ResizableLimits) -> String {
} }
} }
fn write_separated<I, T, M>(mut iter: I, mut func: M, w: Writer) -> Result<()>
where
M: FnMut(T, Writer) -> Result<()>,
I: Iterator<Item = T>,
{
match iter.next() {
Some(first) => func(first, w)?,
None => return Ok(()),
}
iter.try_for_each(|v| {
write!(w, ", ")?;
func(v, w)
})
}
fn write_table_init(limit: &ResizableLimits, w: Writer) -> Result<()> { fn write_table_init(limit: &ResizableLimits, w: Writer) -> Result<()> {
let a = limit.initial(); let a = limit.initial();
let b = new_limit_max(limit); let b = new_limit_max(limit);
@ -43,7 +59,7 @@ fn write_memory_init(limit: &ResizableLimits, w: Writer) -> Result<()> {
write!(w, "rt.allocator.new({}, {})", a, b) write!(w, "rt.allocator.new({}, {})", a, b)
} }
fn write_func_name(wasm: &Module, index: u32, offset: u32, w: Writer) -> Result<()> { fn write_func_start(wasm: &Module, index: u32, offset: u32, w: Writer) -> Result<()> {
let opt = wasm let opt = wasm
.names_section() .names_section()
.and_then(NameSection::functions) .and_then(NameSection::functions)
@ -58,13 +74,8 @@ fn write_func_name(wasm: &Module, index: u32, offset: u32, w: Writer) -> Result<
write!(w, "[{}] =", index + offset) write!(w, "[{}] =", index + offset)
} }
fn write_in_order(prefix: &str, len: usize, w: Writer) -> Result<()> { fn write_ascending(prefix: &str, range: Range<usize>, w: Writer) -> Result<()> {
if len == 0 { write_separated(range, |i, w| write!(w, "{}_{}", prefix, i), w)
return Ok(());
}
write!(w, "{}_{}", prefix, 0)?;
(1..len).try_for_each(|i| write!(w, ", {}_{}", prefix, i))
} }
fn write_f32(f: f32, w: Writer) -> Result<()> { fn write_f32(f: f32, w: Writer) -> Result<()> {
@ -91,7 +102,7 @@ fn write_f64(f: f64, w: Writer) -> Result<()> {
} }
} }
fn write_list(name: &str, len: usize, w: Writer) -> Result<()> { fn write_named_array(name: &str, len: usize, w: Writer) -> Result<()> {
let hash = len.min(1); let hash = len.min(1);
let len = len.saturating_sub(1); let len = len.saturating_sub(1);
@ -100,51 +111,39 @@ fn write_list(name: &str, len: usize, w: Writer) -> Result<()> {
fn write_parameter_list(func: &Function, w: Writer) -> Result<()> { fn write_parameter_list(func: &Function, w: Writer) -> Result<()> {
write!(w, "function(")?; write!(w, "function(")?;
write_in_order("param", func.num_param, w)?; write_ascending("param", 0..func.num_param, w)?;
write!(w, ")") write!(w, ")")
} }
fn write_result_list(range: Range<usize>, w: Writer) -> Result<()> { fn write_call_store(result: Range<usize>, w: Writer) -> Result<()> {
if range.is_empty() { if result.is_empty() {
return Ok(()); return Ok(());
} }
range.clone().try_for_each(|i| { write_ascending("reg", result, w)?;
if i != range.start {
write!(w, ", ")?;
}
write!(w, "reg_{}", i)
})?;
write!(w, " = ") write!(w, " = ")
} }
fn write_variable_list(func: &Function, w: Writer) -> Result<()> { fn write_variable_list(func: &Function, w: Writer) -> Result<()> {
for data in &func.local_data { for data in &func.local_data {
let range = 0..data.count().try_into().unwrap();
write!(w, "local ")?; write!(w, "local ")?;
write_in_order("loc", data.count().try_into().unwrap(), w)?; write_ascending("loc", range.clone(), w)?;
write!(w, " = ")?; write!(w, " = ")?;
write_separated(range, |_, w| write!(w, "ZERO_{} ", data.value_type()), w)?;
for i in 0..data.count() {
if i != 0 {
write!(w, ", ")?;
}
write!(w, "ZERO_{} ", data.value_type())?;
}
} }
if func.num_stack != 0 { if func.num_stack != 0 {
write!(w, "local ")?; write!(w, "local ")?;
write_in_order("reg", func.num_stack, w)?; write_ascending("reg", 0..func.num_stack, w)?;
write!(w, " ")?; write!(w, " ")?;
} }
Ok(()) Ok(())
} }
fn write_expression(code: &[Instruction], w: Writer) -> Result<()> { fn write_constant(code: &[Instruction], w: Writer) -> Result<()> {
// FIXME: Badly generated WASM will produce the wrong constant. // FIXME: Badly generated WASM will produce the wrong constant.
for inst in code { for inst in code {
let result = match *inst { let result = match *inst {
@ -348,13 +347,7 @@ fn write_as_condition(data: &Expression, v: &mut Visitor, w: Writer) -> Result<(
} }
fn write_expr_list(list: &[Expression], v: &mut Visitor, w: Writer) -> Result<()> { fn write_expr_list(list: &[Expression], v: &mut Visitor, w: Writer) -> Result<()> {
list.iter().enumerate().try_for_each(|(i, e)| { write_separated(list.iter(), |e, w| e.visit(v, w), w)
if i != 0 {
write!(w, ", ")?;
}
e.visit(v, w)
})
} }
impl Driver for Expression { impl Driver for Expression {
@ -504,7 +497,7 @@ impl Driver for Return {
impl Driver for Call { impl Driver for Call {
fn visit(&self, v: &mut Visitor, w: Writer) -> Result<()> { fn visit(&self, v: &mut Visitor, w: Writer) -> Result<()> {
write_result_list(self.result.clone(), w)?; write_call_store(self.result.clone(), w)?;
write!(w, "FUNC_LIST[{}](", self.func)?; write!(w, "FUNC_LIST[{}](", self.func)?;
@ -516,7 +509,7 @@ impl Driver for Call {
impl Driver for CallIndirect { impl Driver for CallIndirect {
fn visit(&self, v: &mut Visitor, w: Writer) -> Result<()> { fn visit(&self, v: &mut Visitor, w: Writer) -> Result<()> {
write_result_list(self.result.clone(), w)?; write_call_store(self.result.clone(), w)?;
write!(w, "TABLE_LIST[{}].data[", self.table)?; write!(w, "TABLE_LIST[{}].data[", self.table)?;
@ -626,10 +619,10 @@ impl<'a> Transpiler<'a> for Generator<'a> {
write!(w, "local ZERO_f64 = 0.0 ")?; write!(w, "local ZERO_f64 = 0.0 ")?;
write!(w, "local table_new = require(\"table.new\")")?; write!(w, "local table_new = require(\"table.new\")")?;
write_list("FUNC_LIST", self.wasm.functions_space(), w)?; write_named_array("FUNC_LIST", self.wasm.functions_space(), w)?;
write_list("TABLE_LIST", self.wasm.table_space(), w)?; write_named_array("TABLE_LIST", self.wasm.table_space(), w)?;
write_list("MEMORY_LIST", self.wasm.memory_space(), w)?; write_named_array("MEMORY_LIST", self.wasm.memory_space(), w)?;
write_list("GLOBAL_LIST", self.wasm.globals_space(), w)?; write_named_array("GLOBAL_LIST", self.wasm.globals_space(), w)?;
self.gen_func_list(&func_list, w)?; self.gen_func_list(&func_list, w)?;
self.gen_start_point(w) self.gen_start_point(w)
@ -739,7 +732,7 @@ impl<'a> Generator<'a> {
write!(w, "GLOBAL_LIST[{}] = {{ value =", index)?; write!(w, "GLOBAL_LIST[{}] = {{ value =", index)?;
write_expression(v.init_expr().code(), w)?; write_constant(v.init_expr().code(), w)?;
write!(w, "}}")?; write!(w, "}}")?;
} }
@ -758,7 +751,7 @@ impl<'a> Generator<'a> {
write!(w, "local target = TABLE_LIST[{}].data ", v.index())?; write!(w, "local target = TABLE_LIST[{}].data ", v.index())?;
write!(w, "local offset =")?; write!(w, "local offset =")?;
write_expression(v.offset().as_ref().unwrap().code(), w)?; write_constant(v.offset().as_ref().unwrap().code(), w)?;
write!(w, "local data = {{")?; write!(w, "local data = {{")?;
@ -787,7 +780,7 @@ impl<'a> Generator<'a> {
write!(w, "local target = MEMORY_LIST[{}]", v.index())?; write!(w, "local target = MEMORY_LIST[{}]", v.index())?;
write!(w, "local offset =")?; write!(w, "local offset =")?;
write_expression(v.offset().as_ref().unwrap().code(), w)?; write_constant(v.offset().as_ref().unwrap().code(), w)?;
write!(w, "local data = \"")?; write!(w, "local data = \"")?;
@ -855,10 +848,10 @@ impl<'a> Generator<'a> {
/// # Panics /// # Panics
/// If the number of functions overflows 32 bits. /// If the number of functions overflows 32 bits.
pub fn gen_func_list(&self, func_list: &[Function], w: Writer) -> Result<()> { pub fn gen_func_list(&self, func_list: &[Function], w: Writer) -> Result<()> {
let o = self.type_info.len_ex(); let offset = self.type_info.len_ex().try_into().unwrap();
func_list.iter().enumerate().try_for_each(|(i, v)| { func_list.iter().enumerate().try_for_each(|(i, v)| {
write_func_name(self.wasm, i.try_into().unwrap(), o.try_into().unwrap(), w)?; write_func_start(self.wasm, i.try_into().unwrap(), offset, w)?;
v.visit(&mut Visitor::default(), w) v.visit(&mut Visitor::default(), w)
}) })

View File

@ -29,6 +29,22 @@ fn new_limit_max(limits: &ResizableLimits) -> String {
} }
} }
fn write_separated<I, T, M>(mut iter: I, mut func: M, w: Writer) -> Result<()>
where
M: FnMut(T, Writer) -> Result<()>,
I: Iterator<Item = T>,
{
match iter.next() {
Some(first) => func(first, w)?,
None => return Ok(()),
}
iter.try_for_each(|v| {
write!(w, ", ")?;
func(v, w)
})
}
fn write_table_init(limit: &ResizableLimits, w: Writer) -> Result<()> { fn write_table_init(limit: &ResizableLimits, w: Writer) -> Result<()> {
let a = limit.initial(); let a = limit.initial();
let b = new_limit_max(limit); let b = new_limit_max(limit);
@ -43,7 +59,7 @@ fn write_memory_init(limit: &ResizableLimits, w: Writer) -> Result<()> {
write!(w, "rt.allocator.new({}, {})", a, b) write!(w, "rt.allocator.new({}, {})", a, b)
} }
fn write_func_name(wasm: &Module, index: u32, offset: u32, w: Writer) -> Result<()> { fn write_func_start(wasm: &Module, index: u32, offset: u32, w: Writer) -> Result<()> {
let opt = wasm let opt = wasm
.names_section() .names_section()
.and_then(NameSection::functions) .and_then(NameSection::functions)
@ -58,13 +74,8 @@ fn write_func_name(wasm: &Module, index: u32, offset: u32, w: Writer) -> Result<
write!(w, "[{}] =", index + offset) write!(w, "[{}] =", index + offset)
} }
fn write_in_order(prefix: &str, len: usize, w: Writer) -> Result<()> { fn write_ascending(prefix: &str, range: Range<usize>, w: Writer) -> Result<()> {
if len == 0 { write_separated(range, |i, w| write!(w, "{}_{}", prefix, i), w)
return Ok(());
}
write!(w, "{}_{}", prefix, 0)?;
(1..len).try_for_each(|i| write!(w, ", {}_{}", prefix, i))
} }
fn write_f32(f: f32, w: Writer) -> Result<()> { fn write_f32(f: f32, w: Writer) -> Result<()> {
@ -91,7 +102,7 @@ fn write_f64(f: f64, w: Writer) -> Result<()> {
} }
} }
fn write_list(name: &str, len: usize, w: Writer) -> Result<()> { fn write_named_array(name: &str, len: usize, w: Writer) -> Result<()> {
let len = len.saturating_sub(1); let len = len.saturating_sub(1);
write!(w, "local {} = table.create({})", name, len) write!(w, "local {} = table.create({})", name, len)
@ -99,51 +110,39 @@ fn write_list(name: &str, len: usize, w: Writer) -> Result<()> {
fn write_parameter_list(func: &Function, w: Writer) -> Result<()> { fn write_parameter_list(func: &Function, w: Writer) -> Result<()> {
write!(w, "function(")?; write!(w, "function(")?;
write_in_order("param", func.num_param, w)?; write_ascending("param", 0..func.num_param, w)?;
write!(w, ")") write!(w, ")")
} }
fn write_result_list(range: Range<usize>, w: Writer) -> Result<()> { fn write_call_store(result: Range<usize>, w: Writer) -> Result<()> {
if range.is_empty() { if result.is_empty() {
return Ok(()); return Ok(());
} }
range.clone().try_for_each(|i| { write_ascending("reg", result, w)?;
if i != range.start {
write!(w, ", ")?;
}
write!(w, "reg_{}", i)
})?;
write!(w, " = ") write!(w, " = ")
} }
fn write_variable_list(func: &Function, w: Writer) -> Result<()> { fn write_variable_list(func: &Function, w: Writer) -> Result<()> {
for data in &func.local_data { for data in &func.local_data {
let range = 0..data.count().try_into().unwrap();
write!(w, "local ")?; write!(w, "local ")?;
write_in_order("loc", data.count().try_into().unwrap(), w)?; write_ascending("loc", range.clone(), w)?;
write!(w, " = ")?; write!(w, " = ")?;
write_separated(range, |_, w| write!(w, "ZERO_{} ", data.value_type()), w)?;
for i in 0..data.count() {
if i != 0 {
write!(w, ", ")?;
}
write!(w, "ZERO_{} ", data.value_type())?;
}
} }
if func.num_stack != 0 { if func.num_stack != 0 {
write!(w, "local ")?; write!(w, "local ")?;
write_in_order("reg", func.num_stack, w)?; write_ascending("reg", 0..func.num_stack, w)?;
write!(w, " ")?; write!(w, " ")?;
} }
Ok(()) Ok(())
} }
fn write_expression(code: &[Instruction], w: Writer) -> Result<()> { fn write_constant(code: &[Instruction], w: Writer) -> Result<()> {
// FIXME: Badly generated WASM will produce the wrong constant. // FIXME: Badly generated WASM will produce the wrong constant.
for inst in code { for inst in code {
let result = match *inst { let result = match *inst {
@ -338,13 +337,7 @@ impl Driver for AnyCmpOp {
} }
fn write_expr_list(list: &[Expression], v: &mut Visitor, w: Writer) -> Result<()> { fn write_expr_list(list: &[Expression], v: &mut Visitor, w: Writer) -> Result<()> {
list.iter().enumerate().try_for_each(|(i, e)| { write_separated(list.iter(), |e, w| e.visit(v, w), w)
if i != 0 {
write!(w, ", ")?;
}
e.visit(v, w)
})
} }
impl Driver for Expression { impl Driver for Expression {
@ -508,7 +501,7 @@ impl Driver for Return {
impl Driver for Call { impl Driver for Call {
fn visit(&self, v: &mut Visitor, w: Writer) -> Result<()> { fn visit(&self, v: &mut Visitor, w: Writer) -> Result<()> {
write_result_list(self.result.clone(), w)?; write_call_store(self.result.clone(), w)?;
write!(w, "FUNC_LIST[{}](", self.func)?; write!(w, "FUNC_LIST[{}](", self.func)?;
@ -520,7 +513,7 @@ impl Driver for Call {
impl Driver for CallIndirect { impl Driver for CallIndirect {
fn visit(&self, v: &mut Visitor, w: Writer) -> Result<()> { fn visit(&self, v: &mut Visitor, w: Writer) -> Result<()> {
write_result_list(self.result.clone(), w)?; write_call_store(self.result.clone(), w)?;
write!(w, "TABLE_LIST[{}].data[", self.table)?; write!(w, "TABLE_LIST[{}].data[", self.table)?;
@ -628,10 +621,10 @@ impl<'a> Transpiler<'a> for Generator<'a> {
write!(w, "local ZERO_f32 = 0.0 ")?; write!(w, "local ZERO_f32 = 0.0 ")?;
write!(w, "local ZERO_f64 = 0.0 ")?; write!(w, "local ZERO_f64 = 0.0 ")?;
write_list("FUNC_LIST", self.wasm.functions_space(), w)?; write_named_array("FUNC_LIST", self.wasm.functions_space(), w)?;
write_list("TABLE_LIST", self.wasm.table_space(), w)?; write_named_array("TABLE_LIST", self.wasm.table_space(), w)?;
write_list("MEMORY_LIST", self.wasm.memory_space(), w)?; write_named_array("MEMORY_LIST", self.wasm.memory_space(), w)?;
write_list("GLOBAL_LIST", self.wasm.globals_space(), w)?; write_named_array("GLOBAL_LIST", self.wasm.globals_space(), w)?;
self.gen_func_list(&func_list, w)?; self.gen_func_list(&func_list, w)?;
self.gen_start_point(w) self.gen_start_point(w)
@ -741,7 +734,7 @@ impl<'a> Generator<'a> {
write!(w, "GLOBAL_LIST[{}] = {{ value =", index)?; write!(w, "GLOBAL_LIST[{}] = {{ value =", index)?;
write_expression(v.init_expr().code(), w)?; write_constant(v.init_expr().code(), w)?;
write!(w, "}}")?; write!(w, "}}")?;
} }
@ -760,7 +753,7 @@ impl<'a> Generator<'a> {
write!(w, "local target = TABLE_LIST[{}].data ", v.index())?; write!(w, "local target = TABLE_LIST[{}].data ", v.index())?;
write!(w, "local offset =")?; write!(w, "local offset =")?;
write_expression(v.offset().as_ref().unwrap().code(), w)?; write_constant(v.offset().as_ref().unwrap().code(), w)?;
write!(w, "local data = {{")?; write!(w, "local data = {{")?;
@ -789,7 +782,7 @@ impl<'a> Generator<'a> {
write!(w, "local target = MEMORY_LIST[{}]", v.index())?; write!(w, "local target = MEMORY_LIST[{}]", v.index())?;
write!(w, "local offset =")?; write!(w, "local offset =")?;
write_expression(v.offset().as_ref().unwrap().code(), w)?; write_constant(v.offset().as_ref().unwrap().code(), w)?;
write!(w, "local data = \"")?; write!(w, "local data = \"")?;
@ -850,10 +843,10 @@ impl<'a> Generator<'a> {
} }
fn gen_func_list(&self, func_list: &[Function], w: Writer) -> Result<()> { fn gen_func_list(&self, func_list: &[Function], w: Writer) -> Result<()> {
let o = self.type_info.len_ex(); let offset = self.type_info.len_ex().try_into().unwrap();
func_list.iter().enumerate().try_for_each(|(i, v)| { func_list.iter().enumerate().try_for_each(|(i, v)| {
write_func_name(self.wasm, i.try_into().unwrap(), o.try_into().unwrap(), w)?; write_func_start(self.wasm, i.try_into().unwrap(), offset, w)?;
v.visit(&mut Visitor::default(), w) v.visit(&mut Visitor::default(), w)
}) })