DCIPs/EIPS/eip-663.md

90 lines
3.9 KiB
Markdown

---
eip: 663
title: Unlimited SWAP and DUP instructions
description: Introduce SWAPN and DUPN which take an immediate value for the depth
author: Alex Beregszaszi (@axic)
discussions-to: https://ethereum-magicians.org/t/eip-663-unlimited-swap-and-dup-instructions/3346
status: Review
type: Standards Track
category: Core
created: 2017-07-03
requires: 3540
---
## Abstract
Currently, `SWAP` and `DUP` instructions are limited to a stack depth of 16. Introduce two new instructions, `SWAPN` and `DUPN`, which lift this limitation and allow accessing the stack up to depth of 256 items.
## Motivation
While the stack is 1024 items deep, easy access is only possible for the top 16 items. Supporting more local variables is possible via manually keeping them in memory or through a "stack to memory elevation" in a compiler. This can result in complex and inefficient code.
Furthermore, implementing higher level constructs, such as functions, on top of EVM will result in a list of input and output parameters as well as an instruction offset to return to.
The number of these arguments (or stack items) can easily exceed 16 and thus will require extra care from a compiler to lay them out in a way that all of them are still accessible.
Introducing `SWAPN` and `DUPN` will provide an option to compilers to simplify accessing deep stack items at the price of possibly increased gas costs.
## Specification
We introduce two new instructions:
1. `DUPN` (`0xb5`)
2. `SWAPN` (`0xb6`)
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 valid EOF1, the following execution rules apply:
1. These instructions are followed by an 8-bit immediate value, which we call `imm`, and can have a value of 0 to 255. We introduce the variable `n` which equals to `imm + 1`.
2. For `DUPN`:
- If the current stack height is less than `n`, then a stack underflow exception is issued.
- If the current stack height is at the limit (1024), a stack overflow exception is issued.
- Otherwise the `n`'th stack item is duplicated at the top of the stack. (*Note: We use 1-based indexing here.*)
3. For `SWAPN`:
- If the current stack height is less than `n + 1`, then a stack underflow exception is issued.
- Otherwise the `n + 1`th stack item is swapped with the top stack item.
Clarification: the "stack underflow/overflow exception" means the EVM execution is halted and all gas is consumed.
The gas cost for both instructions is set at 3.
## Rationale
### EOF-only
Since this instruction depends on an immediate argument encoding, it can only be enabled within EOF. In legacy bytecode that encoding could contradict jumpdest-analysis.
### Size of immediate argument
A 16-bit size was considered to accommodate the full stack space of 1024 items, however:
1. that would require an additional restriction/check (`n < 1024`)
2. the 256 depth is a large improvement over the current 16 and the overhead of an extra byte would make it less useful
## Backwards Compatibility
This has no effect on backwards compatibility because the opcodes were not previously allocated and the feature is only enabled in EOF.
## Test Cases
For `0 <= n <= 255`:
- `DUPN n` to fail if `stack_height < n`.
- `SWAPN n` to fail if `stack_height < (n + 1)`.
- `DUPN n` to fail if `stack_height + 1 > 1024`.
- `DUPN n` and `SWAPN n` to fail if gas available is less than 3.
- otherwise `DUPN n` should push the `stack[n]` item to the stack, and `SWAPN n` should swap `stack[n + 1]` with `stack[stack.top()]`.
## Security Considerations
The authors are not aware of any additional risks introduced here. The EVM stack is fixed at 1024 items and most implementations keep that in memory at all times. This change will increase the easy-to-access number of items from 16 to 256.
## Copyright
Copyright and related rights waived via [CC0](../LICENSE.md).