Skip to content

Commit a6f499c

Browse files
committed
refactor custom_step harness
1 parent 5810ac9 commit a6f499c

File tree

1 file changed

+17
-23
lines changed

1 file changed

+17
-23
lines changed

kevm-pyk/src/kevm_pyk/kevm.py

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
if TYPE_CHECKING:
3636
from collections.abc import Iterable
3737
from pathlib import Path
38-
from typing import Final
38+
from typing import Callable, Final, Tuple
3939

4040
from pyk.cterm import CTermSymbolic
4141
from pyk.kast.inner import KAst, Subst
@@ -53,12 +53,12 @@
5353
class KEVMSemantics(DefaultSemantics):
5454
auto_abstract_gas: bool
5555
allow_symbolic_program: bool
56-
_cached_subst: Subst | None
56+
_custom_step_definitions: Tuple[Tuple[KSequence, Callable[[Subst, CTerm, CTermSymbolic], KCFGExtendResult | None]],...]
5757

5858
def __init__(self, auto_abstract_gas: bool = False, allow_symbolic_program: bool = False) -> None:
5959
self.auto_abstract_gas = auto_abstract_gas
6060
self.allow_symbolic_program = allow_symbolic_program
61-
self._cached_subst = None
61+
self._custom_step_definitions = ((self._load_pattern, self._exec_load_custom_step),)
6262

6363
@staticmethod
6464
def is_functional(term: KInner) -> bool:
@@ -145,11 +145,12 @@ def _replace(term: KInner) -> KInner:
145145

146146
return CTerm(config=bottom_up(_replace, cterm.config), constraints=cterm.constraints)
147147

148-
def custom_step(self, cterm: CTerm, _cterm_symbolic: CTermSymbolic) -> KCFGExtendResult | None:
149-
if self._check_load_pattern(cterm):
150-
return self._exec_load_custom_step(cterm)
151-
else:
152-
return None
148+
def custom_step(self, cterm: CTerm, cterm_symbolic: CTermSymbolic) -> KCFGExtendResult | None:
149+
for abstract_pattern, custom_step_fn in self._custom_step_definitions:
150+
subst = abstract_pattern.match(cterm.cell('K_CELL'))
151+
if subst is not None:
152+
return custom_step_fn(subst, cterm, cterm_symbolic)
153+
return None
153154

154155
@staticmethod
155156
def cut_point_rules(
@@ -197,26 +198,16 @@ def terminal_rules(break_every_step: bool) -> list[str]:
197198
terminal_rules.append('EVM.step')
198199
return terminal_rules
199200

200-
def _check_load_pattern(self, cterm: CTerm) -> bool:
201-
"""Given a CTerm, check if the rule 'EVM.program.load' is at the top of the K_CELL.
202-
203-
This method checks if the `EVM.program.load` rule is at the top of the `K_CELL` in the given `cterm`.
204-
If the rule matches, the resulting substitution is cached in `_cached_subst` for later use in `custom_step`
205-
:param cterm: The CTerm representing the current state of the proof node.
206-
:return: `True` if the pattern matches and a custom step can be made; `False` otherwise.
207-
"""
208-
load_pattern = KSequence([KApply('loadProgram', KVariable('###BYTECODE')), KVariable('###CONTINUATION')])
209-
self._cached_subst = load_pattern.match(cterm.cell('K_CELL'))
210-
return self._cached_subst is not None
201+
@property
202+
def _load_pattern(self) -> KSequence:
203+
return KSequence([KApply('loadProgram', KVariable('###BYTECODE')), KVariable('###CONTINUATION')])
211204

212-
def _exec_load_custom_step(self, cterm: CTerm) -> KCFGExtendResult:
205+
def _exec_load_custom_step(self, subst: Subst, cterm: CTerm, _c: CTermSymbolic) -> KCFGExtendResult:
213206
"""Given a CTerm, update the JUMPDESTS_CELL and PROGRAM_CELL if the rule 'EVM.program.load' is at the top of the K_CELL.
214207
215208
:param cterm: CTerm of a proof node.
216209
:return: If the K_CELL matches the load_pattern, a Step with depth 1 is returned together with the new configuration, also registering that the `EVM.program.load` rule has been applied.
217210
"""
218-
subst = self._cached_subst
219-
assert subst is not None
220211
bytecode_sections = flatten_label('_+Bytes__BYTES-HOOKED_Bytes_Bytes_Bytes', subst['###BYTECODE'])
221212
jumpdests_set = compute_jumpdests(bytecode_sections)
222213
new_cterm = CTerm.from_kast(set_cell(cterm.kast, 'JUMPDESTS_CELL', jumpdests_set))
@@ -225,7 +216,10 @@ def _exec_load_custom_step(self, cterm: CTerm) -> KCFGExtendResult:
225216
return Step(new_cterm, 1, (), ['EVM.program.load'], cut=True)
226217

227218
def can_make_custom_step(self, cterm: CTerm) -> bool:
228-
return self._check_load_pattern(cterm)
219+
return any(
220+
abstract_pattern.match(cterm.cell('K_CELL')) is not None
221+
for abstract_pattern, _ in self._custom_step_definitions
222+
)
229223

230224
def is_mergeable(self, ct1: CTerm, ct2: CTerm) -> bool:
231225
"""Given two CTerms of Edges' targets, check if they are mergeable.

0 commit comments

Comments
 (0)