aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/codegen/CompilerContext.h
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/codegen/CompilerContext.h')
-rw-r--r--libsolidity/codegen/CompilerContext.h45
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;
};
}