From 2987d36e57895be870f1eb7364427f688998c689 Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Fri, 27 Sep 2024 14:29:44 -0400 Subject: [PATCH 1/9] refactor[venom]: add effects to instructions --- vyper/venom/basicblock.py | 7 ++++++ vyper/venom/effects.py | 48 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 vyper/venom/effects.py diff --git a/vyper/venom/basicblock.py b/vyper/venom/basicblock.py index d6fb9560cd..07367d71fc 100644 --- a/vyper/venom/basicblock.py +++ b/vyper/venom/basicblock.py @@ -1,5 +1,6 @@ from typing import TYPE_CHECKING, Any, Iterator, Optional, Union +import vyper.venom.effects as effects from vyper.codegen.ir_node import IRnode from vyper.utils import OrderedSet @@ -242,6 +243,12 @@ def is_volatile(self) -> bool: def is_bb_terminator(self) -> bool: return self.opcode in BB_TERMINATORS + def get_read_effects(self): + return effects.reads.get(self.opcode, ()) + + def get_write_effects(self): + return effects.reads.get(self.opcode, ()) + def get_label_operands(self) -> Iterator[IRLabel]: """ Get all labels in instruction. diff --git a/vyper/venom/effects.py b/vyper/venom/effects.py new file mode 100644 index 0000000000..7f6aa52ac7 --- /dev/null +++ b/vyper/venom/effects.py @@ -0,0 +1,48 @@ +_ALL = ("storage", "transient", "memory", "immutables", "balance", "returndata") + +_writes = { + "sstore": "storage", + "tstore": "transient", + "mstore": "memory", + "istore": "immutables", + "call": _ALL, + "delegatecall": _ALL, + "staticcall": "memory", + "create": _ALL, + "create2": _ALL, + "invoke": _ALL, # could be smarter, look up the effects of the invoked function + "dloadbytes": "memory", + "returndatacopy": "memory", + "calldatacopy": "memory", + "codecopy": "memory", + "extcodecopy": "memory", + "mcopy": "memory", +} +_reads = { + "sload": "storage", + "tload": "transient", + "iload": "immutables", + "mload": "memory", + "mcopy": "memory", + "call": _ALL, + "delegatecall": _ALL, + "staticcall": _ALL, + "returndatasize": "returndata", + "returndatacopy": "returndata", + "balance": "balance", + "selfbalance": "balance", + "log": "memory", + "revert": "memory", + "return": "memory", + "sha3": "memory", +} + + +def _mktuple(x): + if not isinstance(x, tuple): + x = (x,) + return x + + +writes = {k: _mktuple(v) for k, v in _writes.items()} +reads = {k: _mktuple(v) for k, v in _reads.items()} From e9b53036a0c827743f472a3add9f9e74842485ba Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Sat, 28 Sep 2024 08:35:03 -0700 Subject: [PATCH 2/9] fix get_write_effects() Co-authored-by: Harry Kalogirou --- vyper/venom/basicblock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vyper/venom/basicblock.py b/vyper/venom/basicblock.py index 07367d71fc..ae1db9b27c 100644 --- a/vyper/venom/basicblock.py +++ b/vyper/venom/basicblock.py @@ -247,7 +247,7 @@ def get_read_effects(self): return effects.reads.get(self.opcode, ()) def get_write_effects(self): - return effects.reads.get(self.opcode, ()) + return effects.writes.get(self.opcode, ()) def get_label_operands(self) -> Iterator[IRLabel]: """ From 8be0bef16935b0e871311c773b7d961be913faba Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Mon, 30 Sep 2024 07:11:50 -0700 Subject: [PATCH 3/9] Update vyper/venom/effects.py Co-authored-by: HodanPlodky <36966616+HodanPlodky@users.noreply.github.com> --- vyper/venom/effects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vyper/venom/effects.py b/vyper/venom/effects.py index 7f6aa52ac7..3c55c3cb5c 100644 --- a/vyper/venom/effects.py +++ b/vyper/venom/effects.py @@ -7,7 +7,7 @@ "istore": "immutables", "call": _ALL, "delegatecall": _ALL, - "staticcall": "memory", + "staticcall": ("memory", "returndata"), "create": _ALL, "create2": _ALL, "invoke": _ALL, # could be smarter, look up the effects of the invoked function From fcb688f0ade74dde67b838c6cbbe74ce0eab72ba Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Mon, 30 Sep 2024 12:16:13 -0400 Subject: [PATCH 4/9] update effects to be an enum.Flag --- vyper/venom/basicblock.py | 4 +- vyper/venom/effects.py | 97 ++++++++++++++++++++++----------------- 2 files changed, 56 insertions(+), 45 deletions(-) diff --git a/vyper/venom/basicblock.py b/vyper/venom/basicblock.py index ae1db9b27c..891dd3eb77 100644 --- a/vyper/venom/basicblock.py +++ b/vyper/venom/basicblock.py @@ -244,10 +244,10 @@ def is_bb_terminator(self) -> bool: return self.opcode in BB_TERMINATORS def get_read_effects(self): - return effects.reads.get(self.opcode, ()) + return effects.reads.get(self.opcode, effects.EMPTY) def get_write_effects(self): - return effects.writes.get(self.opcode, ()) + return effects.writes.get(self.opcode, effects.EMPTY) def get_label_operands(self) -> Iterator[IRLabel]: """ diff --git a/vyper/venom/effects.py b/vyper/venom/effects.py index 3c55c3cb5c..b018357898 100644 --- a/vyper/venom/effects.py +++ b/vyper/venom/effects.py @@ -1,48 +1,59 @@ -_ALL = ("storage", "transient", "memory", "immutables", "balance", "returndata") +from enum import Flag, auto -_writes = { - "sstore": "storage", - "tstore": "transient", - "mstore": "memory", - "istore": "immutables", - "call": _ALL, - "delegatecall": _ALL, - "staticcall": ("memory", "returndata"), - "create": _ALL, - "create2": _ALL, - "invoke": _ALL, # could be smarter, look up the effects of the invoked function - "dloadbytes": "memory", - "returndatacopy": "memory", - "calldatacopy": "memory", - "codecopy": "memory", - "extcodecopy": "memory", - "mcopy": "memory", -} -_reads = { - "sload": "storage", - "tload": "transient", - "iload": "immutables", - "mload": "memory", - "mcopy": "memory", - "call": _ALL, - "delegatecall": _ALL, - "staticcall": _ALL, - "returndatasize": "returndata", - "returndatacopy": "returndata", - "balance": "balance", - "selfbalance": "balance", - "log": "memory", - "revert": "memory", - "return": "memory", - "sha3": "memory", -} + +class Effects(Flag): + STORAGE = auto() + TRANSIENT = auto() + MEMORY = auto() + IMMUTABLES = auto() + BALANCE = auto() + RETURNDATA = auto() -def _mktuple(x): - if not isinstance(x, tuple): - x = (x,) - return x +EMPTY = Effects(0) +ALL = ~EMPTY +STORAGE = Effects.STORAGE +TRANSIENT = Effects.TRANSIENT +MEMORY = Effects.MEMORY +IMMUTABLES = Effects.IMMUTABLES +BALANCE = Effects.BALANCE +RETURNDATA = Effects.RETURNDATA -writes = {k: _mktuple(v) for k, v in _writes.items()} -reads = {k: _mktuple(v) for k, v in _reads.items()} +writes = { + "sstore": STORAGE, + "tstore": TRANSIENT, + "mstore": MEMORY, + "istore": IMMUTABLES, + "call": ALL, + "delegatecall": ALL, + "staticcall": MEMORY | RETURNDATA, + "create": ALL, + "create2": ALL, + "invoke": ALL, # could be smarter, look up the effects of the invoked function + "dloadbytes": MEMORY, + "returndatacopy": MEMORY, + "calldatacopy": MEMORY, + "codecopy": MEMORY, + "extcodecopy": MEMORY, + "mcopy": MEMORY, +} + +reads = { + "sload": STORAGE, + "tload": TRANSIENT, + "iload": IMMUTABLES, + "mload": MEMORY, + "mcopy": MEMORY, + "call": ALL, + "delegatecall": ALL, + "staticcall": ALL, + "returndatasize": RETURNDATA, + "returndatacopy": RETURNDATA, + "balance": BALANCE, + "selfbalance": BALANCE, + "log": MEMORY, + "revert": MEMORY, + "return": MEMORY, + "sha3": MEMORY, +} From 2e6cbb113bf39cb375a4000664cf652b8c9382d6 Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Tue, 1 Oct 2024 11:16:16 -0400 Subject: [PATCH 5/9] add extcode and msize effects add missing create effects --- vyper/venom/effects.py | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/vyper/venom/effects.py b/vyper/venom/effects.py index b018357898..ec9015e493 100644 --- a/vyper/venom/effects.py +++ b/vyper/venom/effects.py @@ -6,8 +6,10 @@ class Effects(Flag): TRANSIENT = auto() MEMORY = auto() IMMUTABLES = auto() - BALANCE = auto() RETURNDATA = auto() + BALANCE = auto() + EXTCODE = auto() + MSIZE = auto() EMPTY = Effects(0) @@ -16,11 +18,13 @@ class Effects(Flag): TRANSIENT = Effects.TRANSIENT MEMORY = Effects.MEMORY IMMUTABLES = Effects.IMMUTABLES -BALANCE = Effects.BALANCE RETURNDATA = Effects.RETURNDATA +BALANCE = Effects.BALANCE +EXTCODE = Effects.EXTCODE +MSIZE = Effects.MSIZE -writes = { +_writes = { "sstore": STORAGE, "tstore": TRANSIENT, "mstore": MEMORY, @@ -39,7 +43,7 @@ class Effects(Flag): "mcopy": MEMORY, } -reads = { +_reads = { "sload": STORAGE, "tload": TRANSIENT, "iload": IMMUTABLES, @@ -48,12 +52,26 @@ class Effects(Flag): "call": ALL, "delegatecall": ALL, "staticcall": ALL, + "create": ALL, + "create2": ALL, + "invoke": ALL, "returndatasize": RETURNDATA, "returndatacopy": RETURNDATA, "balance": BALANCE, "selfbalance": BALANCE, + "extcodecopy": EXTCODE, "log": MEMORY, "revert": MEMORY, "return": MEMORY, "sha3": MEMORY, + "msize": MSIZE, } + +reads = _reads.copy() +writes = _writes.copy() + +for k, v in reads.items(): + if MEMORY in v: + if k not in writes: + writes[k] = EMPTY + writes[k] |= MSIZE From bcd45800b292e242009f0eb302f46bb4756ff9d1 Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Tue, 1 Oct 2024 15:18:02 -0400 Subject: [PATCH 6/9] refine create effects --- vyper/venom/effects.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vyper/venom/effects.py b/vyper/venom/effects.py index ec9015e493..99ae2a9941 100644 --- a/vyper/venom/effects.py +++ b/vyper/venom/effects.py @@ -29,11 +29,11 @@ class Effects(Flag): "tstore": TRANSIENT, "mstore": MEMORY, "istore": IMMUTABLES, - "call": ALL, - "delegatecall": ALL, + "call": ALL ^ IMMUTABLES, + "delegatecall": ALL ^ IMMUTABLES, "staticcall": MEMORY | RETURNDATA, - "create": ALL, - "create2": ALL, + "create": ALL ^ (MEMORY | IMMUTABLES), + "create2": ALL ^ (MEMORY | IMMUTABLES), "invoke": ALL, # could be smarter, look up the effects of the invoked function "dloadbytes": MEMORY, "returndatacopy": MEMORY, From e5923e4732f93b038fb0bf7025e60cf0dc18572f Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Wed, 2 Oct 2024 19:07:57 -0400 Subject: [PATCH 7/9] add msize effect for memory writes --- vyper/venom/effects.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vyper/venom/effects.py b/vyper/venom/effects.py index 99ae2a9941..7f023209c5 100644 --- a/vyper/venom/effects.py +++ b/vyper/venom/effects.py @@ -75,3 +75,7 @@ class Effects(Flag): if k not in writes: writes[k] = EMPTY writes[k] |= MSIZE + +for k, v in writes.items(): + if MEMORY in v: + writes[k] |= MSIZE From e994e53f4fb7f5b65dc381cbfe2123db8eea4395 Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Wed, 2 Oct 2024 19:08:57 -0400 Subject: [PATCH 8/9] add selfdestruct effect --- vyper/venom/effects.py | 1 + 1 file changed, 1 insertion(+) diff --git a/vyper/venom/effects.py b/vyper/venom/effects.py index 7f023209c5..143097b8e8 100644 --- a/vyper/venom/effects.py +++ b/vyper/venom/effects.py @@ -60,6 +60,7 @@ class Effects(Flag): "balance": BALANCE, "selfbalance": BALANCE, "extcodecopy": EXTCODE, + "selfdestruct": BALANCE, # may modify code, but after the transaction "log": MEMORY, "revert": MEMORY, "return": MEMORY, From 2efaf684d808ba8d0a617c8c69edf36a4c294a9c Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Fri, 4 Oct 2024 09:20:20 -0400 Subject: [PATCH 9/9] add log effect --- vyper/venom/effects.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/vyper/venom/effects.py b/vyper/venom/effects.py index 143097b8e8..20cc0e4b02 100644 --- a/vyper/venom/effects.py +++ b/vyper/venom/effects.py @@ -5,11 +5,12 @@ class Effects(Flag): STORAGE = auto() TRANSIENT = auto() MEMORY = auto() + MSIZE = auto() IMMUTABLES = auto() RETURNDATA = auto() + LOG = auto() BALANCE = auto() EXTCODE = auto() - MSIZE = auto() EMPTY = Effects(0) @@ -17,11 +18,12 @@ class Effects(Flag): STORAGE = Effects.STORAGE TRANSIENT = Effects.TRANSIENT MEMORY = Effects.MEMORY +MSIZE = Effects.MSIZE IMMUTABLES = Effects.IMMUTABLES RETURNDATA = Effects.RETURNDATA +LOG = Effects.LOG BALANCE = Effects.BALANCE EXTCODE = Effects.EXTCODE -MSIZE = Effects.MSIZE _writes = { @@ -35,6 +37,7 @@ class Effects(Flag): "create": ALL ^ (MEMORY | IMMUTABLES), "create2": ALL ^ (MEMORY | IMMUTABLES), "invoke": ALL, # could be smarter, look up the effects of the invoked function + "log": LOG, "dloadbytes": MEMORY, "returndatacopy": MEMORY, "calldatacopy": MEMORY,