diff options
author | chriseth <chris@ethereum.org> | 2017-05-27 01:30:42 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-27 01:30:42 +0800 |
commit | 788b64ea6181af6e7e364e86d64508c4809ca9b7 (patch) | |
tree | 2a136a342d6f8980f96043b0f6ce74828f89fdd6 /libjulia/backends/evm/EVMCodeTransform.h | |
parent | e022f11cdb752a07b6c0f824f3e4f91233a19359 (diff) | |
parent | fe32531a16322c9528c34cfbd32924b4c24a1f13 (diff) | |
download | dexon-solidity-788b64ea6181af6e7e364e86d64508c4809ca9b7.tar dexon-solidity-788b64ea6181af6e7e364e86d64508c4809ca9b7.tar.gz dexon-solidity-788b64ea6181af6e7e364e86d64508c4809ca9b7.tar.bz2 dexon-solidity-788b64ea6181af6e7e364e86d64508c4809ca9b7.tar.lz dexon-solidity-788b64ea6181af6e7e364e86d64508c4809ca9b7.tar.xz dexon-solidity-788b64ea6181af6e7e364e86d64508c4809ca9b7.tar.zst dexon-solidity-788b64ea6181af6e7e364e86d64508c4809ca9b7.zip |
Merge pull request #2291 from ethereum/evm15
Allow different assembly types and target machines.
Diffstat (limited to 'libjulia/backends/evm/EVMCodeTransform.h')
-rw-r--r-- | libjulia/backends/evm/EVMCodeTransform.h | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/libjulia/backends/evm/EVMCodeTransform.h b/libjulia/backends/evm/EVMCodeTransform.h new file mode 100644 index 00000000..5408a3aa --- /dev/null +++ b/libjulia/backends/evm/EVMCodeTransform.h @@ -0,0 +1,119 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see <http://www.gnu.org/licenses/>. +*/ +/** + * Common code generator for translating Julia / inline assembly to EVM and EVM1.5. + */ + +#include <libjulia/backends/evm/AbstractAssembly.h> + +#include <libsolidity/interface/Exceptions.h> + +#include <libsolidity/inlineasm/AsmStack.h> +#include <libsolidity/inlineasm/AsmScope.h> + +#include <boost/variant.hpp> + +namespace dev +{ +namespace solidity +{ +namespace assembly +{ +struct Literal; +struct Block; +struct Switch; +struct Label; +struct FunctionalInstruction; +struct Assignment; +struct VariableDeclaration; +struct Instruction; +struct Identifier; +struct StackAssignment; +struct FunctionDefinition; +struct FunctionCall; + +struct AsmAnalysisInfo; +} +} +namespace julia +{ + +class CodeTransform: public boost::static_visitor<> +{ +public: + /// Create the code transformer which appends assembly to _assembly as a side-effect + /// of its creation. + /// @param _identifierAccess used to resolve identifiers external to the inline assembly + CodeTransform( + solidity::ErrorList& _errors, + julia::AbstractAssembly& _assembly, + solidity::assembly::Block const& _block, + solidity::assembly::AsmAnalysisInfo& _analysisInfo, + ExternalIdentifierAccess const& _identifierAccess = ExternalIdentifierAccess() + ): CodeTransform(_errors, _assembly, _block, _analysisInfo, _identifierAccess, _assembly.stackHeight()) + { + } + +private: + CodeTransform( + solidity::ErrorList& _errors, + julia::AbstractAssembly& _assembly, + solidity::assembly::Block const& _block, + solidity::assembly::AsmAnalysisInfo& _analysisInfo, + ExternalIdentifierAccess const& _identifierAccess, + int _initialStackHeight + ); + +public: + void operator()(solidity::assembly::Instruction const& _instruction); + void operator()(solidity::assembly::Literal const& _literal); + void operator()(solidity::assembly::Identifier const& _identifier); + void operator()(solidity::assembly::FunctionalInstruction const& _instr); + void operator()(solidity::assembly::FunctionCall const&); + void operator()(solidity::assembly::Label const& _label); + void operator()(solidity::assembly::StackAssignment const& _assignment); + void operator()(solidity::assembly::Assignment const& _assignment); + void operator()(solidity::assembly::VariableDeclaration const& _varDecl); + void operator()(solidity::assembly::Block const& _block); + void operator()(solidity::assembly::Switch const& _switch); + void operator()(solidity::assembly::FunctionDefinition const&); + +private: + void generateAssignment(solidity::assembly::Identifier const& _variableName, SourceLocation const& _location); + + /// Determines the stack height difference to the given variables. Automatically generates + /// errors if it is not yet in scope or the height difference is too large. Returns 0 on + /// errors and the (positive) stack height difference otherwise. + int variableHeightDiff(solidity::assembly::Scope::Variable const& _var, SourceLocation const& _location, bool _forSwap); + + void expectDeposit(int _deposit, int _oldHeight); + + void checkStackHeight(void const* _astElement); + + /// Assigns the label's id to a value taken from eth::Assembly if it has not yet been set. + void assignLabelIdIfUnset(solidity::assembly::Scope::Label& _label); + + solidity::ErrorList& m_errors; + julia::AbstractAssembly& m_assembly; + solidity::assembly::AsmAnalysisInfo& m_info; + solidity::assembly::Scope& m_scope; + ExternalIdentifierAccess m_identifierAccess; + int const m_initialStackHeight; +}; + +} +} |