Encapsulate nodes
This commit is contained in:
parent
b282bdf490
commit
9db21cc84b
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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, ")")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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, ")")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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, " ")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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, ")")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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, ")")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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, " ")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user