mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Fix copying byte arrays from storage to storage.
This commit is contained in:
		
							parent
							
								
									d84415cb3b
								
							
						
					
					
						commit
						7764ee8d86
					
				| @ -1633,8 +1633,9 @@ string YulUtilFunctions::copyByteArrayToStorageFunction(ArrayType const& _fromTy | ||||
| 
 | ||||
| 				let oldLen := <byteArrayLength>(sload(slot)) | ||||
| 
 | ||||
| 				let srcOffset := 0 | ||||
| 				<?fromMemory> | ||||
| 					src := add(src, 0x20) | ||||
| 					srcOffset := 0x20 | ||||
| 				</fromMemory> | ||||
| 
 | ||||
| 				// This is not needed in all branches.
 | ||||
| @ -1652,14 +1653,16 @@ string YulUtilFunctions::copyByteArrayToStorageFunction(ArrayType const& _fromTy | ||||
| 				switch gt(newLen, 31) | ||||
| 				case 1 { | ||||
| 					let loopEnd := and(newLen, not(0x1f)) | ||||
| 					<?fromStorage> src := <srcDataLocation>(src) </fromStorage> | ||||
| 					let dstPtr := dstDataArea | ||||
| 					let i := 0 | ||||
| 					for { } lt(i, loopEnd) { i := add(i, 32) } { | ||||
| 						sstore(dstPtr, <read>(add(src, i))) | ||||
| 					for { } lt(i, loopEnd) { i := add(i, 0x20) } { | ||||
| 						sstore(dstPtr, <read>(add(src, srcOffset))) | ||||
| 						dstPtr := add(dstPtr, 1) | ||||
| 						srcOffset := add(srcOffset, <srcIncrement>) | ||||
| 					} | ||||
| 					if lt(loopEnd, newLen) { | ||||
| 						let lastValue := <read>(add(src, i)) | ||||
| 						let lastValue := <read>(add(src, srcOffset)) | ||||
| 						sstore(dstPtr, <maskBytes>(lastValue, and(newLen, 0x1f))) | ||||
| 					} | ||||
| 					sstore(slot, add(mul(newLen, 2), 1)) | ||||
| @ -1667,7 +1670,7 @@ string YulUtilFunctions::copyByteArrayToStorageFunction(ArrayType const& _fromTy | ||||
| 				default { | ||||
| 					let value := 0 | ||||
| 					if newLen { | ||||
| 						value := <read>(src) | ||||
| 						value := <read>(add(src, srcOffset)) | ||||
| 					} | ||||
| 					sstore(slot, <byteArrayCombineShort>(value, newLen)) | ||||
| 				} | ||||
| @ -1683,7 +1686,10 @@ string YulUtilFunctions::copyByteArrayToStorageFunction(ArrayType const& _fromTy | ||||
| 		templ("panic", panicFunction()); | ||||
| 		templ("byteArrayLength", extractByteArrayLengthFunction()); | ||||
| 		templ("dstDataLocation", arrayDataAreaFunction(_toType)); | ||||
| 		if (fromStorage) | ||||
| 			templ("srcDataLocation", arrayDataAreaFunction(_fromType)); | ||||
| 		templ("clearStorageRange", clearStorageRangeFunction(*_toType.baseType())); | ||||
| 		templ("srcIncrement", to_string(fromStorage ? 1 : 0x20)); | ||||
| 		templ("read", fromStorage ? "sload" : fromCalldata ? "calldataload" : "mload"); | ||||
| 		templ("maskBytes", maskBytesFunctionDynamic()); | ||||
| 		templ("byteArrayCombineShort", shortByteArrayEncodeUsedAreaSetLengthFunction()); | ||||
|  | ||||
| @ -0,0 +1,26 @@ | ||||
| contract c { | ||||
|     bytes a; | ||||
|     bytes b; | ||||
|     function f(uint len) public returns (bytes memory) { | ||||
|         bytes memory x = new bytes(len); | ||||
|         for (uint i = 0; i < len; i++) | ||||
|             x[i] = byte(uint8(i)); | ||||
|         a = x; | ||||
|         for (uint i = 0; i < len; i++) | ||||
|             assert(a[i] == x[i]); | ||||
|         b = a; | ||||
|         for (uint i = 0; i < len; i++) | ||||
|             assert(b[i] == x[i]); | ||||
|         return b; | ||||
|     } | ||||
| } | ||||
| // ==== | ||||
| // compileViaYul: also | ||||
| // ---- | ||||
| // f(uint256): 0 -> 0x20, 0x00 | ||||
| // f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00 | ||||
| // f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671 | ||||
| // f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000 | ||||
| // f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992 | ||||
| // f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000 | ||||
| // f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968 | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user