From cd5f4958613ab131980c4b15563ad9d0017d8d5c Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 8 Dec 2014 16:56:41 +0100 Subject: [PATCH] Register variably-sized variables on stack. --- Compiler.cpp | 7 ++++--- CompilerContext.cpp | 25 +++++++++++++++---------- CompilerContext.h | 10 ++++++---- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/Compiler.cpp b/Compiler.cpp index 17ad4fd16..66d938d17 100644 --- a/Compiler.cpp +++ b/Compiler.cpp @@ -199,11 +199,12 @@ bool Compiler::visit(FunctionDefinition& _function) unsigned const numReturnValues = _function.getReturnParameters().size(); unsigned const numLocalVariables = _function.getLocalVariables().size(); - for (ASTPointer const& variable: _function.getParameters() + _function.getReturnParameters()) + for (ASTPointer const& variable: _function.getParameters()) m_context.addVariable(*variable); + for (ASTPointer const& variable: _function.getReturnParameters()) + m_context.addAndInitializeVariable(*variable); for (VariableDeclaration const* localVariable: _function.getLocalVariables()) - m_context.addVariable(*localVariable); - m_context.initializeLocalVariables(numReturnValues + numLocalVariables); + m_context.addAndInitializeVariable(*localVariable); _function.getBody().accept(*this); diff --git a/CompilerContext.cpp b/CompilerContext.cpp index b89a8e5b5..fa18520d0 100644 --- a/CompilerContext.cpp +++ b/CompilerContext.cpp @@ -41,20 +41,25 @@ void CompilerContext::addStateVariable(VariableDeclaration const& _declaration) m_stateVariablesSize += _declaration.getType()->getStorageSize(); } -void CompilerContext::initializeLocalVariables(unsigned _numVariables) +void CompilerContext::addVariable(VariableDeclaration const& _declaration) { - if (_numVariables > 0) - { + m_localVariables[&_declaration] = m_localVariablesSize; + m_localVariablesSize += _declaration.getType()->getSizeOnStack(); +} + +void CompilerContext::addAndInitializeVariable(VariableDeclaration const& _declaration) +{ + addVariable(_declaration); + + unsigned const size = _declaration.getType()->getSizeOnStack(); + for (unsigned i = 0; i < size; ++i) *this << u256(0); - for (unsigned i = 1; i < _numVariables; ++i) - *this << eth::Instruction::DUP1; - m_asm.adjustDeposit(-_numVariables); - } + m_asm.adjustDeposit(-size); } bool CompilerContext::isLocalVariable(Declaration const* _declaration) const { - return std::find(m_localVariables.begin(), m_localVariables.end(), _declaration) != m_localVariables.end(); + return m_localVariables.count(_declaration) > 0; } eth::AssemblyItem CompilerContext::getFunctionEntryLabel(FunctionDefinition const& _function) const @@ -67,10 +72,10 @@ eth::AssemblyItem CompilerContext::getFunctionEntryLabel(FunctionDefinition cons unsigned CompilerContext::getBaseStackOffsetOfVariable(Declaration const& _declaration) const { - auto res = find(begin(m_localVariables), end(m_localVariables), &_declaration); + auto res = m_localVariables.find(&_declaration); if (asserts(res != m_localVariables.end())) BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Variable not found on stack.")); - return unsigned(end(m_localVariables) - res - 1); + return m_localVariablesSize - res->second - 1; } unsigned CompilerContext::baseToCurrentStackOffset(unsigned _baseOffset) const diff --git a/CompilerContext.h b/CompilerContext.h index 6a48e1485..7272a368b 100644 --- a/CompilerContext.h +++ b/CompilerContext.h @@ -43,8 +43,8 @@ public: void addMagicGlobal(MagicVariableDeclaration const& _declaration); void addStateVariable(VariableDeclaration const& _declaration); void startNewFunction() { m_localVariables.clear(); m_asm.setDeposit(0); } - void initializeLocalVariables(unsigned _numVariables); - void addVariable(VariableDeclaration const& _declaration) { m_localVariables.push_back(&_declaration); } + void addVariable(VariableDeclaration const& _declaration); + void addAndInitializeVariable(VariableDeclaration const& _declaration); void addFunction(FunctionDefinition const& _function) { m_functionEntryLabels.insert(std::make_pair(&_function, m_asm.newTag())); } void adjustStackOffset(int _adjustment) { m_asm.adjustDeposit(_adjustment); } @@ -98,8 +98,10 @@ private: u256 m_stateVariablesSize; /// Storage offsets of state variables std::map m_stateVariables; - /// Offsets of local variables on the stack. - std::vector m_localVariables; + /// Offsets of local variables on the stack (relative to stack base). + std::map m_localVariables; + /// Sum of stack sizes of local variables + unsigned m_localVariablesSize; /// Labels pointing to the entry points of funcitons. std::map m_functionEntryLabels; };