diff options
author | Alex Beregszaszi <alex@rtfs.hu> | 2016-12-02 21:14:18 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2016-12-12 00:57:15 +0800 |
commit | b93589b3b62ca12fe5446d7caed0c0964158cd6e (patch) | |
tree | c4ff1ade05062375aac0c9c668eae012970a333e /libsolidity/codegen | |
parent | bf5dac1fb255a54825952219c852869b8c2663e9 (diff) | |
download | dexon-solidity-b93589b3b62ca12fe5446d7caed0c0964158cd6e.tar.gz dexon-solidity-b93589b3b62ca12fe5446d7caed0c0964158cd6e.tar.zst dexon-solidity-b93589b3b62ca12fe5446d7caed0c0964158cd6e.zip |
Implement identity call in inline assembly
Diffstat (limited to 'libsolidity/codegen')
-rw-r--r-- | libsolidity/codegen/CompilerUtils.cpp | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 634474a1..8b94bd0d 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -300,6 +300,8 @@ void CompilerUtils::zeroInitialiseMemoryArray(ArrayType const& _type) void CompilerUtils::memoryCopy(bool _useIdentityPrecompile) { + //@TODO do not use ::CALL if less than 32 bytes? + // Stack here: size target source if (!_useIdentityPrecompile) @@ -332,20 +334,25 @@ void CompilerUtils::memoryCopy(bool _useIdentityPrecompile) m_context << Instruction::POP; return; } - - // stack for call: outsize target size source value contract gas - //@TODO do not use ::CALL if less than 32 bytes? - m_context << Instruction::DUP3 << Instruction::SWAP1; - m_context << u256(0) << u256(identityContractAddress); - // compute gas costs - m_context << u256(32) << Instruction::DUP5 << u256(31) << Instruction::ADD; - static unsigned c_identityGas = 15; - static unsigned c_identityWordGas = 3; - m_context << Instruction::DIV << u256(c_identityWordGas) << Instruction::MUL; - m_context << u256(c_identityGas) << Instruction::ADD; - m_context << Instruction::CALL; - m_context << Instruction::ISZERO; - m_context.appendConditionalJumpTo(m_context.errorTag()); + else + { + m_context.appendInlineAssembly(R"( + { + let words := div(add(len, 31), 32) + let cost := add(15, mul(3, words)) + jump(invalidJumpLabel, iszero(call(cost, $identityContractAddress, 0, src, len, dst, len))) + } + )", + { "len", "dst", "src" }, + map<string, string> { + { "$identityContractAddress", toString(identityContractAddress) } + } + ); + m_context << Instruction::POP; + m_context << Instruction::POP; + m_context << Instruction::POP; + return; + } } void CompilerUtils::splitExternalFunctionType(bool _leftAligned) |