Skip to content

Commit

Permalink
Add RJUMPV
Browse files Browse the repository at this point in the history
  • Loading branch information
axic committed Nov 28, 2022
1 parent 0d650fc commit 0f19fd1
Showing 1 changed file with 13 additions and 5 deletions.
18 changes: 13 additions & 5 deletions EIPS/eip-4200.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
eip: 4200
title: EOF - Static relative jumps
description: RJUMP and RJUMPI instructions with a signed immediate encoding the jump destination
description: RJUMP, RJUMPI and RJUMPV instructions with a signed immediate encoding the jump destination
author: Alex Beregszaszi (@axic), Andrei Maiboroda (@gumb0), Paweł Bylica (@chfast)
discussions-to: https://ethereum-magicians.org/t/eip-3920-static-relative-jumps/7108
status: Review
Expand Down Expand Up @@ -39,17 +39,21 @@ We introduce two new instructions on the same block number [EIP-3540](./eip-3540

1. `RJUMP` (0x5c)
2. `RJUMPI` (0x5d)
3. `RJUMPV` (0x5e)

If the code is legacy bytecode, both of these instructions result in an *exceptional halt*. (*Note: This means no change to behaviour.*)
If the code is legacy bytecode, all of these instructions result in an *exceptional halt*. (*Note: This means no change to behaviour.*)

If the code is valid EOF1:

1. `RJUMP relative_offset` (0x5c), sets the `PC` to `PC_post_instruction + relative_offset`.
2. `RJUMPI relative_offset` (0x5d), pops a value (`condition`) from the stack, and sets the `PC` to `PC_post_instruction + ((condition == 0) ? 0 : relative_offset)`.
1. `RJUMP relative_offset` sets the `PC` to `PC_post_instruction + relative_offset`.
2. `RJUMPI relative_offset` pops a value (`condition`) from the stack, and sets the `PC` to `PC_post_instruction + ((condition == 0) ? 0 : relative_offset)`.
3. `RJUMPV count relative_offset+` pops a value (`case`) from the stack, and sets the `PC` to `PC_post_instruction + ((case >= count) ? 0 : relative_offset[case])`.

The immediate argument `relative_offset` is encoded as a 16-bit **signed** (two's-complement) big-endian value. Under `PC_post_instruction` we mean the `PC` position after the entire immediate value.

We also extend the validation algorithm of [EIP-3670](./eip-3670.md) to verify that each `RJUMP`/`RJUMPI` has a `relative_offset` pointing to an instruction. This means it cannot point to an immediate data of `PUSHn`/`RJUMP`/`RJUMPI`. It cannot point outside of code bounds. It is allowed to point to a `JUMPDEST`, but is not required to.
The immediate encoding of `RJUMPV` is more special: the 8-bit `count` value incremented by 1 determines the number of `relative_offset` values following. Based on this it can be seen that the encoding of `RJUMPV` must have at least one `relative_offset` and thus it will take at minimum 4 bytes. Furthermore, the `case >= count` condition falling through means that in many use cases one would place the *default* path following the `RJUMPV` instruction.

We also extend the validation algorithm of [EIP-3670](./eip-3670.md) to verify that each `RJUMP`/`RJUMPI`/`RJUMPV` has a `relative_offset` pointing to an instruction. This means it cannot point to an immediate data of `PUSHn`/`RJUMP`/`RJUMPI`. It cannot point outside of code bounds. It is allowed to point to a `JUMPDEST`, but is not required to.

Because the destinations are validated upfront, the cost of these instructions are less than their dynamic counterparts: `RJUMP` should cost 5, and `RJUMPI` should cost 7. This is a reduction of 2 gas, compared to `JUMP` and `JUMPI`.

Expand Down Expand Up @@ -106,6 +110,10 @@ There are two benefits here:
1. Not wasting a byte for a `JUMPDEST` also means a saving of 200 gas during deployment, for each jump destination.
2. Saving an extra 1 gas per jump during execution, given `JUMPDEST` itself cost 1 gas and is "executed" during jumping.

### `RJUMPV` fallback case

If no match is found (i.e. the *default* case) in the `RJUMPV` instruction execution will continue without branching. This allows for gaps in the arguments to be filled with `0`s, and a choice of implementation by the programmer. Alternate options would include exceptional aborts in case of no match.

## Backwards Compatibility

This change poses no risk to backwards compatibility, as it is introduced at the same time EIP-3540 is. The new instructions are not introduced for legacy bytecode (code which is not EOF formatted).
Expand Down

0 comments on commit 0f19fd1

Please sign in to comment.