MCPcopy Create free account
hub / github.com/argotorg/solidity / clearArray

Method clearArray

libsolidity/codegen/ArrayUtils.cpp:346–409  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

344}
345
346void ArrayUtils::clearArray(ArrayType const& _typeIn) const
347{
348 Type const* type = &_typeIn;
349 m_context.callLowLevelFunction(
350 "$clearArray_" + _typeIn.identifier(),
351 2,
352 0,
353 [type](CompilerContext& _context)
354 {
355 ArrayType const& _type = dynamic_cast<ArrayType const&>(*type);
356 unsigned stackHeightStart = _context.stackHeight();
357 solAssert(_type.location() == DataLocation::Storage, "");
358 if (_type.baseType()->storageBytes() < 32)
359 {
360 solAssert(_type.baseType()->isValueType(), "Invalid storage size for non-value type.");
361 solAssert(_type.baseType()->storageSize() <= 1, "Invalid storage size for type.");
362 }
363 if (_type.baseType()->isValueType())
364 solAssert(_type.baseType()->storageSize() <= 1, "Invalid size for value type.");
365
366 _context << Instruction::POP; // remove byte offset
367 if (_type.isDynamicallySized())
368 ArrayUtils(_context).clearDynamicArray(_type);
369 else if (_type.length() == 0 || _type.baseType()->category() == Type::Category::Mapping)
370 _context << Instruction::POP;
371 else if (_type.baseType()->isValueType() && _type.storageSize() <= 5)
372 {
373 // unroll loop for small arrays @todo choose a good value
374 // Note that we loop over storage slots here, not elements.
375 for (unsigned i = 1; i < _type.storageSize(); ++i)
376 _context
377 << u256(0) << Instruction::DUP2 << Instruction::SSTORE
378 << u256(1) << Instruction::ADD;
379 _context << u256(0) << Instruction::SWAP1 << Instruction::SSTORE;
380 }
381 else if (!_type.baseType()->isValueType() && _type.length() <= 4)
382 {
383 // unroll loop for small arrays @todo choose a good value
384 solAssert(_type.baseType()->storageBytes() >= 32, "Invalid storage size.");
385 for (unsigned i = 1; i < _type.length(); ++i)
386 {
387 _context << u256(0);
388 StorageItem(_context, *_type.baseType()).setToZero(SourceLocation(), false);
389 _context
390 << Instruction::POP
391 << u256(_type.baseType()->storageSize()) << Instruction::ADD;
392 }
393 _context << u256(0);
394 StorageItem(_context, *_type.baseType()).setToZero(SourceLocation(), true);
395 }
396 else
397 {
398 _context << _type.length();
399 ArrayUtils(_context).convertLengthToSize(_type);
400 // stack: storage_ref slot_count
401 if (_type.baseType()->storageBytes() < 32)
402 ArrayUtils(_context).clearStorageLoop(TypeProvider::uint256());
403 else

Callers 1

setToZeroMethod · 0.80

Calls 15

ArrayUtilsClass · 0.85
callLowLevelFunctionMethod · 0.80
identifierMethod · 0.80
clearDynamicArrayMethod · 0.80
setToZeroMethod · 0.80
convertLengthToSizeMethod · 0.80
clearStorageLoopMethod · 0.80
SourceLocationClass · 0.50
stackHeightMethod · 0.45
locationMethod · 0.45
storageBytesMethod · 0.45
baseTypeMethod · 0.45

Tested by

no test coverage detected