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

Method copyByteArrayToStorageFunction

libsolidity/codegen/YulUtilFunctions.cpp:2063–2138  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2061
2062
2063std::string YulUtilFunctions::copyByteArrayToStorageFunction(ArrayType const& _fromType, ArrayType const& _toType)
2064{
2065 solAssert(
2066 (*_fromType.copyForLocation(_toType.location(), _toType.isPointer())).equals(dynamic_cast<ReferenceType const&>(_toType)),
2067 ""
2068 );
2069 solAssert(_fromType.isByteArrayOrString(), "");
2070 solAssert(_toType.isByteArrayOrString(), "");
2071
2072 std::string functionName = "copy_byte_array_to_storage_from_" + _fromType.identifier() + "_to_" + _toType.identifier();
2073 return m_functionCollector.createFunction(functionName, [&](){
2074 Whiskers templ(R"(
2075 function <functionName>(slot, src<?fromCalldata>, len</fromCalldata>) {
2076 <?fromStorage> if eq(slot, src) { leave } </fromStorage>
2077
2078 let newLen := <arrayLength>(src<?fromCalldata>, len</fromCalldata>)
2079 // Make sure array length is sane
2080 if gt(newLen, 0xffffffffffffffff) { <panic>() }
2081
2082 let oldLen := <byteArrayLength>(sload(slot))
2083
2084 // potentially truncate data
2085 <cleanUpEndArray>(slot, oldLen, newLen)
2086
2087 let srcOffset := 0
2088 <?fromMemory>
2089 srcOffset := 0x20
2090 </fromMemory>
2091
2092 switch gt(newLen, 31)
2093 case 1 {
2094 let loopEnd := and(newLen, not(0x1f))
2095 <?fromStorage> src := <srcDataLocation>(src) </fromStorage>
2096 let dstPtr := <dstDataLocation>(slot)
2097 let i := 0
2098 for { } lt(i, loopEnd) { i := add(i, 0x20) } {
2099 sstore(dstPtr, <read>(add(src, srcOffset)))
2100 dstPtr := add(dstPtr, 1)
2101 srcOffset := add(srcOffset, <srcIncrement>)
2102 }
2103 if lt(loopEnd, newLen) {
2104 let lastValue := <read>(add(src, srcOffset))
2105 sstore(dstPtr, <maskBytes>(lastValue, and(newLen, 0x1f)))
2106 }
2107 sstore(slot, add(mul(newLen, 2), 1))
2108 }
2109 default {
2110 let value := 0
2111 if newLen {
2112 value := <read>(add(src, srcOffset))
2113 }
2114 sstore(slot, <byteArrayCombineShort>(value, newLen))
2115 }
2116 }
2117 )");
2118 templ("functionName", functionName);
2119 bool fromStorage = _fromType.dataStoredIn(DataLocation::Storage);
2120 templ("fromStorage", fromStorage);

Callers

nothing calls this directly

Calls 10

equalsMethod · 0.80
isPointerMethod · 0.80
isByteArrayOrStringMethod · 0.80
identifierMethod · 0.80
renderMethod · 0.80
to_stringFunction · 0.50
copyForLocationMethod · 0.45
locationMethod · 0.45
createFunctionMethod · 0.45
dataStoredInMethod · 0.45

Tested by

no test coverage detected