diff options
-rw-r--r-- | Compiler.cpp | 4 | ||||
-rw-r--r-- | CompilerUtils.cpp | 9 | ||||
-rw-r--r-- | CompilerUtils.h | 2 |
3 files changed, 14 insertions, 1 deletions
diff --git a/Compiler.cpp b/Compiler.cpp index 73b3e324..a8a07403 100644 --- a/Compiler.cpp +++ b/Compiler.cpp @@ -155,6 +155,7 @@ void Compiler::appendReturnValuePacker(FunctionDefinition const& _function) //@todo this can be also done more efficiently unsigned dataOffset = 0; vector<ASTPointer<VariableDeclaration>> const& parameters = _function.getReturnParameters(); + unsigned stackDepth = CompilerUtils(m_context).getSizeOnStack(parameters); for (unsigned i = 0; i < parameters.size(); ++i) { Type const& paramType = *parameters[i]->getType(); @@ -163,10 +164,11 @@ void Compiler::appendReturnValuePacker(FunctionDefinition const& _function) BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(parameters[i]->getLocation()) << errinfo_comment("Type " + paramType.toString() + " not yet supported.")); - m_context << eth::dupInstruction(parameters.size() - i); + CompilerUtils(m_context).copyToStackTop(stackDepth, paramType); if (numBytes != 32) m_context << (u256(1) << ((32 - numBytes) * 8)) << eth::Instruction::MUL; m_context << u256(dataOffset) << eth::Instruction::MSTORE; + stackDepth -= paramType.getSizeOnStack(); dataOffset += numBytes; } // note that the stack is not cleaned up here diff --git a/CompilerUtils.cpp b/CompilerUtils.cpp index cbd92d2b..824fd477 100644 --- a/CompilerUtils.cpp +++ b/CompilerUtils.cpp @@ -42,6 +42,15 @@ void CompilerUtils::moveToStackVariable(VariableDeclaration const& _variable) m_context << eth::swapInstruction(stackPosition - size + 1) << eth::Instruction::POP; } +void CompilerUtils::copyToStackTop(unsigned _stackDepth, const Type& _type) +{ + if (_stackDepth > 16) + BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Stack too deep.")); + unsigned const size = _type.getSizeOnStack(); + for (unsigned i = 0; i < size; ++i) + m_context << eth::dupInstruction(_stackDepth); +} + void CompilerUtils::popStackElement(Type const& _type) { unsigned const size = _type.getSizeOnStack(); diff --git a/CompilerUtils.h b/CompilerUtils.h index 2aac7e4e..4da53375 100644 --- a/CompilerUtils.h +++ b/CompilerUtils.h @@ -37,6 +37,8 @@ public: /// Moves the value that is at the top of the stack to a stack variable. void moveToStackVariable(VariableDeclaration const& _variable); + /// Copies a variable of type @a _type from a stack depth of @a _stackDepth to the top of the stack. + void copyToStackTop(unsigned _stackDepth, Type const& _type); /// Removes the current value from the top of the stack. void popStackElement(Type const& _type); |