Encapsulate nodes

This commit is contained in:
Rerumu
2022-06-23 16:03:13 -04:00
parent b282bdf490
commit 9db21cc84b
14 changed files with 636 additions and 306 deletions
+32 -32
View File
@@ -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);
+393 -63
View File
@@ -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
}
}
+1 -1
View File
@@ -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 {
+28 -28
View File
@@ -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);
}
}