1 /* 2 This file is part of solidity. 3 4 solidity is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 solidity is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with solidity. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 // SPDX-License-Identifier: GPL-3.0 18 /** 19 * Common code generator for translating Yul / inline assembly to Wasm. 20 */ 21 22 #pragma once 23 24 #include <libyul/backends/wasm/WasmAST.h> 25 #include <libyul/ASTForward.h> 26 #include <libyul/Dialect.h> 27 #include <libyul/optimiser/NameDispenser.h> 28 #include <libyul/optimiser/TypeInfo.h> 29 30 #include <libsolutil/Common.h> 31 #include <libsolutil/Numeric.h> 32 33 #include <stack> 34 #include <map> 35 36 namespace solidity::yul 37 { 38 struct AsmAnalysisInfo; 39 40 class WasmCodeTransform 41 { 42 public: 43 static wasm::Module run(Dialect const& _dialect, yul::Block const& _ast); 44 45 public: 46 wasm::Expression operator()(yul::Literal const& _literal); 47 wasm::Expression operator()(yul::Identifier const& _identifier); 48 wasm::Expression operator()(yul::FunctionCall const&); 49 wasm::Expression operator()(yul::ExpressionStatement const& _statement); 50 wasm::Expression operator()(yul::Assignment const& _assignment); 51 wasm::Expression operator()(yul::VariableDeclaration const& _varDecl); 52 wasm::Expression operator()(yul::If const& _if); 53 wasm::Expression operator()(yul::Switch const& _switch); 54 wasm::Expression operator()(yul::FunctionDefinition const&); 55 wasm::Expression operator()(yul::ForLoop const&); 56 wasm::Expression operator()(yul::Break const&); 57 wasm::Expression operator()(yul::Continue const&); 58 wasm::Expression operator()(yul::Leave const&); 59 wasm::Expression operator()(yul::Block const& _block); 60 61 private: WasmCodeTransform(Dialect const & _dialect,Block const & _ast,TypeInfo & _typeInfo)62 WasmCodeTransform( 63 Dialect const& _dialect, 64 Block const& _ast, 65 TypeInfo& _typeInfo 66 ): 67 m_dialect(_dialect), 68 m_nameDispenser(_dialect, _ast), 69 m_typeInfo(_typeInfo) 70 {} 71 72 std::unique_ptr<wasm::Expression> visit(yul::Expression const& _expression); 73 wasm::Expression visitReturnByValue(yul::Expression const& _expression); 74 std::vector<wasm::Expression> visit(std::vector<yul::Expression> const& _expressions); 75 wasm::Expression visit(yul::Statement const& _statement); 76 std::vector<wasm::Expression> visit(std::vector<yul::Statement> const& _statements); 77 78 /// Returns an assignment or a block containing multiple assignments. 79 /// @param _variableNames the names of the variables to assign to 80 /// @param _firstValue the value to be assigned to the first variable. If there 81 /// is more than one variable, the values are taken from m_globalVariables. 82 wasm::Expression generateMultiAssignment( 83 std::vector<std::string> _variableNames, 84 std::unique_ptr<wasm::Expression> _firstValue 85 ); 86 87 wasm::FunctionDefinition translateFunction(yul::FunctionDefinition const& _funDef); 88 89 /// Imports an external function into the current module. 90 /// @param _builtin _builtin the builtin that will be imported into the current module. 91 /// @param _module _module the module name under which the external function can be found. 92 /// @param _externalName the name of the external function within the module _module. 93 /// @param _internalName the name of the internal function under that the external function is accessible. 94 void importBuiltinFunction(BuiltinFunction const* _builtin, std::string const& _module, std::string const& _externalName, std::string const& _internalName); 95 96 std::string newLabel(); 97 /// Selects a subset of global variables matching specified sequence of variable types. 98 /// Defines more global variables of a given type if there's not enough. 99 std::vector<size_t> allocateGlobals(std::vector<wasm::Type> const& _typesForGlobals); 100 101 static wasm::Type translatedType(yul::Type _yulType); 102 static wasm::Literal makeLiteral(wasm::Type _type, u256 _value); 103 104 Dialect const& m_dialect; 105 NameDispenser m_nameDispenser; 106 107 std::vector<wasm::VariableDeclaration> m_localVariables; 108 std::vector<wasm::GlobalVariableDeclaration> m_globalVariables; 109 std::map<YulString, wasm::FunctionImport> m_functionsToImport; 110 std::string m_functionBodyLabel; 111 std::stack<std::pair<std::string, std::string>> m_breakContinueLabelNames; 112 TypeInfo& m_typeInfo; 113 }; 114 115 } 116