diff options
Diffstat (limited to 'libsolidity/codegen/CompilerContext.h')
-rw-r--r-- | libsolidity/codegen/CompilerContext.h | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index 8b95c9f5..c4724ee0 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -37,10 +37,6 @@ namespace dev { namespace solidity { -/// Depending on the compilation is on the runtime code or the creation code, -/// the interpretation of internal function values differ. -enum class CompilationMode { Runtime, Creation }; - /** * Context to be shared by all units that compile the same contract. * It stores the generated bytecode and the position of identifiers in memory and on the stack. @@ -48,15 +44,13 @@ enum class CompilationMode { Runtime, Creation }; class CompilerContext { public: - CompilerContext(CompilationMode _mode, CompilerContext* _runtimeContext = nullptr) : - m_mode(_mode), m_runtimeContext(_runtimeContext) + CompilerContext(CompilerContext* _runtimeContext = nullptr) : + m_runtimeContext(_runtimeContext) { - solAssert(m_mode != CompilationMode::Runtime || !m_runtimeContext, "runtime but another runtime context provided"); - solAssert(m_mode != CompilationMode::Creation || m_runtimeContext, "creation but no runtime context provided"); + if (m_runtimeContext) + m_runtimeSub = registerSubroutine(m_runtimeContext->assembly()); } - bool isCreationPhase() const { return m_mode == CompilationMode::Creation; } - void addMagicGlobal(MagicVariableDeclaration const& _declaration); void addStateVariable(VariableDeclaration const& _declaration, u256 const& _storageOffset, unsigned _byteOffset); void addVariable(VariableDeclaration const& _declaration, unsigned _offsetToCurrent = 0); @@ -80,10 +74,10 @@ public: eth::AssemblyItem functionEntryLabelIfExists(Declaration const& _declaration) const; void setInheritanceHierarchy(std::vector<ContractDefinition const*> const& _hierarchy) { m_inheritanceHierarchy = _hierarchy; } /// @returns the entry label of the given function and takes overrides into account. - eth::AssemblyItem virtualFunctionEntryLabel(FunctionDefinition const& _function); - /// @returns the entry label of a function that overrides the given declaration from the most derived class just + FunctionDefinition const& resolveVirtualFunction(FunctionDefinition const& _function); + /// @returns the function that overrides the given declaration from the most derived class just /// above _base in the current inheritance hierarchy. - eth::AssemblyItem superFunctionEntryLabel(FunctionDefinition const& _function, ContractDefinition const& _base); + FunctionDefinition const& superFunction(FunctionDefinition const& _function, ContractDefinition const& _base); FunctionDefinition const* nextConstructor(ContractDefinition const& _contract) const; /// @returns the next function in the queue of functions that are still to be compiled @@ -123,11 +117,15 @@ public: eth::AssemblyItem pushNewTag() { return m_asm.append(m_asm.newPushTag()).tag(); } /// @returns a new tag without pushing any opcodes or data eth::AssemblyItem newTag() { return m_asm.newTag(); } + /// Adds a subroutine to the code (in the data section) + /// @returns the assembly item corresponding to the pushed subroutine, i.e. its offset in the list. + size_t registerSubroutine(eth::Assembly const& _assembly) { return size_t(m_asm.newSub(_assembly).data()); } /// Adds a subroutine to the code (in the data section) and pushes its size (via a tag) - /// on the stack. @returns the assembly item corresponding to the pushed subroutine, i.e. its offset. - eth::AssemblyItem addSubroutine(eth::Assembly const& _assembly) { return m_asm.appendSubSize(_assembly); } + /// on the stack. @returns the pushsub assembly item. + eth::AssemblyItem addSubroutine(eth::Assembly const& _assembly) { auto sub = m_asm.newSub(_assembly); m_asm.append(m_asm.newPushSubSize(size_t(sub.data()))); return sub; } + void appendSubroutineSize(size_t const& _subRoutine) { m_asm.append(m_asm.newPushSubSize(_subRoutine)); } /// Pushes the size of the final program - void appendProgramSize() { return m_asm.appendProgramSize(); } + void appendProgramSize() { m_asm.appendProgramSize(); } /// Adds data to the data section, pushes a reference to the stack eth::AssemblyItem appendData(bytes const& _data) { return m_asm.append(_data); } /// Appends the address (virtual, will be filled in by linker) of a library. @@ -159,6 +157,11 @@ public: void optimise(unsigned _runs = 200) { m_asm.optimise(true, true, _runs); } + /// @returns the runtime context if in creation mode and runtime context is set, nullptr otherwise. + CompilerContext* runtimeContext() { return m_runtimeContext; } + /// @returns the identifier of the runtime subroutine. + size_t runtimeSub() const { return m_runtimeSub; } + eth::Assembly const& assembly() const { return m_asm; } /// @returns non-const reference to the underlying assembly. Should be avoided in favour of /// wrappers in this class. @@ -185,9 +188,9 @@ public: }; private: - /// @returns the entry label of the given function - searches the inheritance hierarchy - /// startig from the given point towards the base. - eth::AssemblyItem virtualFunctionEntryLabel( + /// Searches the inheritance hierarchy towards the base starting from @a _searchStart and returns + /// the first function definition that is overwritten by _function. + FunctionDefinition const& resolveVirtualFunction( FunctionDefinition const& _function, std::vector<ContractDefinition const*>::const_iterator _searchStart ); @@ -241,10 +244,10 @@ private: std::vector<ContractDefinition const*> m_inheritanceHierarchy; /// Stack of current visited AST nodes, used for location attachment std::stack<ASTNode const*> m_visitedNodes; - /// The current mode of the compilation - CompilationMode m_mode; /// The runtime context if in Creation mode, this is used for generating tags that would be stored into the storage and then used at runtime. CompilerContext *m_runtimeContext; + /// The index of the runtime subroutine. + size_t m_runtimeSub = -1; }; } |