diff options
-rw-r--r-- | ExpressionCompiler.cpp | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp index a54915bc..183864ec 100644 --- a/ExpressionCompiler.cpp +++ b/ExpressionCompiler.cpp @@ -586,11 +586,29 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) "TODO: Index acces only implemented for storage arrays."); solAssert(!arrayType.isByteArray(), "TODO: Index acces not implemented for byte arrays."); solAssert(_indexAccess.getIndexExpression(), "Index expression expected."); + + _indexAccess.getIndexExpression()->accept(*this); + // retrieve length if (arrayType.isDynamicallySized()) + m_context << eth::Instruction::DUP2 << eth::Instruction::SLOAD; + else + m_context << arrayType.getLength(); + // stack: <base_ref> <index> <length> + // check out-of-bounds access + m_context << eth::Instruction::DUP2 << eth::Instruction::LT; + eth::AssemblyItem legalAccess = m_context.appendConditionalJump(); + // out-of-bounds access throws exception (just STOP for now) + m_context << eth::Instruction::STOP; + + m_context << legalAccess; + // stack: <base_ref> <index> + m_context << arrayType.getBaseType()->getStorageSize() << eth::Instruction::MUL; + if (arrayType.isDynamicallySized()) + { + m_context << eth::Instruction::SWAP1; CompilerUtils(m_context).computeHashStatic(); - _indexAccess.getIndexExpression()->accept(*this); - m_context << arrayType.getBaseType()->getStorageSize() << eth::Instruction::MUL - << eth::Instruction::ADD; + } + m_context << eth::Instruction::ADD; m_currentLValue = LValue(m_context, LValue::LValueType::Storage, _indexAccess.getType()); m_currentLValue.retrieveValueIfLValueNotRequested(_indexAccess); } |