mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #8720 from ethereum/irSha256
IR generation for sha256.
This commit is contained in:
commit
99aa821410
@ -763,6 +763,14 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
|||||||
"))\n";
|
"))\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case FunctionType::Kind::ECRecover:
|
||||||
|
case FunctionType::Kind::SHA256:
|
||||||
|
case FunctionType::Kind::RIPEMD160:
|
||||||
|
{
|
||||||
|
solAssert(!_functionCall.annotation().tryCall, "");
|
||||||
|
appendExternalFunctionCall(_functionCall, arguments);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case FunctionType::Kind::ArrayPop:
|
case FunctionType::Kind::ArrayPop:
|
||||||
{
|
{
|
||||||
auto const& memberAccessExpression = dynamic_cast<MemberAccess const&>(_functionCall.expression()).expression();
|
auto const& memberAccessExpression = dynamic_cast<MemberAccess const&>(_functionCall.expression()).expression();
|
||||||
@ -1463,7 +1471,8 @@ void IRGeneratorForStatements::appendExternalFunctionCall(
|
|||||||
for (auto const& arg: _arguments)
|
for (auto const& arg: _arguments)
|
||||||
{
|
{
|
||||||
argumentTypes.emplace_back(&type(*arg));
|
argumentTypes.emplace_back(&type(*arg));
|
||||||
argumentStrings.emplace_back(IRVariable(*arg).commaSeparatedList());
|
if (IRVariable(*arg).type().sizeOnStack() > 0)
|
||||||
|
argumentStrings.emplace_back(IRVariable(*arg).commaSeparatedList());
|
||||||
}
|
}
|
||||||
string argumentString = argumentStrings.empty() ? ""s : (", " + joinHumanReadable(argumentStrings));
|
string argumentString = argumentStrings.empty() ? ""s : (", " + joinHumanReadable(argumentStrings));
|
||||||
|
|
||||||
@ -1481,7 +1490,6 @@ void IRGeneratorForStatements::appendExternalFunctionCall(
|
|||||||
|
|
||||||
ABIFunctions abi(m_context.evmVersion(), m_context.revertStrings(), m_context.functionCollector());
|
ABIFunctions abi(m_context.evmVersion(), m_context.revertStrings(), m_context.functionCollector());
|
||||||
|
|
||||||
solUnimplementedAssert(!funType.isBareCall(), "");
|
|
||||||
Whiskers templ(R"(
|
Whiskers templ(R"(
|
||||||
<?checkExistence>
|
<?checkExistence>
|
||||||
if iszero(extcodesize(<address>)) { revert(0, 0) }
|
if iszero(extcodesize(<address>)) { revert(0, 0) }
|
||||||
@ -1489,8 +1497,18 @@ void IRGeneratorForStatements::appendExternalFunctionCall(
|
|||||||
|
|
||||||
// storage for arguments and returned data
|
// storage for arguments and returned data
|
||||||
let <pos> := <freeMemory>
|
let <pos> := <freeMemory>
|
||||||
mstore(<pos>, <shl28>(<funId>))
|
<?bareCall>
|
||||||
let <end> := <encodeArgs>(add(<pos>, 4) <argumentString>)
|
<!bareCall>
|
||||||
|
mstore(<pos>, <shl28>(<funId>))
|
||||||
|
</bareCall>
|
||||||
|
let <end> := <encodeArgs>(
|
||||||
|
<?bareCall>
|
||||||
|
<pos>
|
||||||
|
<!bareCall>
|
||||||
|
add(<pos>, 4)
|
||||||
|
</bareCall>
|
||||||
|
<argumentString>
|
||||||
|
)
|
||||||
|
|
||||||
let <success> := <call>(<gas>, <address>, <?hasValue> <value>, </hasValue> <pos>, sub(<end>, <pos>), <pos>, <reservedReturnSize>)
|
let <success> := <call>(<gas>, <address>, <?hasValue> <value>, </hasValue> <pos>, sub(<end>, <pos>), <pos>, <reservedReturnSize>)
|
||||||
<?noTryCall>
|
<?noTryCall>
|
||||||
@ -1512,14 +1530,25 @@ void IRGeneratorForStatements::appendExternalFunctionCall(
|
|||||||
)");
|
)");
|
||||||
templ("pos", m_context.newYulVariable());
|
templ("pos", m_context.newYulVariable());
|
||||||
templ("end", m_context.newYulVariable());
|
templ("end", m_context.newYulVariable());
|
||||||
|
templ("bareCall", funType.isBareCall());
|
||||||
if (_functionCall.annotation().tryCall)
|
if (_functionCall.annotation().tryCall)
|
||||||
templ("success", m_context.trySuccessConditionVariable(_functionCall));
|
templ("success", m_context.trySuccessConditionVariable(_functionCall));
|
||||||
else
|
else
|
||||||
templ("success", m_context.newYulVariable());
|
templ("success", m_context.newYulVariable());
|
||||||
templ("freeMemory", freeMemory());
|
templ("freeMemory", freeMemory());
|
||||||
templ("shl28", m_utils.shiftLeftFunction(8 * (32 - 4)));
|
templ("shl28", m_utils.shiftLeftFunction(8 * (32 - 4)));
|
||||||
templ("funId", IRVariable(_functionCall.expression()).part("functionIdentifier").name());
|
|
||||||
templ("address", IRVariable(_functionCall.expression()).part("address").name());
|
if (!funType.isBareCall())
|
||||||
|
templ("funId", IRVariable(_functionCall.expression()).part("functionIdentifier").name());
|
||||||
|
|
||||||
|
if (funKind == FunctionType::Kind::ECRecover)
|
||||||
|
templ("address", "1");
|
||||||
|
else if (funKind == FunctionType::Kind::SHA256)
|
||||||
|
templ("address", "2");
|
||||||
|
else if (funKind == FunctionType::Kind::RIPEMD160)
|
||||||
|
templ("address", "3");
|
||||||
|
else
|
||||||
|
templ("address", IRVariable(_functionCall.expression()).part("address").name());
|
||||||
|
|
||||||
// Always use the actual return length, and not our calculated expected length, if returndatacopy is supported.
|
// Always use the actual return length, and not our calculated expected length, if returndatacopy is supported.
|
||||||
// This ensures it can catch badly formatted input from external calls.
|
// This ensures it can catch badly formatted input from external calls.
|
||||||
@ -1551,9 +1580,15 @@ void IRGeneratorForStatements::appendExternalFunctionCall(
|
|||||||
// but all parameters of ecrecover are value types anyway.
|
// but all parameters of ecrecover are value types anyway.
|
||||||
encodeInPlace = false;
|
encodeInPlace = false;
|
||||||
bool encodeForLibraryCall = funKind == FunctionType::Kind::DelegateCall;
|
bool encodeForLibraryCall = funKind == FunctionType::Kind::DelegateCall;
|
||||||
solUnimplementedAssert(!encodeInPlace, "");
|
|
||||||
solUnimplementedAssert(funType.padArguments(), "");
|
solUnimplementedAssert(encodeInPlace == !funType.padArguments(), "");
|
||||||
templ("encodeArgs", abi.tupleEncoder(argumentTypes, funType.parameterTypes(), encodeForLibraryCall));
|
if (encodeInPlace)
|
||||||
|
{
|
||||||
|
solUnimplementedAssert(!encodeForLibraryCall, "");
|
||||||
|
templ("encodeArgs", abi.tupleEncoderPacked(argumentTypes, funType.parameterTypes()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
templ("encodeArgs", abi.tupleEncoder(argumentTypes, funType.parameterTypes(), encodeForLibraryCall));
|
||||||
templ("argumentString", argumentString);
|
templ("argumentString", argumentString);
|
||||||
|
|
||||||
// Output data will replace input data, unless we have ECRecover (then, output
|
// Output data will replace input data, unless we have ECRecover (then, output
|
||||||
|
@ -3,6 +3,7 @@ contract C {
|
|||||||
return sha256("");
|
return sha256("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// f() -> 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
// f() -> 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||||
|
Loading…
Reference in New Issue
Block a user