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

Method encodeToMemory

libsolidity/codegen/CompilerUtils.cpp:422–606  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

420}
421
422void CompilerUtils::encodeToMemory(
423 TypePointers const& _givenTypes,
424 TypePointers const& _targetTypes,
425 bool _padToWordBoundaries,
426 bool _copyDynamicDataInPlace,
427 bool _encodeAsLibraryTypes
428)
429{
430 // stack: <v1> <v2> ... <vn> <mem>
431 bool const encoderV2 = m_context.useABICoderV2();
432 TypePointers targetTypes = _targetTypes.empty() ? _givenTypes : _targetTypes;
433 solAssert(targetTypes.size() == _givenTypes.size());
434 for (Type const*& t: targetTypes)
435 {
436 Type const* tEncoding = t->fullEncodingType(_encodeAsLibraryTypes, encoderV2, !_padToWordBoundaries);
437 solUnimplementedAssert(tEncoding, "Encoding type \"" + t->toString() + "\" not yet implemented.");
438 t = std::move(tEncoding);
439 }
440
441 if (_givenTypes.empty())
442 return;
443 if (encoderV2)
444 {
445 // Use the new Yul-based encoding function
446 solAssert(
447 _padToWordBoundaries != _copyDynamicDataInPlace,
448 "Non-padded and in-place encoding can only be combined."
449 );
450 auto stackHeightBefore = m_context.stackHeight();
451 abiEncodeV2(_givenTypes, targetTypes, _encodeAsLibraryTypes, _padToWordBoundaries);
452 solAssert(stackHeightBefore - m_context.stackHeight() == sizeOnStack(_givenTypes));
453 return;
454 }
455
456 // Stack during operation:
457 // <v1> <v2> ... <vn> <mem_start> <dyn_head_1> ... <dyn_head_r> <end_of_mem>
458 // The values dyn_head_n are added during the first loop and they point to the head part
459 // of the nth dynamic parameter, which is filled once the dynamic parts are processed.
460
461 // store memory start pointer
462 m_context << Instruction::DUP1;
463
464 unsigned argSize = CompilerUtils::sizeOnStack(_givenTypes);
465 unsigned stackPos = 0; // advances through the argument values
466 unsigned dynPointers = 0; // number of dynamic head pointers on the stack
467 for (size_t i = 0; i < _givenTypes.size(); ++i)
468 {
469 Type const* targetType = targetTypes[i];
470 solAssert(!!targetType, "Externalable type expected.");
471 if (targetType->isDynamicallySized() && !_copyDynamicDataInPlace)
472 {
473 // leave end_of_mem as dyn head pointer
474 m_context << Instruction::DUP1 << u256(32) << Instruction::ADD;
475 dynPointers++;
476 assertThrow(
477 (argSize + dynPointers) < m_context.reachableStackDepth(),
478 StackTooDeepError,
479 util::stackTooDeepString

Callers 1

Calls 15

convertTypeFunction · 0.85
ArrayUtilsClass · 0.85
dupInstructionFunction · 0.85
swapInstructionFunction · 0.85
fullEncodingTypeMethod · 0.80
copyArrayToMemoryMethod · 0.80
retrieveLengthMethod · 0.80
useABICoderV2Method · 0.45
emptyMethod · 0.45
sizeMethod · 0.45
toStringMethod · 0.45
stackHeightMethod · 0.45

Tested by

no test coverage detected