| 409 | } |
| 410 | |
| 411 | void ArrayUtils::clearDynamicArray(ArrayType const& _type) const |
| 412 | { |
| 413 | solAssert(_type.location() == DataLocation::Storage, ""); |
| 414 | solAssert(_type.isDynamicallySized(), ""); |
| 415 | |
| 416 | // fetch length |
| 417 | retrieveLength(_type); |
| 418 | // set length to zero |
| 419 | m_context << u256(0) << Instruction::DUP3 << Instruction::SSTORE; |
| 420 | // Special case: short byte arrays are stored togeher with their length |
| 421 | evmasm::AssemblyItem endTag = m_context.newTag(); |
| 422 | if (_type.isByteArrayOrString()) |
| 423 | { |
| 424 | // stack: ref old_length |
| 425 | m_context << Instruction::DUP1 << u256(31) << Instruction::LT; |
| 426 | evmasm::AssemblyItem longByteArray = m_context.appendConditionalJump(); |
| 427 | // Short byte array: no data slots to clear, just pop and exit |
| 428 | m_context << Instruction::POP << Instruction::POP; |
| 429 | m_context.appendJumpTo(endTag); |
| 430 | m_context.adjustStackOffset(2); // the longByteArray path has 2 more items on stack |
| 431 | m_context << longByteArray; |
| 432 | } |
| 433 | // stack: ref old_length |
| 434 | convertLengthToSize(_type); |
| 435 | // stack: ref slot_count |
| 436 | m_context << Instruction::SWAP1; |
| 437 | CompilerUtils(m_context).computeHashStatic(); |
| 438 | // stack: slot_count data_pos |
| 439 | m_context << Instruction::SWAP1; |
| 440 | // stack: data_pos slot_count |
| 441 | if (_type.storageStride() < 32) |
| 442 | clearStorageLoop(TypeProvider::uint256()); |
| 443 | else |
| 444 | clearStorageLoop(_type.baseType()); |
| 445 | // cleanup |
| 446 | m_context << endTag; |
| 447 | } |
| 448 | |
| 449 | void ArrayUtils::incrementDynamicArraySize(ArrayType const& _type) const |
| 450 | { |
no test coverage detected