Encapsulate nodes
This commit is contained in:
parent
b282bdf490
commit
9db21cc84b
@ -14,51 +14,51 @@ struct Visit {
|
||||
|
||||
impl Visitor for Visit {
|
||||
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.local_set.insert(("load", name));
|
||||
}
|
||||
|
||||
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.local_set.insert(("store", name));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
let name = v.op.as_name();
|
||||
let name = v.op_type().as_name();
|
||||
|
||||
self.local_set.insert(name);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
let name = v.op.as_name();
|
||||
let name = v.op_type().as_name();
|
||||
|
||||
self.local_set.insert(name);
|
||||
}
|
||||
|
||||
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) {
|
||||
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 {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "(")?;
|
||||
write_condition(&self.cond, mng, w)?;
|
||||
write_condition(self.condition(), mng, w)?;
|
||||
write!(w, "and ")?;
|
||||
self.a.write(mng, w)?;
|
||||
self.on_true().write(mng, w)?;
|
||||
write!(w, "or ")?;
|
||||
self.b.write(mng, w)?;
|
||||
self.on_false().write(mng, w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for GetTemporary {
|
||||
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "reg_{} ", self.var)
|
||||
write!(w, "reg_{} ", self.var())
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for GetLocal {
|
||||
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 {
|
||||
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 {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "load_{}(memory_at_0, ", self.what.as_name())?;
|
||||
self.pointer.write(mng, w)?;
|
||||
write!(w, "load_{}(memory_at_0, ", self.load_type().as_name())?;
|
||||
self.pointer().write(mng, w)?;
|
||||
|
||||
if self.offset != 0 {
|
||||
write!(w, "+ {}", self.offset)?;
|
||||
if self.offset() != 0 {
|
||||
write!(w, "+ {}", self.offset())?;
|
||||
}
|
||||
|
||||
write!(w, ")")
|
||||
@ -73,7 +73,7 @@ impl Driver for LoadAt {
|
||||
|
||||
impl Driver for MemorySize {
|
||||
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 {
|
||||
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}(")?;
|
||||
self.rhs.write(mng, w)?;
|
||||
self.rhs().write(mng, w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for BinOp {
|
||||
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, "(")?;
|
||||
self.lhs.write(mng, w)?;
|
||||
self.lhs().write(mng, w)?;
|
||||
write!(w, "{symbol} ")?;
|
||||
self.rhs.write(mng, w)?;
|
||||
self.rhs().write(mng, w)?;
|
||||
write!(w, ")")
|
||||
} else {
|
||||
let (head, tail) = self.op.as_name();
|
||||
let (head, tail) = self.op_type().as_name();
|
||||
|
||||
write!(w, "{head}_{tail}(")?;
|
||||
self.lhs.write(mng, w)?;
|
||||
self.lhs().write(mng, w)?;
|
||||
write!(w, ", ")?;
|
||||
self.rhs.write(mng, w)?;
|
||||
self.rhs().write(mng, 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<()> {
|
||||
if let Some(symbol) = cmp_symbol_of(cmp.op) {
|
||||
cmp.lhs.write(mng, w)?;
|
||||
if let Some(symbol) = cmp_symbol_of(cmp.op_type()) {
|
||||
cmp.lhs().write(mng, w)?;
|
||||
write!(w, "{symbol} ")?;
|
||||
cmp.rhs.write(mng, w)
|
||||
cmp.rhs().write(mng, w)
|
||||
} else {
|
||||
let (head, tail) = cmp.op.as_name();
|
||||
let (head, tail) = cmp.op_type().as_name();
|
||||
|
||||
write!(w, "{head}_{tail}(")?;
|
||||
cmp.lhs.write(mng, w)?;
|
||||
cmp.lhs().write(mng, w)?;
|
||||
write!(w, ", ")?;
|
||||
cmp.rhs.write(mng, w)?;
|
||||
cmp.rhs().write(mng, w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
@ -17,12 +17,12 @@ use super::manager::{
|
||||
|
||||
impl Driver for Br {
|
||||
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() {
|
||||
write_ascending("reg", self.align.new_range(), w)?;
|
||||
if !self.align().is_aligned() {
|
||||
write_ascending("reg", self.align().new_range(), w)?;
|
||||
write!(w, " = ")?;
|
||||
write_ascending("reg", self.align.old_range(), w)?;
|
||||
write_ascending("reg", self.align().old_range(), 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> {
|
||||
let mut data: Vec<_> = list.iter().chain(std::iter::once(default)).collect();
|
||||
|
||||
data.sort_by_key(|v| v.target);
|
||||
data.dedup_by_key(|v| v.target);
|
||||
data.sort_by_key(|v| v.target());
|
||||
data.dedup_by_key(|v| v.target());
|
||||
|
||||
data
|
||||
}
|
||||
@ -53,13 +53,13 @@ fn write_search_layer(
|
||||
let br = list[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!(w, "else")?;
|
||||
}
|
||||
|
||||
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!(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] =")?;
|
||||
|
||||
table
|
||||
.data
|
||||
.data()
|
||||
.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, "temp = br_map[{id}][")?;
|
||||
table.cond.write(mng, w)?;
|
||||
write!(w, "] or {} ", table.default.target)
|
||||
table.condition().write(mng, w)?;
|
||||
write!(w, "] or {} ", table.default().target())
|
||||
}
|
||||
|
||||
impl Driver for BrTable {
|
||||
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
|
||||
// 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
|
||||
// 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
|
||||
// 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_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<()> {
|
||||
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)?;
|
||||
}
|
||||
|
||||
@ -142,9 +142,9 @@ impl Driver for Backward {
|
||||
write!(w, "::continue_at_{label}::")?;
|
||||
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)?;
|
||||
} else {
|
||||
write!(w, "break ")?;
|
||||
@ -161,9 +161,9 @@ impl Driver for Backward {
|
||||
impl Driver for BrIf {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "if ")?;
|
||||
write_condition(&self.cond, mng, w)?;
|
||||
write_condition(self.condition(), mng, w)?;
|
||||
write!(w, "then ")?;
|
||||
self.target.write(mng, w)?;
|
||||
self.target().write(mng, w)?;
|
||||
write!(w, "end ")
|
||||
}
|
||||
}
|
||||
@ -171,15 +171,15 @@ impl Driver for BrIf {
|
||||
impl Driver for If {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "if ")?;
|
||||
write_condition(&self.cond, mng, w)?;
|
||||
write_condition(self.condition(), mng, w)?;
|
||||
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 ")?;
|
||||
|
||||
falsey.write(mng, w)?;
|
||||
v.write(mng, w)?;
|
||||
}
|
||||
|
||||
write!(w, "end ")
|
||||
@ -197,70 +197,70 @@ fn write_call_store(result: Range<usize>, w: &mut dyn Write) -> Result<()> {
|
||||
|
||||
impl Driver for Call {
|
||||
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)?;
|
||||
self.param_list.as_slice().write(mng, w)?;
|
||||
write!(w, "FUNC_LIST[{}](", self.function())?;
|
||||
self.param_list().write(mng, w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for CallIndirect {
|
||||
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)?;
|
||||
self.index.write(mng, w)?;
|
||||
write!(w, "TABLE_LIST[{}].data[", self.table())?;
|
||||
self.index().write(mng, w)?;
|
||||
write!(w, "](")?;
|
||||
self.param_list.as_slice().write(mng, w)?;
|
||||
self.param_list().write(mng, w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for SetTemporary {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "reg_{} = ", self.var)?;
|
||||
self.value.write(mng, w)
|
||||
write!(w, "reg_{} = ", self.var())?;
|
||||
self.value().write(mng, w)
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for SetLocal {
|
||||
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, "= ")?;
|
||||
self.value.write(mng, w)
|
||||
self.value().write(mng, w)
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for SetGlobal {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "GLOBAL_LIST[{}].value = ", self.var)?;
|
||||
self.value.write(mng, w)
|
||||
write!(w, "GLOBAL_LIST[{}].value = ", self.var())?;
|
||||
self.value().write(mng, w)
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for StoreAt {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "store_{}(memory_at_0, ", self.what.as_name())?;
|
||||
self.pointer.write(mng, w)?;
|
||||
write!(w, "store_{}(memory_at_0, ", self.store_type().as_name())?;
|
||||
self.pointer().write(mng, w)?;
|
||||
|
||||
if self.offset != 0 {
|
||||
write!(w, "+ {}", self.offset)?;
|
||||
if self.offset() != 0 {
|
||||
write!(w, "+ {}", self.offset())?;
|
||||
}
|
||||
|
||||
write!(w, ", ")?;
|
||||
self.value.write(mng, w)?;
|
||||
self.value().write(mng, w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for MemoryGrow {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
let result = self.result;
|
||||
let memory = self.memory;
|
||||
let result = self.result();
|
||||
let memory = self.memory();
|
||||
|
||||
write!(w, "reg_{result} = rt.allocator.grow(memory_at_{memory}, ")?;
|
||||
self.value.write(mng, w)?;
|
||||
self.size().write(mng, w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
@ -285,14 +285,14 @@ impl Driver for Statement {
|
||||
|
||||
fn write_parameter_list(ast: &FuncData, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "function(")?;
|
||||
write_ascending("param", 0..ast.num_param, w)?;
|
||||
write_ascending("param", 0..ast.num_param(), w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
|
||||
fn write_variable_list(ast: &FuncData, w: &mut dyn Write) -> Result<()> {
|
||||
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 typed = if data.value_type() == ValueType::I64 {
|
||||
"0LL"
|
||||
@ -310,9 +310,9 @@ fn write_variable_list(ast: &FuncData, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, " ")?;
|
||||
}
|
||||
|
||||
if ast.num_stack != 0 {
|
||||
if ast.num_stack() != 0 {
|
||||
write!(w, "local ")?;
|
||||
write_ascending("reg", 0..ast.num_stack, w)?;
|
||||
write_ascending("reg", 0..ast.num_stack(), w)?;
|
||||
write!(w, " ")?;
|
||||
}
|
||||
|
||||
@ -331,12 +331,12 @@ impl Driver for FuncData {
|
||||
}
|
||||
|
||||
mng.set_table_map(br_map);
|
||||
mng.set_num_param(self.num_param);
|
||||
self.code.write(mng, w)?;
|
||||
mng.set_num_param(self.num_param());
|
||||
self.code().write(mng, w)?;
|
||||
|
||||
if self.num_result != 0 {
|
||||
if self.num_result() != 0 {
|
||||
write!(w, "return ")?;
|
||||
write_ascending("reg", 0..self.num_result, w)?;
|
||||
write_ascending("reg", 0..self.num_result(), 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<()> {
|
||||
let func = Builder::from_type_info(type_info).build_anonymous(code);
|
||||
|
||||
if let Some(Statement::SetTemporary(stat)) = func.code.code.last() {
|
||||
stat.value.write(&mut Manager::default(), w)?;
|
||||
if let Some(Statement::SetTemporary(stat)) = func.code().code().last() {
|
||||
stat.value().write(&mut Manager::default(), w)?;
|
||||
} else {
|
||||
panic!("Not a valid constant");
|
||||
}
|
||||
|
@ -15,14 +15,14 @@ struct Visit {
|
||||
|
||||
impl Visitor for Visit {
|
||||
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.local_set.insert(("load", name));
|
||||
}
|
||||
|
||||
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.local_set.insert(("store", name));
|
||||
@ -40,37 +40,37 @@ impl Visitor for Visit {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
let name = v.op.as_name();
|
||||
let name = v.op_type().as_name();
|
||||
|
||||
self.local_set.insert(name);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
let name = v.op.as_name();
|
||||
let name = v.op_type().as_name();
|
||||
|
||||
self.local_set.insert(name);
|
||||
}
|
||||
|
||||
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) {
|
||||
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
|
||||
.local_data
|
||||
.local_data()
|
||||
.iter()
|
||||
.any(|v| v.value_type() == ValueType::I64)
|
||||
{
|
||||
|
@ -31,40 +31,40 @@ macro_rules! impl_write_number {
|
||||
impl Driver for Select {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "(")?;
|
||||
write_condition(&self.cond, mng, w)?;
|
||||
write_condition(self.condition(), mng, w)?;
|
||||
write!(w, "and ")?;
|
||||
self.a.write(mng, w)?;
|
||||
self.on_true().write(mng, w)?;
|
||||
write!(w, "or ")?;
|
||||
self.b.write(mng, w)?;
|
||||
self.on_false().write(mng, w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for GetTemporary {
|
||||
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "reg_{} ", self.var)
|
||||
write!(w, "reg_{} ", self.var())
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for GetLocal {
|
||||
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 {
|
||||
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 {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "load_{}(memory_at_0, ", self.what.as_name())?;
|
||||
self.pointer.write(mng, w)?;
|
||||
write!(w, "load_{}(memory_at_0, ", self.load_type().as_name())?;
|
||||
self.pointer().write(mng, w)?;
|
||||
|
||||
if self.offset != 0 {
|
||||
write!(w, "+ {}", self.offset)?;
|
||||
if self.offset() != 0 {
|
||||
write!(w, "+ {}", self.offset())?;
|
||||
}
|
||||
|
||||
write!(w, ")")
|
||||
@ -73,7 +73,7 @@ impl Driver for LoadAt {
|
||||
|
||||
impl Driver for MemorySize {
|
||||
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 {
|
||||
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}(")?;
|
||||
self.rhs.write(mng, w)?;
|
||||
self.rhs().write(mng, w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for BinOp {
|
||||
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, "(")?;
|
||||
self.lhs.write(mng, w)?;
|
||||
self.lhs().write(mng, w)?;
|
||||
write!(w, "{symbol} ")?;
|
||||
self.rhs.write(mng, w)?;
|
||||
self.rhs().write(mng, w)?;
|
||||
write!(w, ")")
|
||||
} else {
|
||||
let (head, tail) = self.op.as_name();
|
||||
let (head, tail) = self.op_type().as_name();
|
||||
|
||||
write!(w, "{head}_{tail}(")?;
|
||||
self.lhs.write(mng, w)?;
|
||||
self.lhs().write(mng, w)?;
|
||||
write!(w, ", ")?;
|
||||
self.rhs.write(mng, w)?;
|
||||
self.rhs().write(mng, 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<()> {
|
||||
if let Some(symbol) = cmp_symbol_of(cmp.op) {
|
||||
cmp.lhs.write(mng, w)?;
|
||||
if let Some(symbol) = cmp_symbol_of(cmp.op_type()) {
|
||||
cmp.lhs().write(mng, w)?;
|
||||
write!(w, "{symbol} ")?;
|
||||
cmp.rhs.write(mng, w)
|
||||
cmp.rhs().write(mng, w)
|
||||
} else {
|
||||
let (head, tail) = cmp.op.as_name();
|
||||
let (head, tail) = cmp.op_type().as_name();
|
||||
|
||||
write!(w, "{head}_{tail}(")?;
|
||||
cmp.lhs.write(mng, w)?;
|
||||
cmp.lhs().write(mng, w)?;
|
||||
write!(w, ", ")?;
|
||||
cmp.rhs.write(mng, w)?;
|
||||
cmp.rhs().write(mng, w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
@ -17,21 +17,21 @@ use super::manager::{
|
||||
|
||||
impl Driver for Br {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
if !self.align.is_aligned() {
|
||||
write_ascending("reg", self.align.new_range(), w)?;
|
||||
if !self.align().is_aligned() {
|
||||
write_ascending("reg", self.align().new_range(), w)?;
|
||||
write!(w, " = ")?;
|
||||
write_ascending("reg", self.align.old_range(), w)?;
|
||||
write_ascending("reg", self.align().old_range(), w)?;
|
||||
write!(w, " ")?;
|
||||
}
|
||||
|
||||
if self.target == 0 {
|
||||
if self.target() == 0 {
|
||||
if let Some(&Label::Backward) = mng.label_list().last() {
|
||||
write!(w, "continue ")?;
|
||||
} else {
|
||||
write!(w, "break ")?;
|
||||
}
|
||||
} 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, "break ")?;
|
||||
@ -44,8 +44,8 @@ impl Driver for 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();
|
||||
|
||||
data.sort_by_key(|v| v.target);
|
||||
data.dedup_by_key(|v| v.target);
|
||||
data.sort_by_key(|v| v.target());
|
||||
data.dedup_by_key(|v| v.target());
|
||||
|
||||
data
|
||||
}
|
||||
@ -64,13 +64,13 @@ fn write_search_layer(
|
||||
let br = list[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!(w, "else")?;
|
||||
}
|
||||
|
||||
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!(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] =")?;
|
||||
|
||||
table
|
||||
.data
|
||||
.data()
|
||||
.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, "local temp = br_map[{id}][")?;
|
||||
table.cond.write(mng, w)?;
|
||||
write!(w, "] or {} ", table.default.target)
|
||||
table.condition().write(mng, w)?;
|
||||
write!(w, "] or {} ", table.default().target())
|
||||
}
|
||||
|
||||
impl Driver for BrTable {
|
||||
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
|
||||
// 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
|
||||
// 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
|
||||
// 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_search_layer(0..list.len(), &list, mng, w)
|
||||
@ -157,9 +157,9 @@ impl Driver for Forward {
|
||||
|
||||
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)?;
|
||||
} else {
|
||||
write!(w, "break ")?;
|
||||
@ -178,9 +178,9 @@ impl Driver for Backward {
|
||||
|
||||
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)?;
|
||||
} else {
|
||||
write!(w, "break ")?;
|
||||
@ -196,9 +196,9 @@ impl Driver for Backward {
|
||||
impl Driver for BrIf {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "if ")?;
|
||||
write_condition(&self.cond, mng, w)?;
|
||||
write_condition(self.condition(), mng, w)?;
|
||||
write!(w, "then ")?;
|
||||
self.target.write(mng, w)?;
|
||||
self.target().write(mng, w)?;
|
||||
write!(w, "end ")
|
||||
}
|
||||
}
|
||||
@ -206,15 +206,15 @@ impl Driver for BrIf {
|
||||
impl Driver for If {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "if ")?;
|
||||
write_condition(&self.cond, mng, w)?;
|
||||
write_condition(self.condition(), mng, w)?;
|
||||
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 ")?;
|
||||
|
||||
falsey.write(mng, w)?;
|
||||
v.write(mng, w)?;
|
||||
}
|
||||
|
||||
write!(w, "end ")
|
||||
@ -232,70 +232,70 @@ fn write_call_store(result: Range<usize>, w: &mut dyn Write) -> Result<()> {
|
||||
|
||||
impl Driver for Call {
|
||||
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)?;
|
||||
self.param_list.as_slice().write(mng, w)?;
|
||||
write!(w, "FUNC_LIST[{}](", self.function())?;
|
||||
self.param_list().write(mng, w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for CallIndirect {
|
||||
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)?;
|
||||
self.index.write(mng, w)?;
|
||||
write!(w, "TABLE_LIST[{}].data[", self.table())?;
|
||||
self.index().write(mng, w)?;
|
||||
write!(w, "](")?;
|
||||
self.param_list.as_slice().write(mng, w)?;
|
||||
self.param_list().write(mng, w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for SetTemporary {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "reg_{} = ", self.var)?;
|
||||
self.value.write(mng, w)
|
||||
write!(w, "reg_{} = ", self.var())?;
|
||||
self.value().write(mng, w)
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for SetLocal {
|
||||
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, "= ")?;
|
||||
self.value.write(mng, w)
|
||||
self.value().write(mng, w)
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for SetGlobal {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "GLOBAL_LIST[{}].value = ", self.var)?;
|
||||
self.value.write(mng, w)
|
||||
write!(w, "GLOBAL_LIST[{}].value = ", self.var())?;
|
||||
self.value().write(mng, w)
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for StoreAt {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "store_{}(memory_at_0, ", self.what.as_name())?;
|
||||
self.pointer.write(mng, w)?;
|
||||
write!(w, "store_{}(memory_at_0, ", self.store_type().as_name())?;
|
||||
self.pointer().write(mng, w)?;
|
||||
|
||||
if self.offset != 0 {
|
||||
write!(w, "+ {}", self.offset)?;
|
||||
if self.offset() != 0 {
|
||||
write!(w, "+ {}", self.offset())?;
|
||||
}
|
||||
|
||||
write!(w, ", ")?;
|
||||
self.value.write(mng, w)?;
|
||||
self.value().write(mng, w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for MemoryGrow {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
let result = self.result;
|
||||
let memory = self.memory;
|
||||
let result = self.result();
|
||||
let memory = self.memory();
|
||||
|
||||
write!(w, "reg_{result} = rt.allocator.grow(memory_at_{memory}, ")?;
|
||||
self.value.write(mng, w)?;
|
||||
self.size().write(mng, w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
@ -320,14 +320,14 @@ impl Driver for Statement {
|
||||
|
||||
fn write_parameter_list(ast: &FuncData, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "function(")?;
|
||||
write_ascending("param", 0..ast.num_param, w)?;
|
||||
write_ascending("param", 0..ast.num_param(), w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
|
||||
fn write_variable_list(ast: &FuncData, w: &mut dyn Write) -> Result<()> {
|
||||
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 zero = if data.value_type() == ValueType::I64 {
|
||||
"i64_K_ZERO "
|
||||
@ -344,9 +344,9 @@ fn write_variable_list(ast: &FuncData, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, " ")?;
|
||||
}
|
||||
|
||||
if ast.num_stack != 0 {
|
||||
if ast.num_stack() != 0 {
|
||||
write!(w, "local ")?;
|
||||
write_ascending("reg", 0..ast.num_stack, w)?;
|
||||
write_ascending("reg", 0..ast.num_stack(), w)?;
|
||||
write!(w, " ")?;
|
||||
}
|
||||
|
||||
@ -366,12 +366,12 @@ impl Driver for FuncData {
|
||||
}
|
||||
|
||||
mng.set_table_map(br_map);
|
||||
mng.set_num_param(self.num_param);
|
||||
self.code.write(mng, w)?;
|
||||
mng.set_num_param(self.num_param());
|
||||
self.code().write(mng, w)?;
|
||||
|
||||
if self.num_result != 0 {
|
||||
if self.num_result() != 0 {
|
||||
write!(w, "return ")?;
|
||||
write_ascending("reg", 0..self.num_result, w)?;
|
||||
write_ascending("reg", 0..self.num_result(), 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<()> {
|
||||
let func = Builder::from_type_info(type_info).build_anonymous(code);
|
||||
|
||||
if let Some(Statement::SetTemporary(stat)) = func.code.code.last() {
|
||||
stat.value.write(&mut Manager::default(), w)?;
|
||||
if let Some(Statement::SetTemporary(stat)) = func.code().code().last() {
|
||||
stat.value().write(&mut Manager::default(), w)?;
|
||||
} else {
|
||||
panic!("Not a valid constant");
|
||||
}
|
||||
|
@ -182,9 +182,9 @@ impl StatList {
|
||||
leak_on!(leak_global_write, Global);
|
||||
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 {
|
||||
what,
|
||||
load_type,
|
||||
offset,
|
||||
pointer: self.stack.pop().into(),
|
||||
});
|
||||
@ -192,9 +192,9 @@ impl StatList {
|
||||
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 {
|
||||
what,
|
||||
store_type,
|
||||
offset,
|
||||
value: self.stack.pop(),
|
||||
pointer: self.stack.pop(),
|
||||
@ -210,22 +210,22 @@ impl StatList {
|
||||
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 data = Expression::UnOp(UnOp {
|
||||
op,
|
||||
op_type,
|
||||
rhs: rhs.0.into(),
|
||||
});
|
||||
|
||||
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 lhs = self.stack.pop_with_read();
|
||||
|
||||
let data = Expression::BinOp(BinOp {
|
||||
op,
|
||||
op_type,
|
||||
rhs: rhs.0.into(),
|
||||
lhs: lhs.0.into(),
|
||||
});
|
||||
@ -235,12 +235,12 @@ impl StatList {
|
||||
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 lhs = self.stack.pop_with_read();
|
||||
|
||||
let data = Expression::CmpOp(CmpOp {
|
||||
op,
|
||||
op_type,
|
||||
rhs: rhs.0.into(),
|
||||
lhs: lhs.0.into(),
|
||||
});
|
||||
@ -411,13 +411,13 @@ impl<'a> Builder<'a> {
|
||||
BlockData::Forward { .. } => Statement::Forward(now.into()),
|
||||
BlockData::Backward { .. } => Statement::Backward(now.into()),
|
||||
BlockData::If { .. } => Statement::If(If {
|
||||
cond: self.target.stack.pop(),
|
||||
truthy: now.into(),
|
||||
falsey: None,
|
||||
condition: self.target.stack.pop(),
|
||||
on_true: now.into(),
|
||||
on_false: None,
|
||||
}),
|
||||
BlockData::Else { .. } => {
|
||||
if let Statement::If(v) = self.target.code.last_mut().unwrap() {
|
||||
v.falsey = Some(now.into());
|
||||
v.on_false = Some(now.into());
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
@ -454,8 +454,8 @@ impl<'a> Builder<'a> {
|
||||
Br { target, align }
|
||||
}
|
||||
|
||||
fn add_call(&mut self, func: usize) {
|
||||
let arity = self.type_info.rel_arity_of(func);
|
||||
fn add_call(&mut self, function: usize) {
|
||||
let arity = self.type_info.rel_arity_of(function);
|
||||
let param_list = self.target.stack.pop_len(arity.num_param).collect();
|
||||
|
||||
self.target.leak_pre_call();
|
||||
@ -463,7 +463,7 @@ impl<'a> Builder<'a> {
|
||||
let result = self.target.stack.push_temporary(arity.num_result);
|
||||
|
||||
let data = Statement::Call(Call {
|
||||
func,
|
||||
function,
|
||||
result,
|
||||
param_list,
|
||||
});
|
||||
@ -556,7 +556,7 @@ impl<'a> Builder<'a> {
|
||||
}
|
||||
Inst::BrIf(v) => {
|
||||
let data = Statement::BrIf(BrIf {
|
||||
cond: self.target.stack.pop(),
|
||||
condition: self.target.stack.pop(),
|
||||
target: self.get_br_terminator(v.try_into().unwrap()),
|
||||
});
|
||||
|
||||
@ -564,7 +564,7 @@ impl<'a> Builder<'a> {
|
||||
self.target.code.push(data);
|
||||
}
|
||||
Inst::BrTable(ref v) => {
|
||||
let cond = self.target.stack.pop();
|
||||
let condition = self.target.stack.pop();
|
||||
let data = v
|
||||
.table
|
||||
.iter()
|
||||
@ -575,7 +575,7 @@ impl<'a> Builder<'a> {
|
||||
let default = self.get_br_terminator(v.default.try_into().unwrap());
|
||||
|
||||
let term = Terminator::BrTable(BrTable {
|
||||
cond,
|
||||
condition,
|
||||
data,
|
||||
default,
|
||||
});
|
||||
@ -600,20 +600,20 @@ impl<'a> Builder<'a> {
|
||||
self.target.stack.pop();
|
||||
}
|
||||
Inst::Select => {
|
||||
let mut cond = self.target.stack.pop_with_read();
|
||||
let b = self.target.stack.pop_with_read();
|
||||
let a = self.target.stack.pop_with_read();
|
||||
let mut condition = self.target.stack.pop_with_read();
|
||||
let on_false = self.target.stack.pop_with_read();
|
||||
let on_true = self.target.stack.pop_with_read();
|
||||
|
||||
let data = Expression::Select(Select {
|
||||
cond: cond.0.into(),
|
||||
b: b.0.into(),
|
||||
a: a.0.into(),
|
||||
condition: condition.0.into(),
|
||||
on_true: on_true.0.into(),
|
||||
on_false: on_false.0.into(),
|
||||
});
|
||||
|
||||
cond.1.extend(b.1);
|
||||
cond.1.extend(a.1);
|
||||
condition.1.extend(on_true.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) => {
|
||||
let var = i.try_into().unwrap();
|
||||
@ -689,14 +689,14 @@ impl<'a> Builder<'a> {
|
||||
self.target.stack.push(data);
|
||||
}
|
||||
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 memory = i.try_into().unwrap();
|
||||
|
||||
let data = Statement::MemoryGrow(MemoryGrow {
|
||||
result,
|
||||
memory,
|
||||
value,
|
||||
result,
|
||||
size,
|
||||
});
|
||||
|
||||
self.target.leak_memory_write(memory);
|
||||
|
@ -530,39 +530,117 @@ impl TryFrom<&Instruction> for CmpOpType {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GetTemporary {
|
||||
pub var: usize,
|
||||
pub struct Select {
|
||||
pub(crate) condition: Box<Expression>,
|
||||
pub(crate) on_true: Box<Expression>,
|
||||
pub(crate) on_false: Box<Expression>,
|
||||
}
|
||||
|
||||
pub struct Select {
|
||||
pub cond: Box<Expression>,
|
||||
pub a: Box<Expression>,
|
||||
pub b: Box<Expression>,
|
||||
impl Select {
|
||||
#[must_use]
|
||||
pub fn condition(&self) -> &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 var: usize,
|
||||
pub(crate) var: usize,
|
||||
}
|
||||
|
||||
impl GetLocal {
|
||||
#[must_use]
|
||||
pub fn var(&self) -> usize {
|
||||
self.var
|
||||
}
|
||||
}
|
||||
|
||||
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 what: LoadType,
|
||||
pub offset: u32,
|
||||
pub pointer: Box<Expression>,
|
||||
pub(crate) load_type: LoadType,
|
||||
pub(crate) offset: u32,
|
||||
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 memory: usize,
|
||||
pub(crate) memory: usize,
|
||||
}
|
||||
|
||||
impl MemorySize {
|
||||
#[must_use]
|
||||
pub fn memory(&self) -> usize {
|
||||
self.memory
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MemoryGrow {
|
||||
pub result: usize,
|
||||
pub memory: usize,
|
||||
pub value: Box<Expression>,
|
||||
pub(crate) memory: usize,
|
||||
pub(crate) result: usize,
|
||||
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)]
|
||||
@ -598,20 +676,66 @@ impl From<u64> for Value {
|
||||
}
|
||||
|
||||
pub struct UnOp {
|
||||
pub op: UnOpType,
|
||||
pub rhs: Box<Expression>,
|
||||
pub(crate) op_type: UnOpType,
|
||||
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 op: BinOpType,
|
||||
pub lhs: Box<Expression>,
|
||||
pub rhs: Box<Expression>,
|
||||
pub(crate) op_type: BinOpType,
|
||||
pub(crate) lhs: 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 op: CmpOpType,
|
||||
pub lhs: Box<Expression>,
|
||||
pub rhs: Box<Expression>,
|
||||
pub(crate) op_type: CmpOpType,
|
||||
pub(crate) lhs: 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 {
|
||||
@ -628,9 +752,9 @@ pub enum Expression {
|
||||
}
|
||||
|
||||
pub struct Align {
|
||||
pub new: usize,
|
||||
pub old: usize,
|
||||
pub length: usize,
|
||||
pub(crate) new: usize,
|
||||
pub(crate) old: usize,
|
||||
pub(crate) length: usize,
|
||||
}
|
||||
|
||||
impl Align {
|
||||
@ -651,14 +775,43 @@ impl Align {
|
||||
}
|
||||
|
||||
pub struct Br {
|
||||
pub target: usize,
|
||||
pub align: Align,
|
||||
pub(crate) target: usize,
|
||||
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 cond: Expression,
|
||||
pub data: Vec<Br>,
|
||||
pub default: Br,
|
||||
pub(crate) condition: Expression,
|
||||
pub(crate) data: Vec<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 {
|
||||
@ -669,60 +822,210 @@ pub enum Terminator {
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Forward {
|
||||
pub code: Vec<Statement>,
|
||||
pub last: Option<Terminator>,
|
||||
pub(crate) code: Vec<Statement>,
|
||||
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)]
|
||||
pub struct Backward {
|
||||
pub code: Vec<Statement>,
|
||||
pub last: Option<Terminator>,
|
||||
pub(crate) code: Vec<Statement>,
|
||||
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 cond: Expression,
|
||||
pub target: Br,
|
||||
pub(crate) condition: Expression,
|
||||
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 cond: Expression,
|
||||
pub truthy: Forward,
|
||||
pub falsey: Option<Forward>,
|
||||
pub(crate) condition: Expression,
|
||||
pub(crate) on_true: 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 func: usize,
|
||||
pub result: Range<usize>,
|
||||
pub param_list: Vec<Expression>,
|
||||
pub(crate) function: usize,
|
||||
pub(crate) result: Range<usize>,
|
||||
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 table: usize,
|
||||
pub index: Expression,
|
||||
pub result: Range<usize>,
|
||||
pub param_list: Vec<Expression>,
|
||||
pub(crate) table: usize,
|
||||
pub(crate) index: Expression,
|
||||
pub(crate) result: Range<usize>,
|
||||
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 var: usize,
|
||||
pub value: Expression,
|
||||
pub(crate) var: usize,
|
||||
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 var: usize,
|
||||
pub value: Expression,
|
||||
pub(crate) var: usize,
|
||||
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 var: usize,
|
||||
pub value: Expression,
|
||||
pub(crate) var: usize,
|
||||
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 what: StoreType,
|
||||
pub offset: u32,
|
||||
pub pointer: Expression,
|
||||
pub value: Expression,
|
||||
pub(crate) store_type: StoreType,
|
||||
pub(crate) offset: u32,
|
||||
pub(crate) pointer: 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 {
|
||||
@ -740,9 +1043,36 @@ pub enum Statement {
|
||||
}
|
||||
|
||||
pub struct FuncData {
|
||||
pub local_data: Vec<Local>,
|
||||
pub num_result: usize,
|
||||
pub num_param: usize,
|
||||
pub num_stack: usize,
|
||||
pub code: Forward,
|
||||
pub(crate) local_data: Vec<Local>,
|
||||
pub(crate) num_result: usize,
|
||||
pub(crate) num_param: usize,
|
||||
pub(crate) num_stack: usize,
|
||||
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 {
|
||||
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 {
|
||||
|
@ -66,9 +66,9 @@ pub trait Driver<T: Visitor> {
|
||||
|
||||
impl<T: Visitor> Driver<T> for Select {
|
||||
fn accept(&self, visitor: &mut T) {
|
||||
self.cond.accept(visitor);
|
||||
self.a.accept(visitor);
|
||||
self.b.accept(visitor);
|
||||
self.condition().accept(visitor);
|
||||
self.on_true().accept(visitor);
|
||||
self.on_false().accept(visitor);
|
||||
|
||||
visitor.visit_select(self);
|
||||
}
|
||||
@ -94,7 +94,7 @@ impl<T: Visitor> Driver<T> for GetGlobal {
|
||||
|
||||
impl<T: Visitor> Driver<T> for LoadAt {
|
||||
fn accept(&self, visitor: &mut T) {
|
||||
self.pointer.accept(visitor);
|
||||
self.pointer().accept(visitor);
|
||||
|
||||
visitor.visit_load_at(self);
|
||||
}
|
||||
@ -114,7 +114,7 @@ impl<T: Visitor> Driver<T> for Value {
|
||||
|
||||
impl<T: Visitor> Driver<T> for UnOp {
|
||||
fn accept(&self, visitor: &mut T) {
|
||||
self.rhs.accept(visitor);
|
||||
self.rhs().accept(visitor);
|
||||
|
||||
visitor.visit_un_op(self);
|
||||
}
|
||||
@ -122,8 +122,8 @@ impl<T: Visitor> Driver<T> for UnOp {
|
||||
|
||||
impl<T: Visitor> Driver<T> for BinOp {
|
||||
fn accept(&self, visitor: &mut T) {
|
||||
self.lhs.accept(visitor);
|
||||
self.rhs.accept(visitor);
|
||||
self.lhs().accept(visitor);
|
||||
self.rhs().accept(visitor);
|
||||
|
||||
visitor.visit_bin_op(self);
|
||||
}
|
||||
@ -131,8 +131,8 @@ impl<T: Visitor> Driver<T> for BinOp {
|
||||
|
||||
impl<T: Visitor> Driver<T> for CmpOp {
|
||||
fn accept(&self, visitor: &mut T) {
|
||||
self.lhs.accept(visitor);
|
||||
self.rhs.accept(visitor);
|
||||
self.lhs().accept(visitor);
|
||||
self.rhs().accept(visitor);
|
||||
|
||||
visitor.visit_cmp_op(self);
|
||||
}
|
||||
@ -165,7 +165,7 @@ impl<T: Visitor> Driver<T> for Br {
|
||||
|
||||
impl<T: Visitor> Driver<T> for BrTable {
|
||||
fn accept(&self, visitor: &mut T) {
|
||||
self.cond.accept(visitor);
|
||||
self.condition().accept(visitor);
|
||||
|
||||
visitor.visit_br_table(self);
|
||||
}
|
||||
@ -185,11 +185,11 @@ impl<T: Visitor> Driver<T> for Terminator {
|
||||
|
||||
impl<T: Visitor> Driver<T> for Forward {
|
||||
fn accept(&self, visitor: &mut T) {
|
||||
for v in &self.code {
|
||||
for v in self.code() {
|
||||
v.accept(visitor);
|
||||
}
|
||||
|
||||
if let Some(v) = &self.last {
|
||||
if let Some(v) = self.last() {
|
||||
v.accept(visitor);
|
||||
}
|
||||
|
||||
@ -199,11 +199,11 @@ impl<T: Visitor> Driver<T> for Forward {
|
||||
|
||||
impl<T: Visitor> Driver<T> for Backward {
|
||||
fn accept(&self, visitor: &mut T) {
|
||||
for v in &self.code {
|
||||
for v in self.code() {
|
||||
v.accept(visitor);
|
||||
}
|
||||
|
||||
if let Some(v) = &self.last {
|
||||
if let Some(v) = self.last() {
|
||||
v.accept(visitor);
|
||||
}
|
||||
|
||||
@ -213,7 +213,7 @@ impl<T: Visitor> Driver<T> for Backward {
|
||||
|
||||
impl<T: Visitor> Driver<T> for BrIf {
|
||||
fn accept(&self, visitor: &mut T) {
|
||||
self.cond.accept(visitor);
|
||||
self.condition().accept(visitor);
|
||||
|
||||
visitor.visit_br_if(self);
|
||||
}
|
||||
@ -221,10 +221,10 @@ impl<T: Visitor> Driver<T> for BrIf {
|
||||
|
||||
impl<T: Visitor> Driver<T> for If {
|
||||
fn accept(&self, visitor: &mut T) {
|
||||
self.cond.accept(visitor);
|
||||
self.truthy.accept(visitor);
|
||||
self.condition().accept(visitor);
|
||||
self.on_true().accept(visitor);
|
||||
|
||||
if let Some(v) = &self.falsey {
|
||||
if let Some(v) = self.on_false() {
|
||||
v.accept(visitor);
|
||||
}
|
||||
|
||||
@ -234,7 +234,7 @@ impl<T: Visitor> Driver<T> for If {
|
||||
|
||||
impl<T: Visitor> Driver<T> for Call {
|
||||
fn accept(&self, visitor: &mut T) {
|
||||
for v in &self.param_list {
|
||||
for v in self.param_list() {
|
||||
v.accept(visitor);
|
||||
}
|
||||
|
||||
@ -244,9 +244,9 @@ impl<T: Visitor> Driver<T> for Call {
|
||||
|
||||
impl<T: Visitor> Driver<T> for CallIndirect {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -256,7 +256,7 @@ impl<T: Visitor> Driver<T> for CallIndirect {
|
||||
|
||||
impl<T: Visitor> Driver<T> for SetTemporary {
|
||||
fn accept(&self, visitor: &mut T) {
|
||||
self.value.accept(visitor);
|
||||
self.value().accept(visitor);
|
||||
|
||||
visitor.visit_set_temporary(self);
|
||||
}
|
||||
@ -264,7 +264,7 @@ impl<T: Visitor> Driver<T> for SetTemporary {
|
||||
|
||||
impl<T: Visitor> Driver<T> for SetLocal {
|
||||
fn accept(&self, visitor: &mut T) {
|
||||
self.value.accept(visitor);
|
||||
self.value().accept(visitor);
|
||||
|
||||
visitor.visit_set_local(self);
|
||||
}
|
||||
@ -272,7 +272,7 @@ impl<T: Visitor> Driver<T> for SetLocal {
|
||||
|
||||
impl<T: Visitor> Driver<T> for SetGlobal {
|
||||
fn accept(&self, visitor: &mut T) {
|
||||
self.value.accept(visitor);
|
||||
self.value().accept(visitor);
|
||||
|
||||
visitor.visit_set_global(self);
|
||||
}
|
||||
@ -280,8 +280,8 @@ impl<T: Visitor> Driver<T> for SetGlobal {
|
||||
|
||||
impl<T: Visitor> Driver<T> for StoreAt {
|
||||
fn accept(&self, visitor: &mut T) {
|
||||
self.pointer.accept(visitor);
|
||||
self.value.accept(visitor);
|
||||
self.pointer().accept(visitor);
|
||||
self.value().accept(visitor);
|
||||
|
||||
visitor.visit_store_at(self);
|
||||
}
|
||||
@ -289,7 +289,7 @@ impl<T: Visitor> Driver<T> for StoreAt {
|
||||
|
||||
impl<T: Visitor> Driver<T> for MemoryGrow {
|
||||
fn accept(&self, visitor: &mut T) {
|
||||
self.value.accept(visitor);
|
||||
self.size().accept(visitor);
|
||||
|
||||
visitor.visit_memory_grow(self);
|
||||
}
|
||||
@ -317,6 +317,6 @@ impl<T: Visitor> Driver<T> for Statement {
|
||||
|
||||
impl<T: Visitor> Driver<T> for FuncData {
|
||||
fn accept(&self, visitor: &mut T) {
|
||||
self.code.accept(visitor);
|
||||
self.code().accept(visitor);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user