Skip to content

Commit 62f6d23

Browse files
committed
[WIP] Implement subroutine opcodes
1 parent b8e7811 commit 62f6d23

File tree

7 files changed

+36
-34
lines changed

7 files changed

+36
-34
lines changed

eth/abc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1598,7 +1598,7 @@ def rstack_push_int(self) -> Callable[[int], None]:
15981598
"""
15991599
Push integer onto the return stack.
16001600
"""
1601-
1601+
16021602
@abstractmethod
16031603
def rstack_pop1_int(self) -> Callable[[int], None]:
16041604
"""

eth/vm/computation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ def stack_push_int(self) -> Callable[[int], None]:
324324
@cached_property
325325
def stack_push_bytes(self) -> Callable[[bytes], None]:
326326
return self._stack.push_bytes
327-
327+
328328
#
329329
# Return Stack Management
330330
#

eth/vm/forks/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@
2525
from .muir_glacier import ( # noqa: F401
2626
MuirGlacierVM,
2727
)
28-
from .berlin import (
28+
from .berlin import ( # noqa: F401
2929
BerlinVM,
3030
)

eth/vm/forks/berlin/opcodes.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,24 @@
1414
from eth.vm.logic import flow
1515

1616
UPDATED_OPCODES = {
17-
opcode_values.BEGINSUB: as_opcode(
18-
logic_fn = flow.beginsub,
19-
mnemonic = mnemonics.BEGINSUB,
20-
gas_cost = constants.GAS_BASE,
21-
),
22-
opcode_values.JUMPSUB: as_opcode(
23-
logic_fn = flow.jumpsub,
24-
mnemonic = mnemonics.JUMPSUB,
25-
gas_cost = constants.GAS_HIGH,
26-
),
27-
opcode_values.RETURNSUB: as_opcode(
28-
logic_fn = flow.returnsub,
29-
mnemonic = mnemonics.RETURNSUB,
30-
gas_cost = constants.GAS_LOW,
31-
),
17+
opcode_values.BEGINSUB: as_opcode(
18+
logic_fn=flow.beginsub,
19+
mnemonic=mnemonics.BEGINSUB,
20+
gas_cost=constants.GAS_BASE,
21+
),
22+
opcode_values.JUMPSUB: as_opcode(
23+
logic_fn=flow.jumpsub,
24+
mnemonic=mnemonics.JUMPSUB,
25+
gas_cost=constants.GAS_HIGH,
26+
),
27+
opcode_values.RETURNSUB: as_opcode(
28+
logic_fn=flow.returnsub,
29+
mnemonic=mnemonics.RETURNSUB,
30+
gas_cost=constants.GAS_LOW,
31+
),
3232
}
3333

34-
3534
BERLIN_OPCODES = merge(
36-
copy.deepcopy(MUIR_GLACIER_OPCODES),
37-
UPDATED_OPCODES,
35+
copy.deepcopy(MUIR_GLACIER_OPCODES),
36+
UPDATED_OPCODES,
3837
)

eth/vm/logic/flow.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ def jumpsub(computation: BaseComputation) -> None:
7171
code_range_length = computation.code._length_cache
7272

7373
if sub_loc >= code_range_length:
74-
raise InvalidJumpDestination("Error: at pc={}, op=JUMPSUB: invalid jump destination".format(computation.code.program_counter))
74+
raise InvalidJumpDestination(
75+
"Error: at pc={}, op=JUMPSUB: invalid jump destination".format(computation.code.program_counter))
7576

7677
if computation.code.is_valid_opcode(sub_loc):
7778

@@ -87,8 +88,7 @@ def returnsub(computation: BaseComputation) -> None:
8788
try:
8889
ret_loc = computation.rstack_pop1_int()
8990
except InsufficientStack:
90-
raise InsufficientStack("Error: at pc={}, op=RETURNSUB: invalid retsub".format(computation.code.program_counter))
91-
92-
93-
computation.code.program_counter = ret_loc
91+
raise InsufficientStack(
92+
"Error: at pc={}, op=RETURNSUB: invalid retsub".format(computation.code.program_counter))
9493

94+
computation.code.program_counter = ret_loc

eth/vm/rstack.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818

1919
"""
2020
This module simply implements for the return stack the exact same design used for the data stack.
21-
As this stack must simply push_int or pop1_int any time a subroutine is accessed or left, only those two functions are provided.
22-
For the same reason, the class RStack doesn't inherit from the abc StackAPI, as it would require to implement all the abstract methods defined.
21+
As this stack must simply push_int or pop1_int any time a subroutine is accessed or left, only those two functions are
22+
provided.
23+
For the same reason, the class RStack doesn't inherit from the abc StackAPI, as it would require to implement all the
24+
abstract methods defined.
2325
"""
2426

25-
class RStack():
27+
28+
class RStack:
2629
"""
2730
VM Return Stack
2831
"""
@@ -44,8 +47,7 @@ def push_int(self, value) -> int:
4447

4548
self._append((int, value))
4649

47-
48-
def pop1_int(self) -> int:
50+
def pop1_int(self, value) -> int:
4951
#
5052
# Note: This function is optimized for speed over readability.
5153
#
@@ -59,6 +61,6 @@ def pop1_int(self) -> int:
5961
return big_endian_to_int(popped) # type: ignore
6062
else:
6163
raise ValidationError(
62-
"Stack must always be bytes or int, "
63-
f"got {item_type!r} type, val {value!r}"
64+
"Stack must always be bytes or int, "
65+
f"got {item_type!r} type, val {value!r}"
6466
)

tests/core/opcodes/test_opcodes.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1127,6 +1127,7 @@ def test_blake2b_f_compression(vm_class, input_hex, output_hex, expect_exception
11271127
result = comp.output
11281128
assert result.hex() == output_hex
11291129

1130+
11301131
@pytest.mark.parametrize(
11311132
'vm_class, code, expect_gas_used',
11321133
(
@@ -1157,6 +1158,7 @@ def test_jumpsub(vm_class, code, expect_gas_used):
11571158
assert comp.is_success
11581159
assert comp.get_gas_used() == expect_gas_used
11591160

1161+
11601162
@pytest.mark.xfail(reason="invalid subroutines")
11611163
@pytest.mark.parametrize(
11621164
'vm_class, code',
@@ -1183,4 +1185,3 @@ def test_jumpsub(vm_class, code):
11831185
computation.transaction_context,
11841186
)
11851187
assert comp.is_success
1186-

0 commit comments

Comments
 (0)