Browse Source

Merge pull request #1761 from chriseth/sol_fix_deleteBytes

Fix for deleting byte array elements.
cl-refactor
Gav Wood 10 years ago
parent
commit
ae6dbcfc21
  1. 11
      libsolidity/LValue.cpp
  2. 20
      test/libsolidity/SolidityEndToEndTest.cpp

11
libsolidity/LValue.cpp

@ -311,8 +311,6 @@ void StorageByteArrayElement::retrieveValue(SourceLocation const&, bool _remove)
void StorageByteArrayElement::storeValue(Type const&, SourceLocation const&, bool _move) const void StorageByteArrayElement::storeValue(Type const&, SourceLocation const&, bool _move) const
{ {
//@todo optimize this
// stack: value ref byte_number // stack: value ref byte_number
m_context << u256(31) << eth::Instruction::SUB << u256(0x100) << eth::Instruction::EXP; m_context << u256(31) << eth::Instruction::SUB << u256(0x100) << eth::Instruction::EXP;
// stack: value ref (1<<(8*(31-byte_number))) // stack: value ref (1<<(8*(31-byte_number)))
@ -335,19 +333,16 @@ void StorageByteArrayElement::setToZero(SourceLocation const&, bool _removeRefer
{ {
// stack: ref byte_number // stack: ref byte_number
if (!_removeReference) if (!_removeReference)
m_context << eth::Instruction::SWAP1 << eth::Instruction::DUP2; m_context << eth::Instruction::DUP2 << eth::Instruction::DUP2;
m_context << u256(31) << eth::Instruction::SUB << u256(0x100) << eth::Instruction::EXP; m_context << u256(31) << eth::Instruction::SUB << u256(0x100) << eth::Instruction::EXP;
// stack: ref (1<<(8*(31-byte_number))) // stack: ref (1<<(8*(31-byte_number)))
m_context << eth::Instruction::DUP2 << eth::Instruction::SLOAD; m_context << eth::Instruction::DUP2 << eth::Instruction::SLOAD;
// stack: ref (1<<(8*(31-byte_number))) old_full_value // stack: ref (1<<(8*(31-byte_number))) old_full_value
// clear byte in old value // clear byte in old value
m_context << eth::Instruction::SWAP1 << u256(0xff) << eth::Instruction::MUL << eth::Instruction::AND; m_context << eth::Instruction::SWAP1 << u256(0xff) << eth::Instruction::MUL;
m_context << eth::Instruction::NOT << eth::Instruction::AND;
// stack: ref old_full_value_with_cleared_byte // stack: ref old_full_value_with_cleared_byte
m_context << eth::Instruction::SWAP1 << eth::Instruction::SSTORE; m_context << eth::Instruction::SWAP1 << eth::Instruction::SSTORE;
if (!_removeReference)
m_context << eth::Instruction::SWAP1;
else
m_context << eth::Instruction::POP;
} }
StorageArrayLength::StorageArrayLength(CompilerContext& _compilerContext, const ArrayType& _arrayType): StorageArrayLength::StorageArrayLength(CompilerContext& _compilerContext, const ArrayType& _arrayType):

20
test/libsolidity/SolidityEndToEndTest.cpp

@ -3381,6 +3381,26 @@ BOOST_AUTO_TEST_CASE(bytes_index_access)
BOOST_CHECK(callContractFunction("storageWrite()") == encodeArgs(0x193)); BOOST_CHECK(callContractFunction("storageWrite()") == encodeArgs(0x193));
} }
BOOST_AUTO_TEST_CASE(bytes_delete_element)
{
char const* sourceCode = R"(
contract c {
bytes data;
function test1() external returns (bool) {
data.length = 100;
for (uint i = 0; i < data.length; i++)
data[i] = byte(i);
delete data[94];
delete data[96];
delete data[98];
return data[94] == 0 && data[95] == 95 && data[96] == 0 && data[97] == 97;
}
}
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("test1()") == encodeArgs(true));
}
BOOST_AUTO_TEST_CASE(array_copy_calldata_storage) BOOST_AUTO_TEST_CASE(array_copy_calldata_storage)
{ {
char const* sourceCode = R"( char const* sourceCode = R"(

Loading…
Cancel
Save