aboutsummaryrefslogtreecommitdiffstats
path: root/ArrayUtils.cpp
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-03-31 20:59:38 +0800
committerchriseth <c@ethdev.com>2015-04-16 00:06:41 +0800
commit5216a9bc678597c0076b2e8615cac43c9077a95e (patch)
treeec2ec1dc821bfb0348458eaadf1b4336d7d609ad /ArrayUtils.cpp
parente1b20fb3a10f629aff172399c6e6111c941f931d (diff)
downloaddexon-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.cpp118
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.");
}
}