diff options
author | chriseth <chris@ethereum.org> | 2017-04-12 03:12:17 +0800 |
---|---|---|
committer | chriseth <chris@ethereum.org> | 2017-04-25 22:49:04 +0800 |
commit | dfaab73efe1811848a52a218a207f2d4f007a2d8 (patch) | |
tree | f2d5ef4459be7bd01101c8485715dda77b0d7dfd /libsolidity/codegen/ContractCompiler.cpp | |
parent | f19e6a09a7b5293c70e98bbe66ab49aa45f76a73 (diff) | |
download | dexon-solidity-dfaab73efe1811848a52a218a207f2d4f007a2d8.tar.gz dexon-solidity-dfaab73efe1811848a52a218a207f2d4f007a2d8.tar.zst dexon-solidity-dfaab73efe1811848a52a218a207f2d4f007a2d8.zip |
Only allow access to local variables and only if they have a stack size of one.
Diffstat (limited to 'libsolidity/codegen/ContractCompiler.cpp')
-rw-r--r-- | libsolidity/codegen/ContractCompiler.cpp | 48 |
1 files changed, 14 insertions, 34 deletions
diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index de53f182..9bef8a8f 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -557,33 +557,16 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) else if (auto variable = dynamic_cast<VariableDeclaration const*>(decl)) { solAssert(!variable->isConstant(), ""); - if (m_context.isLocalVariable(variable)) - { - int stackDiff = _assembly.deposit() - m_context.baseStackOffsetOfVariable(*variable); - if (stackDiff < 1 || stackDiff > 16) - BOOST_THROW_EXCEPTION( - CompilerError() << - errinfo_sourceLocation(_inlineAssembly.location()) << - errinfo_comment("Stack too deep, try removing local variables.") - ); - for (unsigned i = 0; i < variable->type()->sizeOnStack(); ++i) - _assembly.append(dupInstruction(stackDiff)); - } - else - { - solAssert(m_context.isStateVariable(variable), "Invalid variable type."); - auto const& location = m_context.storageLocationOfVariable(*variable); - if (!variable->type()->isValueType()) - { - solAssert(location.second == 0, "Intra-slot offest assumed to be zero."); - _assembly.append(location.first); - } - else - { - _assembly.append(location.first); - _assembly.append(u256(location.second)); - } - } + solAssert(m_context.isLocalVariable(variable), ""); + int stackDiff = _assembly.deposit() - m_context.baseStackOffsetOfVariable(*variable); + if (stackDiff < 1 || stackDiff > 16) + BOOST_THROW_EXCEPTION( + CompilerError() << + errinfo_sourceLocation(_inlineAssembly.location()) << + errinfo_comment("Stack too deep, try removing local variables.") + ); + solAssert(variable->type()->sizeOnStack() == 1, ""); + _assembly.append(dupInstruction(stackDiff)); } else if (auto contract = dynamic_cast<ContractDefinition const*>(decl)) { @@ -602,19 +585,16 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) !!variable && m_context.isLocalVariable(variable), "Can only assign to stack variables in inline assembly." ); - unsigned size = variable->type()->sizeOnStack(); - int stackDiff = _assembly.deposit() - m_context.baseStackOffsetOfVariable(*variable) - size; + solAssert(variable->type()->sizeOnStack() == 1, ""); + int stackDiff = _assembly.deposit() - m_context.baseStackOffsetOfVariable(*variable) - 1; if (stackDiff > 16 || stackDiff < 1) BOOST_THROW_EXCEPTION( CompilerError() << errinfo_sourceLocation(_inlineAssembly.location()) << errinfo_comment("Stack too deep, try removing local variables.") ); - for (unsigned i = 0; i < size; ++i) - { - _assembly.append(swapInstruction(stackDiff)); - _assembly.append(Instruction::POP); - } + _assembly.append(swapInstruction(stackDiff)); + _assembly.append(Instruction::POP); } }; codeGen.assemble( |