diff options
author | Remco Bloemen <remco@wicked.ventures> | 2018-06-11 15:19:52 +0800 |
---|---|---|
committer | Remco Bloemen <remco@wicked.ventures> | 2018-06-11 15:19:52 +0800 |
commit | 82d1412d456ee28d80597208a241a2b62f561837 (patch) | |
tree | bdea23b9b44ed1e356fd0665a1008eab4785e4dc /packages/contracts/src | |
parent | 817c332d11835f02726f0609374d1c25c9ab39b5 (diff) | |
download | dexon-sol-tools-82d1412d456ee28d80597208a241a2b62f561837.tar dexon-sol-tools-82d1412d456ee28d80597208a241a2b62f561837.tar.gz dexon-sol-tools-82d1412d456ee28d80597208a241a2b62f561837.tar.bz2 dexon-sol-tools-82d1412d456ee28d80597208a241a2b62f561837.tar.lz dexon-sol-tools-82d1412d456ee28d80597208a241a2b62f561837.tar.xz dexon-sol-tools-82d1412d456ee28d80597208a241a2b62f561837.tar.zst dexon-sol-tools-82d1412d456ee28d80597208a241a2b62f561837.zip |
Simplified handling of source < 32 edge case
Diffstat (limited to 'packages/contracts/src')
-rw-r--r-- | packages/contracts/src/contracts/current/utils/LibMem/LibMem.sol | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/packages/contracts/src/contracts/current/utils/LibMem/LibMem.sol b/packages/contracts/src/contracts/current/utils/LibMem/LibMem.sol index 6afb9973a..97fb5fb0f 100644 --- a/packages/contracts/src/contracts/current/utils/LibMem/LibMem.sol +++ b/packages/contracts/src/contracts/current/utils/LibMem/LibMem.sol @@ -80,9 +80,6 @@ contract LibMem // if (source > dest) { assembly { - // Record the total number of full words to copy - let nWords := div(length, 32) - // We subtract 32 from `sEnd` and `dEnd` because it // is easier to compare with in the loop, and these // are also the addresses we need for copying the @@ -98,20 +95,19 @@ contract LibMem let last := mload(sEnd) // Copy whole words front to back - for {let i := 0} lt(i, nWords) {i := add(i, 1)} { + // Note: the first check is always true, + // this could have been a do-while loop. + for {} lt(source, sEnd) {} { mstore(dest, mload(source)) source := add(source, 32) dest := add(dest, 32) } - + // Write the last 32 bytes mstore(dEnd, last) } } else { assembly { - // Record the total number of full words to copy - let nWords := div(length, 32) - // We subtract 32 from `sEnd` and `dEnd` because those // are the starting points when copying a word at the end. length := sub(length, 32) @@ -125,12 +121,18 @@ contract LibMem let first := mload(source) // Copy whole words back to front - for {let i := 0} lt(i, nWords) {i := add(i, 1)} { + // We use a signed comparisson here to allow dEnd to become + // negative (happens when source and dest < 32). Valid + // addresses in local memory will never be larger than + // 2**255, so they can be safely re-interpreted as signed. + // Note: the first check is always true, + // this could have been a do-while loop. + for {} slt(dest, dEnd) {} { mstore(dEnd, mload(sEnd)) sEnd := sub(sEnd, 32) dEnd := sub(dEnd, 32) } - + // Write the first 32 bytes mstore(dest, first) } |