mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Simplify yul conversion function even more.
This commit is contained in:
parent
4480662a58
commit
94c4e1e172
@ -35,6 +35,16 @@ using namespace solidity;
|
|||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
using namespace solidity::frontend;
|
using namespace solidity::frontend;
|
||||||
|
|
||||||
|
string YulUtilFunctions::identityFunction()
|
||||||
|
{
|
||||||
|
string functionName = "identity";
|
||||||
|
return m_functionCollector.createFunction("identity", [&](vector<string>& _args, vector<string>& _rets) {
|
||||||
|
_args.push_back("value");
|
||||||
|
_rets.push_back("ret");
|
||||||
|
return "ret := value";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
string YulUtilFunctions::combineExternalFunctionIdFunction()
|
string YulUtilFunctions::combineExternalFunctionIdFunction()
|
||||||
{
|
{
|
||||||
string functionName = "combine_external_function_id";
|
string functionName = "combine_external_function_id";
|
||||||
@ -3272,48 +3282,38 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to)
|
|||||||
if (rational->isFractional())
|
if (rational->isFractional())
|
||||||
solAssert(toCategory == Type::Category::FixedPoint, "");
|
solAssert(toCategory == Type::Category::FixedPoint, "");
|
||||||
|
|
||||||
if (toCategory == Type::Category::FixedBytes)
|
if (toCategory == Type::Category::Address || toCategory == Type::Category::Contract)
|
||||||
{
|
|
||||||
FixedBytesType const& toBytesType = dynamic_cast<FixedBytesType const&>(_to);
|
|
||||||
body =
|
|
||||||
Whiskers("converted := <shiftLeft>(<clean>(value))")
|
|
||||||
("shiftLeft", shiftLeftFunction(256 - toBytesType.numBytes() * 8))
|
|
||||||
("clean", cleanupFunction(_from))
|
|
||||||
.render();
|
|
||||||
}
|
|
||||||
else if (toCategory == Type::Category::Enum)
|
|
||||||
body =
|
|
||||||
Whiskers("converted := <cleanEnum>(<cleanInt>(value))")
|
|
||||||
("cleanEnum", cleanupFunction(_to))
|
|
||||||
("cleanInt", cleanupFunction(_from))
|
|
||||||
.render();
|
|
||||||
else if (toCategory == Type::Category::FixedPoint)
|
|
||||||
solUnimplemented("Not yet implemented - FixedPointType.");
|
|
||||||
else if (toCategory == Type::Category::Address || toCategory == Type::Category::Contract)
|
|
||||||
body =
|
body =
|
||||||
Whiskers("converted := <convert>(value)")
|
Whiskers("converted := <convert>(value)")
|
||||||
("convert", conversionFunction(_from, IntegerType(160)))
|
("convert", conversionFunction(_from, IntegerType(160)))
|
||||||
.render();
|
.render();
|
||||||
else if (toCategory == Type::Category::Integer)
|
|
||||||
{
|
|
||||||
IntegerType const& to = dynamic_cast<IntegerType const&>(_to);
|
|
||||||
|
|
||||||
// Clean according to the "to" type, except if this is
|
|
||||||
// a widening conversion.
|
|
||||||
IntegerType const* cleanupType = &to;
|
|
||||||
if (fromCategory == Type::Category::Integer)
|
|
||||||
{
|
|
||||||
IntegerType const& from = dynamic_cast<IntegerType const&>(_from);
|
|
||||||
if (to.numBits() > from.numBits())
|
|
||||||
cleanupType = &from;
|
|
||||||
}
|
|
||||||
body =
|
|
||||||
Whiskers("converted := <cleanInt>(value)")
|
|
||||||
("cleanInt", cleanupFunction(*cleanupType))
|
|
||||||
.render();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
solAssert(false, "");
|
{
|
||||||
|
Whiskers bodyTemplate("converted := <cleanOutput>(<convert>(<cleanInput>(value)))");
|
||||||
|
bodyTemplate("cleanInput", cleanupFunction(_from));
|
||||||
|
bodyTemplate("cleanOutput", cleanupFunction(_to));
|
||||||
|
string convert;
|
||||||
|
|
||||||
|
if (auto const* toFixedBytes = dynamic_cast<FixedBytesType const*>(&_to))
|
||||||
|
convert = shiftLeftFunction(256 - toFixedBytes->numBytes() * 8);
|
||||||
|
else if (dynamic_cast<FixedPointType const*>(&_to))
|
||||||
|
solUnimplementedAssert(false, "");
|
||||||
|
else if (dynamic_cast<IntegerType const*>(&_to))
|
||||||
|
{
|
||||||
|
solUnimplementedAssert(fromCategory != Type::Category::FixedPoint, "");
|
||||||
|
convert = identityFunction();
|
||||||
|
}
|
||||||
|
else if (toCategory == Type::Category::Enum)
|
||||||
|
{
|
||||||
|
solAssert(fromCategory != Type::Category::FixedPoint, "");
|
||||||
|
convert = identityFunction();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
solAssert(false, "");
|
||||||
|
solAssert(!convert.empty(), "");
|
||||||
|
bodyTemplate("convert", convert);
|
||||||
|
body = bodyTemplate.render();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Type::Category::Bool:
|
case Type::Category::Bool:
|
||||||
|
@ -59,6 +59,10 @@ public:
|
|||||||
m_functionCollector(_functionCollector)
|
m_functionCollector(_functionCollector)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
/// @returns the name of a function that returns its argument.
|
||||||
|
/// Sometimes needed to satisfy templates.
|
||||||
|
std::string identityFunction();
|
||||||
|
|
||||||
/// @returns a function that combines the address and selector to a single value
|
/// @returns a function that combines the address and selector to a single value
|
||||||
/// for use in the ABI.
|
/// for use in the ABI.
|
||||||
std::string combineExternalFunctionIdFunction();
|
std::string combineExternalFunctionIdFunction();
|
||||||
|
Loading…
Reference in New Issue
Block a user