diff --git a/.changeset/forty-bikes-push.md b/.changeset/forty-bikes-push.md new file mode 100644 index 0000000000..8359c75b2b --- /dev/null +++ b/.changeset/forty-bikes-push.md @@ -0,0 +1,9 @@ +--- +"@latticexyz/cli": patch +"@latticexyz/common": patch +"@latticexyz/store": patch +--- + +Refactor tightcoder to use typescript functions instead of ejs +Optimize `encode` function in generated table libraries using a new `renderEncodeRecord` codegen function +Add `isLeftAligned` and `shiftLeftBits` common codegen helpers diff --git a/e2e/packages/contracts/src/codegen/tables/NumberList.sol b/e2e/packages/contracts/src/codegen/tables/NumberList.sol index 01f3216eb8..27d5f6ccc4 100644 --- a/e2e/packages/contracts/src/codegen/tables/NumberList.sol +++ b/e2e/packages/contracts/src/codegen/tables/NumberList.sol @@ -172,9 +172,30 @@ library NumberList { function encode(uint32[] memory value) internal pure returns (bytes memory) { uint40[] memory _counters = new uint40[](1); _counters[0] = uint40(value.length * 4); - PackedCounter _encodedLengths = PackedCounterLib.pack(_counters); - - return abi.encodePacked(_encodedLengths.unwrap(), EncodeArray.encode((value))); + bytes32 _encodedLengths = PackedCounterLib.pack(_counters).unwrap(); + + uint256 _resultLength; + unchecked { + _resultLength = 32 + value.length * 4; + } + + bytes memory _result; + uint256 _resultPointer; + + /// @solidity memory-safe-assembly + assembly { + // allocate memory + _result := mload(0x40) + _resultPointer := add(_result, 0x20) + mstore(0x40, add(_resultPointer, and(add(_resultLength, 31), not(31)))) + mstore(_result, _resultLength) + + mstore(add(_resultPointer, 0), shl(0, _encodedLengths)) + + _resultPointer := add(_resultPointer, 32) + } + EncodeArray.encodeToLocation((value), _resultPointer); + return _result; } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol b/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol index 935e5bf105..e0ead90236 100644 --- a/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol +++ b/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol @@ -86,9 +86,30 @@ library MessageTable { function encode(string memory value) internal pure returns (bytes memory) { uint40[] memory _counters = new uint40[](1); _counters[0] = uint40(bytes(value).length); - PackedCounter _encodedLengths = PackedCounterLib.pack(_counters); - - return abi.encodePacked(_encodedLengths.unwrap(), bytes((value))); + bytes32 _encodedLengths = PackedCounterLib.pack(_counters).unwrap(); + + uint256 _resultLength; + unchecked { + _resultLength = 32 + bytes(value).length; + } + + bytes memory _result; + uint256 _resultPointer; + + /// @solidity memory-safe-assembly + assembly { + // allocate memory + _result := mload(0x40) + _resultPointer := add(_result, 0x20) + mstore(0x40, add(_resultPointer, and(add(_resultLength, 31), not(31)))) + mstore(_result, _resultLength) + + mstore(add(_resultPointer, 0), shl(0, _encodedLengths)) + + _resultPointer := add(_resultPointer, 32) + } + Memory.copy(Memory.dataPointer(bytes((value))), _resultPointer, bytes(value).length); + return _result; } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/cli/contracts/src/codegen/tables/Dynamics1.sol b/packages/cli/contracts/src/codegen/tables/Dynamics1.sol index d6b5ceb57d..c5e8113b8c 100644 --- a/packages/cli/contracts/src/codegen/tables/Dynamics1.sol +++ b/packages/cli/contracts/src/codegen/tables/Dynamics1.sol @@ -781,17 +781,57 @@ library Dynamics1 { _counters[2] = uint40(staticU128.length * 16); _counters[3] = uint40(staticAddrs.length * 20); _counters[4] = uint40(staticBools.length * 1); - PackedCounter _encodedLengths = PackedCounterLib.pack(_counters); - - return - abi.encodePacked( - _encodedLengths.unwrap(), - EncodeArray.encode(fromStaticArray_bytes32_1(staticB32)), - EncodeArray.encode(fromStaticArray_int32_2(staticI32)), - EncodeArray.encode(fromStaticArray_uint128_3(staticU128)), - EncodeArray.encode(fromStaticArray_address_4(staticAddrs)), - EncodeArray.encode(fromStaticArray_bool_5(staticBools)) - ); + bytes32 _encodedLengths = PackedCounterLib.pack(_counters).unwrap(); + + uint256 _resultLength; + unchecked { + _resultLength = + 32 + + staticB32.length * + 32 + + staticI32.length * + 4 + + staticU128.length * + 16 + + staticAddrs.length * + 20 + + staticBools.length * + 1; + } + + bytes memory _result; + uint256 _resultPointer; + + /// @solidity memory-safe-assembly + assembly { + // allocate memory + _result := mload(0x40) + _resultPointer := add(_result, 0x20) + mstore(0x40, add(_resultPointer, and(add(_resultLength, 31), not(31)))) + mstore(_result, _resultLength) + + mstore(add(_resultPointer, 0), shl(0, _encodedLengths)) + + _resultPointer := add(_resultPointer, 32) + } + EncodeArray.encodeToLocation(fromStaticArray_bytes32_1(staticB32), _resultPointer); + unchecked { + _resultPointer += staticB32.length * 32; + } + EncodeArray.encodeToLocation(fromStaticArray_int32_2(staticI32), _resultPointer); + unchecked { + _resultPointer += staticI32.length * 4; + } + EncodeArray.encodeToLocation(fromStaticArray_uint128_3(staticU128), _resultPointer); + unchecked { + _resultPointer += staticU128.length * 16; + } + EncodeArray.encodeToLocation(fromStaticArray_address_4(staticAddrs), _resultPointer); + unchecked { + _resultPointer += staticAddrs.length * 20; + } + EncodeArray.encodeToLocation(fromStaticArray_bool_5(staticBools), _resultPointer); + return _result; } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/cli/contracts/src/codegen/tables/Dynamics2.sol b/packages/cli/contracts/src/codegen/tables/Dynamics2.sol index 7ad7f58d48..ef98ad393c 100644 --- a/packages/cli/contracts/src/codegen/tables/Dynamics2.sol +++ b/packages/cli/contracts/src/codegen/tables/Dynamics2.sol @@ -508,9 +508,38 @@ library Dynamics2 { _counters[0] = uint40(u64.length * 8); _counters[1] = uint40(bytes(str).length); _counters[2] = uint40(bytes(b).length); - PackedCounter _encodedLengths = PackedCounterLib.pack(_counters); + bytes32 _encodedLengths = PackedCounterLib.pack(_counters).unwrap(); - return abi.encodePacked(_encodedLengths.unwrap(), EncodeArray.encode((u64)), bytes((str)), bytes((b))); + uint256 _resultLength; + unchecked { + _resultLength = 32 + u64.length * 8 + bytes(str).length + bytes(b).length; + } + + bytes memory _result; + uint256 _resultPointer; + + /// @solidity memory-safe-assembly + assembly { + // allocate memory + _result := mload(0x40) + _resultPointer := add(_result, 0x20) + mstore(0x40, add(_resultPointer, and(add(_resultLength, 31), not(31)))) + mstore(_result, _resultLength) + + mstore(add(_resultPointer, 0), shl(0, _encodedLengths)) + + _resultPointer := add(_resultPointer, 32) + } + EncodeArray.encodeToLocation((u64), _resultPointer); + unchecked { + _resultPointer += u64.length * 8; + } + Memory.copy(Memory.dataPointer(bytes((str))), _resultPointer, bytes(str).length); + unchecked { + _resultPointer += bytes(str).length; + } + Memory.copy(Memory.dataPointer(bytes((b))), _resultPointer, bytes(b).length); + return _result; } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/cli/contracts/src/codegen/tables/Singleton.sol b/packages/cli/contracts/src/codegen/tables/Singleton.sol index 8939040967..1fc2dc5f3b 100644 --- a/packages/cli/contracts/src/codegen/tables/Singleton.sol +++ b/packages/cli/contracts/src/codegen/tables/Singleton.sol @@ -488,16 +488,40 @@ library Singleton { _counters[0] = uint40(v2.length * 4); _counters[1] = uint40(v3.length * 4); _counters[2] = uint40(v4.length * 4); - PackedCounter _encodedLengths = PackedCounterLib.pack(_counters); - - return - abi.encodePacked( - v1, - _encodedLengths.unwrap(), - EncodeArray.encode(fromStaticArray_uint32_2(v2)), - EncodeArray.encode(fromStaticArray_uint32_2(v3)), - EncodeArray.encode(fromStaticArray_uint32_1(v4)) - ); + bytes32 _encodedLengths = PackedCounterLib.pack(_counters).unwrap(); + + uint256 _resultLength; + unchecked { + _resultLength = 64 + v2.length * 4 + v3.length * 4 + v4.length * 4; + } + + bytes memory _result; + uint256 _resultPointer; + + /// @solidity memory-safe-assembly + assembly { + // allocate memory + _result := mload(0x40) + _resultPointer := add(_result, 0x20) + mstore(0x40, add(_resultPointer, and(add(_resultLength, 31), not(31)))) + mstore(_result, _resultLength) + + mstore(add(_resultPointer, 0), shl(0, v1)) + + mstore(add(_resultPointer, 32), shl(0, _encodedLengths)) + + _resultPointer := add(_resultPointer, 64) + } + EncodeArray.encodeToLocation(fromStaticArray_uint32_2(v2), _resultPointer); + unchecked { + _resultPointer += v2.length * 4; + } + EncodeArray.encodeToLocation(fromStaticArray_uint32_2(v3), _resultPointer); + unchecked { + _resultPointer += v3.length * 4; + } + EncodeArray.encodeToLocation(fromStaticArray_uint32_1(v4), _resultPointer); + return _result; } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/common/src/codegen/render-solidity/common.ts b/packages/common/src/codegen/render-solidity/common.ts index d8ea6dc0ef..54399134f2 100644 --- a/packages/common/src/codegen/render-solidity/common.ts +++ b/packages/common/src/codegen/render-solidity/common.ts @@ -180,6 +180,18 @@ export function renderValueTypeToBytes32(name: string, { typeUnwrap, internalTyp } } +export function isLeftAligned(field: Pick): boolean { + return field.internalTypeId.match(/^bytes\d{1,2}$/) !== null; +} + +export function shiftLeftBits(field: Pick): number { + if (isLeftAligned(field)) { + return 0; + } else { + return 256 - field.staticByteLength * 8; + } +} + function internalRenderList( lineTerminator: string, list: T[], diff --git a/packages/store/gas-report.json b/packages/store/gas-report.json index 7993745630..a4e0b93279 100644 --- a/packages/store/gas-report.json +++ b/packages/store/gas-report.json @@ -75,25 +75,25 @@ "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", "name": "custom encode", - "gasUsed": 1812 + "gasUsed": 2417 }, { "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", "name": "custom decode", - "gasUsed": 2127 + "gasUsed": 2939 }, { "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", "name": "pass abi encoded bytes to external contract", - "gasUsed": 6551 + "gasUsed": 6550 }, { "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", "name": "pass custom encoded bytes to external contract", - "gasUsed": 1376 + "gasUsed": 1452 }, { "file": "test/KeyEncoding.t.sol", @@ -117,13 +117,13 @@ "file": "test/Mixed.t.sol", "test": "testSetAndGet", "name": "set record in Mixed", - "gasUsed": 111108 + "gasUsed": 110178 }, { "file": "test/Mixed.t.sol", "test": "testSetAndGet", "name": "get record from Mixed", - "gasUsed": 12600 + "gasUsed": 12623 }, { "file": "test/PackedCounter.t.sol", @@ -231,37 +231,37 @@ "file": "test/Slice.t.sol", "test": "testToBytes", "name": "Slice (0 bytes) to bytes memory", - "gasUsed": 476 + "gasUsed": 298 }, { "file": "test/Slice.t.sol", "test": "testToBytes", "name": "Slice (2 bytes) to bytes memory", - "gasUsed": 511 + "gasUsed": 534 }, { "file": "test/Slice.t.sol", "test": "testToBytes", "name": "Slice (32 bytes) to bytes memory", - "gasUsed": 724 + "gasUsed": 545 }, { "file": "test/Slice.t.sol", "test": "testToBytes", "name": "Slice (34 bytes) to bytes memory", - "gasUsed": 727 + "gasUsed": 750 }, { "file": "test/Slice.t.sol", "test": "testToBytes", "name": "Slice (1024 bytes) to bytes memory", - "gasUsed": 7443 + "gasUsed": 7264 }, { "file": "test/Slice.t.sol", "test": "testToBytes", "name": "Slice (1024x1024 bytes) to bytes memory", - "gasUsed": 9205372 + "gasUsed": 9205065 }, { "file": "test/Slice.t.sol", @@ -339,25 +339,25 @@ "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromSecondField", "name": "pop from field (cold, 1 slot, 1 uint32 item)", - "gasUsed": 30792 + "gasUsed": 30815 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromSecondField", "name": "pop from field (warm, 1 slot, 1 uint32 item)", - "gasUsed": 18847 + "gasUsed": 18870 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromThirdField", "name": "pop from field (cold, 2 slots, 10 uint32 items)", - "gasUsed": 32675 + "gasUsed": 32628 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromThirdField", "name": "pop from field (warm, 2 slots, 10 uint32 items)", - "gasUsed": 18730 + "gasUsed": 18683 }, { "file": "test/StoreCoreGas.t.sol", @@ -603,31 +603,31 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetMetadata", "name": "StoreCore: set table metadata", - "gasUsed": 252784 + "gasUsed": 252900 }, { "file": "test/StoreCoreGas.t.sol", "test": "testUpdateInField", "name": "update in field (1 slot, 1 uint32 item)", - "gasUsed": 16064 + "gasUsed": 16040 }, { "file": "test/StoreCoreGas.t.sol", "test": "testUpdateInField", "name": "push to field (2 slots, 6 uint64 items)", - "gasUsed": 17155 + "gasUsed": 17201 }, { "file": "test/StoreMetadata.t.sol", "test": "testSetAndGet", "name": "set record in StoreMetadataTable", - "gasUsed": 251257 + "gasUsed": 251356 }, { "file": "test/StoreMetadata.t.sol", "test": "testSetAndGet", "name": "get record from StoreMetadataTable", - "gasUsed": 12018 + "gasUsed": 11990 }, { "file": "test/StoreSwitch.t.sol", @@ -645,7 +645,7 @@ "file": "test/tables/Callbacks.t.sol", "test": "testSetAndGet", "name": "set field in Callbacks", - "gasUsed": 62243 + "gasUsed": 61982 }, { "file": "test/tables/Callbacks.t.sol", @@ -663,7 +663,7 @@ "file": "test/tables/Hooks.t.sol", "test": "testSetAndGet", "name": "set field in Hooks", - "gasUsed": 64400 + "gasUsed": 63973 }, { "file": "test/tables/Hooks.t.sol", @@ -689,46 +689,40 @@ "name": "decode packed bytes32[]", "gasUsed": 611 }, - { - "file": "test/tightcoder/EncodeArray.t.sol", - "test": "testEncodeBytesArray", - "name": "encode packed bytes[]", - "gasUsed": 1357 - }, { "file": "test/tightcoder/EncodeArray.t.sol", "test": "testEncodeUint16Array", "name": "encode packed uint16[]", - "gasUsed": 1143 + "gasUsed": 710 }, { "file": "test/tightcoder/EncodeArray.t.sol", "test": "testEncodeUint32Array", "name": "encode packed uint32[]", - "gasUsed": 1049 + "gasUsed": 619 }, { "file": "test/tightcoder/EncodeArray.t.sol", "test": "testEncodeUint8Array", "name": "encode packed uint8[]", - "gasUsed": 1038 + "gasUsed": 608 }, { "file": "test/tightcoder/TightCoder.t.sol", "test": "testFromAndToUint32Array", "name": "decode packed uint32[]", - "gasUsed": 788 + "gasUsed": 785 }, { "file": "test/tightcoder/TightCoder.t.sol", "test": "testToAndFromBytes24Array", "name": "encode packed bytes24[]", - "gasUsed": 886 + "gasUsed": 608 }, { "file": "test/tightcoder/TightCoder.t.sol", "test": "testToAndFromBytes24Array", - "name": "decode packed uint32[]", + "name": "decode packed bytes24[]", "gasUsed": 622 }, { diff --git a/packages/store/package.json b/packages/store/package.json index 8c160dc9a4..d7014f0f03 100644 --- a/packages/store/package.json +++ b/packages/store/package.json @@ -34,7 +34,7 @@ } }, "scripts": { - "build": "pnpm run build:mud && pnpm run build:abi && pnpm run build:typechain && pnpm run build:js", + "build": "pnpm run generate-tightcoder && pnpm run build:mud && pnpm run build:abi && pnpm run build:typechain && pnpm run build:js", "build:abi": "forge build --extra-output-files abi --out abi --skip test script MudTest.sol", "build:js": "tsup", "build:mud": "tsx ./ts/scripts/tablegen.ts", @@ -46,7 +46,7 @@ "clean:typechain": "rimraf types", "dev": "tsup --watch", "gas-report": "mud-gas-report --save gas-report.json", - "generate-tightcoder": "tsx ./scripts/generate-tightcoder.ts && prettier --write '**/tightcoder/*.sol'", + "generate-tightcoder": "tsx ./ts/scripts/generate-tightcoder.ts", "lint": "solhint --config ./.solhint.json 'src/**/*.sol'", "test": "vitest typecheck --run && vitest --run --passWithNoTests && forge test" }, diff --git a/packages/store/src/Bytes.sol b/packages/store/src/Bytes.sol index 7fff4357db..8853b52fd4 100644 --- a/packages/store/src/Bytes.sol +++ b/packages/store/src/Bytes.sol @@ -1,8 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import { SliceLib } from "./Slice.sol"; - library Bytes { /** * Converts a `bytes` memory blob to a single `bytes32` memory value, starting at the given byte offset. diff --git a/packages/store/src/Memory.sol b/packages/store/src/Memory.sol index 1856cc18a9..4872c9423a 100644 --- a/packages/store/src/Memory.sol +++ b/packages/store/src/Memory.sol @@ -29,6 +29,8 @@ library Memory { length -= 32; } } + if (length == 0) return; + // Copy the 0-31 length tail uint256 mask = leftMask(length); /// @solidity memory-safe-assembly diff --git a/packages/store/src/codegen/tables/Callbacks.sol b/packages/store/src/codegen/tables/Callbacks.sol index 2383ca033d..7f83a70b7d 100644 --- a/packages/store/src/codegen/tables/Callbacks.sol +++ b/packages/store/src/codegen/tables/Callbacks.sol @@ -187,9 +187,30 @@ library Callbacks { function encode(bytes24[] memory value) internal pure returns (bytes memory) { uint40[] memory _counters = new uint40[](1); _counters[0] = uint40(value.length * 24); - PackedCounter _encodedLengths = PackedCounterLib.pack(_counters); - - return abi.encodePacked(_encodedLengths.unwrap(), EncodeArray.encode((value))); + bytes32 _encodedLengths = PackedCounterLib.pack(_counters).unwrap(); + + uint256 _resultLength; + unchecked { + _resultLength = 32 + value.length * 24; + } + + bytes memory _result; + uint256 _resultPointer; + + /// @solidity memory-safe-assembly + assembly { + // allocate memory + _result := mload(0x40) + _resultPointer := add(_result, 0x20) + mstore(0x40, add(_resultPointer, and(add(_resultLength, 31), not(31)))) + mstore(_result, _resultLength) + + mstore(add(_resultPointer, 0), shl(0, _encodedLengths)) + + _resultPointer := add(_resultPointer, 32) + } + EncodeArray.encodeToLocation((value), _resultPointer); + return _result; } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/store/src/codegen/tables/Hooks.sol b/packages/store/src/codegen/tables/Hooks.sol index 2e0635f124..3b5197ef8d 100644 --- a/packages/store/src/codegen/tables/Hooks.sol +++ b/packages/store/src/codegen/tables/Hooks.sol @@ -187,9 +187,30 @@ library Hooks { function encode(address[] memory value) internal pure returns (bytes memory) { uint40[] memory _counters = new uint40[](1); _counters[0] = uint40(value.length * 20); - PackedCounter _encodedLengths = PackedCounterLib.pack(_counters); - - return abi.encodePacked(_encodedLengths.unwrap(), EncodeArray.encode((value))); + bytes32 _encodedLengths = PackedCounterLib.pack(_counters).unwrap(); + + uint256 _resultLength; + unchecked { + _resultLength = 32 + value.length * 20; + } + + bytes memory _result; + uint256 _resultPointer; + + /// @solidity memory-safe-assembly + assembly { + // allocate memory + _result := mload(0x40) + _resultPointer := add(_result, 0x20) + mstore(0x40, add(_resultPointer, and(add(_resultLength, 31), not(31)))) + mstore(_result, _resultLength) + + mstore(add(_resultPointer, 0), shl(0, _encodedLengths)) + + _resultPointer := add(_resultPointer, 32) + } + EncodeArray.encodeToLocation((value), _resultPointer); + return _result; } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/store/src/codegen/tables/Mixed.sol b/packages/store/src/codegen/tables/Mixed.sol index e8c0803d94..c73fe9e78c 100644 --- a/packages/store/src/codegen/tables/Mixed.sol +++ b/packages/store/src/codegen/tables/Mixed.sol @@ -460,9 +460,38 @@ library Mixed { uint40[] memory _counters = new uint40[](2); _counters[0] = uint40(a32.length * 4); _counters[1] = uint40(bytes(s).length); - PackedCounter _encodedLengths = PackedCounterLib.pack(_counters); + bytes32 _encodedLengths = PackedCounterLib.pack(_counters).unwrap(); - return abi.encodePacked(u32, u128, _encodedLengths.unwrap(), EncodeArray.encode((a32)), bytes((s))); + uint256 _resultLength; + unchecked { + _resultLength = 52 + a32.length * 4 + bytes(s).length; + } + + bytes memory _result; + uint256 _resultPointer; + + /// @solidity memory-safe-assembly + assembly { + // allocate memory + _result := mload(0x40) + _resultPointer := add(_result, 0x20) + mstore(0x40, add(_resultPointer, and(add(_resultLength, 31), not(31)))) + mstore(_result, _resultLength) + + mstore(add(_resultPointer, 0), shl(224, u32)) + + mstore(add(_resultPointer, 4), shl(128, u128)) + + mstore(add(_resultPointer, 20), shl(0, _encodedLengths)) + + _resultPointer := add(_resultPointer, 52) + } + EncodeArray.encodeToLocation((a32), _resultPointer); + unchecked { + _resultPointer += a32.length * 4; + } + Memory.copy(Memory.dataPointer(bytes((s))), _resultPointer, bytes(s).length); + return _result; } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/store/src/codegen/tables/StoreMetadata.sol b/packages/store/src/codegen/tables/StoreMetadata.sol index 1fdcb7394e..996981ee3d 100644 --- a/packages/store/src/codegen/tables/StoreMetadata.sol +++ b/packages/store/src/codegen/tables/StoreMetadata.sol @@ -389,9 +389,34 @@ library StoreMetadata { uint40[] memory _counters = new uint40[](2); _counters[0] = uint40(bytes(tableName).length); _counters[1] = uint40(bytes(abiEncodedFieldNames).length); - PackedCounter _encodedLengths = PackedCounterLib.pack(_counters); + bytes32 _encodedLengths = PackedCounterLib.pack(_counters).unwrap(); - return abi.encodePacked(_encodedLengths.unwrap(), bytes((tableName)), bytes((abiEncodedFieldNames))); + uint256 _resultLength; + unchecked { + _resultLength = 32 + bytes(tableName).length + bytes(abiEncodedFieldNames).length; + } + + bytes memory _result; + uint256 _resultPointer; + + /// @solidity memory-safe-assembly + assembly { + // allocate memory + _result := mload(0x40) + _resultPointer := add(_result, 0x20) + mstore(0x40, add(_resultPointer, and(add(_resultLength, 31), not(31)))) + mstore(_result, _resultLength) + + mstore(add(_resultPointer, 0), shl(0, _encodedLengths)) + + _resultPointer := add(_resultPointer, 32) + } + Memory.copy(Memory.dataPointer(bytes((tableName))), _resultPointer, bytes(tableName).length); + unchecked { + _resultPointer += bytes(tableName).length; + } + Memory.copy(Memory.dataPointer(bytes((abiEncodedFieldNames))), _resultPointer, bytes(abiEncodedFieldNames).length); + return _result; } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/store/src/tightcoder/DecodeSlice.ejs b/packages/store/src/tightcoder/DecodeSlice.ejs deleted file mode 100644 index dac751e1fc..0000000000 --- a/packages/store/src/tightcoder/DecodeSlice.ejs +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; - -/* Autogenerated via `pnpm codegen`. Do not edit the `.sol` file manually. */ - -import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; -import { TightCoder } from "./TightCoder.sol"; -import { Slice } from "../Slice.sol"; - -library DecodeSlice { - /************************************************************************ - * - * uint8 - uint256 - * - ************************************************************************/ -<% for (let i = 8; i <= 256; i += 8) { -%> - - function decodeArray_uint<%= i %>(Slice self) internal pure returns (uint<%= i %>[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, <%= i / 8 %>, false); - assembly { - output := genericArray - } - } -<% } -%> - - /************************************************************************ - * - * int8 - int256 - * - ************************************************************************/ -<% for (let i = 8; i <= 256; i += 8) { -%> - - function decodeArray_int<%= i %>(Slice self) internal pure returns (int<%= i %>[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, <%= i / 8 %>, false); - assembly { - output := genericArray - } - } -<% } -%> - - /************************************************************************ - * - * bytes1 - bytes32 - * - ************************************************************************/ -<% for (let i = 1; i <= 32; i += 1) { -%> - - function decodeArray_bytes<%= i %>(Slice self) internal pure returns (bytes<%= i %>[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, <%= i %>, true); - assembly { - output := genericArray - } - } -<% } -%> - - /************************************************************************ - * - * Other types - * - ************************************************************************/ - - function decodeArray_address(Slice self) internal pure returns (address[] memory output) { - // Note: internally address is right-aligned, like uint160 - bytes32[] memory genericArray = TightCoder.decode(self, 20, false); - assembly { - output := genericArray - } - } - - function decodeArray_bool(Slice self) internal pure returns (bool[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 1, false); - assembly { - output := genericArray - } - } - - function decodeArray_SchemaType(Slice self) internal pure returns (SchemaType[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 1, false); - assembly { - output := genericArray - } - } -} diff --git a/packages/store/src/tightcoder/DecodeSlice.sol b/packages/store/src/tightcoder/DecodeSlice.sol index ecee49c4fb..808f6ba148 100644 --- a/packages/store/src/tightcoder/DecodeSlice.sol +++ b/packages/store/src/tightcoder/DecodeSlice.sol @@ -1,728 +1,695 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -/* Autogenerated via `pnpm codegen`. Do not edit the `.sol` file manually. */ +/* Autogenerated file. Do not edit manually. */ -import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; import { TightCoder } from "./TightCoder.sol"; import { Slice } from "../Slice.sol"; library DecodeSlice { - /************************************************************************ - * - * uint8 - uint256 - * - ************************************************************************/ - - function decodeArray_uint8(Slice self) internal pure returns (uint8[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 1, false); - assembly { - output := genericArray - } - } - - function decodeArray_uint16(Slice self) internal pure returns (uint16[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 2, false); + function decodeArray_uint8(Slice _input) internal pure returns (uint8[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 1, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint24(Slice self) internal pure returns (uint24[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 3, false); + function decodeArray_uint16(Slice _input) internal pure returns (uint16[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 2, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint32(Slice self) internal pure returns (uint32[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 4, false); + function decodeArray_uint24(Slice _input) internal pure returns (uint24[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 3, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint40(Slice self) internal pure returns (uint40[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 5, false); + function decodeArray_uint32(Slice _input) internal pure returns (uint32[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 4, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint48(Slice self) internal pure returns (uint48[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 6, false); + function decodeArray_uint40(Slice _input) internal pure returns (uint40[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 5, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint56(Slice self) internal pure returns (uint56[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 7, false); + function decodeArray_uint48(Slice _input) internal pure returns (uint48[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 6, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint64(Slice self) internal pure returns (uint64[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 8, false); + function decodeArray_uint56(Slice _input) internal pure returns (uint56[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 7, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint72(Slice self) internal pure returns (uint72[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 9, false); + function decodeArray_uint64(Slice _input) internal pure returns (uint64[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 8, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint80(Slice self) internal pure returns (uint80[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 10, false); + function decodeArray_uint72(Slice _input) internal pure returns (uint72[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 9, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint88(Slice self) internal pure returns (uint88[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 11, false); + function decodeArray_uint80(Slice _input) internal pure returns (uint80[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 10, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint96(Slice self) internal pure returns (uint96[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 12, false); + function decodeArray_uint88(Slice _input) internal pure returns (uint88[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 11, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint104(Slice self) internal pure returns (uint104[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 13, false); + function decodeArray_uint96(Slice _input) internal pure returns (uint96[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 12, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint112(Slice self) internal pure returns (uint112[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 14, false); + function decodeArray_uint104(Slice _input) internal pure returns (uint104[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 13, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint120(Slice self) internal pure returns (uint120[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 15, false); + function decodeArray_uint112(Slice _input) internal pure returns (uint112[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 14, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint128(Slice self) internal pure returns (uint128[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 16, false); + function decodeArray_uint120(Slice _input) internal pure returns (uint120[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 15, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint136(Slice self) internal pure returns (uint136[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 17, false); + function decodeArray_uint128(Slice _input) internal pure returns (uint128[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 16, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint144(Slice self) internal pure returns (uint144[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 18, false); + function decodeArray_uint136(Slice _input) internal pure returns (uint136[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 17, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint152(Slice self) internal pure returns (uint152[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 19, false); + function decodeArray_uint144(Slice _input) internal pure returns (uint144[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 18, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint160(Slice self) internal pure returns (uint160[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 20, false); + function decodeArray_uint152(Slice _input) internal pure returns (uint152[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 19, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint168(Slice self) internal pure returns (uint168[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 21, false); + function decodeArray_uint160(Slice _input) internal pure returns (uint160[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 20, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint176(Slice self) internal pure returns (uint176[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 22, false); + function decodeArray_uint168(Slice _input) internal pure returns (uint168[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 21, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint184(Slice self) internal pure returns (uint184[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 23, false); + function decodeArray_uint176(Slice _input) internal pure returns (uint176[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 22, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint192(Slice self) internal pure returns (uint192[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 24, false); + function decodeArray_uint184(Slice _input) internal pure returns (uint184[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 23, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint200(Slice self) internal pure returns (uint200[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 25, false); + function decodeArray_uint192(Slice _input) internal pure returns (uint192[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 24, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint208(Slice self) internal pure returns (uint208[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 26, false); + function decodeArray_uint200(Slice _input) internal pure returns (uint200[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 25, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint216(Slice self) internal pure returns (uint216[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 27, false); + function decodeArray_uint208(Slice _input) internal pure returns (uint208[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 26, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint224(Slice self) internal pure returns (uint224[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 28, false); + function decodeArray_uint216(Slice _input) internal pure returns (uint216[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 27, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint232(Slice self) internal pure returns (uint232[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 29, false); + function decodeArray_uint224(Slice _input) internal pure returns (uint224[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 28, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint240(Slice self) internal pure returns (uint240[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 30, false); + function decodeArray_uint232(Slice _input) internal pure returns (uint232[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 29, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint248(Slice self) internal pure returns (uint248[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 31, false); + function decodeArray_uint240(Slice _input) internal pure returns (uint240[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 30, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_uint256(Slice self) internal pure returns (uint256[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 32, false); + function decodeArray_uint248(Slice _input) internal pure returns (uint248[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 31, false); assembly { - output := genericArray + _output := _genericArray } } - /************************************************************************ - * - * int8 - int256 - * - ************************************************************************/ - - function decodeArray_int8(Slice self) internal pure returns (int8[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 1, false); + function decodeArray_uint256(Slice _input) internal pure returns (uint256[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 32, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int16(Slice self) internal pure returns (int16[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 2, false); + function decodeArray_int8(Slice _input) internal pure returns (int8[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 1, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int24(Slice self) internal pure returns (int24[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 3, false); + function decodeArray_int16(Slice _input) internal pure returns (int16[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 2, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int32(Slice self) internal pure returns (int32[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 4, false); + function decodeArray_int24(Slice _input) internal pure returns (int24[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 3, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int40(Slice self) internal pure returns (int40[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 5, false); + function decodeArray_int32(Slice _input) internal pure returns (int32[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 4, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int48(Slice self) internal pure returns (int48[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 6, false); + function decodeArray_int40(Slice _input) internal pure returns (int40[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 5, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int56(Slice self) internal pure returns (int56[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 7, false); + function decodeArray_int48(Slice _input) internal pure returns (int48[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 6, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int64(Slice self) internal pure returns (int64[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 8, false); + function decodeArray_int56(Slice _input) internal pure returns (int56[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 7, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int72(Slice self) internal pure returns (int72[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 9, false); + function decodeArray_int64(Slice _input) internal pure returns (int64[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 8, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int80(Slice self) internal pure returns (int80[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 10, false); + function decodeArray_int72(Slice _input) internal pure returns (int72[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 9, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int88(Slice self) internal pure returns (int88[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 11, false); + function decodeArray_int80(Slice _input) internal pure returns (int80[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 10, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int96(Slice self) internal pure returns (int96[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 12, false); + function decodeArray_int88(Slice _input) internal pure returns (int88[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 11, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int104(Slice self) internal pure returns (int104[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 13, false); + function decodeArray_int96(Slice _input) internal pure returns (int96[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 12, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int112(Slice self) internal pure returns (int112[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 14, false); + function decodeArray_int104(Slice _input) internal pure returns (int104[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 13, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int120(Slice self) internal pure returns (int120[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 15, false); + function decodeArray_int112(Slice _input) internal pure returns (int112[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 14, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int128(Slice self) internal pure returns (int128[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 16, false); + function decodeArray_int120(Slice _input) internal pure returns (int120[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 15, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int136(Slice self) internal pure returns (int136[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 17, false); + function decodeArray_int128(Slice _input) internal pure returns (int128[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 16, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int144(Slice self) internal pure returns (int144[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 18, false); + function decodeArray_int136(Slice _input) internal pure returns (int136[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 17, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int152(Slice self) internal pure returns (int152[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 19, false); + function decodeArray_int144(Slice _input) internal pure returns (int144[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 18, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int160(Slice self) internal pure returns (int160[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 20, false); + function decodeArray_int152(Slice _input) internal pure returns (int152[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 19, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int168(Slice self) internal pure returns (int168[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 21, false); + function decodeArray_int160(Slice _input) internal pure returns (int160[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 20, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int176(Slice self) internal pure returns (int176[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 22, false); + function decodeArray_int168(Slice _input) internal pure returns (int168[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 21, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int184(Slice self) internal pure returns (int184[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 23, false); + function decodeArray_int176(Slice _input) internal pure returns (int176[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 22, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int192(Slice self) internal pure returns (int192[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 24, false); + function decodeArray_int184(Slice _input) internal pure returns (int184[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 23, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int200(Slice self) internal pure returns (int200[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 25, false); + function decodeArray_int192(Slice _input) internal pure returns (int192[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 24, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int208(Slice self) internal pure returns (int208[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 26, false); + function decodeArray_int200(Slice _input) internal pure returns (int200[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 25, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int216(Slice self) internal pure returns (int216[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 27, false); + function decodeArray_int208(Slice _input) internal pure returns (int208[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 26, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int224(Slice self) internal pure returns (int224[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 28, false); + function decodeArray_int216(Slice _input) internal pure returns (int216[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 27, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int232(Slice self) internal pure returns (int232[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 29, false); + function decodeArray_int224(Slice _input) internal pure returns (int224[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 28, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int240(Slice self) internal pure returns (int240[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 30, false); + function decodeArray_int232(Slice _input) internal pure returns (int232[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 29, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int248(Slice self) internal pure returns (int248[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 31, false); + function decodeArray_int240(Slice _input) internal pure returns (int240[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 30, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_int256(Slice self) internal pure returns (int256[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 32, false); + function decodeArray_int248(Slice _input) internal pure returns (int248[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 31, false); assembly { - output := genericArray + _output := _genericArray } } - /************************************************************************ - * - * bytes1 - bytes32 - * - ************************************************************************/ - - function decodeArray_bytes1(Slice self) internal pure returns (bytes1[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 1, true); + function decodeArray_int256(Slice _input) internal pure returns (int256[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 32, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes2(Slice self) internal pure returns (bytes2[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 2, true); + function decodeArray_bytes1(Slice _input) internal pure returns (bytes1[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 1, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes3(Slice self) internal pure returns (bytes3[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 3, true); + function decodeArray_bytes2(Slice _input) internal pure returns (bytes2[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 2, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes4(Slice self) internal pure returns (bytes4[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 4, true); + function decodeArray_bytes3(Slice _input) internal pure returns (bytes3[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 3, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes5(Slice self) internal pure returns (bytes5[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 5, true); + function decodeArray_bytes4(Slice _input) internal pure returns (bytes4[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 4, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes6(Slice self) internal pure returns (bytes6[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 6, true); + function decodeArray_bytes5(Slice _input) internal pure returns (bytes5[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 5, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes7(Slice self) internal pure returns (bytes7[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 7, true); + function decodeArray_bytes6(Slice _input) internal pure returns (bytes6[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 6, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes8(Slice self) internal pure returns (bytes8[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 8, true); + function decodeArray_bytes7(Slice _input) internal pure returns (bytes7[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 7, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes9(Slice self) internal pure returns (bytes9[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 9, true); + function decodeArray_bytes8(Slice _input) internal pure returns (bytes8[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 8, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes10(Slice self) internal pure returns (bytes10[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 10, true); + function decodeArray_bytes9(Slice _input) internal pure returns (bytes9[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 9, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes11(Slice self) internal pure returns (bytes11[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 11, true); + function decodeArray_bytes10(Slice _input) internal pure returns (bytes10[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 10, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes12(Slice self) internal pure returns (bytes12[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 12, true); + function decodeArray_bytes11(Slice _input) internal pure returns (bytes11[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 11, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes13(Slice self) internal pure returns (bytes13[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 13, true); + function decodeArray_bytes12(Slice _input) internal pure returns (bytes12[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 12, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes14(Slice self) internal pure returns (bytes14[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 14, true); + function decodeArray_bytes13(Slice _input) internal pure returns (bytes13[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 13, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes15(Slice self) internal pure returns (bytes15[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 15, true); + function decodeArray_bytes14(Slice _input) internal pure returns (bytes14[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 14, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes16(Slice self) internal pure returns (bytes16[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 16, true); + function decodeArray_bytes15(Slice _input) internal pure returns (bytes15[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 15, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes17(Slice self) internal pure returns (bytes17[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 17, true); + function decodeArray_bytes16(Slice _input) internal pure returns (bytes16[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 16, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes18(Slice self) internal pure returns (bytes18[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 18, true); + function decodeArray_bytes17(Slice _input) internal pure returns (bytes17[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 17, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes19(Slice self) internal pure returns (bytes19[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 19, true); + function decodeArray_bytes18(Slice _input) internal pure returns (bytes18[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 18, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes20(Slice self) internal pure returns (bytes20[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 20, true); + function decodeArray_bytes19(Slice _input) internal pure returns (bytes19[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 19, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes21(Slice self) internal pure returns (bytes21[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 21, true); + function decodeArray_bytes20(Slice _input) internal pure returns (bytes20[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 20, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes22(Slice self) internal pure returns (bytes22[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 22, true); + function decodeArray_bytes21(Slice _input) internal pure returns (bytes21[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 21, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes23(Slice self) internal pure returns (bytes23[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 23, true); + function decodeArray_bytes22(Slice _input) internal pure returns (bytes22[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 22, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes24(Slice self) internal pure returns (bytes24[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 24, true); + function decodeArray_bytes23(Slice _input) internal pure returns (bytes23[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 23, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes25(Slice self) internal pure returns (bytes25[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 25, true); + function decodeArray_bytes24(Slice _input) internal pure returns (bytes24[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 24, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes26(Slice self) internal pure returns (bytes26[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 26, true); + function decodeArray_bytes25(Slice _input) internal pure returns (bytes25[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 25, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes27(Slice self) internal pure returns (bytes27[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 27, true); + function decodeArray_bytes26(Slice _input) internal pure returns (bytes26[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 26, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes28(Slice self) internal pure returns (bytes28[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 28, true); + function decodeArray_bytes27(Slice _input) internal pure returns (bytes27[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 27, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes29(Slice self) internal pure returns (bytes29[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 29, true); + function decodeArray_bytes28(Slice _input) internal pure returns (bytes28[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 28, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes30(Slice self) internal pure returns (bytes30[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 30, true); + function decodeArray_bytes29(Slice _input) internal pure returns (bytes29[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 29, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes31(Slice self) internal pure returns (bytes31[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 31, true); + function decodeArray_bytes30(Slice _input) internal pure returns (bytes30[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 30, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bytes32(Slice self) internal pure returns (bytes32[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 32, true); + function decodeArray_bytes31(Slice _input) internal pure returns (bytes31[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 31, true); assembly { - output := genericArray + _output := _genericArray } } - /************************************************************************ - * - * Other types - * - ************************************************************************/ - - function decodeArray_address(Slice self) internal pure returns (address[] memory output) { - // Note: internally address is right-aligned, like uint160 - bytes32[] memory genericArray = TightCoder.decode(self, 20, false); + function decodeArray_bytes32(Slice _input) internal pure returns (bytes32[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 32, true); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_bool(Slice self) internal pure returns (bool[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 1, false); + function decodeArray_bool(Slice _input) internal pure returns (bool[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 1, false); assembly { - output := genericArray + _output := _genericArray } } - function decodeArray_SchemaType(Slice self) internal pure returns (SchemaType[] memory output) { - bytes32[] memory genericArray = TightCoder.decode(self, 1, false); + function decodeArray_address(Slice _input) internal pure returns (address[] memory _output) { + bytes32[] memory _genericArray = TightCoder.decode(_input, 20, false); assembly { - output := genericArray + _output := _genericArray } } } diff --git a/packages/store/src/tightcoder/EncodeArray.ejs b/packages/store/src/tightcoder/EncodeArray.ejs deleted file mode 100644 index 7a4e56d7c2..0000000000 --- a/packages/store/src/tightcoder/EncodeArray.ejs +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; - -/* Autogenerated via `pnpm codegen`. Do not edit the `.sol` file manually. */ - -import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; -import { TightCoder } from "./TightCoder.sol"; - -library EncodeArray { - /************************************************************************ - * - * uint8 - uint256 - * - ************************************************************************/ -<% for (let i = 8; i <= 256; i += 8) { -%> - - function encode(uint<%= i %>[] memory input) internal pure returns (bytes memory output) { - bytes32[] memory _genericArray; - assembly { - _genericArray := input - } - return TightCoder.encode(_genericArray, <%= i / 8 %>, false); - } -<% } -%> - - /************************************************************************ - * - * int8 - int256 - * - ************************************************************************/ -<% for (let i = 8; i <= 256; i += 8) { -%> - - function encode(int<%= i %>[] memory input) internal pure returns (bytes memory output) { - bytes32[] memory _genericArray; - assembly { - _genericArray := input - } - return TightCoder.encode(_genericArray, <%= i / 8 %>, false); - } -<% } -%> - - /************************************************************************ - * - * bytes1 - bytes32 - * - ************************************************************************/ -<% for (let i = 1; i <= 32; i += 1) { -%> - - function encode(bytes<%= i %>[] memory input) internal pure returns (bytes memory output) { - bytes32[] memory _genericArray; - assembly { - _genericArray := input - } - return TightCoder.encode(_genericArray, <%= i %>, true); - } -<% } -%> - - /************************************************************************ - * - * Other types - * - ************************************************************************/ - - function encode(address[] memory input) internal pure returns (bytes memory output) { - bytes32[] memory _genericArray; - assembly { - _genericArray := input - } - return TightCoder.encode(_genericArray, 20, false); - } - - function encode(bool[] memory input) internal pure returns (bytes memory output) { - bytes32[] memory _genericArray; - assembly { - _genericArray := input - } - return TightCoder.encode(_genericArray, 1, false); - } - - function encode(SchemaType[] memory input) internal pure returns (bytes memory output) { - bytes32[] memory _genericArray; - assembly { - _genericArray := input - } - return TightCoder.encode(_genericArray, 1, false); - } - - /** - * Converts a `bytes` memory array to a single `bytes` memory value. - * TODO: optimize gas cost - */ - function encode(bytes[] memory input) internal pure returns (bytes memory output) { - output = new bytes(0); - for (uint256 i; i < input.length; i++) { - output = bytes.concat(output, input[i]); - } - } -} diff --git a/packages/store/src/tightcoder/EncodeArray.sol b/packages/store/src/tightcoder/EncodeArray.sol index dd2dc875ad..1d6b543a95 100644 --- a/packages/store/src/tightcoder/EncodeArray.sol +++ b/packages/store/src/tightcoder/EncodeArray.sol @@ -1,836 +1,1674 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -/* Autogenerated via `pnpm codegen`. Do not edit the `.sol` file manually. */ +/* Autogenerated file. Do not edit manually. */ -import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; import { TightCoder } from "./TightCoder.sol"; library EncodeArray { - /************************************************************************ - * - * uint8 - uint256 - * - ************************************************************************/ - - function encode(uint8[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint8[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 1, false); + TightCoder.encodeToLocation(_genericArray, _toPointer, 1, 248); } - function encode(uint16[] memory input) internal pure returns (bytes memory output) { - bytes32[] memory _genericArray; + function encode(uint8[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 1); + uint256 _toPointer; assembly { - _genericArray := input + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 2, false); + encodeToLocation(_input, _toPointer); } - function encode(uint24[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint16[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 2, 240); + } + + function encode(uint16[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 2); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 3, false); + encodeToLocation(_input, _toPointer); } - function encode(uint32[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint24[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 4, false); + TightCoder.encodeToLocation(_genericArray, _toPointer, 3, 232); } - function encode(uint40[] memory input) internal pure returns (bytes memory output) { + function encode(uint24[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 3); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(uint32[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 4, 224); + } + + function encode(uint32[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 4); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 5, false); + encodeToLocation(_input, _toPointer); } - function encode(uint48[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint40[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 5, 216); + } + + function encode(uint40[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 5); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 6, false); + encodeToLocation(_input, _toPointer); } - function encode(uint56[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint48[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 7, false); + TightCoder.encodeToLocation(_genericArray, _toPointer, 6, 208); } - function encode(uint64[] memory input) internal pure returns (bytes memory output) { + function encode(uint48[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 6); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(uint56[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 7, 200); + } + + function encode(uint56[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 7); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 8, false); + encodeToLocation(_input, _toPointer); } - function encode(uint72[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint64[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 8, 192); + } + + function encode(uint64[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 8); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 9, false); + encodeToLocation(_input, _toPointer); } - function encode(uint80[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint72[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 10, false); + TightCoder.encodeToLocation(_genericArray, _toPointer, 9, 184); } - function encode(uint88[] memory input) internal pure returns (bytes memory output) { + function encode(uint72[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 9); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(uint80[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 10, 176); + } + + function encode(uint80[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 10); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 11, false); + encodeToLocation(_input, _toPointer); } - function encode(uint96[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint88[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 11, 168); + } + + function encode(uint88[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 11); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 12, false); + encodeToLocation(_input, _toPointer); } - function encode(uint104[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint96[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 13, false); + TightCoder.encodeToLocation(_genericArray, _toPointer, 12, 160); } - function encode(uint112[] memory input) internal pure returns (bytes memory output) { + function encode(uint96[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 12); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(uint104[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 13, 152); + } + + function encode(uint104[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 13); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 14, false); + encodeToLocation(_input, _toPointer); } - function encode(uint120[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint112[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 14, 144); + } + + function encode(uint112[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 14); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 15, false); + encodeToLocation(_input, _toPointer); } - function encode(uint128[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint120[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 16, false); + TightCoder.encodeToLocation(_genericArray, _toPointer, 15, 136); } - function encode(uint136[] memory input) internal pure returns (bytes memory output) { + function encode(uint120[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 15); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(uint128[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 16, 128); + } + + function encode(uint128[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 16); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 17, false); + encodeToLocation(_input, _toPointer); } - function encode(uint144[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint136[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 17, 120); + } + + function encode(uint136[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 17); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 18, false); + encodeToLocation(_input, _toPointer); } - function encode(uint152[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint144[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 19, false); + TightCoder.encodeToLocation(_genericArray, _toPointer, 18, 112); } - function encode(uint160[] memory input) internal pure returns (bytes memory output) { + function encode(uint144[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 18); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(uint152[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 19, 104); + } + + function encode(uint152[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 19); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 20, false); + encodeToLocation(_input, _toPointer); } - function encode(uint168[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint160[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 20, 96); + } + + function encode(uint160[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 20); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 21, false); + encodeToLocation(_input, _toPointer); } - function encode(uint176[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint168[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 22, false); + TightCoder.encodeToLocation(_genericArray, _toPointer, 21, 88); } - function encode(uint184[] memory input) internal pure returns (bytes memory output) { + function encode(uint168[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 21); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(uint176[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 22, 80); + } + + function encode(uint176[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 22); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 23, false); + encodeToLocation(_input, _toPointer); } - function encode(uint192[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint184[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 23, 72); + } + + function encode(uint184[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 23); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 24, false); + encodeToLocation(_input, _toPointer); } - function encode(uint200[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint192[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 25, false); + TightCoder.encodeToLocation(_genericArray, _toPointer, 24, 64); } - function encode(uint208[] memory input) internal pure returns (bytes memory output) { + function encode(uint192[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 24); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(uint200[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 25, 56); + } + + function encode(uint200[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 25); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 26, false); + encodeToLocation(_input, _toPointer); } - function encode(uint216[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint208[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 26, 48); + } + + function encode(uint208[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 26); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 27, false); + encodeToLocation(_input, _toPointer); } - function encode(uint224[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint216[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 28, false); + TightCoder.encodeToLocation(_genericArray, _toPointer, 27, 40); } - function encode(uint232[] memory input) internal pure returns (bytes memory output) { + function encode(uint216[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 27); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(uint224[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 28, 32); + } + + function encode(uint224[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 28); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 29, false); + encodeToLocation(_input, _toPointer); } - function encode(uint240[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint232[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 29, 24); + } + + function encode(uint232[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 29); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 30, false); + encodeToLocation(_input, _toPointer); } - function encode(uint248[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint240[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 31, false); + TightCoder.encodeToLocation(_genericArray, _toPointer, 30, 16); } - function encode(uint256[] memory input) internal pure returns (bytes memory output) { + function encode(uint240[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 30); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(uint248[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 32, false); + TightCoder.encodeToLocation(_genericArray, _toPointer, 31, 8); } - /************************************************************************ - * - * int8 - int256 - * - ************************************************************************/ + function encode(uint248[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 31); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } - function encode(int8[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(uint256[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 32, 0); + } + + function encode(uint256[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 32); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 1, false); + encodeToLocation(_input, _toPointer); } - function encode(int16[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int8[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 1, 248); + } + + function encode(int8[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 1); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 2, false); + encodeToLocation(_input, _toPointer); } - function encode(int24[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int16[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 2, 240); + } + + function encode(int16[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 2); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 3, false); + encodeToLocation(_input, _toPointer); } - function encode(int32[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int24[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 3, 232); + } + + function encode(int24[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 3); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 4, false); + encodeToLocation(_input, _toPointer); } - function encode(int40[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int32[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 4, 224); + } + + function encode(int32[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 4); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 5, false); + encodeToLocation(_input, _toPointer); } - function encode(int48[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int40[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 5, 216); + } + + function encode(int40[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 5); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 6, false); + encodeToLocation(_input, _toPointer); } - function encode(int56[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int48[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 6, 208); + } + + function encode(int48[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 6); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 7, false); + encodeToLocation(_input, _toPointer); } - function encode(int64[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int56[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 7, 200); + } + + function encode(int56[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 7); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 8, false); + encodeToLocation(_input, _toPointer); } - function encode(int72[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int64[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 8, 192); + } + + function encode(int64[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 8); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 9, false); + encodeToLocation(_input, _toPointer); } - function encode(int80[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int72[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 9, 184); + } + + function encode(int72[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 9); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 10, false); + encodeToLocation(_input, _toPointer); } - function encode(int88[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int80[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 10, 176); + } + + function encode(int80[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 10); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 11, false); + encodeToLocation(_input, _toPointer); } - function encode(int96[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int88[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 11, 168); + } + + function encode(int88[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 11); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 12, false); + encodeToLocation(_input, _toPointer); } - function encode(int104[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int96[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 12, 160); + } + + function encode(int96[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 12); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 13, false); + encodeToLocation(_input, _toPointer); } - function encode(int112[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int104[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 13, 152); + } + + function encode(int104[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 13); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 14, false); + encodeToLocation(_input, _toPointer); } - function encode(int120[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int112[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 14, 144); + } + + function encode(int112[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 14); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 15, false); + encodeToLocation(_input, _toPointer); } - function encode(int128[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int120[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 15, 136); + } + + function encode(int120[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 15); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 16, false); + encodeToLocation(_input, _toPointer); } - function encode(int136[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int128[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 16, 128); + } + + function encode(int128[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 16); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 17, false); + encodeToLocation(_input, _toPointer); } - function encode(int144[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int136[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 17, 120); + } + + function encode(int136[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 17); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 18, false); + encodeToLocation(_input, _toPointer); } - function encode(int152[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int144[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 18, 112); + } + + function encode(int144[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 18); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 19, false); + encodeToLocation(_input, _toPointer); } - function encode(int160[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int152[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 19, 104); + } + + function encode(int152[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 19); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 20, false); + encodeToLocation(_input, _toPointer); } - function encode(int168[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int160[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 20, 96); + } + + function encode(int160[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 20); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 21, false); + encodeToLocation(_input, _toPointer); } - function encode(int176[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int168[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 21, 88); + } + + function encode(int168[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 21); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 22, false); + encodeToLocation(_input, _toPointer); } - function encode(int184[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int176[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 22, 80); + } + + function encode(int176[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 22); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 23, false); + encodeToLocation(_input, _toPointer); } - function encode(int192[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int184[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 23, 72); + } + + function encode(int184[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 23); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 24, false); + encodeToLocation(_input, _toPointer); } - function encode(int200[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int192[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 24, 64); + } + + function encode(int192[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 24); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 25, false); + encodeToLocation(_input, _toPointer); } - function encode(int208[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int200[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 25, 56); + } + + function encode(int200[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 25); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 26, false); + encodeToLocation(_input, _toPointer); } - function encode(int216[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int208[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 26, 48); + } + + function encode(int208[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 26); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 27, false); + encodeToLocation(_input, _toPointer); } - function encode(int224[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int216[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 27, 40); + } + + function encode(int216[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 27); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 28, false); + encodeToLocation(_input, _toPointer); } - function encode(int232[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int224[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 28, 32); + } + + function encode(int224[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 28); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 29, false); + encodeToLocation(_input, _toPointer); } - function encode(int240[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int232[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 29, 24); + } + + function encode(int232[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 29); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 30, false); + encodeToLocation(_input, _toPointer); } - function encode(int248[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int240[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 30, 16); + } + + function encode(int240[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 30); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 31, false); + encodeToLocation(_input, _toPointer); } - function encode(int256[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int248[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 32, false); + TightCoder.encodeToLocation(_genericArray, _toPointer, 31, 8); } - /************************************************************************ - * - * bytes1 - bytes32 - * - ************************************************************************/ + function encode(int248[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 31); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } - function encode(bytes1[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(int256[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 32, 0); + } + + function encode(int256[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 32); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 1, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes2[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes1[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 2, true); + TightCoder.encodeToLocation(_genericArray, _toPointer, 1, 0); } - function encode(bytes3[] memory input) internal pure returns (bytes memory output) { + function encode(bytes1[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 1); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(bytes2[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 2, 0); + } + + function encode(bytes2[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 2); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 3, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes4[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes3[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 3, 0); + } + + function encode(bytes3[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 3); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 4, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes5[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes4[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 5, true); + TightCoder.encodeToLocation(_genericArray, _toPointer, 4, 0); } - function encode(bytes6[] memory input) internal pure returns (bytes memory output) { + function encode(bytes4[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 4); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(bytes5[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 5, 0); + } + + function encode(bytes5[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 5); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 6, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes7[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes6[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 6, 0); + } + + function encode(bytes6[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 6); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 7, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes8[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes7[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 8, true); + TightCoder.encodeToLocation(_genericArray, _toPointer, 7, 0); } - function encode(bytes9[] memory input) internal pure returns (bytes memory output) { + function encode(bytes7[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 7); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(bytes8[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 8, 0); + } + + function encode(bytes8[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 8); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 9, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes10[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes9[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 9, 0); + } + + function encode(bytes9[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 9); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 10, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes11[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes10[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 11, true); + TightCoder.encodeToLocation(_genericArray, _toPointer, 10, 0); } - function encode(bytes12[] memory input) internal pure returns (bytes memory output) { + function encode(bytes10[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 10); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(bytes11[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 11, 0); + } + + function encode(bytes11[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 11); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 12, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes13[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes12[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 12, 0); + } + + function encode(bytes12[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 12); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 13, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes14[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes13[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 14, true); + TightCoder.encodeToLocation(_genericArray, _toPointer, 13, 0); } - function encode(bytes15[] memory input) internal pure returns (bytes memory output) { + function encode(bytes13[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 13); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(bytes14[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 14, 0); + } + + function encode(bytes14[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 14); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 15, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes16[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes15[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 15, 0); + } + + function encode(bytes15[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 15); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 16, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes17[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes16[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 17, true); + TightCoder.encodeToLocation(_genericArray, _toPointer, 16, 0); } - function encode(bytes18[] memory input) internal pure returns (bytes memory output) { + function encode(bytes16[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 16); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(bytes17[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 17, 0); + } + + function encode(bytes17[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 17); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 18, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes19[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes18[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 18, 0); + } + + function encode(bytes18[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 18); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 19, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes20[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes19[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 20, true); + TightCoder.encodeToLocation(_genericArray, _toPointer, 19, 0); } - function encode(bytes21[] memory input) internal pure returns (bytes memory output) { + function encode(bytes19[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 19); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(bytes20[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 20, 0); + } + + function encode(bytes20[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 20); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 21, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes22[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes21[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 21, 0); + } + + function encode(bytes21[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 21); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 22, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes23[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes22[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 23, true); + TightCoder.encodeToLocation(_genericArray, _toPointer, 22, 0); } - function encode(bytes24[] memory input) internal pure returns (bytes memory output) { + function encode(bytes22[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 22); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(bytes23[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 23, 0); + } + + function encode(bytes23[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 23); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 24, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes25[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes24[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 24, 0); + } + + function encode(bytes24[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 24); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 25, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes26[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes25[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 26, true); + TightCoder.encodeToLocation(_genericArray, _toPointer, 25, 0); } - function encode(bytes27[] memory input) internal pure returns (bytes memory output) { + function encode(bytes25[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 25); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(bytes26[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 26, 0); + } + + function encode(bytes26[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 26); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 27, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes28[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes27[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 27, 0); + } + + function encode(bytes27[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 27); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 28, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes29[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes28[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 29, true); + TightCoder.encodeToLocation(_genericArray, _toPointer, 28, 0); } - function encode(bytes30[] memory input) internal pure returns (bytes memory output) { + function encode(bytes28[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 28); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + + function encodeToLocation(bytes29[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 29, 0); + } + + function encode(bytes29[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 29); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 30, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes31[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes30[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 30, 0); + } + + function encode(bytes30[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 30); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 31, true); + encodeToLocation(_input, _toPointer); } - function encode(bytes32[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes31[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 32, true); + TightCoder.encodeToLocation(_genericArray, _toPointer, 31, 0); } - /************************************************************************ - * - * Other types - * - ************************************************************************/ + function encode(bytes31[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 31); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } - function encode(address[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bytes32[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 32, 0); + } + + function encode(bytes32[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 32); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 20, false); + encodeToLocation(_input, _toPointer); } - function encode(bool[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(bool[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input + } + TightCoder.encodeToLocation(_genericArray, _toPointer, 1, 248); + } + + function encode(bool[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 1); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } - return TightCoder.encode(_genericArray, 1, false); + encodeToLocation(_input, _toPointer); } - function encode(SchemaType[] memory input) internal pure returns (bytes memory output) { + function encodeToLocation(address[] memory _input, uint256 _toPointer) internal pure { bytes32[] memory _genericArray; assembly { - _genericArray := input + _genericArray := _input } - return TightCoder.encode(_genericArray, 1, false); + TightCoder.encodeToLocation(_genericArray, _toPointer, 20, 96); } - /** - * Converts a `bytes` memory array to a single `bytes` memory value. - * TODO: optimize gas cost - */ - function encode(bytes[] memory input) internal pure returns (bytes memory output) { - output = new bytes(0); - for (uint256 i; i < input.length; i++) { - output = bytes.concat(output, input[i]); + function encode(address[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * 20); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) } + encodeToLocation(_input, _toPointer); } } diff --git a/packages/store/src/tightcoder/TightCoder.sol b/packages/store/src/tightcoder/TightCoder.sol index 200f9e4290..558fbcc2c6 100644 --- a/packages/store/src/tightcoder/TightCoder.sol +++ b/packages/store/src/tightcoder/TightCoder.sol @@ -1,65 +1,36 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; -import { Slice, SliceLib } from "../Slice.sol"; +import { Slice } from "../Slice.sol"; library TightCoder { /** * @dev Copies the array to the location of `packedSlice`, * tightly packing it using the given size per element (in bytes) - * - * TODO this function is currently not used externally and will be changed in the future - * (see https://github.com/latticexyz/mud/issues/444) */ - function _encodeToLocation( + function encodeToLocation( bytes32[] memory array, - Slice packedSlice, + uint256 toPointer, uint256 elementSize, - bool leftAligned - ) private pure { + uint256 shiftLeftBits + ) internal pure { uint256 arrayLength = array.length; - uint256 packedPointer = packedSlice.pointer(); - uint256 shiftLeft = leftAligned ? 0 : 256 - elementSize * 8; - - // TODO temporary check to catch bugs, either remove it or use a custom error - // (see https://github.com/latticexyz/mud/issues/444) - uint256 packedLength = arrayLength * elementSize; - if (packedLength > packedSlice.length()) { - revert("packFromArray: insufficient allocated packedSlice length"); - } - /// @solidity memory-safe-assembly assembly { for { let i := 0 let arrayCursor := add(array, 0x20) // skip array length - let packedCursor := packedPointer } lt(i, arrayLength) { // Loop until we reach the end of the array i := add(i, 1) arrayCursor := add(arrayCursor, 0x20) // increment array pointer by one word - packedCursor := add(packedCursor, elementSize) // increment packed pointer by one element size + toPointer := add(toPointer, elementSize) // increment packed pointer by one element size } { - mstore(packedCursor, shl(shiftLeft, mload(arrayCursor))) // pack one array element + mstore(toPointer, shl(shiftLeftBits, mload(arrayCursor))) // pack one array element } } } - /** - * @dev Copies the array to a new bytes array, - * tightly packing it using the given size per element (in bytes) - */ - function encode( - bytes32[] memory array, - uint256 elementSize, - bool leftAligned - ) internal pure returns (bytes memory data) { - uint256 packedLength = array.length * elementSize; - data = new bytes(packedLength); - _encodeToLocation(array, SliceLib.fromBytes(data), elementSize, leftAligned); - } - /** * @dev Unpacks the slice to a new memory location * and lays it out like a memory array with the given size per element (in bytes) diff --git a/packages/store/test/Gas.t.sol b/packages/store/test/Gas.t.sol index 156ced0905..4caa605c23 100644 --- a/packages/store/test/Gas.t.sol +++ b/packages/store/test/Gas.t.sol @@ -5,14 +5,7 @@ import { Test, console } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; import { Bytes } from "../src/Bytes.sol"; import { SliceLib } from "../src/Slice.sol"; -import { EncodeArray } from "../src/tightcoder/EncodeArray.sol"; - -struct Mixed { - uint32 u32; - uint128 u128; - uint32[] a32; - string s; -} +import { Mixed, MixedData } from "../src/codegen/Tables.sol"; contract SomeContract { function doSomethingWithBytes(bytes memory data) public {} @@ -22,7 +15,7 @@ contract GasTest is Test, GasReporter { SomeContract someContract = new SomeContract(); function testCompareAbiEncodeVsCustom() public { - Mixed memory mixed = Mixed({ u32: 1, u128: 2, a32: new uint32[](3), s: "hello" }); + MixedData memory mixed = MixedData({ u32: 1, u128: 2, a32: new uint32[](3), s: "hello" }); mixed.a32[0] = 1; mixed.a32[1] = 2; mixed.a32[2] = 3; @@ -32,15 +25,15 @@ contract GasTest is Test, GasReporter { endGasReport(); startGasReport("abi decode"); - Mixed memory abiDecoded = abi.decode(abiEncoded, (Mixed)); + MixedData memory abiDecoded = abi.decode(abiEncoded, (MixedData)); endGasReport(); startGasReport("custom encode"); - bytes memory customEncoded = customEncode(mixed); + bytes memory customEncoded = Mixed.encode(mixed.u32, mixed.u128, mixed.a32, mixed.s); endGasReport(); startGasReport("custom decode"); - Mixed memory customDecoded = customDecode(customEncoded); + MixedData memory customDecoded = Mixed.decode(customEncoded); endGasReport(); console.log("Length comparison: abi encode %s, custom %s", abiEncoded.length, customEncoded.length); @@ -53,20 +46,6 @@ contract GasTest is Test, GasReporter { someContract.doSomethingWithBytes(customEncoded); endGasReport(); - assertEq(keccak256(abi.encode(abiDecoded)), keccak256(abi.encode(customDecoded))); + assertEq(abi.encode(abiDecoded), abi.encode(customDecoded)); } } - -function customEncode(Mixed memory mixed) pure returns (bytes memory) { - return abi.encodePacked(mixed.u32, mixed.u128, EncodeArray.encode(mixed.a32), mixed.s); -} - -function customDecode(bytes memory input) view returns (Mixed memory) { - return - Mixed({ - u32: uint32(Bytes.slice4(input, 0)), - u128: uint128(Bytes.slice16(input, 4)), - a32: SliceLib.getSubslice(input, 20, 20 + 3 * 4).decodeArray_uint32(), - s: string(SliceLib.getSubslice(input, 20 + 3 * 4, input.length).toBytes()) - }); -} diff --git a/packages/store/test/tightcoder/EncodeArray.t.sol b/packages/store/test/tightcoder/EncodeArray.t.sol index 989cfc0038..2dcd24d9e1 100644 --- a/packages/store/test/tightcoder/EncodeArray.t.sol +++ b/packages/store/test/tightcoder/EncodeArray.t.sol @@ -7,24 +7,6 @@ import { Bytes } from "../../src/Bytes.sol"; import { EncodeArray } from "../../src/tightcoder/EncodeArray.sol"; contract EncodeArrayTest is Test, GasReporter { - function testEncodeBytesArray() public { - bytes[] memory input = new bytes[](2); - input[0] = new bytes(32); - input[0][0] = 0x01; - input[0][31] = 0x02; - input[1] = new bytes(32); - input[1][0] = 0x03; - input[1][31] = 0x04; - - startGasReport("encode packed bytes[]"); - bytes memory output = EncodeArray.encode(input); - endGasReport(); - - assertEq(output.length, 64); - assertEq(uint256(Bytes.toBytes32(output, 0)), 0x0100000000000000000000000000000000000000000000000000000000000002); - assertEq(uint256(Bytes.toBytes32(output, 32)), 0x0300000000000000000000000000000000000000000000000000000000000004); - } - function testEncodeUint8Array() public { uint8 val0 = 0x01; uint8 val1 = 0x02; diff --git a/packages/store/test/tightcoder/TightCoder.t.sol b/packages/store/test/tightcoder/TightCoder.t.sol index 0f1e183769..b664f80920 100644 --- a/packages/store/test/tightcoder/TightCoder.t.sol +++ b/packages/store/test/tightcoder/TightCoder.t.sol @@ -3,7 +3,6 @@ pragma solidity >=0.8.0; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; -import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; import { SliceLib } from "../../src/Slice.sol"; import { EncodeArray } from "../../src/tightcoder/EncodeArray.sol"; @@ -36,7 +35,7 @@ contract TightCoderTest is Test, GasReporter { assertEq(packed.length, 48); - startGasReport("decode packed uint32[]"); + startGasReport("decode packed bytes24[]"); bytes24[] memory output = SliceLib.fromBytes(packed).decodeArray_bytes24(); endGasReport(); @@ -44,56 +43,4 @@ contract TightCoderTest is Test, GasReporter { assertEq(output[0], input[0]); assertEq(output[1], input[1]); } - - /************************************************************************ - * - * Other types - * - ************************************************************************/ - - function testEncodeDecodeArray__address(address val0, address val1, address val2) public { - address[] memory input = new address[](3); - input[0] = val0; - input[1] = val1; - input[2] = val2; - - bytes memory output = EncodeArray.encode(input); - - assertEq(output, abi.encodePacked(val0, val1, val2)); - } - - function testEncodeDecodeArray__bool(bool val0, bool val1, bool val2) public { - bool[] memory input = new bool[](3); - input[0] = val0; - input[1] = val1; - input[2] = val2; - - bytes memory encoded = EncodeArray.encode(input); - assertEq(encoded, abi.encodePacked(val0, val1, val2)); - - bool[] memory decoded = SliceLib.fromBytes(encoded).decodeArray_bool(); - assertEq(decoded.length, 3); - assertEq(decoded[0], val0); - assertEq(decoded[1], val1); - assertEq(decoded[2], val2); - } - - function testEncodeDecodeArray__SchemaType() public { - SchemaType val0 = SchemaType.UINT8; - SchemaType val1 = SchemaType.INT128; - SchemaType val2 = SchemaType.STRING; - SchemaType[] memory input = new SchemaType[](3); - input[0] = val0; - input[1] = val1; - input[2] = val2; - - bytes memory encoded = EncodeArray.encode(input); - assertEq(encoded, abi.encodePacked(val0, val1, val2)); - - SchemaType[] memory decoded = SliceLib.fromBytes(encoded).decodeArray_SchemaType(); - assertEq(decoded.length, 3); - assertEq(uint8(decoded[0]), uint8(val0)); - assertEq(uint8(decoded[1]), uint8(val1)); - assertEq(uint8(decoded[2]), uint8(val2)); - } } diff --git a/packages/store/test/tightcoder/TightCoderAuto.t.ejs b/packages/store/test/tightcoder/TightCoderAuto.t.ejs deleted file mode 100644 index 621557fec1..0000000000 --- a/packages/store/test/tightcoder/TightCoderAuto.t.ejs +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; - -/* Autogenerated via `pnpm codegen`. Do not edit the `.sol` file manually. */ - -import "forge-std/Test.sol"; -import { Bytes } from "../../src/Bytes.sol"; -import { EncodeArray } from "../../src/tightcoder/EncodeArray.sol"; -import { SliceLib } from "../../src/Slice.sol"; - -contract TightCoderAutoTest is Test { -<% for (const prefix of ["uint", "int", "bytes"]) { -%> -<% const [start, end, step] = prefix === "bytes" ? [1, 32, 1] : [8, 256, 8]; -%> -<%= prefix === "uint" ? "" : "\n" -%> - /************************************************************************ - * - * <%= prefix %><%= start %> - <%= prefix %><%= end %> - * - ************************************************************************/ -<% for (let i = start; i <= end; i += step) { -%> -<% const T = `${prefix}${i}`; -%> - - function testEncodeDecodeArray_<%= `${prefix}${i}` %>( - <%= T %> val0, - <%= T %> val1, - <%= T %> val2 - ) public { - <%= T %>[] memory input = new <%= T %>[](3); - input[0] = val0; - input[1] = val1; - input[2] = val2; - - bytes memory encoded = EncodeArray.encode(input); - assertEq(encoded, abi.encodePacked(val0, val1, val2)); - - <%= T %>[] memory decoded = SliceLib.fromBytes(encoded).decodeArray_<%= T %>(); - assertEq(decoded.length, 3); - assertEq(decoded[0], val0); - assertEq(decoded[1], val1); - assertEq(decoded[2], val2); - } -<% } -%> -<% } -%> -} diff --git a/packages/store/test/tightcoder/TightCoderAuto.t.sol b/packages/store/test/tightcoder/TightCoderAuto.t.sol index 1543e1e366..0022bc9634 100644 --- a/packages/store/test/tightcoder/TightCoderAuto.t.sol +++ b/packages/store/test/tightcoder/TightCoderAuto.t.sol @@ -1,20 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -/* Autogenerated via `pnpm codegen`. Do not edit the `.sol` file manually. */ +/* Autogenerated file. Do not edit manually. */ -import "forge-std/Test.sol"; -import { Bytes } from "../../src/Bytes.sol"; +import { Test } from "forge-std/Test.sol"; import { EncodeArray } from "../../src/tightcoder/EncodeArray.sol"; import { SliceLib } from "../../src/Slice.sol"; contract TightCoderAutoTest is Test { - /************************************************************************ - * - * uint8 - uint256 - * - ************************************************************************/ - function testEncodeDecodeArray_uint8(uint8 val0, uint8 val1, uint8 val2) public { uint8[] memory input = new uint8[](3); input[0] = val0; @@ -527,12 +520,6 @@ contract TightCoderAutoTest is Test { assertEq(decoded[2], val2); } - /************************************************************************ - * - * int8 - int256 - * - ************************************************************************/ - function testEncodeDecodeArray_int8(int8 val0, int8 val1, int8 val2) public { int8[] memory input = new int8[](3); input[0] = val0; @@ -1045,12 +1032,6 @@ contract TightCoderAutoTest is Test { assertEq(decoded[2], val2); } - /************************************************************************ - * - * bytes1 - bytes32 - * - ************************************************************************/ - function testEncodeDecodeArray_bytes1(bytes1 val0, bytes1 val1, bytes1 val2) public { bytes1[] memory input = new bytes1[](3); input[0] = val0; @@ -1562,4 +1543,36 @@ contract TightCoderAutoTest is Test { assertEq(decoded[1], val1); assertEq(decoded[2], val2); } + + function testEncodeDecodeArray_bool(bool val0, bool val1, bool val2) public { + bool[] memory input = new bool[](3); + input[0] = val0; + input[1] = val1; + input[2] = val2; + + bytes memory encoded = EncodeArray.encode(input); + assertEq(encoded, abi.encodePacked(val0, val1, val2)); + + bool[] memory decoded = SliceLib.fromBytes(encoded).decodeArray_bool(); + assertEq(decoded.length, 3); + assertEq(decoded[0], val0); + assertEq(decoded[1], val1); + assertEq(decoded[2], val2); + } + + function testEncodeDecodeArray_address(address val0, address val1, address val2) public { + address[] memory input = new address[](3); + input[0] = val0; + input[1] = val1; + input[2] = val2; + + bytes memory encoded = EncodeArray.encode(input); + assertEq(encoded, abi.encodePacked(val0, val1, val2)); + + address[] memory decoded = SliceLib.fromBytes(encoded).decodeArray_address(); + assertEq(decoded.length, 3); + assertEq(decoded[0], val0); + assertEq(decoded[1], val1); + assertEq(decoded[2], val2); + } } diff --git a/packages/store/ts/codegen/field.ts b/packages/store/ts/codegen/field.ts index 51952e8a9f..ca076f54ac 100644 --- a/packages/store/ts/codegen/field.ts +++ b/packages/store/ts/codegen/field.ts @@ -42,7 +42,7 @@ export function renderFieldMethods(options: RenderTableOptions) { _typedFieldName, ])}) internal { ${_keyTupleDefinition} - ${_store}.setField(_tableId, _keyTuple, ${schemaIndex}, ${renderEncodeField(field)}); + ${_store}.setField(_tableId, _keyTuple, ${schemaIndex}, ${renderEncodeFieldSingle(field)}); } ` ); @@ -148,18 +148,6 @@ export function renderFieldMethods(options: RenderTableOptions) { return result; } -export function renderEncodeField(field: RenderField) { - let func; - if (field.arrayElement) { - func = "EncodeArray.encode"; - } else if (field.isDynamic) { - func = "bytes"; - } else { - func = "abi.encodePacked"; - } - return `${func}(${field.typeUnwrap}(${field.name}))`; -} - export function renderDecodeValueType(field: RenderType, offset: number) { const { staticByteLength, internalTypeId } = field; @@ -190,7 +178,7 @@ function fieldPortionData(field: RenderField) { return { typeWithLocation: field.arrayElement.typeWithLocation, name: "_element", - encoded: renderEncodeField(elementFieldData), + encoded: renderEncodeFieldSingle(elementFieldData), decoded: renderDecodeFieldSingle(elementFieldData), title: "an element", elementLength: field.arrayElement.staticByteLength, @@ -201,7 +189,7 @@ function fieldPortionData(field: RenderField) { return { typeWithLocation: `${field.typeId} memory`, name, - encoded: renderEncodeField(elementFieldData), + encoded: renderEncodeFieldSingle(elementFieldData), decoded: renderDecodeFieldSingle(elementFieldData), title: "a slice", elementLength: 1, @@ -209,6 +197,18 @@ function fieldPortionData(field: RenderField) { } } +function renderEncodeFieldSingle(field: RenderField) { + let func; + if (field.arrayElement) { + func = "EncodeArray.encode"; + } else if (field.isDynamic) { + func = "bytes"; + } else { + func = "abi.encodePacked"; + } + return `${func}(${field.typeUnwrap}(${field.name}))`; +} + function renderDecodeFieldSingle(field: RenderField) { const { isDynamic, arrayElement } = field; if (arrayElement) { diff --git a/packages/store/ts/codegen/index.ts b/packages/store/ts/codegen/index.ts index 3915c4f1db..d5dfbf0f96 100644 --- a/packages/store/ts/codegen/index.ts +++ b/packages/store/ts/codegen/index.ts @@ -4,5 +4,6 @@ export * from "./renderTable"; export * from "./renderTypesFromConfig"; export * from "./tablegen"; export * from "./tableOptions"; +export * from "./tightcoder"; export * from "./types"; export * from "./userType"; diff --git a/packages/store/ts/codegen/renderEncodeRecord.ts b/packages/store/ts/codegen/renderEncodeRecord.ts new file mode 100644 index 0000000000..9aacf18758 --- /dev/null +++ b/packages/store/ts/codegen/renderEncodeRecord.ts @@ -0,0 +1,165 @@ +import { AbiTypeToSchemaType } from "@latticexyz/schema-type/deprecated"; +import { + RenderDynamicField, + RenderField, + RenderStaticField, + renderArguments, + renderList, + shiftLeftBits, +} from "@latticexyz/common/codegen"; +import { getSchemaTypeInfo } from "./userType"; + +export function renderEncodeRecord( + fields: RenderField[], + staticFields: RenderStaticField[], + dynamicFields: RenderDynamicField[] +) { + return ` + /** Tightly pack full data using this table's schema */ + function encode(${renderArguments( + fields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`) + )}) internal pure returns (bytes memory) { + ${renderEncodedLengths(dynamicFields)} + ${renderEncodeRecordBody(staticFields, dynamicFields)} + } + `; +} + +const PACKED_COUNTER_INNER_TYPE = "bytes32"; + +function renderEncodedLengths(dynamicFields: RenderDynamicField[]) { + if (dynamicFields.length > 0) { + return ` + uint40[] memory _counters = new uint40[](${dynamicFields.length}); + ${renderList(dynamicFields, (field, index) => { + return `_counters[${index}] = uint40(${renderDynamicLength(field)});`; + })} + ${PACKED_COUNTER_INNER_TYPE} _encodedLengths = PackedCounterLib.pack(_counters).unwrap(); + `; + } else { + return ""; + } +} + +/** + * Render the contents of a solidity function to tightly encode the Store record. + * The result is equivalent to solidity's internal storage packing; or encodePacked if it didn't pad array elements. + * + * Some MUD-specific concessions (as opposed to a generic function like encodePacked): + * - source data location is assumed to be memory + * - _encodedLengths isn't a normal static field, but hardcoded based on dynamicFields existence + * - no nested structs + * - static fields always precede dynamic fields + * + * TODO replace this with `abi.encodeTightlyPacked` if it's added to solidity + * https://github.com/ethereum/solidity/issues/8441 + */ +function renderEncodeRecordBody(staticFields: RenderField[], dynamicFields: RenderField[]) { + if (dynamicFields.length === 0) { + return ` + return abi.encodePacked(${renderArguments(staticFields.map(({ name }) => name))}); + `; + } + // Encode PackedCounter as a static pseudo-field if dynamic fields are present + staticFields.push(encodedLengthsAsField()); + + const totalStaticByteLength = staticFields.reduce((acc, { staticByteLength }) => acc + staticByteLength, 0); + + // Compute total length first, to know how much memory to allocate + let result = ` + uint256 _resultLength; + unchecked { + _resultLength = ${totalStaticByteLength} + + ${dynamicFields.map(renderDynamicLength).join(" + ")}; + } + `; + + // Within the same assembly block allocate memory and mstore all static fields + // to take advantage of the memory tail being unallocated + // (otherwise we'd have to be careful about memory corruption) + result += ` + bytes memory _result; + uint256 _resultPointer; + + /// @solidity memory-safe-assembly + assembly { + // allocate memory + _result := mload(0x40) + _resultPointer := add(_result, 0x20) + mstore(0x40, add(_resultPointer, ${yulRoundUp("_resultLength")})) + mstore(_result, _resultLength) + `; + if (staticFields.length > 0) { + // Track the static field memory offset here to save some gas at runtime + let staticFieldOffset = 0; + for (const field of staticFields) { + result += ` + mstore(add(_resultPointer, ${staticFieldOffset}), shl(${shiftLeftBits(field)}, ${field.name})) + `; + staticFieldOffset += field.staticByteLength; + } + result += ` + _resultPointer := add(_resultPointer, ${staticFieldOffset}) + `; + } + result += ` + } + `; + + // Store all dynamic data + // Ideally this would use yul functions to keep everything in 1 assembly block, + // but yul functions can't be imported, and inlining would be bulky and make table libs unreadable + for (const [index, field] of dynamicFields.entries()) { + const unwrappedField = `${field.typeUnwrap}(${field.name})`; + // Encode the field to the result pointer + if (field.arrayElement) { + result += `EncodeArray.encodeToLocation(${unwrappedField}, _resultPointer);`; + } else { + result += `Memory.copy(Memory.dataPointer(bytes(${unwrappedField})), _resultPointer, ${renderDynamicLength( + field + )});`; + } + // Add field length to the result pointer, unless this was the last field + if (index !== dynamicFields.length - 1) { + result += ` + unchecked { + _resultPointer += ${renderDynamicLength(field)}; + } + `; + } + } + result += ` + return _result; + `; + + return result; +} + +/** + * Render yul ops that round up the variable to a multiple of 32 + * (solidity memory allocation should be word-aligned) + */ +function yulRoundUp(variableName: string) { + return `and(add(${variableName}, 31), not(31))`; +} + +// Recomputing the length each time is cheap (storing them in an array would add lots of overhead). +function renderDynamicLength(field: RenderField) { + // The field is not unwrapped here because all dynamic memory types have length in solidity + // (except string, which is what `bytes` cast is for; user types can only be elementary) + if (field.arrayElement) { + return `${field.name}.length * ${field.arrayElement.staticByteLength}`; + } else { + return `bytes(${field.name}).length`; + } +} + +function encodedLengthsAsField(): RenderField { + const typeInfo = getSchemaTypeInfo(AbiTypeToSchemaType[PACKED_COUNTER_INNER_TYPE]); + return { + ...typeInfo, + name: "_encodedLengths", + methodNameSuffix: "", + arrayElement: undefined, + }; +} diff --git a/packages/store/ts/codegen/renderTable.ts b/packages/store/ts/codegen/renderTable.ts index 7d4897cb19..6be6828bdb 100644 --- a/packages/store/ts/codegen/renderTable.ts +++ b/packages/store/ts/codegen/renderTable.ts @@ -8,12 +8,12 @@ import { renderValueTypeToBytes32, renderWithStore, renderTypeHelpers, - RenderDynamicField, } from "@latticexyz/common/codegen"; import { renderEphemeralMethods } from "./ephemeral"; -import { renderEncodeField, renderFieldMethods } from "./field"; +import { renderFieldMethods } from "./field"; import { renderRecordMethods } from "./record"; import { RenderTableOptions } from "./types"; +import { renderEncodeRecord } from "./renderEncodeRecord"; export function renderTable(options: RenderTableOptions) { const { @@ -121,20 +121,7 @@ library ${libraryName} { ${withEphemeralMethods ? renderEphemeralMethods(options) : ""} - /** Tightly pack full data using this table's schema */ - function encode(${renderArguments( - options.fields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`) - )}) internal pure returns (bytes memory) { - ${renderEncodedLengths(dynamicFields)} - return abi.encodePacked(${renderArguments([ - renderArguments(staticFields.map(({ name }) => name)), - // TODO try gas optimization (preallocate for all, encodePacked statics, and direct encode dynamics) - // (see https://github.com/latticexyz/mud/issues/444) - ...(dynamicFields.length === 0 - ? [] - : ["_encodedLengths.unwrap()", renderArguments(dynamicFields.map((field) => renderEncodeField(field)))]), - ])}); - } + ${renderEncodeRecord(fields, staticFields, dynamicFields)} /** Encode keys as a bytes32 array using this table's schema */ function encodeKeyTuple(${renderArguments([_typedKeyArgs])}) internal pure returns (bytes32[] memory _keyTuple) { @@ -162,21 +149,3 @@ ${renderTypeHelpers(options)} `; } - -function renderEncodedLengths(dynamicFields: RenderDynamicField[]) { - if (dynamicFields.length > 0) { - return ` - uint40[] memory _counters = new uint40[](${dynamicFields.length}); - ${renderList(dynamicFields, ({ name, arrayElement }, index) => { - if (arrayElement) { - return `_counters[${index}] = uint40(${name}.length * ${arrayElement.staticByteLength});`; - } else { - return `_counters[${index}] = uint40(bytes(${name}).length);`; - } - })} - PackedCounter _encodedLengths = PackedCounterLib.pack(_counters); - `; - } else { - return ""; - } -} diff --git a/packages/store/ts/codegen/tightcoder/index.ts b/packages/store/ts/codegen/tightcoder/index.ts new file mode 100644 index 0000000000..0d46ef2076 --- /dev/null +++ b/packages/store/ts/codegen/tightcoder/index.ts @@ -0,0 +1,4 @@ +export * from "./renderDecodeSlice"; +export * from "./renderEncodeArray"; +export * from "./renderFunctions"; +export * from "./renderTightCoderAutoTest"; diff --git a/packages/store/ts/codegen/tightcoder/renderDecodeSlice.ts b/packages/store/ts/codegen/tightcoder/renderDecodeSlice.ts new file mode 100644 index 0000000000..b6e1705c52 --- /dev/null +++ b/packages/store/ts/codegen/tightcoder/renderDecodeSlice.ts @@ -0,0 +1,24 @@ +import { renderedSolidityHeader } from "@latticexyz/common/codegen"; +import { staticAbiTypeToByteLength, staticAbiTypes } from "@latticexyz/schema-type"; +import { renderTightCoderDecode } from "./renderFunctions"; + +export function renderDecodeSlice() { + let result = `${renderedSolidityHeader} + + import { TightCoder } from "./TightCoder.sol"; + import { Slice } from "../Slice.sol"; + + library DecodeSlice { + `; + + for (const staticAbiType of staticAbiTypes) { + const staticByteLength = staticAbiTypeToByteLength[staticAbiType]; + result += renderTightCoderDecode({ internalTypeId: staticAbiType, staticByteLength }); + } + + result += ` + } + `; + + return result; +} diff --git a/packages/store/ts/codegen/tightcoder/renderEncodeArray.ts b/packages/store/ts/codegen/tightcoder/renderEncodeArray.ts new file mode 100644 index 0000000000..0a883c663e --- /dev/null +++ b/packages/store/ts/codegen/tightcoder/renderEncodeArray.ts @@ -0,0 +1,23 @@ +import { renderedSolidityHeader } from "@latticexyz/common/codegen"; +import { staticAbiTypeToByteLength, staticAbiTypes } from "@latticexyz/schema-type"; +import { renderTightCoderEncode } from "./renderFunctions"; + +export function renderEncodeArray() { + let result = `${renderedSolidityHeader} + + import { TightCoder } from "./TightCoder.sol"; + + library EncodeArray { + `; + + for (const staticAbiType of staticAbiTypes) { + const staticByteLength = staticAbiTypeToByteLength[staticAbiType]; + result += renderTightCoderEncode({ internalTypeId: staticAbiType, staticByteLength }); + } + + result += ` + } + `; + + return result; +} diff --git a/packages/store/ts/codegen/tightcoder/renderFunctions.ts b/packages/store/ts/codegen/tightcoder/renderFunctions.ts new file mode 100644 index 0000000000..6f7d887f3a --- /dev/null +++ b/packages/store/ts/codegen/tightcoder/renderFunctions.ts @@ -0,0 +1,46 @@ +import { isLeftAligned, shiftLeftBits } from "@latticexyz/common/codegen"; + +export function renderTightCoderDecode(element: { internalTypeId: string; staticByteLength: number }) { + return ` + function decodeArray_${element.internalTypeId}( + Slice _input + ) internal pure returns ( + ${element.internalTypeId}[] memory _output + ) { + bytes32[] memory _genericArray = TightCoder.decode( + _input, + ${element.staticByteLength}, + ${isLeftAligned(element)} + ); + assembly { + _output := _genericArray + } + } + `.trim(); +} + +export function renderTightCoderEncode(element: { internalTypeId: string; staticByteLength: number }) { + return ` + function encodeToLocation(${element.internalTypeId}[] memory _input, uint256 _toPointer) internal pure { + bytes32[] memory _genericArray; + assembly { + _genericArray := _input + } + TightCoder.encodeToLocation( + _genericArray, + _toPointer, + ${element.staticByteLength}, + ${shiftLeftBits(element)} + ); + } + + function encode(${element.internalTypeId}[] memory _input) internal pure returns (bytes memory _output) { + _output = new bytes(_input.length * ${element.staticByteLength}); + uint256 _toPointer; + assembly { + _toPointer := add(_output, 0x20) + } + encodeToLocation(_input, _toPointer); + } + `.trim(); +} diff --git a/packages/store/ts/codegen/tightcoder/renderTightCoderAutoTest.ts b/packages/store/ts/codegen/tightcoder/renderTightCoderAutoTest.ts new file mode 100644 index 0000000000..84f9cb9a86 --- /dev/null +++ b/packages/store/ts/codegen/tightcoder/renderTightCoderAutoTest.ts @@ -0,0 +1,47 @@ +import { renderedSolidityHeader } from "@latticexyz/common/codegen"; +import { staticAbiTypes } from "@latticexyz/schema-type"; + +export function renderTightCoderAutoTestFunction({ typeId }: { typeId: string }) { + return ` + function testEncodeDecodeArray_${typeId}( + ${typeId} val0, + ${typeId} val1, + ${typeId} val2 + ) public { + ${typeId}[] memory input = new ${typeId}[](3); + input[0] = val0; + input[1] = val1; + input[2] = val2; + + bytes memory encoded = EncodeArray.encode(input); + assertEq(encoded, abi.encodePacked(val0, val1, val2)); + + ${typeId}[] memory decoded = SliceLib.fromBytes(encoded).decodeArray_${typeId}(); + assertEq(decoded.length, 3); + assertEq(decoded[0], val0); + assertEq(decoded[1], val1); + assertEq(decoded[2], val2); + } + `.trim(); +} + +export function renderTightCoderAutoTest() { + let result = `${renderedSolidityHeader} + + import { Test } from "forge-std/Test.sol"; + import { EncodeArray } from "../../src/tightcoder/EncodeArray.sol"; + import { SliceLib } from "../../src/Slice.sol"; + + contract TightCoderAutoTest is Test { + `; + + for (const staticAbiType of staticAbiTypes) { + result += renderTightCoderAutoTestFunction({ typeId: staticAbiType }); + } + + result += ` + } + `; + + return result; +} diff --git a/packages/store/ts/scripts/generate-tightcoder.ts b/packages/store/ts/scripts/generate-tightcoder.ts index ec09fc3505..dd95ddb9bb 100644 --- a/packages/store/ts/scripts/generate-tightcoder.ts +++ b/packages/store/ts/scripts/generate-tightcoder.ts @@ -1,17 +1,10 @@ -import { renderFile } from "ejs"; -import { writeFileSync } from "fs"; -import { extname, basename, join, dirname } from "path"; +import { formatAndWriteSolidity } from "@latticexyz/common/codegen"; +import { renderDecodeSlice, renderEncodeArray, renderTightCoderAutoTest } from "../codegen/tightcoder"; -function renderEjsToSol(file: string, data: object) { - renderFile(file, data, {}, (err, str) => { - if (err) throw err; - const solFile = basename(file, extname(file)) + ".sol"; - const outFullPath = join(dirname(file), solFile); - writeFileSync(outFullPath, str); - console.log(`generated: ${outFullPath}`); - }); -} - -renderEjsToSol("src/tightcoder/DecodeSlice.ejs", {}); -renderEjsToSol("src/tightcoder/EncodeArray.ejs", {}); -renderEjsToSol("test/tightcoder/TightCoderAuto.t.ejs", {}); +await formatAndWriteSolidity(renderDecodeSlice(), "src/tightcoder/DecodeSlice.sol", "Generated DecodeSlice"); +await formatAndWriteSolidity(renderEncodeArray(), "src/tightcoder/EncodeArray.sol", "Generated EncodeArray"); +await formatAndWriteSolidity( + renderTightCoderAutoTest(), + "test/tightcoder/TightCoderAuto.t.sol", + "Generated TightCoderAutoTest" +); diff --git a/packages/world/gas-report.json b/packages/world/gas-report.json index 36f0745446..e45293cff9 100644 --- a/packages/world/gas-report.json +++ b/packages/world/gas-report.json @@ -3,13 +3,13 @@ "file": "test/KeysInTableModule.t.sol", "test": "testInstallComposite", "name": "install keys in table module", - "gasUsed": 1255918 + "gasUsed": 1256245 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallGas", "name": "install keys in table module", - "gasUsed": 1255918 + "gasUsed": 1256245 }, { "file": "test/KeysInTableModule.t.sol", @@ -21,13 +21,13 @@ "file": "test/KeysInTableModule.t.sol", "test": "testInstallSingleton", "name": "install keys in table module", - "gasUsed": 1255918 + "gasUsed": 1256245 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "install keys in table module", - "gasUsed": 1255918 + "gasUsed": 1256245 }, { "file": "test/KeysInTableModule.t.sol", @@ -39,13 +39,13 @@ "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "delete a composite record on a table with keysInTableModule installed", - "gasUsed": 270004 + "gasUsed": 269581 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "install keys in table module", - "gasUsed": 1255918 + "gasUsed": 1256245 }, { "file": "test/KeysInTableModule.t.sol", @@ -57,13 +57,13 @@ "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "delete a record on a table with keysInTableModule installed", - "gasUsed": 141266 + "gasUsed": 141125 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testGetKeysWithValueGas", "name": "install keys with value module", - "gasUsed": 606592 + "gasUsed": 606643 }, { "file": "test/KeysWithValueModule.t.sol", @@ -81,7 +81,7 @@ "file": "test/KeysWithValueModule.t.sol", "test": "testInstall", "name": "install keys with value module", - "gasUsed": 606592 + "gasUsed": 606643 }, { "file": "test/KeysWithValueModule.t.sol", @@ -93,13 +93,13 @@ "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "install keys with value module", - "gasUsed": 606592 + "gasUsed": 606643 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "change a record on a table with KeysWithValueModule installed", - "gasUsed": 129713 + "gasUsed": 129451 }, { "file": "test/KeysWithValueModule.t.sol", @@ -111,7 +111,7 @@ "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "install keys with value module", - "gasUsed": 606592 + "gasUsed": 606643 }, { "file": "test/KeysWithValueModule.t.sol", @@ -207,7 +207,7 @@ "file": "test/UniqueEntityModule.t.sol", "test": "testInstall", "name": "install unique entity module", - "gasUsed": 797781 + "gasUsed": 797832 }, { "file": "test/UniqueEntityModule.t.sol", @@ -219,7 +219,7 @@ "file": "test/UniqueEntityModule.t.sol", "test": "testInstallRoot", "name": "installRoot unique entity module", - "gasUsed": 769225 + "gasUsed": 769276 }, { "file": "test/UniqueEntityModule.t.sol", @@ -285,7 +285,7 @@ "file": "test/World.t.sol", "test": "testSetMetadata", "name": "Set metadata", - "gasUsed": 279560 + "gasUsed": 279656 }, { "file": "test/World.t.sol", @@ -297,24 +297,24 @@ "file": "test/WorldDynamicUpdate.t.sol", "test": "testPopFromField", "name": "pop 1 address (cold)", - "gasUsed": 38906 + "gasUsed": 38929 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testPopFromField", "name": "pop 1 address (warm)", - "gasUsed": 21696 + "gasUsed": 21719 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testUpdateInField", "name": "updateInField 1 item (cold)", - "gasUsed": 41285 + "gasUsed": 40834 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testUpdateInField", "name": "updateInField 1 item (warm)", - "gasUsed": 24487 + "gasUsed": 24036 } ] diff --git a/packages/world/src/modules/core/tables/SystemHooks.sol b/packages/world/src/modules/core/tables/SystemHooks.sol index 8b2300a63d..4cffb7eb74 100644 --- a/packages/world/src/modules/core/tables/SystemHooks.sol +++ b/packages/world/src/modules/core/tables/SystemHooks.sol @@ -187,9 +187,30 @@ library SystemHooks { function encode(address[] memory value) internal pure returns (bytes memory) { uint40[] memory _counters = new uint40[](1); _counters[0] = uint40(value.length * 20); - PackedCounter _encodedLengths = PackedCounterLib.pack(_counters); - - return abi.encodePacked(_encodedLengths.unwrap(), EncodeArray.encode((value))); + bytes32 _encodedLengths = PackedCounterLib.pack(_counters).unwrap(); + + uint256 _resultLength; + unchecked { + _resultLength = 32 + value.length * 20; + } + + bytes memory _result; + uint256 _resultPointer; + + /// @solidity memory-safe-assembly + assembly { + // allocate memory + _result := mload(0x40) + _resultPointer := add(_result, 0x20) + mstore(0x40, add(_resultPointer, and(add(_resultLength, 31), not(31)))) + mstore(_result, _resultLength) + + mstore(add(_resultPointer, 0), shl(0, _encodedLengths)) + + _resultPointer := add(_resultPointer, 32) + } + EncodeArray.encodeToLocation((value), _resultPointer); + return _result; } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/src/modules/keysintable/tables/KeysInTable.sol b/packages/world/src/modules/keysintable/tables/KeysInTable.sol index 274a4b14aa..af2139f617 100644 --- a/packages/world/src/modules/keysintable/tables/KeysInTable.sol +++ b/packages/world/src/modules/keysintable/tables/KeysInTable.sol @@ -781,17 +781,57 @@ library KeysInTable { _counters[2] = uint40(keys2.length * 32); _counters[3] = uint40(keys3.length * 32); _counters[4] = uint40(keys4.length * 32); - PackedCounter _encodedLengths = PackedCounterLib.pack(_counters); - - return - abi.encodePacked( - _encodedLengths.unwrap(), - EncodeArray.encode((keys0)), - EncodeArray.encode((keys1)), - EncodeArray.encode((keys2)), - EncodeArray.encode((keys3)), - EncodeArray.encode((keys4)) - ); + bytes32 _encodedLengths = PackedCounterLib.pack(_counters).unwrap(); + + uint256 _resultLength; + unchecked { + _resultLength = + 32 + + keys0.length * + 32 + + keys1.length * + 32 + + keys2.length * + 32 + + keys3.length * + 32 + + keys4.length * + 32; + } + + bytes memory _result; + uint256 _resultPointer; + + /// @solidity memory-safe-assembly + assembly { + // allocate memory + _result := mload(0x40) + _resultPointer := add(_result, 0x20) + mstore(0x40, add(_resultPointer, and(add(_resultLength, 31), not(31)))) + mstore(_result, _resultLength) + + mstore(add(_resultPointer, 0), shl(0, _encodedLengths)) + + _resultPointer := add(_resultPointer, 32) + } + EncodeArray.encodeToLocation((keys0), _resultPointer); + unchecked { + _resultPointer += keys0.length * 32; + } + EncodeArray.encodeToLocation((keys1), _resultPointer); + unchecked { + _resultPointer += keys1.length * 32; + } + EncodeArray.encodeToLocation((keys2), _resultPointer); + unchecked { + _resultPointer += keys2.length * 32; + } + EncodeArray.encodeToLocation((keys3), _resultPointer); + unchecked { + _resultPointer += keys3.length * 32; + } + EncodeArray.encodeToLocation((keys4), _resultPointer); + return _result; } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol b/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol index 209ef4ee8d..f86679282a 100644 --- a/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol +++ b/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol @@ -188,9 +188,30 @@ library KeysWithValue { function encode(bytes32[] memory keysWithValue) internal pure returns (bytes memory) { uint40[] memory _counters = new uint40[](1); _counters[0] = uint40(keysWithValue.length * 32); - PackedCounter _encodedLengths = PackedCounterLib.pack(_counters); - - return abi.encodePacked(_encodedLengths.unwrap(), EncodeArray.encode((keysWithValue))); + bytes32 _encodedLengths = PackedCounterLib.pack(_counters).unwrap(); + + uint256 _resultLength; + unchecked { + _resultLength = 32 + keysWithValue.length * 32; + } + + bytes memory _result; + uint256 _resultPointer; + + /// @solidity memory-safe-assembly + assembly { + // allocate memory + _result := mload(0x40) + _resultPointer := add(_result, 0x20) + mstore(0x40, add(_resultPointer, and(add(_resultLength, 31), not(31)))) + mstore(_result, _resultLength) + + mstore(add(_resultPointer, 0), shl(0, _encodedLengths)) + + _resultPointer := add(_resultPointer, 32) + } + EncodeArray.encodeToLocation((keysWithValue), _resultPointer); + return _result; } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/test/tables/AddressArray.sol b/packages/world/test/tables/AddressArray.sol index a55dc0553e..729523595b 100644 --- a/packages/world/test/tables/AddressArray.sol +++ b/packages/world/test/tables/AddressArray.sol @@ -184,9 +184,30 @@ library AddressArray { function encode(address[] memory value) internal pure returns (bytes memory) { uint40[] memory _counters = new uint40[](1); _counters[0] = uint40(value.length * 20); - PackedCounter _encodedLengths = PackedCounterLib.pack(_counters); - - return abi.encodePacked(_encodedLengths.unwrap(), EncodeArray.encode((value))); + bytes32 _encodedLengths = PackedCounterLib.pack(_counters).unwrap(); + + uint256 _resultLength; + unchecked { + _resultLength = 32 + value.length * 20; + } + + bytes memory _result; + uint256 _resultPointer; + + /// @solidity memory-safe-assembly + assembly { + // allocate memory + _result := mload(0x40) + _resultPointer := add(_result, 0x20) + mstore(0x40, add(_resultPointer, and(add(_resultLength, 31), not(31)))) + mstore(_result, _resultLength) + + mstore(add(_resultPointer, 0), shl(0, _encodedLengths)) + + _resultPointer := add(_resultPointer, 32) + } + EncodeArray.encodeToLocation((value), _resultPointer); + return _result; } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 966bbda4b8..3bd2aadef9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -987,7 +987,7 @@ importers: version: 3.3.7 tsup: specifier: ^6.7.0 - version: 6.7.0(postcss@8.4.23)(typescript@5.1.6) + version: 6.7.0(typescript@5.1.6) tsx: specifier: ^3.12.6 version: 3.12.6 @@ -9039,6 +9039,22 @@ packages: postcss: 8.4.23 dev: true + /postcss-load-config@3.1.4: + resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} + engines: {node: '>= 10'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 2.1.0 + yaml: 1.10.2 + dev: true + /postcss-load-config@3.1.4(postcss@8.4.23): resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} engines: {node: '>= 10'} @@ -10623,6 +10639,42 @@ packages: - ts-node dev: true + /tsup@6.7.0(typescript@5.1.6): + resolution: {integrity: sha512-L3o8hGkaHnu5TdJns+mCqFsDBo83bJ44rlK7e6VdanIvpea4ArPcU3swWGsLVbXak1PqQx/V+SSmFPujBK+zEQ==} + engines: {node: '>=14.18'} + hasBin: true + peerDependencies: + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.1.0' + peerDependenciesMeta: + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + dependencies: + bundle-require: 4.0.1(esbuild@0.17.17) + cac: 6.7.14 + chokidar: 3.5.3 + debug: 4.3.4(supports-color@8.1.1) + esbuild: 0.17.17 + execa: 5.1.1 + globby: 11.1.0 + joycon: 3.1.1 + postcss-load-config: 3.1.4 + resolve-from: 5.0.0 + rollup: 3.21.8 + source-map: 0.8.0-beta.0 + sucrase: 3.32.0 + tree-kill: 1.2.2 + typescript: 5.1.6 + transitivePeerDependencies: + - supports-color + - ts-node + dev: true + /tsutils@3.21.0(typescript@5.1.6): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'}