diff --git a/examples/sizes.txt b/examples/sizes.txt index 8b47810865..e729e821d6 100644 --- a/examples/sizes.txt +++ b/examples/sizes.txt @@ -112,6 +112,7 @@ state_totals 65 32 - | 32 16 - stress_tests/BruteForceRotationSearch 228 163 - | 152 106 - string_ops 156 154 - | 58 55 - + struct_by_name/Demo 271 217 - | 155 113 - struct_in_box/Example 242 206 - | 127 99 - stubs/BigUInt 192 121 - | 126 73 - stubs/Bytes 944 279 - | 606 153 - @@ -134,4 +135,4 @@ unssa/UnSSA 432 368 - | 241 204 - voting/VotingRoundApp 1580 1475 - | 727 644 - with_reentrancy/WithReentrancy 245 234 - | 126 117 - - Total 70231 54641 54582 | 33265 22305 22261 \ No newline at end of file + Total 70502 54858 54799 | 33420 22418 22374 \ No newline at end of file diff --git a/src/puya/arc56.py b/src/puya/arc56.py index bdde5a7d16..dc41217c35 100644 --- a/src/puya/arc56.py +++ b/src/puya/arc56.py @@ -181,13 +181,15 @@ def _get_source_info(debug_info: DebugInfo) -> Sequence[models.SourceInfo]: class _StructAliases: def __init__(self, structs: Iterable[ARC4Struct]) -> None: - self.aliases = dict[str, str]() + alias_to_fullname = dict[str, str]() for struct in structs: - self.aliases[struct.fullname] = ( + alias = ( struct.fullname - if struct.name in self.aliases or struct.name in models.AVMType + if struct.name in alias_to_fullname or struct.name in models.AVMType else struct.name ) + alias_to_fullname[alias] = struct.fullname + self.aliases = {v: k for k, v in alias_to_fullname.items()} @typing.overload def resolve(self, struct: str) -> str: ... @@ -203,7 +205,7 @@ def resolve(self, struct: str | None) -> str | None: def _struct_to_event(structs: _StructAliases, struct: ARC4Struct) -> models.Event: return models.Event( - name=struct.name, + name=structs.resolve(struct.name), desc=struct.desc, args=[ models.EventArg( diff --git a/src/puya/ir/main.py b/src/puya/ir/main.py index 11c03902a3..56466162f6 100644 --- a/src/puya/ir/main.py +++ b/src/puya/ir/main.py @@ -573,20 +573,18 @@ def _wtypes_to_structs( Will recursively include any structs referenced in fields """ structs = list(structs) - struct_results = dict[wtypes.ARC4Struct | wtypes.WTuple, ARC4Struct]() + struct_results = dict[str, ARC4Struct]() while structs: struct = structs.pop() - if struct in struct_results: + if struct.name in struct_results: continue structs.extend( wtype for wtype in struct.fields.values() - if isinstance(wtype, wtypes.ARC4Struct) and wtype not in struct_results + if isinstance(wtype, wtypes.ARC4Struct) and wtype.name not in struct_results ) - struct_results[struct] = _wtype_to_struct(struct) - return { - wtype.name: struct_results[wtype] for wtype in sorted(struct_results, key=lambda s: s.name) - } + struct_results[struct.name] = _wtype_to_struct(struct) + return dict(sorted(struct_results.items(), key=lambda item: item[0])) def _wtype_to_struct(struct: wtypes.ARC4Struct | wtypes.WTuple) -> ARC4Struct: diff --git a/src/puya/models.py b/src/puya/models.py index 0555f1e195..40faa8069c 100644 --- a/src/puya/models.py +++ b/src/puya/models.py @@ -1,5 +1,6 @@ import abc import enum +import re import typing from collections.abc import Mapping, Sequence @@ -62,7 +63,7 @@ class ARC4Struct: @property def name(self) -> str: - return self.fullname.rsplit(".", maxsplit=1)[-1] + return re.split(r"\W", self.fullname)[-1] @attrs.frozen(kw_only=True) diff --git a/src/puyapy/awst_build/arc4_client_gen.py b/src/puyapy/awst_build/arc4_client_gen.py index e5917bdf7a..683f63361d 100644 --- a/src/puyapy/awst_build/arc4_client_gen.py +++ b/src/puyapy/awst_build/arc4_client_gen.py @@ -1,3 +1,4 @@ +import re import textwrap from collections.abc import Iterable, Sequence from pathlib import Path @@ -18,6 +19,7 @@ _AUTO_GENERATED_COMMENT = "# This file is auto-generated, do not modify" _INDENT = " " * 4 +_NON_ALPHA_NUMERIC = re.compile(r"\W+") def write_arc4_client(contract: arc56.Contract, out_dir: Path) -> None: @@ -42,7 +44,7 @@ def __init__(self, contract: arc56.Contract): self.contract = contract self.python_methods = set[str]() self.struct_to_class = dict[str, str]() - self.reserved_class_names = {contract.name} + self.reserved_class_names = set[str]() self.reserved_method_names = set[str]() self.class_decls = list[str]() @@ -53,6 +55,7 @@ def generate(cls, contract: arc56.Contract) -> str: def _gen(self) -> str: # generate class definitions for any referenced structs in methods # don't generate from self.contract.structs as it may contain other struct definitions + client_class = self._unique_class(self.contract.name) for method in self.contract.methods: for struct in filter(None, (method.returns.struct, *(a.struct for a in method.args))): if struct not in self.struct_to_class and ( @@ -70,7 +73,7 @@ def _gen(self) -> str: "", *self.class_decls, "", - f"class {self.contract.name}(algopy.arc4.ARC4Client, typing.Protocol):", + f"class {client_class}(algopy.arc4.ARC4Client, typing.Protocol):", *_docstring(self.contract.desc), *self._gen_methods(), ) @@ -110,7 +113,7 @@ def _get_client_type(self, typ: str) -> str: return str(arc4_to_pytype(typ, None)) def _unique_class(self, name: str) -> str: - base_name = name + base_name = name = _get_python_safe_name(name) seq = 1 while name in self.reserved_class_names: seq += 1 @@ -120,7 +123,7 @@ def _unique_class(self, name: str) -> str: return name def _unique_method(self, name: str) -> str: - base_name = name + base_name = name = _get_python_safe_name(name) seq = 1 while name in self.reserved_method_names: seq += 1 @@ -218,3 +221,7 @@ def _indent(lines: Iterable[str] | str) -> str: if not isinstance(lines, str): lines = "\n".join(lines) return textwrap.indent(lines, _INDENT) + + +def _get_python_safe_name(name: str) -> str: + return _NON_ALPHA_NUMERIC.sub("_", name) diff --git a/test_cases/struct_by_name/contract.py b/test_cases/struct_by_name/contract.py new file mode 100644 index 0000000000..add2c00ff9 --- /dev/null +++ b/test_cases/struct_by_name/contract.py @@ -0,0 +1,48 @@ +import typing + +from algopy import ARC4Contract, arc4 + +from test_cases.struct_by_name.mod import StructTwo as StructThree + + +class StructOne(typing.NamedTuple): + x: arc4.UInt8 + y: arc4.UInt8 + + +class StructTwo(typing.NamedTuple): + x: arc4.UInt8 + y: arc4.UInt8 + + +class DemoContract(ARC4Contract): + """ + Verify that even though named tuples with different names but the same structure should be + considered 'comparable' in the type system, they should be output separately when being + interpreted as an arc4 Struct in an abi method + """ + + @arc4.abimethod() + def get_one(self) -> StructOne: + return StructOne( + x=arc4.UInt8(1), + y=arc4.UInt8(1), + ) + + @arc4.abimethod() + def get_two(self) -> StructTwo: + return StructTwo( + x=arc4.UInt8(1), + y=arc4.UInt8(1), + ) + + @arc4.abimethod() + def get_three(self) -> StructThree: + return StructThree( + x=arc4.UInt8(1), + y=arc4.UInt8(1), + ) + + @arc4.abimethod() + def compare(self) -> bool: + return self.get_one() == self.get_two() and self.get_two() == self.get_three() diff --git a/test_cases/struct_by_name/mod.py b/test_cases/struct_by_name/mod.py new file mode 100644 index 0000000000..5a38f47c92 --- /dev/null +++ b/test_cases/struct_by_name/mod.py @@ -0,0 +1,8 @@ +import typing + +from algopy import arc4 + + +class StructTwo(typing.NamedTuple): + x: arc4.UInt8 + y: arc4.UInt8 diff --git a/test_cases/struct_by_name/out/DemoContract.approval.teal b/test_cases/struct_by_name/out/DemoContract.approval.teal new file mode 100644 index 0000000000..d807f4dcdf --- /dev/null +++ b/test_cases/struct_by_name/out/DemoContract.approval.teal @@ -0,0 +1,207 @@ +#pragma version 10 + +test_cases.struct_by_name.contract.DemoContract.approval_program: + intcblock 1 0 + bytecblock 0x151f7c75 0x01 + callsub __puya_arc4_router__ + return + + +// test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__() -> uint64: +__puya_arc4_router__: + // struct_by_name/contract.py:18 + // class DemoContract(ARC4Contract): + proto 0 1 + txn NumAppArgs + bz __puya_arc4_router___bare_routing@8 + pushbytess 0x3d694b70 0x7fb34e8a 0x8ba7c4c2 0x46dadea3 // method "get_one()(uint8,uint8)", method "get_two()(uint8,uint8)", method "get_three()(uint8,uint8)", method "compare()bool" + txna ApplicationArgs 0 + match __puya_arc4_router___get_one_route@2 __puya_arc4_router___get_two_route@3 __puya_arc4_router___get_three_route@4 __puya_arc4_router___compare_route@5 + intc_1 // 0 + retsub + +__puya_arc4_router___get_one_route@2: + // struct_by_name/contract.py:25 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is not NoOp + txn ApplicationID + assert // can only call when not creating + callsub get_one + concat + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + retsub + +__puya_arc4_router___get_two_route@3: + // struct_by_name/contract.py:32 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is not NoOp + txn ApplicationID + assert // can only call when not creating + callsub get_two + concat + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + retsub + +__puya_arc4_router___get_three_route@4: + // struct_by_name/contract.py:39 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is not NoOp + txn ApplicationID + assert // can only call when not creating + callsub get_three + concat + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + retsub + +__puya_arc4_router___compare_route@5: + // struct_by_name/contract.py:46 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is not NoOp + txn ApplicationID + assert // can only call when not creating + callsub compare + pushbytes 0x00 + intc_1 // 0 + uncover 2 + setbit + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + retsub + +__puya_arc4_router___bare_routing@8: + // struct_by_name/contract.py:18 + // class DemoContract(ARC4Contract): + txn OnCompletion + bnz __puya_arc4_router___after_if_else@12 + txn ApplicationID + ! + assert // can only call when creating + intc_0 // 1 + retsub + +__puya_arc4_router___after_if_else@12: + // struct_by_name/contract.py:18 + // class DemoContract(ARC4Contract): + intc_1 // 0 + retsub + + +// test_cases.struct_by_name.contract.DemoContract.get_one() -> bytes, bytes: +get_one: + // struct_by_name/contract.py:25-26 + // @arc4.abimethod() + // def get_one(self) -> StructOne: + proto 0 2 + // struct_by_name/contract.py:28 + // x=arc4.UInt8(1), + bytec_1 // 0x01 + // struct_by_name/contract.py:29 + // y=arc4.UInt8(1), + dup + // struct_by_name/contract.py:27-30 + // return StructOne( + // x=arc4.UInt8(1), + // y=arc4.UInt8(1), + // ) + retsub + + +// test_cases.struct_by_name.contract.DemoContract.get_two() -> bytes, bytes: +get_two: + // struct_by_name/contract.py:32-33 + // @arc4.abimethod() + // def get_two(self) -> StructTwo: + proto 0 2 + // struct_by_name/contract.py:35 + // x=arc4.UInt8(1), + bytec_1 // 0x01 + // struct_by_name/contract.py:36 + // y=arc4.UInt8(1), + dup + // struct_by_name/contract.py:34-37 + // return StructTwo( + // x=arc4.UInt8(1), + // y=arc4.UInt8(1), + // ) + retsub + + +// test_cases.struct_by_name.contract.DemoContract.get_three() -> bytes, bytes: +get_three: + // struct_by_name/contract.py:39-40 + // @arc4.abimethod() + // def get_three(self) -> StructThree: + proto 0 2 + // struct_by_name/contract.py:42 + // x=arc4.UInt8(1), + bytec_1 // 0x01 + // struct_by_name/contract.py:43 + // y=arc4.UInt8(1), + dup + // struct_by_name/contract.py:41-44 + // return StructThree( + // x=arc4.UInt8(1), + // y=arc4.UInt8(1), + // ) + retsub + + +// test_cases.struct_by_name.contract.DemoContract.compare() -> uint64: +compare: + // struct_by_name/contract.py:46-47 + // @arc4.abimethod() + // def compare(self) -> bool: + proto 0 1 + // struct_by_name/contract.py:48 + // return self.get_one() == self.get_two() and self.get_two() == self.get_three() + callsub get_one + callsub get_two + uncover 3 + uncover 2 + b== + cover 2 + b== + && + bz compare_bool_false@3 + callsub get_two + callsub get_three + uncover 3 + uncover 2 + b== + cover 2 + b== + && + bz compare_bool_false@3 + intc_0 // 1 + b compare_bool_merge@4 + +compare_bool_false@3: + intc_1 // 0 + +compare_bool_merge@4: + // struct_by_name/contract.py:48 + // return self.get_one() == self.get_two() and self.get_two() == self.get_three() + retsub diff --git a/test_cases/struct_by_name/out/DemoContract.arc32.json b/test_cases/struct_by_name/out/DemoContract.arc32.json new file mode 100644 index 0000000000..f10b5b8a20 --- /dev/null +++ b/test_cases/struct_by_name/out/DemoContract.arc32.json @@ -0,0 +1,135 @@ +{ + "hints": { + "get_one()(uint8,uint8)": { + "call_config": { + "no_op": "CALL" + }, + "structs": { + "output": { + "name": "StructOne", + "elements": [ + [ + "x", + "uint8" + ], + [ + "y", + "uint8" + ] + ] + } + } + }, + "get_two()(uint8,uint8)": { + "call_config": { + "no_op": "CALL" + }, + "structs": { + "output": { + "name": "StructTwo", + "elements": [ + [ + "x", + "uint8" + ], + [ + "y", + "uint8" + ] + ] + } + } + }, + "get_three()(uint8,uint8)": { + "call_config": { + "no_op": "CALL" + }, + "structs": { + "output": { + "name": "StructTwo", + "elements": [ + [ + "x", + "uint8" + ], + [ + "y", + "uint8" + ] + ] + } + } + }, + "compare()bool": { + "call_config": { + "no_op": "CALL" + } + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnN0cnVjdF9ieV9uYW1lLmNvbnRyYWN0LkRlbW9Db250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgaW50Y2Jsb2NrIDEgMAogICAgYnl0ZWNibG9jayAweDE1MWY3Yzc1IDB4MDEKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RfY2FzZXMuc3RydWN0X2J5X25hbWUuY29udHJhY3QuRGVtb0NvbnRyYWN0Ll9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIHN0cnVjdF9ieV9uYW1lL2NvbnRyYWN0LnB5OjE4CiAgICAvLyBjbGFzcyBEZW1vQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A4CiAgICBwdXNoYnl0ZXNzIDB4M2Q2OTRiNzAgMHg3ZmIzNGU4YSAweDhiYTdjNGMyIDB4NDZkYWRlYTMgLy8gbWV0aG9kICJnZXRfb25lKCkodWludDgsdWludDgpIiwgbWV0aG9kICJnZXRfdHdvKCkodWludDgsdWludDgpIiwgbWV0aG9kICJnZXRfdGhyZWUoKSh1aW50OCx1aW50OCkiLCBtZXRob2QgImNvbXBhcmUoKWJvb2wiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfb25lX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X3R3b19yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF90aHJlZV9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2NvbXBhcmVfcm91dGVANQogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X29uZV9yb3V0ZUAyOgogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X29uZQogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfdHdvX3JvdXRlQDM6CiAgICAvLyBzdHJ1Y3RfYnlfbmFtZS9jb250cmFjdC5weTozMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfdHdvCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF90aHJlZV9yb3V0ZUA0OgogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X3RocmVlCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NvbXBhcmVfcm91dGVANToKICAgIC8vIHN0cnVjdF9ieV9uYW1lL2NvbnRyYWN0LnB5OjQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGNvbXBhcmUKICAgIHB1c2hieXRlcyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A4OgogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MTgKICAgIC8vIGNsYXNzIERlbW9Db250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTIKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDEyOgogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MTgKICAgIC8vIGNsYXNzIERlbW9Db250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuc3RydWN0X2J5X25hbWUuY29udHJhY3QuRGVtb0NvbnRyYWN0LmdldF9vbmUoKSAtPiBieXRlcywgYnl0ZXM6CmdldF9vbmU6CiAgICAvLyBzdHJ1Y3RfYnlfbmFtZS9jb250cmFjdC5weToyNS0yNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfb25lKHNlbGYpIC0+IFN0cnVjdE9uZToKICAgIHByb3RvIDAgMgogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MjgKICAgIC8vIHg9YXJjNC5VSW50OCgxKSwKICAgIGJ5dGVjXzEgLy8gMHgwMQogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MjkKICAgIC8vIHk9YXJjNC5VSW50OCgxKSwKICAgIGR1cAogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MjctMzAKICAgIC8vIHJldHVybiBTdHJ1Y3RPbmUoCiAgICAvLyAgICAgeD1hcmM0LlVJbnQ4KDEpLAogICAgLy8gICAgIHk9YXJjNC5VSW50OCgxKSwKICAgIC8vICkKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuc3RydWN0X2J5X25hbWUuY29udHJhY3QuRGVtb0NvbnRyYWN0LmdldF90d28oKSAtPiBieXRlcywgYnl0ZXM6CmdldF90d286CiAgICAvLyBzdHJ1Y3RfYnlfbmFtZS9jb250cmFjdC5weTozMi0zMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfdHdvKHNlbGYpIC0+IFN0cnVjdFR3bzoKICAgIHByb3RvIDAgMgogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MzUKICAgIC8vIHg9YXJjNC5VSW50OCgxKSwKICAgIGJ5dGVjXzEgLy8gMHgwMQogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MzYKICAgIC8vIHk9YXJjNC5VSW50OCgxKSwKICAgIGR1cAogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MzQtMzcKICAgIC8vIHJldHVybiBTdHJ1Y3RUd28oCiAgICAvLyAgICAgeD1hcmM0LlVJbnQ4KDEpLAogICAgLy8gICAgIHk9YXJjNC5VSW50OCgxKSwKICAgIC8vICkKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuc3RydWN0X2J5X25hbWUuY29udHJhY3QuRGVtb0NvbnRyYWN0LmdldF90aHJlZSgpIC0+IGJ5dGVzLCBieXRlczoKZ2V0X3RocmVlOgogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MzktNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ2V0X3RocmVlKHNlbGYpIC0+IFN0cnVjdFRocmVlOgogICAgcHJvdG8gMCAyCiAgICAvLyBzdHJ1Y3RfYnlfbmFtZS9jb250cmFjdC5weTo0MgogICAgLy8geD1hcmM0LlVJbnQ4KDEpLAogICAgYnl0ZWNfMSAvLyAweDAxCiAgICAvLyBzdHJ1Y3RfYnlfbmFtZS9jb250cmFjdC5weTo0MwogICAgLy8geT1hcmM0LlVJbnQ4KDEpLAogICAgZHVwCiAgICAvLyBzdHJ1Y3RfYnlfbmFtZS9jb250cmFjdC5weTo0MS00NAogICAgLy8gcmV0dXJuIFN0cnVjdFRocmVlKAogICAgLy8gICAgIHg9YXJjNC5VSW50OCgxKSwKICAgIC8vICAgICB5PWFyYzQuVUludDgoMSksCiAgICAvLyApCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLnN0cnVjdF9ieV9uYW1lLmNvbnRyYWN0LkRlbW9Db250cmFjdC5jb21wYXJlKCkgLT4gdWludDY0Ogpjb21wYXJlOgogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6NDYtNDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgY29tcGFyZShzZWxmKSAtPiBib29sOgogICAgcHJvdG8gMCAxCiAgICAvLyBzdHJ1Y3RfYnlfbmFtZS9jb250cmFjdC5weTo0OAogICAgLy8gcmV0dXJuIHNlbGYuZ2V0X29uZSgpID09IHNlbGYuZ2V0X3R3bygpIGFuZCBzZWxmLmdldF90d28oKSA9PSBzZWxmLmdldF90aHJlZSgpCiAgICBjYWxsc3ViIGdldF9vbmUKICAgIGNhbGxzdWIgZ2V0X3R3bwogICAgdW5jb3ZlciAzCiAgICB1bmNvdmVyIDIKICAgIGI9PQogICAgY292ZXIgMgogICAgYj09CiAgICAmJgogICAgYnogY29tcGFyZV9ib29sX2ZhbHNlQDMKICAgIGNhbGxzdWIgZ2V0X3R3bwogICAgY2FsbHN1YiBnZXRfdGhyZWUKICAgIHVuY292ZXIgMwogICAgdW5jb3ZlciAyCiAgICBiPT0KICAgIGNvdmVyIDIKICAgIGI9PQogICAgJiYKICAgIGJ6IGNvbXBhcmVfYm9vbF9mYWxzZUAzCiAgICBpbnRjXzAgLy8gMQogICAgYiBjb21wYXJlX2Jvb2xfbWVyZ2VANAoKY29tcGFyZV9ib29sX2ZhbHNlQDM6CiAgICBpbnRjXzEgLy8gMAoKY29tcGFyZV9ib29sX21lcmdlQDQ6CiAgICAvLyBzdHJ1Y3RfYnlfbmFtZS9jb250cmFjdC5weTo0OAogICAgLy8gcmV0dXJuIHNlbGYuZ2V0X29uZSgpID09IHNlbGYuZ2V0X3R3bygpIGFuZCBzZWxmLmdldF90d28oKSA9PSBzZWxmLmdldF90aHJlZSgpCiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnN0cnVjdF9ieV9uYW1lLmNvbnRyYWN0LkRlbW9Db250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "schema": { + "global": { + "declared": {}, + "reserved": {} + }, + "local": { + "declared": {}, + "reserved": {} + } + }, + "contract": { + "name": "DemoContract", + "desc": "\n Verify that even though named tuples with different names but the same structure should be\n considered 'comparable' in the type system, they should be output separately when being\n interpreted as an arc4 Struct in an abi method\n ", + "methods": [ + { + "name": "get_one", + "args": [], + "readonly": false, + "returns": { + "type": "(uint8,uint8)" + } + }, + { + "name": "get_two", + "args": [], + "readonly": false, + "returns": { + "type": "(uint8,uint8)" + } + }, + { + "name": "get_three", + "args": [], + "readonly": false, + "returns": { + "type": "(uint8,uint8)" + } + }, + { + "name": "compare", + "args": [], + "readonly": false, + "returns": { + "type": "bool" + } + } + ], + "networks": {} + }, + "bare_call_config": { + "no_op": "CREATE" + } +} \ No newline at end of file diff --git a/test_cases/struct_by_name/out/DemoContract.arc56.json b/test_cases/struct_by_name/out/DemoContract.arc56.json new file mode 100644 index 0000000000..ad56f19e05 --- /dev/null +++ b/test_cases/struct_by_name/out/DemoContract.arc56.json @@ -0,0 +1,191 @@ +{ + "name": "DemoContract", + "structs": { + "StructOne": [ + { + "name": "x", + "type": "uint8" + }, + { + "name": "y", + "type": "uint8" + } + ], + "StructTwo": [ + { + "name": "x", + "type": "uint8" + }, + { + "name": "y", + "type": "uint8" + } + ], + "test_cases.struct_by_name.mod.StructTwo": [ + { + "name": "x", + "type": "uint8" + }, + { + "name": "y", + "type": "uint8" + } + ] + }, + "methods": [ + { + "name": "get_one", + "args": [], + "returns": { + "type": "(uint8,uint8)", + "struct": "StructOne" + }, + "actions": { + "create": [], + "call": [ + "NoOp" + ] + }, + "readonly": false, + "events": [], + "recommendations": {} + }, + { + "name": "get_two", + "args": [], + "returns": { + "type": "(uint8,uint8)", + "struct": "StructTwo" + }, + "actions": { + "create": [], + "call": [ + "NoOp" + ] + }, + "readonly": false, + "events": [], + "recommendations": {} + }, + { + "name": "get_three", + "args": [], + "returns": { + "type": "(uint8,uint8)", + "struct": "test_cases.struct_by_name.mod.StructTwo" + }, + "actions": { + "create": [], + "call": [ + "NoOp" + ] + }, + "readonly": false, + "events": [], + "recommendations": {} + }, + { + "name": "compare", + "args": [], + "returns": { + "type": "bool" + }, + "actions": { + "create": [], + "call": [ + "NoOp" + ] + }, + "readonly": false, + "events": [], + "recommendations": {} + } + ], + "arcs": [ + 22, + 28 + ], + "desc": "\n Verify that even though named tuples with different names but the same structure should be\n considered 'comparable' in the type system, they should be output separately when being\n interpreted as an arc4 Struct in an abi method\n ", + "networks": {}, + "state": { + "schema": { + "global": { + "ints": 0, + "bytes": 0 + }, + "local": { + "ints": 0, + "bytes": 0 + } + }, + "keys": { + "global": {}, + "local": {}, + "box": {} + }, + "maps": { + "global": {}, + "local": {}, + "box": {} + } + }, + "bareActions": { + "create": [ + "NoOp" + ], + "call": [] + }, + "sourceInfo": { + "approval": { + "sourceInfo": [ + { + "pc": [ + 66, + 83, + 100, + 117 + ], + "errorMessage": "OnCompletion is not NoOp" + }, + { + "pc": [ + 145 + ], + "errorMessage": "can only call when creating" + }, + { + "pc": [ + 69, + 86, + 103, + 120 + ], + "errorMessage": "can only call when not creating" + } + ], + "pcOffsetMethod": "none" + }, + "clear": { + "sourceInfo": [], + "pcOffsetMethod": "none" + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnN0cnVjdF9ieV9uYW1lLmNvbnRyYWN0LkRlbW9Db250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgaW50Y2Jsb2NrIDEgMAogICAgYnl0ZWNibG9jayAweDE1MWY3Yzc1IDB4MDEKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RfY2FzZXMuc3RydWN0X2J5X25hbWUuY29udHJhY3QuRGVtb0NvbnRyYWN0Ll9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIHN0cnVjdF9ieV9uYW1lL2NvbnRyYWN0LnB5OjE4CiAgICAvLyBjbGFzcyBEZW1vQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A4CiAgICBwdXNoYnl0ZXNzIDB4M2Q2OTRiNzAgMHg3ZmIzNGU4YSAweDhiYTdjNGMyIDB4NDZkYWRlYTMgLy8gbWV0aG9kICJnZXRfb25lKCkodWludDgsdWludDgpIiwgbWV0aG9kICJnZXRfdHdvKCkodWludDgsdWludDgpIiwgbWV0aG9kICJnZXRfdGhyZWUoKSh1aW50OCx1aW50OCkiLCBtZXRob2QgImNvbXBhcmUoKWJvb2wiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfb25lX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X3R3b19yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF90aHJlZV9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2NvbXBhcmVfcm91dGVANQogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X29uZV9yb3V0ZUAyOgogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X29uZQogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfdHdvX3JvdXRlQDM6CiAgICAvLyBzdHJ1Y3RfYnlfbmFtZS9jb250cmFjdC5weTozMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfdHdvCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF90aHJlZV9yb3V0ZUA0OgogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X3RocmVlCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NvbXBhcmVfcm91dGVANToKICAgIC8vIHN0cnVjdF9ieV9uYW1lL2NvbnRyYWN0LnB5OjQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGNvbXBhcmUKICAgIHB1c2hieXRlcyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A4OgogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MTgKICAgIC8vIGNsYXNzIERlbW9Db250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTIKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDEyOgogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MTgKICAgIC8vIGNsYXNzIERlbW9Db250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuc3RydWN0X2J5X25hbWUuY29udHJhY3QuRGVtb0NvbnRyYWN0LmdldF9vbmUoKSAtPiBieXRlcywgYnl0ZXM6CmdldF9vbmU6CiAgICAvLyBzdHJ1Y3RfYnlfbmFtZS9jb250cmFjdC5weToyNS0yNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfb25lKHNlbGYpIC0+IFN0cnVjdE9uZToKICAgIHByb3RvIDAgMgogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MjgKICAgIC8vIHg9YXJjNC5VSW50OCgxKSwKICAgIGJ5dGVjXzEgLy8gMHgwMQogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MjkKICAgIC8vIHk9YXJjNC5VSW50OCgxKSwKICAgIGR1cAogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MjctMzAKICAgIC8vIHJldHVybiBTdHJ1Y3RPbmUoCiAgICAvLyAgICAgeD1hcmM0LlVJbnQ4KDEpLAogICAgLy8gICAgIHk9YXJjNC5VSW50OCgxKSwKICAgIC8vICkKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuc3RydWN0X2J5X25hbWUuY29udHJhY3QuRGVtb0NvbnRyYWN0LmdldF90d28oKSAtPiBieXRlcywgYnl0ZXM6CmdldF90d286CiAgICAvLyBzdHJ1Y3RfYnlfbmFtZS9jb250cmFjdC5weTozMi0zMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfdHdvKHNlbGYpIC0+IFN0cnVjdFR3bzoKICAgIHByb3RvIDAgMgogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MzUKICAgIC8vIHg9YXJjNC5VSW50OCgxKSwKICAgIGJ5dGVjXzEgLy8gMHgwMQogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MzYKICAgIC8vIHk9YXJjNC5VSW50OCgxKSwKICAgIGR1cAogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MzQtMzcKICAgIC8vIHJldHVybiBTdHJ1Y3RUd28oCiAgICAvLyAgICAgeD1hcmM0LlVJbnQ4KDEpLAogICAgLy8gICAgIHk9YXJjNC5VSW50OCgxKSwKICAgIC8vICkKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuc3RydWN0X2J5X25hbWUuY29udHJhY3QuRGVtb0NvbnRyYWN0LmdldF90aHJlZSgpIC0+IGJ5dGVzLCBieXRlczoKZ2V0X3RocmVlOgogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6MzktNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ2V0X3RocmVlKHNlbGYpIC0+IFN0cnVjdFRocmVlOgogICAgcHJvdG8gMCAyCiAgICAvLyBzdHJ1Y3RfYnlfbmFtZS9jb250cmFjdC5weTo0MgogICAgLy8geD1hcmM0LlVJbnQ4KDEpLAogICAgYnl0ZWNfMSAvLyAweDAxCiAgICAvLyBzdHJ1Y3RfYnlfbmFtZS9jb250cmFjdC5weTo0MwogICAgLy8geT1hcmM0LlVJbnQ4KDEpLAogICAgZHVwCiAgICAvLyBzdHJ1Y3RfYnlfbmFtZS9jb250cmFjdC5weTo0MS00NAogICAgLy8gcmV0dXJuIFN0cnVjdFRocmVlKAogICAgLy8gICAgIHg9YXJjNC5VSW50OCgxKSwKICAgIC8vICAgICB5PWFyYzQuVUludDgoMSksCiAgICAvLyApCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLnN0cnVjdF9ieV9uYW1lLmNvbnRyYWN0LkRlbW9Db250cmFjdC5jb21wYXJlKCkgLT4gdWludDY0Ogpjb21wYXJlOgogICAgLy8gc3RydWN0X2J5X25hbWUvY29udHJhY3QucHk6NDYtNDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgY29tcGFyZShzZWxmKSAtPiBib29sOgogICAgcHJvdG8gMCAxCiAgICAvLyBzdHJ1Y3RfYnlfbmFtZS9jb250cmFjdC5weTo0OAogICAgLy8gcmV0dXJuIHNlbGYuZ2V0X29uZSgpID09IHNlbGYuZ2V0X3R3bygpIGFuZCBzZWxmLmdldF90d28oKSA9PSBzZWxmLmdldF90aHJlZSgpCiAgICBjYWxsc3ViIGdldF9vbmUKICAgIGNhbGxzdWIgZ2V0X3R3bwogICAgdW5jb3ZlciAzCiAgICB1bmNvdmVyIDIKICAgIGI9PQogICAgY292ZXIgMgogICAgYj09CiAgICAmJgogICAgYnogY29tcGFyZV9ib29sX2ZhbHNlQDMKICAgIGNhbGxzdWIgZ2V0X3R3bwogICAgY2FsbHN1YiBnZXRfdGhyZWUKICAgIHVuY292ZXIgMwogICAgdW5jb3ZlciAyCiAgICBiPT0KICAgIGNvdmVyIDIKICAgIGI9PQogICAgJiYKICAgIGJ6IGNvbXBhcmVfYm9vbF9mYWxzZUAzCiAgICBpbnRjXzAgLy8gMQogICAgYiBjb21wYXJlX2Jvb2xfbWVyZ2VANAoKY29tcGFyZV9ib29sX2ZhbHNlQDM6CiAgICBpbnRjXzEgLy8gMAoKY29tcGFyZV9ib29sX21lcmdlQDQ6CiAgICAvLyBzdHJ1Y3RfYnlfbmFtZS9jb250cmFjdC5weTo0OAogICAgLy8gcmV0dXJuIHNlbGYuZ2V0X29uZSgpID09IHNlbGYuZ2V0X3R3bygpIGFuZCBzZWxmLmdldF90d28oKSA9PSBzZWxmLmdldF90aHJlZSgpCiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnN0cnVjdF9ieV9uYW1lLmNvbnRyYWN0LkRlbW9Db250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" + }, + "byteCode": { + "approval": "CiACAQAmAgQVH3x1AQGIAAFDigABMRtBAG+CBAQ9aUtwBH+zTooEi6fEwgRG2t6jNhoAjgQAAgATACQANSOJMRkURDEYRIgATVAoTFCwIokxGRREMRhEiABCUChMULAiiTEZFEQxGESIADdQKExQsCKJMRkURDEYRIgALIABACNPAlQoTFCwIokxGUAABjEYFEQiiSOJigACKUmJigACKUmJigACKUmJigABiP/oiP/rTwNPAqhOAqgQQQAWiP/ciP/fTwNPAqhOAqgQQQAEIkIAASOJ", + "clear": "CoEBQw==" + }, + "compilerInfo": { + "compiler": "puya", + "compilerVersion": { + "major": 99, + "minor": 99, + "patch": 99 + } + }, + "events": [], + "templateVariables": {} +} \ No newline at end of file diff --git a/test_cases/struct_by_name/out/DemoContract.clear.teal b/test_cases/struct_by_name/out/DemoContract.clear.teal new file mode 100644 index 0000000000..41c3a3f9e2 --- /dev/null +++ b/test_cases/struct_by_name/out/DemoContract.clear.teal @@ -0,0 +1,5 @@ +#pragma version 10 + +test_cases.struct_by_name.contract.DemoContract.clear_state_program: + pushint 1 // 1 + return diff --git a/test_cases/struct_by_name/out/DemoContract.destructured.ir b/test_cases/struct_by_name/out/DemoContract.destructured.ir new file mode 100644 index 0000000000..d577859cc2 --- /dev/null +++ b/test_cases/struct_by_name/out/DemoContract.destructured.ir @@ -0,0 +1,109 @@ +contract test_cases.struct_by_name.contract.DemoContract: + program approval: + subroutine algopy.arc4.ARC4Contract.approval_program() -> bool: + block@0: // L1 + let tmp%0#0: bool = test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__() + return tmp%0#0 + + subroutine test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__() -> bool: + block@0: // L18 + let tmp%0#0: uint64 = (txn NumAppArgs) + goto tmp%0#0 ? block@1 : block@8 + block@1: // abi_routing_L18 + let tmp%2#0: bytes = (txna ApplicationArgs 0) + switch tmp%2#0 {method "get_one()(uint8,uint8)" => block@2, method "get_two()(uint8,uint8)" => block@3, method "get_three()(uint8,uint8)" => block@4, method "compare()bool" => block@5, * => return 0u} + block@2: // get_one_route_L25 + let tmp%3#0: uint64 = (txn OnCompletion) + let tmp%4#0: bool = (! tmp%3#0) + (assert tmp%4#0) // OnCompletion is not NoOp + let tmp%5#0: uint64 = (txn ApplicationID) + (assert tmp%5#0) // can only call when not creating + let (elements_to_encode%0#0: bytes, elements_to_encode%1#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_one() + let encoded_tuple_buffer%2#0: bytes = (concat elements_to_encode%0#0 elements_to_encode%1#0) + let tmp%7#0: bytes = (concat 0x151f7c75 encoded_tuple_buffer%2#0) + (log tmp%7#0) + return 1u + block@3: // get_two_route_L32 + let tmp%8#0: uint64 = (txn OnCompletion) + let tmp%9#0: bool = (! tmp%8#0) + (assert tmp%9#0) // OnCompletion is not NoOp + let tmp%10#0: uint64 = (txn ApplicationID) + (assert tmp%10#0) // can only call when not creating + let (elements_to_encode%2#0: bytes, elements_to_encode%3#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_two() + let encoded_tuple_buffer%5#0: bytes = (concat elements_to_encode%2#0 elements_to_encode%3#0) + let tmp%12#0: bytes = (concat 0x151f7c75 encoded_tuple_buffer%5#0) + (log tmp%12#0) + return 1u + block@4: // get_three_route_L39 + let tmp%13#0: uint64 = (txn OnCompletion) + let tmp%14#0: bool = (! tmp%13#0) + (assert tmp%14#0) // OnCompletion is not NoOp + let tmp%15#0: uint64 = (txn ApplicationID) + (assert tmp%15#0) // can only call when not creating + let (elements_to_encode%4#0: bytes, elements_to_encode%5#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_three() + let encoded_tuple_buffer%8#0: bytes = (concat elements_to_encode%4#0 elements_to_encode%5#0) + let tmp%17#0: bytes = (concat 0x151f7c75 encoded_tuple_buffer%8#0) + (log tmp%17#0) + return 1u + block@5: // compare_route_L46 + let tmp%18#0: uint64 = (txn OnCompletion) + let tmp%19#0: bool = (! tmp%18#0) + (assert tmp%19#0) // OnCompletion is not NoOp + let tmp%20#0: uint64 = (txn ApplicationID) + (assert tmp%20#0) // can only call when not creating + let to_encode%0#0: bool = test_cases.struct_by_name.contract.DemoContract.compare() + let encoded_bool%0#0: bytes = (setbit 0x00 0u to_encode%0#0) + let tmp%22#0: bytes = (concat 0x151f7c75 encoded_bool%0#0) + (log tmp%22#0) + return 1u + block@8: // bare_routing_L18 + let tmp%23#0: uint64 = (txn OnCompletion) + goto tmp%23#0 ? block@12 : block@9 + block@9: // __algopy_default_create_L1 + let tmp%24#0: uint64 = (txn ApplicationID) + let tmp%25#0: bool = (! tmp%24#0) + (assert tmp%25#0) // can only call when creating + return 1u + block@12: // after_if_else_L18 + return 0u + + subroutine test_cases.struct_by_name.contract.DemoContract.get_one() -> : + block@0: // L25 + return 0x01 0x01 + + subroutine test_cases.struct_by_name.contract.DemoContract.get_two() -> : + block@0: // L32 + return 0x01 0x01 + + subroutine test_cases.struct_by_name.contract.DemoContract.get_three() -> : + block@0: // L39 + return 0x01 0x01 + + subroutine test_cases.struct_by_name.contract.DemoContract.compare() -> bool: + block@0: // L46 + let (awst_tmp%0#0: bytes, awst_tmp%1#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_one() + let (awst_tmp%2#0: bytes, awst_tmp%3#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_two() + let tmp%0#0: bool = (b== awst_tmp%0#0 awst_tmp%2#0) + let tmp%1#0: bool = (b== awst_tmp%1#0 awst_tmp%3#0) + let tmp%2#0: bool = (&& tmp%0#0 tmp%1#0) + goto tmp%2#0 ? block@1 : block@3 + block@1: // and_contd_L48 + let (awst_tmp%4#0: bytes, awst_tmp%5#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_two() + let (awst_tmp%6#0: bytes, awst_tmp%7#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_three() + let tmp%3#0: bool = (b== awst_tmp%4#0 awst_tmp%6#0) + let tmp%4#0: bool = (b== awst_tmp%5#0 awst_tmp%7#0) + let tmp%5#0: bool = (&& tmp%3#0 tmp%4#0) + goto tmp%5#0 ? block@2 : block@3 + block@2: // bool_true_L48 + let and_result%0#0: bool = 1u + goto block@4 + block@3: // bool_false_L48 + let and_result%0#0: bool = 0u + goto block@4 + block@4: // bool_merge_L48 + return and_result%0#0 + + program clear-state: + subroutine algopy.arc4.ARC4Contract.clear_state_program() -> bool: + block@0: // L1 + return 1u \ No newline at end of file diff --git a/test_cases/struct_by_name/out/DemoContract.ssa.ir b/test_cases/struct_by_name/out/DemoContract.ssa.ir new file mode 100644 index 0000000000..bc2901d6a2 --- /dev/null +++ b/test_cases/struct_by_name/out/DemoContract.ssa.ir @@ -0,0 +1,145 @@ +contract test_cases.struct_by_name.contract.DemoContract: + program approval: + subroutine algopy.arc4.ARC4Contract.approval_program() -> bool: + block@0: // L1 + let tmp%0#0: bool = test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__() + return tmp%0#0 + + subroutine test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__() -> bool: + block@0: // L18 + let tmp%0#0: uint64 = (txn NumAppArgs) + let tmp%1#0: bool = (!= tmp%0#0 0u) + goto tmp%1#0 ? block@1 : block@8 + block@1: // abi_routing_L18 + let tmp%2#0: bytes = (txna ApplicationArgs 0) + switch tmp%2#0 {method "get_one()(uint8,uint8)" => block@2, method "get_two()(uint8,uint8)" => block@3, method "get_three()(uint8,uint8)" => block@4, method "compare()bool" => block@5, * => block@6} + block@2: // get_one_route_L25 + let tmp%3#0: uint64 = (txn OnCompletion) + let tmp%4#0: bool = (== tmp%3#0 NoOp) + (assert tmp%4#0) // OnCompletion is not NoOp + let tmp%5#0: uint64 = (txn ApplicationID) + let tmp%6#0: bool = (!= tmp%5#0 0u) + (assert tmp%6#0) // can only call when not creating + let (elements_to_encode%0#0: bytes, elements_to_encode%1#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_one() + let current_tail_offset%0#0: uint64 = 2u + let encoded_tuple_buffer%0#0: bytes = 0x + let encoded_tuple_buffer%1#0: bytes = (concat encoded_tuple_buffer%0#0 elements_to_encode%0#0) + let encoded_tuple_buffer%2#0: bytes = (concat encoded_tuple_buffer%1#0 elements_to_encode%1#0) + let tmp%7#0: bytes = (concat 0x151f7c75 encoded_tuple_buffer%2#0) + (log tmp%7#0) + return 1u + block@3: // get_two_route_L32 + let tmp%8#0: uint64 = (txn OnCompletion) + let tmp%9#0: bool = (== tmp%8#0 NoOp) + (assert tmp%9#0) // OnCompletion is not NoOp + let tmp%10#0: uint64 = (txn ApplicationID) + let tmp%11#0: bool = (!= tmp%10#0 0u) + (assert tmp%11#0) // can only call when not creating + let (elements_to_encode%2#0: bytes, elements_to_encode%3#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_two() + let current_tail_offset%1#0: uint64 = 2u + let encoded_tuple_buffer%3#0: bytes = 0x + let encoded_tuple_buffer%4#0: bytes = (concat encoded_tuple_buffer%3#0 elements_to_encode%2#0) + let encoded_tuple_buffer%5#0: bytes = (concat encoded_tuple_buffer%4#0 elements_to_encode%3#0) + let tmp%12#0: bytes = (concat 0x151f7c75 encoded_tuple_buffer%5#0) + (log tmp%12#0) + return 1u + block@4: // get_three_route_L39 + let tmp%13#0: uint64 = (txn OnCompletion) + let tmp%14#0: bool = (== tmp%13#0 NoOp) + (assert tmp%14#0) // OnCompletion is not NoOp + let tmp%15#0: uint64 = (txn ApplicationID) + let tmp%16#0: bool = (!= tmp%15#0 0u) + (assert tmp%16#0) // can only call when not creating + let (elements_to_encode%4#0: bytes, elements_to_encode%5#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_three() + let current_tail_offset%2#0: uint64 = 2u + let encoded_tuple_buffer%6#0: bytes = 0x + let encoded_tuple_buffer%7#0: bytes = (concat encoded_tuple_buffer%6#0 elements_to_encode%4#0) + let encoded_tuple_buffer%8#0: bytes = (concat encoded_tuple_buffer%7#0 elements_to_encode%5#0) + let tmp%17#0: bytes = (concat 0x151f7c75 encoded_tuple_buffer%8#0) + (log tmp%17#0) + return 1u + block@5: // compare_route_L46 + let tmp%18#0: uint64 = (txn OnCompletion) + let tmp%19#0: bool = (== tmp%18#0 NoOp) + (assert tmp%19#0) // OnCompletion is not NoOp + let tmp%20#0: uint64 = (txn ApplicationID) + let tmp%21#0: bool = (!= tmp%20#0 0u) + (assert tmp%21#0) // can only call when not creating + let to_encode%0#0: bool = test_cases.struct_by_name.contract.DemoContract.compare() + let encoded_bool%0#0: bytes = (setbit 0x00 0u to_encode%0#0) + let tmp%22#0: bytes = (concat 0x151f7c75 encoded_bool%0#0) + (log tmp%22#0) + return 1u + block@6: // switch_case_default_L18 + goto block@7 + block@7: // switch_case_next_L18 + goto block@12 + block@8: // bare_routing_L18 + let tmp%23#0: uint64 = (txn OnCompletion) + switch tmp%23#0 {0u => block@9, * => block@10} + block@9: // __algopy_default_create_L1 + let tmp%24#0: uint64 = (txn ApplicationID) + let tmp%25#0: bool = (== tmp%24#0 0u) + (assert tmp%25#0) // can only call when creating + test_cases.struct_by_name.contract.DemoContract.__algopy_default_create() + return 1u + block@10: // switch_case_default_L18 + goto block@11 + block@11: // switch_case_next_L18 + goto block@12 + block@12: // after_if_else_L18 + return 0u + + subroutine test_cases.struct_by_name.contract.DemoContract.get_one() -> : + block@0: // L25 + return 0x01 0x01 + + subroutine test_cases.struct_by_name.contract.DemoContract.get_two() -> : + block@0: // L32 + return 0x01 0x01 + + subroutine test_cases.struct_by_name.contract.DemoContract.get_three() -> : + block@0: // L39 + return 0x01 0x01 + + subroutine test_cases.struct_by_name.contract.DemoContract.compare() -> bool: + block@0: // L46 + let (awst_tmp%0#0: bytes, awst_tmp%1#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_one() + let reinterpret_biguint%0#0: biguint = awst_tmp%0#0 + let (awst_tmp%2#0: bytes, awst_tmp%3#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_two() + let reinterpret_biguint%1#0: biguint = awst_tmp%2#0 + let tmp%0#0: bool = (b== reinterpret_biguint%0#0 reinterpret_biguint%1#0) + let reinterpret_biguint%2#0: biguint = awst_tmp%1#0 + let reinterpret_biguint%3#0: biguint = awst_tmp%3#0 + let tmp%1#0: bool = (b== reinterpret_biguint%2#0 reinterpret_biguint%3#0) + let tmp%2#0: bool = (&& tmp%0#0 tmp%1#0) + goto tmp%2#0 ? block@1 : block@3 + block@1: // and_contd_L48 + let (awst_tmp%4#0: bytes, awst_tmp%5#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_two() + let reinterpret_biguint%4#0: biguint = awst_tmp%4#0 + let (awst_tmp%6#0: bytes, awst_tmp%7#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_three() + let reinterpret_biguint%5#0: biguint = awst_tmp%6#0 + let tmp%3#0: bool = (b== reinterpret_biguint%4#0 reinterpret_biguint%5#0) + let reinterpret_biguint%6#0: biguint = awst_tmp%5#0 + let reinterpret_biguint%7#0: biguint = awst_tmp%7#0 + let tmp%4#0: bool = (b== reinterpret_biguint%6#0 reinterpret_biguint%7#0) + let tmp%5#0: bool = (&& tmp%3#0 tmp%4#0) + goto tmp%5#0 ? block@2 : block@3 + block@2: // bool_true_L48 + let and_result%0#0: bool = 1u + goto block@4 + block@3: // bool_false_L48 + let and_result%0#1: bool = 0u + goto block@4 + block@4: // bool_merge_L48 + let and_result%0#2: bool = φ(and_result%0#0 <- block@2, and_result%0#1 <- block@3) + return and_result%0#2 + + subroutine test_cases.struct_by_name.contract.DemoContract.__algopy_default_create() -> void: + block@0: // L1 + return + + program clear-state: + subroutine algopy.arc4.ARC4Contract.clear_state_program() -> bool: + block@0: // L1 + return 1u \ No newline at end of file diff --git a/test_cases/struct_by_name/out/DemoContract.ssa.opt_pass_1.ir b/test_cases/struct_by_name/out/DemoContract.ssa.opt_pass_1.ir new file mode 100644 index 0000000000..1373bd840b --- /dev/null +++ b/test_cases/struct_by_name/out/DemoContract.ssa.opt_pass_1.ir @@ -0,0 +1,113 @@ +contract test_cases.struct_by_name.contract.DemoContract: + program approval: + subroutine algopy.arc4.ARC4Contract.approval_program() -> bool: + block@0: // L1 + let tmp%0#0: bool = test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__() + return tmp%0#0 + + subroutine test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__() -> bool: + block@0: // L18 + let tmp%0#0: uint64 = (txn NumAppArgs) + goto tmp%0#0 ? block@1 : block@8 + block@1: // abi_routing_L18 + let tmp%2#0: bytes = (txna ApplicationArgs 0) + switch tmp%2#0 {method "get_one()(uint8,uint8)" => block@2, method "get_two()(uint8,uint8)" => block@3, method "get_three()(uint8,uint8)" => block@4, method "compare()bool" => block@5, * => return 0u} + block@2: // get_one_route_L25 + let tmp%3#0: uint64 = (txn OnCompletion) + let tmp%4#0: bool = (! tmp%3#0) + (assert tmp%4#0) // OnCompletion is not NoOp + let tmp%5#0: uint64 = (txn ApplicationID) + (assert tmp%5#0) // can only call when not creating + let (elements_to_encode%0#0: bytes, elements_to_encode%1#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_one() + let encoded_tuple_buffer%1#0: bytes = elements_to_encode%0#0 + let encoded_tuple_buffer%2#0: bytes = (concat encoded_tuple_buffer%1#0 elements_to_encode%1#0) + let tmp%7#0: bytes = (concat 0x151f7c75 encoded_tuple_buffer%2#0) + (log tmp%7#0) + return 1u + block@3: // get_two_route_L32 + let tmp%8#0: uint64 = (txn OnCompletion) + let tmp%9#0: bool = (! tmp%8#0) + (assert tmp%9#0) // OnCompletion is not NoOp + let tmp%10#0: uint64 = (txn ApplicationID) + (assert tmp%10#0) // can only call when not creating + let (elements_to_encode%2#0: bytes, elements_to_encode%3#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_two() + let encoded_tuple_buffer%4#0: bytes = elements_to_encode%2#0 + let encoded_tuple_buffer%5#0: bytes = (concat encoded_tuple_buffer%4#0 elements_to_encode%3#0) + let tmp%12#0: bytes = (concat 0x151f7c75 encoded_tuple_buffer%5#0) + (log tmp%12#0) + return 1u + block@4: // get_three_route_L39 + let tmp%13#0: uint64 = (txn OnCompletion) + let tmp%14#0: bool = (! tmp%13#0) + (assert tmp%14#0) // OnCompletion is not NoOp + let tmp%15#0: uint64 = (txn ApplicationID) + (assert tmp%15#0) // can only call when not creating + let (elements_to_encode%4#0: bytes, elements_to_encode%5#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_three() + let encoded_tuple_buffer%7#0: bytes = elements_to_encode%4#0 + let encoded_tuple_buffer%8#0: bytes = (concat encoded_tuple_buffer%7#0 elements_to_encode%5#0) + let tmp%17#0: bytes = (concat 0x151f7c75 encoded_tuple_buffer%8#0) + (log tmp%17#0) + return 1u + block@5: // compare_route_L46 + let tmp%18#0: uint64 = (txn OnCompletion) + let tmp%19#0: bool = (! tmp%18#0) + (assert tmp%19#0) // OnCompletion is not NoOp + let tmp%20#0: uint64 = (txn ApplicationID) + (assert tmp%20#0) // can only call when not creating + let to_encode%0#0: bool = test_cases.struct_by_name.contract.DemoContract.compare() + let encoded_bool%0#0: bytes = (setbit 0x00 0u to_encode%0#0) + let tmp%22#0: bytes = (concat 0x151f7c75 encoded_bool%0#0) + (log tmp%22#0) + return 1u + block@8: // bare_routing_L18 + let tmp%23#0: uint64 = (txn OnCompletion) + goto tmp%23#0 ? block@12 : block@9 + block@9: // __algopy_default_create_L1 + let tmp%24#0: uint64 = (txn ApplicationID) + let tmp%25#0: bool = (! tmp%24#0) + (assert tmp%25#0) // can only call when creating + return 1u + block@12: // after_if_else_L18 + return 0u + + subroutine test_cases.struct_by_name.contract.DemoContract.get_one() -> : + block@0: // L25 + return 0x01 0x01 + + subroutine test_cases.struct_by_name.contract.DemoContract.get_two() -> : + block@0: // L32 + return 0x01 0x01 + + subroutine test_cases.struct_by_name.contract.DemoContract.get_three() -> : + block@0: // L39 + return 0x01 0x01 + + subroutine test_cases.struct_by_name.contract.DemoContract.compare() -> bool: + block@0: // L46 + let (awst_tmp%0#0: bytes, awst_tmp%1#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_one() + let (awst_tmp%2#0: bytes, awst_tmp%3#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_two() + let tmp%0#0: bool = (b== awst_tmp%0#0 awst_tmp%2#0) + let tmp%1#0: bool = (b== awst_tmp%1#0 awst_tmp%3#0) + let tmp%2#0: bool = (&& tmp%0#0 tmp%1#0) + goto tmp%2#0 ? block@1 : block@3 + block@1: // and_contd_L48 + let (awst_tmp%4#0: bytes, awst_tmp%5#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_two() + let (awst_tmp%6#0: bytes, awst_tmp%7#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_three() + let tmp%3#0: bool = (b== awst_tmp%4#0 awst_tmp%6#0) + let tmp%4#0: bool = (b== awst_tmp%5#0 awst_tmp%7#0) + let tmp%5#0: bool = (&& tmp%3#0 tmp%4#0) + goto tmp%5#0 ? block@2 : block@3 + block@2: // bool_true_L48 + let and_result%0#0: bool = 1u + goto block@4 + block@3: // bool_false_L48 + let and_result%0#1: bool = 0u + goto block@4 + block@4: // bool_merge_L48 + let and_result%0#2: bool = φ(and_result%0#0 <- block@2, and_result%0#1 <- block@3) + return and_result%0#2 + + program clear-state: + subroutine algopy.arc4.ARC4Contract.clear_state_program() -> bool: + block@0: // L1 + return 1u \ No newline at end of file diff --git a/test_cases/struct_by_name/out/DemoContract.ssa.opt_pass_2.ir b/test_cases/struct_by_name/out/DemoContract.ssa.opt_pass_2.ir new file mode 100644 index 0000000000..aa1086996b --- /dev/null +++ b/test_cases/struct_by_name/out/DemoContract.ssa.opt_pass_2.ir @@ -0,0 +1,110 @@ +contract test_cases.struct_by_name.contract.DemoContract: + program approval: + subroutine algopy.arc4.ARC4Contract.approval_program() -> bool: + block@0: // L1 + let tmp%0#0: bool = test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__() + return tmp%0#0 + + subroutine test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__() -> bool: + block@0: // L18 + let tmp%0#0: uint64 = (txn NumAppArgs) + goto tmp%0#0 ? block@1 : block@8 + block@1: // abi_routing_L18 + let tmp%2#0: bytes = (txna ApplicationArgs 0) + switch tmp%2#0 {method "get_one()(uint8,uint8)" => block@2, method "get_two()(uint8,uint8)" => block@3, method "get_three()(uint8,uint8)" => block@4, method "compare()bool" => block@5, * => return 0u} + block@2: // get_one_route_L25 + let tmp%3#0: uint64 = (txn OnCompletion) + let tmp%4#0: bool = (! tmp%3#0) + (assert tmp%4#0) // OnCompletion is not NoOp + let tmp%5#0: uint64 = (txn ApplicationID) + (assert tmp%5#0) // can only call when not creating + let (elements_to_encode%0#0: bytes, elements_to_encode%1#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_one() + let encoded_tuple_buffer%2#0: bytes = (concat elements_to_encode%0#0 elements_to_encode%1#0) + let tmp%7#0: bytes = (concat 0x151f7c75 encoded_tuple_buffer%2#0) + (log tmp%7#0) + return 1u + block@3: // get_two_route_L32 + let tmp%8#0: uint64 = (txn OnCompletion) + let tmp%9#0: bool = (! tmp%8#0) + (assert tmp%9#0) // OnCompletion is not NoOp + let tmp%10#0: uint64 = (txn ApplicationID) + (assert tmp%10#0) // can only call when not creating + let (elements_to_encode%2#0: bytes, elements_to_encode%3#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_two() + let encoded_tuple_buffer%5#0: bytes = (concat elements_to_encode%2#0 elements_to_encode%3#0) + let tmp%12#0: bytes = (concat 0x151f7c75 encoded_tuple_buffer%5#0) + (log tmp%12#0) + return 1u + block@4: // get_three_route_L39 + let tmp%13#0: uint64 = (txn OnCompletion) + let tmp%14#0: bool = (! tmp%13#0) + (assert tmp%14#0) // OnCompletion is not NoOp + let tmp%15#0: uint64 = (txn ApplicationID) + (assert tmp%15#0) // can only call when not creating + let (elements_to_encode%4#0: bytes, elements_to_encode%5#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_three() + let encoded_tuple_buffer%8#0: bytes = (concat elements_to_encode%4#0 elements_to_encode%5#0) + let tmp%17#0: bytes = (concat 0x151f7c75 encoded_tuple_buffer%8#0) + (log tmp%17#0) + return 1u + block@5: // compare_route_L46 + let tmp%18#0: uint64 = (txn OnCompletion) + let tmp%19#0: bool = (! tmp%18#0) + (assert tmp%19#0) // OnCompletion is not NoOp + let tmp%20#0: uint64 = (txn ApplicationID) + (assert tmp%20#0) // can only call when not creating + let to_encode%0#0: bool = test_cases.struct_by_name.contract.DemoContract.compare() + let encoded_bool%0#0: bytes = (setbit 0x00 0u to_encode%0#0) + let tmp%22#0: bytes = (concat 0x151f7c75 encoded_bool%0#0) + (log tmp%22#0) + return 1u + block@8: // bare_routing_L18 + let tmp%23#0: uint64 = (txn OnCompletion) + goto tmp%23#0 ? block@12 : block@9 + block@9: // __algopy_default_create_L1 + let tmp%24#0: uint64 = (txn ApplicationID) + let tmp%25#0: bool = (! tmp%24#0) + (assert tmp%25#0) // can only call when creating + return 1u + block@12: // after_if_else_L18 + return 0u + + subroutine test_cases.struct_by_name.contract.DemoContract.get_one() -> : + block@0: // L25 + return 0x01 0x01 + + subroutine test_cases.struct_by_name.contract.DemoContract.get_two() -> : + block@0: // L32 + return 0x01 0x01 + + subroutine test_cases.struct_by_name.contract.DemoContract.get_three() -> : + block@0: // L39 + return 0x01 0x01 + + subroutine test_cases.struct_by_name.contract.DemoContract.compare() -> bool: + block@0: // L46 + let (awst_tmp%0#0: bytes, awst_tmp%1#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_one() + let (awst_tmp%2#0: bytes, awst_tmp%3#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_two() + let tmp%0#0: bool = (b== awst_tmp%0#0 awst_tmp%2#0) + let tmp%1#0: bool = (b== awst_tmp%1#0 awst_tmp%3#0) + let tmp%2#0: bool = (&& tmp%0#0 tmp%1#0) + goto tmp%2#0 ? block@1 : block@3 + block@1: // and_contd_L48 + let (awst_tmp%4#0: bytes, awst_tmp%5#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_two() + let (awst_tmp%6#0: bytes, awst_tmp%7#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_three() + let tmp%3#0: bool = (b== awst_tmp%4#0 awst_tmp%6#0) + let tmp%4#0: bool = (b== awst_tmp%5#0 awst_tmp%7#0) + let tmp%5#0: bool = (&& tmp%3#0 tmp%4#0) + goto tmp%5#0 ? block@2 : block@3 + block@2: // bool_true_L48 + let and_result%0#0: bool = 1u + goto block@4 + block@3: // bool_false_L48 + let and_result%0#1: bool = 0u + goto block@4 + block@4: // bool_merge_L48 + let and_result%0#2: bool = φ(and_result%0#0 <- block@2, and_result%0#1 <- block@3) + return and_result%0#2 + + program clear-state: + subroutine algopy.arc4.ARC4Contract.clear_state_program() -> bool: + block@0: // L1 + return 1u \ No newline at end of file diff --git a/test_cases/struct_by_name/out/client_DemoContract.py b/test_cases/struct_by_name/out/client_DemoContract.py new file mode 100644 index 0000000000..9644b856a6 --- /dev/null +++ b/test_cases/struct_by_name/out/client_DemoContract.py @@ -0,0 +1,46 @@ +# This file is auto-generated, do not modify +# flake8: noqa +# fmt: off +import typing + +import algopy + +class StructOne(algopy.arc4.Struct): + x: algopy.arc4.UIntN[typing.Literal[8]] + y: algopy.arc4.UIntN[typing.Literal[8]] + +class StructTwo(algopy.arc4.Struct): + x: algopy.arc4.UIntN[typing.Literal[8]] + y: algopy.arc4.UIntN[typing.Literal[8]] + +class test_cases_struct_by_name_mod_StructTwo(algopy.arc4.Struct): + x: algopy.arc4.UIntN[typing.Literal[8]] + y: algopy.arc4.UIntN[typing.Literal[8]] + +class DemoContract(algopy.arc4.ARC4Client, typing.Protocol): + """ + + Verify that even though named tuples with different names but the same structure should be + considered 'comparable' in the type system, they should be output separately when being + interpreted as an arc4 Struct in an abi method + + """ + @algopy.arc4.abimethod + def get_one( + self, + ) -> StructOne: ... + + @algopy.arc4.abimethod + def get_two( + self, + ) -> StructTwo: ... + + @algopy.arc4.abimethod + def get_three( + self, + ) -> test_cases_struct_by_name_mod_StructTwo: ... + + @algopy.arc4.abimethod + def compare( + self, + ) -> algopy.arc4.Bool: ... diff --git a/test_cases/struct_by_name/out/module.awst b/test_cases/struct_by_name/out/module.awst new file mode 100644 index 0000000000..5b54962f89 --- /dev/null +++ b/test_cases/struct_by_name/out/module.awst @@ -0,0 +1,40 @@ +contract DemoContract +{ + method_resolution_order: ( + algopy.arc4.ARC4Contract, + ) + + subroutine algopy.arc4.ARC4Contract.approval_program(): bool + { + return arc4_router() + } + + subroutine algopy.arc4.ARC4Contract.clear_state_program(): bool + { + return true + } + + abimethod test_cases.struct_by_name.contract.DemoContract.get_one(): test_cases.struct_by_name.contract.StructOne + { + return (1_arc4u8, 1_arc4u8) + } + + abimethod test_cases.struct_by_name.contract.DemoContract.get_two(): test_cases.struct_by_name.contract.StructTwo + { + return (1_arc4u8, 1_arc4u8) + } + + abimethod test_cases.struct_by_name.contract.DemoContract.get_three(): test_cases.struct_by_name.mod.StructTwo + { + return (1_arc4u8, 1_arc4u8) + } + + abimethod test_cases.struct_by_name.contract.DemoContract.compare(): bool + { + return &&(reinterpret_cast(SINGLE_EVAL(id=0, source=this::get_one())[0]) == reinterpret_cast(SINGLE_EVAL(id=1, source=this::get_two())[0]), reinterpret_cast(SINGLE_EVAL(id=0)[1]) == reinterpret_cast(SINGLE_EVAL(id=1)[1])) and &&(reinterpret_cast(SINGLE_EVAL(id=2, source=this::get_two())[0]) == reinterpret_cast(SINGLE_EVAL(id=3, source=this::get_three())[0]), reinterpret_cast(SINGLE_EVAL(id=2)[1]) == reinterpret_cast(SINGLE_EVAL(id=3)[1])) + } + + baremethod test_cases.struct_by_name.contract.DemoContract.__algopy_default_create(): void + { + } +} \ No newline at end of file diff --git a/test_cases/struct_by_name/out_O2/DemoContract.approval.teal b/test_cases/struct_by_name/out_O2/DemoContract.approval.teal new file mode 100644 index 0000000000..f4559f012e --- /dev/null +++ b/test_cases/struct_by_name/out_O2/DemoContract.approval.teal @@ -0,0 +1,150 @@ +#pragma version 10 + +test_cases.struct_by_name.contract.DemoContract.approval_program: + intcblock 1 0 + bytecblock 0x151f7c75 0x01 + callsub __puya_arc4_router__ + return + + +// test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__() -> uint64: +__puya_arc4_router__: + proto 0 1 + txn NumAppArgs + bz __puya_arc4_router___bare_routing@8 + pushbytess 0x3d694b70 0x7fb34e8a 0x8ba7c4c2 0x46dadea3 // method "get_one()(uint8,uint8)", method "get_two()(uint8,uint8)", method "get_three()(uint8,uint8)", method "compare()bool" + txna ApplicationArgs 0 + match __puya_arc4_router___get_one_route@2 __puya_arc4_router___get_two_route@3 __puya_arc4_router___get_three_route@4 __puya_arc4_router___compare_route@5 + intc_1 // 0 + retsub + +__puya_arc4_router___get_one_route@2: + txn OnCompletion + ! + assert // OnCompletion is not NoOp + txn ApplicationID + assert // can only call when not creating + callsub get_one + concat + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + retsub + +__puya_arc4_router___get_two_route@3: + txn OnCompletion + ! + assert // OnCompletion is not NoOp + txn ApplicationID + assert // can only call when not creating + callsub get_two + concat + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + retsub + +__puya_arc4_router___get_three_route@4: + txn OnCompletion + ! + assert // OnCompletion is not NoOp + txn ApplicationID + assert // can only call when not creating + callsub get_three + concat + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + retsub + +__puya_arc4_router___compare_route@5: + txn OnCompletion + ! + assert // OnCompletion is not NoOp + txn ApplicationID + assert // can only call when not creating + callsub compare + pushbytes 0x00 + intc_1 // 0 + uncover 2 + setbit + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + retsub + +__puya_arc4_router___bare_routing@8: + txn OnCompletion + bnz __puya_arc4_router___after_if_else@12 + txn ApplicationID + ! + assert // can only call when creating + intc_0 // 1 + retsub + +__puya_arc4_router___after_if_else@12: + intc_1 // 0 + retsub + + +// test_cases.struct_by_name.contract.DemoContract.get_one() -> bytes, bytes: +get_one: + proto 0 2 + bytec_1 // 0x01 + dup + retsub + + +// test_cases.struct_by_name.contract.DemoContract.get_two() -> bytes, bytes: +get_two: + proto 0 2 + bytec_1 // 0x01 + dup + retsub + + +// test_cases.struct_by_name.contract.DemoContract.get_three() -> bytes, bytes: +get_three: + proto 0 2 + bytec_1 // 0x01 + dup + retsub + + +// test_cases.struct_by_name.contract.DemoContract.compare() -> uint64: +compare: + proto 0 1 + callsub get_one + callsub get_two + uncover 3 + uncover 2 + b== + cover 2 + b== + && + bz compare_bool_false@3 + callsub get_two + callsub get_three + uncover 3 + uncover 2 + b== + cover 2 + b== + && + bz compare_bool_false@3 + intc_0 // 1 + b compare_bool_merge@4 + +compare_bool_false@3: + intc_1 // 0 + +compare_bool_merge@4: + retsub diff --git a/test_cases/struct_by_name/out_O2/DemoContract.clear.teal b/test_cases/struct_by_name/out_O2/DemoContract.clear.teal new file mode 100644 index 0000000000..41c3a3f9e2 --- /dev/null +++ b/test_cases/struct_by_name/out_O2/DemoContract.clear.teal @@ -0,0 +1,5 @@ +#pragma version 10 + +test_cases.struct_by_name.contract.DemoContract.clear_state_program: + pushint 1 // 1 + return diff --git a/test_cases/struct_by_name/out_O2/DemoContract.destructured.ir b/test_cases/struct_by_name/out_O2/DemoContract.destructured.ir new file mode 100644 index 0000000000..d577859cc2 --- /dev/null +++ b/test_cases/struct_by_name/out_O2/DemoContract.destructured.ir @@ -0,0 +1,109 @@ +contract test_cases.struct_by_name.contract.DemoContract: + program approval: + subroutine algopy.arc4.ARC4Contract.approval_program() -> bool: + block@0: // L1 + let tmp%0#0: bool = test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__() + return tmp%0#0 + + subroutine test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__() -> bool: + block@0: // L18 + let tmp%0#0: uint64 = (txn NumAppArgs) + goto tmp%0#0 ? block@1 : block@8 + block@1: // abi_routing_L18 + let tmp%2#0: bytes = (txna ApplicationArgs 0) + switch tmp%2#0 {method "get_one()(uint8,uint8)" => block@2, method "get_two()(uint8,uint8)" => block@3, method "get_three()(uint8,uint8)" => block@4, method "compare()bool" => block@5, * => return 0u} + block@2: // get_one_route_L25 + let tmp%3#0: uint64 = (txn OnCompletion) + let tmp%4#0: bool = (! tmp%3#0) + (assert tmp%4#0) // OnCompletion is not NoOp + let tmp%5#0: uint64 = (txn ApplicationID) + (assert tmp%5#0) // can only call when not creating + let (elements_to_encode%0#0: bytes, elements_to_encode%1#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_one() + let encoded_tuple_buffer%2#0: bytes = (concat elements_to_encode%0#0 elements_to_encode%1#0) + let tmp%7#0: bytes = (concat 0x151f7c75 encoded_tuple_buffer%2#0) + (log tmp%7#0) + return 1u + block@3: // get_two_route_L32 + let tmp%8#0: uint64 = (txn OnCompletion) + let tmp%9#0: bool = (! tmp%8#0) + (assert tmp%9#0) // OnCompletion is not NoOp + let tmp%10#0: uint64 = (txn ApplicationID) + (assert tmp%10#0) // can only call when not creating + let (elements_to_encode%2#0: bytes, elements_to_encode%3#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_two() + let encoded_tuple_buffer%5#0: bytes = (concat elements_to_encode%2#0 elements_to_encode%3#0) + let tmp%12#0: bytes = (concat 0x151f7c75 encoded_tuple_buffer%5#0) + (log tmp%12#0) + return 1u + block@4: // get_three_route_L39 + let tmp%13#0: uint64 = (txn OnCompletion) + let tmp%14#0: bool = (! tmp%13#0) + (assert tmp%14#0) // OnCompletion is not NoOp + let tmp%15#0: uint64 = (txn ApplicationID) + (assert tmp%15#0) // can only call when not creating + let (elements_to_encode%4#0: bytes, elements_to_encode%5#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_three() + let encoded_tuple_buffer%8#0: bytes = (concat elements_to_encode%4#0 elements_to_encode%5#0) + let tmp%17#0: bytes = (concat 0x151f7c75 encoded_tuple_buffer%8#0) + (log tmp%17#0) + return 1u + block@5: // compare_route_L46 + let tmp%18#0: uint64 = (txn OnCompletion) + let tmp%19#0: bool = (! tmp%18#0) + (assert tmp%19#0) // OnCompletion is not NoOp + let tmp%20#0: uint64 = (txn ApplicationID) + (assert tmp%20#0) // can only call when not creating + let to_encode%0#0: bool = test_cases.struct_by_name.contract.DemoContract.compare() + let encoded_bool%0#0: bytes = (setbit 0x00 0u to_encode%0#0) + let tmp%22#0: bytes = (concat 0x151f7c75 encoded_bool%0#0) + (log tmp%22#0) + return 1u + block@8: // bare_routing_L18 + let tmp%23#0: uint64 = (txn OnCompletion) + goto tmp%23#0 ? block@12 : block@9 + block@9: // __algopy_default_create_L1 + let tmp%24#0: uint64 = (txn ApplicationID) + let tmp%25#0: bool = (! tmp%24#0) + (assert tmp%25#0) // can only call when creating + return 1u + block@12: // after_if_else_L18 + return 0u + + subroutine test_cases.struct_by_name.contract.DemoContract.get_one() -> : + block@0: // L25 + return 0x01 0x01 + + subroutine test_cases.struct_by_name.contract.DemoContract.get_two() -> : + block@0: // L32 + return 0x01 0x01 + + subroutine test_cases.struct_by_name.contract.DemoContract.get_three() -> : + block@0: // L39 + return 0x01 0x01 + + subroutine test_cases.struct_by_name.contract.DemoContract.compare() -> bool: + block@0: // L46 + let (awst_tmp%0#0: bytes, awst_tmp%1#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_one() + let (awst_tmp%2#0: bytes, awst_tmp%3#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_two() + let tmp%0#0: bool = (b== awst_tmp%0#0 awst_tmp%2#0) + let tmp%1#0: bool = (b== awst_tmp%1#0 awst_tmp%3#0) + let tmp%2#0: bool = (&& tmp%0#0 tmp%1#0) + goto tmp%2#0 ? block@1 : block@3 + block@1: // and_contd_L48 + let (awst_tmp%4#0: bytes, awst_tmp%5#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_two() + let (awst_tmp%6#0: bytes, awst_tmp%7#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_three() + let tmp%3#0: bool = (b== awst_tmp%4#0 awst_tmp%6#0) + let tmp%4#0: bool = (b== awst_tmp%5#0 awst_tmp%7#0) + let tmp%5#0: bool = (&& tmp%3#0 tmp%4#0) + goto tmp%5#0 ? block@2 : block@3 + block@2: // bool_true_L48 + let and_result%0#0: bool = 1u + goto block@4 + block@3: // bool_false_L48 + let and_result%0#0: bool = 0u + goto block@4 + block@4: // bool_merge_L48 + return and_result%0#0 + + program clear-state: + subroutine algopy.arc4.ARC4Contract.clear_state_program() -> bool: + block@0: // L1 + return 1u \ No newline at end of file diff --git a/test_cases/struct_by_name/out_unoptimized/DemoContract.approval.teal b/test_cases/struct_by_name/out_unoptimized/DemoContract.approval.teal new file mode 100644 index 0000000000..428e64a75c --- /dev/null +++ b/test_cases/struct_by_name/out_unoptimized/DemoContract.approval.teal @@ -0,0 +1,259 @@ +#pragma version 10 + +test_cases.struct_by_name.contract.DemoContract.approval_program: + intcblock 0 1 + bytecblock 0x151f7c75 0x 0x01 + callsub __puya_arc4_router__ + return + + +// test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__() -> uint64: +__puya_arc4_router__: + // struct_by_name/contract.py:18 + // class DemoContract(ARC4Contract): + proto 0 1 + txn NumAppArgs + intc_0 // 0 + != + bz __puya_arc4_router___bare_routing@8 + txna ApplicationArgs 0 + pushbytes 0x3d694b70 // method "get_one()(uint8,uint8)" + pushbytes 0x7fb34e8a // method "get_two()(uint8,uint8)" + pushbytes 0x8ba7c4c2 // method "get_three()(uint8,uint8)" + pushbytes 0x46dadea3 // method "compare()bool" + uncover 4 + match __puya_arc4_router___get_one_route@2 __puya_arc4_router___get_two_route@3 __puya_arc4_router___get_three_route@4 __puya_arc4_router___compare_route@5 + b __puya_arc4_router___switch_case_default@6 + +__puya_arc4_router___get_one_route@2: + // struct_by_name/contract.py:25 + // @arc4.abimethod() + txn OnCompletion + intc_0 // NoOp + == + assert // OnCompletion is not NoOp + txn ApplicationID + intc_0 // 0 + != + assert // can only call when not creating + callsub get_one + swap + bytec_1 // 0x + swap + concat + swap + concat + bytec_0 // 0x151f7c75 + swap + concat + log + intc_1 // 1 + retsub + +__puya_arc4_router___get_two_route@3: + // struct_by_name/contract.py:32 + // @arc4.abimethod() + txn OnCompletion + intc_0 // NoOp + == + assert // OnCompletion is not NoOp + txn ApplicationID + intc_0 // 0 + != + assert // can only call when not creating + callsub get_two + swap + bytec_1 // 0x + swap + concat + swap + concat + bytec_0 // 0x151f7c75 + swap + concat + log + intc_1 // 1 + retsub + +__puya_arc4_router___get_three_route@4: + // struct_by_name/contract.py:39 + // @arc4.abimethod() + txn OnCompletion + intc_0 // NoOp + == + assert // OnCompletion is not NoOp + txn ApplicationID + intc_0 // 0 + != + assert // can only call when not creating + callsub get_three + swap + bytec_1 // 0x + swap + concat + swap + concat + bytec_0 // 0x151f7c75 + swap + concat + log + intc_1 // 1 + retsub + +__puya_arc4_router___compare_route@5: + // struct_by_name/contract.py:46 + // @arc4.abimethod() + txn OnCompletion + intc_0 // NoOp + == + assert // OnCompletion is not NoOp + txn ApplicationID + intc_0 // 0 + != + assert // can only call when not creating + callsub compare + pushbytes 0x00 + intc_0 // 0 + uncover 2 + setbit + bytec_0 // 0x151f7c75 + swap + concat + log + intc_1 // 1 + retsub + +__puya_arc4_router___switch_case_default@6: + b __puya_arc4_router___after_if_else@12 + +__puya_arc4_router___bare_routing@8: + // struct_by_name/contract.py:18 + // class DemoContract(ARC4Contract): + txn OnCompletion + intc_0 // 0 + swap + match __puya_arc4_router_____algopy_default_create@9 + b __puya_arc4_router___switch_case_default@10 + +__puya_arc4_router_____algopy_default_create@9: + txn ApplicationID + intc_0 // 0 + == + assert // can only call when creating + callsub __algopy_default_create + intc_1 // 1 + retsub + +__puya_arc4_router___switch_case_default@10: + +__puya_arc4_router___after_if_else@12: + // struct_by_name/contract.py:18 + // class DemoContract(ARC4Contract): + intc_0 // 0 + retsub + + +// test_cases.struct_by_name.contract.DemoContract.get_one() -> bytes, bytes: +get_one: + // struct_by_name/contract.py:25-26 + // @arc4.abimethod() + // def get_one(self) -> StructOne: + proto 0 2 + // struct_by_name/contract.py:28 + // x=arc4.UInt8(1), + bytec_2 // 0x01 + // struct_by_name/contract.py:29 + // y=arc4.UInt8(1), + dup + // struct_by_name/contract.py:27-30 + // return StructOne( + // x=arc4.UInt8(1), + // y=arc4.UInt8(1), + // ) + retsub + + +// test_cases.struct_by_name.contract.DemoContract.get_two() -> bytes, bytes: +get_two: + // struct_by_name/contract.py:32-33 + // @arc4.abimethod() + // def get_two(self) -> StructTwo: + proto 0 2 + // struct_by_name/contract.py:35 + // x=arc4.UInt8(1), + bytec_2 // 0x01 + // struct_by_name/contract.py:36 + // y=arc4.UInt8(1), + dup + // struct_by_name/contract.py:34-37 + // return StructTwo( + // x=arc4.UInt8(1), + // y=arc4.UInt8(1), + // ) + retsub + + +// test_cases.struct_by_name.contract.DemoContract.get_three() -> bytes, bytes: +get_three: + // struct_by_name/contract.py:39-40 + // @arc4.abimethod() + // def get_three(self) -> StructThree: + proto 0 2 + // struct_by_name/contract.py:42 + // x=arc4.UInt8(1), + bytec_2 // 0x01 + // struct_by_name/contract.py:43 + // y=arc4.UInt8(1), + dup + // struct_by_name/contract.py:41-44 + // return StructThree( + // x=arc4.UInt8(1), + // y=arc4.UInt8(1), + // ) + retsub + + +// test_cases.struct_by_name.contract.DemoContract.compare() -> uint64: +compare: + // struct_by_name/contract.py:46-47 + // @arc4.abimethod() + // def compare(self) -> bool: + proto 0 1 + // struct_by_name/contract.py:48 + // return self.get_one() == self.get_two() and self.get_two() == self.get_three() + callsub get_one + swap + callsub get_two + cover 2 + b== + uncover 2 + uncover 2 + b== + && + bz compare_bool_false@3 + callsub get_two + swap + callsub get_three + cover 2 + b== + uncover 2 + uncover 2 + b== + && + bz compare_bool_false@3 + intc_1 // 1 + b compare_bool_merge@4 + +compare_bool_false@3: + intc_0 // 0 + +compare_bool_merge@4: + // struct_by_name/contract.py:48 + // return self.get_one() == self.get_two() and self.get_two() == self.get_three() + retsub + + +// test_cases.struct_by_name.contract.DemoContract.__algopy_default_create() -> void: +__algopy_default_create: + proto 0 0 + retsub diff --git a/test_cases/struct_by_name/out_unoptimized/DemoContract.clear.teal b/test_cases/struct_by_name/out_unoptimized/DemoContract.clear.teal new file mode 100644 index 0000000000..41c3a3f9e2 --- /dev/null +++ b/test_cases/struct_by_name/out_unoptimized/DemoContract.clear.teal @@ -0,0 +1,5 @@ +#pragma version 10 + +test_cases.struct_by_name.contract.DemoContract.clear_state_program: + pushint 1 // 1 + return diff --git a/test_cases/struct_by_name/out_unoptimized/DemoContract.destructured.ir b/test_cases/struct_by_name/out_unoptimized/DemoContract.destructured.ir new file mode 100644 index 0000000000..b282675536 --- /dev/null +++ b/test_cases/struct_by_name/out_unoptimized/DemoContract.destructured.ir @@ -0,0 +1,138 @@ +contract test_cases.struct_by_name.contract.DemoContract: + program approval: + subroutine algopy.arc4.ARC4Contract.approval_program() -> bool: + block@0: // L1 + let tmp%0#0: bool = test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__() + return tmp%0#0 + + subroutine test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__() -> bool: + block@0: // L18 + let tmp%0#0: uint64 = (txn NumAppArgs) + let tmp%1#0: bool = (!= tmp%0#0 0u) + goto tmp%1#0 ? block@1 : block@8 + block@1: // abi_routing_L18 + let tmp%2#0: bytes = (txna ApplicationArgs 0) + switch tmp%2#0 {method "get_one()(uint8,uint8)" => block@2, method "get_two()(uint8,uint8)" => block@3, method "get_three()(uint8,uint8)" => block@4, method "compare()bool" => block@5, * => block@6} + block@2: // get_one_route_L25 + let tmp%3#0: uint64 = (txn OnCompletion) + let tmp%4#0: bool = (== tmp%3#0 NoOp) + (assert tmp%4#0) // OnCompletion is not NoOp + let tmp%5#0: uint64 = (txn ApplicationID) + let tmp%6#0: bool = (!= tmp%5#0 0u) + (assert tmp%6#0) // can only call when not creating + let (elements_to_encode%0#0: bytes, elements_to_encode%1#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_one() + let encoded_tuple_buffer%1#0: bytes = (concat 0x elements_to_encode%0#0) + let encoded_tuple_buffer%2#0: bytes = (concat encoded_tuple_buffer%1#0 elements_to_encode%1#0) + let tmp%7#0: bytes = (concat 0x151f7c75 encoded_tuple_buffer%2#0) + (log tmp%7#0) + return 1u + block@3: // get_two_route_L32 + let tmp%8#0: uint64 = (txn OnCompletion) + let tmp%9#0: bool = (== tmp%8#0 NoOp) + (assert tmp%9#0) // OnCompletion is not NoOp + let tmp%10#0: uint64 = (txn ApplicationID) + let tmp%11#0: bool = (!= tmp%10#0 0u) + (assert tmp%11#0) // can only call when not creating + let (elements_to_encode%2#0: bytes, elements_to_encode%3#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_two() + let encoded_tuple_buffer%4#0: bytes = (concat 0x elements_to_encode%2#0) + let encoded_tuple_buffer%5#0: bytes = (concat encoded_tuple_buffer%4#0 elements_to_encode%3#0) + let tmp%12#0: bytes = (concat 0x151f7c75 encoded_tuple_buffer%5#0) + (log tmp%12#0) + return 1u + block@4: // get_three_route_L39 + let tmp%13#0: uint64 = (txn OnCompletion) + let tmp%14#0: bool = (== tmp%13#0 NoOp) + (assert tmp%14#0) // OnCompletion is not NoOp + let tmp%15#0: uint64 = (txn ApplicationID) + let tmp%16#0: bool = (!= tmp%15#0 0u) + (assert tmp%16#0) // can only call when not creating + let (elements_to_encode%4#0: bytes, elements_to_encode%5#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_three() + let encoded_tuple_buffer%7#0: bytes = (concat 0x elements_to_encode%4#0) + let encoded_tuple_buffer%8#0: bytes = (concat encoded_tuple_buffer%7#0 elements_to_encode%5#0) + let tmp%17#0: bytes = (concat 0x151f7c75 encoded_tuple_buffer%8#0) + (log tmp%17#0) + return 1u + block@5: // compare_route_L46 + let tmp%18#0: uint64 = (txn OnCompletion) + let tmp%19#0: bool = (== tmp%18#0 NoOp) + (assert tmp%19#0) // OnCompletion is not NoOp + let tmp%20#0: uint64 = (txn ApplicationID) + let tmp%21#0: bool = (!= tmp%20#0 0u) + (assert tmp%21#0) // can only call when not creating + let to_encode%0#0: bool = test_cases.struct_by_name.contract.DemoContract.compare() + let encoded_bool%0#0: bytes = (setbit 0x00 0u to_encode%0#0) + let tmp%22#0: bytes = (concat 0x151f7c75 encoded_bool%0#0) + (log tmp%22#0) + return 1u + block@6: // switch_case_default_L18 + goto block@7 + block@7: // switch_case_next_L18 + goto block@12 + block@8: // bare_routing_L18 + let tmp%23#0: uint64 = (txn OnCompletion) + switch tmp%23#0 {0u => block@9, * => block@10} + block@9: // __algopy_default_create_L1 + let tmp%24#0: uint64 = (txn ApplicationID) + let tmp%25#0: bool = (== tmp%24#0 0u) + (assert tmp%25#0) // can only call when creating + test_cases.struct_by_name.contract.DemoContract.__algopy_default_create() + return 1u + block@10: // switch_case_default_L18 + goto block@11 + block@11: // switch_case_next_L18 + goto block@12 + block@12: // after_if_else_L18 + return 0u + + subroutine test_cases.struct_by_name.contract.DemoContract.get_one() -> : + block@0: // L25 + return 0x01 0x01 + + subroutine test_cases.struct_by_name.contract.DemoContract.get_two() -> : + block@0: // L32 + return 0x01 0x01 + + subroutine test_cases.struct_by_name.contract.DemoContract.get_three() -> : + block@0: // L39 + return 0x01 0x01 + + subroutine test_cases.struct_by_name.contract.DemoContract.compare() -> bool: + block@0: // L46 + let (awst_tmp%0#0: bytes, awst_tmp%1#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_one() + let reinterpret_biguint%0#0: biguint = awst_tmp%0#0 + let (awst_tmp%2#0: bytes, awst_tmp%3#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_two() + let reinterpret_biguint%1#0: biguint = awst_tmp%2#0 + let tmp%0#0: bool = (b== reinterpret_biguint%0#0 reinterpret_biguint%1#0) + let reinterpret_biguint%2#0: biguint = awst_tmp%1#0 + let reinterpret_biguint%3#0: biguint = awst_tmp%3#0 + let tmp%1#0: bool = (b== reinterpret_biguint%2#0 reinterpret_biguint%3#0) + let tmp%2#0: bool = (&& tmp%0#0 tmp%1#0) + goto tmp%2#0 ? block@1 : block@3 + block@1: // and_contd_L48 + let (awst_tmp%4#0: bytes, awst_tmp%5#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_two() + let reinterpret_biguint%4#0: biguint = awst_tmp%4#0 + let (awst_tmp%6#0: bytes, awst_tmp%7#0: bytes) = test_cases.struct_by_name.contract.DemoContract.get_three() + let reinterpret_biguint%5#0: biguint = awst_tmp%6#0 + let tmp%3#0: bool = (b== reinterpret_biguint%4#0 reinterpret_biguint%5#0) + let reinterpret_biguint%6#0: biguint = awst_tmp%5#0 + let reinterpret_biguint%7#0: biguint = awst_tmp%7#0 + let tmp%4#0: bool = (b== reinterpret_biguint%6#0 reinterpret_biguint%7#0) + let tmp%5#0: bool = (&& tmp%3#0 tmp%4#0) + goto tmp%5#0 ? block@2 : block@3 + block@2: // bool_true_L48 + let and_result%0#0: bool = 1u + goto block@4 + block@3: // bool_false_L48 + let and_result%0#0: bool = 0u + goto block@4 + block@4: // bool_merge_L48 + return and_result%0#0 + + subroutine test_cases.struct_by_name.contract.DemoContract.__algopy_default_create() -> void: + block@0: // L1 + return + + program clear-state: + subroutine algopy.arc4.ARC4Contract.clear_state_program() -> bool: + block@0: // L1 + return 1u \ No newline at end of file diff --git a/test_cases/struct_by_name/puya.log b/test_cases/struct_by_name/puya.log new file mode 100644 index 0000000000..4ef0a136cd --- /dev/null +++ b/test_cases/struct_by_name/puya.log @@ -0,0 +1,925 @@ +debug: PuyaPyOptions(output_teal=True, output_source_map=True, output_arc32=True, output_arc56=True, output_ssa_ir=True, output_optimization_ir=True, output_destructured_ir=True, output_memory_ir=True, output_bytecode=True, debug_level=1, optimization_level=1, target_avm_version=10, cli_template_definitions={}, template_vars_prefix='TMPL_', locals_coalescing_strategy=, paths=['struct_by_name'], output_awst=True, output_awst_json=False, output_client=True, log_level=) +info: Found python prefix: /.venv +info: writing struct_by_name/out/module.awst +debug: Sealing block@0: // L12 +debug: Terminated block@0: // L12 +debug: Looking for 'required_budget_with_buffer' in an unsealed block creating an incomplete Phi: block@1: // while_top_L20 +debug: Created Phi assignment: let required_budget_with_buffer#1: uint64 = undefined while trying to resolve 'required_budget_with_buffer' in block@1: // while_top_L20 +debug: Terminated block@1: // while_top_L20 +debug: Sealing block@2: // while_body_L21 +debug: Looking for 'fee_source' in an unsealed block creating an incomplete Phi: block@1: // while_top_L20 +debug: Created Phi assignment: let fee_source#1: uint64 = undefined while trying to resolve 'fee_source' in block@1: // while_top_L20 +debug: Terminated block@2: // while_body_L21 +debug: Sealing block@3: // switch_case_0_L28 +debug: Terminated block@3: // switch_case_0_L28 +debug: Sealing block@4: // switch_case_1_L30 +debug: Terminated block@4: // switch_case_1_L30 +debug: Sealing block@5: // switch_case_default_L26 +debug: Terminated block@5: // switch_case_default_L26 +debug: Sealing block@6: // switch_case_next_L26 +debug: Terminated block@6: // switch_case_next_L26 +debug: Sealing block@1: // while_top_L20 +debug: Added required_budget_with_buffer#0 to Phi node: let required_budget_with_buffer#1: uint64 = φ(required_budget_with_buffer#0 <- block@0) in block@0: // L12 +debug: Created Phi assignment: let required_budget_with_buffer#2: uint64 = undefined while trying to resolve 'required_budget_with_buffer' in block@6: // switch_case_next_L26 +debug: Added required_budget_with_buffer#1 to Phi node: let required_budget_with_buffer#2: uint64 = φ(required_budget_with_buffer#1 <- block@3) in block@3: // switch_case_0_L28 +debug: Added required_budget_with_buffer#1 to Phi node: let required_budget_with_buffer#2: uint64 = φ(required_budget_with_buffer#1 <- block@3, required_budget_with_buffer#1 <- block@4) in block@4: // switch_case_1_L30 +debug: Added required_budget_with_buffer#1 to Phi node: let required_budget_with_buffer#2: uint64 = φ(required_budget_with_buffer#1 <- block@3, required_budget_with_buffer#1 <- block@4, required_budget_with_buffer#1 <- block@5) in block@5: // switch_case_default_L26 +debug: Replacing trivial Phi node: let required_budget_with_buffer#2: uint64 = φ(required_budget_with_buffer#1 <- block@3, required_budget_with_buffer#1 <- block@4, required_budget_with_buffer#1 <- block@5) (required_budget_with_buffer#2) with required_budget_with_buffer#1 +debug: Deleting Phi assignment: let required_budget_with_buffer#2: uint64 = φ(required_budget_with_buffer#1 <- block@3, required_budget_with_buffer#1 <- block@4, required_budget_with_buffer#1 <- block@5) +debug: Replaced trivial Phi node: let required_budget_with_buffer#2: uint64 = φ(required_budget_with_buffer#1 <- block@3, required_budget_with_buffer#1 <- block@4, required_budget_with_buffer#1 <- block@5) (required_budget_with_buffer#2) with required_budget_with_buffer#1 in current definition for 1 blocks +debug: Added required_budget_with_buffer#1 to Phi node: let required_budget_with_buffer#1: uint64 = φ(required_budget_with_buffer#0 <- block@0, required_budget_with_buffer#1 <- block@6) in block@6: // switch_case_next_L26 +debug: Replacing trivial Phi node: let required_budget_with_buffer#1: uint64 = φ(required_budget_with_buffer#0 <- block@0, required_budget_with_buffer#1 <- block@6) (required_budget_with_buffer#1) with required_budget_with_buffer#0 +debug: Deleting Phi assignment: let required_budget_with_buffer#1: uint64 = φ(required_budget_with_buffer#0 <- block@0, required_budget_with_buffer#1 <- block@6) +debug: Replaced trivial Phi node: let required_budget_with_buffer#1: uint64 = φ(required_budget_with_buffer#0 <- block@0, required_budget_with_buffer#1 <- block@6) (required_budget_with_buffer#1) with required_budget_with_buffer#0 in current definition for 6 blocks +debug: Added fee_source#0 to Phi node: let fee_source#1: uint64 = φ(fee_source#0 <- block@0) in block@0: // L12 +debug: Created Phi assignment: let fee_source#2: uint64 = undefined while trying to resolve 'fee_source' in block@6: // switch_case_next_L26 +debug: Added fee_source#1 to Phi node: let fee_source#2: uint64 = φ(fee_source#1 <- block@3) in block@3: // switch_case_0_L28 +debug: Added fee_source#1 to Phi node: let fee_source#2: uint64 = φ(fee_source#1 <- block@3, fee_source#1 <- block@4) in block@4: // switch_case_1_L30 +debug: Added fee_source#1 to Phi node: let fee_source#2: uint64 = φ(fee_source#1 <- block@3, fee_source#1 <- block@4, fee_source#1 <- block@5) in block@5: // switch_case_default_L26 +debug: Replacing trivial Phi node: let fee_source#2: uint64 = φ(fee_source#1 <- block@3, fee_source#1 <- block@4, fee_source#1 <- block@5) (fee_source#2) with fee_source#1 +debug: Deleting Phi assignment: let fee_source#2: uint64 = φ(fee_source#1 <- block@3, fee_source#1 <- block@4, fee_source#1 <- block@5) +debug: Replaced trivial Phi node: let fee_source#2: uint64 = φ(fee_source#1 <- block@3, fee_source#1 <- block@4, fee_source#1 <- block@5) (fee_source#2) with fee_source#1 in current definition for 1 blocks +debug: Added fee_source#1 to Phi node: let fee_source#1: uint64 = φ(fee_source#0 <- block@0, fee_source#1 <- block@6) in block@6: // switch_case_next_L26 +debug: Replacing trivial Phi node: let fee_source#1: uint64 = φ(fee_source#0 <- block@0, fee_source#1 <- block@6) (fee_source#1) with fee_source#0 +debug: Deleting Phi assignment: let fee_source#1: uint64 = φ(fee_source#0 <- block@0, fee_source#1 <- block@6) +debug: Replaced trivial Phi node: let fee_source#1: uint64 = φ(fee_source#0 <- block@0, fee_source#1 <- block@6) (fee_source#1) with fee_source#0 in current definition for 6 blocks +debug: Sealing block@7: // after_while_L20 +debug: Terminated block@7: // after_while_L20 +debug: Sealing block@0: // L4 +debug: Terminated block@0: // L4 +debug: Looking for 'start' in an unsealed block creating an incomplete Phi: block@1: // while_top_L11 +debug: Created Phi assignment: let start#1: uint64 = undefined while trying to resolve 'start' in block@1: // while_top_L11 +debug: Looking for 'item' in an unsealed block creating an incomplete Phi: block@1: // while_top_L11 +debug: Created Phi assignment: let item#1: bytes = undefined while trying to resolve 'item' in block@1: // while_top_L11 +debug: Looking for 'sequence' in an unsealed block creating an incomplete Phi: block@1: // while_top_L11 +debug: Created Phi assignment: let sequence#1: bytes = undefined while trying to resolve 'sequence' in block@1: // while_top_L11 +debug: Terminated block@1: // while_top_L11 +debug: Sealing block@2: // while_body_L12 +debug: Terminated block@2: // while_body_L12 +debug: Sealing block@3: // if_body_L13 +debug: Terminated block@3: // if_body_L13 +debug: Sealing block@4: // after_if_else_L12 +debug: Terminated block@4: // after_if_else_L12 +debug: Sealing block@1: // while_top_L11 +debug: Added start#0 to Phi node: let start#1: uint64 = φ(start#0 <- block@0) in block@0: // L4 +debug: Added start#2 to Phi node: let start#1: uint64 = φ(start#0 <- block@0, start#2 <- block@4) in block@4: // after_if_else_L12 +debug: Added item#0 to Phi node: let item#1: bytes = φ(item#0 <- block@0) in block@0: // L4 +debug: Added item#1 to Phi node: let item#1: bytes = φ(item#0 <- block@0, item#1 <- block@4) in block@4: // after_if_else_L12 +debug: Replacing trivial Phi node: let item#1: bytes = φ(item#0 <- block@0, item#1 <- block@4) (item#1) with item#0 +debug: Deleting Phi assignment: let item#1: bytes = φ(item#0 <- block@0, item#1 <- block@4) +debug: Replaced trivial Phi node: let item#1: bytes = φ(item#0 <- block@0, item#1 <- block@4) (item#1) with item#0 in current definition for 3 blocks +debug: Added sequence#0 to Phi node: let sequence#1: bytes = φ(sequence#0 <- block@0) in block@0: // L4 +debug: Added sequence#1 to Phi node: let sequence#1: bytes = φ(sequence#0 <- block@0, sequence#1 <- block@4) in block@4: // after_if_else_L12 +debug: Replacing trivial Phi node: let sequence#1: bytes = φ(sequence#0 <- block@0, sequence#1 <- block@4) (sequence#1) with sequence#0 +debug: Deleting Phi assignment: let sequence#1: bytes = φ(sequence#0 <- block@0, sequence#1 <- block@4) +debug: Replaced trivial Phi node: let sequence#1: bytes = φ(sequence#0 <- block@0, sequence#1 <- block@4) (sequence#1) with sequence#0 in current definition for 3 blocks +debug: Sealing block@5: // after_while_L11 +debug: Terminated block@5: // after_while_L11 +debug: Sealing block@0: // L25 +debug: Terminated block@0: // L25 +debug: Sealing block@0: // L44 +debug: Terminated block@0: // L44 +debug: Sealing block@0: // L62 +debug: Terminated block@0: // L62 +debug: Sealing block@0: // L92 +debug: Terminated block@0: // L92 +debug: Looking for 'head_offset' in an unsealed block creating an incomplete Phi: block@1: // for_header_L110 +debug: Created Phi assignment: let head_offset#1: uint64 = undefined while trying to resolve 'head_offset' in block@1: // for_header_L110 +debug: Terminated block@1: // for_header_L110 +debug: Sealing block@2: // for_body_L111 +debug: Looking for 'head_and_tail' in an unsealed block creating an incomplete Phi: block@1: // for_header_L110 +debug: Created Phi assignment: let head_and_tail#1: bytes = undefined while trying to resolve 'head_and_tail' in block@1: // for_header_L110 +debug: Looking for 'new_head' in an unsealed block creating an incomplete Phi: block@1: // for_header_L110 +debug: Created Phi assignment: let new_head#1: bytes = undefined while trying to resolve 'new_head' in block@1: // for_header_L110 +debug: Terminated block@2: // for_body_L111 +debug: Sealing block@3: // for_footer_L110 +debug: Terminated block@3: // for_footer_L110 +debug: Sealing block@1: // for_header_L110 +debug: Added head_offset#0 to Phi node: let head_offset#1: uint64 = φ(head_offset#0 <- block@0) in block@0: // L92 +debug: Added head_offset#2 to Phi node: let head_offset#1: uint64 = φ(head_offset#0 <- block@0, head_offset#2 <- block@3) in block@3: // for_footer_L110 +debug: Added head_and_tail#0 to Phi node: let head_and_tail#1: bytes = φ(head_and_tail#0 <- block@0) in block@0: // L92 +debug: Added head_and_tail#1 to Phi node: let head_and_tail#1: bytes = φ(head_and_tail#0 <- block@0, head_and_tail#1 <- block@3) in block@3: // for_footer_L110 +debug: Replacing trivial Phi node: let head_and_tail#1: bytes = φ(head_and_tail#0 <- block@0, head_and_tail#1 <- block@3) (head_and_tail#1) with head_and_tail#0 +debug: Deleting Phi assignment: let head_and_tail#1: bytes = φ(head_and_tail#0 <- block@0, head_and_tail#1 <- block@3) +debug: Replaced trivial Phi node: let head_and_tail#1: bytes = φ(head_and_tail#0 <- block@0, head_and_tail#1 <- block@3) (head_and_tail#1) with head_and_tail#0 in current definition for 3 blocks +debug: Added new_head#0 to Phi node: let new_head#1: bytes = φ(new_head#0 <- block@0) in block@0: // L92 +debug: Added new_head#2 to Phi node: let new_head#1: bytes = φ(new_head#0 <- block@0, new_head#2 <- block@3) in block@3: // for_footer_L110 +debug: Sealing block@4: // after_for_L110 +debug: Created Phi assignment: let length_minus_1#1: uint64 = undefined while trying to resolve 'length_minus_1' in block@1: // for_header_L110 +debug: Added length_minus_1#0 to Phi node: let length_minus_1#1: uint64 = φ(length_minus_1#0 <- block@0) in block@0: // L92 +debug: Added length_minus_1#1 to Phi node: let length_minus_1#1: uint64 = φ(length_minus_1#0 <- block@0, length_minus_1#1 <- block@3) in block@3: // for_footer_L110 +debug: Replacing trivial Phi node: let length_minus_1#1: uint64 = φ(length_minus_1#0 <- block@0, length_minus_1#1 <- block@3) (length_minus_1#1) with length_minus_1#0 +debug: Deleting Phi assignment: let length_minus_1#1: uint64 = φ(length_minus_1#0 <- block@0, length_minus_1#1 <- block@3) +debug: Replaced trivial Phi node: let length_minus_1#1: uint64 = φ(length_minus_1#0 <- block@0, length_minus_1#1 <- block@3) (length_minus_1#1) with length_minus_1#0 in current definition for 3 blocks +debug: Created Phi assignment: let popped_header_offset#1: uint64 = undefined while trying to resolve 'popped_header_offset' in block@1: // for_header_L110 +debug: Added popped_header_offset#0 to Phi node: let popped_header_offset#1: uint64 = φ(popped_header_offset#0 <- block@0) in block@0: // L92 +debug: Added popped_header_offset#1 to Phi node: let popped_header_offset#1: uint64 = φ(popped_header_offset#0 <- block@0, popped_header_offset#1 <- block@3) in block@3: // for_footer_L110 +debug: Replacing trivial Phi node: let popped_header_offset#1: uint64 = φ(popped_header_offset#0 <- block@0, popped_header_offset#1 <- block@3) (popped_header_offset#1) with popped_header_offset#0 +debug: Deleting Phi assignment: let popped_header_offset#1: uint64 = φ(popped_header_offset#0 <- block@0, popped_header_offset#1 <- block@3) +debug: Replaced trivial Phi node: let popped_header_offset#1: uint64 = φ(popped_header_offset#0 <- block@0, popped_header_offset#1 <- block@3) (popped_header_offset#1) with popped_header_offset#0 in current definition for 3 blocks +debug: Created Phi assignment: let popped_offset#1: uint64 = undefined while trying to resolve 'popped_offset' in block@1: // for_header_L110 +debug: Added popped_offset#0 to Phi node: let popped_offset#1: uint64 = φ(popped_offset#0 <- block@0) in block@0: // L92 +debug: Added popped_offset#1 to Phi node: let popped_offset#1: uint64 = φ(popped_offset#0 <- block@0, popped_offset#1 <- block@3) in block@3: // for_footer_L110 +debug: Replacing trivial Phi node: let popped_offset#1: uint64 = φ(popped_offset#0 <- block@0, popped_offset#1 <- block@3) (popped_offset#1) with popped_offset#0 +debug: Deleting Phi assignment: let popped_offset#1: uint64 = φ(popped_offset#0 <- block@0, popped_offset#1 <- block@3) +debug: Replaced trivial Phi node: let popped_offset#1: uint64 = φ(popped_offset#0 <- block@0, popped_offset#1 <- block@3) (popped_offset#1) with popped_offset#0 in current definition for 3 blocks +debug: Created Phi assignment: let popped#1: bytes = undefined while trying to resolve 'popped' in block@1: // for_header_L110 +debug: Added popped#0 to Phi node: let popped#1: bytes = φ(popped#0 <- block@0) in block@0: // L92 +debug: Added popped#1 to Phi node: let popped#1: bytes = φ(popped#0 <- block@0, popped#1 <- block@3) in block@3: // for_footer_L110 +debug: Replacing trivial Phi node: let popped#1: bytes = φ(popped#0 <- block@0, popped#1 <- block@3) (popped#1) with popped#0 +debug: Deleting Phi assignment: let popped#1: bytes = φ(popped#0 <- block@0, popped#1 <- block@3) +debug: Replaced trivial Phi node: let popped#1: bytes = φ(popped#0 <- block@0, popped#1 <- block@3) (popped#1) with popped#0 in current definition for 3 blocks +debug: Terminated block@4: // after_for_L110 +debug: Sealing block@0: // L124 +debug: Terminated block@0: // L124 +debug: Sealing block@1: // if_body_L147 +debug: Terminated block@1: // if_body_L147 +debug: Sealing block@2: // after_if_else_L146 +debug: Created Phi assignment: let array_length#1: uint64 = undefined while trying to resolve 'array_length' in block@2: // after_if_else_L146 +debug: Added array_length#0 to Phi node: let array_length#1: uint64 = φ(array_length#0 <- block@0) in block@0: // L124 +debug: Added array_length#0 to Phi node: let array_length#1: uint64 = φ(array_length#0 <- block@0, array_length#0 <- block@1) in block@1: // if_body_L147 +debug: Replacing trivial Phi node: let array_length#1: uint64 = φ(array_length#0 <- block@0, array_length#0 <- block@1) (array_length#1) with array_length#0 +debug: Deleting Phi assignment: let array_length#1: uint64 = φ(array_length#0 <- block@0, array_length#0 <- block@1) +debug: Replaced trivial Phi node: let array_length#1: uint64 = φ(array_length#0 <- block@0, array_length#0 <- block@1) (array_length#1) with array_length#0 in current definition for 1 blocks +debug: Created Phi assignment: let is_packed#1: bool = undefined while trying to resolve 'is_packed' in block@2: // after_if_else_L146 +debug: Added is_packed#0 to Phi node: let is_packed#1: bool = φ(is_packed#0 <- block@0) in block@0: // L124 +debug: Added is_packed#0 to Phi node: let is_packed#1: bool = φ(is_packed#0 <- block@0, is_packed#0 <- block@1) in block@1: // if_body_L147 +debug: Replacing trivial Phi node: let is_packed#1: bool = φ(is_packed#0 <- block@0, is_packed#0 <- block@1) (is_packed#1) with is_packed#0 +debug: Deleting Phi assignment: let is_packed#1: bool = φ(is_packed#0 <- block@0, is_packed#0 <- block@1) +debug: Replaced trivial Phi node: let is_packed#1: bool = φ(is_packed#0 <- block@0, is_packed#0 <- block@1) (is_packed#1) with is_packed#0 in current definition for 1 blocks +debug: Created Phi assignment: let new_items_count#1: uint64 = undefined while trying to resolve 'new_items_count' in block@2: // after_if_else_L146 +debug: Added new_items_count#0 to Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0) in block@0: // L124 +debug: Added new_items_count#0 to Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0, new_items_count#0 <- block@1) in block@1: // if_body_L147 +debug: Replacing trivial Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0, new_items_count#0 <- block@1) (new_items_count#1) with new_items_count#0 +debug: Deleting Phi assignment: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0, new_items_count#0 <- block@1) +debug: Replaced trivial Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0, new_items_count#0 <- block@1) (new_items_count#1) with new_items_count#0 in current definition for 1 blocks +debug: Terminated block@2: // after_if_else_L146 +debug: Looking for 'i' in an unsealed block creating an incomplete Phi: block@3: // for_header_L150 +debug: Created Phi assignment: let i#1: uint64 = undefined while trying to resolve 'i' in block@3: // for_header_L150 +debug: Terminated block@3: // for_header_L150 +debug: Sealing block@4: // for_body_L151 +debug: Looking for 'result' in an unsealed block creating an incomplete Phi: block@3: // for_header_L150 +debug: Created Phi assignment: let result#2: bytes = undefined while trying to resolve 'result' in block@3: // for_header_L150 +debug: Looking for 'write_offset' in an unsealed block creating an incomplete Phi: block@3: // for_header_L150 +debug: Created Phi assignment: let write_offset#1: uint64 = undefined while trying to resolve 'write_offset' in block@3: // for_header_L150 +debug: Looking for 'new_items_bytes' in an unsealed block creating an incomplete Phi: block@3: // for_header_L150 +debug: Created Phi assignment: let new_items_bytes#1: bytes = undefined while trying to resolve 'new_items_bytes' in block@3: // for_header_L150 +debug: Terminated block@4: // for_body_L151 +debug: Sealing block@5: // for_footer_L150 +debug: Terminated block@5: // for_footer_L150 +debug: Sealing block@3: // for_header_L150 +debug: Added i#0 to Phi node: let i#1: uint64 = φ(i#0 <- block@2) in block@2: // after_if_else_L146 +debug: Added i#2 to Phi node: let i#1: uint64 = φ(i#0 <- block@2, i#2 <- block@5) in block@5: // for_footer_L150 +debug: Created Phi assignment: let result#4: bytes = undefined while trying to resolve 'result' in block@2: // after_if_else_L146 +debug: Added result#0 to Phi node: let result#4: bytes = φ(result#0 <- block@0) in block@0: // L124 +debug: Added result#1 to Phi node: let result#4: bytes = φ(result#0 <- block@0, result#1 <- block@1) in block@1: // if_body_L147 +debug: Added result#4 to Phi node: let result#2: bytes = φ(result#4 <- block@2) in block@2: // after_if_else_L146 +debug: Added result#3 to Phi node: let result#2: bytes = φ(result#4 <- block@2, result#3 <- block@5) in block@5: // for_footer_L150 +debug: Added write_offset#0 to Phi node: let write_offset#1: uint64 = φ(write_offset#0 <- block@2) in block@2: // after_if_else_L146 +debug: Added write_offset#2 to Phi node: let write_offset#1: uint64 = φ(write_offset#0 <- block@2, write_offset#2 <- block@5) in block@5: // for_footer_L150 +debug: Created Phi assignment: let new_items_bytes#2: bytes = undefined while trying to resolve 'new_items_bytes' in block@2: // after_if_else_L146 +debug: Added new_items_bytes#0 to Phi node: let new_items_bytes#2: bytes = φ(new_items_bytes#0 <- block@0) in block@0: // L124 +debug: Added new_items_bytes#0 to Phi node: let new_items_bytes#2: bytes = φ(new_items_bytes#0 <- block@0, new_items_bytes#0 <- block@1) in block@1: // if_body_L147 +debug: Replacing trivial Phi node: let new_items_bytes#2: bytes = φ(new_items_bytes#0 <- block@0, new_items_bytes#0 <- block@1) (new_items_bytes#2) with new_items_bytes#0 +debug: Deleting Phi assignment: let new_items_bytes#2: bytes = φ(new_items_bytes#0 <- block@0, new_items_bytes#0 <- block@1) +debug: Replaced trivial Phi node: let new_items_bytes#2: bytes = φ(new_items_bytes#0 <- block@0, new_items_bytes#0 <- block@1) (new_items_bytes#2) with new_items_bytes#0 in current definition for 1 blocks +debug: Added new_items_bytes#0 to Phi node: let new_items_bytes#1: bytes = φ(new_items_bytes#0 <- block@2) in block@2: // after_if_else_L146 +debug: Added new_items_bytes#1 to Phi node: let new_items_bytes#1: bytes = φ(new_items_bytes#0 <- block@2, new_items_bytes#1 <- block@5) in block@5: // for_footer_L150 +debug: Replacing trivial Phi node: let new_items_bytes#1: bytes = φ(new_items_bytes#0 <- block@2, new_items_bytes#1 <- block@5) (new_items_bytes#1) with new_items_bytes#0 +debug: Deleting Phi assignment: let new_items_bytes#1: bytes = φ(new_items_bytes#0 <- block@2, new_items_bytes#1 <- block@5) +debug: Replaced trivial Phi node: let new_items_bytes#1: bytes = φ(new_items_bytes#0 <- block@2, new_items_bytes#1 <- block@5) (new_items_bytes#1) with new_items_bytes#0 in current definition for 3 blocks +debug: Sealing block@6: // after_for_L150 +debug: Terminated block@6: // after_for_L150 +debug: Sealing block@0: // L157 +debug: Terminated block@0: // L157 +debug: Sealing block@0: // L189 +debug: Terminated block@0: // L189 +debug: Looking for 'head_offset' in an unsealed block creating an incomplete Phi: block@1: // for_header_L199 +debug: Created Phi assignment: let head_offset#1: uint64 = undefined while trying to resolve 'head_offset' in block@1: // for_header_L199 +debug: Terminated block@1: // for_header_L199 +debug: Sealing block@2: // for_body_L200 +debug: Looking for 'array_head_and_tail' in an unsealed block creating an incomplete Phi: block@1: // for_header_L199 +debug: Created Phi assignment: let array_head_and_tail#1: bytes = undefined while trying to resolve 'array_head_and_tail' in block@1: // for_header_L199 +debug: Looking for 'new_head' in an unsealed block creating an incomplete Phi: block@1: // for_header_L199 +debug: Created Phi assignment: let new_head#1: bytes = undefined while trying to resolve 'new_head' in block@1: // for_header_L199 +debug: Looking for 'item_offset_adjustment' in an unsealed block creating an incomplete Phi: block@1: // for_header_L199 +debug: Created Phi assignment: let item_offset_adjustment#1: uint64 = undefined while trying to resolve 'item_offset_adjustment' in block@1: // for_header_L199 +debug: Terminated block@2: // for_body_L200 +debug: Sealing block@3: // for_footer_L199 +debug: Terminated block@3: // for_footer_L199 +debug: Sealing block@1: // for_header_L199 +debug: Added head_offset#0 to Phi node: let head_offset#1: uint64 = φ(head_offset#0 <- block@0) in block@0: // L189 +debug: Added head_offset#2 to Phi node: let head_offset#1: uint64 = φ(head_offset#0 <- block@0, head_offset#2 <- block@3) in block@3: // for_footer_L199 +debug: Added array_head_and_tail#0 to Phi node: let array_head_and_tail#1: bytes = φ(array_head_and_tail#0 <- block@0) in block@0: // L189 +debug: Added array_head_and_tail#1 to Phi node: let array_head_and_tail#1: bytes = φ(array_head_and_tail#0 <- block@0, array_head_and_tail#1 <- block@3) in block@3: // for_footer_L199 +debug: Replacing trivial Phi node: let array_head_and_tail#1: bytes = φ(array_head_and_tail#0 <- block@0, array_head_and_tail#1 <- block@3) (array_head_and_tail#1) with array_head_and_tail#0 +debug: Deleting Phi assignment: let array_head_and_tail#1: bytes = φ(array_head_and_tail#0 <- block@0, array_head_and_tail#1 <- block@3) +debug: Replaced trivial Phi node: let array_head_and_tail#1: bytes = φ(array_head_and_tail#0 <- block@0, array_head_and_tail#1 <- block@3) (array_head_and_tail#1) with array_head_and_tail#0 in current definition for 3 blocks +debug: Added new_head#0 to Phi node: let new_head#1: bytes = φ(new_head#0 <- block@0) in block@0: // L189 +debug: Added new_head#2 to Phi node: let new_head#1: bytes = φ(new_head#0 <- block@0, new_head#2 <- block@3) in block@3: // for_footer_L199 +debug: Added item_offset_adjustment#0 to Phi node: let item_offset_adjustment#1: uint64 = φ(item_offset_adjustment#0 <- block@0) in block@0: // L189 +debug: Added item_offset_adjustment#1 to Phi node: let item_offset_adjustment#1: uint64 = φ(item_offset_adjustment#0 <- block@0, item_offset_adjustment#1 <- block@3) in block@3: // for_footer_L199 +debug: Replacing trivial Phi node: let item_offset_adjustment#1: uint64 = φ(item_offset_adjustment#0 <- block@0, item_offset_adjustment#1 <- block@3) (item_offset_adjustment#1) with item_offset_adjustment#0 +debug: Deleting Phi assignment: let item_offset_adjustment#1: uint64 = φ(item_offset_adjustment#0 <- block@0, item_offset_adjustment#1 <- block@3) +debug: Replaced trivial Phi node: let item_offset_adjustment#1: uint64 = φ(item_offset_adjustment#0 <- block@0, item_offset_adjustment#1 <- block@3) (item_offset_adjustment#1) with item_offset_adjustment#0 in current definition for 3 blocks +debug: Sealing block@4: // after_for_L199 +debug: Created Phi assignment: let new_items_count#1: uint64 = undefined while trying to resolve 'new_items_count' in block@1: // for_header_L199 +debug: Added new_items_count#0 to Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0) in block@0: // L189 +debug: Added new_items_count#1 to Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0, new_items_count#1 <- block@3) in block@3: // for_footer_L199 +debug: Replacing trivial Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0, new_items_count#1 <- block@3) (new_items_count#1) with new_items_count#0 +debug: Deleting Phi assignment: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0, new_items_count#1 <- block@3) +debug: Replaced trivial Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0, new_items_count#1 <- block@3) (new_items_count#1) with new_items_count#0 in current definition for 3 blocks +debug: Terminated block@4: // after_for_L199 +debug: Looking for 'head_offset' in an unsealed block creating an incomplete Phi: block@5: // for_header_L204 +debug: Created Phi assignment: let head_offset#4: uint64 = undefined while trying to resolve 'head_offset' in block@5: // for_header_L204 +debug: Terminated block@5: // for_header_L204 +debug: Sealing block@6: // for_body_L205 +debug: Looking for 'new_head_and_tail' in an unsealed block creating an incomplete Phi: block@5: // for_header_L204 +debug: Created Phi assignment: let new_head_and_tail#1: bytes = undefined while trying to resolve 'new_head_and_tail' in block@5: // for_header_L204 +debug: Looking for 'new_head' in an unsealed block creating an incomplete Phi: block@5: // for_header_L204 +debug: Created Phi assignment: let new_head#3: bytes = undefined while trying to resolve 'new_head' in block@5: // for_header_L204 +debug: Looking for 'item_offset_adjustment' in an unsealed block creating an incomplete Phi: block@5: // for_header_L204 +debug: Created Phi assignment: let item_offset_adjustment#3: uint64 = undefined while trying to resolve 'item_offset_adjustment' in block@5: // for_header_L204 +debug: Terminated block@6: // for_body_L205 +debug: Sealing block@7: // for_footer_L204 +debug: Terminated block@7: // for_footer_L204 +debug: Sealing block@5: // for_header_L204 +debug: Added head_offset#3 to Phi node: let head_offset#4: uint64 = φ(head_offset#3 <- block@4) in block@4: // after_for_L199 +debug: Added head_offset#5 to Phi node: let head_offset#4: uint64 = φ(head_offset#3 <- block@4, head_offset#5 <- block@7) in block@7: // for_footer_L204 +debug: Created Phi assignment: let new_head_and_tail#2: bytes = undefined while trying to resolve 'new_head_and_tail' in block@1: // for_header_L199 +debug: Added new_head_and_tail#0 to Phi node: let new_head_and_tail#2: bytes = φ(new_head_and_tail#0 <- block@0) in block@0: // L189 +debug: Added new_head_and_tail#2 to Phi node: let new_head_and_tail#2: bytes = φ(new_head_and_tail#0 <- block@0, new_head_and_tail#2 <- block@3) in block@3: // for_footer_L199 +debug: Replacing trivial Phi node: let new_head_and_tail#2: bytes = φ(new_head_and_tail#0 <- block@0, new_head_and_tail#2 <- block@3) (new_head_and_tail#2) with new_head_and_tail#0 +debug: Deleting Phi assignment: let new_head_and_tail#2: bytes = φ(new_head_and_tail#0 <- block@0, new_head_and_tail#2 <- block@3) +debug: Replaced trivial Phi node: let new_head_and_tail#2: bytes = φ(new_head_and_tail#0 <- block@0, new_head_and_tail#2 <- block@3) (new_head_and_tail#2) with new_head_and_tail#0 in current definition for 3 blocks +debug: Added new_head_and_tail#0 to Phi node: let new_head_and_tail#1: bytes = φ(new_head_and_tail#0 <- block@4) in block@4: // after_for_L199 +debug: Added new_head_and_tail#1 to Phi node: let new_head_and_tail#1: bytes = φ(new_head_and_tail#0 <- block@4, new_head_and_tail#1 <- block@7) in block@7: // for_footer_L204 +debug: Replacing trivial Phi node: let new_head_and_tail#1: bytes = φ(new_head_and_tail#0 <- block@4, new_head_and_tail#1 <- block@7) (new_head_and_tail#1) with new_head_and_tail#0 +debug: Deleting Phi assignment: let new_head_and_tail#1: bytes = φ(new_head_and_tail#0 <- block@4, new_head_and_tail#1 <- block@7) +debug: Replaced trivial Phi node: let new_head_and_tail#1: bytes = φ(new_head_and_tail#0 <- block@4, new_head_and_tail#1 <- block@7) (new_head_and_tail#1) with new_head_and_tail#0 in current definition for 3 blocks +debug: Added new_head#1 to Phi node: let new_head#3: bytes = φ(new_head#1 <- block@4) in block@4: // after_for_L199 +debug: Added new_head#4 to Phi node: let new_head#3: bytes = φ(new_head#1 <- block@4, new_head#4 <- block@7) in block@7: // for_footer_L204 +debug: Added item_offset_adjustment#2 to Phi node: let item_offset_adjustment#3: uint64 = φ(item_offset_adjustment#2 <- block@4) in block@4: // after_for_L199 +debug: Added item_offset_adjustment#3 to Phi node: let item_offset_adjustment#3: uint64 = φ(item_offset_adjustment#2 <- block@4, item_offset_adjustment#3 <- block@7) in block@7: // for_footer_L204 +debug: Replacing trivial Phi node: let item_offset_adjustment#3: uint64 = φ(item_offset_adjustment#2 <- block@4, item_offset_adjustment#3 <- block@7) (item_offset_adjustment#3) with item_offset_adjustment#2 +debug: Deleting Phi assignment: let item_offset_adjustment#3: uint64 = φ(item_offset_adjustment#2 <- block@4, item_offset_adjustment#3 <- block@7) +debug: Replaced trivial Phi node: let item_offset_adjustment#3: uint64 = φ(item_offset_adjustment#2 <- block@4, item_offset_adjustment#3 <- block@7) (item_offset_adjustment#3) with item_offset_adjustment#2 in current definition for 3 blocks +debug: Sealing block@8: // after_for_L204 +debug: Created Phi assignment: let array_items_count#1: uint64 = undefined while trying to resolve 'array_items_count' in block@5: // for_header_L204 +debug: Created Phi assignment: let array_items_count#2: uint64 = undefined while trying to resolve 'array_items_count' in block@1: // for_header_L199 +debug: Added array_items_count#0 to Phi node: let array_items_count#2: uint64 = φ(array_items_count#0 <- block@0) in block@0: // L189 +debug: Added array_items_count#2 to Phi node: let array_items_count#2: uint64 = φ(array_items_count#0 <- block@0, array_items_count#2 <- block@3) in block@3: // for_footer_L199 +debug: Replacing trivial Phi node: let array_items_count#2: uint64 = φ(array_items_count#0 <- block@0, array_items_count#2 <- block@3) (array_items_count#2) with array_items_count#0 +debug: Deleting Phi assignment: let array_items_count#2: uint64 = φ(array_items_count#0 <- block@0, array_items_count#2 <- block@3) +debug: Replaced trivial Phi node: let array_items_count#2: uint64 = φ(array_items_count#0 <- block@0, array_items_count#2 <- block@3) (array_items_count#2) with array_items_count#0 in current definition for 3 blocks +debug: Added array_items_count#0 to Phi node: let array_items_count#1: uint64 = φ(array_items_count#0 <- block@4) in block@4: // after_for_L199 +debug: Added array_items_count#1 to Phi node: let array_items_count#1: uint64 = φ(array_items_count#0 <- block@4, array_items_count#1 <- block@7) in block@7: // for_footer_L204 +debug: Replacing trivial Phi node: let array_items_count#1: uint64 = φ(array_items_count#0 <- block@4, array_items_count#1 <- block@7) (array_items_count#1) with array_items_count#0 +debug: Deleting Phi assignment: let array_items_count#1: uint64 = φ(array_items_count#0 <- block@4, array_items_count#1 <- block@7) +debug: Replaced trivial Phi node: let array_items_count#1: uint64 = φ(array_items_count#0 <- block@4, array_items_count#1 <- block@7) (array_items_count#1) with array_items_count#0 in current definition for 3 blocks +debug: Created Phi assignment: let new_items_count#2: uint64 = undefined while trying to resolve 'new_items_count' in block@5: // for_header_L204 +debug: Added new_items_count#0 to Phi node: let new_items_count#2: uint64 = φ(new_items_count#0 <- block@4) in block@4: // after_for_L199 +debug: Added new_items_count#2 to Phi node: let new_items_count#2: uint64 = φ(new_items_count#0 <- block@4, new_items_count#2 <- block@7) in block@7: // for_footer_L204 +debug: Replacing trivial Phi node: let new_items_count#2: uint64 = φ(new_items_count#0 <- block@4, new_items_count#2 <- block@7) (new_items_count#2) with new_items_count#0 +debug: Deleting Phi assignment: let new_items_count#2: uint64 = φ(new_items_count#0 <- block@4, new_items_count#2 <- block@7) +debug: Replaced trivial Phi node: let new_items_count#2: uint64 = φ(new_items_count#0 <- block@4, new_items_count#2 <- block@7) (new_items_count#2) with new_items_count#0 in current definition for 3 blocks +debug: Created Phi assignment: let array_head_and_tail#2: bytes = undefined while trying to resolve 'array_head_and_tail' in block@5: // for_header_L204 +debug: Added array_head_and_tail#0 to Phi node: let array_head_and_tail#2: bytes = φ(array_head_and_tail#0 <- block@4) in block@4: // after_for_L199 +debug: Added array_head_and_tail#2 to Phi node: let array_head_and_tail#2: bytes = φ(array_head_and_tail#0 <- block@4, array_head_and_tail#2 <- block@7) in block@7: // for_footer_L204 +debug: Replacing trivial Phi node: let array_head_and_tail#2: bytes = φ(array_head_and_tail#0 <- block@4, array_head_and_tail#2 <- block@7) (array_head_and_tail#2) with array_head_and_tail#0 +debug: Deleting Phi assignment: let array_head_and_tail#2: bytes = φ(array_head_and_tail#0 <- block@4, array_head_and_tail#2 <- block@7) +debug: Replaced trivial Phi node: let array_head_and_tail#2: bytes = φ(array_head_and_tail#0 <- block@4, array_head_and_tail#2 <- block@7) (array_head_and_tail#2) with array_head_and_tail#0 in current definition for 3 blocks +debug: Terminated block@8: // after_for_L204 +debug: Sealing block@0: // L217 +debug: Terminated block@0: // L217 +debug: Sealing block@0: // L240 +debug: Terminated block@0: // L240 +debug: Sealing block@0: // L252 +debug: Terminated block@0: // L252 +debug: Looking for 'head_offset' in an unsealed block creating an incomplete Phi: block@1: // for_header_L269 +debug: Created Phi assignment: let head_offset#1: uint64 = undefined while trying to resolve 'head_offset' in block@1: // for_header_L269 +debug: Terminated block@1: // for_header_L269 +debug: Sealing block@2: // for_body_L270 +debug: Looking for 'new_head_and_tail' in an unsealed block creating an incomplete Phi: block@1: // for_header_L269 +debug: Created Phi assignment: let new_head_and_tail#1: bytes = undefined while trying to resolve 'new_head_and_tail' in block@1: // for_header_L269 +debug: Looking for 'new_item_length' in an unsealed block creating an incomplete Phi: block@1: // for_header_L269 +debug: Created Phi assignment: let new_item_length#1: uint64 = undefined while trying to resolve 'new_item_length' in block@1: // for_header_L269 +debug: Looking for 'original_item_length' in an unsealed block creating an incomplete Phi: block@1: // for_header_L269 +debug: Created Phi assignment: let original_item_length#1: uint64 = undefined while trying to resolve 'original_item_length' in block@1: // for_header_L269 +debug: Terminated block@2: // for_body_L270 +debug: Sealing block@3: // for_footer_L269 +debug: Terminated block@3: // for_footer_L269 +debug: Sealing block@1: // for_header_L269 +debug: Added head_offset#0 to Phi node: let head_offset#1: uint64 = φ(head_offset#0 <- block@0) in block@0: // L252 +debug: Added head_offset#2 to Phi node: let head_offset#1: uint64 = φ(head_offset#0 <- block@0, head_offset#2 <- block@3) in block@3: // for_footer_L269 +debug: Added new_head_and_tail#0 to Phi node: let new_head_and_tail#1: bytes = φ(new_head_and_tail#0 <- block@0) in block@0: // L252 +debug: Added new_head_and_tail#2 to Phi node: let new_head_and_tail#1: bytes = φ(new_head_and_tail#0 <- block@0, new_head_and_tail#2 <- block@3) in block@3: // for_footer_L269 +debug: Added new_item_length#0 to Phi node: let new_item_length#1: uint64 = φ(new_item_length#0 <- block@0) in block@0: // L252 +debug: Added new_item_length#1 to Phi node: let new_item_length#1: uint64 = φ(new_item_length#0 <- block@0, new_item_length#1 <- block@3) in block@3: // for_footer_L269 +debug: Replacing trivial Phi node: let new_item_length#1: uint64 = φ(new_item_length#0 <- block@0, new_item_length#1 <- block@3) (new_item_length#1) with new_item_length#0 +debug: Deleting Phi assignment: let new_item_length#1: uint64 = φ(new_item_length#0 <- block@0, new_item_length#1 <- block@3) +debug: Replaced trivial Phi node: let new_item_length#1: uint64 = φ(new_item_length#0 <- block@0, new_item_length#1 <- block@3) (new_item_length#1) with new_item_length#0 in current definition for 3 blocks +debug: Added original_item_length#0 to Phi node: let original_item_length#1: uint64 = φ(original_item_length#0 <- block@0) in block@0: // L252 +debug: Added original_item_length#1 to Phi node: let original_item_length#1: uint64 = φ(original_item_length#0 <- block@0, original_item_length#1 <- block@3) in block@3: // for_footer_L269 +debug: Replacing trivial Phi node: let original_item_length#1: uint64 = φ(original_item_length#0 <- block@0, original_item_length#1 <- block@3) (original_item_length#1) with original_item_length#0 +debug: Deleting Phi assignment: let original_item_length#1: uint64 = φ(original_item_length#0 <- block@0, original_item_length#1 <- block@3) +debug: Replaced trivial Phi node: let original_item_length#1: uint64 = φ(original_item_length#0 <- block@0, original_item_length#1 <- block@3) (original_item_length#1) with original_item_length#0 in current definition for 3 blocks +debug: Sealing block@4: // after_for_L269 +debug: Terminated block@4: // after_for_L269 +debug: Sealing block@0: // L278 +debug: Terminated block@0: // L278 +debug: Sealing block@0: // L306 +debug: Terminated block@0: // L306 +debug: Looking for 'head_offset' in an unsealed block creating an incomplete Phi: block@1: // for_header_L327 +debug: Created Phi assignment: let head_offset#1: uint64 = undefined while trying to resolve 'head_offset' in block@1: // for_header_L327 +debug: Terminated block@1: // for_header_L327 +debug: Sealing block@2: // for_body_L328 +debug: Looking for 'tail_offset' in an unsealed block creating an incomplete Phi: block@1: // for_header_L327 +debug: Created Phi assignment: let tail_offset#1: uint64 = undefined while trying to resolve 'tail_offset' in block@1: // for_header_L327 +debug: Looking for 'array_head_and_tail' in an unsealed block creating an incomplete Phi: block@1: // for_header_L327 +debug: Created Phi assignment: let array_head_and_tail#1: bytes = undefined while trying to resolve 'array_head_and_tail' in block@1: // for_header_L327 +debug: Terminated block@2: // for_body_L328 +debug: Sealing block@3: // for_footer_L327 +debug: Terminated block@3: // for_footer_L327 +debug: Sealing block@1: // for_header_L327 +debug: Added head_offset#0 to Phi node: let head_offset#1: uint64 = φ(head_offset#0 <- block@0) in block@0: // L306 +debug: Added head_offset#3 to Phi node: let head_offset#1: uint64 = φ(head_offset#0 <- block@0, head_offset#3 <- block@3) in block@3: // for_footer_L327 +debug: Added tail_offset#0 to Phi node: let tail_offset#1: uint64 = φ(tail_offset#0 <- block@0) in block@0: // L306 +debug: Added tail_offset#2 to Phi node: let tail_offset#1: uint64 = φ(tail_offset#0 <- block@0, tail_offset#2 <- block@3) in block@3: // for_footer_L327 +debug: Added array_head_and_tail#0 to Phi node: let array_head_and_tail#1: bytes = φ(array_head_and_tail#0 <- block@0) in block@0: // L306 +debug: Added array_head_and_tail#2 to Phi node: let array_head_and_tail#1: bytes = φ(array_head_and_tail#0 <- block@0, array_head_and_tail#2 <- block@3) in block@3: // for_footer_L327 +debug: Sealing block@4: // after_for_L327 +debug: Terminated block@4: // after_for_L327 +debug: Sealing block@0: // L18 +debug: Terminated block@0: // L18 +debug: Sealing block@1: // abi_routing_L18 +debug: Terminated block@1: // abi_routing_L18 +debug: Sealing block@2: // get_one_route_L25 +debug: Terminated block@2: // get_one_route_L25 +debug: Sealing block@3: // get_two_route_L32 +debug: Terminated block@3: // get_two_route_L32 +debug: Sealing block@4: // get_three_route_L39 +debug: Terminated block@4: // get_three_route_L39 +debug: Sealing block@5: // compare_route_L46 +debug: Terminated block@5: // compare_route_L46 +debug: Sealing block@6: // switch_case_default_L18 +debug: Terminated block@6: // switch_case_default_L18 +debug: Sealing block@7: // switch_case_next_L18 +debug: Terminated block@7: // switch_case_next_L18 +debug: Sealing block@8: // bare_routing_L18 +debug: Terminated block@8: // bare_routing_L18 +debug: Sealing block@9: // __algopy_default_create_L1 +debug: Terminated block@9: // __algopy_default_create_L1 +debug: Sealing block@10: // switch_case_default_L18 +debug: Terminated block@10: // switch_case_default_L18 +debug: Sealing block@11: // switch_case_next_L18 +debug: Terminated block@11: // switch_case_next_L18 +debug: Sealing block@12: // after_if_else_L18 +debug: Terminated block@12: // after_if_else_L18 +debug: Sealing block@0: // L25 +debug: Terminated block@0: // L25 +debug: Sealing block@0: // L32 +debug: Terminated block@0: // L32 +debug: Sealing block@0: // L39 +debug: Terminated block@0: // L39 +debug: Sealing block@0: // L46 +debug: Terminated block@0: // L46 +debug: Sealing block@1: // and_contd_L48 +debug: Terminated block@1: // and_contd_L48 +debug: Sealing block@2: // bool_true_L48 +debug: Terminated block@2: // bool_true_L48 +debug: Sealing block@3: // bool_false_L48 +debug: Terminated block@3: // bool_false_L48 +debug: Sealing block@4: // bool_merge_L48 +debug: Created Phi assignment: let and_result%0#2: bool = undefined while trying to resolve 'and_result%0' in block@4: // bool_merge_L48 +debug: Added and_result%0#0 to Phi node: let and_result%0#2: bool = φ(and_result%0#0 <- block@2) in block@2: // bool_true_L48 +debug: Added and_result%0#1 to Phi node: let and_result%0#2: bool = φ(and_result%0#0 <- block@2, and_result%0#1 <- block@3) in block@3: // bool_false_L48 +debug: Terminated block@4: // bool_merge_L48 +debug: Sealing block@0: // L1 +debug: Terminated block@0: // L1 +debug: Sealing block@0: // L1 +debug: Terminated block@0: // L1 +debug: Sealing block@0: // L1 +debug: Terminated block@0: // L1 +debug: Output IR to struct_by_name/out/DemoContract.ssa.ir +info: optimizing test_cases.struct_by_name.contract.DemoContract at level 1 +debug: Begin optimization pass 1/100 +debug: Optimizing subroutine algopy.arc4.ARC4Contract.approval_program +debug: Splitting parallel copies prior to optimization +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__ +debug: Splitting parallel copies prior to optimization +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Simplified (== tmp%3#0 NoOp) to (! tmp%3#0) +debug: Simplified (concat 0x elements_to_encode%0#0) to elements_to_encode%0#0 +debug: Simplified (== tmp%8#0 NoOp) to (! tmp%8#0) +debug: Simplified (concat 0x elements_to_encode%2#0) to elements_to_encode%2#0 +debug: Simplified (== tmp%13#0 NoOp) to (! tmp%13#0) +debug: Simplified (concat 0x elements_to_encode%4#0) to elements_to_encode%4#0 +debug: Simplified (== tmp%18#0 NoOp) to (! tmp%18#0) +debug: Simplified (== tmp%24#0 0u) to (! tmp%24#0) +debug: Optimizer: Remove Unused Variables +debug: Removing unused variable tmp%1#0 +debug: Removing unused variable tmp%6#0 +debug: Removing unused variable current_tail_offset%0#0 +debug: Removing unused variable encoded_tuple_buffer%0#0 +debug: Removing unused variable tmp%11#0 +debug: Removing unused variable current_tail_offset%1#0 +debug: Removing unused variable encoded_tuple_buffer%3#0 +debug: Removing unused variable tmp%16#0 +debug: Removing unused variable current_tail_offset%2#0 +debug: Removing unused variable encoded_tuple_buffer%6#0 +debug: Removing unused variable tmp%21#0 +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: inlining the default target of a switch/goto nth +debug: adding block@1: // abi_routing_L18 as a predecessor of block@7: // switch_case_next_L18 due to inlining of block@6: // switch_case_default_L18 +debug: simplified terminator of block@1: // abi_routing_L18 from switch tmp%2#0 {method "get_one()(uint8,uint8)" => block@2, method "get_two()(uint8,uint8)" => block@3, method "get_three()(uint8,uint8)" => block@4, method "compare()bool" => block@5, * => block@6} to switch tmp%2#0 {method "get_one()(uint8,uint8)" => block@2, method "get_two()(uint8,uint8)" => block@3, method "get_three()(uint8,uint8)" => block@4, method "compare()bool" => block@5, * => block@7} +debug: simplifying a switch with constants into goto nth +debug: simplified terminator of block@8: // bare_routing_L18 from switch tmp%23#0 {0u => block@9, * => block@10} to goto_nth [block@9][tmp%23#0] else goto block@10 +debug: inlining the default target of a switch/goto nth +debug: adding block@1: // abi_routing_L18 as a predecessor of block@12: // after_if_else_L18 due to inlining of block@7: // switch_case_next_L18 +debug: simplified terminator of block@1: // abi_routing_L18 from switch tmp%2#0 {method "get_one()(uint8,uint8)" => block@2, method "get_two()(uint8,uint8)" => block@3, method "get_three()(uint8,uint8)" => block@4, method "compare()bool" => block@5, * => block@7} to switch tmp%2#0 {method "get_one()(uint8,uint8)" => block@2, method "get_two()(uint8,uint8)" => block@3, method "get_three()(uint8,uint8)" => block@4, method "compare()bool" => block@5, * => block@12} +debug: simplifying a goto nth with two targets into a conditional branch +debug: simplified terminator of block@8: // bare_routing_L18 from goto_nth [block@9][tmp%23#0] else goto block@10 to goto tmp%23#0 ? block@10 : block@9 +debug: inlining the default target of a switch/goto nth +debug: simplified terminator of block@1: // abi_routing_L18 from switch tmp%2#0 {method "get_one()(uint8,uint8)" => block@2, method "get_two()(uint8,uint8)" => block@3, method "get_three()(uint8,uint8)" => block@4, method "compare()bool" => block@5, * => block@12} to switch tmp%2#0 {method "get_one()(uint8,uint8)" => block@2, method "get_two()(uint8,uint8)" => block@3, method "get_three()(uint8,uint8)" => block@4, method "compare()bool" => block@5, * => return 0u} +debug: Optimizer: Remove Linear Jump +debug: Replaced predecessor block@7: // switch_case_next_L18 with block@6: // switch_case_default_L18 in block@12: // after_if_else_L18 +debug: Merged linear block@7: // switch_case_next_L18 into block@6: // switch_case_default_L18 +debug: Replaced predecessor block@11: // switch_case_next_L18 with block@10: // switch_case_default_L18 in block@12: // after_if_else_L18 +debug: Merged linear block@11: // switch_case_next_L18 into block@10: // switch_case_default_L18 +debug: Optimizer: Remove Empty Blocks +debug: Removed empty block: block@6: // switch_case_default_L18 +debug: Removed empty block: block@10: // switch_case_default_L18 +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.struct_by_name.contract.DemoContract.get_one +debug: Splitting parallel copies prior to optimization +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.struct_by_name.contract.DemoContract.get_two +debug: Splitting parallel copies prior to optimization +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.struct_by_name.contract.DemoContract.get_three +debug: Splitting parallel copies prior to optimization +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.struct_by_name.contract.DemoContract.compare +debug: Splitting parallel copies prior to optimization +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Found equivalence set: awst_tmp%0#0, reinterpret_biguint%0#0 +debug: Replacing {reinterpret_biguint%0#0} with awst_tmp%0#0 made 1 modifications +debug: Found equivalence set: awst_tmp%2#0, reinterpret_biguint%1#0 +debug: Replacing {reinterpret_biguint%1#0} with awst_tmp%2#0 made 1 modifications +debug: Found equivalence set: awst_tmp%1#0, reinterpret_biguint%2#0 +debug: Replacing {reinterpret_biguint%2#0} with awst_tmp%1#0 made 1 modifications +debug: Found equivalence set: awst_tmp%3#0, reinterpret_biguint%3#0 +debug: Replacing {reinterpret_biguint%3#0} with awst_tmp%3#0 made 1 modifications +debug: Found equivalence set: awst_tmp%4#0, reinterpret_biguint%4#0 +debug: Replacing {reinterpret_biguint%4#0} with awst_tmp%4#0 made 1 modifications +debug: Found equivalence set: awst_tmp%6#0, reinterpret_biguint%5#0 +debug: Replacing {reinterpret_biguint%5#0} with awst_tmp%6#0 made 1 modifications +debug: Found equivalence set: awst_tmp%5#0, reinterpret_biguint%6#0 +debug: Replacing {reinterpret_biguint%6#0} with awst_tmp%5#0 made 1 modifications +debug: Found equivalence set: awst_tmp%7#0, reinterpret_biguint%7#0 +debug: Replacing {reinterpret_biguint%7#0} with awst_tmp%7#0 made 1 modifications +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.struct_by_name.contract.DemoContract.__algopy_default_create +debug: Splitting parallel copies prior to optimization +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine algopy.arc4.ARC4Contract.clear_state_program +debug: Splitting parallel copies prior to optimization +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Output IR to struct_by_name/out/DemoContract.ssa.opt_pass_1.ir +debug: Begin optimization pass 2/100 +debug: Optimizing subroutine algopy.arc4.ARC4Contract.approval_program +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__ +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Found equivalence set: elements_to_encode%0#0, encoded_tuple_buffer%1#0 +debug: Replacing {encoded_tuple_buffer%1#0} with elements_to_encode%0#0 made 1 modifications +debug: Found equivalence set: elements_to_encode%2#0, encoded_tuple_buffer%4#0 +debug: Replacing {encoded_tuple_buffer%4#0} with elements_to_encode%2#0 made 1 modifications +debug: Found equivalence set: elements_to_encode%4#0, encoded_tuple_buffer%7#0 +debug: Replacing {encoded_tuple_buffer%7#0} with elements_to_encode%4#0 made 1 modifications +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.struct_by_name.contract.DemoContract.get_one +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.struct_by_name.contract.DemoContract.get_two +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.struct_by_name.contract.DemoContract.get_three +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.struct_by_name.contract.DemoContract.compare +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine algopy.arc4.ARC4Contract.clear_state_program +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Output IR to struct_by_name/out/DemoContract.ssa.opt_pass_2.ir +debug: Begin optimization pass 3/100 +debug: Optimizing subroutine algopy.arc4.ARC4Contract.approval_program +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__ +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.struct_by_name.contract.DemoContract.get_one +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.struct_by_name.contract.DemoContract.get_two +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.struct_by_name.contract.DemoContract.get_three +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.struct_by_name.contract.DemoContract.compare +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine algopy.arc4.ARC4Contract.clear_state_program +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Remove Unused Ops +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: No optimizations performed in pass 3, ending loop +debug: Removing Phis from algopy.arc4.ARC4Contract.approval_program +debug: Removing Phis from test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__ +debug: Removing Phis from test_cases.struct_by_name.contract.DemoContract.get_one +debug: Removing Phis from test_cases.struct_by_name.contract.DemoContract.get_two +debug: Removing Phis from test_cases.struct_by_name.contract.DemoContract.get_three +debug: Removing Phis from test_cases.struct_by_name.contract.DemoContract.compare +debug: Removing Phis from algopy.arc4.ARC4Contract.clear_state_program +debug: Coalescing local variables in algopy.arc4.ARC4Contract.approval_program using strategy RootOperandGrouping +debug: Coalescing resulted in 0 replacement/s +debug: Coalescing local variables in test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__ using strategy RootOperandGrouping +debug: Coalescing resulted in 0 replacement/s +debug: Coalescing local variables in test_cases.struct_by_name.contract.DemoContract.get_one using strategy RootOperandGrouping +debug: Coalescing resulted in 0 replacement/s +debug: Coalescing local variables in test_cases.struct_by_name.contract.DemoContract.get_two using strategy RootOperandGrouping +debug: Coalescing resulted in 0 replacement/s +debug: Coalescing local variables in test_cases.struct_by_name.contract.DemoContract.get_three using strategy RootOperandGrouping +debug: Coalescing resulted in 0 replacement/s +debug: Coalescing local variables in test_cases.struct_by_name.contract.DemoContract.compare using strategy RootOperandGrouping +debug: Coalescing and_result%0#0 with [and_result%0#5, and_result%0#1, and_result%0#2] +debug: Coalescing resulted in 7 replacement/s +debug: Coalescing local variables in algopy.arc4.ARC4Contract.clear_state_program using strategy RootOperandGrouping +debug: Coalescing resulted in 0 replacement/s +debug: Sequentializing parallel copies in algopy.arc4.ARC4Contract.approval_program +debug: Sequentializing parallel copies in test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__ +debug: Sequentializing parallel copies in test_cases.struct_by_name.contract.DemoContract.get_one +debug: Sequentializing parallel copies in test_cases.struct_by_name.contract.DemoContract.get_two +debug: Sequentializing parallel copies in test_cases.struct_by_name.contract.DemoContract.get_three +debug: Sequentializing parallel copies in test_cases.struct_by_name.contract.DemoContract.compare +debug: Sequentializing parallel copies in algopy.arc4.ARC4Contract.clear_state_program +debug: Performing post-SSA optimizations +debug: Output IR to struct_by_name/out/DemoContract.destructured.ir +debug: Inserted main_block@0.ops[1]: 'l-store-copy tmp%0#0 0' +debug: Replaced main_block@0.ops[3]: 'v-load tmp%0#0' with 'l-load tmp%0#0' +debug: Inserted __puya_arc4_router___block@0.ops[1]: 'l-store-copy tmp%0#0 0' +debug: Replaced __puya_arc4_router___block@0.ops[3]: 'v-load tmp%0#0' with 'l-load tmp%0#0' +debug: Inserted __puya_arc4_router___abi_routing@1.ops[1]: 'l-store-copy tmp%2#0 0' +debug: Replaced __puya_arc4_router___abi_routing@1.ops[7]: 'v-load tmp%2#0' with 'l-load tmp%2#0' +debug: Inserted __puya_arc4_router___get_one_route@2.ops[1]: 'l-store-copy tmp%3#0 0' +debug: Replaced __puya_arc4_router___get_one_route@2.ops[3]: 'v-load tmp%3#0' with 'l-load tmp%3#0' +debug: Inserted __puya_arc4_router___get_one_route@2.ops[5]: 'l-store-copy tmp%4#0 0' +debug: Replaced __puya_arc4_router___get_one_route@2.ops[7]: 'v-load tmp%4#0' with 'l-load tmp%4#0' +debug: Inserted __puya_arc4_router___get_one_route@2.ops[10]: 'l-store-copy tmp%5#0 0' +debug: Replaced __puya_arc4_router___get_one_route@2.ops[12]: 'v-load tmp%5#0' with 'l-load tmp%5#0' +debug: Inserted __puya_arc4_router___get_one_route@2.ops[16]: 'l-store-copy elements_to_encode%0#0 0' +debug: Replaced __puya_arc4_router___get_one_route@2.ops[18]: 'v-load elements_to_encode%0#0' with 'l-load elements_to_encode%0#0' +debug: Inserted __puya_arc4_router___get_one_route@2.ops[25]: 'l-store-copy tmp%7#0 0' +debug: Replaced __puya_arc4_router___get_one_route@2.ops[27]: 'v-load tmp%7#0' with 'l-load tmp%7#0' +debug: Inserted __puya_arc4_router___get_one_route@2.ops[21]: 'l-store-copy encoded_tuple_buffer%2#0 0' +debug: Replaced __puya_arc4_router___get_one_route@2.ops[24]: 'v-load encoded_tuple_buffer%2#0' with 'l-load encoded_tuple_buffer%2#0' +debug: Inserted __puya_arc4_router___get_one_route@2.ops[15]: 'l-store-copy elements_to_encode%1#0 1' +debug: Replaced __puya_arc4_router___get_one_route@2.ops[20]: 'v-load elements_to_encode%1#0' with 'l-load elements_to_encode%1#0' +debug: Inserted __puya_arc4_router___get_two_route@3.ops[1]: 'l-store-copy tmp%8#0 0' +debug: Replaced __puya_arc4_router___get_two_route@3.ops[3]: 'v-load tmp%8#0' with 'l-load tmp%8#0' +debug: Inserted __puya_arc4_router___get_two_route@3.ops[5]: 'l-store-copy tmp%9#0 0' +debug: Replaced __puya_arc4_router___get_two_route@3.ops[7]: 'v-load tmp%9#0' with 'l-load tmp%9#0' +debug: Inserted __puya_arc4_router___get_two_route@3.ops[10]: 'l-store-copy tmp%10#0 0' +debug: Replaced __puya_arc4_router___get_two_route@3.ops[12]: 'v-load tmp%10#0' with 'l-load tmp%10#0' +debug: Inserted __puya_arc4_router___get_two_route@3.ops[16]: 'l-store-copy elements_to_encode%2#0 0' +debug: Replaced __puya_arc4_router___get_two_route@3.ops[18]: 'v-load elements_to_encode%2#0' with 'l-load elements_to_encode%2#0' +debug: Inserted __puya_arc4_router___get_two_route@3.ops[25]: 'l-store-copy tmp%12#0 0' +debug: Replaced __puya_arc4_router___get_two_route@3.ops[27]: 'v-load tmp%12#0' with 'l-load tmp%12#0' +debug: Inserted __puya_arc4_router___get_two_route@3.ops[21]: 'l-store-copy encoded_tuple_buffer%5#0 0' +debug: Replaced __puya_arc4_router___get_two_route@3.ops[24]: 'v-load encoded_tuple_buffer%5#0' with 'l-load encoded_tuple_buffer%5#0' +debug: Inserted __puya_arc4_router___get_two_route@3.ops[15]: 'l-store-copy elements_to_encode%3#0 1' +debug: Replaced __puya_arc4_router___get_two_route@3.ops[20]: 'v-load elements_to_encode%3#0' with 'l-load elements_to_encode%3#0' +debug: Inserted __puya_arc4_router___get_three_route@4.ops[1]: 'l-store-copy tmp%13#0 0' +debug: Replaced __puya_arc4_router___get_three_route@4.ops[3]: 'v-load tmp%13#0' with 'l-load tmp%13#0' +debug: Inserted __puya_arc4_router___get_three_route@4.ops[5]: 'l-store-copy tmp%14#0 0' +debug: Replaced __puya_arc4_router___get_three_route@4.ops[7]: 'v-load tmp%14#0' with 'l-load tmp%14#0' +debug: Inserted __puya_arc4_router___get_three_route@4.ops[10]: 'l-store-copy tmp%15#0 0' +debug: Replaced __puya_arc4_router___get_three_route@4.ops[12]: 'v-load tmp%15#0' with 'l-load tmp%15#0' +debug: Inserted __puya_arc4_router___get_three_route@4.ops[16]: 'l-store-copy elements_to_encode%4#0 0' +debug: Replaced __puya_arc4_router___get_three_route@4.ops[18]: 'v-load elements_to_encode%4#0' with 'l-load elements_to_encode%4#0' +debug: Inserted __puya_arc4_router___get_three_route@4.ops[25]: 'l-store-copy tmp%17#0 0' +debug: Replaced __puya_arc4_router___get_three_route@4.ops[27]: 'v-load tmp%17#0' with 'l-load tmp%17#0' +debug: Inserted __puya_arc4_router___get_three_route@4.ops[21]: 'l-store-copy encoded_tuple_buffer%8#0 0' +debug: Replaced __puya_arc4_router___get_three_route@4.ops[24]: 'v-load encoded_tuple_buffer%8#0' with 'l-load encoded_tuple_buffer%8#0' +debug: Inserted __puya_arc4_router___get_three_route@4.ops[15]: 'l-store-copy elements_to_encode%5#0 1' +debug: Replaced __puya_arc4_router___get_three_route@4.ops[20]: 'v-load elements_to_encode%5#0' with 'l-load elements_to_encode%5#0' +debug: Inserted __puya_arc4_router___compare_route@5.ops[1]: 'l-store-copy tmp%18#0 0' +debug: Replaced __puya_arc4_router___compare_route@5.ops[3]: 'v-load tmp%18#0' with 'l-load tmp%18#0' +debug: Inserted __puya_arc4_router___compare_route@5.ops[5]: 'l-store-copy tmp%19#0 0' +debug: Replaced __puya_arc4_router___compare_route@5.ops[7]: 'v-load tmp%19#0' with 'l-load tmp%19#0' +debug: Inserted __puya_arc4_router___compare_route@5.ops[10]: 'l-store-copy tmp%20#0 0' +debug: Replaced __puya_arc4_router___compare_route@5.ops[12]: 'v-load tmp%20#0' with 'l-load tmp%20#0' +debug: Inserted __puya_arc4_router___compare_route@5.ops[24]: 'l-store-copy tmp%22#0 0' +debug: Replaced __puya_arc4_router___compare_route@5.ops[26]: 'v-load tmp%22#0' with 'l-load tmp%22#0' +debug: Inserted __puya_arc4_router___compare_route@5.ops[20]: 'l-store-copy encoded_bool%0#0 0' +debug: Replaced __puya_arc4_router___compare_route@5.ops[23]: 'v-load encoded_bool%0#0' with 'l-load encoded_bool%0#0' +debug: Inserted __puya_arc4_router___compare_route@5.ops[15]: 'l-store-copy to_encode%0#0 0' +debug: Replaced __puya_arc4_router___compare_route@5.ops[19]: 'v-load to_encode%0#0' with 'l-load to_encode%0#0' +debug: Inserted __puya_arc4_router___bare_routing@8.ops[1]: 'l-store-copy tmp%23#0 0' +debug: Replaced __puya_arc4_router___bare_routing@8.ops[3]: 'v-load tmp%23#0' with 'l-load tmp%23#0' +debug: Inserted __puya_arc4_router_____algopy_default_create@9.ops[1]: 'l-store-copy tmp%24#0 0' +debug: Replaced __puya_arc4_router_____algopy_default_create@9.ops[3]: 'v-load tmp%24#0' with 'l-load tmp%24#0' +debug: Inserted __puya_arc4_router_____algopy_default_create@9.ops[5]: 'l-store-copy tmp%25#0 0' +debug: Replaced __puya_arc4_router_____algopy_default_create@9.ops[7]: 'v-load tmp%25#0' with 'l-load tmp%25#0' +debug: Inserted compare_block@0.ops[17]: 'l-store-copy tmp%2#0 0' +debug: Replaced compare_block@0.ops[19]: 'v-load tmp%2#0' with 'l-load tmp%2#0' +debug: Inserted compare_block@0.ops[5]: 'l-store-copy awst_tmp%2#0 0' +debug: Replaced compare_block@0.ops[8]: 'v-load awst_tmp%2#0' with 'l-load awst_tmp%2#0' +debug: Inserted compare_block@0.ops[14]: 'l-store-copy tmp%1#0 0' +debug: Replaced compare_block@0.ops[17]: 'v-load tmp%1#0' with 'l-load tmp%1#0' +debug: Inserted compare_block@0.ops[2]: 'l-store-copy awst_tmp%0#0 0' +debug: Replaced compare_block@0.ops[8]: 'v-load awst_tmp%0#0' with 'l-load awst_tmp%0#0' +debug: Inserted compare_block@0.ops[11]: 'l-store-copy tmp%0#0 0' +debug: Replaced compare_block@0.ops[18]: 'v-load tmp%0#0' with 'l-load tmp%0#0' +debug: Inserted compare_block@0.ops[5]: 'l-store-copy awst_tmp%3#0 2' +debug: Replaced compare_block@0.ops[15]: 'v-load awst_tmp%3#0' with 'l-load awst_tmp%3#0' +debug: Inserted compare_block@0.ops[1]: 'l-store-copy awst_tmp%1#0 1' +debug: Replaced compare_block@0.ops[15]: 'v-load awst_tmp%1#0' with 'l-load awst_tmp%1#0' +debug: Inserted compare_and_contd@1.ops[17]: 'l-store-copy tmp%5#0 0' +debug: Replaced compare_and_contd@1.ops[19]: 'v-load tmp%5#0' with 'l-load tmp%5#0' +debug: Inserted compare_and_contd@1.ops[5]: 'l-store-copy awst_tmp%6#0 0' +debug: Replaced compare_and_contd@1.ops[8]: 'v-load awst_tmp%6#0' with 'l-load awst_tmp%6#0' +debug: Inserted compare_and_contd@1.ops[14]: 'l-store-copy tmp%4#0 0' +debug: Replaced compare_and_contd@1.ops[17]: 'v-load tmp%4#0' with 'l-load tmp%4#0' +debug: Inserted compare_and_contd@1.ops[2]: 'l-store-copy awst_tmp%4#0 0' +debug: Replaced compare_and_contd@1.ops[8]: 'v-load awst_tmp%4#0' with 'l-load awst_tmp%4#0' +debug: Inserted compare_and_contd@1.ops[11]: 'l-store-copy tmp%3#0 0' +debug: Replaced compare_and_contd@1.ops[18]: 'v-load tmp%3#0' with 'l-load tmp%3#0' +debug: Inserted compare_and_contd@1.ops[5]: 'l-store-copy awst_tmp%7#0 2' +debug: Replaced compare_and_contd@1.ops[15]: 'v-load awst_tmp%7#0' with 'l-load awst_tmp%7#0' +debug: Inserted compare_and_contd@1.ops[1]: 'l-store-copy awst_tmp%5#0 1' +debug: Replaced compare_and_contd@1.ops[15]: 'v-load awst_tmp%5#0' with 'l-load awst_tmp%5#0' +debug: Found 3 edge set/s for test_cases.struct_by_name.contract.DemoContract.__puya_arc4_router__ +debug: Found 2 edge set/s for test_cases.struct_by_name.contract.DemoContract.compare +debug: Allocated 1 variable/s to x-stack: and_result%0#0 +debug: shared x-stack for compare_bool_true@2 -> compare_bool_merge@4: and_result%0#0 +debug: shared x-stack for compare_bool_false@3 -> compare_bool_merge@4: and_result%0#0 +info: Writing struct_by_name/out/DemoContract.arc32.json +info: Writing struct_by_name/out/DemoContract.arc56.json +info: Writing struct_by_name/out/DemoContract.approval.teal +info: Writing struct_by_name/out/DemoContract.clear.teal +info: Writing struct_by_name/out/DemoContract.approval.bin +info: Writing struct_by_name/out/DemoContract.clear.bin +info: Writing struct_by_name/out/DemoContract.approval.puya.map +info: Writing struct_by_name/out/DemoContract.clear.puya.map +info: writing struct_by_name/out/client_DemoContract.py \ No newline at end of file