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

Method copyValueArrayToStorageFunction

libsolidity/codegen/YulUtilFunctions.cpp:2140–2306  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2138}
2139
2140std::string YulUtilFunctions::copyValueArrayToStorageFunction(ArrayType const& _fromType, ArrayType const& _toType)
2141{
2142 solAssert(_fromType.baseType()->isValueType(), "");
2143 solAssert(_toType.baseType()->isValueType(), "");
2144 solAssert(_fromType.baseType()->isImplicitlyConvertibleTo(*_toType.baseType()), "");
2145
2146 solAssert(!_fromType.isByteArrayOrString(), "");
2147 solAssert(!_toType.isByteArrayOrString(), "");
2148 solAssert(_toType.dataStoredIn(DataLocation::Storage), "");
2149
2150 solAssert(_fromType.storageStride() <= _toType.storageStride(), "");
2151 solAssert(_toType.storageStride() <= 32, "");
2152
2153 std::string functionName = "copy_array_to_storage_from_" + _fromType.identifier() + "_to_" + _toType.identifier();
2154 return m_functionCollector.createFunction(functionName, [&](){
2155 Whiskers templ(R"(
2156 function <functionName>(dst, src<?isFromDynamicCalldata>, len</isFromDynamicCalldata>) {
2157 <?isFromStorage>
2158 if eq(dst, src) { leave }
2159 </isFromStorage>
2160 let length := <arrayLength>(src<?isFromDynamicCalldata>, len</isFromDynamicCalldata>)
2161 // Make sure array length is sane
2162 if gt(length, 0xffffffffffffffff) { <panic>() }
2163 <resizeArray>(dst, length)
2164
2165 let srcPtr := <srcDataLocation>(src)
2166 let dstSlot := <dstDataLocation>(dst)
2167
2168 let fullSlots := div(length, <itemsPerSlot>)
2169
2170 <?isFromStorage>
2171 let srcSlotValue := sload(srcPtr)
2172 let srcItemIndexInSlot := 0
2173 </isFromStorage>
2174
2175 for { let i := 0 } lt(i, fullSlots) { i := add(i, 1) } {
2176 let dstSlotValue := 0
2177 <?sameTypeFromStorage>
2178 dstSlotValue := <maskFull>(srcSlotValue)
2179 <updateSrcPtr>
2180 <!sameTypeFromStorage>
2181 <?multipleItemsPerSlotDst>for { let j := 0 } lt(j, <itemsPerSlot>) { j := add(j, 1) } </multipleItemsPerSlotDst>
2182 {
2183 <?isFromStorage>
2184 let <stackItems> := <convert>(
2185 <extractFromSlot>(srcSlotValue, mul(<srcStride>, srcItemIndexInSlot))
2186 )
2187 <!isFromStorage>
2188 let <stackItems> := <readFromMemoryOrCalldata>(srcPtr)
2189 </isFromStorage>
2190 let itemValue := <prepareStore>(<stackItems>)
2191 dstSlotValue :=
2192 <?multipleItemsPerSlotDst>
2193 <updateByteSlice>(dstSlotValue, mul(<dstStride>, j), itemValue)
2194 <!multipleItemsPerSlotDst>
2195 itemValue
2196 </multipleItemsPerSlotDst>
2197

Callers

nothing calls this directly

Calls 15

WhiskersClass · 0.85
isByteArrayOrStringMethod · 0.80
storageStrideMethod · 0.80
identifierMethod · 0.80
renderMethod · 0.80
calldataStrideMethod · 0.80
memoryStrideMethod · 0.80
to_stringFunction · 0.50
isValueTypeMethod · 0.45
baseTypeMethod · 0.45

Tested by

no test coverage detected