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

Method incrementDynamicArraySize

libsolidity/codegen/ArrayUtils.cpp:449–491  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

447}
448
449void ArrayUtils::incrementDynamicArraySize(ArrayType const& _type) const
450{
451 solAssert(_type.location() == DataLocation::Storage, "");
452 solAssert(_type.isDynamicallySized(), "");
453 if (!_type.isByteArrayOrString() && _type.baseType()->storageBytes() < 32)
454 solAssert(_type.baseType()->isValueType(), "Invalid storage size for non-value type.");
455
456 if (_type.isByteArrayOrString())
457 {
458 // We almost always just add 2 (length of byte arrays is shifted left by one)
459 // except for the case where we transition from a short byte array
460 // to a long byte array, there we have to copy.
461 // This happens if the length is exactly 31, which means that the
462 // lowest-order byte (we actually use a mask with fewer bits) must
463 // be (31*2+0) = 62
464
465 m_context << Instruction::DUP1 << Instruction::SLOAD << Instruction::DUP1;
466 m_context.callYulFunction(m_context.utilFunctions().extractByteArrayLengthFunction(), 1, 1);
467 m_context.appendInlineAssembly(R"({
468 // We have to copy if length is exactly 31, because that marks
469 // the transition between in-place and out-of-place storage.
470 switch length
471 case 31
472 {
473 mstore(0, ref)
474 let data_area := keccak256(0, 0x20)
475 sstore(data_area, and(data, not(0xff)))
476 // Set old length in new format (31 * 2 + 1)
477 data := 63
478 }
479 sstore(ref, add(data, 2))
480 // return new length in ref
481 ref := add(length, 1)
482 })", {"ref", "data", "length"});
483 m_context << Instruction::POP << Instruction::POP;
484 }
485 else
486 m_context.appendInlineAssembly(R"({
487 let new_length := add(sload(ref), 1)
488 sstore(ref, new_length)
489 ref := new_length
490 })", {"ref"});
491}
492
493void ArrayUtils::popStorageArrayElement(ArrayType const& _type) const
494{

Callers 1

visitMethod · 0.80

Calls 9

isByteArrayOrStringMethod · 0.80
callYulFunctionMethod · 0.80
appendInlineAssemblyMethod · 0.80
locationMethod · 0.45
isDynamicallySizedMethod · 0.45
storageBytesMethod · 0.45
baseTypeMethod · 0.45
isValueTypeMethod · 0.45

Tested by

no test coverage detected