Add context-less writing
This commit is contained in:
parent
33bd235c0f
commit
369097c432
@ -10,7 +10,7 @@ use wasm_ast::node::{
|
||||
|
||||
use crate::analyzer::as_symbol::AsSymbol;
|
||||
|
||||
use super::manager::{write_cmp_op, write_condition, write_separated, Driver, Manager};
|
||||
use super::manager::{write_separated, DriverNoContext};
|
||||
|
||||
macro_rules! impl_write_number {
|
||||
($name:tt, $numeric:ty) => {
|
||||
@ -26,40 +26,40 @@ macro_rules! impl_write_number {
|
||||
};
|
||||
}
|
||||
|
||||
impl Driver for Select {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for Select {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "(")?;
|
||||
write_condition(self.condition(), mng, w)?;
|
||||
Condition(self.condition()).write(w)?;
|
||||
write!(w, "and ")?;
|
||||
self.on_true().write(mng, w)?;
|
||||
self.on_true().write(w)?;
|
||||
write!(w, "or ")?;
|
||||
self.on_false().write(mng, w)?;
|
||||
self.on_false().write(w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for GetTemporary {
|
||||
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for GetTemporary {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "reg_{} ", self.var())
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for GetLocal {
|
||||
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for GetLocal {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "loc_{} ", self.var())
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for GetGlobal {
|
||||
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for GetGlobal {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "GLOBAL_LIST[{}].value ", self.var())
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for LoadAt {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for LoadAt {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "load_{}(memory_at_0, ", self.load_type().as_name())?;
|
||||
self.pointer().write(mng, w)?;
|
||||
self.pointer().write(w)?;
|
||||
|
||||
if self.offset() != 0 {
|
||||
write!(w, "+ {}", self.offset())?;
|
||||
@ -69,8 +69,8 @@ impl Driver for LoadAt {
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for MemorySize {
|
||||
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for MemorySize {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "memory_at_{}.min ", self.memory())
|
||||
}
|
||||
}
|
||||
@ -78,8 +78,8 @@ impl Driver for MemorySize {
|
||||
impl_write_number!(write_f32, f32);
|
||||
impl_write_number!(write_f64, f64);
|
||||
|
||||
impl Driver for Value {
|
||||
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for Value {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
match self {
|
||||
Self::I32(i) => write!(w, "{i} "),
|
||||
Self::I64(i) => write!(w, "{i}LL "),
|
||||
@ -89,63 +89,98 @@ impl Driver for Value {
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for UnOp {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for UnOp {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
let (a, b) = self.op_type().as_name();
|
||||
|
||||
write!(w, "{a}_{b}(")?;
|
||||
self.rhs().write(mng, w)?;
|
||||
self.rhs().write(w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for BinOp {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for BinOp {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
if let Some(symbol) = self.op_type().as_symbol() {
|
||||
write!(w, "(")?;
|
||||
self.lhs().write(mng, w)?;
|
||||
self.lhs().write(w)?;
|
||||
write!(w, "{symbol} ")?;
|
||||
self.rhs().write(mng, w)?;
|
||||
self.rhs().write(w)?;
|
||||
write!(w, ")")
|
||||
} else {
|
||||
let (head, tail) = self.op_type().as_name();
|
||||
|
||||
write!(w, "{head}_{tail}(")?;
|
||||
self.lhs().write(mng, w)?;
|
||||
self.lhs().write(w)?;
|
||||
write!(w, ", ")?;
|
||||
self.rhs().write(mng, w)?;
|
||||
self.rhs().write(w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for CmpOp {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
struct CmpOpBoolean<'a>(&'a CmpOp);
|
||||
|
||||
impl DriverNoContext for CmpOpBoolean<'_> {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
let cmp = self.0;
|
||||
|
||||
if let Some(symbol) = cmp.op_type().as_symbol() {
|
||||
cmp.lhs().write(w)?;
|
||||
write!(w, "{symbol} ")?;
|
||||
cmp.rhs().write(w)
|
||||
} else {
|
||||
let (head, tail) = cmp.op_type().as_name();
|
||||
|
||||
write!(w, "{head}_{tail}(")?;
|
||||
cmp.lhs().write(w)?;
|
||||
write!(w, ", ")?;
|
||||
cmp.rhs().write(w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DriverNoContext for CmpOp {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "(")?;
|
||||
write_cmp_op(self, mng, w)?;
|
||||
CmpOpBoolean(self).write(w)?;
|
||||
write!(w, "and 1 or 0)")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for Expression {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
match self {
|
||||
Self::Select(e) => e.write(mng, w),
|
||||
Self::GetTemporary(e) => e.write(mng, w),
|
||||
Self::GetLocal(e) => e.write(mng, w),
|
||||
Self::GetGlobal(e) => e.write(mng, w),
|
||||
Self::LoadAt(e) => e.write(mng, w),
|
||||
Self::MemorySize(e) => e.write(mng, w),
|
||||
Self::Value(e) => e.write(mng, w),
|
||||
Self::UnOp(e) => e.write(mng, w),
|
||||
Self::BinOp(e) => e.write(mng, w),
|
||||
Self::CmpOp(e) => e.write(mng, w),
|
||||
pub struct Condition<'a>(pub &'a Expression);
|
||||
|
||||
impl DriverNoContext for Condition<'_> {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
if let Expression::CmpOp(node) = self.0 {
|
||||
CmpOpBoolean(node).write(w)
|
||||
} else {
|
||||
self.0.write(w)?;
|
||||
write!(w, "~= 0 ")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for &[Expression] {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write_separated(self.iter(), |e, w| e.write(mng, w), w)
|
||||
impl DriverNoContext for Expression {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
match self {
|
||||
Self::Select(e) => e.write(w),
|
||||
Self::GetTemporary(e) => e.write(w),
|
||||
Self::GetLocal(e) => e.write(w),
|
||||
Self::GetGlobal(e) => e.write(w),
|
||||
Self::LoadAt(e) => e.write(w),
|
||||
Self::MemorySize(e) => e.write(w),
|
||||
Self::Value(e) => e.write(w),
|
||||
Self::UnOp(e) => e.write(w),
|
||||
Self::BinOp(e) => e.write(w),
|
||||
Self::CmpOp(e) => e.write(w),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DriverNoContext for &[Expression] {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write_separated(self.iter(), |e, w| e.write(w), w)
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,7 @@ use std::{
|
||||
ops::Range,
|
||||
};
|
||||
|
||||
use wasm_ast::node::{BrTable, CmpOp, Expression};
|
||||
|
||||
use crate::analyzer::as_symbol::AsSymbol;
|
||||
use wasm_ast::node::BrTable;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Manager {
|
||||
@ -46,6 +44,10 @@ pub trait Driver {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()>;
|
||||
}
|
||||
|
||||
pub trait DriverNoContext {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()>;
|
||||
}
|
||||
|
||||
pub fn write_separated<I, T, M>(mut iter: I, mut func: M, w: &mut dyn Write) -> Result<()>
|
||||
where
|
||||
M: FnMut(T, &mut dyn Write) -> Result<()>,
|
||||
@ -65,28 +67,3 @@ where
|
||||
pub fn write_ascending(prefix: &str, range: Range<usize>, w: &mut dyn Write) -> Result<()> {
|
||||
write_separated(range, |i, w| write!(w, "{prefix}_{i}"), w)
|
||||
}
|
||||
|
||||
pub fn write_cmp_op(cmp: &CmpOp, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
if let Some(symbol) = cmp.op_type().as_symbol() {
|
||||
cmp.lhs().write(mng, w)?;
|
||||
write!(w, "{symbol} ")?;
|
||||
cmp.rhs().write(mng, w)
|
||||
} else {
|
||||
let (head, tail) = cmp.op_type().as_name();
|
||||
|
||||
write!(w, "{head}_{tail}(")?;
|
||||
cmp.lhs().write(mng, w)?;
|
||||
write!(w, ", ")?;
|
||||
cmp.rhs().write(mng, w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_condition(data: &Expression, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
if let Expression::CmpOp(node) = data {
|
||||
write_cmp_op(node, mng, w)
|
||||
} else {
|
||||
data.write(mng, w)?;
|
||||
write!(w, "~= 0 ")
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,10 @@ use wasmparser::ValType;
|
||||
|
||||
use crate::analyzer::br_table;
|
||||
|
||||
use super::manager::{write_ascending, write_condition, write_separated, Driver, Manager};
|
||||
use super::{
|
||||
expression::Condition,
|
||||
manager::{write_ascending, write_separated, Driver, DriverNoContext, Manager},
|
||||
};
|
||||
|
||||
impl Driver for Br {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
@ -82,7 +85,7 @@ fn write_table_setup(table: &BrTable, mng: &mut Manager, w: &mut dyn Write) -> R
|
||||
write!(w, "end ")?;
|
||||
|
||||
write!(w, "temp = br_map[{id}][")?;
|
||||
table.condition().write(mng, w)?;
|
||||
table.condition().write(w)?;
|
||||
write!(w, "] or {} ", table.default().target())
|
||||
}
|
||||
|
||||
@ -156,7 +159,7 @@ impl Driver for Block {
|
||||
impl Driver for BrIf {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "if ")?;
|
||||
write_condition(self.condition(), mng, w)?;
|
||||
Condition(self.condition()).write(w)?;
|
||||
write!(w, "then ")?;
|
||||
self.target().write(mng, w)?;
|
||||
write!(w, "end ")
|
||||
@ -166,7 +169,7 @@ impl Driver for BrIf {
|
||||
impl Driver for If {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "if ")?;
|
||||
write_condition(self.condition(), mng, w)?;
|
||||
Condition(self.condition()).write(w)?;
|
||||
write!(w, "then ")?;
|
||||
|
||||
self.on_true().write(mng, w)?;
|
||||
@ -190,71 +193,71 @@ fn write_call_store(result: Range<usize>, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, " = ")
|
||||
}
|
||||
|
||||
impl Driver for Call {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for Call {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write_call_store(self.result(), w)?;
|
||||
|
||||
write!(w, "FUNC_LIST[{}](", self.function())?;
|
||||
self.param_list().write(mng, w)?;
|
||||
self.param_list().write(w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for CallIndirect {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for CallIndirect {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write_call_store(self.result(), w)?;
|
||||
|
||||
write!(w, "TABLE_LIST[{}].data[", self.table())?;
|
||||
self.index().write(mng, w)?;
|
||||
self.index().write(w)?;
|
||||
write!(w, "](")?;
|
||||
self.param_list().write(mng, w)?;
|
||||
self.param_list().write(w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for SetTemporary {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for SetTemporary {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "reg_{} = ", self.var())?;
|
||||
self.value().write(mng, w)
|
||||
self.value().write(w)
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for SetLocal {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for SetLocal {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "loc_{} = ", self.var())?;
|
||||
self.value().write(mng, w)
|
||||
self.value().write(w)
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for SetGlobal {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for SetGlobal {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "GLOBAL_LIST[{}].value = ", self.var())?;
|
||||
self.value().write(mng, w)
|
||||
self.value().write(w)
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for StoreAt {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for StoreAt {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "store_{}(memory_at_0, ", self.store_type().as_name())?;
|
||||
self.pointer().write(mng, w)?;
|
||||
self.pointer().write(w)?;
|
||||
|
||||
if self.offset() != 0 {
|
||||
write!(w, "+ {}", self.offset())?;
|
||||
}
|
||||
|
||||
write!(w, ", ")?;
|
||||
self.value().write(mng, w)?;
|
||||
self.value().write(w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for MemoryGrow {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for MemoryGrow {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
let result = self.result();
|
||||
let memory = self.memory();
|
||||
|
||||
write!(w, "reg_{result} = rt.allocator.grow(memory_at_{memory}, ")?;
|
||||
self.size().write(mng, w)?;
|
||||
self.size().write(w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
@ -265,13 +268,13 @@ impl Driver for Statement {
|
||||
Self::Block(s) => s.write(mng, w),
|
||||
Self::BrIf(s) => s.write(mng, w),
|
||||
Self::If(s) => s.write(mng, w),
|
||||
Self::Call(s) => s.write(mng, w),
|
||||
Self::CallIndirect(s) => s.write(mng, w),
|
||||
Self::SetTemporary(s) => s.write(mng, w),
|
||||
Self::SetLocal(s) => s.write(mng, w),
|
||||
Self::SetGlobal(s) => s.write(mng, w),
|
||||
Self::StoreAt(s) => s.write(mng, w),
|
||||
Self::MemoryGrow(s) => s.write(mng, w),
|
||||
Self::Call(s) => s.write(w),
|
||||
Self::CallIndirect(s) => s.write(w),
|
||||
Self::SetTemporary(s) => s.write(w),
|
||||
Self::SetLocal(s) => s.write(w),
|
||||
Self::SetGlobal(s) => s.write(w),
|
||||
Self::StoreAt(s) => s.write(w),
|
||||
Self::MemoryGrow(s) => s.write(w),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use wasmparser::{
|
||||
|
||||
use crate::{
|
||||
analyzer::localize,
|
||||
backend::manager::{Driver, Manager},
|
||||
backend::manager::{Driver, DriverNoContext, Manager},
|
||||
};
|
||||
|
||||
trait AsIEName {
|
||||
@ -54,7 +54,7 @@ fn write_constant(init: &InitExpr, type_info: &TypeInfo, w: &mut dyn Write) -> R
|
||||
let func = Factory::from_type_info(type_info).create_anonymous(&code);
|
||||
|
||||
if let Some(Statement::SetTemporary(stat)) = func.code().code().last() {
|
||||
stat.value().write(&mut Manager::default(), w)
|
||||
stat.value().write(w)
|
||||
} else {
|
||||
write!(w, r#"error("Valueless constant")"#)
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ use wasm_ast::node::{
|
||||
|
||||
use crate::analyzer::as_symbol::AsSymbol;
|
||||
|
||||
use super::manager::{write_cmp_op, write_condition, write_separated, Driver, Manager};
|
||||
use super::manager::{write_separated, DriverNoContext};
|
||||
|
||||
macro_rules! impl_write_number {
|
||||
($name:tt, $numeric:ty) => {
|
||||
@ -26,40 +26,40 @@ macro_rules! impl_write_number {
|
||||
};
|
||||
}
|
||||
|
||||
impl Driver for Select {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for Select {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "(")?;
|
||||
write_condition(self.condition(), mng, w)?;
|
||||
Condition(self.condition()).write(w)?;
|
||||
write!(w, "and ")?;
|
||||
self.on_true().write(mng, w)?;
|
||||
self.on_true().write(w)?;
|
||||
write!(w, "or ")?;
|
||||
self.on_false().write(mng, w)?;
|
||||
self.on_false().write(w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for GetTemporary {
|
||||
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for GetTemporary {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "reg_{} ", self.var())
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for GetLocal {
|
||||
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for GetLocal {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "loc_{} ", self.var())
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for GetGlobal {
|
||||
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for GetGlobal {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "GLOBAL_LIST[{}].value ", self.var())
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for LoadAt {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for LoadAt {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "load_{}(memory_at_0, ", self.load_type().as_name())?;
|
||||
self.pointer().write(mng, w)?;
|
||||
self.pointer().write(w)?;
|
||||
|
||||
if self.offset() != 0 {
|
||||
write!(w, "+ {}", self.offset())?;
|
||||
@ -69,8 +69,8 @@ impl Driver for LoadAt {
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for MemorySize {
|
||||
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for MemorySize {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "memory_at_{}.min ", self.memory())
|
||||
}
|
||||
}
|
||||
@ -98,8 +98,8 @@ fn write_i64(number: i64, w: &mut dyn Write) -> Result<()> {
|
||||
impl_write_number!(write_f32, f32);
|
||||
impl_write_number!(write_f64, f64);
|
||||
|
||||
impl Driver for Value {
|
||||
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for Value {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
match self {
|
||||
Self::I32(i) => write_i32(*i, w),
|
||||
Self::I64(i) => write_i64(*i, w),
|
||||
@ -109,63 +109,98 @@ impl Driver for Value {
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for UnOp {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for UnOp {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
let (a, b) = self.op_type().as_name();
|
||||
|
||||
write!(w, "{a}_{b}(")?;
|
||||
self.rhs().write(mng, w)?;
|
||||
self.rhs().write(w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for BinOp {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for BinOp {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
if let Some(symbol) = self.op_type().as_symbol() {
|
||||
write!(w, "(")?;
|
||||
self.lhs().write(mng, w)?;
|
||||
self.lhs().write(w)?;
|
||||
write!(w, "{symbol} ")?;
|
||||
self.rhs().write(mng, w)?;
|
||||
self.rhs().write(w)?;
|
||||
write!(w, ")")
|
||||
} else {
|
||||
let (head, tail) = self.op_type().as_name();
|
||||
|
||||
write!(w, "{head}_{tail}(")?;
|
||||
self.lhs().write(mng, w)?;
|
||||
self.lhs().write(w)?;
|
||||
write!(w, ", ")?;
|
||||
self.rhs().write(mng, w)?;
|
||||
self.rhs().write(w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for CmpOp {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
struct CmpOpBoolean<'a>(&'a CmpOp);
|
||||
|
||||
impl DriverNoContext for CmpOpBoolean<'_> {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
let cmp = self.0;
|
||||
|
||||
if let Some(symbol) = cmp.op_type().as_symbol() {
|
||||
cmp.lhs().write(w)?;
|
||||
write!(w, "{symbol} ")?;
|
||||
cmp.rhs().write(w)
|
||||
} else {
|
||||
let (head, tail) = cmp.op_type().as_name();
|
||||
|
||||
write!(w, "{head}_{tail}(")?;
|
||||
cmp.lhs().write(w)?;
|
||||
write!(w, ", ")?;
|
||||
cmp.rhs().write(w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DriverNoContext for CmpOp {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "(")?;
|
||||
write_cmp_op(self, mng, w)?;
|
||||
CmpOpBoolean(self).write(w)?;
|
||||
write!(w, "and 1 or 0)")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for Expression {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
match self {
|
||||
Self::Select(e) => e.write(mng, w),
|
||||
Self::GetTemporary(e) => e.write(mng, w),
|
||||
Self::GetLocal(e) => e.write(mng, w),
|
||||
Self::GetGlobal(e) => e.write(mng, w),
|
||||
Self::LoadAt(e) => e.write(mng, w),
|
||||
Self::MemorySize(e) => e.write(mng, w),
|
||||
Self::Value(e) => e.write(mng, w),
|
||||
Self::UnOp(e) => e.write(mng, w),
|
||||
Self::BinOp(e) => e.write(mng, w),
|
||||
Self::CmpOp(e) => e.write(mng, w),
|
||||
pub struct Condition<'a>(pub &'a Expression);
|
||||
|
||||
impl DriverNoContext for Condition<'_> {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
if let Expression::CmpOp(node) = self.0 {
|
||||
CmpOpBoolean(node).write(w)
|
||||
} else {
|
||||
self.0.write(w)?;
|
||||
write!(w, "~= 0 ")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for &[Expression] {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write_separated(self.iter(), |e, w| e.write(mng, w), w)
|
||||
impl DriverNoContext for Expression {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
match self {
|
||||
Self::Select(e) => e.write(w),
|
||||
Self::GetTemporary(e) => e.write(w),
|
||||
Self::GetLocal(e) => e.write(w),
|
||||
Self::GetGlobal(e) => e.write(w),
|
||||
Self::LoadAt(e) => e.write(w),
|
||||
Self::MemorySize(e) => e.write(w),
|
||||
Self::Value(e) => e.write(w),
|
||||
Self::UnOp(e) => e.write(w),
|
||||
Self::BinOp(e) => e.write(w),
|
||||
Self::CmpOp(e) => e.write(w),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DriverNoContext for &[Expression] {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write_separated(self.iter(), |e, w| e.write(w), w)
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,7 @@ use std::{
|
||||
ops::Range,
|
||||
};
|
||||
|
||||
use wasm_ast::node::{BrTable, CmpOp, Expression, LabelType};
|
||||
|
||||
use crate::analyzer::as_symbol::AsSymbol;
|
||||
use wasm_ast::node::{BrTable, LabelType};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Manager {
|
||||
@ -42,6 +40,10 @@ pub trait Driver {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()>;
|
||||
}
|
||||
|
||||
pub trait DriverNoContext {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()>;
|
||||
}
|
||||
|
||||
pub fn write_separated<I, T, M>(mut iter: I, mut func: M, w: &mut dyn Write) -> Result<()>
|
||||
where
|
||||
M: FnMut(T, &mut dyn Write) -> Result<()>,
|
||||
@ -61,28 +63,3 @@ where
|
||||
pub fn write_ascending(prefix: &str, range: Range<usize>, w: &mut dyn Write) -> Result<()> {
|
||||
write_separated(range, |i, w| write!(w, "{prefix}_{i}"), w)
|
||||
}
|
||||
|
||||
pub fn write_cmp_op(cmp: &CmpOp, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
if let Some(symbol) = cmp.op_type().as_symbol() {
|
||||
cmp.lhs().write(mng, w)?;
|
||||
write!(w, "{symbol} ")?;
|
||||
cmp.rhs().write(mng, w)
|
||||
} else {
|
||||
let (head, tail) = cmp.op_type().as_name();
|
||||
|
||||
write!(w, "{head}_{tail}(")?;
|
||||
cmp.lhs().write(mng, w)?;
|
||||
write!(w, ", ")?;
|
||||
cmp.rhs().write(mng, w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_condition(data: &Expression, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
if let Expression::CmpOp(node) = data {
|
||||
write_cmp_op(node, mng, w)
|
||||
} else {
|
||||
data.write(mng, w)?;
|
||||
write!(w, "~= 0 ")
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,10 @@ use wasmparser::ValType;
|
||||
|
||||
use crate::analyzer::br_target;
|
||||
|
||||
use super::manager::{write_ascending, write_condition, write_separated, Driver, Manager};
|
||||
use super::{
|
||||
expression::Condition,
|
||||
manager::{write_ascending, write_separated, Driver, DriverNoContext, Manager},
|
||||
};
|
||||
|
||||
impl Driver for Br {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
@ -90,7 +93,7 @@ fn write_table_setup(table: &BrTable, mng: &mut Manager, w: &mut dyn Write) -> R
|
||||
write!(w, "end ")?;
|
||||
|
||||
write!(w, "local temp = br_map[{id}][")?;
|
||||
table.condition().write(mng, w)?;
|
||||
table.condition().write(w)?;
|
||||
write!(w, "] or {} ", table.default().target())
|
||||
}
|
||||
|
||||
@ -170,7 +173,7 @@ impl Driver for Block {
|
||||
impl Driver for BrIf {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "if ")?;
|
||||
write_condition(self.condition(), mng, w)?;
|
||||
Condition(self.condition()).write(w)?;
|
||||
write!(w, "then ")?;
|
||||
self.target().write(mng, w)?;
|
||||
write!(w, "end ")
|
||||
@ -180,7 +183,7 @@ impl Driver for BrIf {
|
||||
impl Driver for If {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "if ")?;
|
||||
write_condition(self.condition(), mng, w)?;
|
||||
Condition(self.condition()).write(w)?;
|
||||
write!(w, "then ")?;
|
||||
|
||||
self.on_true().write(mng, w)?;
|
||||
@ -204,71 +207,71 @@ fn write_call_store(result: Range<usize>, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, " = ")
|
||||
}
|
||||
|
||||
impl Driver for Call {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for Call {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write_call_store(self.result(), w)?;
|
||||
|
||||
write!(w, "FUNC_LIST[{}](", self.function())?;
|
||||
self.param_list().write(mng, w)?;
|
||||
self.param_list().write(w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for CallIndirect {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for CallIndirect {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write_call_store(self.result(), w)?;
|
||||
|
||||
write!(w, "TABLE_LIST[{}].data[", self.table())?;
|
||||
self.index().write(mng, w)?;
|
||||
self.index().write(w)?;
|
||||
write!(w, "](")?;
|
||||
self.param_list().write(mng, w)?;
|
||||
self.param_list().write(w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for SetTemporary {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for SetTemporary {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "reg_{} = ", self.var())?;
|
||||
self.value().write(mng, w)
|
||||
self.value().write(w)
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for SetLocal {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for SetLocal {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "loc_{} = ", self.var())?;
|
||||
self.value().write(mng, w)
|
||||
self.value().write(w)
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for SetGlobal {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for SetGlobal {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "GLOBAL_LIST[{}].value = ", self.var())?;
|
||||
self.value().write(mng, w)
|
||||
self.value().write(w)
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for StoreAt {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for StoreAt {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "store_{}(memory_at_0, ", self.store_type().as_name())?;
|
||||
self.pointer().write(mng, w)?;
|
||||
self.pointer().write(w)?;
|
||||
|
||||
if self.offset() != 0 {
|
||||
write!(w, "+ {}", self.offset())?;
|
||||
}
|
||||
|
||||
write!(w, ", ")?;
|
||||
self.value().write(mng, w)?;
|
||||
self.value().write(w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for MemoryGrow {
|
||||
fn write(&self, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
impl DriverNoContext for MemoryGrow {
|
||||
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||
let result = self.result();
|
||||
let memory = self.memory();
|
||||
|
||||
write!(w, "reg_{result} = rt.allocator.grow(memory_at_{memory}, ")?;
|
||||
self.size().write(mng, w)?;
|
||||
self.size().write(w)?;
|
||||
write!(w, ")")
|
||||
}
|
||||
}
|
||||
@ -279,13 +282,13 @@ impl Driver for Statement {
|
||||
Self::Block(s) => s.write(mng, w),
|
||||
Self::BrIf(s) => s.write(mng, w),
|
||||
Self::If(s) => s.write(mng, w),
|
||||
Self::Call(s) => s.write(mng, w),
|
||||
Self::CallIndirect(s) => s.write(mng, w),
|
||||
Self::SetTemporary(s) => s.write(mng, w),
|
||||
Self::SetLocal(s) => s.write(mng, w),
|
||||
Self::SetGlobal(s) => s.write(mng, w),
|
||||
Self::StoreAt(s) => s.write(mng, w),
|
||||
Self::MemoryGrow(s) => s.write(mng, w),
|
||||
Self::Call(s) => s.write(w),
|
||||
Self::CallIndirect(s) => s.write(w),
|
||||
Self::SetTemporary(s) => s.write(w),
|
||||
Self::SetLocal(s) => s.write(w),
|
||||
Self::SetGlobal(s) => s.write(w),
|
||||
Self::StoreAt(s) => s.write(w),
|
||||
Self::MemoryGrow(s) => s.write(w),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use wasmparser::{
|
||||
|
||||
use crate::{
|
||||
analyzer::localize,
|
||||
backend::manager::{Driver, Manager},
|
||||
backend::manager::{Driver, DriverNoContext, Manager},
|
||||
};
|
||||
|
||||
trait AsIEName {
|
||||
@ -54,7 +54,7 @@ fn write_constant(init: &InitExpr, type_info: &TypeInfo, w: &mut dyn Write) -> R
|
||||
let func = Factory::from_type_info(type_info).create_anonymous(&code);
|
||||
|
||||
if let Some(Statement::SetTemporary(stat)) = func.code().code().last() {
|
||||
stat.value().write(&mut Manager::default(), w)
|
||||
stat.value().write(w)
|
||||
} else {
|
||||
write!(w, r#"error("Valueless constant")"#)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user