diff --git a/EIPS/eip-2315.md b/EIPS/eip-2315.md index b58f6194..bc8c88a0 100644 --- a/EIPS/eip-2315.md +++ b/EIPS/eip-2315.md @@ -36,25 +36,28 @@ pushes: `0` 1. Pops `1` value from the `stack`, hereafter referred to as `location`. - 1.1 If the opcode at `location` is not a `BEGINSUB`, abort with error. -2. Pushes the current `pc+1` to the `return_stack`. +2. Pushes the current `pc+1` to the `return_stack`. (See Note 1 below) - 2.1 If the `return_stack` already has `1023` items, abort with error. 3. Sets the `pc` to `location`. pops: `1` pushes: `0` (`return_stack` pushes: `1`) +**Note 1:** The description above lays out the _semantics_ of the `JUMPSUB`. It's up to node implementations to decide the internal representation. For example, a node may decide +to place `PC` on the `return_stack` at `JUMPSUB`, as long as the `RETURNSUB` correctly returns to the `PC+1` location. The internals of the `return_stack` is not one of the +"observable"/consensus-critical parts of the EVM. ##### `RETURNSUB` 1. Pops `1` value form the `return_stack`. 1.1 If the `return_stack` is empty, abort with error -2. Sets `pc` to the popped value +2. Sets `pc` to the popped value (See Note 1 above) pops: `0` (`return_stack` pops: `1`) pushes: `0` -**Note:** Values popped from `return_stack` do not need to be validated, since they cannot be set arbitrarily from code, only implicitly by the evm. -**Note2:** A value popped from `return_stack` _may_ be outside of the code length, if the last `JUMPSUB` was the last byte of the `code`. In this case the next opcode is implicitly a `STOP`, which is not an error. +**Note 2:** Values popped from `return_stack` do not need to be validated, since they cannot be set arbitrarily from code, only implicitly by the evm. +**Note 3:** A value popped from `return_stack` _may_ be outside of the code length, if the last `JUMPSUB` was the last byte of the `code`. In this case the next opcode is implicitly a `STOP`, which is not an error. ## Rationale @@ -142,6 +145,25 @@ Bytecode: `0xb75858` (`RETURNSUB`, `PC`, `PC`) Error: at pc=0, op=RETURNSUB: evm: invalid retsub ``` +### Subroutine at end of code + +In this example. the JUMPSUB is on the last byte of code. When the subroutine returns, it should hit the 'virtual stop' _after_ the bytecode, and not exit with error + +Bytecode: `0x600556b2b75b6003b3` + +| Pc | Op | Cost | Stack | RStack | +|-------|-------------|------|-----------|-----------| +| 0 | PUSH1 | 3 | [] | [] | +| 2 | JUMP | 8 | [5] | [] | +| 5 | JUMPDEST | 1 | [] | [] | +| 6 | PUSH1 | 3 | [] | [] | +| 8 | JUMPSUB | 8 | [3] | [] | +| 3 | BEGINSUB | 1 | [] | [ 8] | +| 4 | RETURNSUB | 2 | [] | [ 8] | +| 9 | STOP | 0 | [] | [] | + +Consumed gas: `26` + ## Implementations No clients have implemented this proposal as of yet, but there are Draft PRs for