2626using namespace std ;
2727using namespace solidity ::yul;
2828
29+ std::string const WasmDialect::i64 {" i64" };
30+ std::string const WasmDialect::i32 {" i32" };
31+ std::string const WasmDialect::i32ptr{" i32" }; // Uses "i32" on purpose.
32+
2933WasmDialect::WasmDialect ()
3034{
31- YulString i64 = " i64" _yulstring;
32- YulString i32 = " i32" _yulstring;
33- defaultType = i64 ;
34- boolType = i32 ;
35- types = {i64 , i32 };
35+ YulString i64_type = " i64" _yulstring;
36+ YulString i32_type = " i32" _yulstring;
37+ defaultType = i64_type ;
38+ boolType = i32_type ;
39+ types = {i64_type, i32_type };
3640
3741 for (auto t: types)
3842 for (auto const & name: {
@@ -67,10 +71,10 @@ WasmDialect::WasmDialect()
6771 // TODO: ge_s
6872 " ge_u"
6973 })
70- addFunction (t.str () + " ." + name, {t, t}, {i32 });
74+ addFunction (t.str () + " ." + name, {t, t}, {i32_type });
7175
72- addFunction (" i32.eqz" , {i32 }, {i32 });
73- addFunction (" i64.eqz" , {i64 }, {i32 });
76+ addFunction (" i32.eqz" , {i32_type }, {i32_type });
77+ addFunction (" i64.eqz" , {i64_type }, {i32_type });
7478
7579 for (auto t: types)
7680 for (auto const & name: {
@@ -80,27 +84,27 @@ WasmDialect::WasmDialect()
8084 })
8185 addFunction (t.str () + " ." + name, {t}, {t});
8286
83- addFunction (" i32.wrap_i64" , {i64 }, {i32 });
87+ addFunction (" i32.wrap_i64" , {i64_type }, {i32_type });
8488
85- addFunction (" i64.extend_i32_u" , {i32 }, {i64 });
89+ addFunction (" i64.extend_i32_u" , {i32_type }, {i64_type });
8690
87- addFunction (" i32.store" , {i32 , i32 }, {}, false );
91+ addFunction (" i32.store" , {i32_type, i32_type }, {}, false );
8892 m_functions[" i32.store" _yulstring].sideEffects .invalidatesStorage = false ;
89- addFunction (" i64.store" , {i32 , i64 }, {}, false );
93+ addFunction (" i64.store" , {i32_type, i64_type }, {}, false );
9094 m_functions[" i64.store" _yulstring].sideEffects .invalidatesStorage = false ;
9195 // TODO: add i32.store16, i64.store8, i64.store16, i64.store32
9296
93- addFunction (" i32.store8" , {i32 , i32 }, {}, false );
97+ addFunction (" i32.store8" , {i32_type, i32_type }, {}, false );
9498 m_functions[" i32.store8" _yulstring].sideEffects .invalidatesStorage = false ;
95- addFunction (" i64.store8" , {i32 , i64 }, {}, false );
99+ addFunction (" i64.store8" , {i32_type, i64_type }, {}, false );
96100 m_functions[" i64.store8" _yulstring].sideEffects .invalidatesStorage = false ;
97101
98- addFunction (" i32.load" , {i32 }, {i32 }, false );
102+ addFunction (" i32.load" , {i32_type }, {i32_type }, false );
99103 m_functions[" i32.load" _yulstring].sideEffects .invalidatesStorage = false ;
100104 m_functions[" i32.load" _yulstring].sideEffects .invalidatesMemory = false ;
101105 m_functions[" i32.load" _yulstring].sideEffects .sideEffectFree = true ;
102106 m_functions[" i32.load" _yulstring].sideEffects .sideEffectFreeIfNoMSize = true ;
103- addFunction (" i64.load" , {i32 }, {i64 }, false );
107+ addFunction (" i64.load" , {i32_type }, {i64_type }, false );
104108 m_functions[" i64.load" _yulstring].sideEffects .invalidatesStorage = false ;
105109 m_functions[" i64.load" _yulstring].sideEffects .invalidatesMemory = false ;
106110 m_functions[" i64.load" _yulstring].sideEffects .sideEffectFree = true ;
@@ -109,8 +113,8 @@ WasmDialect::WasmDialect()
109113
110114 // Drop is actually overloaded for all types, but Yul does not support that.
111115 // Because of that, we introduce "i32.drop" and "i64.drop".
112- addFunction (" i32.drop" , {i32 }, {});
113- addFunction (" i64.drop" , {i64 }, {});
116+ addFunction (" i32.drop" , {i32_type }, {});
117+ addFunction (" i64.drop" , {i64_type }, {});
114118
115119 addFunction (" nop" , {}, {});
116120 addFunction (" unreachable" , {}, {}, false );
@@ -119,10 +123,11 @@ WasmDialect::WasmDialect()
119123 m_functions[" unreachable" _yulstring].controlFlowSideEffects .terminates = true ;
120124 m_functions[" unreachable" _yulstring].controlFlowSideEffects .reverts = true ;
121125
122- addFunction (" datasize" , {i64 }, {i64 }, true , {true });
123- addFunction (" dataoffset" , {i64 }, {i64 }, true , {true });
126+ addFunction (" datasize" , {i64_type }, {i64_type }, true , {true });
127+ addFunction (" dataoffset" , {i64_type }, {i64_type }, true , {true });
124128
125129 addEthereumExternals ();
130+ addDebugExternals ();
126131}
127132
128133BuiltinFunction const * WasmDialect::builtin (YulString _name) const
@@ -161,18 +166,6 @@ WasmDialect const& WasmDialect::instance()
161166
162167void WasmDialect::addEthereumExternals ()
163168{
164- // These are not YulStrings because that would be too complicated with regards
165- // to the YulStringRepository reset.
166- static string const i64 {" i64" };
167- static string const i32 {" i32" };
168- static string const i32ptr{" i32" }; // Uses "i32" on purpose.
169- struct External
170- {
171- string name;
172- vector<string> parameters;
173- vector<string> returns;
174- ControlFlowSideEffects controlFlowSideEffects = ControlFlowSideEffects{};
175- };
176169 static vector<External> externals{
177170 {" getAddress" , {i32ptr}, {}},
178171 {" getExternalBalance" , {i32ptr, i32ptr}, {}},
@@ -225,6 +218,34 @@ void WasmDialect::addEthereumExternals()
225218 }
226219}
227220
221+ void WasmDialect::addDebugExternals ()
222+ {
223+ static vector<External> debugExternals {
224+ {" print32" , {i32 }, {}},
225+ {" print64" , {i64 }, {}},
226+ {" printMem" , {i32 , i32 }, {}},
227+ {" printMemHex" , {i32 , i32 }, {}},
228+ {" printStorage" , {i32 }, {}},
229+ {" printStorageHex" , {i32 }, {}},
230+ };
231+ for (External const & ext: debugExternals)
232+ {
233+ YulString name{" debug." + ext.name };
234+ BuiltinFunction& f = m_functions[name];
235+ f.name = name;
236+ for (string const & p: ext.parameters )
237+ f.parameters .emplace_back (YulString (p));
238+ for (string const & p: ext.returns )
239+ f.returns .emplace_back (YulString (p));
240+ // TODO some of them are side effect free.
241+ f.sideEffects = SideEffects::worst ();
242+ f.controlFlowSideEffects = ext.controlFlowSideEffects ;
243+ f.isMSize = false ;
244+ f.sideEffects .invalidatesStorage = false ;
245+ f.literalArguments .reset ();
246+ }
247+ }
248+
228249void WasmDialect::addFunction (
229250 string _name,
230251 vector<YulString> _params,
0 commit comments