fixup! User-defined literal suffixes: Code generation

This commit is contained in:
Kamil Śliwak 2023-04-12 12:22:59 +02:00
parent b5f4fcc9b1
commit 134c5a951f
2 changed files with 24 additions and 53 deletions

View File

@ -698,42 +698,28 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
evmasm::AssemblyItem returnLabel = m_context.pushNewTag(); evmasm::AssemblyItem returnLabel = m_context.pushNewTag();
if (!_functionCall.isSuffixCall()) if (!_functionCall.isSuffixCall() || parameterTypes.size() == 1)
{ {
for (unsigned i = 0; i < arguments.size(); ++i) for (unsigned i = 0; i < arguments.size(); ++i)
acceptAndConvert(*arguments[i], *parameterTypes[i]); acceptAndConvert(*arguments[i], *parameterTypes[i]);
} }
else else
{ {
solAssert(arguments.size() == 1); solAssert(parameterTypes.size() == 2);
solAssert(arguments[0]); solAssert(arguments.size() == 1 && arguments[0]);
auto const* literal = dynamic_cast<Literal const*>(arguments[0].get()); auto const* literal = dynamic_cast<Literal const*>(arguments[0].get());
Type const& literalType = *literal->annotation().type;
solAssert(literal); solAssert(literal);
solAssert(literal->annotation().type); solAssert(literal->annotation().type);
if (parameterTypes.size() == 1) auto const* rationalNumberType = dynamic_cast<RationalNumberType const*>(literal->annotation().type);
{ solAssert(rationalNumberType);
if (literalType.category() != Type::Category::StringLiteral)
// NOTE: For string literals we do not need to define the variable. The variable
// value will be embedded inside the conversion function.
m_context << literalType.literalValue(literal);
utils().convertType(literalType, *parameterTypes.at(0));
}
else
{
solAssert(parameterTypes.size() == 2);
auto const* rationalNumberType = dynamic_cast<RationalNumberType const*>(&literalType); auto&& [mantissa, exponent] = rationalNumberType->fractionalDecomposition();
solAssert(rationalNumberType); solAssert(mantissa && exponent);
m_context << mantissa->literalValue(nullptr);
auto&& [mantissa, exponent] = rationalNumberType->fractionalDecomposition(); utils().convertType(*mantissa, *parameterTypes.at(0));
solAssert(mantissa && exponent); m_context << exponent->literalValue(nullptr);
m_context << mantissa->literalValue(nullptr); utils().convertType(*exponent, *parameterTypes.at(1));
utils().convertType(*mantissa, *parameterTypes.at(0));
m_context << exponent->literalValue(nullptr);
utils().convertType(*exponent, *parameterTypes.at(1));
}
} }
_functionCall.expression().accept(*this); _functionCall.expression().accept(*this);

View File

@ -1003,7 +1003,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
vector<string> args; vector<string> args;
FunctionDefinition const* functionDef = nullptr; FunctionDefinition const* functionDef = nullptr;
if (!_functionCall.isSuffixCall()) if (!_functionCall.isSuffixCall() || parameterTypes.size() == 1)
{ {
functionDef = ASTNode::resolveFunctionCall(_functionCall, &m_context.mostDerivedContract()); functionDef = ASTNode::resolveFunctionCall(_functionCall, &m_context.mostDerivedContract());
@ -1020,40 +1020,25 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
solAssert(!functionDef->virtualSemantics()); solAssert(!functionDef->virtualSemantics());
solAssert(!functionType->hasBoundFirstArgument()); solAssert(!functionType->hasBoundFirstArgument());
solAssert(arguments.size() == 1); solAssert(parameterTypes.size() == 2);
solAssert(arguments[0]); solAssert(arguments.size() == 1 && arguments[0]);
auto const* literal = dynamic_cast<Literal const*>(arguments[0].get()); auto const* literal = dynamic_cast<Literal const*>(arguments[0].get());
Type const& literalType = *literal->annotation().type;
solAssert(literal); solAssert(literal);
solAssert(literal->annotation().type); solAssert(literal->annotation().type);
if (parameterTypes.size() == 2) auto const* literalRationalType = dynamic_cast<RationalNumberType const*>(literal->annotation().type);
{ solAssert(literalRationalType);
auto const* literalRationalType = dynamic_cast<RationalNumberType const*>(&literalType);
solAssert(literalRationalType);
auto&& [mantissa, exponent] = literalRationalType->fractionalDecomposition(); auto&& [mantissa, exponent] = literalRationalType->fractionalDecomposition();
solAssert(mantissa && exponent); solAssert(mantissa && exponent);
IRVariable mantissaVar(m_context.newYulVariable(), *mantissa); IRVariable mantissaVar(m_context.newYulVariable(), *mantissa);
define(mantissaVar) << toCompactHexWithPrefix(mantissa->literalValue(literal)) << "\n"; define(mantissaVar) << toCompactHexWithPrefix(mantissa->literalValue(literal)) << "\n";
args += convert(mantissaVar, *parameterTypes[0]).stackSlots(); args += convert(mantissaVar, *parameterTypes[0]).stackSlots();
IRVariable exponentVar(m_context.newYulVariable(), *exponent); IRVariable exponentVar(m_context.newYulVariable(), *exponent);
define(exponentVar) << toCompactHexWithPrefix(exponent->literalValue(literal)) << "\n"; define(exponentVar) << toCompactHexWithPrefix(exponent->literalValue(literal)) << "\n";
args += convert(exponentVar, *parameterTypes[1]).stackSlots(); args += convert(exponentVar, *parameterTypes[1]).stackSlots();
}
else
{
solAssert(parameterTypes.size() == 1);
IRVariable value(m_context.newYulVariable(), literalType);
if (literalType.category() != Type::Category::StringLiteral)
// NOTE: For string literals we do not need to define the variable. The variable
// value will be embedded inside the conversion function.
define(value) << toCompactHexWithPrefix(literalType.literalValue(literal)) << "\n";
args += convert(value, *parameterTypes[0]).stackSlots();
}
} }
if (functionDef) if (functionDef)