Encapsulate nodes

This commit is contained in:
Rerumu 2022-06-23 16:03:13 -04:00
parent b282bdf490
commit 9db21cc84b
14 changed files with 636 additions and 306 deletions

View File

@ -14,51 +14,51 @@ struct Visit {
impl Visitor for Visit { impl Visitor for Visit {
fn visit_load_at(&mut self, v: &LoadAt) { fn visit_load_at(&mut self, v: &LoadAt) {
let name = v.what.as_name(); let name = v.load_type().as_name();
self.memory_set.insert(0); self.memory_set.insert(0);
self.local_set.insert(("load", name)); self.local_set.insert(("load", name));
} }
fn visit_store_at(&mut self, v: &StoreAt) { fn visit_store_at(&mut self, v: &StoreAt) {
let name = v.what.as_name(); let name = v.store_type().as_name();
self.memory_set.insert(0); self.memory_set.insert(0);
self.local_set.insert(("store", name)); self.local_set.insert(("store", name));
} }
fn visit_un_op(&mut self, v: &UnOp) { fn visit_un_op(&mut self, v: &UnOp) {
let name = v.op.as_name(); let name = v.op_type().as_name();
self.local_set.insert(name); self.local_set.insert(name);
} }
fn visit_bin_op(&mut self, v: &BinOp) { fn visit_bin_op(&mut self, v: &BinOp) {
if bin_symbol_of(v.op).is_some() { if bin_symbol_of(v.op_type()).is_some() {
return; return;
} }
let name = v.op.as_name(); let name = v.op_type().as_name();
self.local_set.insert(name); self.local_set.insert(name);
} }
fn visit_cmp_op(&mut self, v: &CmpOp) { fn visit_cmp_op(&mut self, v: &CmpOp) {
if cmp_symbol_of(v.op).is_some() { if cmp_symbol_of(v.op_type()).is_some() {
return; return;
} }
let name = v.op.as_name(); let name = v.op_type().as_name();
self.local_set.insert(name); self.local_set.insert(name);
} }
fn visit_memory_size(&mut self, m: &MemorySize) { fn visit_memory_size(&mut self, m: &MemorySize) {
self.memory_set.insert(m.memory); self.memory_set.insert(m.memory());
} }
fn visit_memory_grow(&mut self, m: &MemoryGrow) { fn visit_memory_grow(&mut self, m: &MemoryGrow) {
self.memory_set.insert(m.memory); self.memory_set.insert(m.memory());
} }
} }

View File

@ -31,40 +31,40 @@ macro_rules! impl_write_number {
impl Driver for Select { impl Driver for Select {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "(")?; write!(w, "(")?;
write_condition(&self.cond, mng, w)?; write_condition(self.condition(), mng, w)?;
write!(w, "and ")?; write!(w, "and ")?;
self.a.write(mng, w)?; self.on_true().write(mng, w)?;
write!(w, "or ")?; write!(w, "or ")?;
self.b.write(mng, w)?; self.on_false().write(mng, w)?;
write!(w, ")") write!(w, ")")
} }
} }
impl Driver for GetTemporary { impl Driver for GetTemporary {
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "reg_{} ", self.var) write!(w, "reg_{} ", self.var())
} }
} }
impl Driver for GetLocal { impl Driver for GetLocal {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write_variable(self.var, mng, w) write_variable(self.var(), mng, w)
} }
} }
impl Driver for GetGlobal { impl Driver for GetGlobal {
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "GLOBAL_LIST[{}].value ", self.var) write!(w, "GLOBAL_LIST[{}].value ", self.var())
} }
} }
impl Driver for LoadAt { impl Driver for LoadAt {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "load_{}(memory_at_0, ", self.what.as_name())?; write!(w, "load_{}(memory_at_0, ", self.load_type().as_name())?;
self.pointer.write(mng, w)?; self.pointer().write(mng, w)?;
if self.offset != 0 { if self.offset() != 0 {
write!(w, "+ {}", self.offset)?; write!(w, "+ {}", self.offset())?;
} }
write!(w, ")") write!(w, ")")
@ -73,7 +73,7 @@ impl Driver for LoadAt {
impl Driver for MemorySize { impl Driver for MemorySize {
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "memory_at_{}.min ", self.memory) write!(w, "memory_at_{}.min ", self.memory())
} }
} }
@ -93,29 +93,29 @@ impl Driver for Value {
impl Driver for UnOp { impl Driver for UnOp {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
let (a, b) = self.op.as_name(); let (a, b) = self.op_type().as_name();
write!(w, "{a}_{b}(")?; write!(w, "{a}_{b}(")?;
self.rhs.write(mng, w)?; self.rhs().write(mng, w)?;
write!(w, ")") write!(w, ")")
} }
} }
impl Driver for BinOp { impl Driver for BinOp {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
if let Some(symbol) = bin_symbol_of(self.op) { if let Some(symbol) = bin_symbol_of(self.op_type()) {
write!(w, "(")?; write!(w, "(")?;
self.lhs.write(mng, w)?; self.lhs().write(mng, w)?;
write!(w, "{symbol} ")?; write!(w, "{symbol} ")?;
self.rhs.write(mng, w)?; self.rhs().write(mng, w)?;
write!(w, ")") write!(w, ")")
} else { } else {
let (head, tail) = self.op.as_name(); let (head, tail) = self.op_type().as_name();
write!(w, "{head}_{tail}(")?; write!(w, "{head}_{tail}(")?;
self.lhs.write(mng, w)?; self.lhs().write(mng, w)?;
write!(w, ", ")?; write!(w, ", ")?;
self.rhs.write(mng, w)?; self.rhs().write(mng, w)?;
write!(w, ")") write!(w, ")")
} }
} }

View File

@ -80,17 +80,17 @@ pub fn write_variable(var: usize, mng: &Manager, w: &mut dyn Write) -> Result<()
} }
pub fn write_cmp_op(cmp: &CmpOp, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { pub fn write_cmp_op(cmp: &CmpOp, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
if let Some(symbol) = cmp_symbol_of(cmp.op) { if let Some(symbol) = cmp_symbol_of(cmp.op_type()) {
cmp.lhs.write(mng, w)?; cmp.lhs().write(mng, w)?;
write!(w, "{symbol} ")?; write!(w, "{symbol} ")?;
cmp.rhs.write(mng, w) cmp.rhs().write(mng, w)
} else { } else {
let (head, tail) = cmp.op.as_name(); let (head, tail) = cmp.op_type().as_name();
write!(w, "{head}_{tail}(")?; write!(w, "{head}_{tail}(")?;
cmp.lhs.write(mng, w)?; cmp.lhs().write(mng, w)?;
write!(w, ", ")?; write!(w, ", ")?;
cmp.rhs.write(mng, w)?; cmp.rhs().write(mng, w)?;
write!(w, ")") write!(w, ")")
} }
} }

View File

@ -17,12 +17,12 @@ use super::manager::{
impl Driver for Br { impl Driver for Br {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
let level = *mng.label_list().iter().nth_back(self.target).unwrap(); let level = *mng.label_list().iter().nth_back(self.target()).unwrap();
if !self.align.is_aligned() { if !self.align().is_aligned() {
write_ascending("reg", self.align.new_range(), w)?; write_ascending("reg", self.align().new_range(), w)?;
write!(w, " = ")?; write!(w, " = ")?;
write_ascending("reg", self.align.old_range(), w)?; write_ascending("reg", self.align().old_range(), w)?;
write!(w, " ")?; write!(w, " ")?;
} }
@ -33,8 +33,8 @@ impl Driver for Br {
fn to_ordered_table<'a>(list: &'a [Br], default: &'a Br) -> Vec<&'a Br> { fn to_ordered_table<'a>(list: &'a [Br], default: &'a Br) -> Vec<&'a Br> {
let mut data: Vec<_> = list.iter().chain(std::iter::once(default)).collect(); let mut data: Vec<_> = list.iter().chain(std::iter::once(default)).collect();
data.sort_by_key(|v| v.target); data.sort_by_key(|v| v.target());
data.dedup_by_key(|v| v.target); data.dedup_by_key(|v| v.target());
data data
} }
@ -53,13 +53,13 @@ fn write_search_layer(
let br = list[center]; let br = list[center];
if range.start != center { if range.start != center {
write!(w, "if temp < {} then ", br.target)?; write!(w, "if temp < {} then ", br.target())?;
write_search_layer(range.start..center, list, mng, w)?; write_search_layer(range.start..center, list, mng, w)?;
write!(w, "else")?; write!(w, "else")?;
} }
if range.end != center + 1 { if range.end != center + 1 {
write!(w, "if temp > {} then ", br.target)?; write!(w, "if temp > {} then ", br.target())?;
write_search_layer(center + 1..range.end, list, mng, w)?; write_search_layer(center + 1..range.end, list, mng, w)?;
write!(w, "else")?; write!(w, "else")?;
} }
@ -76,31 +76,31 @@ fn write_table_setup(table: &BrTable, mng: &mut Manager, w: &mut dyn Write) -> R
write!(w, "br_map[{id}] = (function() return {{[0] =")?; write!(w, "br_map[{id}] = (function() return {{[0] =")?;
table table
.data .data()
.iter() .iter()
.try_for_each(|v| write!(w, "{},", v.target))?; .try_for_each(|v| write!(w, "{},", v.target()))?;
write!(w, "}} end)()")?; write!(w, "}} end)()")?;
write!(w, "end ")?; write!(w, "end ")?;
write!(w, "temp = br_map[{id}][")?; write!(w, "temp = br_map[{id}][")?;
table.cond.write(mng, w)?; table.condition().write(mng, w)?;
write!(w, "] or {} ", table.default.target) write!(w, "] or {} ", table.default().target())
} }
impl Driver for BrTable { impl Driver for BrTable {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
if self.data.is_empty() { if self.data().is_empty() {
// Our condition should be pure so we probably don't need // Our condition should be pure so we probably don't need
// to emit it in this case. // to emit it in this case.
return self.default.write(mng, w); return self.default().write(mng, w);
} }
// `BrTable` is optimized by first mapping all indices to targets through // `BrTable` is optimized by first mapping all indices to targets through
// a Lua table; this reduces the size of the code generated as duplicate entries // a Lua table; this reduces the size of the code generated as duplicate entries
// don't need checking. Then, for speed, a binary search is done for the target // don't need checking. Then, for speed, a binary search is done for the target
// and the appropriate jump is performed. // and the appropriate jump is performed.
let list = to_ordered_table(&self.data, &self.default); let list = to_ordered_table(self.data(), self.default());
write_table_setup(self, mng, w)?; write_table_setup(self, mng, w)?;
write_search_layer(0..list.len(), &list, mng, w) write_search_layer(0..list.len(), &list, mng, w)
@ -121,9 +121,9 @@ impl Driver for Forward {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
let label = mng.push_label(); let label = mng.push_label();
self.code.iter().try_for_each(|s| s.write(mng, w))?; self.code().iter().try_for_each(|s| s.write(mng, w))?;
if let Some(v) = &self.last { if let Some(v) = self.last() {
v.write(mng, w)?; v.write(mng, w)?;
} }
@ -142,9 +142,9 @@ impl Driver for Backward {
write!(w, "::continue_at_{label}::")?; write!(w, "::continue_at_{label}::")?;
write!(w, "while true do ")?; write!(w, "while true do ")?;
self.code.iter().try_for_each(|s| s.write(mng, w))?; self.code().iter().try_for_each(|s| s.write(mng, w))?;
if let Some(v) = &self.last { if let Some(v) = self.last() {
v.write(mng, w)?; v.write(mng, w)?;
} else { } else {
write!(w, "break ")?; write!(w, "break ")?;
@ -161,9 +161,9 @@ impl Driver for Backward {
impl Driver for BrIf { impl Driver for BrIf {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "if ")?; write!(w, "if ")?;
write_condition(&self.cond, mng, w)?; write_condition(self.condition(), mng, w)?;
write!(w, "then ")?; write!(w, "then ")?;
self.target.write(mng, w)?; self.target().write(mng, w)?;
write!(w, "end ") write!(w, "end ")
} }
} }
@ -171,15 +171,15 @@ impl Driver for BrIf {
impl Driver for If { impl Driver for If {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "if ")?; write!(w, "if ")?;
write_condition(&self.cond, mng, w)?; write_condition(self.condition(), mng, w)?;
write!(w, "then ")?; write!(w, "then ")?;
self.truthy.write(mng, w)?; self.on_true().write(mng, w)?;
if let Some(falsey) = &self.falsey { if let Some(v) = self.on_false() {
write!(w, "else ")?; write!(w, "else ")?;
falsey.write(mng, w)?; v.write(mng, w)?;
} }
write!(w, "end ") write!(w, "end ")
@ -197,70 +197,70 @@ fn write_call_store(result: Range<usize>, w: &mut dyn Write) -> Result<()> {
impl Driver for Call { impl Driver for Call {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write_call_store(self.result.clone(), w)?; write_call_store(self.result(), w)?;
write!(w, "FUNC_LIST[{}](", self.func)?; write!(w, "FUNC_LIST[{}](", self.function())?;
self.param_list.as_slice().write(mng, w)?; self.param_list().write(mng, w)?;
write!(w, ")") write!(w, ")")
} }
} }
impl Driver for CallIndirect { impl Driver for CallIndirect {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write_call_store(self.result.clone(), w)?; write_call_store(self.result(), w)?;
write!(w, "TABLE_LIST[{}].data[", self.table)?; write!(w, "TABLE_LIST[{}].data[", self.table())?;
self.index.write(mng, w)?; self.index().write(mng, w)?;
write!(w, "](")?; write!(w, "](")?;
self.param_list.as_slice().write(mng, w)?; self.param_list().write(mng, w)?;
write!(w, ")") write!(w, ")")
} }
} }
impl Driver for SetTemporary { impl Driver for SetTemporary {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "reg_{} = ", self.var)?; write!(w, "reg_{} = ", self.var())?;
self.value.write(mng, w) self.value().write(mng, w)
} }
} }
impl Driver for SetLocal { impl Driver for SetLocal {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write_variable(self.var, mng, w)?; write_variable(self.var(), mng, w)?;
write!(w, "= ")?; write!(w, "= ")?;
self.value.write(mng, w) self.value().write(mng, w)
} }
} }
impl Driver for SetGlobal { impl Driver for SetGlobal {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "GLOBAL_LIST[{}].value = ", self.var)?; write!(w, "GLOBAL_LIST[{}].value = ", self.var())?;
self.value.write(mng, w) self.value().write(mng, w)
} }
} }
impl Driver for StoreAt { impl Driver for StoreAt {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "store_{}(memory_at_0, ", self.what.as_name())?; write!(w, "store_{}(memory_at_0, ", self.store_type().as_name())?;
self.pointer.write(mng, w)?; self.pointer().write(mng, w)?;
if self.offset != 0 { if self.offset() != 0 {
write!(w, "+ {}", self.offset)?; write!(w, "+ {}", self.offset())?;
} }
write!(w, ", ")?; write!(w, ", ")?;
self.value.write(mng, w)?; self.value().write(mng, w)?;
write!(w, ")") write!(w, ")")
} }
} }
impl Driver for MemoryGrow { impl Driver for MemoryGrow {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
let result = self.result; let result = self.result();
let memory = self.memory; let memory = self.memory();
write!(w, "reg_{result} = rt.allocator.grow(memory_at_{memory}, ")?; write!(w, "reg_{result} = rt.allocator.grow(memory_at_{memory}, ")?;
self.value.write(mng, w)?; self.size().write(mng, w)?;
write!(w, ")") write!(w, ")")
} }
} }
@ -285,14 +285,14 @@ impl Driver for Statement {
fn write_parameter_list(ast: &FuncData, w: &mut dyn Write) -> Result<()> { fn write_parameter_list(ast: &FuncData, w: &mut dyn Write) -> Result<()> {
write!(w, "function(")?; write!(w, "function(")?;
write_ascending("param", 0..ast.num_param, w)?; write_ascending("param", 0..ast.num_param(), w)?;
write!(w, ")") write!(w, ")")
} }
fn write_variable_list(ast: &FuncData, w: &mut dyn Write) -> Result<()> { fn write_variable_list(ast: &FuncData, w: &mut dyn Write) -> Result<()> {
let mut total = 0; let mut total = 0;
for data in ast.local_data.iter().filter(|v| v.count() != 0) { for data in ast.local_data().iter().filter(|v| v.count() != 0) {
let range = total..total + usize::try_from(data.count()).unwrap(); let range = total..total + usize::try_from(data.count()).unwrap();
let typed = if data.value_type() == ValueType::I64 { let typed = if data.value_type() == ValueType::I64 {
"0LL" "0LL"
@ -310,9 +310,9 @@ fn write_variable_list(ast: &FuncData, w: &mut dyn Write) -> Result<()> {
write!(w, " ")?; write!(w, " ")?;
} }
if ast.num_stack != 0 { if ast.num_stack() != 0 {
write!(w, "local ")?; write!(w, "local ")?;
write_ascending("reg", 0..ast.num_stack, w)?; write_ascending("reg", 0..ast.num_stack(), w)?;
write!(w, " ")?; write!(w, " ")?;
} }
@ -331,12 +331,12 @@ impl Driver for FuncData {
} }
mng.set_table_map(br_map); mng.set_table_map(br_map);
mng.set_num_param(self.num_param); mng.set_num_param(self.num_param());
self.code.write(mng, w)?; self.code().write(mng, w)?;
if self.num_result != 0 { if self.num_result() != 0 {
write!(w, "return ")?; write!(w, "return ")?;
write_ascending("reg", 0..self.num_result, w)?; write_ascending("reg", 0..self.num_result(), w)?;
write!(w, " ")?; write!(w, " ")?;
} }

View File

@ -51,8 +51,8 @@ fn write_named_array(name: &str, len: usize, w: &mut dyn Write) -> Result<()> {
fn write_constant(code: &[Instruction], type_info: &TypeInfo, w: &mut dyn Write) -> Result<()> { fn write_constant(code: &[Instruction], type_info: &TypeInfo, w: &mut dyn Write) -> Result<()> {
let func = Builder::from_type_info(type_info).build_anonymous(code); let func = Builder::from_type_info(type_info).build_anonymous(code);
if let Some(Statement::SetTemporary(stat)) = func.code.code.last() { if let Some(Statement::SetTemporary(stat)) = func.code().code().last() {
stat.value.write(&mut Manager::default(), w)?; stat.value().write(&mut Manager::default(), w)?;
} else { } else {
panic!("Not a valid constant"); panic!("Not a valid constant");
} }

View File

@ -15,14 +15,14 @@ struct Visit {
impl Visitor for Visit { impl Visitor for Visit {
fn visit_load_at(&mut self, v: &LoadAt) { fn visit_load_at(&mut self, v: &LoadAt) {
let name = v.what.as_name(); let name = v.load_type().as_name();
self.memory_set.insert(0); self.memory_set.insert(0);
self.local_set.insert(("load", name)); self.local_set.insert(("load", name));
} }
fn visit_store_at(&mut self, v: &StoreAt) { fn visit_store_at(&mut self, v: &StoreAt) {
let name = v.what.as_name(); let name = v.store_type().as_name();
self.memory_set.insert(0); self.memory_set.insert(0);
self.local_set.insert(("store", name)); self.local_set.insert(("store", name));
@ -40,37 +40,37 @@ impl Visitor for Visit {
} }
fn visit_un_op(&mut self, v: &UnOp) { fn visit_un_op(&mut self, v: &UnOp) {
let name = v.op.as_name(); let name = v.op_type().as_name();
self.local_set.insert(name); self.local_set.insert(name);
} }
fn visit_bin_op(&mut self, v: &BinOp) { fn visit_bin_op(&mut self, v: &BinOp) {
if bin_symbol_of(v.op).is_some() { if bin_symbol_of(v.op_type()).is_some() {
return; return;
} }
let name = v.op.as_name(); let name = v.op_type().as_name();
self.local_set.insert(name); self.local_set.insert(name);
} }
fn visit_cmp_op(&mut self, v: &CmpOp) { fn visit_cmp_op(&mut self, v: &CmpOp) {
if cmp_symbol_of(v.op).is_some() { if cmp_symbol_of(v.op_type()).is_some() {
return; return;
} }
let name = v.op.as_name(); let name = v.op_type().as_name();
self.local_set.insert(name); self.local_set.insert(name);
} }
fn visit_memory_size(&mut self, m: &MemorySize) { fn visit_memory_size(&mut self, m: &MemorySize) {
self.memory_set.insert(m.memory); self.memory_set.insert(m.memory());
} }
fn visit_memory_grow(&mut self, m: &MemoryGrow) { fn visit_memory_grow(&mut self, m: &MemoryGrow) {
self.memory_set.insert(m.memory); self.memory_set.insert(m.memory());
} }
} }
@ -81,7 +81,7 @@ pub fn visit(ast: &FuncData) -> (BTreeSet<(&'static str, &'static str)>, BTreeSe
}; };
if ast if ast
.local_data .local_data()
.iter() .iter()
.any(|v| v.value_type() == ValueType::I64) .any(|v| v.value_type() == ValueType::I64)
{ {

View File

@ -31,40 +31,40 @@ macro_rules! impl_write_number {
impl Driver for Select { impl Driver for Select {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "(")?; write!(w, "(")?;
write_condition(&self.cond, mng, w)?; write_condition(self.condition(), mng, w)?;
write!(w, "and ")?; write!(w, "and ")?;
self.a.write(mng, w)?; self.on_true().write(mng, w)?;
write!(w, "or ")?; write!(w, "or ")?;
self.b.write(mng, w)?; self.on_false().write(mng, w)?;
write!(w, ")") write!(w, ")")
} }
} }
impl Driver for GetTemporary { impl Driver for GetTemporary {
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "reg_{} ", self.var) write!(w, "reg_{} ", self.var())
} }
} }
impl Driver for GetLocal { impl Driver for GetLocal {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write_variable(self.var, mng, w) write_variable(self.var(), mng, w)
} }
} }
impl Driver for GetGlobal { impl Driver for GetGlobal {
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "GLOBAL_LIST[{}].value ", self.var) write!(w, "GLOBAL_LIST[{}].value ", self.var())
} }
} }
impl Driver for LoadAt { impl Driver for LoadAt {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "load_{}(memory_at_0, ", self.what.as_name())?; write!(w, "load_{}(memory_at_0, ", self.load_type().as_name())?;
self.pointer.write(mng, w)?; self.pointer().write(mng, w)?;
if self.offset != 0 { if self.offset() != 0 {
write!(w, "+ {}", self.offset)?; write!(w, "+ {}", self.offset())?;
} }
write!(w, ")") write!(w, ")")
@ -73,7 +73,7 @@ impl Driver for LoadAt {
impl Driver for MemorySize { impl Driver for MemorySize {
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "memory_at_{}.min ", self.memory) write!(w, "memory_at_{}.min ", self.memory())
} }
} }
@ -113,29 +113,29 @@ impl Driver for Value {
impl Driver for UnOp { impl Driver for UnOp {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
let (a, b) = self.op.as_name(); let (a, b) = self.op_type().as_name();
write!(w, "{a}_{b}(")?; write!(w, "{a}_{b}(")?;
self.rhs.write(mng, w)?; self.rhs().write(mng, w)?;
write!(w, ")") write!(w, ")")
} }
} }
impl Driver for BinOp { impl Driver for BinOp {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
if let Some(symbol) = bin_symbol_of(self.op) { if let Some(symbol) = bin_symbol_of(self.op_type()) {
write!(w, "(")?; write!(w, "(")?;
self.lhs.write(mng, w)?; self.lhs().write(mng, w)?;
write!(w, "{symbol} ")?; write!(w, "{symbol} ")?;
self.rhs.write(mng, w)?; self.rhs().write(mng, w)?;
write!(w, ")") write!(w, ")")
} else { } else {
let (head, tail) = self.op.as_name(); let (head, tail) = self.op_type().as_name();
write!(w, "{head}_{tail}(")?; write!(w, "{head}_{tail}(")?;
self.lhs.write(mng, w)?; self.lhs().write(mng, w)?;
write!(w, ", ")?; write!(w, ", ")?;
self.rhs.write(mng, w)?; self.rhs().write(mng, w)?;
write!(w, ")") write!(w, ")")
} }
} }

