diff --git a/packages/world/src/codegen/experimental/systems/BatchCallSystemLib.sol b/packages/world/src/codegen/experimental/systems/BatchCallSystemLib.sol index 253f12f939..d07fb2cf01 100644 --- a/packages/world/src/codegen/experimental/systems/BatchCallSystemLib.sol +++ b/packages/world/src/codegen/experimental/systems/BatchCallSystemLib.sol @@ -59,7 +59,7 @@ library BatchCallSystemLib { // if the contract calling this function is a root system, it should use `callAsRoot` if (address(_world()) == address(this)) revert BatchCallSystemLib_CallingFromRootSystem(); - bytes memory systemCall = abi.encodeCall(_batchCall_SystemCallDataArray.batchCall, (systemCalls)); + bytes memory systemCall = abi.encodeCall(_batchCall_SystemCallData0x5b5d.batchCall, (systemCalls)); bytes memory result = self.from == address(0) ? _world().call(self.systemId, systemCall) @@ -74,7 +74,7 @@ library BatchCallSystemLib { // if the contract calling this function is a root system, it should use `callAsRoot` if (address(_world()) == address(this)) revert BatchCallSystemLib_CallingFromRootSystem(); - bytes memory systemCall = abi.encodeCall(_batchCallFrom_SystemCallFromDataArray.batchCallFrom, (systemCalls)); + bytes memory systemCall = abi.encodeCall(_batchCallFrom_SystemCallFromData0x5b5d.batchCallFrom, (systemCalls)); bytes memory result = self.from == address(0) ? _world().call(self.systemId, systemCall) @@ -86,7 +86,7 @@ library BatchCallSystemLib { RootCallWrapper memory self, SystemCallData[] memory systemCalls ) internal returns (bytes[] memory returnDatas) { - bytes memory systemCall = abi.encodeCall(_batchCall_SystemCallDataArray.batchCall, (systemCalls)); + bytes memory systemCall = abi.encodeCall(_batchCall_SystemCallData0x5b5d.batchCall, (systemCalls)); bytes memory result = SystemCall.callWithHooksOrRevert(self.from, self.systemId, systemCall, msg.value); return abi.decode(result, (bytes[])); @@ -96,7 +96,7 @@ library BatchCallSystemLib { RootCallWrapper memory self, SystemCallFromData[] memory systemCalls ) internal returns (bytes[] memory returnDatas) { - bytes memory systemCall = abi.encodeCall(_batchCallFrom_SystemCallFromDataArray.batchCallFrom, (systemCalls)); + bytes memory systemCall = abi.encodeCall(_batchCallFrom_SystemCallFromData0x5b5d.batchCallFrom, (systemCalls)); bytes memory result = SystemCall.callWithHooksOrRevert(self.from, self.systemId, systemCall, msg.value); return abi.decode(result, (bytes[])); @@ -140,11 +140,11 @@ library BatchCallSystemLib { * Each interface is uniquely named based on the function name and parameters to prevent collisions. */ -interface _batchCall_SystemCallDataArray { +interface _batchCall_SystemCallData0x5b5d { function batchCall(SystemCallData[] memory systemCalls) external; } -interface _batchCallFrom_SystemCallFromDataArray { +interface _batchCallFrom_SystemCallFromData0x5b5d { function batchCallFrom(SystemCallFromData[] memory systemCalls) external; } diff --git a/packages/world/src/codegen/experimental/systems/StoreRegistrationSystemLib.sol b/packages/world/src/codegen/experimental/systems/StoreRegistrationSystemLib.sol index 5f7809b947..7bf3592c47 100644 --- a/packages/world/src/codegen/experimental/systems/StoreRegistrationSystemLib.sol +++ b/packages/world/src/codegen/experimental/systems/StoreRegistrationSystemLib.sol @@ -87,7 +87,7 @@ library StoreRegistrationSystemLib { if (address(_world()) == address(this)) revert StoreRegistrationSystemLib_CallingFromRootSystem(); bytes memory systemCall = abi.encodeCall( - _registerTable_ResourceId_FieldLayout_Schema_Schema_stringArray_stringArray.registerTable, + _registerTable_ResourceId_FieldLayout_Schema_Schema_string0x5b5d_string0x5b5d.registerTable, (tableId, fieldLayout, keySchema, valueSchema, keyNames, fieldNames) ); self.from == address(0) @@ -136,7 +136,7 @@ library StoreRegistrationSystemLib { string[] memory fieldNames ) internal { bytes memory systemCall = abi.encodeCall( - _registerTable_ResourceId_FieldLayout_Schema_Schema_stringArray_stringArray.registerTable, + _registerTable_ResourceId_FieldLayout_Schema_Schema_string0x5b5d_string0x5b5d.registerTable, (tableId, fieldLayout, keySchema, valueSchema, keyNames, fieldNames) ); SystemCall.callWithHooksOrRevert(self.from, self.systemId, systemCall, msg.value); @@ -204,7 +204,7 @@ library StoreRegistrationSystemLib { * Each interface is uniquely named based on the function name and parameters to prevent collisions. */ -interface _registerTable_ResourceId_FieldLayout_Schema_Schema_stringArray_stringArray { +interface _registerTable_ResourceId_FieldLayout_Schema_Schema_string0x5b5d_string0x5b5d { function registerTable( ResourceId tableId, FieldLayout fieldLayout, diff --git a/packages/world/ts/node/render-solidity/renderSystemLibrary.ts b/packages/world/ts/node/render-solidity/renderSystemLibrary.ts index f5ffcaae3b..57434d628f 100644 --- a/packages/world/ts/node/render-solidity/renderSystemLibrary.ts +++ b/packages/world/ts/node/render-solidity/renderSystemLibrary.ts @@ -289,9 +289,9 @@ function functionInterfaceName(contractFunction: ContractInterfaceFunction) { const { name, parameters } = contractFunction; const paramTypes = parameters .map((param) => param.split(" ")[0]) - .map((type) => type.replace("[]", "Array")) // Static arrays may contain multiple disallowed symbols, for name uniqueness toHex is easier than escaping - .map((type) => type.replace(/\[.+\]/, (match) => stringToHex(match))) + // Multidimensional arrays are also captured by `.*` + .map((type) => type.replace(/\[.*\]/, (match) => stringToHex(match))) .join("_"); return `_${name}${paramTypes.length === 0 ? "" : `_${paramTypes}`}`; } diff --git a/test/system-libraries/src/codegen/world/IASystem.sol b/test/system-libraries/src/codegen/world/IASystem.sol index 1160967ced..1dfcf70309 100644 --- a/test/system-libraries/src/codegen/world/IASystem.sol +++ b/test/system-libraries/src/codegen/world/IASystem.sol @@ -33,4 +33,6 @@ interface IASystem { function a__setValuesStaticArray(uint256[2] memory values) external; function a__setValuesStaticArray(uint256[THREE] memory values) external; + + function a__set2dArray(uint256[][] memory array2d) external returns (uint256[][] memory); } diff --git a/test/system-libraries/src/namespaces/a/ASystem.sol b/test/system-libraries/src/namespaces/a/ASystem.sol index 664f501fb1..76b73c9eca 100644 --- a/test/system-libraries/src/namespaces/a/ASystem.sol +++ b/test/system-libraries/src/namespaces/a/ASystem.sol @@ -64,4 +64,10 @@ contract ASystem is System { Value.set(values[3]); } */ + + function set2dArray(uint256[][] memory array2d) external returns (uint256[][] memory) { + address addr = _msgSender(); + AddressValue.set(addr); + return array2d; + } } diff --git a/test/system-libraries/src/namespaces/a/codegen/systems/ASystemLib.sol b/test/system-libraries/src/namespaces/a/codegen/systems/ASystemLib.sol index 12ac5aeb37..ab1e148fa3 100644 --- a/test/system-libraries/src/namespaces/a/codegen/systems/ASystemLib.sol +++ b/test/system-libraries/src/namespaces/a/codegen/systems/ASystemLib.sol @@ -81,6 +81,10 @@ library ASystemLib { return CallWrapper(self.toResourceId(), address(0)).setValuesStaticArray(values); } + function set2dArray(ASystemType self, uint256[][] memory array2d) internal returns (uint256[][] memory) { + return CallWrapper(self.toResourceId(), address(0)).set2dArray(array2d); + } + function setValue(CallWrapper memory self, ASystemThing memory value) internal { // if the contract calling this function is a root system, it should use `callAsRoot` if (address(_world()) == address(this)) revert ASystemLib_CallingFromRootSystem(); @@ -125,7 +129,7 @@ library ASystemLib { // if the contract calling this function is a root system, it should use `callAsRoot` if (address(_world()) == address(this)) revert ASystemLib_CallingFromRootSystem(); - bytes memory systemCall = abi.encodeCall(_setPositions_PositionArray.setPositions, (positions)); + bytes memory systemCall = abi.encodeCall(_setPositions_Position0x5b5d.setPositions, (positions)); self.from == address(0) ? _world().call(self.systemId, systemCall) : _world().callFrom(self.from, self.systemId, systemCall); @@ -206,6 +210,18 @@ library ASystemLib { : _world().callFrom(self.from, self.systemId, systemCall); } + function set2dArray(CallWrapper memory self, uint256[][] memory array2d) internal returns (uint256[][] memory) { + // if the contract calling this function is a root system, it should use `callAsRoot` + if (address(_world()) == address(this)) revert ASystemLib_CallingFromRootSystem(); + + bytes memory systemCall = abi.encodeCall(_set2dArray_uint2560x5b5d5b5d.set2dArray, (array2d)); + + bytes memory result = self.from == address(0) + ? _world().call(self.systemId, systemCall) + : _world().callFrom(self.from, self.systemId, systemCall); + return abi.decode(result, (uint256[][])); + } + function setValue(RootCallWrapper memory self, ASystemThing memory value) internal { bytes memory systemCall = abi.encodeCall(_setValue_ASystemThing.setValue, (value)); SystemCall.callWithHooksOrRevert(self.from, self.systemId, systemCall, msg.value); @@ -227,7 +243,7 @@ library ASystemLib { } function setPositions(RootCallWrapper memory self, Position[] memory positions) internal { - bytes memory systemCall = abi.encodeCall(_setPositions_PositionArray.setPositions, (positions)); + bytes memory systemCall = abi.encodeCall(_setPositions_Position0x5b5d.setPositions, (positions)); SystemCall.callWithHooksOrRevert(self.from, self.systemId, systemCall, msg.value); } @@ -270,6 +286,13 @@ library ASystemLib { SystemCall.callWithHooksOrRevert(self.from, self.systemId, systemCall, msg.value); } + function set2dArray(RootCallWrapper memory self, uint256[][] memory array2d) internal returns (uint256[][] memory) { + bytes memory systemCall = abi.encodeCall(_set2dArray_uint2560x5b5d5b5d.set2dArray, (array2d)); + + bytes memory result = SystemCall.callWithHooksOrRevert(self.from, self.systemId, systemCall, msg.value); + return abi.decode(result, (uint256[][])); + } + function callFrom(ASystemType self, address from) internal pure returns (CallWrapper memory) { return CallWrapper(self.toResourceId(), from); } @@ -324,7 +347,7 @@ interface _setPosition_uint256_uint256_uint256 { function setPosition(uint256 x, uint256 y, uint256 z) external; } -interface _setPositions_PositionArray { +interface _setPositions_Position0x5b5d { function setPositions(Position[] memory positions) external; } @@ -352,6 +375,10 @@ interface _setValuesStaticArray_uint2560x5b54485245455d { function setValuesStaticArray(uint256[THREE] memory values) external; } +interface _set2dArray_uint2560x5b5d5b5d { + function set2dArray(uint256[][] memory array2d) external; +} + using ASystemLib for ASystemType global; using ASystemLib for CallWrapper global; using ASystemLib for RootCallWrapper global; diff --git a/test/system-libraries/test/Libraries.t.sol b/test/system-libraries/test/Libraries.t.sol index 1c5b63e19a..d0526b780e 100644 --- a/test/system-libraries/test/Libraries.t.sol +++ b/test/system-libraries/test/Libraries.t.sol @@ -60,6 +60,12 @@ contract LibrariesTest is MudTest { assertEq(Value.get(), 2); aSystem.setValuesStaticArray([uint256(1), 2, 3]); assertEq(Value.get(), 3); + + uint256[][] memory array2d = new uint256[][](1); + array2d[0] = new uint256[](1); + array2d[0][0] = 10; + uint256[][] memory array2dResult = aSystem.set2dArray(array2d); + assertEq(abi.encode(array2d), abi.encode(array2dResult)); } function testCanCallSystemFromOtherSystem() public {