Skip to content

Commit 7a2392f

Browse files
committed
feat(tools): Implement While code opcode generator
1 parent 1c2e150 commit 7a2392f

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

src/ethereum_test_tools/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
Conditional,
8080
Initcode,
8181
Switch,
82+
While,
8283
Yul,
8384
YulCompiler,
8485
)
@@ -145,6 +146,7 @@
145146
"TransactionTest",
146147
"TransactionTestFiller",
147148
"UndefinedOpcodes",
149+
"While",
148150
"Withdrawal",
149151
"WithdrawalRequest",
150152
"Yul",
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
"""Code related utilities and classes."""
22

3-
from .generators import CalldataCase, Case, CodeGasMeasure, Conditional, Initcode, Switch
3+
from .generators import CalldataCase, Case, CodeGasMeasure, Conditional, Initcode, Switch, While
44
from .yul import Solc, Yul, YulCompiler
55

66
__all__ = (
7-
"Case",
87
"CalldataCase",
8+
"Case",
99
"CodeGasMeasure",
1010
"Conditional",
1111
"Initcode",
1212
"Solc",
1313
"Switch",
14+
"While",
1415
"Yul",
1516
"YulCompiler",
1617
)

src/ethereum_test_tools/code/generators.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,33 @@ def __new__(
237237
return super().__new__(cls, bytecode)
238238

239239

240+
class While(Bytecode):
241+
"""Helper class used to generate while-loop bytecode."""
242+
243+
def __new__(
244+
cls,
245+
*,
246+
body: Bytecode | Op,
247+
condition: Bytecode | Op,
248+
evm_code_type: EVMCodeType = EVMCodeType.LEGACY,
249+
):
250+
"""
251+
Assemble the loop bytecode.
252+
253+
The condition nor the body can leave a stack item on the stack.
254+
"""
255+
bytecode = Bytecode()
256+
if evm_code_type == EVMCodeType.LEGACY:
257+
bytecode += Op.JUMPDEST
258+
bytecode += body
259+
bytecode += Op.JUMPI(
260+
Op.SUB(Op.PC, Op.PUSH4[len(body) + len(condition) + 6]), condition
261+
)
262+
elif evm_code_type == EVMCodeType.EOF_V1:
263+
raise NotImplementedError("EOF while loops are not implemented")
264+
return super().__new__(cls, bytecode)
265+
266+
240267
@dataclass(kw_only=True)
241268
class Case:
242269
"""

0 commit comments

Comments
 (0)