nyar_wasm/operations/branch/
mod.rs1use super::*;
2use std::collections::BTreeMap;
3
4#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
15pub struct EnumerationTable {
16 pub branches: BTreeMap<u32, Vec<WasiInstruction>>,
17 pub default: Vec<WasiInstruction>,
18 pub r#return: Vec<WasiType>,
19}
20
21#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
32pub struct JumpTable {
33 pub branches: Vec<JumpCondition>,
34 pub default: Vec<WasiInstruction>,
35 pub r#return: Vec<WasiType>,
36}
37
38#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
39pub struct JumpBranch {
40 pub main: JumpCondition,
42 pub default: Vec<WasiInstruction>,
44 pub select: bool,
46 pub r#return: Vec<WasiType>,
48}
49
50#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
51pub struct JumpCondition {
52 pub condition: Vec<WasiInstruction>,
54 pub action: Vec<WasiInstruction>,
56}
57
58impl JumpBranch {
59 pub fn if_then(r#if: Vec<WasiInstruction>, then: Vec<WasiInstruction>) -> Self {
61 Self { main: JumpCondition { condition: r#if, action: then }, default: vec![], select: false, r#return: vec![] }
62 }
63 pub fn if_then_else(r#if: Vec<WasiInstruction>, then: Vec<WasiInstruction>, r#else: Vec<WasiInstruction>) -> Self {
65 Self { main: JumpCondition { condition: r#if, action: then }, default: r#else, select: false, r#return: vec![] }
66 }
67 pub fn with_return_type(self, r#type: Vec<WasiType>) -> Self {
69 Self { r#return: r#type, ..self }
70 }
71 pub fn with_parallel(self, select: bool) -> Self {
73 Self { select, ..self }
74 }
75}
76
77impl JumpCondition {
78 pub fn new(condition: Vec<WasiInstruction>, action: Vec<WasiInstruction>) -> Self {
79 Self { condition, action }
80 }
81}
82
83impl WasiInstruction {
84 pub fn if_then(r#if: Vec<WasiInstruction>, then: Vec<WasiInstruction>) -> Self {
85 JumpBranch::if_then(r#if, then).into()
86 }
87 pub fn if_then_else(r#if: Vec<WasiInstruction>, then: Vec<WasiInstruction>, r#else: Vec<WasiInstruction>) -> Self {
88 JumpBranch::if_then_else(r#if, then, r#else).into()
89 }
90}
91
92impl Emit for JumpBranch {
93 fn emit<W: Write>(&self, w: &mut WastEncoder<W>) -> std::fmt::Result {
94 for i in &self.main.condition {
95 i.emit(w)?;
96 }
97 let recover = std::mem::take(&mut w.stack);
98 write!(w, "(if")?;
99 w.indent();
100 write!(w, "(then")?;
101 w.indent();
102 for i in &self.main.action {
103 i.emit(w)?;
104 }
105 w.dedent(1);
106 write!(w, "(else")?;
107 w.indent();
108 for i in &self.default {
109 i.emit(w)?;
110 }
111 w.dedent(1);
112 w.dedent(1);
113 w.stack = recover;
114 Ok(())
115 }
116}
117
118impl From<JumpBranch> for WasiInstruction {
119 fn from(value: JumpBranch) -> Self {
120 Self::JumpBranch(value)
121 }
122}