diff options
Diffstat (limited to 'libsolidity/codegen')
-rw-r--r-- | libsolidity/codegen/CompilerContext.cpp | 21 | ||||
-rw-r--r-- | libsolidity/codegen/CompilerContext.h | 10 |
2 files changed, 26 insertions, 5 deletions
diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 7577a606..a8316109 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -70,19 +70,30 @@ void CompilerContext::callLowLevelFunction( eth::AssemblyItem retTag = pushNewTag(); CompilerUtils(*this).moveIntoStack(_inArgs); + *this << lowLevelFunctionTag(_name, _inArgs, _outArgs, _generator); + + appendJump(eth::AssemblyItem::JumpType::IntoFunction); + adjustStackOffset(int(_outArgs) - 1 - _inArgs); + *this << retTag.tag(); +} + +eth::AssemblyItem CompilerContext::lowLevelFunctionTag( + string const& _name, + unsigned _inArgs, + unsigned _outArgs, + function<void(CompilerContext&)> const& _generator +) +{ auto it = m_lowLevelFunctions.find(_name); if (it == m_lowLevelFunctions.end()) { eth::AssemblyItem tag = newTag().pushTag(); m_lowLevelFunctions.insert(make_pair(_name, tag)); m_lowLevelFunctionGenerationQueue.push(make_tuple(_name, _inArgs, _outArgs, _generator)); - *this << tag; + return tag; } else - *this << it->second; - appendJump(eth::AssemblyItem::JumpType::IntoFunction); - adjustStackOffset(int(_outArgs) - 1 - _inArgs); - *this << retTag.tag(); + return it->second; } void CompilerContext::appendMissingLowLevelFunctions() diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index 58d6cb2a..c37142c9 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -104,6 +104,16 @@ public: unsigned _outArgs, std::function<void(CompilerContext&)> const& _generator ); + /// Returns the tag of the named low-level function and inserts the generator into the + /// list of low-level-functions to be generated, unless it already exists. + /// Note that the generator should not assume that objects are still alive when it is called, + /// unless they are guaranteed to be alive for the whole run of the compiler (AST nodes, for example). + eth::AssemblyItem lowLevelFunctionTag( + std::string const& _name, + unsigned _inArgs, + unsigned _outArgs, + std::function<void(CompilerContext&)> const& _generator + ); /// Generates the code for missing low-level functions, i.e. calls the generators passed above. void appendMissingLowLevelFunctions(); |