diff options
author | chriseth <c@ethdev.com> | 2015-03-31 20:59:38 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-04-16 00:06:41 +0800 |
commit | 5216a9bc678597c0076b2e8615cac43c9077a95e (patch) | |
tree | ec2ec1dc821bfb0348458eaadf1b4336d7d609ad /ArrayUtils.cpp | |
parent | e1b20fb3a10f629aff172399c6e6111c941f931d (diff) | |
download | dexon-solidity-5216a9bc678597c0076b2e8615cac43c9077a95e.tar.gz dexon-solidity-5216a9bc678597c0076b2e8615cac43c9077a95e.tar.zst dexon-solidity-5216a9bc678597c0076b2e8615cac43c9077a95e.zip |
Some cleanup concerning byte arrays.
Diffstat (limited to 'ArrayUtils.cpp')
-rw-r--r-- | ArrayUtils.cpp | 118 |
1 files changed, 47 insertions, 71 deletions
diff --git a/ArrayUtils.cpp b/ArrayUtils.cpp index 58031390..1a91b053 100644 --- a/ArrayUtils.cpp +++ b/ArrayUtils.cpp @@ -388,10 +388,7 @@ void ArrayUtils::convertLengthToSize(ArrayType const& _arrayType, bool _pad) con { if (_arrayType.getLocation() == ArrayType::Location::Storage) { - if (_arrayType.isByteArray()) - m_context << u256(31) << eth::Instruction::ADD - << u256(32) << eth::Instruction::SWAP1 << eth::Instruction::DIV; - else if (_arrayType.getBaseType()->getStorageSize() <= 1) + if (_arrayType.getBaseType()->getStorageSize() <= 1) { unsigned baseBytes = _arrayType.getBaseType()->getStorageBytes(); if (baseBytes == 0) @@ -465,82 +462,61 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType) const m_context << legalAccess; // stack: <base_ref> <index> - if (_arrayType.isByteArray()) - switch (location) - { - case ArrayType::Location::Storage: - // byte array index storage lvalue on stack (goal): - // <ref> <byte_number> = <base_ref + index / 32> <index % 32> - m_context << u256(32) << eth::Instruction::SWAP2; + m_context << eth::Instruction::SWAP1; + if (_arrayType.isDynamicallySized()) + { + if (location == ArrayType::Location::Storage) CompilerUtils(m_context).computeHashStatic(); - // stack: 32 index data_ref + else if (location == ArrayType::Location::Memory) + m_context << u256(32) << eth::Instruction::ADD; + } + // stack: <index> <data_ref> + switch (location) + { + case ArrayType::Location::CallData: + if (!_arrayType.isByteArray()) + m_context + << eth::Instruction::SWAP1 << _arrayType.getBaseType()->getCalldataEncodedSize() + << eth::Instruction::MUL; + m_context << eth::Instruction::ADD; + if (_arrayType.getBaseType()->isValueType()) + CompilerUtils(m_context).loadFromMemoryDynamic( + *_arrayType.getBaseType(), + true, + !_arrayType.isByteArray(), + false + ); + break; + case ArrayType::Location::Storage: + m_context << eth::Instruction::SWAP1; + if (_arrayType.getBaseType()->getStorageBytes() <= 16) + { + // stack: <data_ref> <index> + // goal: + // <ref> <byte_number> = <base_ref + index / itemsPerSlot> <(index % itemsPerSlot) * byteSize> + unsigned byteSize = _arrayType.getBaseType()->getStorageBytes(); + solAssert(byteSize != 0, ""); + unsigned itemsPerSlot = 32 / byteSize; + m_context << u256(itemsPerSlot) << eth::Instruction::SWAP2; + // stack: itemsPerSlot index data_ref m_context << eth::Instruction::DUP3 << eth::Instruction::DUP3 << eth::Instruction::DIV << eth::Instruction::ADD - // stack: 32 index (data_ref + index / 32) + // stack: itemsPerSlot index (data_ref + index / itemsPerSlot) << eth::Instruction::SWAP2 << eth::Instruction::SWAP1 << eth::Instruction::MOD; - break; - case ArrayType::Location::CallData: - // no lvalue, just retrieve the value - m_context - << eth::Instruction::ADD << eth::Instruction::CALLDATALOAD - << ((u256(0xff) << (256 - 8))) << eth::Instruction::AND; - break; - case ArrayType::Location::Memory: - solAssert(false, "Memory lvalues not yet implemented."); - } - else - { - // stack: <base_ref> <index> - m_context << eth::Instruction::SWAP1; - if (_arrayType.isDynamicallySized()) - { - if (location == ArrayType::Location::Storage) - CompilerUtils(m_context).computeHashStatic(); - else if (location == ArrayType::Location::Memory) - m_context << u256(32) << eth::Instruction::ADD; + if (byteSize != 1) + m_context << u256(byteSize) << eth::Instruction::MUL; } - // stack: <index> <data_ref> - switch (location) + else { - case ArrayType::Location::CallData: - m_context - << eth::Instruction::SWAP1 << _arrayType.getBaseType()->getCalldataEncodedSize() - << eth::Instruction::MUL << eth::Instruction::ADD; - if (_arrayType.getBaseType()->isValueType()) - CompilerUtils(m_context).loadFromMemoryDynamic(*_arrayType.getBaseType(), true, true, false); - break; - case ArrayType::Location::Storage: - m_context << eth::Instruction::SWAP1; - if (_arrayType.getBaseType()->getStorageBytes() <= 16) - { - // stack: <data_ref> <index> - // goal: - // <ref> <byte_number> = <base_ref + index / itemsPerSlot> <(index % itemsPerSlot) * byteSize> - unsigned byteSize = _arrayType.getBaseType()->getStorageBytes(); - solAssert(byteSize != 0, ""); - unsigned itemsPerSlot = 32 / byteSize; - m_context << u256(itemsPerSlot) << eth::Instruction::SWAP2; - // stack: itemsPerSlot index data_ref - m_context - << eth::Instruction::DUP3 << eth::Instruction::DUP3 - << eth::Instruction::DIV << eth::Instruction::ADD - // stack: itemsPerSlot index (data_ref + index / itemsPerSlot) - << eth::Instruction::SWAP2 << eth::Instruction::SWAP1 - << eth::Instruction::MOD - << u256(byteSize) << eth::Instruction::MUL; - } - else - { - if (_arrayType.getBaseType()->getStorageSize() != 1) - m_context << _arrayType.getBaseType()->getStorageSize() << eth::Instruction::MUL; - m_context << eth::Instruction::ADD << u256(0); - } - break; - case ArrayType::Location::Memory: - solAssert(false, "Memory lvalues not yet implemented."); + if (_arrayType.getBaseType()->getStorageSize() != 1) + m_context << _arrayType.getBaseType()->getStorageSize() << eth::Instruction::MUL; + m_context << eth::Instruction::ADD << u256(0); } + break; + case ArrayType::Location::Memory: + solAssert(false, "Memory lvalues not yet implemented."); } } |