View File

@ -84,17 +84,17 @@ pub fn write_variable(var: usize, mng: &Manager, w: &mut dyn Write) -> Result<()
} }
pub fn write_cmp_op(cmp: &CmpOp, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { pub fn write_cmp_op(cmp: &CmpOp, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
if let Some(symbol) = cmp_symbol_of(cmp.op) { if let Some(symbol) = cmp_symbol_of(cmp.op_type()) {
cmp.lhs.write(mng, w)?; cmp.lhs().write(mng, w)?;
write!(w, "{symbol} ")?; write!(w, "{symbol} ")?;
cmp.rhs.write(mng, w) cmp.rhs().write(mng, w)
} else { } else {
let (head, tail) = cmp.op.as_name(); let (head, tail) = cmp.op_type().as_name();
write!(w, "{head}_{tail}(")?; write!(w, "{head}_{tail}(")?;
cmp.lhs.write(mng, w)?; cmp.lhs().write(mng, w)?;
write!(w, ", ")?; write!(w, ", ")?;
cmp.rhs.write(mng, w)?; cmp.rhs().write(mng, w)?;
write!(w, ")") write!(w, ")")
} }
} }

View File

@ -17,21 +17,21 @@ use super::manager::{
impl Driver for Br { impl Driver for Br {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
if !self.align.is_aligned() { if !self.align().is_aligned() {
write_ascending("reg", self.align.new_range(), w)?; write_ascending("reg", self.align().new_range(), w)?;
write!(w, " = ")?; write!(w, " = ")?;
write_ascending("reg", self.align.old_range(), w)?; write_ascending("reg", self.align().old_range(), w)?;
write!(w, " ")?; write!(w, " ")?;
} }
if self.target == 0 { if self.target() == 0 {
if let Some(&Label::Backward) = mng.label_list().last() { if let Some(&Label::Backward) = mng.label_list().last() {
write!(w, "continue ")?; write!(w, "continue ")?;
} else { } else {
write!(w, "break ")?; write!(w, "break ")?;
} }
} else { } else {
let level = mng.label_list().len() - 1 - self.target; let level = mng.label_list().len() - 1 - self.target();
write!(w, "desired = {level} ")?; write!(w, "desired = {level} ")?;
write!(w, "break ")?; write!(w, "break ")?;
@ -44,8 +44,8 @@ impl Driver for Br {
fn to_ordered_table<'a>(list: &'a [Br], default: &'a Br) -> Vec<&'a Br> { fn to_ordered_table<'a>(list: &'a [Br], default: &'a Br) -> Vec<&'a Br> {
let mut data: Vec<_> = list.iter().chain(std::iter::once(default)).collect(); let mut data: Vec<_> = list.iter().chain(std::iter::once(default)).collect();
data.sort_by_key(|v| v.target); data.sort_by_key(|v| v.target());
data.dedup_by_key(|v| v.target); data.dedup_by_key(|v| v.target());
data data
} }
@ -64,13 +64,13 @@ fn write_search_layer(
let br = list[center]; let br = list[center];
if range.start != center { if range.start != center {
write!(w, "if temp < {} then ", br.target)?; write!(w, "if temp < {} then ", br.target())?;
write_search_layer(range.start..center, list, mng, w)?; write_search_layer(range.start..center, list, mng, w)?;
write!(w, "else")?; write!(w, "else")?;
} }
if range.end != center + 1 { if range.end != center + 1 {
write!(w, "if temp > {} then ", br.target)?; write!(w, "if temp > {} then ", br.target())?;
write_search_layer(center + 1..range.end, list, mng, w)?; write_search_layer(center + 1..range.end, list, mng, w)?;
write!(w, "else")?; write!(w, "else")?;
} }
@ -87,31 +87,31 @@ fn write_table_setup(table: &BrTable, mng: &mut Manager, w: &mut dyn Write) -> R
write!(w, "br_map[{id}] = (function() return {{[0] =")?; write!(w, "br_map[{id}] = (function() return {{[0] =")?;
table table
.data .data()
.iter() .iter()
.try_for_each(|v| write!(w, "{},", v.target))?; .try_for_each(|v| write!(w, "{},", v.target()))?;
write!(w, "}} end)()")?; write!(w, "}} end)()")?;
write!(w, "end ")?; write!(w, "end ")?;
write!(w, "local temp = br_map[{id}][")?; write!(w, "local temp = br_map[{id}][")?;
table.cond.write(mng, w)?; table.condition().write(mng, w)?;
write!(w, "] or {} ", table.default.target) write!(w, "] or {} ", table.default().target())
} }
impl Driver for BrTable { impl Driver for BrTable {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
if self.data.is_empty() { if self.data().is_empty() {
// Our condition should be pure so we probably don't need // Our condition should be pure so we probably don't need
// to emit it in this case. // to emit it in this case.
return self.default.write(mng, w); return self.default().write(mng, w);
} }
// `BrTable` is optimized by first mapping all indices to targets through // `BrTable` is optimized by first mapping all indices to targets through
// a Lua table; this reduces the size of the code generated as duplicate entries // a Lua table; this reduces the size of the code generated as duplicate entries
// don't need checking. Then, for speed, a binary search is done for the target // don't need checking. Then, for speed, a binary search is done for the target
// and the appropriate jump is performed. // and the appropriate jump is performed.
let list = to_ordered_table(&self.data, &self.default); let list = to_ordered_table(self.data(), self.default());
write_table_setup(self, mng, w)?; write_table_setup(self, mng, w)?;
write_search_layer(0..list.len(), &list, mng, w) write_search_layer(0..list.len(), &list, mng, w)
@ -157,9 +157,9 @@ impl Driver for Forward {
write!(w, "while true do ")?; write!(w, "while true do ")?;
self.code.iter().try_for_each(|s| s.write(mng, w))?; self.code().iter().try_for_each(|s| s.write(mng, w))?;
if let Some(v) = &self.last { if let Some(v) = self.last() {
v.write(mng, w)?; v.write(mng, w)?;
} else { } else {
write!(w, "break ")?; write!(w, "break ")?;
@ -178,9 +178,9 @@ impl Driver for Backward {
write!(w, "while true do ")?; write!(w, "while true do ")?;
self.code.iter().try_for_each(|s| s.write(mng, w))?; self.code().iter().try_for_each(|s| s.write(mng, w))?;
if let Some(v) = &self.last { if let Some(v) = self.last() {
v.write(mng, w)?; v.write(mng, w)?;
} else { } else {
write!(w, "break ")?; write!(w, "break ")?;
@ -196,9 +196,9 @@ impl Driver for Backward {
impl Driver for BrIf { impl Driver for BrIf {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "if ")?; write!(w, "if ")?;
write_condition(&self.cond, mng, w)?; write_condition(self.condition(), mng, w)?;
write!(w, "then ")?; write!(w, "then ")?;
self.target.write(mng, w)?; self.target().write(mng, w)?;
write!(w, "end ") write!(w, "end ")
} }
} }
@ -206,15 +206,15 @@ impl Driver for BrIf {
impl Driver for If { impl Driver for If {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "if ")?; write!(w, "if ")?;
write_condition(&self.cond, mng, w)?; write_condition(self.condition(), mng, w)?;
write!(w, "then ")?; write!(w, "then ")?;
self.truthy.write(mng, w)?; self.on_true().write(mng, w)?;
if let Some(falsey) = &self.falsey { if let Some(v) = self.on_false() {
write!(w, "else ")?; write!(w, "else ")?;
falsey.write(mng, w)?; v.write(mng, w)?;
} }
write!(w, "end ") write!(w, "end ")
@ -232,70 +232,70 @@ fn write_call_store(result: Range<usize>, w: &mut dyn Write) -> Result<()> {
impl Driver for Call { impl Driver for Call {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write_call_store(self.result.clone(), w)?; write_call_store(self.result(), w)?;
write!(w, "FUNC_LIST[{}](", self.func)?; write!(w, "FUNC_LIST[{}](", self.function())?;
self.param_list.as_slice().write(mng, w)?; self.param_list().write(mng, w)?;
write!(w, ")") write!(w, ")")
} }
} }
impl Driver for CallIndirect { impl Driver for CallIndirect {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write_call_store(self.result.clone(), w)?; write_call_store(self.result(), w)?;
write!(w, "TABLE_LIST[{}].data[", self.table)?; write!(w, "TABLE_LIST[{}].data[", self.table())?;
self.index.write(mng, w)?; self.index().write(mng, w)?;
write!(w, "](")?; write!(w, "](")?;
self.param_list.as_slice().write(mng, w)?; self.param_list().write(mng, w)?;
write!(w, ")") write!(w, ")")
} }
} }
impl Driver for SetTemporary { impl Driver for SetTemporary {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "reg_{} = ", self.var)?; write!(w, "reg_{} = ", self.var())?;
self.value.write(mng, w) self.value().write(mng, w)
} }
} }
impl Driver for SetLocal { impl Driver for SetLocal {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write_variable(self.var, mng, w)?; write_variable(self.var(), mng, w)?;
write!(w, "= ")?; write!(w, "= ")?;
self.value.write(mng, w) self.value().write(mng, w)
} }
} }
impl Driver for SetGlobal { impl Driver for SetGlobal {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "GLOBAL_LIST[{}].value = ", self.var)?; write!(w, "GLOBAL_LIST[{}].value = ", self.var())?;
self.value.write(mng, w) self.value().write(mng, w)
} }
} }
impl Driver for StoreAt { impl Driver for StoreAt {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
write!(w, "store_{}(memory_at_0, ", self.what.as_name())?; write!(w, "store_{}(memory_at_0, ", self.store_type().as_name())?;
self.pointer.write(mng, w)?; self.pointer().write(mng, w)?;
if self.offset != 0 { if self.offset() != 0 {
write!(w, "+ {}", self.offset)?; write!(w, "+ {}", self.offset())?;
} }
write!(w, ", ")?; write!(w, ", ")?;
self.value.write(mng, w)?; self.value().write(mng, w)?;
write!(w, ")") write!(w, ")")
} }
} }
impl Driver for MemoryGrow { impl Driver for MemoryGrow {
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> { fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
let result = self.result; let result = self.result();
let memory = self.memory; let memory = self.memory();
write!(w, "reg_{result} = rt.allocator.grow(memory_at_{memory}, ")?; write!(w, "reg_{result} = rt.allocator.grow(memory_at_{memory}, ")?;
self.value.write(mng, w)?; self.size().write(mng, w)?;
write!(w, ")") write!(w, ")")
} }
} }
@ -320,14 +320,14 @@ impl Driver for Statement {
fn write_parameter_list(ast: &FuncData, w: &mut dyn Write) -> Result<()> { fn write_parameter_list(ast: &FuncData, w: &mut dyn Write) -> Result<()> {
write!(w, "function(")?; write!(w, "function(")?;
write_ascending("param", 0..ast.num_param, w)?; write_ascending("param", 0..ast.num_param(), w)?;
write!(w, ")") write!(w, ")")
} }
fn write_variable_list(ast: &FuncData, w: &mut dyn Write) -> Result<()> { fn write_variable_list(ast: &FuncData, w: &mut dyn Write) -> Result<()> {
let mut total = 0; let mut total = 0;
for data in ast.local_data.iter().filter(|v| v.count() != 0) { for data in ast.local_data().iter().filter(|v| v.count() != 0) {
let range = total..total + usize::try_from(data.count()).unwrap(); let range = total..total + usize::try_from(data.count()).unwrap();
let zero = if data.value_type() == ValueType::I64 { let zero = if data.value_type() == ValueType::I64 {
"i64_K_ZERO " "i64_K_ZERO "
@ -344,9 +344,9 @@ fn write_variable_list(ast: &FuncData, w: &mut dyn Write) -> Result<()> {
write!(w, " ")?; write!(w, " ")?;
} }
if ast.num_stack != 0 { if ast.num_stack() != 0 {
write!(w, "local ")?; write!(w, "local ")?;
write_ascending("reg", 0..ast.num_stack, w)?; write_ascending("reg", 0..ast.num_stack(), w)?;
write!(w, " ")?; write!(w, " ")?;
} }
@ -366,12 +366,12 @@ impl Driver for FuncData {
} }
mng.set_table_map(br_map); mng.set_table_map(br_map);
mng.set_num_param(self.num_param); mng.set_num_param(self.num_param());
self.code.write(mng, w)?; self.code().write(mng, w)?;
if self.num_result != 0 { if self.num_result() != 0 {
write!(w, "return ")?; write!(w, "return ")?;
write_ascending("reg", 0..self.num_result, w)?; write_ascending("reg", 0..self.num_result(), w)?;
write!(w, " ")?; write!(w, " ")?;
} }

View File

@ -50,8 +50,8 @@ fn write_named_array(name: &str, len: usize, w: &mut dyn Write) -> Result<()> {
fn write_constant(code: &[Instruction], type_info: &TypeInfo, w: &mut dyn Write) -> Result<()> { fn write_constant(code: &[Instruction], type_info: &TypeInfo, w: &mut dyn Write) -> Result<()> {
let func = Builder::from_type_info(type_info).build_anonymous(code); let func = Builder::from_type_info(type_info).build_anonymous(code);
if let Some(Statement::SetTemporary(stat)) = func.code.code.last() { if let Some(Statement::SetTemporary(stat)) = func.code().code().last() {
stat.value.write(&mut Manager::default(), w)?; stat.value().write(&mut Manager::default(), w)?;
} else { } else {
panic!("Not a valid constant"); panic!("Not a valid constant");
} }

View File

@ -182,9 +182,9 @@ impl StatList {
leak_on!(leak_global_write, Global); leak_on!(leak_global_write, Global);
leak_on!(leak_memory_write, Memory); leak_on!(leak_memory_write, Memory);
fn push_load(&mut self, what: LoadType, offset: u32) { fn push_load(&mut self, load_type: LoadType, offset: u32) {
let data = Expression::LoadAt(LoadAt { let data = Expression::LoadAt(LoadAt {
what, load_type,
offset, offset,
pointer: self.stack.pop().into(), pointer: self.stack.pop().into(),
}); });
@ -192,9 +192,9 @@ impl StatList {
self.stack.push_with_single(data); self.stack.push_with_single(data);
} }
fn add_store(&mut self, what: StoreType, offset: u32) { fn add_store(&mut self, store_type: StoreType, offset: u32) {
let data = Statement::StoreAt(StoreAt { let data = Statement::StoreAt(StoreAt {
what, store_type,
offset, offset,
value: self.stack.pop(), value: self.stack.pop(),
pointer: self.stack.pop(), pointer: self.stack.pop(),
@ -210,22 +210,22 @@ impl StatList {
self.stack.push(value); self.stack.push(value);
} }
fn push_un_op(&mut self, op: UnOpType) { fn push_un_op(&mut self, op_type: UnOpType) {
let rhs = self.stack.pop_with_read(); let rhs = self.stack.pop_with_read();
let data = Expression::UnOp(UnOp { let data = Expression::UnOp(UnOp {
op, op_type,
rhs: rhs.0.into(), rhs: rhs.0.into(),
}); });
self.stack.push_with_read(data, rhs.1); self.stack.push_with_read(data, rhs.1);
} }
fn push_bin_op(&mut self, op: BinOpType) { fn push_bin_op(&mut self, op_type: BinOpType) {
let mut rhs = self.stack.pop_with_read(); let mut rhs = self.stack.pop_with_read();
let lhs = self.stack.pop_with_read(); let lhs = self.stack.pop_with_read();
let data = Expression::BinOp(BinOp { let data = Expression::BinOp(BinOp {
op, op_type,
rhs: rhs.0.into(), rhs: rhs.0.into(),
lhs: lhs.0.into(), lhs: lhs.0.into(),
}); });
@ -235,12 +235,12 @@ impl StatList {
self.stack.push_with_read(data, rhs.1); self.stack.push_with_read(data, rhs.1);
} }
fn push_cmp_op(&mut self, op: CmpOpType) { fn push_cmp_op(&mut self, op_type: CmpOpType) {
let mut rhs = self.stack.pop_with_read(); let mut rhs = self.stack.pop_with_read();
let lhs = self.stack.pop_with_read(); let lhs = self.stack.pop_with_read();
let data = Expression::CmpOp(CmpOp { let data = Expression::CmpOp(CmpOp {
op, op_type,
rhs: rhs.0.into(), rhs: rhs.0.into(),
lhs: lhs.0.into(), lhs: lhs.0.into(),
}); });
@ -411,13 +411,13 @@ impl<'a> Builder<'a> {
BlockData::Forward { .. } => Statement::Forward(now.into()), BlockData::Forward { .. } => Statement::Forward(now.into()),
BlockData::Backward { .. } => Statement::Backward(now.into()), BlockData::Backward { .. } => Statement::Backward(now.into()),
BlockData::If { .. } => Statement::If(If { BlockData::If { .. } => Statement::If(If {
cond: self.target.stack.pop(), condition: self.target.stack.pop(),
truthy: now.into(), on_true: now.into(),
falsey: None, on_false: None,
}), }),
BlockData::Else { .. } => { BlockData::Else { .. } => {
if let Statement::If(v) = self.target.code.last_mut().unwrap() { if let Statement::If(v) = self.target.code.last_mut().unwrap() {
v.falsey = Some(now.into()); v.on_false = Some(now.into());
} else { } else {
unreachable!() unreachable!()
} }
@ -454,8 +454,8 @@ impl<'a> Builder<'a> {
Br { target, align } Br { target, align }
} }
fn add_call(&mut self, func: usize) { fn add_call(&mut self, function: usize) {
let arity = self.type_info.rel_arity_of(func); let arity = self.type_info.rel_arity_of(function);
let param_list = self.target.stack.pop_len(arity.num_param).collect(); let param_list = self.target.stack.pop_len(arity.num_param).collect();
self.target.leak_pre_call(); self.target.leak_pre_call();
@ -463,7 +463,7 @@ impl<'a> Builder<'a> {
let result = self.target.stack.push_temporary(arity.num_result); let result = self.target.stack.push_temporary(arity.num_result);
let data = Statement::Call(Call { let data = Statement::Call(Call {
func, function,
result, result,
param_list, param_list,
}); });
@ -556,7 +556,7 @@ impl<'a> Builder<'a> {
} }
Inst::BrIf(v) => { Inst::BrIf(v) => {
let data = Statement::BrIf(BrIf { let data = Statement::BrIf(BrIf {
cond: self.target.stack.pop(), condition: self.target.stack.pop(),
target: self.get_br_terminator(v.try_into().unwrap()), target: self.get_br_terminator(v.try_into().unwrap()),
}); });
@ -564,7 +564,7 @@ impl<'a> Builder<'a> {
self.target.code.push(data); self.target.code.push(data);
} }
Inst::BrTable(ref v) => { Inst::BrTable(ref v) => {
let cond = self.target.stack.pop(); let condition = self.target.stack.pop();
let data = v let data = v
.table .table
.iter() .iter()
@ -575,7 +575,7 @@ impl<'a> Builder<'a> {
let default = self.get_br_terminator(v.default.try_into().unwrap()); let default = self.get_br_terminator(v.default.try_into().unwrap());
let term = Terminator::BrTable(BrTable { let term = Terminator::BrTable(BrTable {
cond, condition,
data, data,
default, default,
}); });
@ -600,20 +600,20 @@ impl<'a> Builder<'a> {
self.target.stack.pop(); self.target.stack.pop();
} }
Inst::Select => { Inst::Select => {
let mut cond = self.target.stack.pop_with_read(); let mut condition = self.target.stack.pop_with_read();
let b = self.target.stack.pop_with_read(); let on_false = self.target.stack.pop_with_read();
let a = self.target.stack.pop_with_read(); let on_true = self.target.stack.pop_with_read();
let data = Expression::Select(Select { let data = Expression::Select(Select {
cond: cond.0.into(), condition: condition.0.into(),
b: b.0.into(), on_true: on_true.0.into(),
a: a.0.into(), on_false: on_false.0.into(),
}); });
cond.1.extend(b.1); condition.1.extend(on_true.1);
cond.1.extend(a.1); condition.1.extend(on_false.1);
self.target.stack.push_with_read(data, cond.1); self.target.stack.push_with_read(data, condition.1);
} }
Inst::GetLocal(i) => { Inst::GetLocal(i) => {
let var = i.try_into().unwrap(); let var = i.try_into().unwrap();
@ -689,14 +689,14 @@ impl<'a> Builder<'a> {
self.target.stack.push(data); self.target.stack.push(data);
} }
Inst::GrowMemory(i) => { Inst::GrowMemory(i) => {
let value = self.target.stack.pop().into(); let size = self.target.stack.pop().into();
let result = self.target.stack.push_temporary(1).start; let result = self.target.stack.push_temporary(1).start;
let memory = i.try_into().unwrap(); let memory = i.try_into().unwrap();
let data = Statement::MemoryGrow(MemoryGrow { let data = Statement::MemoryGrow(MemoryGrow {
result,
memory, memory,
value, result,
size,
}); });
self.target.leak_memory_write(memory); self.target.leak_memory_write(memory);

View File

@ -530,39 +530,117 @@ impl TryFrom<&Instruction> for CmpOpType {
} }
} }
#[derive(Clone)] pub struct Select {
pub struct GetTemporary { pub(crate) condition: Box<Expression>,
pub var: usize, pub(crate) on_true: Box<Expression>,
pub(crate) on_false: Box<Expression>,
} }
pub struct Select { impl Select {
pub cond: Box<Expression>, #[must_use]
pub a: Box<Expression>, pub fn condition(&self) -> &Expression {
pub b: Box<Expression>, &self.condition
}
#[must_use]
pub fn on_true(&self) -> &Expression {
&self.on_true
}
#[must_use]
pub fn on_false(&self) -> &Expression {
&self.on_false
}
}
pub struct GetTemporary {
pub(crate) var: usize,
}
impl GetTemporary {
#[must_use]
pub fn var(&self) -> usize {
self.var
}
} }
pub struct GetLocal { pub struct GetLocal {
pub var: usize, pub(crate) var: usize,
}
impl GetLocal {
#[must_use]
pub fn var(&self) -> usize {
self.var
}
} }
pub struct GetGlobal { pub struct GetGlobal {
pub var: usize, pub(crate) var: usize,
}
impl GetGlobal {
#[must_use]
pub fn var(&self) -> usize {
self.var
}
} }
pub struct LoadAt { pub struct LoadAt {
pub what: LoadType, pub(crate) load_type: LoadType,
pub offset: u32, pub(crate) offset: u32,
pub pointer: Box<Expression>, pub(crate) pointer: Box<Expression>,
}
impl LoadAt {
#[must_use]
pub fn load_type(&self) -> LoadType {
self.load_type
}
#[must_use]
pub fn offset(&self) -> u32 {
self.offset
}
#[must_use]
pub fn pointer(&self) -> &Expression {
&self.pointer
}
} }
pub struct MemorySize { pub struct MemorySize {
pub memory: usize, pub(crate) memory: usize,
}
impl MemorySize {
#[must_use]
pub fn memory(&self) -> usize {
self.memory
}
} }
pub struct MemoryGrow { pub struct MemoryGrow {
pub result: usize, pub(crate) memory: usize,
pub memory: usize, pub(crate) result: usize,
pub value: Box<Expression>, pub(crate) size: Box<Expression>,
}
impl MemoryGrow {
#[must_use]
pub fn memory(&self) -> usize {
self.memory
}
#[must_use]
pub fn result(&self) -> usize {
self.result
}
#[must_use]
pub fn size(&self) -> &Expression {
&self.size
}
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
@ -598,20 +676,66 @@ impl From<u64> for Value {
} }
pub struct UnOp { pub struct UnOp {
pub op: UnOpType, pub(crate) op_type: UnOpType,
pub rhs: Box<Expression>, pub(crate) rhs: Box<Expression>,
}
impl UnOp {
#[must_use]
pub fn op_type(&self) -> UnOpType {
self.op_type
}
#[must_use]
pub fn rhs(&self) -> &Expression {
&self.rhs
}
} }
pub struct BinOp { pub struct BinOp {
pub op: BinOpType, pub(crate) op_type: BinOpType,
pub lhs: Box<Expression>, pub(crate) lhs: Box<Expression>,
pub rhs: Box<Expression>, pub(crate) rhs: Box<Expression>,
}
impl BinOp {
#[must_use]
pub fn op_type(&self) -> BinOpType {
self.op_type
}
#[must_use]
pub fn lhs(&self) -> &Expression {
&self.lhs
}
#[must_use]
pub fn rhs(&self) -> &Expression {
&self.rhs
}
} }
pub struct CmpOp { pub struct CmpOp {
pub op: CmpOpType, pub(crate) op_type: CmpOpType,
pub lhs: Box<Expression>, pub(crate) lhs: Box<Expression>,
pub rhs: Box<Expression>, pub(crate) rhs: Box<Expression>,
}
impl CmpOp {
#[must_use]
pub fn op_type(&self) -> CmpOpType {
self.op_type
}
#[must_use]
pub fn lhs(&self) -> &Expression {
&self.lhs
}
#[must_use]
pub fn rhs(&self) -> &Expression {
&self.rhs
}
} }
pub enum Expression { pub enum Expression {
@ -628,9 +752,9 @@ pub enum Expression {
} }
pub struct Align { pub struct Align {
pub new: usize, pub(crate) new: usize,
pub old: usize, pub(crate) old: usize,
pub length: usize, pub(crate) length: usize,
} }
impl Align { impl Align {
@ -651,14 +775,43 @@ impl Align {
} }
pub struct Br { pub struct Br {
pub target: usize, pub(crate) target: usize,
pub align: Align, pub(crate) align: Align,
}
impl Br {
#[must_use]
pub fn target(&self) -> usize {
self.target
}
#[must_use]
pub fn align(&self) -> &Align {
&self.align
}
} }
pub struct BrTable { pub struct BrTable {
pub cond: Expression, pub(crate) condition: Expression,
pub data: Vec<Br>, pub(crate) data: Vec<Br>,
pub default: Br, pub(crate) default: Br,
}
impl BrTable {
#[must_use]
pub fn condition(&self) -> &Expression {
&self.condition
}
#[must_use]
pub fn data(&self) -> &[Br] {
&self.data
}
#[must_use]
pub fn default(&self) -> &Br {
&self.default
}
} }
pub enum Terminator { pub enum Terminator {
@ -669,60 +822,210 @@ pub enum Terminator {
#[derive(Default)] #[derive(Default)]
pub struct Forward { pub struct Forward {
pub code: Vec<Statement>, pub(crate) code: Vec<Statement>,
pub last: Option<Terminator>, pub(crate) last: Option<Terminator>,
}
impl Forward {
#[must_use]
pub fn code(&self) -> &[Statement] {
&self.code
}
#[must_use]
pub fn last(&self) -> Option<&Terminator> {
self.last.as_ref()
}
} }
#[derive(Default)] #[derive(Default)]
pub struct Backward { pub struct Backward {
pub code: Vec<Statement>, pub(crate) code: Vec<Statement>,
pub last: Option<Terminator>, pub(crate) last: Option<Terminator>,
}
impl Backward {
#[must_use]
pub fn code(&self) -> &[Statement] {
&self.code
}
#[must_use]
pub fn last(&self) -> Option<&Terminator> {
self.last.as_ref()
}
} }
pub struct BrIf { pub struct BrIf {
pub cond: Expression, pub(crate) condition: Expression,
pub target: Br, pub(crate) target: Br,
}
impl BrIf {
#[must_use]
pub fn condition(&self) -> &Expression {
&self.condition
}
#[must_use]
pub fn target(&self) -> &Br {
&self.target
}
} }
pub struct If { pub struct If {
pub cond: Expression, pub(crate) condition: Expression,
pub truthy: Forward, pub(crate) on_true: Forward,
pub falsey: Option<Forward>, pub(crate) on_false: Option<Forward>,
}
impl If {
#[must_use]
pub fn condition(&self) -> &Expression {
&self.condition
}
#[must_use]
pub fn on_true(&self) -> &Forward {
&self.on_true
}
#[must_use]
pub fn on_false(&self) -> Option<&Forward> {
self.on_false.as_ref()
}
} }
pub struct Call { pub struct Call {
pub func: usize, pub(crate) function: usize,
pub result: Range<usize>, pub(crate) result: Range<usize>,
pub param_list: Vec<Expression>, pub(crate) param_list: Vec<Expression>,
}
impl Call {
#[must_use]
pub fn function(&self) -> usize {
self.function
}
#[must_use]
pub fn result(&self) -> Range<usize> {
self.result.clone()
}
#[must_use]
pub fn param_list(&self) -> &[Expression] {
&self.param_list
}
} }
pub struct CallIndirect { pub struct CallIndirect {
pub table: usize, pub(crate) table: usize,
pub index: Expression, pub(crate) index: Expression,
pub result: Range<usize>, pub(crate) result: Range<usize>,
pub param_list: Vec<Expression>, pub(crate) param_list: Vec<Expression>,
}
impl CallIndirect {
#[must_use]
pub fn table(&self) -> usize {
self.table
}
#[must_use]
pub fn index(&self) -> &Expression {
&self.index
}
#[must_use]
pub fn result(&self) -> Range<usize> {
self.result.clone()
}
#[must_use]
pub fn param_list(&self) -> &[Expression] {
&self.param_list
}
} }
pub struct SetTemporary { pub struct SetTemporary {
pub var: usize, pub(crate) var: usize,
pub value: Expression, pub(crate) value: Expression,
}
impl SetTemporary {
#[must_use]
pub fn var(&self) -> usize {
self.var
}
#[must_use]
pub fn value(&self) -> &Expression {
&self.value
}
} }
pub struct SetLocal { pub struct SetLocal {
pub var: usize, pub(crate) var: usize,
pub value: Expression, pub(crate) value: Expression,
}
impl SetLocal {
#[must_use]
pub fn var(&self) -> usize {
self.var
}
#[must_use]
pub fn value(&self) -> &Expression {
&self.value
}
} }
pub struct SetGlobal { pub struct SetGlobal {
pub var: usize, pub(crate) var: usize,
pub value: Expression, pub(crate) value: Expression,
}
impl SetGlobal {
#[must_use]
pub fn var(&self) -> usize {
self.var
}
#[must_use]
pub fn value(&self) -> &Expression {
&self.value
}
} }
pub struct StoreAt { pub struct StoreAt {
pub what: StoreType, pub(crate) store_type: StoreType,
pub offset: u32, pub(crate) offset: u32,
pub pointer: Expression, pub(crate) pointer: Expression,
pub value: Expression, pub(crate) value: Expression,
}
impl StoreAt {
#[must_use]
pub fn store_type(&self) -> StoreType {
self.store_type
}
#[must_use]
pub fn offset(&self) -> u32 {
self.offset
}
#[must_use]
pub fn pointer(&self) -> &Expression {
&self.pointer
}
#[must_use]
pub fn value(&self) -> &Expression {
&self.value
}
} }
pub enum Statement { pub enum Statement {
@ -740,9 +1043,36 @@ pub enum Statement {
} }
pub struct FuncData { pub struct FuncData {
pub local_data: Vec<Local>, pub(crate) local_data: Vec<Local>,
pub num_result: usize, pub(crate) num_result: usize,
pub num_param: usize, pub(crate) num_param: usize,
pub num_stack: usize, pub(crate) num_stack: usize,
pub code: Forward, pub(crate) code: Forward,
}
impl FuncData {
#[must_use]
pub fn local_data(&self) -> &[Local] {
&self.local_data
}
#[must_use]
pub fn num_result(&self) -> usize {
self.num_result
}
#[must_use]
pub fn num_param(&self) -> usize {
self.num_param
}
#[must_use]
pub fn num_stack(&self) -> usize {
self.num_stack
}
#[must_use]
pub fn code(&self) -> &Forward {
&self.code
}
} }

View File

@ -18,7 +18,7 @@ pub struct Slot {
impl Slot { impl Slot {
fn is_temporary(&self, id: usize) -> bool { fn is_temporary(&self, id: usize) -> bool {
matches!(self.data, Expression::GetTemporary(ref v) if v.var == id) matches!(self.data, Expression::GetTemporary(ref v) if v.var() == id)
} }
pub fn has_read(&self, id: ReadType) -> bool { pub fn has_read(&self, id: ReadType) -> bool {

View File

@ -66,9 +66,9 @@ pub trait Driver<T: Visitor> {
impl<T: Visitor> Driver<T> for Select { impl<T: Visitor> Driver<T> for Select {
fn accept(&self, visitor: &mut T) { fn accept(&self, visitor: &mut T) {
self.cond.accept(visitor); self.condition().accept(visitor);
self.a.accept(visitor); self.on_true().accept(visitor);
self.b.accept(visitor); self.on_false().accept(visitor);
visitor.visit_select(self); visitor.visit_select(self);
} }
@ -94,7 +94,7 @@ impl<T: Visitor> Driver<T> for GetGlobal {
impl<T: Visitor> Driver<T> for LoadAt { impl<T: Visitor> Driver<T> for LoadAt {
fn accept(&self, visitor: &mut T) { fn accept(&self, visitor: &mut T) {
self.pointer.accept(visitor); self.pointer().accept(visitor);
visitor.visit_load_at(self); visitor.visit_load_at(self);
} }
@ -114,7 +114,7 @@ impl<T: Visitor> Driver<T> for Value {
impl<T: Visitor> Driver<T> for UnOp { impl<T: Visitor> Driver<T> for UnOp {
fn accept(&self, visitor: &mut T) { fn accept(&self, visitor: &mut T) {
self.rhs.accept(visitor); self.rhs().accept(visitor);
visitor.visit_un_op(self); visitor.visit_un_op(self);
} }
@ -122,8 +122,8 @@ impl<T: Visitor> Driver<T> for UnOp {
impl<T: Visitor> Driver<T> for BinOp { impl<T: Visitor> Driver<T> for BinOp {
fn accept(&self, visitor: &mut T) { fn accept(&self, visitor: &mut T) {
self.lhs.accept(visitor); self.lhs().accept(visitor);
self.rhs.accept(visitor); self.rhs().accept(visitor);
visitor.visit_bin_op(self); visitor.visit_bin_op(self);
} }
@ -131,8 +131,8 @@ impl<T: Visitor> Driver<T> for BinOp {
impl<T: Visitor> Driver<T> for CmpOp { impl<T: Visitor> Driver<T> for CmpOp {
fn accept(&self, visitor: &mut T) { fn accept(&self, visitor: &mut T) {
self.lhs.accept(visitor); self.lhs().accept(visitor);
self.rhs.accept(visitor); self.rhs().accept(visitor);
visitor.visit_cmp_op(self); visitor.visit_cmp_op(self);
} }
@ -165,7 +165,7 @@ impl<T: Visitor> Driver<T> for Br {
impl<T: Visitor> Driver<T> for BrTable { impl<T: Visitor> Driver<T> for BrTable {
fn accept(&self, visitor: &mut T) { fn accept(&self, visitor: &mut T) {
self.cond.accept(visitor); self.condition().accept(visitor);
visitor.visit_br_table(self); visitor.visit_br_table(self);
} }
@ -185,11 +185,11 @@ impl<T: Visitor> Driver<T> for Terminator {
impl<T: Visitor> Driver<T> for Forward { impl<T: Visitor> Driver<T> for Forward {
fn accept(&self, visitor: &mut T) { fn accept(&self, visitor: &mut T) {
for v in &self.code { for v in self.code() {
v.accept(visitor); v.accept(visitor);
} }
if let Some(v) = &self.last { if let Some(v) = self.last() {
v.accept(visitor); v.accept(visitor);
} }
@ -199,11 +199,11 @@ impl<T: Visitor> Driver<T> for Forward {
impl<T: Visitor> Driver<T> for Backward { impl<T: Visitor> Driver<T> for Backward {
fn accept(&self, visitor: &mut T) { fn accept(&self, visitor: &mut T) {
for v in &self.code { for v in self.code() {
v.accept(visitor); v.accept(visitor);
} }
if let Some(v) = &self.last { if let Some(v) = self.last() {
v.accept(visitor); v.accept(visitor);
} }
@ -213,7 +213,7 @@ impl<T: Visitor> Driver<T> for Backward {
impl<T: Visitor> Driver<T> for BrIf { impl<T: Visitor> Driver<T> for BrIf {
fn accept(&self, visitor: &mut T) { fn accept(&self, visitor: &mut T) {
self.cond.accept(visitor); self.condition().accept(visitor);
visitor.visit_br_if(self); visitor.visit_br_if(self);
} }
@ -221,10 +221,10 @@ impl<T: Visitor> Driver<T> for BrIf {
impl<T: Visitor> Driver<T> for If { impl<T: Visitor> Driver<T> for If {
fn accept(&self, visitor: &mut T) { fn accept(&self, visitor: &mut T) {
self.cond.accept(visitor); self.condition().accept(visitor);
self.truthy.accept(visitor); self.on_true().accept(visitor);
if let Some(v) = &self.falsey { if let Some(v) = self.on_false() {
v.accept(visitor); v.accept(visitor);
} }
@ -234,7 +234,7 @@ impl<T: Visitor> Driver<T> for If {
impl<T: Visitor> Driver<T> for Call { impl<T: Visitor> Driver<T> for Call {
fn accept(&self, visitor: &mut T) { fn accept(&self, visitor: &mut T) {
for v in &self.param_list { for v in self.param_list() {
v.accept(visitor); v.accept(visitor);
} }
@ -244,9 +244,9 @@ impl<T: Visitor> Driver<T> for Call {
impl<T: Visitor> Driver<T> for CallIndirect { impl<T: Visitor> Driver<T> for CallIndirect {
fn accept(&self, visitor: &mut T) { fn accept(&self, visitor: &mut T) {
self.index.accept(visitor); self.index().accept(visitor);
for v in &self.param_list { for v in self.param_list() {
v.accept(visitor); v.accept(visitor);
} }
@ -256,7 +256,7 @@ impl<T: Visitor> Driver<T> for CallIndirect {
impl<T: Visitor> Driver<T> for SetTemporary { impl<T: Visitor> Driver<T> for SetTemporary {
fn accept(&self, visitor: &mut T) { fn accept(&self, visitor: &mut T) {
self.value.accept(visitor); self.value().accept(visitor);
visitor.visit_set_temporary(self); visitor.visit_set_temporary(self);
} }
@ -264,7 +264,7 @@ impl<T: Visitor> Driver<T> for SetTemporary {
impl<T: Visitor> Driver<T> for SetLocal { impl<T: Visitor> Driver<T> for SetLocal {
fn accept(&self, visitor: &mut T) { fn accept(&self, visitor: &mut T) {
self.value.accept(visitor); self.value().accept(visitor);
visitor.visit_set_local(self); visitor.visit_set_local(self);
} }
@ -272,7 +272,7 @@ impl<T: Visitor> Driver<T> for SetLocal {
impl<T: Visitor> Driver<T> for SetGlobal { impl<T: Visitor> Driver<T> for SetGlobal {
fn accept(&self, visitor: &mut T) { fn accept(&self, visitor: &mut T) {
self.value.accept(visitor); self.value().accept(visitor);
visitor.visit_set_global(self); visitor.visit_set_global(self);
} }
@ -280,8 +280,8 @@ impl<T: Visitor> Driver<T> for SetGlobal {
impl<T: Visitor> Driver<T> for StoreAt { impl<T: Visitor> Driver<T> for StoreAt {
fn accept(&self, visitor: &mut T) { fn accept(&self, visitor: &mut T) {
self.pointer.accept(visitor); self.pointer().accept(visitor);
self.value.accept(visitor); self.value().accept(visitor);
visitor.visit_store_at(self); visitor.visit_store_at(self);
} }
@ -289,7 +289,7 @@ impl<T: Visitor> Driver<T> for StoreAt {
impl<T: Visitor> Driver<T> for MemoryGrow { impl<T: Visitor> Driver<T> for MemoryGrow {
fn accept(&self, visitor: &mut T) { fn accept(&self, visitor: &mut T) {
self.value.accept(visitor); self.size().accept(visitor);
visitor.visit_memory_grow(self); visitor.visit_memory_grow(self);
} }
@ -317,6 +317,6 @@ impl<T: Visitor> Driver<T> for Statement {
impl<T: Visitor> Driver<T> for FuncData { impl<T: Visitor> Driver<T> for FuncData {
fn accept(&self, visitor: &mut T) { fn accept(&self, visitor: &mut T) {
self.code.accept(visitor); self.code().accept(visitor);
} }
} }