Implement identity call in inline assembly

This commit is contained in:
Alex Beregszaszi 2016-12-02 13:14:18 +00:00 committed by chriseth
parent bf5dac1fb2
commit b93589b3b6

View File

@ -300,6 +300,8 @@ void CompilerUtils::zeroInitialiseMemoryArray(ArrayType const& _type)
void CompilerUtils::memoryCopy(bool _useIdentityPrecompile) void CompilerUtils::memoryCopy(bool _useIdentityPrecompile)
{ {
//@TODO do not use ::CALL if less than 32 bytes?
// Stack here: size target source // Stack here: size target source
if (!_useIdentityPrecompile) if (!_useIdentityPrecompile)
@ -332,20 +334,25 @@ void CompilerUtils::memoryCopy(bool _useIdentityPrecompile)
m_context << Instruction::POP; m_context << Instruction::POP;
return; return;
} }
else
// stack for call: outsize target size source value contract gas {
//@TODO do not use ::CALL if less than 32 bytes? m_context.appendInlineAssembly(R"(
m_context << Instruction::DUP3 << Instruction::SWAP1; {
m_context << u256(0) << u256(identityContractAddress); let words := div(add(len, 31), 32)
// compute gas costs let cost := add(15, mul(3, words))
m_context << u256(32) << Instruction::DUP5 << u256(31) << Instruction::ADD; jump(invalidJumpLabel, iszero(call(cost, $identityContractAddress, 0, src, len, dst, len)))
static unsigned c_identityGas = 15; }
static unsigned c_identityWordGas = 3; )",
m_context << Instruction::DIV << u256(c_identityWordGas) << Instruction::MUL; { "len", "dst", "src" },
m_context << u256(c_identityGas) << Instruction::ADD; map<string, string> {
m_context << Instruction::CALL; { "$identityContractAddress", toString(identityContractAddress) }
m_context << Instruction::ISZERO; }
m_context.appendConditionalJumpTo(m_context.errorTag()); );
m_context << Instruction::POP;
m_context << Instruction::POP;
m_context << Instruction::POP;
return;
}
} }
void CompilerUtils::splitExternalFunctionType(bool _leftAligned) void CompilerUtils::splitExternalFunctionType(bool _leftAligned)