|
|
@ -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) |
|
|
@ -464,34 +461,6 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType) const |
|
|
|
m_context << eth::Instruction::STOP; |
|
|
|
|
|
|
|
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; |
|
|
|
CompilerUtils(m_context).computeHashStatic(); |
|
|
|
// stack: 32 index data_ref
|
|
|
|
m_context |
|
|
|
<< eth::Instruction::DUP3 << eth::Instruction::DUP3 |
|
|
|
<< eth::Instruction::DIV << eth::Instruction::ADD |
|
|
|
// stack: 32 index (data_ref + index / 32)
|
|
|
|
<< 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()) |
|
|
@ -505,11 +474,19 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType) const |
|
|
|
switch (location) |
|
|
|
{ |
|
|
|
case ArrayType::Location::CallData: |
|
|
|
if (!_arrayType.isByteArray()) |
|
|
|
m_context |
|
|
|
<< eth::Instruction::SWAP1 << _arrayType.getBaseType()->getCalldataEncodedSize() |
|
|
|
<< eth::Instruction::MUL << eth::Instruction::ADD; |
|
|
|
<< 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, true, false); |
|
|
|
CompilerUtils(m_context).loadFromMemoryDynamic( |
|
|
|
*_arrayType.getBaseType(), |
|
|
|
true, |
|
|
|
!_arrayType.isByteArray(), |
|
|
|
false |
|
|
|
); |
|
|
|
break; |
|
|
|
case ArrayType::Location::Storage: |
|
|
|
m_context << eth::Instruction::SWAP1; |
|
|
@ -528,8 +505,9 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType) const |
|
|
|
<< 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; |
|
|
|
<< eth::Instruction::MOD; |
|
|
|
if (byteSize != 1) |
|
|
|
m_context << u256(byteSize) << eth::Instruction::MUL; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
@ -542,7 +520,6 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType) const |
|
|
|
solAssert(false, "Memory lvalues not yet implemented."); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void ArrayUtils::incrementByteOffset(unsigned _byteSize, unsigned _byteOffsetPosition, unsigned _storageOffsetPosition) const |
|
|
|
{ |
|
|
|