From 73771f5bb2d8aee1b71dfcc909a60aa47c591dec Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 25 Aug 2017 17:04:31 +0200 Subject: Named assembly labels. --- libjulia/backends/evm/AbstractAssembly.h | 2 ++ libjulia/backends/evm/EVMAssembly.cpp | 8 ++++++++ libjulia/backends/evm/EVMAssembly.h | 3 +++ libjulia/backends/evm/EVMCodeTransform.cpp | 30 ++++++++++++++++++++++-------- libjulia/backends/evm/EVMCodeTransform.h | 9 +++++++-- 5 files changed, 42 insertions(+), 10 deletions(-) (limited to 'libjulia') diff --git a/libjulia/backends/evm/AbstractAssembly.h b/libjulia/backends/evm/AbstractAssembly.h index cfc9b8a5..8e90a912 100644 --- a/libjulia/backends/evm/AbstractAssembly.h +++ b/libjulia/backends/evm/AbstractAssembly.h @@ -66,6 +66,8 @@ public: virtual void appendLabelReference(LabelID _labelId) = 0; /// Generate a new unique label. virtual LabelID newLabelId() = 0; + /// Returns a label identified by the given name. Creates it if it does not yet exist. + virtual LabelID namedLabel(std::string const& _name) = 0; /// Append a reference to a to-be-linked symobl. /// Currently, we assume that the value is always a 20 byte number. virtual void appendLinkerSymbol(std::string const& _name) = 0; diff --git a/libjulia/backends/evm/EVMAssembly.cpp b/libjulia/backends/evm/EVMAssembly.cpp index 173d5e93..1d499b20 100644 --- a/libjulia/backends/evm/EVMAssembly.cpp +++ b/libjulia/backends/evm/EVMAssembly.cpp @@ -77,6 +77,14 @@ EVMAssembly::LabelID EVMAssembly::newLabelId() return m_nextLabelId++; } +AbstractAssembly::LabelID EVMAssembly::namedLabel(string const& _name) +{ + solAssert(!_name.empty(), ""); + if (!m_namedLabels.count(_name)) + m_namedLabels[_name] = newLabelId(); + return m_namedLabels[_name]; +} + void EVMAssembly::appendLinkerSymbol(string const&) { solAssert(false, "Linker symbols not yet implemented."); diff --git a/libjulia/backends/evm/EVMAssembly.h b/libjulia/backends/evm/EVMAssembly.h index 69585822..593cee6a 100644 --- a/libjulia/backends/evm/EVMAssembly.h +++ b/libjulia/backends/evm/EVMAssembly.h @@ -52,6 +52,8 @@ public: virtual void appendLabelReference(LabelID _labelId) override; /// Generate a new unique label. virtual LabelID newLabelId() override; + /// Returns a label identified by the given name. Creates it if it does not yet exist. + virtual LabelID namedLabel(std::string const& _name) override; /// Append a reference to a to-be-linked symobl. /// Currently, we assume that the value is always a 20 byte number. virtual void appendLinkerSymbol(std::string const& _name) override; @@ -85,6 +87,7 @@ private: LabelID m_nextLabelId = 0; int m_stackHeight = 0; bytes m_bytecode; + std::map m_namedLabels; std::map m_labelPositions; std::map m_labelReferences; std::vector m_assemblySizePositions; diff --git a/libjulia/backends/evm/EVMCodeTransform.cpp b/libjulia/backends/evm/EVMCodeTransform.cpp index 704aa3c1..e0b11cf3 100644 --- a/libjulia/backends/evm/EVMCodeTransform.cpp +++ b/libjulia/backends/evm/EVMCodeTransform.cpp @@ -108,10 +108,10 @@ void CodeTransform::operator()(FunctionCall const& _call) visitExpression(arg); m_assembly.setSourceLocation(_call.location); if (m_evm15) - m_assembly.appendJumpsub(functionEntryID(*function), function->arguments.size(), function->returns.size()); + m_assembly.appendJumpsub(functionEntryID(_call.functionName.name, *function), function->arguments.size(), function->returns.size()); else { - m_assembly.appendJumpTo(functionEntryID(*function), function->returns.size() - function->arguments.size() - 1); + m_assembly.appendJumpTo(functionEntryID(_call.functionName.name, *function), function->returns.size() - function->arguments.size() - 1); m_assembly.appendLabel(returnLabel); m_stackAdjustment--; } @@ -286,12 +286,12 @@ void CodeTransform::operator()(FunctionDefinition const& _function) if (m_evm15) { m_assembly.appendJumpTo(afterFunction, -stackHeightBefore); - m_assembly.appendBeginsub(functionEntryID(function), _function.arguments.size()); + m_assembly.appendBeginsub(functionEntryID(_function.name, function), _function.arguments.size()); } else { m_assembly.appendJumpTo(afterFunction, -stackHeightBefore + height); - m_assembly.appendLabel(functionEntryID(function)); + m_assembly.appendLabel(functionEntryID(_function.name, function)); } m_stackAdjustment += localStackAdjustment; @@ -303,8 +303,16 @@ void CodeTransform::operator()(FunctionDefinition const& _function) m_assembly.appendConstant(u256(0)); } - CodeTransform(m_assembly, m_info, m_julia, m_evm15, m_identifierAccess, localStackAdjustment, m_context) - (_function.body); + CodeTransform( + m_assembly, + m_info, + m_julia, + m_evm15, + m_identifierAccess, + m_useNamedLabelsForFunctions, + localStackAdjustment, + m_context + )(_function.body); { // The stack layout here is: @@ -421,10 +429,16 @@ AbstractAssembly::LabelID CodeTransform::labelID(Scope::Label const& _label) return m_context->labelIDs[&_label]; } -AbstractAssembly::LabelID CodeTransform::functionEntryID(Scope::Function const& _function) +AbstractAssembly::LabelID CodeTransform::functionEntryID(string const& _name, Scope::Function const& _function) { if (!m_context->functionEntryIDs.count(&_function)) - m_context->functionEntryIDs[&_function] = m_assembly.newLabelId(); + { + AbstractAssembly::LabelID id = + m_useNamedLabelsForFunctions ? + m_assembly.namedLabel(_name) : + m_assembly.newLabelId(); + m_context->functionEntryIDs[&_function] = id; + } return m_context->functionEntryIDs[&_function]; } diff --git a/libjulia/backends/evm/EVMCodeTransform.h b/libjulia/backends/evm/EVMCodeTransform.h index cd452c5b..2c0fd10c 100644 --- a/libjulia/backends/evm/EVMCodeTransform.h +++ b/libjulia/backends/evm/EVMCodeTransform.h @@ -50,13 +50,15 @@ public: solidity::assembly::AsmAnalysisInfo& _analysisInfo, bool _julia = false, bool _evm15 = false, - ExternalIdentifierAccess const& _identifierAccess = ExternalIdentifierAccess() + ExternalIdentifierAccess const& _identifierAccess = ExternalIdentifierAccess(), + bool _useNamedLabelsForFunctions = false ): CodeTransform( _assembly, _analysisInfo, _julia, _evm15, _identifierAccess, + _useNamedLabelsForFunctions, _assembly.stackHeight(), std::make_shared() ) @@ -78,6 +80,7 @@ protected: bool _julia, bool _evm15, ExternalIdentifierAccess const& _identifierAccess, + bool _useNamedLabelsForFunctions, int _stackAdjustment, std::shared_ptr _context ): @@ -85,6 +88,7 @@ protected: m_info(_analysisInfo), m_julia(_julia), m_evm15(_evm15), + m_useNamedLabelsForFunctions(_useNamedLabelsForFunctions), m_identifierAccess(_identifierAccess), m_stackAdjustment(_stackAdjustment), m_context(_context) @@ -110,7 +114,7 @@ private: /// @returns the label ID corresponding to the given label, allocating a new one if /// necessary. AbstractAssembly::LabelID labelID(solidity::assembly::Scope::Label const& _label); - AbstractAssembly::LabelID functionEntryID(solidity::assembly::Scope::Function const& _function); + AbstractAssembly::LabelID functionEntryID(std::string const& _name, solidity::assembly::Scope::Function const& _function); /// Generates code for an expression that is supposed to return a single value. void visitExpression(solidity::assembly::Statement const& _expression); @@ -136,6 +140,7 @@ private: solidity::assembly::Scope* m_scope = nullptr; bool m_julia = false; bool m_evm15 = false; + bool m_useNamedLabelsForFunctions = false; ExternalIdentifierAccess m_identifierAccess; /// Adjustment between the stack height as determined during the analysis phase /// and the stack height in the assembly. This is caused by an initial stack being present -- cgit v1.2.3