From 369097c432ffa5d1e0825f601b5ddf9699808e8a Mon Sep 17 00:00:00 2001 From: Rerumu <25379555+Rerumu@users.noreply.github.com> Date: Sat, 20 Aug 2022 17:55:11 -0400 Subject: [PATCH] Add context-less writing --- codegen/luajit/src/backend/expression.rs | 137 ++++++++++++++--------- codegen/luajit/src/backend/manager.rs | 33 +----- codegen/luajit/src/backend/statement.rs | 71 ++++++------ codegen/luajit/src/translator.rs | 4 +- codegen/luau/src/backend/expression.rs | 137 ++++++++++++++--------- codegen/luau/src/backend/manager.rs | 33 +----- codegen/luau/src/backend/statement.rs | 71 ++++++------ codegen/luau/src/translator.rs | 4 +- 8 files changed, 260 insertions(+), 230 deletions(-) diff --git a/codegen/luajit/src/backend/expression.rs b/codegen/luajit/src/backend/expression.rs index 7da904e..ce87f8c 100644 --- a/codegen/luajit/src/backend/expression.rs +++ b/codegen/luajit/src/backend/expression.rs @@ -10,7 +10,7 @@ use wasm_ast::node::{ use crate::analyzer::as_symbol::AsSymbol; -use super::manager::{write_cmp_op, write_condition, write_separated, Driver, Manager}; +use super::manager::{write_separated, DriverNoContext}; macro_rules! impl_write_number { ($name:tt, $numeric:ty) => { @@ -26,40 +26,40 @@ macro_rules! impl_write_number { }; } -impl Driver for Select { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for Select { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "(")?; - write_condition(self.condition(), mng, w)?; + Condition(self.condition()).write(w)?; write!(w, "and ")?; - self.on_true().write(mng, w)?; + self.on_true().write(w)?; write!(w, "or ")?; - self.on_false().write(mng, w)?; + self.on_false().write(w)?; write!(w, ")") } } -impl Driver for GetTemporary { - fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for GetTemporary { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "reg_{} ", self.var()) } } -impl Driver for GetLocal { - fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for GetLocal { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "loc_{} ", self.var()) } } -impl Driver for GetGlobal { - fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for GetGlobal { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "GLOBAL_LIST[{}].value ", self.var()) } } -impl Driver for LoadAt { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for LoadAt { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "load_{}(memory_at_0, ", self.load_type().as_name())?; - self.pointer().write(mng, w)?; + self.pointer().write(w)?; if self.offset() != 0 { write!(w, "+ {}", self.offset())?; @@ -69,8 +69,8 @@ impl Driver for LoadAt { } } -impl Driver for MemorySize { - fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for MemorySize { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "memory_at_{}.min ", self.memory()) } } @@ -78,8 +78,8 @@ impl Driver for MemorySize { impl_write_number!(write_f32, f32); impl_write_number!(write_f64, f64); -impl Driver for Value { - fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for Value { + fn write(&self, w: &mut dyn Write) -> Result<()> { match self { Self::I32(i) => write!(w, "{i} "), Self::I64(i) => write!(w, "{i}LL "), @@ -89,63 +89,98 @@ impl Driver for Value { } } -impl Driver for UnOp { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for UnOp { + fn write(&self, w: &mut dyn Write) -> Result<()> { let (a, b) = self.op_type().as_name(); write!(w, "{a}_{b}(")?; - self.rhs().write(mng, w)?; + self.rhs().write(w)?; write!(w, ")") } } -impl Driver for BinOp { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for BinOp { + fn write(&self, w: &mut dyn Write) -> Result<()> { if let Some(symbol) = self.op_type().as_symbol() { write!(w, "(")?; - self.lhs().write(mng, w)?; + self.lhs().write(w)?; write!(w, "{symbol} ")?; - self.rhs().write(mng, w)?; + self.rhs().write(w)?; write!(w, ")") } else { let (head, tail) = self.op_type().as_name(); write!(w, "{head}_{tail}(")?; - self.lhs().write(mng, w)?; + self.lhs().write(w)?; write!(w, ", ")?; - self.rhs().write(mng, w)?; + self.rhs().write(w)?; write!(w, ")") } } } -impl Driver for CmpOp { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { - write!(w, "(")?; - write_cmp_op(self, mng, w)?; - write!(w, "and 1 or 0)") - } -} +struct CmpOpBoolean<'a>(&'a CmpOp); -impl Driver for Expression { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { - match self { - Self::Select(e) => e.write(mng, w), - Self::GetTemporary(e) => e.write(mng, w), - Self::GetLocal(e) => e.write(mng, w), - Self::GetGlobal(e) => e.write(mng, w), - Self::LoadAt(e) => e.write(mng, w), - Self::MemorySize(e) => e.write(mng, w), - Self::Value(e) => e.write(mng, w), - Self::UnOp(e) => e.write(mng, w), - Self::BinOp(e) => e.write(mng, w), - Self::CmpOp(e) => e.write(mng, w), +impl DriverNoContext for CmpOpBoolean<'_> { + fn write(&self, w: &mut dyn Write) -> Result<()> { + let cmp = self.0; + + if let Some(symbol) = cmp.op_type().as_symbol() { + cmp.lhs().write(w)?; + write!(w, "{symbol} ")?; + cmp.rhs().write(w) + } else { + let (head, tail) = cmp.op_type().as_name(); + + write!(w, "{head}_{tail}(")?; + cmp.lhs().write(w)?; + write!(w, ", ")?; + cmp.rhs().write(w)?; + write!(w, ")") } } } -impl Driver for &[Expression] { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { - write_separated(self.iter(), |e, w| e.write(mng, w), w) +impl DriverNoContext for CmpOp { + fn write(&self, w: &mut dyn Write) -> Result<()> { + write!(w, "(")?; + CmpOpBoolean(self).write(w)?; + write!(w, "and 1 or 0)") + } +} + +pub struct Condition<'a>(pub &'a Expression); + +impl DriverNoContext for Condition<'_> { + fn write(&self, w: &mut dyn Write) -> Result<()> { + if let Expression::CmpOp(node) = self.0 { + CmpOpBoolean(node).write(w) + } else { + self.0.write(w)?; + write!(w, "~= 0 ") + } + } +} + +impl DriverNoContext for Expression { + fn write(&self, w: &mut dyn Write) -> Result<()> { + match self { + Self::Select(e) => e.write(w), + Self::GetTemporary(e) => e.write(w), + Self::GetLocal(e) => e.write(w), + Self::GetGlobal(e) => e.write(w), + Self::LoadAt(e) => e.write(w), + Self::MemorySize(e) => e.write(w), + Self::Value(e) => e.write(w), + Self::UnOp(e) => e.write(w), + Self::BinOp(e) => e.write(w), + Self::CmpOp(e) => e.write(w), + } + } +} + +impl DriverNoContext for &[Expression] { + fn write(&self, w: &mut dyn Write) -> Result<()> { + write_separated(self.iter(), |e, w| e.write(w), w) } } diff --git a/codegen/luajit/src/backend/manager.rs b/codegen/luajit/src/backend/manager.rs index c42a853..b95bfb7 100644 --- a/codegen/luajit/src/backend/manager.rs +++ b/codegen/luajit/src/backend/manager.rs @@ -4,9 +4,7 @@ use std::{ ops::Range, }; -use wasm_ast::node::{BrTable, CmpOp, Expression}; - -use crate::analyzer::as_symbol::AsSymbol; +use wasm_ast::node::BrTable; #[derive(Default)] pub struct Manager { @@ -46,6 +44,10 @@ pub trait Driver { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()>; } +pub trait DriverNoContext { + fn write(&self, w: &mut dyn Write) -> Result<()>; +} + pub fn write_separated(mut iter: I, mut func: M, w: &mut dyn Write) -> Result<()> where M: FnMut(T, &mut dyn Write) -> Result<()>, @@ -65,28 +67,3 @@ where pub fn write_ascending(prefix: &str, range: Range, w: &mut dyn Write) -> Result<()> { write_separated(range, |i, w| write!(w, "{prefix}_{i}"), w) } - -pub fn write_cmp_op(cmp: &CmpOp, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { - if let Some(symbol) = cmp.op_type().as_symbol() { - cmp.lhs().write(mng, w)?; - write!(w, "{symbol} ")?; - cmp.rhs().write(mng, w) - } else { - let (head, tail) = cmp.op_type().as_name(); - - write!(w, "{head}_{tail}(")?; - cmp.lhs().write(mng, w)?; - write!(w, ", ")?; - cmp.rhs().write(mng, w)?; - write!(w, ")") - } -} - -pub fn write_condition(data: &Expression, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { - if let Expression::CmpOp(node) = data { - write_cmp_op(node, mng, w) - } else { - data.write(mng, w)?; - write!(w, "~= 0 ") - } -} diff --git a/codegen/luajit/src/backend/statement.rs b/codegen/luajit/src/backend/statement.rs index 527ebb8..2a63aea 100644 --- a/codegen/luajit/src/backend/statement.rs +++ b/codegen/luajit/src/backend/statement.rs @@ -11,7 +11,10 @@ use wasmparser::ValType; use crate::analyzer::br_table; -use super::manager::{write_ascending, write_condition, write_separated, Driver, Manager}; +use super::{ + expression::Condition, + manager::{write_ascending, write_separated, Driver, DriverNoContext, Manager}, +}; impl Driver for Br { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { @@ -82,7 +85,7 @@ fn write_table_setup(table: &BrTable, mng: &mut Manager, w: &mut dyn Write) -> R write!(w, "end ")?; write!(w, "temp = br_map[{id}][")?; - table.condition().write(mng, w)?; + table.condition().write(w)?; write!(w, "] or {} ", table.default().target()) } @@ -156,7 +159,7 @@ impl Driver for Block { impl Driver for BrIf { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { write!(w, "if ")?; - write_condition(self.condition(), mng, w)?; + Condition(self.condition()).write(w)?; write!(w, "then ")?; self.target().write(mng, w)?; write!(w, "end ") @@ -166,7 +169,7 @@ impl Driver for BrIf { impl Driver for If { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { write!(w, "if ")?; - write_condition(self.condition(), mng, w)?; + Condition(self.condition()).write(w)?; write!(w, "then ")?; self.on_true().write(mng, w)?; @@ -190,71 +193,71 @@ fn write_call_store(result: Range, w: &mut dyn Write) -> Result<()> { write!(w, " = ") } -impl Driver for Call { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for Call { + fn write(&self, w: &mut dyn Write) -> Result<()> { write_call_store(self.result(), w)?; write!(w, "FUNC_LIST[{}](", self.function())?; - self.param_list().write(mng, w)?; + self.param_list().write(w)?; write!(w, ")") } } -impl Driver for CallIndirect { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for CallIndirect { + fn write(&self, w: &mut dyn Write) -> Result<()> { write_call_store(self.result(), w)?; write!(w, "TABLE_LIST[{}].data[", self.table())?; - self.index().write(mng, w)?; + self.index().write(w)?; write!(w, "](")?; - self.param_list().write(mng, w)?; + self.param_list().write(w)?; write!(w, ")") } } -impl Driver for SetTemporary { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for SetTemporary { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "reg_{} = ", self.var())?; - self.value().write(mng, w) + self.value().write(w) } } -impl Driver for SetLocal { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for SetLocal { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "loc_{} = ", self.var())?; - self.value().write(mng, w) + self.value().write(w) } } -impl Driver for SetGlobal { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for SetGlobal { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "GLOBAL_LIST[{}].value = ", self.var())?; - self.value().write(mng, w) + self.value().write(w) } } -impl Driver for StoreAt { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for StoreAt { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "store_{}(memory_at_0, ", self.store_type().as_name())?; - self.pointer().write(mng, w)?; + self.pointer().write(w)?; if self.offset() != 0 { write!(w, "+ {}", self.offset())?; } write!(w, ", ")?; - self.value().write(mng, w)?; + self.value().write(w)?; write!(w, ")") } } -impl Driver for MemoryGrow { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for MemoryGrow { + fn write(&self, w: &mut dyn Write) -> Result<()> { let result = self.result(); let memory = self.memory(); write!(w, "reg_{result} = rt.allocator.grow(memory_at_{memory}, ")?; - self.size().write(mng, w)?; + self.size().write(w)?; write!(w, ")") } } @@ -265,13 +268,13 @@ impl Driver for Statement { Self::Block(s) => s.write(mng, w), Self::BrIf(s) => s.write(mng, w), Self::If(s) => s.write(mng, w), - Self::Call(s) => s.write(mng, w), - Self::CallIndirect(s) => s.write(mng, w), - Self::SetTemporary(s) => s.write(mng, w), - Self::SetLocal(s) => s.write(mng, w), - Self::SetGlobal(s) => s.write(mng, w), - Self::StoreAt(s) => s.write(mng, w), - Self::MemoryGrow(s) => s.write(mng, w), + Self::Call(s) => s.write(w), + Self::CallIndirect(s) => s.write(w), + Self::SetTemporary(s) => s.write(w), + Self::SetLocal(s) => s.write(w), + Self::SetGlobal(s) => s.write(w), + Self::StoreAt(s) => s.write(w), + Self::MemoryGrow(s) => s.write(w), } } } diff --git a/codegen/luajit/src/translator.rs b/codegen/luajit/src/translator.rs index 343770f..13d3905 100644 --- a/codegen/luajit/src/translator.rs +++ b/codegen/luajit/src/translator.rs @@ -15,7 +15,7 @@ use wasmparser::{ use crate::{ analyzer::localize, - backend::manager::{Driver, Manager}, + backend::manager::{Driver, DriverNoContext, Manager}, }; trait AsIEName { @@ -54,7 +54,7 @@ fn write_constant(init: &InitExpr, type_info: &TypeInfo, w: &mut dyn Write) -> R let func = Factory::from_type_info(type_info).create_anonymous(&code); if let Some(Statement::SetTemporary(stat)) = func.code().code().last() { - stat.value().write(&mut Manager::default(), w) + stat.value().write(w) } else { write!(w, r#"error("Valueless constant")"#) } diff --git a/codegen/luau/src/backend/expression.rs b/codegen/luau/src/backend/expression.rs index 77662bf..b65a245 100644 --- a/codegen/luau/src/backend/expression.rs +++ b/codegen/luau/src/backend/expression.rs @@ -10,7 +10,7 @@ use wasm_ast::node::{ use crate::analyzer::as_symbol::AsSymbol; -use super::manager::{write_cmp_op, write_condition, write_separated, Driver, Manager}; +use super::manager::{write_separated, DriverNoContext}; macro_rules! impl_write_number { ($name:tt, $numeric:ty) => { @@ -26,40 +26,40 @@ macro_rules! impl_write_number { }; } -impl Driver for Select { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for Select { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "(")?; - write_condition(self.condition(), mng, w)?; + Condition(self.condition()).write(w)?; write!(w, "and ")?; - self.on_true().write(mng, w)?; + self.on_true().write(w)?; write!(w, "or ")?; - self.on_false().write(mng, w)?; + self.on_false().write(w)?; write!(w, ")") } } -impl Driver for GetTemporary { - fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for GetTemporary { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "reg_{} ", self.var()) } } -impl Driver for GetLocal { - fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for GetLocal { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "loc_{} ", self.var()) } } -impl Driver for GetGlobal { - fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for GetGlobal { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "GLOBAL_LIST[{}].value ", self.var()) } } -impl Driver for LoadAt { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for LoadAt { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "load_{}(memory_at_0, ", self.load_type().as_name())?; - self.pointer().write(mng, w)?; + self.pointer().write(w)?; if self.offset() != 0 { write!(w, "+ {}", self.offset())?; @@ -69,8 +69,8 @@ impl Driver for LoadAt { } } -impl Driver for MemorySize { - fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for MemorySize { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "memory_at_{}.min ", self.memory()) } } @@ -98,8 +98,8 @@ fn write_i64(number: i64, w: &mut dyn Write) -> Result<()> { impl_write_number!(write_f32, f32); impl_write_number!(write_f64, f64); -impl Driver for Value { - fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for Value { + fn write(&self, w: &mut dyn Write) -> Result<()> { match self { Self::I32(i) => write_i32(*i, w), Self::I64(i) => write_i64(*i, w), @@ -109,63 +109,98 @@ impl Driver for Value { } } -impl Driver for UnOp { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for UnOp { + fn write(&self, w: &mut dyn Write) -> Result<()> { let (a, b) = self.op_type().as_name(); write!(w, "{a}_{b}(")?; - self.rhs().write(mng, w)?; + self.rhs().write(w)?; write!(w, ")") } } -impl Driver for BinOp { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for BinOp { + fn write(&self, w: &mut dyn Write) -> Result<()> { if let Some(symbol) = self.op_type().as_symbol() { write!(w, "(")?; - self.lhs().write(mng, w)?; + self.lhs().write(w)?; write!(w, "{symbol} ")?; - self.rhs().write(mng, w)?; + self.rhs().write(w)?; write!(w, ")") } else { let (head, tail) = self.op_type().as_name(); write!(w, "{head}_{tail}(")?; - self.lhs().write(mng, w)?; + self.lhs().write(w)?; write!(w, ", ")?; - self.rhs().write(mng, w)?; + self.rhs().write(w)?; write!(w, ")") } } } -impl Driver for CmpOp { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { - write!(w, "(")?; - write_cmp_op(self, mng, w)?; - write!(w, "and 1 or 0)") - } -} +struct CmpOpBoolean<'a>(&'a CmpOp); -impl Driver for Expression { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { - match self { - Self::Select(e) => e.write(mng, w), - Self::GetTemporary(e) => e.write(mng, w), - Self::GetLocal(e) => e.write(mng, w), - Self::GetGlobal(e) => e.write(mng, w), - Self::LoadAt(e) => e.write(mng, w), - Self::MemorySize(e) => e.write(mng, w), - Self::Value(e) => e.write(mng, w), - Self::UnOp(e) => e.write(mng, w), - Self::BinOp(e) => e.write(mng, w), - Self::CmpOp(e) => e.write(mng, w), +impl DriverNoContext for CmpOpBoolean<'_> { + fn write(&self, w: &mut dyn Write) -> Result<()> { + let cmp = self.0; + + if let Some(symbol) = cmp.op_type().as_symbol() { + cmp.lhs().write(w)?; + write!(w, "{symbol} ")?; + cmp.rhs().write(w) + } else { + let (head, tail) = cmp.op_type().as_name(); + + write!(w, "{head}_{tail}(")?; + cmp.lhs().write(w)?; + write!(w, ", ")?; + cmp.rhs().write(w)?; + write!(w, ")") } } } -impl Driver for &[Expression] { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { - write_separated(self.iter(), |e, w| e.write(mng, w), w) +impl DriverNoContext for CmpOp { + fn write(&self, w: &mut dyn Write) -> Result<()> { + write!(w, "(")?; + CmpOpBoolean(self).write(w)?; + write!(w, "and 1 or 0)") + } +} + +pub struct Condition<'a>(pub &'a Expression); + +impl DriverNoContext for Condition<'_> { + fn write(&self, w: &mut dyn Write) -> Result<()> { + if let Expression::CmpOp(node) = self.0 { + CmpOpBoolean(node).write(w) + } else { + self.0.write(w)?; + write!(w, "~= 0 ") + } + } +} + +impl DriverNoContext for Expression { + fn write(&self, w: &mut dyn Write) -> Result<()> { + match self { + Self::Select(e) => e.write(w), + Self::GetTemporary(e) => e.write(w), + Self::GetLocal(e) => e.write(w), + Self::GetGlobal(e) => e.write(w), + Self::LoadAt(e) => e.write(w), + Self::MemorySize(e) => e.write(w), + Self::Value(e) => e.write(w), + Self::UnOp(e) => e.write(w), + Self::BinOp(e) => e.write(w), + Self::CmpOp(e) => e.write(w), + } + } +} + +impl DriverNoContext for &[Expression] { + fn write(&self, w: &mut dyn Write) -> Result<()> { + write_separated(self.iter(), |e, w| e.write(w), w) } } diff --git a/codegen/luau/src/backend/manager.rs b/codegen/luau/src/backend/manager.rs index 7927e34..5212525 100644 --- a/codegen/luau/src/backend/manager.rs +++ b/codegen/luau/src/backend/manager.rs @@ -4,9 +4,7 @@ use std::{ ops::Range, }; -use wasm_ast::node::{BrTable, CmpOp, Expression, LabelType}; - -use crate::analyzer::as_symbol::AsSymbol; +use wasm_ast::node::{BrTable, LabelType}; #[derive(Default)] pub struct Manager { @@ -42,6 +40,10 @@ pub trait Driver { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()>; } +pub trait DriverNoContext { + fn write(&self, w: &mut dyn Write) -> Result<()>; +} + pub fn write_separated(mut iter: I, mut func: M, w: &mut dyn Write) -> Result<()> where M: FnMut(T, &mut dyn Write) -> Result<()>, @@ -61,28 +63,3 @@ where pub fn write_ascending(prefix: &str, range: Range, w: &mut dyn Write) -> Result<()> { write_separated(range, |i, w| write!(w, "{prefix}_{i}"), w) } - -pub fn write_cmp_op(cmp: &CmpOp, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { - if let Some(symbol) = cmp.op_type().as_symbol() { - cmp.lhs().write(mng, w)?; - write!(w, "{symbol} ")?; - cmp.rhs().write(mng, w) - } else { - let (head, tail) = cmp.op_type().as_name(); - - write!(w, "{head}_{tail}(")?; - cmp.lhs().write(mng, w)?; - write!(w, ", ")?; - cmp.rhs().write(mng, w)?; - write!(w, ")") - } -} - -pub fn write_condition(data: &Expression, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { - if let Expression::CmpOp(node) = data { - write_cmp_op(node, mng, w) - } else { - data.write(mng, w)?; - write!(w, "~= 0 ") - } -} diff --git a/codegen/luau/src/backend/statement.rs b/codegen/luau/src/backend/statement.rs index cc4661c..0d4a8e3 100644 --- a/codegen/luau/src/backend/statement.rs +++ b/codegen/luau/src/backend/statement.rs @@ -11,7 +11,10 @@ use wasmparser::ValType; use crate::analyzer::br_target; -use super::manager::{write_ascending, write_condition, write_separated, Driver, Manager}; +use super::{ + expression::Condition, + manager::{write_ascending, write_separated, Driver, DriverNoContext, Manager}, +}; impl Driver for Br { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { @@ -90,7 +93,7 @@ fn write_table_setup(table: &BrTable, mng: &mut Manager, w: &mut dyn Write) -> R write!(w, "end ")?; write!(w, "local temp = br_map[{id}][")?; - table.condition().write(mng, w)?; + table.condition().write(w)?; write!(w, "] or {} ", table.default().target()) } @@ -170,7 +173,7 @@ impl Driver for Block { impl Driver for BrIf { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { write!(w, "if ")?; - write_condition(self.condition(), mng, w)?; + Condition(self.condition()).write(w)?; write!(w, "then ")?; self.target().write(mng, w)?; write!(w, "end ") @@ -180,7 +183,7 @@ impl Driver for BrIf { impl Driver for If { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { write!(w, "if ")?; - write_condition(self.condition(), mng, w)?; + Condition(self.condition()).write(w)?; write!(w, "then ")?; self.on_true().write(mng, w)?; @@ -204,71 +207,71 @@ fn write_call_store(result: Range, w: &mut dyn Write) -> Result<()> { write!(w, " = ") } -impl Driver for Call { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for Call { + fn write(&self, w: &mut dyn Write) -> Result<()> { write_call_store(self.result(), w)?; write!(w, "FUNC_LIST[{}](", self.function())?; - self.param_list().write(mng, w)?; + self.param_list().write(w)?; write!(w, ")") } } -impl Driver for CallIndirect { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for CallIndirect { + fn write(&self, w: &mut dyn Write) -> Result<()> { write_call_store(self.result(), w)?; write!(w, "TABLE_LIST[{}].data[", self.table())?; - self.index().write(mng, w)?; + self.index().write(w)?; write!(w, "](")?; - self.param_list().write(mng, w)?; + self.param_list().write(w)?; write!(w, ")") } } -impl Driver for SetTemporary { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for SetTemporary { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "reg_{} = ", self.var())?; - self.value().write(mng, w) + self.value().write(w) } } -impl Driver for SetLocal { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for SetLocal { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "loc_{} = ", self.var())?; - self.value().write(mng, w) + self.value().write(w) } } -impl Driver for SetGlobal { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for SetGlobal { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "GLOBAL_LIST[{}].value = ", self.var())?; - self.value().write(mng, w) + self.value().write(w) } } -impl Driver for StoreAt { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for StoreAt { + fn write(&self, w: &mut dyn Write) -> Result<()> { write!(w, "store_{}(memory_at_0, ", self.store_type().as_name())?; - self.pointer().write(mng, w)?; + self.pointer().write(w)?; if self.offset() != 0 { write!(w, "+ {}", self.offset())?; } write!(w, ", ")?; - self.value().write(mng, w)?; + self.value().write(w)?; write!(w, ")") } } -impl Driver for MemoryGrow { - fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { +impl DriverNoContext for MemoryGrow { + fn write(&self, w: &mut dyn Write) -> Result<()> { let result = self.result(); let memory = self.memory(); write!(w, "reg_{result} = rt.allocator.grow(memory_at_{memory}, ")?; - self.size().write(mng, w)?; + self.size().write(w)?; write!(w, ")") } } @@ -279,13 +282,13 @@ impl Driver for Statement { Self::Block(s) => s.write(mng, w), Self::BrIf(s) => s.write(mng, w), Self::If(s) => s.write(mng, w), - Self::Call(s) => s.write(mng, w), - Self::CallIndirect(s) => s.write(mng, w), - Self::SetTemporary(s) => s.write(mng, w), - Self::SetLocal(s) => s.write(mng, w), - Self::SetGlobal(s) => s.write(mng, w), - Self::StoreAt(s) => s.write(mng, w), - Self::MemoryGrow(s) => s.write(mng, w), + Self::Call(s) => s.write(w), + Self::CallIndirect(s) => s.write(w), + Self::SetTemporary(s) => s.write(w), + Self::SetLocal(s) => s.write(w), + Self::SetGlobal(s) => s.write(w), + Self::StoreAt(s) => s.write(w), + Self::MemoryGrow(s) => s.write(w), } } } diff --git a/codegen/luau/src/translator.rs b/codegen/luau/src/translator.rs index b0b7b2d..0a7800c 100644 --- a/codegen/luau/src/translator.rs +++ b/codegen/luau/src/translator.rs @@ -15,7 +15,7 @@ use wasmparser::{ use crate::{ analyzer::localize, - backend::manager::{Driver, Manager}, + backend::manager::{Driver, DriverNoContext, Manager}, }; trait AsIEName { @@ -54,7 +54,7 @@ fn write_constant(init: &InitExpr, type_info: &TypeInfo, w: &mut dyn Write) -> R let func = Factory::from_type_info(type_info).create_anonymous(&code); if let Some(Statement::SetTemporary(stat)) = func.code().code().last() { - stat.value().write(&mut Manager::default(), w) + stat.value().write(w) } else { write!(w, r#"error("Valueless constant")"#) }