Implementing bytes.concat for legacy codegen.

This commit is contained in:
Djordje Mijovic 2021-03-17 13:09:24 +01:00
parent 80866d3ee4
commit 4e75c6c3e8

View File

@ -1024,7 +1024,37 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
case FunctionType::Kind::BytesConcat:
{
_functionCall.expression().accept(*this);
solUnimplementedAssert(false, "Bytes concat not implemented in codegen yet.");
vector<Type const*> argumentTypes;
vector<Type const*> targetTypes;
for (auto const& argument: arguments)
{
argument->accept(*this);
solAssert(argument->annotation().type, "");
argumentTypes.emplace_back(argument->annotation().type);
if (argument->annotation().type->category() == Type::Category::FixedBytes)
targetTypes.emplace_back(argument->annotation().type);
else if (
auto const* literalType = dynamic_cast<StringLiteralType const*>(argument->annotation().type);
literalType && literalType->value().size() <= 32
)
targetTypes.emplace_back(TypeProvider::fixedBytes(static_cast<unsigned>(literalType->value().size())));
else
{
solAssert(argument->annotation().type->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory()), "");
targetTypes.emplace_back(TypeProvider::bytesMemory());
}
}
utils().fetchFreeMemoryPointer();
// stack: <arg1> <arg2> ... <argn> <free mem>
m_context << u256(32) << Instruction::ADD;
utils().packedEncode(argumentTypes, targetTypes);
utils().fetchFreeMemoryPointer();
m_context.appendInlineAssembly(R"({
mstore(mem_ptr, sub(sub(mem_end, mem_ptr), 0x20))
})", {"mem_end", "mem_ptr"});
m_context << Instruction::SWAP1;
utils().storeFreeMemoryPointer();
break;
}
case FunctionType::Kind::ObjectCreation: