codegen: add a compilation mode and a runtime context to CompilerContext

This commit is contained in:
Yoichi Hirai 2016-11-08 15:25:32 +01:00 committed by chriseth
parent 5011d6339a
commit c9f9b2ab4d
5 changed files with 24 additions and 7 deletions

View File

@ -33,10 +33,10 @@ void Compiler::compileContract(
std::map<const ContractDefinition*, eth::Assembly const*> const& _contracts std::map<const ContractDefinition*, eth::Assembly const*> const& _contracts
) )
{ {
ContractCompiler runtimeCompiler(m_runtimeContext, m_optimize); ContractCompiler runtimeCompiler(CompilationMode::Runtime, nullptr, m_runtimeContext, m_optimize);
runtimeCompiler.compileContract(_contract, _contracts); runtimeCompiler.compileContract(_contract, _contracts);
ContractCompiler creationCompiler(m_context, m_optimize); ContractCompiler creationCompiler(CompilationMode::Creation, &m_runtimeContext, m_context, m_optimize);
m_runtimeSub = creationCompiler.compileConstructor(m_runtimeContext, _contract, _contracts); m_runtimeSub = creationCompiler.compileConstructor(m_runtimeContext, _contract, _contracts);
if (m_optimize) if (m_optimize)
@ -54,7 +54,7 @@ void Compiler::compileClone(
map<ContractDefinition const*, eth::Assembly const*> const& _contracts map<ContractDefinition const*, eth::Assembly const*> const& _contracts
) )
{ {
ContractCompiler cloneCompiler(m_context, m_optimize); ContractCompiler cloneCompiler(CompilationMode::Creation, &m_runtimeContext, m_context, m_optimize);
m_runtimeSub = cloneCompiler.compileClone(_contract, _contracts); m_runtimeSub = cloneCompiler.compileClone(_contract, _contracts);
if (m_optimize) if (m_optimize)

View File

@ -35,7 +35,9 @@ class Compiler
public: public:
explicit Compiler(bool _optimize = false, unsigned _runs = 200): explicit Compiler(bool _optimize = false, unsigned _runs = 200):
m_optimize(_optimize), m_optimize(_optimize),
m_optimizeRuns(_runs) m_optimizeRuns(_runs),
m_context(CompilationMode::Creation, &m_runtimeContext),
m_runtimeContext(CompilationMode::Runtime)
{ } { }
void compileContract( void compileContract(

View File

@ -37,6 +37,10 @@ namespace dev {
namespace solidity { 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. * 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. * It stores the generated bytecode and the position of identifiers in memory and on the stack.
@ -44,6 +48,13 @@ namespace solidity {
class CompilerContext class CompilerContext
{ {
public: public:
CompilerContext(CompilationMode _mode, CompilerContext* _runtimeContext = nullptr) :
m_mode(_mode), 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");
}
bool isCreationPhase() const { return m_mode == CompilationMode::Creation; } bool isCreationPhase() const { return m_mode == CompilationMode::Creation; }
void addMagicGlobal(MagicVariableDeclaration const& _declaration); void addMagicGlobal(MagicVariableDeclaration const& _declaration);
@ -230,6 +241,10 @@ private:
std::vector<ContractDefinition const*> m_inheritanceHierarchy; std::vector<ContractDefinition const*> m_inheritanceHierarchy;
/// Stack of current visited AST nodes, used for location attachment /// Stack of current visited AST nodes, used for location attachment
std::stack<ASTNode const*> m_visitedNodes; 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;
}; };
} }

View File

@ -38,11 +38,11 @@ namespace solidity {
class ContractCompiler: private ASTConstVisitor class ContractCompiler: private ASTConstVisitor
{ {
public: public:
explicit ContractCompiler(CompilerContext& _context, bool _optimise): explicit ContractCompiler(CompilationMode _mode, CompilerContext* _runtimeContext, CompilerContext& _context, bool _optimise):
m_optimise(_optimise), m_optimise(_optimise),
m_context(_context) m_context(_context)
{ {
m_context = CompilerContext(); m_context = CompilerContext(_mode, _runtimeContext);
} }
void compileContract( void compileContract(

View File

@ -136,7 +136,7 @@ bytes compileFirstExpression(
FirstExpressionExtractor extractor(*contract); FirstExpressionExtractor extractor(*contract);
BOOST_REQUIRE(extractor.expression() != nullptr); BOOST_REQUIRE(extractor.expression() != nullptr);
CompilerContext context; CompilerContext context { CompilationMode::Runtime /* probably simpler */ };
context.resetVisitedNodes(contract); context.resetVisitedNodes(contract);
context.setInheritanceHierarchy(inheritanceHierarchy); context.setInheritanceHierarchy(inheritanceHierarchy);
unsigned parametersSize = _localVariables.size(); // assume they are all one slot on the stack unsigned parametersSize = _localVariables.size(); // assume they are all one slot on the stack