Save double encode call for sha3.

This commit is contained in:
chriseth 2018-05-23 16:55:58 +02:00 committed by Alex Beregszaszi
parent 86a720b96a
commit a55e8c93ce

View File

@ -699,16 +699,24 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
} }
case FunctionType::Kind::SHA3: case FunctionType::Kind::SHA3:
{ {
TypePointers argumentTypes; solAssert(arguments.size() == 1, "");
for (auto const& arg: arguments)
{
arg->accept(*this);
argumentTypes.push_back(arg->annotation().type);
}
utils().fetchFreeMemoryPointer();
solAssert(!function.padArguments(), ""); solAssert(!function.padArguments(), "");
utils().packedEncode(argumentTypes, TypePointers()); TypePointer const& argType = arguments.front()->annotation().type;
utils().toSizeAfterFreeMemoryPointer(); solAssert(argType, "");
arguments.front()->accept(*this);
// Optimization: If type is bytes or string, then do not encode,
// but directly compute keccak256 on memory.
if (*argType == ArrayType(DataLocation::Memory) || *argType == ArrayType(DataLocation::Memory, true))
{
ArrayUtils(m_context).retrieveLength(ArrayType(DataLocation::Memory));
m_context << Instruction::SWAP1 << u256(0x20) << Instruction::ADD;
}
else
{
utils().fetchFreeMemoryPointer();
utils().packedEncode({argType}, TypePointers());
utils().toSizeAfterFreeMemoryPointer();
}
m_context << Instruction::KECCAK256; m_context << Instruction::KECCAK256;
break; break;
} }