mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Evaluate keccak256 of string literals at compile-time.
This commit is contained in:
parent
ad5ae2eefe
commit
0a0f578d7c
@ -1,5 +1,7 @@
|
||||
### 0.6.12 (unreleased)
|
||||
|
||||
Compiler Features:
|
||||
* Code Generator: Evaluate ``keccak256`` of string literals at compile-time.
|
||||
|
||||
|
||||
|
||||
|
@ -792,20 +792,24 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
||||
TypePointer const& argType = arguments.front()->annotation().type;
|
||||
solAssert(argType, "");
|
||||
arguments.front()->accept(*this);
|
||||
if (auto const* stringLiteral = dynamic_cast<StringLiteralType const*>(argType))
|
||||
// Optimization: Compute keccak256 on string literals at compile-time.
|
||||
m_context << u256(keccak256(stringLiteral->value()));
|
||||
else if (*argType == *TypeProvider::bytesMemory() || *argType == *TypeProvider::stringMemory())
|
||||
{
|
||||
// Optimization: If type is bytes or string, then do not encode,
|
||||
// but directly compute keccak256 on memory.
|
||||
if (*argType == *TypeProvider::bytesMemory() || *argType == *TypeProvider::stringMemory())
|
||||
{
|
||||
ArrayUtils(m_context).retrieveLength(*TypeProvider::bytesMemory());
|
||||
m_context << Instruction::SWAP1 << u256(0x20) << Instruction::ADD;
|
||||
m_context << Instruction::KECCAK256;
|
||||
}
|
||||
else
|
||||
{
|
||||
utils().fetchFreeMemoryPointer();
|
||||
utils().packedEncode({argType}, TypePointers());
|
||||
utils().toSizeAfterFreeMemoryPointer();
|
||||
}
|
||||
m_context << Instruction::KECCAK256;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FunctionType::Kind::Log0:
|
||||
|
@ -1020,6 +1020,15 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
||||
|
||||
ArrayType const* arrayType = TypeProvider::bytesMemory();
|
||||
|
||||
if (auto const* stringLiteral = dynamic_cast<StringLiteralType const*>(arguments.front()->annotation().type))
|
||||
{
|
||||
// Optimization: Compute keccak256 on string literals at compile-time.
|
||||
define(_functionCall) <<
|
||||
("0x" + keccak256(stringLiteral->value()).hex()) <<
|
||||
"\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
auto array = convert(*arguments[0], *arrayType);
|
||||
|
||||
define(_functionCall) <<
|
||||
@ -1032,6 +1041,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
||||
"(" <<
|
||||
array.commaSeparatedList() <<
|
||||
"))\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FunctionType::Kind::ArrayPop:
|
||||
|
@ -0,0 +1,19 @@
|
||||
// tests compile-time evaluation of keccak256 on literal strings
|
||||
contract C {
|
||||
function short() public pure returns (bool) {
|
||||
bytes32 a = keccak256("abcdefghijklmn");
|
||||
bytes memory s = "abcdefghijklmn";
|
||||
return a == keccak256(s);
|
||||
}
|
||||
bytes32 constant sc = keccak256("abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn");
|
||||
function long() public pure returns (bool, bool) {
|
||||
bytes32 a = keccak256("abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn");
|
||||
bytes memory s = "abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn";
|
||||
return (a == keccak256(s), sc == keccak256(s));
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// short() -> true
|
||||
// long() -> true, true
|
Loading…
Reference in New Issue
Block a user