From 00c6c8f9aa05b36e3463b5ab357cd5ff2170d4e0 Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Sat, 23 Mar 2024 20:49:15 -0400 Subject: [PATCH] fix revert codegen --- vyper/codegen/stmt.py | 52 +++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/vyper/codegen/stmt.py b/vyper/codegen/stmt.py index 618adf8cdc..1bee7eef7a 100644 --- a/vyper/codegen/stmt.py +++ b/vyper/codegen/stmt.py @@ -1,29 +1,23 @@ import vyper.codegen.events as events import vyper.utils as util from vyper import ast as vy_ast +from vyper.codegen.abi_encoder import abi_encode from vyper.codegen.context import Constancy, Context from vyper.codegen.core import ( LOAD, STORE, IRnode, + add_ofst, clamp_le, - ensure_in_memory, get_dyn_array_count, get_element_ptr, - make_byte_array_copier, + get_type_for_exact_size, make_setter, - zero_pad, ) from vyper.codegen.expr import Expr from vyper.codegen.return_ import make_return_stmt from vyper.evm.address_space import MEMORY, STORAGE -from vyper.exceptions import ( - CodegenPanic, - CompilerPanic, - StructureException, - TypeCheckFailure, - tag_exceptions, -) +from vyper.exceptions import CodegenPanic, StructureException, TypeCheckFailure, tag_exceptions from vyper.semantics.types import DArrayT from vyper.semantics.types.shortcuts import UINT256_T @@ -133,32 +127,26 @@ def _assert_reason(self, test_expr, msg): finally: self.context.constancy = tmp - # TODO this is probably useful in codegen.core - # compare with eval_seq. - def _get_last(ir): - if len(ir.args) == 0: - return ir.value - return _get_last(ir.args[-1]) - - instantiate_msg = ensure_in_memory(msg_ir, self.context) - buf = _get_last(instantiate_msg) + bufsz = msg_ir.typ.memory_bytes_required + 64 + buf = self.context.new_internal_variable(get_type_for_exact_size(bufsz)) # offset of bytes in (bytes,) method_id = util.method_id_int("Error(string)") - # abi encode method_id + bytestring - assert buf >= 36, "invalid buffer" - # we don't mind overwriting other memory because we are - # getting out of here anyway. - _runtime_length = ["mload", buf] - revert_seq = [ - "seq", - instantiate_msg, - zero_pad(buf), - ["mstore", buf - 64, method_id], - ["mstore", buf - 32, 0x20], - ["revert", buf - 36, ["add", 4 + 32 + 32, ["ceil32", _runtime_length]]], - ] + # abi encode method_id + bytestring to `buf+32`, then + # write method_id to `buf` and get out of here + bufsz -= 32 # reduce buffer by size of `method_id` slot + encoded_length = abi_encode( + add_ofst(buf, 32), msg_ir, self.context, bufsz, returns_len=True + ) + with encoded_length.cache_when_complex("encoded_len") as (b1, encoded_length): + revert_seq = [ + "seq", + ["mstore", buf, method_id], + ["revert", add_ofst(buf, 28), ["add", 4 + 32, encoded_length]], + ] + revert_seq = b1.resolve(revert_seq) + if is_raise: ir_node = revert_seq else: