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

Method copyArrayToMemory

libsolidity/codegen/ArrayUtils.cpp:110–344  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

108}
109
110void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWordBoundaries) const
111{
112 solUnimplementedAssert(
113 !_sourceType.baseType()->isDynamicallySized(),
114 "Nested dynamic arrays not implemented here."
115 );
116 CompilerUtils utils(m_context);
117
118 if (_sourceType.location() == DataLocation::CallData)
119 {
120 if (!_sourceType.isDynamicallySized())
121 m_context << _sourceType.length();
122 if (!_sourceType.isByteArrayOrString())
123 convertLengthToSize(_sourceType);
124
125 std::string routine = "calldatacopy(target, source, len)\n";
126 if (_padToWordBoundaries)
127 routine += R"(
128 // Set padding suffix to zero
129 mstore(add(target, len), 0)
130 len := and(add(len, 0x1f), not(0x1f))
131 )";
132 routine += "target := add(target, len)\n";
133 m_context.appendInlineAssembly("{" + routine + "}", {"target", "source", "len"});
134 m_context << Instruction::POP << Instruction::POP;
135 }
136 else if (_sourceType.location() == DataLocation::Memory)
137 {
138 retrieveLength(_sourceType);
139 // stack: target source length
140 if (!_sourceType.baseType()->isValueType())
141 {
142 // copy using a loop
143 m_context << u256(0) << Instruction::SWAP3;
144 // stack: counter source length target
145 auto repeat = m_context.newTag();
146 m_context << repeat;
147 m_context << Instruction::DUP2 << Instruction::DUP5;
148 m_context << Instruction::LT << Instruction::ISZERO;
149 auto loopEnd = m_context.appendConditionalJump();
150 m_context << Instruction::DUP3 << Instruction::DUP5;
151 accessIndex(_sourceType, false);
152 MemoryItem(m_context, *_sourceType.baseType(), true).retrieveValue(SourceLocation(), true);
153 if (auto baseArray = dynamic_cast<ArrayType const*>(_sourceType.baseType()))
154 copyArrayToMemory(*baseArray, _padToWordBoundaries);
155 else
156 utils.storeInMemoryDynamic(*_sourceType.baseType());
157 m_context << Instruction::SWAP3 << u256(1) << Instruction::ADD;
158 m_context << Instruction::SWAP3;
159 m_context.appendJumpTo(repeat);
160 m_context << loopEnd;
161 m_context << Instruction::SWAP3;
162 utils.popStackSlots(3);
163 // stack: updated_target_pos
164 return;
165 }
166
167 // memcpy using the built-in contract

Callers 3

abiDecodeMethod · 0.80
encodeToMemoryMethod · 0.80
convertTypeMethod · 0.80

Calls 15

MemoryItemClass · 0.85
dupInstructionFunction · 0.85
isByteArrayOrStringMethod · 0.80
appendInlineAssemblyMethod · 0.80
appendConditionalJumpMethod · 0.80
retrieveValueMethod · 0.80
storeInMemoryDynamicMethod · 0.80
popStackSlotsMethod · 0.80
memoryCopy32Method · 0.80
memoryCopyMethod · 0.80
tagMethod · 0.80
computeHashStaticMethod · 0.80

Tested by

no test coverage detected