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

Method bytesOrStringConcatFunction

libsolidity/codegen/YulUtilFunctions.cpp:2675–2737  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2673}
2674
2675std::string YulUtilFunctions::bytesOrStringConcatFunction(
2676 std::vector<Type const*> const& _argumentTypes,
2677 FunctionType::Kind _functionTypeKind
2678)
2679{
2680 solAssert(_functionTypeKind == FunctionType::Kind::BytesConcat || _functionTypeKind == FunctionType::Kind::StringConcat);
2681 std::string functionName = (_functionTypeKind == FunctionType::Kind::StringConcat) ? "string_concat" : "bytes_concat";
2682 size_t totalParams = 0;
2683 std::vector<Type const*> targetTypes;
2684
2685 for (Type const* argumentType: _argumentTypes)
2686 {
2687 if (_functionTypeKind == FunctionType::Kind::StringConcat)
2688 solAssert(argumentType->isImplicitlyConvertibleTo(*TypeProvider::stringMemory()));
2689 else if (_functionTypeKind == FunctionType::Kind::BytesConcat)
2690 solAssert(
2691 argumentType->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory()) ||
2692 argumentType->isImplicitlyConvertibleTo(*TypeProvider::fixedBytes(32))
2693 );
2694
2695 if (argumentType->category() == Type::Category::FixedBytes)
2696 targetTypes.emplace_back(argumentType);
2697 else if (
2698 auto const* literalType = dynamic_cast<StringLiteralType const*>(argumentType);
2699 literalType && !literalType->value().empty() && literalType->value().size() <= 32
2700 )
2701 targetTypes.emplace_back(TypeProvider::fixedBytes(static_cast<unsigned>(literalType->value().size())));
2702 else
2703 {
2704 solAssert(!dynamic_cast<RationalNumberType const*>(argumentType));
2705 targetTypes.emplace_back(
2706 _functionTypeKind == FunctionType::Kind::StringConcat ?
2707 TypeProvider::stringMemory() :
2708 TypeProvider::bytesMemory()
2709 );
2710 }
2711 totalParams += argumentType->sizeOnStack();
2712 functionName += "_" + argumentType->identifier();
2713 }
2714 return m_functionCollector.createFunction(functionName, [&]() {
2715 Whiskers templ(R"(
2716 function <functionName>(<parameters>) -> outPtr {
2717 outPtr := <allocateUnbounded>()
2718 let dataStart := add(outPtr, 0x20)
2719 let dataEnd := <encodePacked>(dataStart<?+parameters>, <parameters></+parameters>)
2720 mstore(outPtr, sub(dataEnd, dataStart))
2721 <finalizeAllocation>(outPtr, sub(dataEnd, outPtr))
2722 }
2723 )");
2724 templ("functionName", functionName);
2725 templ("parameters", suffixedVariableNameList("param_", 0, totalParams));
2726 templ("allocateUnbounded", allocateUnboundedFunction());
2727 templ("finalizeAllocation", finalizeAllocationFunction());
2728 templ(
2729 "encodePacked",
2730 ABIFunctions{m_evmVersion, m_eofVersion, m_revertStrings, m_functionCollector}.tupleEncoderPacked(
2731 _argumentTypes,
2732 targetTypes

Callers 1

endVisitMethod · 0.80

Calls 10

identifierMethod · 0.80
tupleEncoderPackedMethod · 0.80
renderMethod · 0.80
categoryMethod · 0.45
emptyMethod · 0.45
valueMethod · 0.45
sizeMethod · 0.45
sizeOnStackMethod · 0.45
createFunctionMethod · 0.45

Tested by

no test coverage detected