From 730b4ed6e27af9943ab689b5363e1d70ec123b78 Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Fri, 16 Jun 2023 11:16:18 -0700 Subject: [PATCH 1/5] fix: pc maps for function selectors the existing pc annotator was annotating functions too early - when we do the check in the selector table rather than when the function is actually entered into. this moves the pc annotation to a few instructions later in the codegen so that tracers will not be confused as to where the function actually starts. --- vyper/codegen/function_definitions/external_function.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vyper/codegen/function_definitions/external_function.py b/vyper/codegen/function_definitions/external_function.py index 207356860b..4182e2fec2 100644 --- a/vyper/codegen/function_definitions/external_function.py +++ b/vyper/codegen/function_definitions/external_function.py @@ -205,7 +205,7 @@ def generate_ir_for_external_function(code, func_t, context, skip_nonpayable_che # the ir which comprises the main body of the function, # besides any kwarg handling - func_common_ir = ["seq", body, exit] + func_common_ir = IRnode.from_list(["seq", body, exit], source_pos=getpos(code)) if func_t.is_fallback or func_t.is_constructor: ret = ["seq"] @@ -219,4 +219,4 @@ def generate_ir_for_external_function(code, func_t, context, skip_nonpayable_che # TODO rethink this / make it clearer ret[-1][-1].append(func_common_ir) - return IRnode.from_list(ret, source_pos=getpos(code)) + return IRnode.from_list(ret) From 12dd1dcae1a6ef5bd0d2f927b23faf07e1c8787c Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Fri, 16 Jun 2023 11:41:24 -0700 Subject: [PATCH 2/5] annotate the calldatasize check as well --- .../codegen/function_definitions/external_function.py | 10 ++++++---- vyper/codegen/ir_node.py | 9 ++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/vyper/codegen/function_definitions/external_function.py b/vyper/codegen/function_definitions/external_function.py index 4182e2fec2..cb7bd349ec 100644 --- a/vyper/codegen/function_definitions/external_function.py +++ b/vyper/codegen/function_definitions/external_function.py @@ -68,7 +68,6 @@ def _generate_kwarg_handlers(func_t: ContractFunctionT, context: Context) -> Lis # copy calldata args to memory # write default args to memory # goto external_function_common_ir - def handler_for(calldata_kwargs, default_kwargs): calldata_args = func_t.positional_args + calldata_kwargs # create a fake type so that get_element_ptr works @@ -201,22 +200,25 @@ def generate_ir_for_external_function(code, func_t, context, skip_nonpayable_che if context.return_type is not None: exit_sequence_args += ["ret_ofst", "ret_len"] # wrap the exit in a labeled block - exit = ["label", func_t._ir_info.exit_sequence_label, exit_sequence_args, exit_sequence] + exit_ = ["label", func_t._ir_info.exit_sequence_label, exit_sequence_args, exit_sequence] # the ir which comprises the main body of the function, # besides any kwarg handling - func_common_ir = IRnode.from_list(["seq", body, exit], source_pos=getpos(code)) + func_common_ir = IRnode.from_list(["seq", body, exit_], source_pos=getpos(code)) if func_t.is_fallback or func_t.is_constructor: ret = ["seq"] # add a goto to make the function entry look like other functions # (for zksync interpreter) ret.append(["goto", func_t._ir_info.external_function_base_entry_label]) - ret.append(func_common_ir) + ret.append(IRnode.from_list(func_common_ir, source_pos=getpos(code))) else: ret = kwarg_handlers # sneak the base code into the kwarg handler # TODO rethink this / make it clearer ret[-1][-1].append(func_common_ir) + # annotate the first node in the function as soon as we have validated + # the method id. + ret[-1][2] = IRnode.from_list(ret[-1][2], source_pos=getpos(code)) return IRnode.from_list(ret) diff --git a/vyper/codegen/ir_node.py b/vyper/codegen/ir_node.py index d36a18ec66..9b33c0a44f 100644 --- a/vyper/codegen/ir_node.py +++ b/vyper/codegen/ir_node.py @@ -451,7 +451,7 @@ def _colorise_keywords(val): return OKMAGENTA + val + ENDC return val - def repr(self) -> str: + def __repr__(self) -> str: if not len(self.args): if self.annotation: return f"{self.repr_value} " + OKLIGHTBLUE + f"<{self.annotation}>" + ENDC @@ -463,6 +463,8 @@ def repr(self) -> str: o = "" if self.annotation: o += f"/* {self.annotation} */ \n" + if self.source_pos: + o += f"/* POS {self.source_pos} */ " if self.repr_show_gas and self.gas: o += OKBLUE + "{" + ENDC + str(self.gas) + OKBLUE + "} " + ENDC # add gas for info. o += "[" + self._colorise_keywords(self.repr_value) @@ -477,7 +479,7 @@ def repr(self) -> str: o += f"# Line {(arg_lineno)}\n " prev_lineno = arg_lineno annotated = True - arg_repr = arg.repr() + arg_repr = repr(arg) if "\n" in arg_repr: has_inner_newlines = True sub = arg_repr.replace("\n", "\n ").strip(" ") @@ -494,9 +496,6 @@ def repr(self) -> str: else: return output - def __repr__(self): - return self.repr() - @classmethod def from_list( cls, From 4d70129ab3e18cd9a2dd3141bec0014a883a1189 Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Fri, 16 Jun 2023 11:42:57 -0700 Subject: [PATCH 3/5] add comment --- vyper/codegen/ir_node.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vyper/codegen/ir_node.py b/vyper/codegen/ir_node.py index 9b33c0a44f..7cf1a517b5 100644 --- a/vyper/codegen/ir_node.py +++ b/vyper/codegen/ir_node.py @@ -463,8 +463,8 @@ def __repr__(self) -> str: o = "" if self.annotation: o += f"/* {self.annotation} */ \n" - if self.source_pos: - o += f"/* POS {self.source_pos} */ " + #if self.source_pos: + # o += f"/* POS {self.source_pos} */ " if self.repr_show_gas and self.gas: o += OKBLUE + "{" + ENDC + str(self.gas) + OKBLUE + "} " + ENDC # add gas for info. o += "[" + self._colorise_keywords(self.repr_value) From 806bef48e8dadccb6b284e3a5ede130e64e23df6 Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Fri, 16 Jun 2023 16:50:09 -0700 Subject: [PATCH 4/5] fix lint --- vyper/codegen/ir_node.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vyper/codegen/ir_node.py b/vyper/codegen/ir_node.py index 7cf1a517b5..20941dee62 100644 --- a/vyper/codegen/ir_node.py +++ b/vyper/codegen/ir_node.py @@ -463,7 +463,7 @@ def __repr__(self) -> str: o = "" if self.annotation: o += f"/* {self.annotation} */ \n" - #if self.source_pos: + # if self.source_pos: # o += f"/* POS {self.source_pos} */ " if self.repr_show_gas and self.gas: o += OKBLUE + "{" + ENDC + str(self.gas) + OKBLUE + "} " + ENDC # add gas for info. From 48a0c659864072c5e8ebc73b6c23eb01739a6fb3 Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Fri, 16 Jun 2023 17:46:40 -0700 Subject: [PATCH 5/5] fix another bug in source map --- vyper/ir/compile_ir.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vyper/ir/compile_ir.py b/vyper/ir/compile_ir.py index b2a58fa8c9..a4b696f22c 100644 --- a/vyper/ir/compile_ir.py +++ b/vyper/ir/compile_ir.py @@ -128,7 +128,7 @@ def _rewrite_return_sequences(ir_node, label_params=None): dest = args[0].value[5:] # `_sym_foo` -> `foo` more_args = ["pass" if t.value == "return_pc" else t for t in args[1:]] _t.append(["goto", dest] + more_args) - ir_node.args = IRnode.from_list(_t, source_pos=ir_node.source_pos).args + ir_node.args = IRnode.from_list(_t).args if ir_node.value == "label": label_params = set(t.value for t in ir_node.args[1].args)