Merge pull request #2453 from ethereum/memcopyAsForLoop

Use for loop for assembly memcopy.
This commit is contained in:
Alex Beregszaszi 2017-06-26 22:39:30 +01:00 committed by GitHub
commit b0ab9aaee0
2 changed files with 20 additions and 23 deletions

View File

@ -305,15 +305,9 @@ void CompilerUtils::memoryCopy32()
m_context.appendInlineAssembly(R"( m_context.appendInlineAssembly(R"(
{ {
jumpi(end, eq(len, 0)) for { let i := 0 } lt(i, len) { i := add(i, 32) } {
start: mstore(add(dst, i), mload(add(src, i)))
mstore(dst, mload(src)) }
jumpi(end, iszero(gt(len, 32)))
dst := add(dst, 32)
src := add(src, 32)
len := sub(len, 32)
jump(start)
end:
} }
)", )",
{ "len", "dst", "src" } { "len", "dst", "src" }
@ -327,21 +321,22 @@ void CompilerUtils::memoryCopy()
m_context.appendInlineAssembly(R"( m_context.appendInlineAssembly(R"(
{ {
// copy 32 bytes at once // copy 32 bytes at once
start32: for
jumpi(end32, lt(len, 32)) {}
mstore(dst, mload(src)) iszero(lt(len, 32))
dst := add(dst, 32) {
src := add(src, 32) dst := add(dst, 32)
len := sub(len, 32) src := add(src, 32)
jump(start32) len := sub(len, 32)
end32: }
{ mstore(dst, mload(src)) }
// copy the remainder (0 < len < 32) // copy the remainder (0 < len < 32)
let mask := sub(exp(256, sub(32, len)), 1) let mask := sub(exp(256, sub(32, len)), 1)
let srcpart := and(mload(src), not(mask)) let srcpart := and(mload(src), not(mask))
let dstpart := and(mload(dst), mask) let dstpart := and(mload(dst), mask)
mstore(dst, or(srcpart, dstpart)) mstore(dst, or(srcpart, dstpart))
} }
)", )",
{ "len", "dst", "src" } { "len", "dst", "src" }

View File

@ -110,10 +110,12 @@ public:
void zeroInitialiseMemoryArray(ArrayType const& _type); void zeroInitialiseMemoryArray(ArrayType const& _type);
/// Copies full 32 byte words in memory (regions cannot overlap), i.e. may copy more than length. /// Copies full 32 byte words in memory (regions cannot overlap), i.e. may copy more than length.
/// Length can be zero, in this case, it copies nothing.
/// Stack pre: <size> <target> <source> /// Stack pre: <size> <target> <source>
/// Stack post: /// Stack post:
void memoryCopy32(); void memoryCopy32();
/// Copies data in memory (regions cannot overlap). /// Copies data in memory (regions cannot overlap).
/// Length can be zero, in this case, it copies nothing.
/// Stack pre: <size> <target> <source> /// Stack pre: <size> <target> <source>
/// Stack post: /// Stack post:
void memoryCopy(); void memoryCopy();