diff --git a/examples/sizes.txt b/examples/sizes.txt index 6c44f8f32b..47823f0646 100644 --- a/examples/sizes.txt +++ b/examples/sizes.txt @@ -62,6 +62,7 @@ string_ops 157 152 152 stubs/BigUInt 172 112 112 stubs/Bytes 1769 258 258 stubs/Uint64 371 8 8 +template_variables/TemplateVariables 168 155 155 too_many_permutations 108 107 107 transaction/Transaction 914 864 864 tuple_support/TupleSupport 442 294 294 diff --git a/scripts/compile_all_examples.py b/scripts/compile_all_examples.py index c163602baf..cdc41d70d7 100755 --- a/scripts/compile_all_examples.py +++ b/scripts/compile_all_examples.py @@ -105,12 +105,20 @@ class CompilationResult: def get_program_size(path: Path) -> int: try: - program = algokit_utils.Program(path.read_text("utf-8"), ALGOD_CLIENT) + program = algokit_utils.Program(replace_templates(path.read_text("utf-8")), ALGOD_CLIENT) return len(program.raw_binary) except Exception as e: raise Exception(f"Error compiling teal application: {path}") from e +def replace_templates( + teal: str, *, uint_replacement: int = 0, bytes_replacement: bytes = b"" +) -> str: + teal = re.sub(r"int TMPL_\w+", f"int {uint_replacement}", teal) + teal = re.sub(r"byte TMPL_\w+", f"byte 0x{bytes_replacement.hex()}", teal) + return teal + + def _stabilise_logs(stdout: str) -> list[str]: return [ line.replace("\\", "/").replace(str(GIT_ROOT).replace("\\", "/"), "") diff --git a/src/puya/awst/function_traverser.py b/src/puya/awst/function_traverser.py index 7161f3d30d..0e9cbd4bcf 100644 --- a/src/puya/awst/function_traverser.py +++ b/src/puya/awst/function_traverser.py @@ -212,6 +212,9 @@ def visit_expression_statement(self, statement: awst_nodes.ExpressionStatement) def visit_assert_statement(self, statement: awst_nodes.AssertStatement) -> None: statement.condition.accept(self) + def visit_template_var(self, statement: awst_nodes.TemplateVar) -> None: + pass + def visit_uint64_augmented_assignment( self, statement: awst_nodes.UInt64AugmentedAssignment ) -> None: diff --git a/src/puya/awst/nodes.py b/src/puya/awst/nodes.py index d2c2d99fbb..21e2552bb0 100644 --- a/src/puya/awst/nodes.py +++ b/src/puya/awst/nodes.py @@ -370,6 +370,15 @@ def accept(self, visitor: ExpressionVisitor[T]) -> T: return visitor.visit_bytes_constant(self) +@attrs.frozen +class TemplateVar(Expression): + wtype: WType + name: str + + def accept(self, visitor: ExpressionVisitor[T]) -> T: + return visitor.visit_template_var(self) + + @attrs.frozen class MethodConstant(Expression): wtype: WType = attrs.field(default=wtypes.bytes_wtype, init=False) diff --git a/src/puya/awst/to_code_visitor.py b/src/puya/awst/to_code_visitor.py index 834cff9d7f..f433997e87 100644 --- a/src/puya/awst/to_code_visitor.py +++ b/src/puya/awst/to_code_visitor.py @@ -534,6 +534,9 @@ def visit_state_get(self, expr: nodes.StateGet) -> str: def visit_state_exists(self, expr: nodes.StateExists) -> str: return f"STATE_EXISTS({expr.field.accept(self)})" + def visit_template_var(self, expr: nodes.TemplateVar) -> str: + return f"TemplateVar[{expr.wtype}]({expr.name})" + def _indent(lines: t.Iterable[str], indent_size: str = " ") -> t.Iterator[str]: yield from (f"{indent_size}{line}" for line in lines) diff --git a/src/puya/awst/visitors.py b/src/puya/awst/visitors.py index c2d1badf67..8071f441d6 100644 --- a/src/puya/awst/visitors.py +++ b/src/puya/awst/visitors.py @@ -307,3 +307,7 @@ def visit_state_get_ex(self, expr: puya.awst.nodes.StateGetEx) -> T: @abstractmethod def visit_state_exists(self, expr: puya.awst.nodes.StateExists) -> T: ... + + @abstractmethod + def visit_template_var(self, expr: puya.awst.nodes.TemplateVar) -> T: + ... diff --git a/src/puya/awst_build/constants.py b/src/puya/awst_build/constants.py index 9f4b1dbd97..0c3a4c7d98 100644 --- a/src/puya/awst_build/constants.py +++ b/src/puya/awst_build/constants.py @@ -59,6 +59,7 @@ CLS_ARC4_STATIC_ARRAY = "puyapy.arc4.StaticArray" CLS_ARC4_TUPLE = "puyapy.arc4.Tuple" CLS_ARC4_STRUCT = "puyapy.arc4.Struct" +CLS_TEMPLATE_VAR_METHOD = f"{PUYAPY_PREFIX}_template_variables.TemplateVar" CONTRACT_STUB_TYPES = [ CONTRACT_BASE, diff --git a/src/puya/awst_build/eb/template_variables.py b/src/puya/awst_build/eb/template_variables.py new file mode 100644 index 0000000000..6ea0bf4be2 --- /dev/null +++ b/src/puya/awst_build/eb/template_variables.py @@ -0,0 +1,86 @@ +from collections.abc import Sequence + +import mypy.nodes + +from puya.awst import wtypes +from puya.awst.nodes import Literal, TemplateVar +from puya.awst_build.eb.base import ( + ExpressionBuilder, + IntermediateExpressionBuilder, + TypeClassExpressionBuilder, +) +from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.utils import get_arg_mapping +from puya.errors import CodeError +from puya.parse import SourceLocation + + +class GenericTemplateVariableExpressionBuilder(IntermediateExpressionBuilder): + def index_multiple( + self, index: Sequence[ExpressionBuilder | Literal], location: SourceLocation + ) -> ExpressionBuilder: + match index: + case [TypeClassExpressionBuilder() as eb]: + wtype = eb.produces() + case _: + raise CodeError("Invalid/unhandled arguments", location) + return TemplateVariableExpressionBuilder(location=location, wtype=wtype) + + def index( + self, index: ExpressionBuilder | Literal, location: SourceLocation + ) -> ExpressionBuilder: + return self.index_multiple([index], location) + + +class TemplateVariableExpressionBuilder(TypeClassExpressionBuilder): + def __init__(self, location: SourceLocation, wtype: wtypes.WType): + super().__init__(location) + self.wtype = wtype + + def produces(self) -> wtypes.WType: + return self.wtype + + def call( + self, + args: Sequence[ExpressionBuilder | Literal], + arg_kinds: list[mypy.nodes.ArgKind], + arg_names: list[str | None], + location: SourceLocation, + original_expr: mypy.nodes.CallExpr, + ) -> ExpressionBuilder: + var_name_arg_name = "variable_name" + arg_mapping = get_arg_mapping( + positional_arg_names=[var_name_arg_name], + args=zip(arg_names, args, strict=True), + location=location, + ) + + try: + var_name = arg_mapping.pop(var_name_arg_name) + except KeyError as ex: + raise CodeError("Required positional argument missing", location) from ex + + prefix_arg = arg_mapping.pop("prefix", None) + if arg_mapping: + raise CodeError( + f"Unrecognised keyword argument(s): {", ".join(arg_mapping)}", location + ) + match prefix_arg: + case Literal(value=str(prefix_value)): + pass + case None: + prefix_value = "TMPL_" + case _: + raise CodeError("Invalid value for prefix argument", location) + + match var_name: + case Literal(value=str(str_value)): + return var_expression( + TemplateVar( + name=prefix_value + str_value, source_location=location, wtype=self.wtype + ) + ) + case _: + raise CodeError( + "TemplateVars must be declared using a string literal for the variable name" + ) diff --git a/src/puya/awst_build/eb/type_registry.py b/src/puya/awst_build/eb/type_registry.py index d61958fd1c..b0c381f1d2 100644 --- a/src/puya/awst_build/eb/type_registry.py +++ b/src/puya/awst_build/eb/type_registry.py @@ -17,6 +17,7 @@ log, named_int_constants, struct, + template_variables, transaction, tuple as tuple_, uint64, @@ -65,6 +66,9 @@ constants.CLS_BIGUINT: biguint.BigUIntClassExpressionBuilder, constants.CLS_BYTES: bytes_.BytesClassExpressionBuilder, constants.CLS_UINT64: uint64.UInt64ClassExpressionBuilder, + constants.CLS_TEMPLATE_VAR_METHOD: ( + template_variables.GenericTemplateVariableExpressionBuilder + ), constants.SUBMIT_TXNS: transaction.SubmitInnerTransactionExpressionBuilder, constants.CLS_TRANSACTION_BASE: functools.partial( transaction.GroupTransactionClassExpressionBuilder, diff --git a/src/puya/ir/builder/main.py b/src/puya/ir/builder/main.py index 367b4d7378..7f424dd7da 100644 --- a/src/puya/ir/builder/main.py +++ b/src/puya/ir/builder/main.py @@ -39,6 +39,7 @@ ProgramExit, Subroutine, SubroutineReturn, + TemplateVar, UInt64Constant, Value, ValueProvider, @@ -717,6 +718,11 @@ def visit_return_statement(self, statement: awst_nodes.ReturnStatement) -> TStat ) ) + def visit_template_var(self, expr: puya.awst.nodes.TemplateVar) -> TExpression: + atype = wtype_to_avm_type(expr.wtype) + typing.assert_type(atype, typing.Literal[AVMType.uint64, AVMType.bytes]) + return TemplateVar(name=expr.name, atype=atype, source_location=expr.source_location) + def visit_continue_statement(self, statement: awst_nodes.ContinueStatement) -> TStatement: self.context.block_builder.loop_continue(statement.source_location) diff --git a/src/puya/ir/main.py b/src/puya/ir/main.py index c9c48a6374..8670e2a55e 100644 --- a/src/puya/ir/main.py +++ b/src/puya/ir/main.py @@ -274,12 +274,6 @@ class FoldedContract: arc4_methods: list[ARC4Method] = attrs.field(factory=list) -def wtype_to_storage_type(wtype: wtypes.WType) -> typing.Literal[AVMType.uint64, AVMType.bytes]: - atype = wtype_to_avm_type(wtype) - assert atype is not AVMType.any - return atype - - def fold_state_and_special_methods( ctx: IRBuildContext, contract: awst_nodes.ContractFragment ) -> FoldedContract: @@ -298,7 +292,7 @@ def fold_state_and_special_methods( name=state.member_name, source_location=state.source_location, key=state.key, - storage_type=wtype_to_storage_type(state.storage_wtype), + storage_type=wtype_to_avm_type(state.storage_wtype), description=state.description, ) if state.kind == awst_nodes.AppStateKind.app_global: diff --git a/src/puya/ir/models.py b/src/puya/ir/models.py index 0cad035da0..d1ba58337c 100644 --- a/src/puya/ir/models.py +++ b/src/puya/ir/models.py @@ -223,6 +223,15 @@ def accept(self, visitor: IRVisitor[T]) -> T: return visitor.visit_biguint_constant(self) +@attrs.frozen +class TemplateVar(Value): + name: str + atype: AVMType + + def accept(self, visitor: IRVisitor[T]) -> T: + return visitor.visit_template_var(self) + + @attrs.frozen class BytesConstant(Constant): """Constant for types that are logically bytes""" diff --git a/src/puya/ir/to_text_visitor.py b/src/puya/ir/to_text_visitor.py index 35a3d82851..8fa21133f3 100644 --- a/src/puya/ir/to_text_visitor.py +++ b/src/puya/ir/to_text_visitor.py @@ -78,6 +78,9 @@ def visit_subroutine_return(self, op: models.SubroutineReturn) -> str: results = " ".join(r.accept(self) for r in op.result) return f"return {results}" + def visit_template_var(self, deploy_var: models.TemplateVar) -> str: + return f"TemplateVar[{deploy_var.atype}]({deploy_var.name})" + def visit_program_exit(self, op: models.ProgramExit) -> str: return f"exit {op.result.accept(self)}" diff --git a/src/puya/ir/types_.py b/src/puya/ir/types_.py index 342a0410ad..5f9afb58ed 100644 --- a/src/puya/ir/types_.py +++ b/src/puya/ir/types_.py @@ -1,4 +1,5 @@ import enum +import typing from puya.avm_type import AVMType from puya.awst import ( @@ -30,7 +31,7 @@ def bytes_enc_to_avm_bytes_enc(bytes_encoding: BytesEncoding) -> AVMBytesEncodin def wtype_to_avm_type( expr_or_wtype: wtypes.WType | awst_nodes.Expression, source_location: SourceLocation | None = None, -) -> AVMType: +) -> typing.Literal[AVMType.bytes, AVMType.uint64]: if isinstance(expr_or_wtype, awst_nodes.Expression): return wtype_to_avm_type( expr_or_wtype.wtype, source_location=source_location or expr_or_wtype.source_location diff --git a/src/puya/ir/visitor.py b/src/puya/ir/visitor.py index 3ef2750106..38ec6eaf0c 100644 --- a/src/puya/ir/visitor.py +++ b/src/puya/ir/visitor.py @@ -91,6 +91,10 @@ def visit_program_exit(self, exit_: puya.ir.models.ProgramExit) -> T: def visit_fail(self, fail: puya.ir.models.Fail) -> T: ... + @abstractmethod + def visit_template_var(self, deploy_var: puya.ir.models.TemplateVar) -> T: + ... + class IRTraverser(IRVisitor[None]): active_block: puya.ir.models.BasicBlock @@ -124,6 +128,9 @@ def visit_bytes_constant(self, const: puya.ir.models.BytesConstant) -> None: def visit_address_constant(self, const: puya.ir.models.AddressConstant) -> None: pass + def visit_template_var(self, deploy_var: puya.ir.models.TemplateVar) -> None: + pass + def visit_method_constant(self, const: puya.ir.models.MethodConstant) -> None: pass @@ -199,6 +206,9 @@ def visit_method_constant(self, const: puya.ir.models.MethodConstant) -> T | Non def visit_phi(self, phi: puya.ir.models.Phi) -> T | None: return None + def visit_template_var(self, deploy_var: puya.ir.models.TemplateVar) -> T | None: + return None + def visit_phi_argument(self, arg: puya.ir.models.PhiArgument) -> T | None: return None diff --git a/src/puya/ir/visitor_mutator.py b/src/puya/ir/visitor_mutator.py index 16f44fa866..3cf6e7d4b3 100644 --- a/src/puya/ir/visitor_mutator.py +++ b/src/puya/ir/visitor_mutator.py @@ -25,6 +25,7 @@ Register, SubroutineReturn, Switch, + TemplateVar, UInt64Constant, ValueTuple, ) @@ -75,6 +76,9 @@ def visit_assignment(self, ass: Assignment) -> Assignment | None: def visit_register(self, reg: Register) -> Register: return reg + def visit_template_var(self, deploy_var: TemplateVar) -> TemplateVar: + return deploy_var + def visit_uint64_constant(self, const: UInt64Constant) -> UInt64Constant: return const diff --git a/src/puya/mir/builder.py b/src/puya/mir/builder.py index a569daa9c1..9ecf370cbe 100644 --- a/src/puya/mir/builder.py +++ b/src/puya/mir/builder.py @@ -77,6 +77,15 @@ def visit_register(self, reg: ir.Register) -> None: ) ) + def visit_template_var(self, deploy_var: ir.TemplateVar) -> None: + self._add_op( + models.PushTemplateVar( + name=deploy_var.name, + atype=deploy_var.atype, + source_location=deploy_var.source_location, + ) + ) + def visit_value_tuple(self, tup: ir.ValueTuple) -> None: raise InternalError( "Encountered ValueTuple during codegen - should have been eliminated in prior stages", diff --git a/src/puya/mir/models.py b/src/puya/mir/models.py index 19dc740a7f..a2cfe7d42b 100644 --- a/src/puya/mir/models.py +++ b/src/puya/mir/models.py @@ -6,13 +6,13 @@ import attrs +from puya.avm_type import AVMType from puya.errors import InternalError from puya.ir.utils import format_bytes if t.TYPE_CHECKING: from collections.abc import Iterable, Iterator, Mapping, Sequence - from puya.avm_type import AVMType from puya.ir.types_ import AVMBytesEncoding from puya.mir.visitor import MIRVisitor from puya.parse import SourceLocation @@ -53,6 +53,31 @@ def __str__(self) -> str: return f"byte {format_bytes(self.value, self.encoding)}" +@attrs.frozen(eq=False) +class PushTemplateVar(BaseOp): + name: str + atype: AVMType = attrs.field() + op_code: str = attrs.field(init=False) + + @op_code.default + def _default_opcode(self) -> str: + match self.atype: + case AVMType.bytes: + return "byte" + case AVMType.uint64: + return "int" + case _: + raise InternalError( + f"Unsupported atype for PushTemplateVar: {self.atype}", self.source_location + ) + + def accept(self, visitor: MIRVisitor[_T]) -> _T: + return visitor.visit_push_deploy_var(self) + + def __str__(self) -> str: + return f"{self.op_code} {self.name}" + + @attrs.frozen(eq=False) class PushAddress(BaseOp): value: str diff --git a/src/puya/mir/stack.py b/src/puya/mir/stack.py index 9b515a931e..237c5b24ef 100644 --- a/src/puya/mir/stack.py +++ b/src/puya/mir/stack.py @@ -89,6 +89,16 @@ def visit_push_bytes(self, push: models.PushBytes) -> list[teal.TealOp]: self.l_stack.append(format_bytes(push.value, push.encoding)) return [teal.PushBytes(push.value, push.encoding, source_location=push.source_location)] + def visit_push_deploy_var(self, deploy_var: models.PushTemplateVar) -> list[teal.TealOp]: + self.l_stack.append(deploy_var.name) + return [ + teal.PushTemplateVar( + name=deploy_var.name, + op_code=deploy_var.op_code, + source_location=deploy_var.source_location, + ) + ] + def visit_push_address(self, addr: models.PushAddress) -> list[teal.TealOp]: self.l_stack.append(addr.value) return [teal.PushAddress(addr.value, source_location=addr.source_location)] diff --git a/src/puya/mir/visitor.py b/src/puya/mir/visitor.py index 2f4340879d..2ffa4cd0d5 100644 --- a/src/puya/mir/visitor.py +++ b/src/puya/mir/visitor.py @@ -95,5 +95,9 @@ def visit_push_address(self, addr: models.PushAddress) -> _T: ... @abc.abstractmethod - def visit_push_method(self, addr: models.PushMethod) -> _T: + def visit_push_method(self, method: models.PushMethod) -> _T: + ... + + @abc.abstractmethod + def visit_push_deploy_var(self, deploy_var: models.PushTemplateVar) -> _T: ... diff --git a/src/puya/teal/models.py b/src/puya/teal/models.py index fdf294a810..9e4a7f097c 100644 --- a/src/puya/teal/models.py +++ b/src/puya/teal/models.py @@ -226,6 +226,18 @@ def immediates(self) -> Sequence[int | str]: return hint, bytes_str +@attrs.frozen +class PushTemplateVar(TealOp): + name: str + op_code: str + consumes: int = attrs.field(default=0, init=False) + produces: int = attrs.field(default=1, init=False) + + @property + def immediates(self) -> Sequence[int | str]: + return (self.name,) + + @attrs.frozen class PushAddress(TealOp): a: str diff --git a/src/puyapy-stubs/__init__.pyi b/src/puyapy-stubs/__init__.pyi index a20a339bc5..2ba25a3dd1 100644 --- a/src/puyapy-stubs/__init__.pyi +++ b/src/puyapy-stubs/__init__.pyi @@ -10,6 +10,7 @@ from puyapy._hints import * from puyapy._state import * from puyapy._unsigned_builtins import * from puyapy._util import * +from puyapy._template_variables import * from puyapy import arc4 as arc4 from puyapy import gtxn as gtxn from puyapy import itxn as itxn diff --git a/src/puyapy-stubs/_primitives.pyi b/src/puyapy-stubs/_primitives.pyi index 469925ebf0..b17b0eb6e0 100644 --- a/src/puyapy-stubs/_primitives.pyi +++ b/src/puyapy-stubs/_primitives.pyi @@ -163,13 +163,13 @@ class Bytes(Reversible[Bytes]): """Bytes can be initialized with a Python bytes literal, or bytes variable declared at the module level""" @staticmethod - def from_base32(value: typing.LiteralString, /) -> Bytes: + def from_base32(value: str, /) -> Bytes: """Creates Bytes from a base32 encoded string e.g. `Bytes.from_base32("74======")`""" @staticmethod - def from_base64(value: typing.LiteralString, /) -> Bytes: + def from_base64(value: str, /) -> Bytes: """Creates Bytes from a base64 encoded string e.g. `Bytes.from_base64("RkY=")`""" @staticmethod - def from_hex(value: typing.LiteralString, /) -> Bytes: + def from_hex(value: str, /) -> Bytes: """Creates Bytes from a hex/octal encoded string e.g. `Bytes.from_hex("FF")`""" def __add__(self, other: Bytes | bytes) -> Bytes: """Concatenate Bytes with another Bytes or bytes literal diff --git a/src/puyapy-stubs/_template_variables.pyi b/src/puyapy-stubs/_template_variables.pyi new file mode 100644 index 0000000000..ca27df21aa --- /dev/null +++ b/src/puyapy-stubs/_template_variables.pyi @@ -0,0 +1,13 @@ +import typing + +from puyapy import Bytes, BytesBacked, UInt64 + +_T_co = typing.TypeVar("_T_co", bound=UInt64 | bool | Bytes | BytesBacked, covariant=True) + +class _TemplateVarMethod(typing.Protocol[_T_co]): + def __call__(self, variable_name: str, /, *, prefix: str = "TMPL_") -> _T_co: ... + +class _TemplateVarGeneric(typing.Protocol): + def __getitem__(self, _: type[_T_co]) -> _TemplateVarMethod[_T_co]: ... + +TemplateVar: _TemplateVarGeneric = ... diff --git a/test_cases/template_variables/contract.py b/test_cases/template_variables/contract.py new file mode 100644 index 0000000000..1cbc476bee --- /dev/null +++ b/test_cases/template_variables/contract.py @@ -0,0 +1,21 @@ +from puyapy import BigUInt, Bytes, TemplateVar, UInt64, arc4 +from puyapy.arc4 import UInt512 + + +class TemplateVariablesContract(arc4.ARC4Contract): + @arc4.abimethod() + def get_bytes(self) -> Bytes: + return TemplateVar[Bytes]("SOME_BYTES") + + @arc4.abimethod() + def get_big_uint(self) -> UInt512: + x = TemplateVar[BigUInt]("SOME_BIG_UINT") + return UInt512(x) + + @arc4.baremethod(allow_actions=["UpdateApplication"]) + def on_update(self) -> None: + assert TemplateVar[bool]("UPDATABLE") + + @arc4.baremethod(allow_actions=["DeleteApplication"]) + def on_delete(self) -> None: + assert TemplateVar[UInt64]("DELETABLE") diff --git a/test_cases/template_variables/out/TemplateVariablesContract.approval.mir b/test_cases/template_variables/out/TemplateVariablesContract.approval.mir new file mode 100644 index 0000000000..c3c3ca52b4 --- /dev/null +++ b/test_cases/template_variables/out/TemplateVariablesContract.approval.mir @@ -0,0 +1,175 @@ +// Op // Op Description Stack (out) X stack Source code Source line + +#pragma version 10 + +// test_cases.template_variables.contract.TemplateVariablesContract.approval_program() -> uint64: +main_block@0: + txn NumAppArgs // {txn} class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + // virtual: store tmp%0#0 to l-stack (no copy) tmp%0#0 class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + // virtual: load tmp%0#0 from l-stack (no copy) tmp%0#0 class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + bz main_bare_routing@6 // class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + // Implicit fall through to main_abi_routing@1 // class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + +main_abi_routing@1: + txna ApplicationArgs 0 // {txna} class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + // virtual: store tmp%1#0 to l-stack (no copy) tmp%1#0 class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + method "get_bytes()byte[]" // tmp%1#0,method<"get_bytes()byte[]"> class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + method "get_big_uint()uint512" // tmp%1#0,method<"get_bytes()byte[]">,method<"get_big_uint()uint512"> class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + uncover 2 // load tmp%1#0 from l-stack (no copy) method<"get_bytes()byte[]">,method<"get_big_uint()uint512">,tmp%1#0 class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + match main_get_bytes_route@2 main_get_big_uint_route@3 // class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + err // reject transaction // class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + +main_get_bytes_route@2: + txn OnCompletion // {txn} arc4.abimethod() template_variables/contract.py:6 + // virtual: store tmp%2#0 to l-stack (no copy) tmp%2#0 arc4.abimethod() template_variables/contract.py:6 + // virtual: load tmp%2#0 from l-stack (no copy) tmp%2#0 arc4.abimethod() template_variables/contract.py:6 + ! // {!} arc4.abimethod() template_variables/contract.py:6 + // virtual: store tmp%3#0 to l-stack (no copy) tmp%3#0 arc4.abimethod() template_variables/contract.py:6 + // virtual: load tmp%3#0 from l-stack (no copy) tmp%3#0 arc4.abimethod() template_variables/contract.py:6 + assert // OnCompletion is NoOp // arc4.abimethod() template_variables/contract.py:6 + txn ApplicationID // {txn} arc4.abimethod() template_variables/contract.py:6 + // virtual: store tmp%4#0 to l-stack (no copy) tmp%4#0 arc4.abimethod() template_variables/contract.py:6 + // virtual: load tmp%4#0 from l-stack (no copy) tmp%4#0 arc4.abimethod() template_variables/contract.py:6 + assert // is not creating // arc4.abimethod() template_variables/contract.py:6 + callsub get_bytes // {get_bytes} arc4.abimethod() template_variables/contract.py:6 + // virtual: store awst_tmp%5#0 to l-stack (no copy) awst_tmp%5#0 arc4.abimethod() template_variables/contract.py:6 + dup // load awst_tmp%5#0 from l-stack (copy) awst_tmp%5#0,awst_tmp%5#0 arc4.abimethod() template_variables/contract.py:6 + len // awst_tmp%5#0,{len} arc4.abimethod() template_variables/contract.py:6 + // virtual: store tmp%6#0 to l-stack (no copy) awst_tmp%5#0,tmp%6#0 arc4.abimethod() template_variables/contract.py:6 + // virtual: load tmp%6#0 from l-stack (no copy) awst_tmp%5#0,tmp%6#0 arc4.abimethod() template_variables/contract.py:6 + itob // awst_tmp%5#0,{itob} arc4.abimethod() template_variables/contract.py:6 + // virtual: store tmp%7#0 to l-stack (no copy) awst_tmp%5#0,tmp%7#0 arc4.abimethod() template_variables/contract.py:6 + // virtual: load tmp%7#0 from l-stack (no copy) awst_tmp%5#0,tmp%7#0 arc4.abimethod() template_variables/contract.py:6 + substring 6 8 // awst_tmp%5#0,{substring} arc4.abimethod() template_variables/contract.py:6 + // virtual: store tmp%8#0 to l-stack (no copy) awst_tmp%5#0,tmp%8#0 arc4.abimethod() template_variables/contract.py:6 + // virtual: load tmp%8#0 from l-stack (no copy) awst_tmp%5#0,tmp%8#0 arc4.abimethod() template_variables/contract.py:6 + swap // load awst_tmp%5#0 from l-stack (no copy) tmp%8#0,awst_tmp%5#0 arc4.abimethod() template_variables/contract.py:6 + concat // {concat} arc4.abimethod() template_variables/contract.py:6 + // virtual: store tmp%9#0 to l-stack (no copy) tmp%9#0 arc4.abimethod() template_variables/contract.py:6 + byte 0x151f7c75 // tmp%9#0,0x151f7c75 arc4.abimethod() template_variables/contract.py:6 + swap // load tmp%9#0 from l-stack (no copy) 0x151f7c75,tmp%9#0 arc4.abimethod() template_variables/contract.py:6 + concat // {concat} arc4.abimethod() template_variables/contract.py:6 + // virtual: store tmp%10#0 to l-stack (no copy) tmp%10#0 arc4.abimethod() template_variables/contract.py:6 + // virtual: load tmp%10#0 from l-stack (no copy) tmp%10#0 arc4.abimethod() template_variables/contract.py:6 + log // arc4.abimethod() template_variables/contract.py:6 + int 1 // 1 arc4.abimethod() template_variables/contract.py:6 + return // arc4.abimethod() template_variables/contract.py:6 + +main_get_big_uint_route@3: + txn OnCompletion // {txn} arc4.abimethod() template_variables/contract.py:10 + // virtual: store tmp%11#0 to l-stack (no copy) tmp%11#0 arc4.abimethod() template_variables/contract.py:10 + // virtual: load tmp%11#0 from l-stack (no copy) tmp%11#0 arc4.abimethod() template_variables/contract.py:10 + ! // {!} arc4.abimethod() template_variables/contract.py:10 + // virtual: store tmp%12#0 to l-stack (no copy) tmp%12#0 arc4.abimethod() template_variables/contract.py:10 + // virtual: load tmp%12#0 from l-stack (no copy) tmp%12#0 arc4.abimethod() template_variables/contract.py:10 + assert // OnCompletion is NoOp // arc4.abimethod() template_variables/contract.py:10 + txn ApplicationID // {txn} arc4.abimethod() template_variables/contract.py:10 + // virtual: store tmp%13#0 to l-stack (no copy) tmp%13#0 arc4.abimethod() template_variables/contract.py:10 + // virtual: load tmp%13#0 from l-stack (no copy) tmp%13#0 arc4.abimethod() template_variables/contract.py:10 + assert // is not creating // arc4.abimethod() template_variables/contract.py:10 + callsub get_big_uint // {get_big_uint} arc4.abimethod() template_variables/contract.py:10 + // virtual: store tmp%14#0 to l-stack (no copy) tmp%14#0 arc4.abimethod() template_variables/contract.py:10 + byte 0x151f7c75 // tmp%14#0,0x151f7c75 arc4.abimethod() template_variables/contract.py:10 + swap // load tmp%14#0 from l-stack (no copy) 0x151f7c75,tmp%14#0 arc4.abimethod() template_variables/contract.py:10 + concat // {concat} arc4.abimethod() template_variables/contract.py:10 + // virtual: store tmp%15#0 to l-stack (no copy) tmp%15#0 arc4.abimethod() template_variables/contract.py:10 + // virtual: load tmp%15#0 from l-stack (no copy) tmp%15#0 arc4.abimethod() template_variables/contract.py:10 + log // arc4.abimethod() template_variables/contract.py:10 + int 1 // 1 arc4.abimethod() template_variables/contract.py:10 + return // arc4.abimethod() template_variables/contract.py:10 + +main_bare_routing@6: + txn OnCompletion // {txn} class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + // virtual: store tmp%16#0 to l-stack (no copy) tmp%16#0 class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + // virtual: load tmp%16#0 from l-stack (no copy) tmp%16#0 class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + switch main_create@7 main_reject_bare_on_completion@10 main_reject_bare_on_completion@10 main_reject_bare_on_completion@10 main_on_update@8 main_on_delete@9 // class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + err // reject transaction // class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + +main_create@7: + txn ApplicationID // {txn} class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + // virtual: store tmp%17#0 to l-stack (no copy) tmp%17#0 class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + // virtual: load tmp%17#0 from l-stack (no copy) tmp%17#0 class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + ! // {!} class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + // virtual: store tmp%18#0 to l-stack (no copy) tmp%18#0 class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + // virtual: load tmp%18#0 from l-stack (no copy) tmp%18#0 class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + assert // is creating // class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + int 1 // 1 class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + return // class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + +main_on_update@8: + txn ApplicationID // {txn} arc4.baremethod(allow_actions=["UpdateApplication"]) template_variables/contract.py:15 + // virtual: store tmp%19#0 to l-stack (no copy) tmp%19#0 arc4.baremethod(allow_actions=["UpdateApplication"]) template_variables/contract.py:15 + // virtual: load tmp%19#0 from l-stack (no copy) tmp%19#0 arc4.baremethod(allow_actions=["UpdateApplication"]) template_variables/contract.py:15 + assert // is not creating // arc4.baremethod(allow_actions=["UpdateApplication"]) template_variables/contract.py:15 + callsub on_update // @arc4.baremethod(allow_actions=["UpdateApplication"])\ndef on_update(self) -> None: template_variables/contract.py:15-16 + int 1 // 1 @arc4.baremethod(allow_actions=["UpdateApplication"])\ndef on_update(self) -> None: template_variables/contract.py:15-16 + return // @arc4.baremethod(allow_actions=["UpdateApplication"])\ndef on_update(self) -> None: template_variables/contract.py:15-16 + +main_on_delete@9: + txn ApplicationID // {txn} arc4.baremethod(allow_actions=["DeleteApplication"]) template_variables/contract.py:19 + // virtual: store tmp%20#0 to l-stack (no copy) tmp%20#0 arc4.baremethod(allow_actions=["DeleteApplication"]) template_variables/contract.py:19 + // virtual: load tmp%20#0 from l-stack (no copy) tmp%20#0 arc4.baremethod(allow_actions=["DeleteApplication"]) template_variables/contract.py:19 + assert // is not creating // arc4.baremethod(allow_actions=["DeleteApplication"]) template_variables/contract.py:19 + callsub on_delete // @arc4.baremethod(allow_actions=["DeleteApplication"])\ndef on_delete(self) -> None: template_variables/contract.py:19-20 + int 1 // 1 @arc4.baremethod(allow_actions=["DeleteApplication"])\ndef on_delete(self) -> None: template_variables/contract.py:19-20 + return // @arc4.baremethod(allow_actions=["DeleteApplication"])\ndef on_delete(self) -> None: template_variables/contract.py:19-20 + +main_reject_bare_on_completion@10: + err // reject transaction // class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + + +// test_cases.template_variables.contract.TemplateVariablesContract.get_bytes() -> bytes: +get_bytes: + proto 0 1 // @arc4.abimethod()\ndef get_bytes(self) -> Bytes: template_variables/contract.py:6-7 + +get_bytes_block@0: + byte TMPL_SOME_BYTES // TMPL_SOME_BYTES TemplateVar[Bytes]("SOME_BYTES") template_variables/contract.py:8 + retsub // TMPL_SOME_BYTES return TemplateVar[Bytes]("SOME_BYTES") template_variables/contract.py:8 + + +// test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint() -> bytes: +get_big_uint: + proto 0 1 // @arc4.abimethod()\ndef get_big_uint(self) -> UInt512: template_variables/contract.py:10-11 + +get_big_uint_block@0: + byte TMPL_SOME_BIG_UINT // TMPL_SOME_BIG_UINT TemplateVar[BigUInt]("SOME_BIG_UINT") template_variables/contract.py:12 + // virtual: store x#0 to l-stack (no copy) x#0 x = TemplateVar[BigUInt]("SOME_BIG_UINT") template_variables/contract.py:12 + dup // load x#0 from l-stack (copy) x#0,x#0 UInt512(x) template_variables/contract.py:13 + len // x#0,{len} UInt512(x) template_variables/contract.py:13 + // virtual: store len_%0#0 to l-stack (no copy) x#0,len_%0#0 UInt512(x) template_variables/contract.py:13 + // virtual: load len_%0#0 from l-stack (no copy) x#0,len_%0#0 UInt512(x) template_variables/contract.py:13 + int 64 // x#0,len_%0#0,64 UInt512(x) template_variables/contract.py:13 + <= // x#0,{<=} UInt512(x) template_variables/contract.py:13 + // virtual: store no_overflow%1#0 to l-stack (no copy) x#0,no_overflow%1#0 UInt512(x) template_variables/contract.py:13 + // virtual: load no_overflow%1#0 from l-stack (no copy) x#0,no_overflow%1#0 UInt512(x) template_variables/contract.py:13 + assert // overflow // x#0 UInt512(x) template_variables/contract.py:13 + int 64 // x#0,64 UInt512(x) template_variables/contract.py:13 + bzero // x#0,{bzero} UInt512(x) template_variables/contract.py:13 + // virtual: store b_zeros%2#0 to l-stack (no copy) x#0,b_zeros%2#0 UInt512(x) template_variables/contract.py:13 + // virtual: load x#0 from l-stack (no copy) b_zeros%2#0,x#0 UInt512(x) template_variables/contract.py:13 + // virtual: load b_zeros%2#0 from l-stack (no copy) x#0,b_zeros%2#0 UInt512(x) template_variables/contract.py:13 + b| // {b|} UInt512(x) template_variables/contract.py:13 + // virtual: store tmp%3#0 to l-stack (no copy) tmp%3#0 UInt512(x) template_variables/contract.py:13 + // virtual: load tmp%3#0 from l-stack (no copy) tmp%3#0 return UInt512(x) template_variables/contract.py:13 + retsub // tmp%3#0 return UInt512(x) template_variables/contract.py:13 + + +// test_cases.template_variables.contract.TemplateVariablesContract.on_update() -> void: +on_update: + proto 0 0 // @arc4.baremethod(allow_actions=["UpdateApplication"])\ndef on_update(self) -> None: template_variables/contract.py:15-16 + +on_update_block@0: + int TMPL_UPDATABLE // TMPL_UPDATABLE TemplateVar[bool]("UPDATABLE") template_variables/contract.py:17 + assert // assert TemplateVar[bool]("UPDATABLE") template_variables/contract.py:17 + retsub // + + +// test_cases.template_variables.contract.TemplateVariablesContract.on_delete() -> void: +on_delete: + proto 0 0 // @arc4.baremethod(allow_actions=["DeleteApplication"])\ndef on_delete(self) -> None: template_variables/contract.py:19-20 + +on_delete_block@0: + int TMPL_DELETABLE // TMPL_DELETABLE TemplateVar[UInt64]("DELETABLE") template_variables/contract.py:21 + assert // assert TemplateVar[UInt64]("DELETABLE") template_variables/contract.py:21 + retsub // + diff --git a/test_cases/template_variables/out/TemplateVariablesContract.approval.teal b/test_cases/template_variables/out/TemplateVariablesContract.approval.teal new file mode 100644 index 0000000000..3b7cf190f7 --- /dev/null +++ b/test_cases/template_variables/out/TemplateVariablesContract.approval.teal @@ -0,0 +1,155 @@ +#pragma version 10 + +test_cases.template_variables.contract.TemplateVariablesContract.approval_program: + // template_variables/contract.py:5 + // class TemplateVariablesContract(arc4.ARC4Contract): + txn NumAppArgs + bz main_bare_routing@6 + method "get_bytes()byte[]" + method "get_big_uint()uint512" + txna ApplicationArgs 0 + match main_get_bytes_route@2 main_get_big_uint_route@3 + err // reject transaction + +main_get_bytes_route@2: + // template_variables/contract.py:6 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + callsub get_bytes + dup + len + itob + substring 6 8 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_get_big_uint_route@3: + // template_variables/contract.py:10 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + callsub get_big_uint + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_bare_routing@6: + // template_variables/contract.py:5 + // class TemplateVariablesContract(arc4.ARC4Contract): + txn OnCompletion + switch main_create@7 main_reject_bare_on_completion@10 main_reject_bare_on_completion@10 main_reject_bare_on_completion@10 main_on_update@8 main_on_delete@9 + err // reject transaction + +main_create@7: + // template_variables/contract.py:5 + // class TemplateVariablesContract(arc4.ARC4Contract): + txn ApplicationID + ! + assert // is creating + int 1 + return + +main_on_update@8: + // template_variables/contract.py:15 + // @arc4.baremethod(allow_actions=["UpdateApplication"]) + txn ApplicationID + assert // is not creating + // template_variables/contract.py:15-16 + // @arc4.baremethod(allow_actions=["UpdateApplication"]) + // def on_update(self) -> None: + callsub on_update + int 1 + return + +main_on_delete@9: + // template_variables/contract.py:19 + // @arc4.baremethod(allow_actions=["DeleteApplication"]) + txn ApplicationID + assert // is not creating + // template_variables/contract.py:19-20 + // @arc4.baremethod(allow_actions=["DeleteApplication"]) + // def on_delete(self) -> None: + callsub on_delete + int 1 + return + +main_reject_bare_on_completion@10: + // template_variables/contract.py:5 + // class TemplateVariablesContract(arc4.ARC4Contract): + err // reject transaction + + +// test_cases.template_variables.contract.TemplateVariablesContract.get_bytes() -> bytes: +get_bytes: + // template_variables/contract.py:6-7 + // @arc4.abimethod() + // def get_bytes(self) -> Bytes: + proto 0 1 + // template_variables/contract.py:8 + // return TemplateVar[Bytes]("SOME_BYTES") + byte TMPL_SOME_BYTES + retsub + + +// test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint() -> bytes: +get_big_uint: + // template_variables/contract.py:10-11 + // @arc4.abimethod() + // def get_big_uint(self) -> UInt512: + proto 0 1 + // template_variables/contract.py:12 + // x = TemplateVar[BigUInt]("SOME_BIG_UINT") + byte TMPL_SOME_BIG_UINT + // template_variables/contract.py:13 + // return UInt512(x) + dup + len + int 64 + <= + assert // overflow + int 64 + bzero + b| + retsub + + +// test_cases.template_variables.contract.TemplateVariablesContract.on_update() -> void: +on_update: + // template_variables/contract.py:15-16 + // @arc4.baremethod(allow_actions=["UpdateApplication"]) + // def on_update(self) -> None: + proto 0 0 + // template_variables/contract.py:17 + // assert TemplateVar[bool]("UPDATABLE") + int TMPL_UPDATABLE + assert + retsub + + +// test_cases.template_variables.contract.TemplateVariablesContract.on_delete() -> void: +on_delete: + // template_variables/contract.py:19-20 + // @arc4.baremethod(allow_actions=["DeleteApplication"]) + // def on_delete(self) -> None: + proto 0 0 + // template_variables/contract.py:21 + // assert TemplateVar[UInt64]("DELETABLE") + int TMPL_DELETABLE + assert + retsub diff --git a/test_cases/template_variables/out/TemplateVariablesContract.arc32.json b/test_cases/template_variables/out/TemplateVariablesContract.arc32.json new file mode 100644 index 0000000000..8ec88c8720 --- /dev/null +++ b/test_cases/template_variables/out/TemplateVariablesContract.arc32.json @@ -0,0 +1,63 @@ +{ + "hints": { + "get_bytes()byte[]": { + "call_config": { + "no_op": "CALL" + } + }, + "get_big_uint()uint512": { + "call_config": { + "no_op": "CALL" + } + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnRlbXBsYXRlX3ZhcmlhYmxlcy5jb250cmFjdC5UZW1wbGF0ZVZhcmlhYmxlc0NvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZW1wbGF0ZV92YXJpYWJsZXMvY29udHJhY3QucHk6NQogICAgLy8gY2xhc3MgVGVtcGxhdGVWYXJpYWJsZXNDb250cmFjdChhcmM0LkFSQzRDb250cmFjdCk6CiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogbWFpbl9iYXJlX3JvdXRpbmdANgogICAgbWV0aG9kICJnZXRfYnl0ZXMoKWJ5dGVbXSIKICAgIG1ldGhvZCAiZ2V0X2JpZ191aW50KCl1aW50NTEyIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggbWFpbl9nZXRfYnl0ZXNfcm91dGVAMiBtYWluX2dldF9iaWdfdWludF9yb3V0ZUAzCiAgICBlcnIgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCgptYWluX2dldF9ieXRlc19yb3V0ZUAyOgogICAgLy8gdGVtcGxhdGVfdmFyaWFibGVzL2NvbnRyYWN0LnB5OjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIHN1YnN0cmluZyA2IDgKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9nZXRfYmlnX3VpbnRfcm91dGVAMzoKICAgIC8vIHRlbXBsYXRlX3ZhcmlhYmxlcy9jb250cmFjdC5weToxMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X2JpZ191aW50CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JhcmVfcm91dGluZ0A2OgogICAgLy8gdGVtcGxhdGVfdmFyaWFibGVzL2NvbnRyYWN0LnB5OjUKICAgIC8vIGNsYXNzIFRlbXBsYXRlVmFyaWFibGVzQ29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgc3dpdGNoIG1haW5fY3JlYXRlQDcgbWFpbl9yZWplY3RfYmFyZV9vbl9jb21wbGV0aW9uQDEwIG1haW5fcmVqZWN0X2JhcmVfb25fY29tcGxldGlvbkAxMCBtYWluX3JlamVjdF9iYXJlX29uX2NvbXBsZXRpb25AMTAgbWFpbl9vbl91cGRhdGVAOCBtYWluX29uX2RlbGV0ZUA5CiAgICBlcnIgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCgptYWluX2NyZWF0ZUA3OgogICAgLy8gdGVtcGxhdGVfdmFyaWFibGVzL2NvbnRyYWN0LnB5OjUKICAgIC8vIGNsYXNzIFRlbXBsYXRlVmFyaWFibGVzQ29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9vbl91cGRhdGVAODoKICAgIC8vIHRlbXBsYXRlX3ZhcmlhYmxlcy9jb250cmFjdC5weToxNQogICAgLy8gQGFyYzQuYmFyZW1ldGhvZChhbGxvd19hY3Rpb25zPVsiVXBkYXRlQXBwbGljYXRpb24iXSkKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZW1wbGF0ZV92YXJpYWJsZXMvY29udHJhY3QucHk6MTUtMTYKICAgIC8vIEBhcmM0LmJhcmVtZXRob2QoYWxsb3dfYWN0aW9ucz1bIlVwZGF0ZUFwcGxpY2F0aW9uIl0pCiAgICAvLyBkZWYgb25fdXBkYXRlKHNlbGYpIC0+IE5vbmU6CiAgICBjYWxsc3ViIG9uX3VwZGF0ZQogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9vbl9kZWxldGVAOToKICAgIC8vIHRlbXBsYXRlX3ZhcmlhYmxlcy9jb250cmFjdC5weToxOQogICAgLy8gQGFyYzQuYmFyZW1ldGhvZChhbGxvd19hY3Rpb25zPVsiRGVsZXRlQXBwbGljYXRpb24iXSkKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZW1wbGF0ZV92YXJpYWJsZXMvY29udHJhY3QucHk6MTktMjAKICAgIC8vIEBhcmM0LmJhcmVtZXRob2QoYWxsb3dfYWN0aW9ucz1bIkRlbGV0ZUFwcGxpY2F0aW9uIl0pCiAgICAvLyBkZWYgb25fZGVsZXRlKHNlbGYpIC0+IE5vbmU6CiAgICBjYWxsc3ViIG9uX2RlbGV0ZQogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9yZWplY3RfYmFyZV9vbl9jb21wbGV0aW9uQDEwOgogICAgLy8gdGVtcGxhdGVfdmFyaWFibGVzL2NvbnRyYWN0LnB5OjUKICAgIC8vIGNsYXNzIFRlbXBsYXRlVmFyaWFibGVzQ29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKCi8vIHRlc3RfY2FzZXMudGVtcGxhdGVfdmFyaWFibGVzLmNvbnRyYWN0LlRlbXBsYXRlVmFyaWFibGVzQ29udHJhY3QuZ2V0X2J5dGVzKCkgLT4gYnl0ZXM6CmdldF9ieXRlczoKICAgIC8vIHRlbXBsYXRlX3ZhcmlhYmxlcy9jb250cmFjdC5weTo2LTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ2V0X2J5dGVzKHNlbGYpIC0+IEJ5dGVzOgogICAgcHJvdG8gMCAxCiAgICAvLyB0ZW1wbGF0ZV92YXJpYWJsZXMvY29udHJhY3QucHk6OAogICAgLy8gcmV0dXJuIFRlbXBsYXRlVmFyW0J5dGVzXSgiU09NRV9CWVRFUyIpCiAgICBieXRlIFRNUExfU09NRV9CWVRFUwogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy50ZW1wbGF0ZV92YXJpYWJsZXMuY29udHJhY3QuVGVtcGxhdGVWYXJpYWJsZXNDb250cmFjdC5nZXRfYmlnX3VpbnQoKSAtPiBieXRlczoKZ2V0X2JpZ191aW50OgogICAgLy8gdGVtcGxhdGVfdmFyaWFibGVzL2NvbnRyYWN0LnB5OjEwLTExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9iaWdfdWludChzZWxmKSAtPiBVSW50NTEyOgogICAgcHJvdG8gMCAxCiAgICAvLyB0ZW1wbGF0ZV92YXJpYWJsZXMvY29udHJhY3QucHk6MTIKICAgIC8vIHggPSBUZW1wbGF0ZVZhcltCaWdVSW50XSgiU09NRV9CSUdfVUlOVCIpCiAgICBieXRlIFRNUExfU09NRV9CSUdfVUlOVAogICAgLy8gdGVtcGxhdGVfdmFyaWFibGVzL2NvbnRyYWN0LnB5OjEzCiAgICAvLyByZXR1cm4gVUludDUxMih4KQogICAgZHVwCiAgICBsZW4KICAgIGludCA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50IDY0CiAgICBiemVybwogICAgYnwKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMudGVtcGxhdGVfdmFyaWFibGVzLmNvbnRyYWN0LlRlbXBsYXRlVmFyaWFibGVzQ29udHJhY3Qub25fdXBkYXRlKCkgLT4gdm9pZDoKb25fdXBkYXRlOgogICAgLy8gdGVtcGxhdGVfdmFyaWFibGVzL2NvbnRyYWN0LnB5OjE1LTE2CiAgICAvLyBAYXJjNC5iYXJlbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJVcGRhdGVBcHBsaWNhdGlvbiJdKQogICAgLy8gZGVmIG9uX3VwZGF0ZShzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyB0ZW1wbGF0ZV92YXJpYWJsZXMvY29udHJhY3QucHk6MTcKICAgIC8vIGFzc2VydCBUZW1wbGF0ZVZhcltib29sXSgiVVBEQVRBQkxFIikKICAgIGludCBUTVBMX1VQREFUQUJMRQogICAgYXNzZXJ0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLnRlbXBsYXRlX3ZhcmlhYmxlcy5jb250cmFjdC5UZW1wbGF0ZVZhcmlhYmxlc0NvbnRyYWN0Lm9uX2RlbGV0ZSgpIC0+IHZvaWQ6Cm9uX2RlbGV0ZToKICAgIC8vIHRlbXBsYXRlX3ZhcmlhYmxlcy9jb250cmFjdC5weToxOS0yMAogICAgLy8gQGFyYzQuYmFyZW1ldGhvZChhbGxvd19hY3Rpb25zPVsiRGVsZXRlQXBwbGljYXRpb24iXSkKICAgIC8vIGRlZiBvbl9kZWxldGUoc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gdGVtcGxhdGVfdmFyaWFibGVzL2NvbnRyYWN0LnB5OjIxCiAgICAvLyBhc3NlcnQgVGVtcGxhdGVWYXJbVUludDY0XSgiREVMRVRBQkxFIikKICAgIGludCBUTVBMX0RFTEVUQUJMRQogICAgYXNzZXJ0CiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnRlbXBsYXRlX3ZhcmlhYmxlcy5jb250cmFjdC5UZW1wbGF0ZVZhcmlhYmxlc0NvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZW1wbGF0ZV92YXJpYWJsZXMvY29udHJhY3QucHk6NQogICAgLy8gY2xhc3MgVGVtcGxhdGVWYXJpYWJsZXNDb250cmFjdChhcmM0LkFSQzRDb250cmFjdCk6CiAgICBpbnQgMQogICAgcmV0dXJuCg==" + }, + "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": "TemplateVariablesContract", + "methods": [ + { + "name": "get_bytes", + "args": [], + "returns": { + "type": "byte[]" + } + }, + { + "name": "get_big_uint", + "args": [], + "returns": { + "type": "uint512" + } + } + ], + "networks": {} + }, + "bare_call_config": { + "update_application": "CALL", + "delete_application": "CALL", + "no_op": "CREATE" + } +} \ No newline at end of file diff --git a/test_cases/template_variables/out/TemplateVariablesContract.clear.mir b/test_cases/template_variables/out/TemplateVariablesContract.clear.mir new file mode 100644 index 0000000000..ed988808b0 --- /dev/null +++ b/test_cases/template_variables/out/TemplateVariablesContract.clear.mir @@ -0,0 +1,9 @@ +// Op // Stack (out) Source code Source line + +#pragma version 10 + +// test_cases.template_variables.contract.TemplateVariablesContract.clear_state_program() -> uint64: +main_block@0: + int 1 // 1 class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + return // class TemplateVariablesContract(arc4.ARC4Contract): template_variables/contract.py:5 + diff --git a/test_cases/template_variables/out/TemplateVariablesContract.clear.teal b/test_cases/template_variables/out/TemplateVariablesContract.clear.teal new file mode 100644 index 0000000000..cacf6dfefe --- /dev/null +++ b/test_cases/template_variables/out/TemplateVariablesContract.clear.teal @@ -0,0 +1,7 @@ +#pragma version 10 + +test_cases.template_variables.contract.TemplateVariablesContract.clear_state_program: + // template_variables/contract.py:5 + // class TemplateVariablesContract(arc4.ARC4Contract): + int 1 + return diff --git a/test_cases/template_variables/out/TemplateVariablesContract.destructured.ir b/test_cases/template_variables/out/TemplateVariablesContract.destructured.ir new file mode 100644 index 0000000000..d21218c290 --- /dev/null +++ b/test_cases/template_variables/out/TemplateVariablesContract.destructured.ir @@ -0,0 +1,82 @@ +contract test_cases.template_variables.contract.TemplateVariablesContract: + program approval: + subroutine test_cases.template_variables.contract.TemplateVariablesContract.approval_program() -> uint64: + block@0: // L5 + let tmp%0#0: uint64 = (txn NumAppArgs) + goto tmp%0#0 ? block@1 : block@6 + block@1: // abi_routing_L5 + let tmp%1#0: bytes = (txna ApplicationArgs 0) + switch tmp%1#0 {method "get_bytes()byte[]" => block@2, method "get_big_uint()uint512" => block@3, * => fail // reject transaction} + block@2: // get_bytes_route_L6 + let tmp%2#0: uint64 = (txn OnCompletion) + let tmp%3#0: uint64 = (! tmp%2#0) + (assert tmp%3#0) // OnCompletion is NoOp + let tmp%4#0: uint64 = (txn ApplicationID) + (assert tmp%4#0) // is not creating + let awst_tmp%5#0: bytes = test_cases.template_variables.contract.TemplateVariablesContract.get_bytes() + let tmp%6#0: uint64 = (len awst_tmp%5#0) + let tmp%7#0: bytes = (itob tmp%6#0) + let tmp%8#0: bytes = ((substring 6 8) tmp%7#0) + let tmp%9#0: bytes = (concat tmp%8#0 awst_tmp%5#0) + let tmp%10#0: bytes = (concat 0x151f7c75 tmp%9#0) + (log tmp%10#0) + return 1u + block@3: // get_big_uint_route_L10 + let tmp%11#0: uint64 = (txn OnCompletion) + let tmp%12#0: uint64 = (! tmp%11#0) + (assert tmp%12#0) // OnCompletion is NoOp + let tmp%13#0: uint64 = (txn ApplicationID) + (assert tmp%13#0) // is not creating + let tmp%14#0: bytes = test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint() + let tmp%15#0: bytes = (concat 0x151f7c75 tmp%14#0) + (log tmp%15#0) + return 1u + block@6: // bare_routing_L5 + let tmp%16#0: uint64 = (txn OnCompletion) + goto_nth [block@7, block@10, block@10, block@10, block@8, block@9][tmp%16#0] else fail // reject transaction + block@7: // create_L5 + let tmp%17#0: uint64 = (txn ApplicationID) + let tmp%18#0: uint64 = (! tmp%17#0) + (assert tmp%18#0) // is creating + return 1u + block@8: // on_update_L15 + let tmp%19#0: uint64 = (txn ApplicationID) + (assert tmp%19#0) // is not creating + test_cases.template_variables.contract.TemplateVariablesContract.on_update() + return 1u + block@9: // on_delete_L19 + let tmp%20#0: uint64 = (txn ApplicationID) + (assert tmp%20#0) // is not creating + test_cases.template_variables.contract.TemplateVariablesContract.on_delete() + return 1u + block@10: // reject_bare_on_completion_L5 + fail // reject transaction + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.get_bytes() -> bytes: + block@0: // L6 + return TemplateVar[AVMType.bytes](TMPL_SOME_BYTES) + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint() -> bytes: + block@0: // L10 + let x#0: bytes = TemplateVar[AVMType.bytes](TMPL_SOME_BIG_UINT) + let len_%0#0: uint64 = (len x#0) + let no_overflow%1#0: uint64 = (<= len_%0#0 64u) + (assert no_overflow%1#0) // overflow + let b_zeros%2#0: bytes = (bzero 64u) + let tmp%3#0: bytes = (b| x#0 b_zeros%2#0) + return tmp%3#0 + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.on_update() -> void: + block@0: // L15 + (assert TemplateVar[AVMType.uint64](TMPL_UPDATABLE)) + return + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.on_delete() -> void: + block@0: // L19 + (assert TemplateVar[AVMType.uint64](TMPL_DELETABLE)) + return + + program clear-state: + subroutine test_cases.template_variables.contract.TemplateVariablesContract.clear_state_program() -> uint64: + block@0: // L5 + return 1u \ No newline at end of file diff --git a/test_cases/template_variables/out/TemplateVariablesContract.ssa.ir b/test_cases/template_variables/out/TemplateVariablesContract.ssa.ir new file mode 100644 index 0000000000..51f8f9f792 --- /dev/null +++ b/test_cases/template_variables/out/TemplateVariablesContract.ssa.ir @@ -0,0 +1,88 @@ +contract test_cases.template_variables.contract.TemplateVariablesContract: + program approval: + subroutine test_cases.template_variables.contract.TemplateVariablesContract.approval_program() -> uint64: + block@0: // L5 + let tmp%0#0: uint64 = (txn NumAppArgs) + goto tmp%0#0 ? block@1 : block@6 + block@1: // abi_routing_L5 + let tmp%1#0: bytes = (txna ApplicationArgs 0) + switch tmp%1#0 {method "get_bytes()byte[]" => block@2, method "get_big_uint()uint512" => block@3, * => block@4} + block@2: // get_bytes_route_L6 + let tmp%2#0: uint64 = (txn OnCompletion) + let tmp%3#0: uint64 = (== tmp%2#0 NoOp) + (assert tmp%3#0) // OnCompletion is NoOp + let tmp%4#0: uint64 = (txn ApplicationID) + (assert tmp%4#0) // is not creating + let awst_tmp%5#0: bytes = test_cases.template_variables.contract.TemplateVariablesContract.get_bytes() + let tmp%6#0: uint64 = (len awst_tmp%5#0) + let tmp%7#0: bytes = (itob tmp%6#0) + let tmp%8#0: bytes = ((substring 6 8) tmp%7#0) + let tmp%9#0: bytes = (concat tmp%8#0 awst_tmp%5#0) + let tmp%10#0: bytes = (concat 0x151f7c75 tmp%9#0) + (log tmp%10#0) + return 1u + block@3: // get_big_uint_route_L10 + let tmp%11#0: uint64 = (txn OnCompletion) + let tmp%12#0: uint64 = (== tmp%11#0 NoOp) + (assert tmp%12#0) // OnCompletion is NoOp + let tmp%13#0: uint64 = (txn ApplicationID) + (assert tmp%13#0) // is not creating + let tmp%14#0: bytes = test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint() + let tmp%15#0: bytes = (concat 0x151f7c75 tmp%14#0) + (log tmp%15#0) + return 1u + block@4: // switch_case_default_L5 + goto block@5 + block@5: // switch_case_next_L5 + goto block@11 + block@6: // bare_routing_L5 + let tmp%16#0: uint64 = (txn OnCompletion) + switch tmp%16#0 {0u => block@7, 4u => block@8, 5u => block@9, * => block@10} + block@7: // create_L5 + let tmp%17#0: uint64 = (txn ApplicationID) + let tmp%18#0: uint64 = (! tmp%17#0) + (assert tmp%18#0) // is creating + return 1u + block@8: // on_update_L15 + let tmp%19#0: uint64 = (txn ApplicationID) + (assert tmp%19#0) // is not creating + test_cases.template_variables.contract.TemplateVariablesContract.on_update() + return 1u + block@9: // on_delete_L19 + let tmp%20#0: uint64 = (txn ApplicationID) + (assert tmp%20#0) // is not creating + test_cases.template_variables.contract.TemplateVariablesContract.on_delete() + return 1u + block@10: // reject_bare_on_completion_L5 + fail // reject transaction + block@11: // after_if_else_L5 + fail // reject transaction + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.get_bytes() -> bytes: + block@0: // L6 + return TemplateVar[AVMType.bytes](TMPL_SOME_BYTES) + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint() -> bytes: + block@0: // L10 + let x#0: bytes = TemplateVar[AVMType.bytes](TMPL_SOME_BIG_UINT) + let len_%0#0: uint64 = (len x#0) + let no_overflow%1#0: uint64 = (<= len_%0#0 64u) + (assert no_overflow%1#0) // overflow + let b_zeros%2#0: bytes = (bzero 64u) + let tmp%3#0: bytes = (b| x#0 b_zeros%2#0) + return tmp%3#0 + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.on_update() -> void: + block@0: // L15 + (assert TemplateVar[AVMType.uint64](TMPL_UPDATABLE)) + return + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.on_delete() -> void: + block@0: // L19 + (assert TemplateVar[AVMType.uint64](TMPL_DELETABLE)) + return + + program clear-state: + subroutine test_cases.template_variables.contract.TemplateVariablesContract.clear_state_program() -> uint64: + block@0: // L5 + return 1u \ No newline at end of file diff --git a/test_cases/template_variables/out/TemplateVariablesContract.ssa.opt_pass_1.ir b/test_cases/template_variables/out/TemplateVariablesContract.ssa.opt_pass_1.ir new file mode 100644 index 0000000000..d21218c290 --- /dev/null +++ b/test_cases/template_variables/out/TemplateVariablesContract.ssa.opt_pass_1.ir @@ -0,0 +1,82 @@ +contract test_cases.template_variables.contract.TemplateVariablesContract: + program approval: + subroutine test_cases.template_variables.contract.TemplateVariablesContract.approval_program() -> uint64: + block@0: // L5 + let tmp%0#0: uint64 = (txn NumAppArgs) + goto tmp%0#0 ? block@1 : block@6 + block@1: // abi_routing_L5 + let tmp%1#0: bytes = (txna ApplicationArgs 0) + switch tmp%1#0 {method "get_bytes()byte[]" => block@2, method "get_big_uint()uint512" => block@3, * => fail // reject transaction} + block@2: // get_bytes_route_L6 + let tmp%2#0: uint64 = (txn OnCompletion) + let tmp%3#0: uint64 = (! tmp%2#0) + (assert tmp%3#0) // OnCompletion is NoOp + let tmp%4#0: uint64 = (txn ApplicationID) + (assert tmp%4#0) // is not creating + let awst_tmp%5#0: bytes = test_cases.template_variables.contract.TemplateVariablesContract.get_bytes() + let tmp%6#0: uint64 = (len awst_tmp%5#0) + let tmp%7#0: bytes = (itob tmp%6#0) + let tmp%8#0: bytes = ((substring 6 8) tmp%7#0) + let tmp%9#0: bytes = (concat tmp%8#0 awst_tmp%5#0) + let tmp%10#0: bytes = (concat 0x151f7c75 tmp%9#0) + (log tmp%10#0) + return 1u + block@3: // get_big_uint_route_L10 + let tmp%11#0: uint64 = (txn OnCompletion) + let tmp%12#0: uint64 = (! tmp%11#0) + (assert tmp%12#0) // OnCompletion is NoOp + let tmp%13#0: uint64 = (txn ApplicationID) + (assert tmp%13#0) // is not creating + let tmp%14#0: bytes = test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint() + let tmp%15#0: bytes = (concat 0x151f7c75 tmp%14#0) + (log tmp%15#0) + return 1u + block@6: // bare_routing_L5 + let tmp%16#0: uint64 = (txn OnCompletion) + goto_nth [block@7, block@10, block@10, block@10, block@8, block@9][tmp%16#0] else fail // reject transaction + block@7: // create_L5 + let tmp%17#0: uint64 = (txn ApplicationID) + let tmp%18#0: uint64 = (! tmp%17#0) + (assert tmp%18#0) // is creating + return 1u + block@8: // on_update_L15 + let tmp%19#0: uint64 = (txn ApplicationID) + (assert tmp%19#0) // is not creating + test_cases.template_variables.contract.TemplateVariablesContract.on_update() + return 1u + block@9: // on_delete_L19 + let tmp%20#0: uint64 = (txn ApplicationID) + (assert tmp%20#0) // is not creating + test_cases.template_variables.contract.TemplateVariablesContract.on_delete() + return 1u + block@10: // reject_bare_on_completion_L5 + fail // reject transaction + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.get_bytes() -> bytes: + block@0: // L6 + return TemplateVar[AVMType.bytes](TMPL_SOME_BYTES) + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint() -> bytes: + block@0: // L10 + let x#0: bytes = TemplateVar[AVMType.bytes](TMPL_SOME_BIG_UINT) + let len_%0#0: uint64 = (len x#0) + let no_overflow%1#0: uint64 = (<= len_%0#0 64u) + (assert no_overflow%1#0) // overflow + let b_zeros%2#0: bytes = (bzero 64u) + let tmp%3#0: bytes = (b| x#0 b_zeros%2#0) + return tmp%3#0 + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.on_update() -> void: + block@0: // L15 + (assert TemplateVar[AVMType.uint64](TMPL_UPDATABLE)) + return + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.on_delete() -> void: + block@0: // L19 + (assert TemplateVar[AVMType.uint64](TMPL_DELETABLE)) + return + + program clear-state: + subroutine test_cases.template_variables.contract.TemplateVariablesContract.clear_state_program() -> uint64: + block@0: // L5 + return 1u \ No newline at end of file diff --git a/test_cases/template_variables/out/contract.awst b/test_cases/template_variables/out/contract.awst new file mode 100644 index 0000000000..797d17f096 --- /dev/null +++ b/test_cases/template_variables/out/contract.awst @@ -0,0 +1,23 @@ +contract TemplateVariablesContract +{ + abimethod get_bytes(): puyapy.Bytes + { + return TemplateVar[puyapy.Bytes](TMPL_SOME_BYTES) + } + + abimethod get_big_uint(): puyapy.arc4.BigUIntN[typing.Literal[512]] + { + x: puyapy.BigUInt = TemplateVar[puyapy.BigUInt](TMPL_SOME_BIG_UINT) + return arc4_encode(x, puyapy.arc4.BigUIntN[typing.Literal[512]]) + } + + abimethod on_update(): None + { + assert(TemplateVar[bool](TMPL_UPDATABLE)) + } + + abimethod on_delete(): None + { + assert(reinterpret_cast(TemplateVar[puyapy.UInt64](TMPL_DELETABLE))) + } +} \ No newline at end of file diff --git a/test_cases/template_variables/out_O2/TemplateVariablesContract.approval.teal b/test_cases/template_variables/out_O2/TemplateVariablesContract.approval.teal new file mode 100644 index 0000000000..f7e5db4946 --- /dev/null +++ b/test_cases/template_variables/out_O2/TemplateVariablesContract.approval.teal @@ -0,0 +1,111 @@ +#pragma version 10 + +test_cases.template_variables.contract.TemplateVariablesContract.approval_program: + txn NumAppArgs + bz main_bare_routing@6 + method "get_bytes()byte[]" + method "get_big_uint()uint512" + txna ApplicationArgs 0 + match main_get_bytes_route@2 main_get_big_uint_route@3 + err // reject transaction + +main_get_bytes_route@2: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + callsub get_bytes + dup + len + itob + substring 6 8 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_get_big_uint_route@3: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + callsub get_big_uint + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_bare_routing@6: + txn OnCompletion + switch main_create@7 main_reject_bare_on_completion@10 main_reject_bare_on_completion@10 main_reject_bare_on_completion@10 main_on_update@8 main_on_delete@9 + err // reject transaction + +main_create@7: + txn ApplicationID + ! + assert // is creating + int 1 + return + +main_on_update@8: + txn ApplicationID + assert // is not creating + callsub on_update + int 1 + return + +main_on_delete@9: + txn ApplicationID + assert // is not creating + callsub on_delete + int 1 + return + +main_reject_bare_on_completion@10: + err // reject transaction + + +// test_cases.template_variables.contract.TemplateVariablesContract.get_bytes() -> bytes: +get_bytes: + proto 0 1 + byte TMPL_SOME_BYTES + retsub + + +// test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint() -> bytes: +get_big_uint: + proto 0 1 + byte TMPL_SOME_BIG_UINT + dup + len + int 64 + <= + assert // overflow + int 64 + bzero + b| + retsub + + +// test_cases.template_variables.contract.TemplateVariablesContract.on_update() -> void: +on_update: + proto 0 0 + int TMPL_UPDATABLE + assert + retsub + + +// test_cases.template_variables.contract.TemplateVariablesContract.on_delete() -> void: +on_delete: + proto 0 0 + int TMPL_DELETABLE + assert + retsub diff --git a/test_cases/template_variables/out_O2/TemplateVariablesContract.clear.teal b/test_cases/template_variables/out_O2/TemplateVariablesContract.clear.teal new file mode 100644 index 0000000000..f7f4225e93 --- /dev/null +++ b/test_cases/template_variables/out_O2/TemplateVariablesContract.clear.teal @@ -0,0 +1,5 @@ +#pragma version 10 + +test_cases.template_variables.contract.TemplateVariablesContract.clear_state_program: + int 1 + return diff --git a/test_cases/template_variables/out_O2/TemplateVariablesContract.destructured.ir b/test_cases/template_variables/out_O2/TemplateVariablesContract.destructured.ir new file mode 100644 index 0000000000..d21218c290 --- /dev/null +++ b/test_cases/template_variables/out_O2/TemplateVariablesContract.destructured.ir @@ -0,0 +1,82 @@ +contract test_cases.template_variables.contract.TemplateVariablesContract: + program approval: + subroutine test_cases.template_variables.contract.TemplateVariablesContract.approval_program() -> uint64: + block@0: // L5 + let tmp%0#0: uint64 = (txn NumAppArgs) + goto tmp%0#0 ? block@1 : block@6 + block@1: // abi_routing_L5 + let tmp%1#0: bytes = (txna ApplicationArgs 0) + switch tmp%1#0 {method "get_bytes()byte[]" => block@2, method "get_big_uint()uint512" => block@3, * => fail // reject transaction} + block@2: // get_bytes_route_L6 + let tmp%2#0: uint64 = (txn OnCompletion) + let tmp%3#0: uint64 = (! tmp%2#0) + (assert tmp%3#0) // OnCompletion is NoOp + let tmp%4#0: uint64 = (txn ApplicationID) + (assert tmp%4#0) // is not creating + let awst_tmp%5#0: bytes = test_cases.template_variables.contract.TemplateVariablesContract.get_bytes() + let tmp%6#0: uint64 = (len awst_tmp%5#0) + let tmp%7#0: bytes = (itob tmp%6#0) + let tmp%8#0: bytes = ((substring 6 8) tmp%7#0) + let tmp%9#0: bytes = (concat tmp%8#0 awst_tmp%5#0) + let tmp%10#0: bytes = (concat 0x151f7c75 tmp%9#0) + (log tmp%10#0) + return 1u + block@3: // get_big_uint_route_L10 + let tmp%11#0: uint64 = (txn OnCompletion) + let tmp%12#0: uint64 = (! tmp%11#0) + (assert tmp%12#0) // OnCompletion is NoOp + let tmp%13#0: uint64 = (txn ApplicationID) + (assert tmp%13#0) // is not creating + let tmp%14#0: bytes = test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint() + let tmp%15#0: bytes = (concat 0x151f7c75 tmp%14#0) + (log tmp%15#0) + return 1u + block@6: // bare_routing_L5 + let tmp%16#0: uint64 = (txn OnCompletion) + goto_nth [block@7, block@10, block@10, block@10, block@8, block@9][tmp%16#0] else fail // reject transaction + block@7: // create_L5 + let tmp%17#0: uint64 = (txn ApplicationID) + let tmp%18#0: uint64 = (! tmp%17#0) + (assert tmp%18#0) // is creating + return 1u + block@8: // on_update_L15 + let tmp%19#0: uint64 = (txn ApplicationID) + (assert tmp%19#0) // is not creating + test_cases.template_variables.contract.TemplateVariablesContract.on_update() + return 1u + block@9: // on_delete_L19 + let tmp%20#0: uint64 = (txn ApplicationID) + (assert tmp%20#0) // is not creating + test_cases.template_variables.contract.TemplateVariablesContract.on_delete() + return 1u + block@10: // reject_bare_on_completion_L5 + fail // reject transaction + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.get_bytes() -> bytes: + block@0: // L6 + return TemplateVar[AVMType.bytes](TMPL_SOME_BYTES) + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint() -> bytes: + block@0: // L10 + let x#0: bytes = TemplateVar[AVMType.bytes](TMPL_SOME_BIG_UINT) + let len_%0#0: uint64 = (len x#0) + let no_overflow%1#0: uint64 = (<= len_%0#0 64u) + (assert no_overflow%1#0) // overflow + let b_zeros%2#0: bytes = (bzero 64u) + let tmp%3#0: bytes = (b| x#0 b_zeros%2#0) + return tmp%3#0 + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.on_update() -> void: + block@0: // L15 + (assert TemplateVar[AVMType.uint64](TMPL_UPDATABLE)) + return + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.on_delete() -> void: + block@0: // L19 + (assert TemplateVar[AVMType.uint64](TMPL_DELETABLE)) + return + + program clear-state: + subroutine test_cases.template_variables.contract.TemplateVariablesContract.clear_state_program() -> uint64: + block@0: // L5 + return 1u \ No newline at end of file diff --git a/test_cases/template_variables/out_unoptimized/TemplateVariablesContract.approval.teal b/test_cases/template_variables/out_unoptimized/TemplateVariablesContract.approval.teal new file mode 100644 index 0000000000..64b51d131e --- /dev/null +++ b/test_cases/template_variables/out_unoptimized/TemplateVariablesContract.approval.teal @@ -0,0 +1,170 @@ +#pragma version 10 + +test_cases.template_variables.contract.TemplateVariablesContract.approval_program: + // template_variables/contract.py:5 + // class TemplateVariablesContract(arc4.ARC4Contract): + txn NumAppArgs + bz main_bare_routing@6 + txna ApplicationArgs 0 + method "get_bytes()byte[]" + method "get_big_uint()uint512" + uncover 2 + match main_get_bytes_route@2 main_get_big_uint_route@3 + b main_switch_case_default@4 + +main_get_bytes_route@2: + // template_variables/contract.py:6 + // @arc4.abimethod() + txn OnCompletion + int NoOp + == + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + callsub get_bytes + dup + len + itob + substring 6 8 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_get_big_uint_route@3: + // template_variables/contract.py:10 + // @arc4.abimethod() + txn OnCompletion + int NoOp + == + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + callsub get_big_uint + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_switch_case_default@4: + b main_after_if_else@11 + +main_bare_routing@6: + // template_variables/contract.py:5 + // class TemplateVariablesContract(arc4.ARC4Contract): + txn OnCompletion + int 0 + int 4 + int 5 + uncover 3 + match main_create@7 main_on_update@8 main_on_delete@9 + b main_reject_bare_on_completion@10 + +main_create@7: + // template_variables/contract.py:5 + // class TemplateVariablesContract(arc4.ARC4Contract): + txn ApplicationID + ! + assert // is creating + int 1 + return + +main_on_update@8: + // template_variables/contract.py:15 + // @arc4.baremethod(allow_actions=["UpdateApplication"]) + txn ApplicationID + assert // is not creating + // template_variables/contract.py:15-16 + // @arc4.baremethod(allow_actions=["UpdateApplication"]) + // def on_update(self) -> None: + callsub on_update + int 1 + return + +main_on_delete@9: + // template_variables/contract.py:19 + // @arc4.baremethod(allow_actions=["DeleteApplication"]) + txn ApplicationID + assert // is not creating + // template_variables/contract.py:19-20 + // @arc4.baremethod(allow_actions=["DeleteApplication"]) + // def on_delete(self) -> None: + callsub on_delete + int 1 + return + +main_reject_bare_on_completion@10: + // template_variables/contract.py:5 + // class TemplateVariablesContract(arc4.ARC4Contract): + err // reject transaction + +main_after_if_else@11: + // template_variables/contract.py:5 + // class TemplateVariablesContract(arc4.ARC4Contract): + err // reject transaction + + +// test_cases.template_variables.contract.TemplateVariablesContract.get_bytes() -> bytes: +get_bytes: + // template_variables/contract.py:6-7 + // @arc4.abimethod() + // def get_bytes(self) -> Bytes: + proto 0 1 + // template_variables/contract.py:8 + // return TemplateVar[Bytes]("SOME_BYTES") + byte TMPL_SOME_BYTES + retsub + + +// test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint() -> bytes: +get_big_uint: + // template_variables/contract.py:10-11 + // @arc4.abimethod() + // def get_big_uint(self) -> UInt512: + proto 0 1 + // template_variables/contract.py:12 + // x = TemplateVar[BigUInt]("SOME_BIG_UINT") + byte TMPL_SOME_BIG_UINT + // template_variables/contract.py:13 + // return UInt512(x) + dup + len + int 64 + <= + assert // overflow + int 64 + bzero + b| + retsub + + +// test_cases.template_variables.contract.TemplateVariablesContract.on_update() -> void: +on_update: + // template_variables/contract.py:15-16 + // @arc4.baremethod(allow_actions=["UpdateApplication"]) + // def on_update(self) -> None: + proto 0 0 + // template_variables/contract.py:17 + // assert TemplateVar[bool]("UPDATABLE") + int TMPL_UPDATABLE + assert + retsub + + +// test_cases.template_variables.contract.TemplateVariablesContract.on_delete() -> void: +on_delete: + // template_variables/contract.py:19-20 + // @arc4.baremethod(allow_actions=["DeleteApplication"]) + // def on_delete(self) -> None: + proto 0 0 + // template_variables/contract.py:21 + // assert TemplateVar[UInt64]("DELETABLE") + int TMPL_DELETABLE + assert + retsub diff --git a/test_cases/template_variables/out_unoptimized/TemplateVariablesContract.clear.teal b/test_cases/template_variables/out_unoptimized/TemplateVariablesContract.clear.teal new file mode 100644 index 0000000000..cacf6dfefe --- /dev/null +++ b/test_cases/template_variables/out_unoptimized/TemplateVariablesContract.clear.teal @@ -0,0 +1,7 @@ +#pragma version 10 + +test_cases.template_variables.contract.TemplateVariablesContract.clear_state_program: + // template_variables/contract.py:5 + // class TemplateVariablesContract(arc4.ARC4Contract): + int 1 + return diff --git a/test_cases/template_variables/out_unoptimized/TemplateVariablesContract.destructured.ir b/test_cases/template_variables/out_unoptimized/TemplateVariablesContract.destructured.ir new file mode 100644 index 0000000000..51f8f9f792 --- /dev/null +++ b/test_cases/template_variables/out_unoptimized/TemplateVariablesContract.destructured.ir @@ -0,0 +1,88 @@ +contract test_cases.template_variables.contract.TemplateVariablesContract: + program approval: + subroutine test_cases.template_variables.contract.TemplateVariablesContract.approval_program() -> uint64: + block@0: // L5 + let tmp%0#0: uint64 = (txn NumAppArgs) + goto tmp%0#0 ? block@1 : block@6 + block@1: // abi_routing_L5 + let tmp%1#0: bytes = (txna ApplicationArgs 0) + switch tmp%1#0 {method "get_bytes()byte[]" => block@2, method "get_big_uint()uint512" => block@3, * => block@4} + block@2: // get_bytes_route_L6 + let tmp%2#0: uint64 = (txn OnCompletion) + let tmp%3#0: uint64 = (== tmp%2#0 NoOp) + (assert tmp%3#0) // OnCompletion is NoOp + let tmp%4#0: uint64 = (txn ApplicationID) + (assert tmp%4#0) // is not creating + let awst_tmp%5#0: bytes = test_cases.template_variables.contract.TemplateVariablesContract.get_bytes() + let tmp%6#0: uint64 = (len awst_tmp%5#0) + let tmp%7#0: bytes = (itob tmp%6#0) + let tmp%8#0: bytes = ((substring 6 8) tmp%7#0) + let tmp%9#0: bytes = (concat tmp%8#0 awst_tmp%5#0) + let tmp%10#0: bytes = (concat 0x151f7c75 tmp%9#0) + (log tmp%10#0) + return 1u + block@3: // get_big_uint_route_L10 + let tmp%11#0: uint64 = (txn OnCompletion) + let tmp%12#0: uint64 = (== tmp%11#0 NoOp) + (assert tmp%12#0) // OnCompletion is NoOp + let tmp%13#0: uint64 = (txn ApplicationID) + (assert tmp%13#0) // is not creating + let tmp%14#0: bytes = test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint() + let tmp%15#0: bytes = (concat 0x151f7c75 tmp%14#0) + (log tmp%15#0) + return 1u + block@4: // switch_case_default_L5 + goto block@5 + block@5: // switch_case_next_L5 + goto block@11 + block@6: // bare_routing_L5 + let tmp%16#0: uint64 = (txn OnCompletion) + switch tmp%16#0 {0u => block@7, 4u => block@8, 5u => block@9, * => block@10} + block@7: // create_L5 + let tmp%17#0: uint64 = (txn ApplicationID) + let tmp%18#0: uint64 = (! tmp%17#0) + (assert tmp%18#0) // is creating + return 1u + block@8: // on_update_L15 + let tmp%19#0: uint64 = (txn ApplicationID) + (assert tmp%19#0) // is not creating + test_cases.template_variables.contract.TemplateVariablesContract.on_update() + return 1u + block@9: // on_delete_L19 + let tmp%20#0: uint64 = (txn ApplicationID) + (assert tmp%20#0) // is not creating + test_cases.template_variables.contract.TemplateVariablesContract.on_delete() + return 1u + block@10: // reject_bare_on_completion_L5 + fail // reject transaction + block@11: // after_if_else_L5 + fail // reject transaction + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.get_bytes() -> bytes: + block@0: // L6 + return TemplateVar[AVMType.bytes](TMPL_SOME_BYTES) + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint() -> bytes: + block@0: // L10 + let x#0: bytes = TemplateVar[AVMType.bytes](TMPL_SOME_BIG_UINT) + let len_%0#0: uint64 = (len x#0) + let no_overflow%1#0: uint64 = (<= len_%0#0 64u) + (assert no_overflow%1#0) // overflow + let b_zeros%2#0: bytes = (bzero 64u) + let tmp%3#0: bytes = (b| x#0 b_zeros%2#0) + return tmp%3#0 + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.on_update() -> void: + block@0: // L15 + (assert TemplateVar[AVMType.uint64](TMPL_UPDATABLE)) + return + + subroutine test_cases.template_variables.contract.TemplateVariablesContract.on_delete() -> void: + block@0: // L19 + (assert TemplateVar[AVMType.uint64](TMPL_DELETABLE)) + return + + program clear-state: + subroutine test_cases.template_variables.contract.TemplateVariablesContract.clear_state_program() -> uint64: + block@0: // L5 + return 1u \ No newline at end of file diff --git a/test_cases/template_variables/puya.log b/test_cases/template_variables/puya.log new file mode 100644 index 0000000000..af707efb5f --- /dev/null +++ b/test_cases/template_variables/puya.log @@ -0,0 +1,553 @@ +debug: PuyaOptions(paths=['template_variables'], output_teal=True, output_arc32=True, output_awst=True, output_ssa_ir=True, output_optimization_ir=True, output_destructured_ir=True, output_memory_ir=True, debug_level=1, optimization_level=1, log_level=, target_avm_version=10, locals_coalescing_strategy=) +debug: Sealing block@0: // L11 +debug: Terminated block@0: // L11 +debug: Looking for 'required_budget_with_buffer' in an unsealed block creating an incomplete Phi: block@1: // while_top_L19 +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_L19 +debug: Terminated block@1: // while_top_L19 +debug: Sealing block@None: // while_body_L19 +debug: Looking for 'fee_source' in an unsealed block creating an incomplete Phi: block@1: // while_top_L19 +debug: Created Phi assignment: let fee_source#1: uint64 = undefined while trying to resolve 'fee_source' in block@1: // while_top_L19 +debug: Terminated block@2: // while_body_L19 +debug: Sealing block@None: // switch_case_default_L25 +debug: Sealing block@None: // switch_case_0_L27 +debug: Sealing block@None: // switch_case_1_L29 +debug: Terminated block@3: // switch_case_0_L27 +debug: Terminated block@4: // switch_case_1_L29 +debug: Terminated block@5: // switch_case_default_L25 +debug: Sealing block@6: // switch_case_next_L25 +debug: Terminated block@6: // switch_case_next_L25 +debug: Sealing block@1: // while_top_L19 +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: // L11 +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_L25 +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_L27 +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_L29 +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_L25 +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_L25 +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: // L11 +debug: Created Phi assignment: let fee_source#2: uint64 = undefined while trying to resolve 'fee_source' in block@6: // switch_case_next_L25 +debug: Added fee_source#1 to Phi node: let fee_source#2: uint64 = φ(fee_source#1 <- block@3) in block@3: // switch_case_0_L27 +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_L29 +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_L25 +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_L25 +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@None: // after_while_L19 +debug: Terminated block@7: // after_while_L19 +debug: Sealing block@0: // L20 +debug: Terminated block@0: // L20 +debug: Sealing block@0: // L39 +debug: Terminated block@0: // L39 +debug: Sealing block@0: // L57 +debug: Terminated block@0: // L57 +debug: Sealing block@0: // L84 +debug: Terminated block@0: // L84 +debug: Sealing block@None: // if_body_L106 +debug: Sealing block@None: // else_body_L106 +debug: Terminated block@1: // if_body_L106 +debug: Sealing block@2: // after_if_else_L106 +debug: Created Phi assignment: let array_length#1: uint64 = undefined while trying to resolve 'array_length' in block@2: // after_if_else_L106 +debug: Added array_length#0 to Phi node: let array_length#1: uint64 = φ(array_length#0 <- block@0) in block@0: // L84 +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_L106 +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: uint64 = undefined while trying to resolve 'is_packed' in block@2: // after_if_else_L106 +debug: Added is_packed#0 to Phi node: let is_packed#1: uint64 = φ(is_packed#0 <- block@0) in block@0: // L84 +debug: Added is_packed#0 to Phi node: let is_packed#1: uint64 = φ(is_packed#0 <- block@0, is_packed#0 <- block@1) in block@1: // if_body_L106 +debug: Replacing trivial Phi node: let is_packed#1: uint64 = φ(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: uint64 = φ(is_packed#0 <- block@0, is_packed#0 <- block@1) +debug: Replaced trivial Phi node: let is_packed#1: uint64 = φ(is_packed#0 <- block@0, is_packed#0 <- block@1) (is_packed#1) with is_packed#0 in current definition for 1 blocks +debug: Terminated block@2: // after_if_else_L106 +debug: Sealing block@None: // ternary_true_L110 +debug: Sealing block@None: // ternary_false_L110 +debug: Terminated block@3: // ternary_true_L110 +debug: Terminated block@4: // ternary_false_L110 +debug: Sealing block@5: // ternary_merge_L110 +debug: Created Phi assignment: let ternary_result%6#2: uint64 = undefined while trying to resolve 'ternary_result%6' in block@5: // ternary_merge_L110 +debug: Added ternary_result%6#0 to Phi node: let ternary_result%6#2: uint64 = φ(ternary_result%6#0 <- block@3) in block@3: // ternary_true_L110 +debug: Added ternary_result%6#1 to Phi node: let ternary_result%6#2: uint64 = φ(ternary_result%6#0 <- block@3, ternary_result%6#1 <- block@4) in block@4: // ternary_false_L110 +debug: Created Phi assignment: let new_items_count#1: uint64 = undefined while trying to resolve 'new_items_count' in block@5: // ternary_merge_L110 +debug: Created Phi assignment: let new_items_count#2: uint64 = undefined while trying to resolve 'new_items_count' in block@2: // after_if_else_L106 +debug: Added new_items_count#0 to Phi node: let new_items_count#2: uint64 = φ(new_items_count#0 <- block@0) in block@0: // L84 +debug: Added new_items_count#0 to Phi node: let new_items_count#2: uint64 = φ(new_items_count#0 <- block@0, new_items_count#0 <- block@1) in block@1: // if_body_L106 +debug: Replacing trivial Phi node: let new_items_count#2: uint64 = φ(new_items_count#0 <- block@0, new_items_count#0 <- block@1) (new_items_count#2) with new_items_count#0 +debug: Deleting Phi assignment: let new_items_count#2: uint64 = φ(new_items_count#0 <- block@0, new_items_count#0 <- block@1) +debug: Replaced trivial Phi node: let new_items_count#2: uint64 = φ(new_items_count#0 <- block@0, new_items_count#0 <- block@1) (new_items_count#2) with new_items_count#0 in current definition for 1 blocks +debug: Added new_items_count#0 to Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@3) in block@3: // ternary_true_L110 +debug: Added new_items_count#0 to Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@3, new_items_count#0 <- block@4) in block@4: // ternary_false_L110 +debug: Replacing trivial Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@3, new_items_count#0 <- block@4) (new_items_count#1) with new_items_count#0 +debug: Deleting Phi assignment: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@3, new_items_count#0 <- block@4) +debug: Replaced trivial Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@3, new_items_count#0 <- block@4) (new_items_count#1) with new_items_count#0 in current definition for 1 blocks +debug: Terminated block@5: // ternary_merge_L110 +debug: Looking for 'range_item%7' in an unsealed block creating an incomplete Phi: block@6: // for_header_L110 +debug: Created Phi assignment: let range_item%7#1: uint64 = undefined while trying to resolve 'range_item%7' in block@6: // for_header_L110 +debug: Terminated block@6: // for_header_L110 +debug: Looking for 'range_item%7' in an unsealed block creating an incomplete Phi: block@7: // for_body_L110 +debug: Created Phi assignment: let range_item%7#2: uint64 = undefined while trying to resolve 'range_item%7' in block@7: // for_body_L110 +debug: Looking for 'result' in an unsealed block creating an incomplete Phi: block@7: // for_body_L110 +debug: Created Phi assignment: let result#2: bytes = undefined while trying to resolve 'result' in block@7: // for_body_L110 +debug: Looking for 'write_offset' in an unsealed block creating an incomplete Phi: block@7: // for_body_L110 +debug: Created Phi assignment: let write_offset#1: uint64 = undefined while trying to resolve 'write_offset' in block@7: // for_body_L110 +debug: Looking for 'new_items_bytes' in an unsealed block creating an incomplete Phi: block@7: // for_body_L110 +debug: Created Phi assignment: let new_items_bytes#1: bytes = undefined while trying to resolve 'new_items_bytes' in block@7: // for_body_L110 +debug: Terminated block@7: // for_body_L110 +debug: Sealing block@8: // for_footer_L110 +debug: Terminated block@8: // for_footer_L110 +debug: Sealing block@9: // for_increment_L110 +debug: Terminated block@9: // for_increment_L110 +debug: Sealing block@6: // for_header_L110 +debug: Added range_item%7#0 to Phi node: let range_item%7#1: uint64 = φ(range_item%7#0 <- block@5) in block@5: // ternary_merge_L110 +debug: Added range_item%7#3 to Phi node: let range_item%7#1: uint64 = φ(range_item%7#0 <- block@5, range_item%7#3 <- block@9) in block@9: // for_increment_L110 +debug: Sealing block@7: // for_body_L110 +debug: Added range_item%7#1 to Phi node: let range_item%7#2: uint64 = φ(range_item%7#1 <- block@6) in block@6: // for_header_L110 +debug: Replacing trivial Phi node: let range_item%7#2: uint64 = φ(range_item%7#1 <- block@6) (range_item%7#2) with range_item%7#1 +debug: Deleting Phi assignment: let range_item%7#2: uint64 = φ(range_item%7#1 <- block@6) +debug: Replaced trivial Phi node: let range_item%7#2: uint64 = φ(range_item%7#1 <- block@6) (range_item%7#2) with range_item%7#1 in current definition for 2 blocks +debug: Created Phi assignment: let result#4: bytes = undefined while trying to resolve 'result' in block@6: // for_header_L110 +debug: Created Phi assignment: let result#5: bytes = undefined while trying to resolve 'result' in block@5: // ternary_merge_L110 +debug: Created Phi assignment: let result#6: bytes = undefined while trying to resolve 'result' in block@2: // after_if_else_L106 +debug: Added result#0 to Phi node: let result#6: bytes = φ(result#0 <- block@0) in block@0: // L84 +debug: Added result#1 to Phi node: let result#6: bytes = φ(result#0 <- block@0, result#1 <- block@1) in block@1: // if_body_L106 +debug: Added result#6 to Phi node: let result#5: bytes = φ(result#6 <- block@3) in block@3: // ternary_true_L110 +debug: Added result#6 to Phi node: let result#5: bytes = φ(result#6 <- block@3, result#6 <- block@4) in block@4: // ternary_false_L110 +debug: Replacing trivial Phi node: let result#5: bytes = φ(result#6 <- block@3, result#6 <- block@4) (result#5) with result#6 +debug: Deleting Phi assignment: let result#5: bytes = φ(result#6 <- block@3, result#6 <- block@4) +debug: Replaced trivial Phi node: let result#5: bytes = φ(result#6 <- block@3, result#6 <- block@4) (result#5) with result#6 in current definition for 1 blocks +debug: Added result#6 to Phi node: let result#4: bytes = φ(result#6 <- block@5) in block@5: // ternary_merge_L110 +debug: Added result#3 to Phi node: let result#4: bytes = φ(result#6 <- block@5, result#3 <- block@9) in block@9: // for_increment_L110 +debug: Added result#4 to Phi node: let result#2: bytes = φ(result#4 <- block@6) in block@6: // for_header_L110 +debug: Replacing trivial Phi node: let result#2: bytes = φ(result#4 <- block@6) (result#2) with result#4 +debug: Deleting Phi assignment: let result#2: bytes = φ(result#4 <- block@6) +debug: Replaced trivial Phi node: let result#2: bytes = φ(result#4 <- block@6) (result#2) with result#4 in current definition for 0 blocks +debug: Created Phi assignment: let write_offset#3: uint64 = undefined while trying to resolve 'write_offset' in block@6: // for_header_L110 +debug: Created Phi assignment: let write_offset#4: uint64 = undefined while trying to resolve 'write_offset' in block@5: // ternary_merge_L110 +debug: Added write_offset#0 to Phi node: let write_offset#4: uint64 = φ(write_offset#0 <- block@3) in block@3: // ternary_true_L110 +debug: Added write_offset#0 to Phi node: let write_offset#4: uint64 = φ(write_offset#0 <- block@3, write_offset#0 <- block@4) in block@4: // ternary_false_L110 +debug: Replacing trivial Phi node: let write_offset#4: uint64 = φ(write_offset#0 <- block@3, write_offset#0 <- block@4) (write_offset#4) with write_offset#0 +debug: Deleting Phi assignment: let write_offset#4: uint64 = φ(write_offset#0 <- block@3, write_offset#0 <- block@4) +debug: Replaced trivial Phi node: let write_offset#4: uint64 = φ(write_offset#0 <- block@3, write_offset#0 <- block@4) (write_offset#4) with write_offset#0 in current definition for 1 blocks +debug: Added write_offset#0 to Phi node: let write_offset#3: uint64 = φ(write_offset#0 <- block@5) in block@5: // ternary_merge_L110 +debug: Added write_offset#2 to Phi node: let write_offset#3: uint64 = φ(write_offset#0 <- block@5, write_offset#2 <- block@9) in block@9: // for_increment_L110 +debug: Added write_offset#3 to Phi node: let write_offset#1: uint64 = φ(write_offset#3 <- block@6) in block@6: // for_header_L110 +debug: Replacing trivial Phi node: let write_offset#1: uint64 = φ(write_offset#3 <- block@6) (write_offset#1) with write_offset#3 +debug: Deleting Phi assignment: let write_offset#1: uint64 = φ(write_offset#3 <- block@6) +debug: Replaced trivial Phi node: let write_offset#1: uint64 = φ(write_offset#3 <- block@6) (write_offset#1) with write_offset#3 in current definition for 0 blocks +debug: Created Phi assignment: let new_items_bytes#2: bytes = undefined while trying to resolve 'new_items_bytes' in block@6: // for_header_L110 +debug: Created Phi assignment: let new_items_bytes#3: bytes = undefined while trying to resolve 'new_items_bytes' in block@5: // ternary_merge_L110 +debug: Created Phi assignment: let new_items_bytes#4: bytes = undefined while trying to resolve 'new_items_bytes' in block@2: // after_if_else_L106 +debug: Added new_items_bytes#0 to Phi node: let new_items_bytes#4: bytes = φ(new_items_bytes#0 <- block@0) in block@0: // L84 +debug: Added new_items_bytes#0 to Phi node: let new_items_bytes#4: bytes = φ(new_items_bytes#0 <- block@0, new_items_bytes#0 <- block@1) in block@1: // if_body_L106 +debug: Replacing trivial Phi node: let new_items_bytes#4: bytes = φ(new_items_bytes#0 <- block@0, new_items_bytes#0 <- block@1) (new_items_bytes#4) with new_items_bytes#0 +debug: Deleting Phi assignment: let new_items_bytes#4: bytes = φ(new_items_bytes#0 <- block@0, new_items_bytes#0 <- block@1) +debug: Replaced trivial Phi node: let new_items_bytes#4: bytes = φ(new_items_bytes#0 <- block@0, new_items_bytes#0 <- block@1) (new_items_bytes#4) with new_items_bytes#0 in current definition for 1 blocks +debug: Added new_items_bytes#0 to Phi node: let new_items_bytes#3: bytes = φ(new_items_bytes#0 <- block@3) in block@3: // ternary_true_L110 +debug: Added new_items_bytes#0 to Phi node: let new_items_bytes#3: bytes = φ(new_items_bytes#0 <- block@3, new_items_bytes#0 <- block@4) in block@4: // ternary_false_L110 +debug: Replacing trivial Phi node: let new_items_bytes#3: bytes = φ(new_items_bytes#0 <- block@3, new_items_bytes#0 <- block@4) (new_items_bytes#3) with new_items_bytes#0 +debug: Deleting Phi assignment: let new_items_bytes#3: bytes = φ(new_items_bytes#0 <- block@3, new_items_bytes#0 <- block@4) +debug: Replaced trivial Phi node: let new_items_bytes#3: bytes = φ(new_items_bytes#0 <- block@3, new_items_bytes#0 <- block@4) (new_items_bytes#3) with new_items_bytes#0 in current definition for 1 blocks +debug: Added new_items_bytes#0 to Phi node: let new_items_bytes#2: bytes = φ(new_items_bytes#0 <- block@5) in block@5: // ternary_merge_L110 +debug: Added new_items_bytes#1 to Phi node: let new_items_bytes#2: bytes = φ(new_items_bytes#0 <- block@5, new_items_bytes#1 <- block@9) in block@9: // for_increment_L110 +debug: Added new_items_bytes#2 to Phi node: let new_items_bytes#1: bytes = φ(new_items_bytes#2 <- block@6) in block@6: // for_header_L110 +debug: Replacing trivial Phi node: let new_items_bytes#1: bytes = φ(new_items_bytes#2 <- block@6) (new_items_bytes#1) with new_items_bytes#2 +debug: Deleting Phi assignment: let new_items_bytes#1: bytes = φ(new_items_bytes#2 <- block@6) +debug: Replacing trivial Phi node: let new_items_bytes#2: bytes = φ(new_items_bytes#0 <- block@5, new_items_bytes#2 <- block@9) (new_items_bytes#2) with new_items_bytes#0 +debug: Deleting Phi assignment: let new_items_bytes#2: bytes = φ(new_items_bytes#0 <- block@5, new_items_bytes#2 <- block@9) +debug: Replaced trivial Phi node: let new_items_bytes#1: bytes = φ(new_items_bytes#2 <- block@6) (new_items_bytes#1) with new_items_bytes#2 in current definition for 3 blocks +debug: Replaced trivial Phi node: let new_items_bytes#2: bytes = φ(new_items_bytes#0 <- block@5, new_items_bytes#2 <- block@9) (new_items_bytes#2) with new_items_bytes#0 in current definition for 4 blocks +debug: Sealing block@None: // after_for_L110 +debug: Terminated block@10: // after_for_L110 +debug: Sealing block@0: // L117 +debug: Terminated block@0: // L117 +debug: Sealing block@0: // L139 +debug: Terminated block@0: // L139 +debug: Sealing block@0: // L166 +debug: Terminated block@0: // L166 +debug: Sealing block@0: // L195 +debug: Terminated block@0: // L195 +debug: Sealing block@None: // if_body_L210 +debug: Sealing block@None: // else_body_L210 +debug: Terminated block@1: // if_body_L210 +debug: Terminated block@2: // else_body_L210 +debug: Sealing block@3: // after_if_else_L210 +debug: Created Phi assignment: let length#1: uint64 = undefined while trying to resolve 'length' in block@3: // after_if_else_L210 +debug: Added length#0 to Phi node: let length#1: uint64 = φ(length#0 <- block@1) in block@1: // if_body_L210 +debug: Added length#0 to Phi node: let length#1: uint64 = φ(length#0 <- block@1, length#0 <- block@2) in block@2: // else_body_L210 +debug: Replacing trivial Phi node: let length#1: uint64 = φ(length#0 <- block@1, length#0 <- block@2) (length#1) with length#0 +debug: Deleting Phi assignment: let length#1: uint64 = φ(length#0 <- block@1, length#0 <- block@2) +debug: Replaced trivial Phi node: let length#1: uint64 = φ(length#0 <- block@1, length#0 <- block@2) (length#1) with length#0 in current definition for 1 blocks +debug: Created Phi assignment: let start_at_index#1: uint64 = undefined while trying to resolve 'start_at_index' in block@3: // after_if_else_L210 +debug: Added start_at_index#0 to Phi node: let start_at_index#1: uint64 = φ(start_at_index#0 <- block@1) in block@1: // if_body_L210 +debug: Added start_at_index#0 to Phi node: let start_at_index#1: uint64 = φ(start_at_index#0 <- block@1, start_at_index#0 <- block@2) in block@2: // else_body_L210 +debug: Replacing trivial Phi node: let start_at_index#1: uint64 = φ(start_at_index#0 <- block@1, start_at_index#0 <- block@2) (start_at_index#1) with start_at_index#0 +debug: Deleting Phi assignment: let start_at_index#1: uint64 = φ(start_at_index#0 <- block@1, start_at_index#0 <- block@2) +debug: Replaced trivial Phi node: let start_at_index#1: uint64 = φ(start_at_index#0 <- block@1, start_at_index#0 <- block@2) (start_at_index#1) with start_at_index#0 in current definition for 1 blocks +debug: Terminated block@3: // after_if_else_L210 +debug: Looking for 'range_item%1' in an unsealed block creating an incomplete Phi: block@4: // for_header_L215 +debug: Created Phi assignment: let range_item%1#1: uint64 = undefined while trying to resolve 'range_item%1' in block@4: // for_header_L215 +debug: Terminated block@4: // for_header_L215 +debug: Looking for 'range_item%1' in an unsealed block creating an incomplete Phi: block@5: // for_body_L215 +debug: Created Phi assignment: let range_item%1#2: uint64 = undefined while trying to resolve 'range_item%1' in block@5: // for_body_L215 +debug: Looking for 'tail_cursor' in an unsealed block creating an incomplete Phi: block@5: // for_body_L215 +debug: Created Phi assignment: let tail_cursor#2: uint64 = undefined while trying to resolve 'tail_cursor' in block@5: // for_body_L215 +debug: Looking for 'array_data' in an unsealed block creating an incomplete Phi: block@5: // for_body_L215 +debug: Created Phi assignment: let array_data#1: bytes = undefined while trying to resolve 'array_data' in block@5: // for_body_L215 +debug: Looking for 'header_cursor' in an unsealed block creating an incomplete Phi: block@5: // for_body_L215 +debug: Created Phi assignment: let header_cursor#1: uint64 = undefined while trying to resolve 'header_cursor' in block@5: // for_body_L215 +debug: Terminated block@5: // for_body_L215 +debug: Sealing block@6: // for_footer_L215 +debug: Terminated block@6: // for_footer_L215 +debug: Sealing block@7: // for_increment_L215 +debug: Terminated block@7: // for_increment_L215 +debug: Sealing block@4: // for_header_L215 +debug: Added range_item%1#0 to Phi node: let range_item%1#1: uint64 = φ(range_item%1#0 <- block@3) in block@3: // after_if_else_L210 +debug: Added range_item%1#3 to Phi node: let range_item%1#1: uint64 = φ(range_item%1#0 <- block@3, range_item%1#3 <- block@7) in block@7: // for_increment_L215 +debug: Sealing block@5: // for_body_L215 +debug: Added range_item%1#1 to Phi node: let range_item%1#2: uint64 = φ(range_item%1#1 <- block@4) in block@4: // for_header_L215 +debug: Replacing trivial Phi node: let range_item%1#2: uint64 = φ(range_item%1#1 <- block@4) (range_item%1#2) with range_item%1#1 +debug: Deleting Phi assignment: let range_item%1#2: uint64 = φ(range_item%1#1 <- block@4) +debug: Replaced trivial Phi node: let range_item%1#2: uint64 = φ(range_item%1#1 <- block@4) (range_item%1#2) with range_item%1#1 in current definition for 2 blocks +debug: Created Phi assignment: let tail_cursor#4: uint64 = undefined while trying to resolve 'tail_cursor' in block@4: // for_header_L215 +debug: Created Phi assignment: let tail_cursor#5: uint64 = undefined while trying to resolve 'tail_cursor' in block@3: // after_if_else_L210 +debug: Added tail_cursor#0 to Phi node: let tail_cursor#5: uint64 = φ(tail_cursor#0 <- block@1) in block@1: // if_body_L210 +debug: Added tail_cursor#1 to Phi node: let tail_cursor#5: uint64 = φ(tail_cursor#0 <- block@1, tail_cursor#1 <- block@2) in block@2: // else_body_L210 +debug: Added tail_cursor#5 to Phi node: let tail_cursor#4: uint64 = φ(tail_cursor#5 <- block@3) in block@3: // after_if_else_L210 +debug: Added tail_cursor#3 to Phi node: let tail_cursor#4: uint64 = φ(tail_cursor#5 <- block@3, tail_cursor#3 <- block@7) in block@7: // for_increment_L215 +debug: Added tail_cursor#4 to Phi node: let tail_cursor#2: uint64 = φ(tail_cursor#4 <- block@4) in block@4: // for_header_L215 +debug: Replacing trivial Phi node: let tail_cursor#2: uint64 = φ(tail_cursor#4 <- block@4) (tail_cursor#2) with tail_cursor#4 +debug: Deleting Phi assignment: let tail_cursor#2: uint64 = φ(tail_cursor#4 <- block@4) +debug: Replaced trivial Phi node: let tail_cursor#2: uint64 = φ(tail_cursor#4 <- block@4) (tail_cursor#2) with tail_cursor#4 in current definition for 0 blocks +debug: Created Phi assignment: let array_data#3: bytes = undefined while trying to resolve 'array_data' in block@4: // for_header_L215 +debug: Created Phi assignment: let array_data#4: bytes = undefined while trying to resolve 'array_data' in block@3: // after_if_else_L210 +debug: Added array_data#0 to Phi node: let array_data#4: bytes = φ(array_data#0 <- block@1) in block@1: // if_body_L210 +debug: Added array_data#0 to Phi node: let array_data#4: bytes = φ(array_data#0 <- block@1, array_data#0 <- block@2) in block@2: // else_body_L210 +debug: Replacing trivial Phi node: let array_data#4: bytes = φ(array_data#0 <- block@1, array_data#0 <- block@2) (array_data#4) with array_data#0 +debug: Deleting Phi assignment: let array_data#4: bytes = φ(array_data#0 <- block@1, array_data#0 <- block@2) +debug: Replaced trivial Phi node: let array_data#4: bytes = φ(array_data#0 <- block@1, array_data#0 <- block@2) (array_data#4) with array_data#0 in current definition for 1 blocks +debug: Added array_data#0 to Phi node: let array_data#3: bytes = φ(array_data#0 <- block@3) in block@3: // after_if_else_L210 +debug: Added array_data#2 to Phi node: let array_data#3: bytes = φ(array_data#0 <- block@3, array_data#2 <- block@7) in block@7: // for_increment_L215 +debug: Added array_data#3 to Phi node: let array_data#1: bytes = φ(array_data#3 <- block@4) in block@4: // for_header_L215 +debug: Replacing trivial Phi node: let array_data#1: bytes = φ(array_data#3 <- block@4) (array_data#1) with array_data#3 +debug: Deleting Phi assignment: let array_data#1: bytes = φ(array_data#3 <- block@4) +debug: Replaced trivial Phi node: let array_data#1: bytes = φ(array_data#3 <- block@4) (array_data#1) with array_data#3 in current definition for 0 blocks +debug: Created Phi assignment: let header_cursor#3: uint64 = undefined while trying to resolve 'header_cursor' in block@4: // for_header_L215 +debug: Created Phi assignment: let header_cursor#4: uint64 = undefined while trying to resolve 'header_cursor' in block@3: // after_if_else_L210 +debug: Added header_cursor#0 to Phi node: let header_cursor#4: uint64 = φ(header_cursor#0 <- block@1) in block@1: // if_body_L210 +debug: Added header_cursor#0 to Phi node: let header_cursor#4: uint64 = φ(header_cursor#0 <- block@1, header_cursor#0 <- block@2) in block@2: // else_body_L210 +debug: Replacing trivial Phi node: let header_cursor#4: uint64 = φ(header_cursor#0 <- block@1, header_cursor#0 <- block@2) (header_cursor#4) with header_cursor#0 +debug: Deleting Phi assignment: let header_cursor#4: uint64 = φ(header_cursor#0 <- block@1, header_cursor#0 <- block@2) +debug: Replaced trivial Phi node: let header_cursor#4: uint64 = φ(header_cursor#0 <- block@1, header_cursor#0 <- block@2) (header_cursor#4) with header_cursor#0 in current definition for 1 blocks +debug: Added header_cursor#0 to Phi node: let header_cursor#3: uint64 = φ(header_cursor#0 <- block@3) in block@3: // after_if_else_L210 +debug: Added header_cursor#2 to Phi node: let header_cursor#3: uint64 = φ(header_cursor#0 <- block@3, header_cursor#2 <- block@7) in block@7: // for_increment_L215 +debug: Added header_cursor#3 to Phi node: let header_cursor#1: uint64 = φ(header_cursor#3 <- block@4) in block@4: // for_header_L215 +debug: Replacing trivial Phi node: let header_cursor#1: uint64 = φ(header_cursor#3 <- block@4) (header_cursor#1) with header_cursor#3 +debug: Deleting Phi assignment: let header_cursor#1: uint64 = φ(header_cursor#3 <- block@4) +debug: Replaced trivial Phi node: let header_cursor#1: uint64 = φ(header_cursor#3 <- block@4) (header_cursor#1) with header_cursor#3 in current definition for 0 blocks +debug: Sealing block@None: // after_for_L215 +debug: Terminated block@8: // after_for_L215 +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@None: // while_body_L11 +debug: Terminated block@2: // while_body_L11 +debug: Sealing block@None: // if_body_L12 +debug: Sealing block@None: // else_body_L12 +debug: Terminated block@3: // if_body_L12 +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@None: // after_while_L11 +debug: Terminated block@5: // after_while_L11 +debug: Sealing block@0: // L6 +debug: Terminated block@0: // L6 +debug: Sealing block@0: // L10 +debug: Terminated block@0: // L10 +debug: Sealing block@0: // L15 +debug: Terminated block@0: // L15 +debug: Sealing block@0: // L19 +debug: Terminated block@0: // L19 +debug: Sealing block@0: // L5 +debug: Terminated block@0: // L5 +debug: Sealing block@None: // abi_routing_L5 +debug: Sealing block@None: // bare_routing_L5 +debug: Terminated block@1: // abi_routing_L5 +debug: Sealing block@None: // switch_case_default_L5 +debug: Sealing block@None: // get_bytes_route_L6 +debug: Sealing block@None: // get_big_uint_route_L10 +debug: Terminated block@2: // get_bytes_route_L6 +debug: Terminated block@3: // get_big_uint_route_L10 +debug: Terminated block@4: // switch_case_default_L5 +debug: Sealing block@5: // switch_case_next_L5 +debug: Terminated block@5: // switch_case_next_L5 +debug: Terminated block@6: // bare_routing_L5 +debug: Sealing block@None: // reject_bare_on_completion_L5 +debug: Sealing block@None: // create_L5 +debug: Sealing block@None: // on_update_L15 +debug: Sealing block@None: // on_delete_L19 +debug: Terminated block@7: // create_L5 +debug: Terminated block@8: // on_update_L15 +debug: Terminated block@9: // on_delete_L19 +debug: Terminated block@10: // reject_bare_on_completion_L5 +debug: Sealing block@None: // switch_case_next_L5 +debug: Sealing block@11: // after_if_else_L5 +debug: Terminated block@11: // after_if_else_L5 +debug: Sealing block@0: // L5 +debug: Terminated block@0: // L5 +debug: Output IR to template_variables/out/TemplateVariablesContract.ssa.ir +info: Optimizing test_cases.template_variables.contract.TemplateVariablesContract at level 1 +debug: Begin optimization pass 1/100 +debug: Optimizing subroutine test_cases.template_variables.contract.TemplateVariablesContract.approval_program +debug: Splitting parallel copies prior to optimization +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Simplified (== tmp%2#0 NoOp) to (! tmp%2#0) +debug: Simplified (== tmp%11#0 NoOp) to (! tmp%11#0) +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Simplify Control Ops +debug: adding block@1: // abi_routing_L5 as a predecessor of block@5: // switch_case_next_L5 due to inlining of block@4: // switch_case_default_L5 +debug: simplified terminator of block@1: // abi_routing_L5 from switch tmp%1#0 {method "get_bytes()byte[]" => block@2, method "get_big_uint()uint512" => block@3, * => block@4} to switch tmp%1#0 {method "get_bytes()byte[]" => block@2, method "get_big_uint()uint512" => block@3, * => block@5} +debug: simplified terminator of block@6: // bare_routing_L5 from switch tmp%16#0 {0u => block@7, 4u => block@8, 5u => block@9, * => block@10} to goto_nth [block@7, block@10, block@10, block@10, block@8, block@9][tmp%16#0] else goto block@10 +debug: adding block@1: // abi_routing_L5 as a predecessor of block@11: // after_if_else_L5 due to inlining of block@5: // switch_case_next_L5 +debug: simplified terminator of block@1: // abi_routing_L5 from switch tmp%1#0 {method "get_bytes()byte[]" => block@2, method "get_big_uint()uint512" => block@3, * => block@5} to switch tmp%1#0 {method "get_bytes()byte[]" => block@2, method "get_big_uint()uint512" => block@3, * => block@11} +debug: simplified terminator of block@6: // bare_routing_L5 from goto_nth [block@7, block@10, block@10, block@10, block@8, block@9][tmp%16#0] else goto block@10 to goto_nth [block@7, block@10, block@10, block@10, block@8, block@9][tmp%16#0] else fail // reject transaction +debug: simplified terminator of block@1: // abi_routing_L5 from switch tmp%1#0 {method "get_bytes()byte[]" => block@2, method "get_big_uint()uint512" => block@3, * => block@11} to switch tmp%1#0 {method "get_bytes()byte[]" => block@2, method "get_big_uint()uint512" => block@3, * => fail // reject transaction} +debug: Optimizer: Remove Linear Jump +debug: Replaced predecessor block@5: // switch_case_next_L5 with block@4: // switch_case_default_L5 in block@11: // after_if_else_L5 +debug: Merged linear block@5: // switch_case_next_L5 into block@4: // switch_case_default_L5 +debug: Merged linear block@11: // after_if_else_L5 into block@4: // switch_case_default_L5 +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Removing unreachable blocks: block@4: // switch_case_default_L5 +debug: Optimizer: Repeated Expression Elimination +debug: Optimizing subroutine test_cases.template_variables.contract.TemplateVariablesContract.get_bytes +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: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizing subroutine test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint +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: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizing subroutine test_cases.template_variables.contract.TemplateVariablesContract.on_update +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: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizing subroutine test_cases.template_variables.contract.TemplateVariablesContract.on_delete +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: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizing subroutine test_cases.template_variables.contract.TemplateVariablesContract.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: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Output IR to template_variables/out/TemplateVariablesContract.ssa.opt_pass_1.ir +debug: Begin optimization pass 2/100 +debug: Optimizing subroutine test_cases.template_variables.contract.TemplateVariablesContract.approval_program +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +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: Optimizing subroutine test_cases.template_variables.contract.TemplateVariablesContract.get_bytes +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +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: Optimizing subroutine test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +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: Optimizing subroutine test_cases.template_variables.contract.TemplateVariablesContract.on_update +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +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: Optimizing subroutine test_cases.template_variables.contract.TemplateVariablesContract.on_delete +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +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: Optimizing subroutine test_cases.template_variables.contract.TemplateVariablesContract.clear_state_program +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +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: No optimizations performed in pass 2, ending loop +debug: Removing Phis from test_cases.template_variables.contract.TemplateVariablesContract.approval_program +debug: Removing Phis from test_cases.template_variables.contract.TemplateVariablesContract.get_bytes +debug: Removing Phis from test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint +debug: Removing Phis from test_cases.template_variables.contract.TemplateVariablesContract.on_update +debug: Removing Phis from test_cases.template_variables.contract.TemplateVariablesContract.on_delete +debug: Removing Phis from test_cases.template_variables.contract.TemplateVariablesContract.clear_state_program +debug: Coalescing local variables in test_cases.template_variables.contract.TemplateVariablesContract.approval_program using strategy RootOperandGrouping +debug: Coalescing resulted in 0 replacement/s +debug: Coalescing local variables in test_cases.template_variables.contract.TemplateVariablesContract.get_bytes using strategy RootOperandGrouping +debug: Coalescing resulted in 0 replacement/s +debug: Coalescing local variables in test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint using strategy RootOperandGrouping +debug: Coalescing resulted in 0 replacement/s +debug: Coalescing local variables in test_cases.template_variables.contract.TemplateVariablesContract.on_update using strategy RootOperandGrouping +debug: Coalescing resulted in 0 replacement/s +debug: Coalescing local variables in test_cases.template_variables.contract.TemplateVariablesContract.on_delete using strategy RootOperandGrouping +debug: Coalescing resulted in 0 replacement/s +debug: Coalescing local variables in test_cases.template_variables.contract.TemplateVariablesContract.clear_state_program using strategy RootOperandGrouping +debug: Coalescing resulted in 0 replacement/s +debug: Sequentializing parallel copies in test_cases.template_variables.contract.TemplateVariablesContract.approval_program +debug: Sequentializing parallel copies in test_cases.template_variables.contract.TemplateVariablesContract.get_bytes +debug: Sequentializing parallel copies in test_cases.template_variables.contract.TemplateVariablesContract.get_big_uint +debug: Sequentializing parallel copies in test_cases.template_variables.contract.TemplateVariablesContract.on_update +debug: Sequentializing parallel copies in test_cases.template_variables.contract.TemplateVariablesContract.on_delete +debug: Sequentializing parallel copies in test_cases.template_variables.contract.TemplateVariablesContract.clear_state_program +debug: Performing post-SSA optimizations +debug: Output IR to template_variables/out/TemplateVariablesContract.destructured.ir +debug: Inserted main_block@0.ops[1]: 'store tmp%0#0 to l-stack (copy)' +debug: Replaced main_block@0.ops[3]: 'load tmp%0#0' with 'load tmp%0#0 from l-stack (no copy)' +debug: Inserted main_abi_routing@1.ops[1]: 'store tmp%1#0 to l-stack (copy)' +debug: Replaced main_abi_routing@1.ops[5]: 'load tmp%1#0' with 'load tmp%1#0 from l-stack (no copy)' +debug: Inserted main_get_bytes_route@2.ops[1]: 'store tmp%2#0 to l-stack (copy)' +debug: Replaced main_get_bytes_route@2.ops[3]: 'load tmp%2#0' with 'load tmp%2#0 from l-stack (no copy)' +debug: Inserted main_get_bytes_route@2.ops[5]: 'store tmp%3#0 to l-stack (copy)' +debug: Replaced main_get_bytes_route@2.ops[7]: 'load tmp%3#0' with 'load tmp%3#0 from l-stack (no copy)' +debug: Inserted main_get_bytes_route@2.ops[10]: 'store tmp%4#0 to l-stack (copy)' +debug: Replaced main_get_bytes_route@2.ops[12]: 'load tmp%4#0' with 'load tmp%4#0 from l-stack (no copy)' +debug: Inserted main_get_bytes_route@2.ops[15]: 'store awst_tmp%5#0 to l-stack (copy)' +debug: Replaced main_get_bytes_route@2.ops[17]: 'load awst_tmp%5#0' with 'load awst_tmp%5#0 from l-stack (no copy)' +debug: Inserted main_get_bytes_route@2.ops[19]: 'store tmp%6#0 to l-stack (copy)' +debug: Replaced main_get_bytes_route@2.ops[21]: 'load tmp%6#0' with 'load tmp%6#0 from l-stack (no copy)' +debug: Inserted main_get_bytes_route@2.ops[23]: 'store tmp%7#0 to l-stack (copy)' +debug: Replaced main_get_bytes_route@2.ops[25]: 'load tmp%7#0' with 'load tmp%7#0 from l-stack (no copy)' +debug: Inserted main_get_bytes_route@2.ops[27]: 'store tmp%8#0 to l-stack (copy)' +debug: Replaced main_get_bytes_route@2.ops[29]: 'load tmp%8#0' with 'load tmp%8#0 from l-stack (no copy)' +debug: Inserted main_get_bytes_route@2.ops[36]: 'store tmp%10#0 to l-stack (copy)' +debug: Replaced main_get_bytes_route@2.ops[38]: 'load tmp%10#0' with 'load tmp%10#0 from l-stack (no copy)' +debug: Inserted main_get_bytes_route@2.ops[32]: 'store tmp%9#0 to l-stack (copy)' +debug: Replaced main_get_bytes_route@2.ops[35]: 'load tmp%9#0' with 'load tmp%9#0 from l-stack (no copy)' +debug: Inserted main_get_bytes_route@2.ops[18]: 'store awst_tmp%5#0 to l-stack (copy)' +debug: Replaced main_get_bytes_route@2.ops[31]: 'load awst_tmp%5#0' with 'load awst_tmp%5#0 from l-stack (no copy)' +debug: Inserted main_get_big_uint_route@3.ops[1]: 'store tmp%11#0 to l-stack (copy)' +debug: Replaced main_get_big_uint_route@3.ops[3]: 'load tmp%11#0' with 'load tmp%11#0 from l-stack (no copy)' +debug: Inserted main_get_big_uint_route@3.ops[5]: 'store tmp%12#0 to l-stack (copy)' +debug: Replaced main_get_big_uint_route@3.ops[7]: 'load tmp%12#0' with 'load tmp%12#0 from l-stack (no copy)' +debug: Inserted main_get_big_uint_route@3.ops[10]: 'store tmp%13#0 to l-stack (copy)' +debug: Replaced main_get_big_uint_route@3.ops[12]: 'load tmp%13#0' with 'load tmp%13#0 from l-stack (no copy)' +debug: Inserted main_get_big_uint_route@3.ops[19]: 'store tmp%15#0 to l-stack (copy)' +debug: Replaced main_get_big_uint_route@3.ops[21]: 'load tmp%15#0' with 'load tmp%15#0 from l-stack (no copy)' +debug: Inserted main_get_big_uint_route@3.ops[15]: 'store tmp%14#0 to l-stack (copy)' +debug: Replaced main_get_big_uint_route@3.ops[18]: 'load tmp%14#0' with 'load tmp%14#0 from l-stack (no copy)' +debug: Inserted main_bare_routing@6.ops[1]: 'store tmp%16#0 to l-stack (copy)' +debug: Replaced main_bare_routing@6.ops[3]: 'load tmp%16#0' with 'load tmp%16#0 from l-stack (no copy)' +debug: Inserted main_create@7.ops[1]: 'store tmp%17#0 to l-stack (copy)' +debug: Replaced main_create@7.ops[3]: 'load tmp%17#0' with 'load tmp%17#0 from l-stack (no copy)' +debug: Inserted main_create@7.ops[5]: 'store tmp%18#0 to l-stack (copy)' +debug: Replaced main_create@7.ops[7]: 'load tmp%18#0' with 'load tmp%18#0 from l-stack (no copy)' +debug: Inserted main_on_update@8.ops[1]: 'store tmp%19#0 to l-stack (copy)' +debug: Replaced main_on_update@8.ops[3]: 'load tmp%19#0' with 'load tmp%19#0 from l-stack (no copy)' +debug: Inserted main_on_delete@9.ops[1]: 'store tmp%20#0 to l-stack (copy)' +debug: Replaced main_on_delete@9.ops[3]: 'load tmp%20#0' with 'load tmp%20#0 from l-stack (no copy)' +debug: Found 3 edge set/s for test_cases.template_variables.contract.TemplateVariablesContract.approval_program +debug: Inserted get_big_uint_block@0.ops[1]: 'store x#0 to l-stack (copy)' +debug: Replaced get_big_uint_block@0.ops[3]: 'load x#0' with 'load x#0 from l-stack (no copy)' +debug: Inserted get_big_uint_block@0.ops[5]: 'store len_%0#0 to l-stack (copy)' +debug: Replaced get_big_uint_block@0.ops[7]: 'load len_%0#0' with 'load len_%0#0 from l-stack (no copy)' +debug: Inserted get_big_uint_block@0.ops[10]: 'store no_overflow%1#0 to l-stack (copy)' +debug: Replaced get_big_uint_block@0.ops[12]: 'load no_overflow%1#0' with 'load no_overflow%1#0 from l-stack (no copy)' +debug: Inserted get_big_uint_block@0.ops[20]: 'store tmp%3#0 to l-stack (copy)' +debug: Replaced get_big_uint_block@0.ops[22]: 'load tmp%3#0' with 'load tmp%3#0 from l-stack (no copy)' +debug: Inserted get_big_uint_block@0.ops[16]: 'store b_zeros%2#0 to l-stack (copy)' +debug: Replaced get_big_uint_block@0.ops[19]: 'load b_zeros%2#0' with 'load b_zeros%2#0 from l-stack (no copy)' +debug: Inserted get_big_uint_block@0.ops[4]: 'store x#0 to l-stack (copy)' +debug: Replaced get_big_uint_block@0.ops[19]: 'load x#0' with 'load x#0 from l-stack (no copy)' +info: Writing template_variables/out/TemplateVariablesContract.approval.teal +info: Writing template_variables/out/TemplateVariablesContract.clear.teal +info: Writing template_variables/out/TemplateVariablesContract.arc32.json \ No newline at end of file diff --git a/tests/test_arc32.py b/tests/test_arc32.py index 1f134fd151..65ad001c52 100644 --- a/tests/test_arc32.py +++ b/tests/test_arc32.py @@ -6,6 +6,7 @@ import algokit_utils.config import algosdk import pytest +from algokit_utils import LogicError from algosdk import constants, transaction from algosdk.atomic_transaction_composer import AtomicTransactionComposer, TransactionWithSigner from algosdk.transaction import OnComplete @@ -658,3 +659,69 @@ def test_state_proxies(algod_client: AlgodClient, account: algokit_utils.Account app_client.create(transaction_parameters={"on_complete": OnComplete.OptInOC}) assert app_client.get_global_state() == {"g1": 1, "g2": 0} assert app_client.get_local_state(account.address) == {"l1": 2, "l2": 3} + + +def test_template_variables( + algod_client: AlgodClient, + account: algokit_utils.Account, +) -> None: + example = TEST_CASES_DIR / "template_variables" + app_spec = algokit_utils.ApplicationSpecification.from_json(compile_arc32(example)) + app_client = algokit_utils.ApplicationClient( + algod_client, + app_spec, + signer=account, + template_values={ + "SOME_BYTES": b"Hello I'm a variable", + "SOME_BIG_UINT": (1337).to_bytes(length=2), + "UPDATABLE": 1, + "DELETABLE": 1, + }, + ) + + app_client.create() + + get_bytes = app_client.call( + call_abi_method="get_bytes", + ) + assert bytes(get_bytes.return_value) == b"Hello I'm a variable" + + get_uint = app_client.call( + call_abi_method="get_big_uint", + ) + + assert get_uint.return_value == 1337 + + app_client = algokit_utils.ApplicationClient( + algod_client, + app_spec, + signer=account, + app_id=app_client.app_id, + template_values={ + "SOME_BYTES": b"Updated variable", + "SOME_BIG_UINT": (0).to_bytes(length=2), + "UPDATABLE": 0, + "DELETABLE": 1, + }, + ) + + app_client.update() + + get_bytes = app_client.call( + call_abi_method="get_bytes", + ) + assert bytes(get_bytes.return_value) == b"Updated variable" + + get_uint = app_client.call( + call_abi_method="get_big_uint", + ) + + assert get_uint.return_value == 0 + + try: + app_client.update() + raise AssertionError("Update should fail") + except LogicError: + pass + + app_client.delete()