You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: spec/eof.md
+9-8Lines changed: 9 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -204,24 +204,24 @@ The following instructions are introduced in EOF code:
204
204
- if `case > max_index` (out-of-bounds case), fall through and set `pc += (max_index + 1) * 2`
205
205
- otherwise interpret 2 byte operand at `pc + case * 2` as int16, call it `offset`, and set `pc += (max_index + 1) * 2 + offset`
206
206
- introduce new vm context variables
207
-
-`current_code_idx` which stores the actively executing code section index
207
+
-`current_section_index` which stores the actively executing code section index
208
208
- new `return_stack` which stores the pairs `(code_section, pc)`.
209
209
- when instantiating a vm context, push an initial value to the *return stack* of `(0,0)`
210
210
-`CALLF (0xe3)` instruction
211
211
- deduct 5 gas
212
212
- read uint16 operand `idx`
213
213
- if `1024 < len(stack) + types[idx].max_stack_increase`, execution results in an exceptional halt
214
214
- if `1024 <= len(return_stack)`, execution results in an exceptional halt
215
-
- push new element to `return_stack``(current_code_idx, pc+3)`
216
-
- update `current_code_idx` to `idx` and set `pc` to 0
215
+
- push new element to `return_stack``(current_section_index, pc+3)`
216
+
- update `current_section_index` to `idx` and set `pc` to 0
217
217
-`RETF (0xe4)` instruction
218
218
- deduct 3 gas
219
-
- pops `val` from `return_stack` and sets `current_code_idx` to `val.code_section` and `pc` to `val.pc`
219
+
- pops `val` from `return_stack` and sets `current_section_index` to `val.code_section` and `pc` to `val.pc`
220
220
-`JUMPF (0xe5)` instruction
221
221
- deduct 5 gas
222
222
- read uint16 operand `idx`
223
223
- if `1024 < len(stack) + types[idx].max_stack_increase`, execution results in an exceptional halt
224
-
- set `current_code_idx` to `idx`
224
+
- set `current_section_index` to `idx`
225
225
- set `pc = 0`
226
226
-`EOFCREATE (0xec)` instruction
227
227
- deduct `32000` gas
@@ -369,9 +369,10 @@ During scanning, for each instruction:
369
369
2. Determine the effect the instruction has on the operand stack:
370
370
1. Check if the recorded stack height bounds satisfy the instruction requirements. Specifically:
371
371
- for `CALLF` the following must hold: `stack_height_min >= types[target_section_index].inputs`,
372
-
- for `RETF` the following must hold: `stack_height_max == stack_height_min == types[current_code_index].outputs`,
372
+
- for `RETF` the following must hold: `stack_height_max == stack_height_min == types[current_section_index].outputs`,
373
373
- Stack validation of `JUMPF` depends on "non-returning" status of target section
374
-
-`JUMPF` into returning section (can be only from returning section): `stack_height_min == stack_height_max == type[current_section_index].outputs + type[target_section_index].inputs - type[target_section_index].outputs`
374
+
-`JUMPF` into returning section (can be only from returning section): `stack_height_min == stack_height_max == type[current_section_index].outputs + type[target_section_index].inputs - type[target_section_index].outputs`.
375
+
**NOTE**: This means `JUMPF` must ensure target's inputs, must ensure its own outputs (to return control), but must take into account that the target section may leave extra output items after it finishes, so it may need that many fewer items on the operand stack
375
376
-`JUMPF` into non-returning section: `stack_height_min >= types[target_section_index].inputs`
376
377
- for any other instruction `stack_height_min` must be at least the number of inputs required by instruction,
377
378
- there is no additional check for terminating instructions other than `RETF` and `JUMPF`, this implies that extra items left on stack at instruction ending EVM execution are allowed.
@@ -389,7 +390,7 @@ During scanning, for each instruction:
389
390
2. If the successor is reached via forwards jump or sequential flow from previous instruction:
390
391
1. If the instruction does not have stack heights recorded (visited for the first time), record the instruction `stack_height_min` and `stack_height_max` equal to the value computed in 2.3.
391
392
2. Otherwise instruction was already visited (by previously seen forward jump). Update this instruction's recorded stack height bounds so that they contain the bounds computed in 2.3, i.e. `target_stack_min = min(target_stack_min, current_stack_min)` and `target_stack_max = max(target_stack_max, current_stack_max)`, where `(target_stack_min, target_stack_max)` are successor bounds and `(current_stack_min, current_stack_max)` are bounds computed in 2.3.
392
-
3. If the successor is reached via backwards jump, check if target bounds equal the value computed in 2.3, i.e. `target_stack_min == current_stack_min && target_stack_max == current_stack_max`. Validation fails if they are not equal, i.e. we see backwards jump to a different stack height.
393
+
3. If the successor is reached via backwards jump, check if target bounds equal the value computed in 2.3, i.e. `target_stack_min == current_stack_min && target_stack_max == current_stack_max`. Validation fails if they are not equal, i.e. we see backwards jump to a different stack height.**NOTE**: Since instructions are scanned in a single linear pass, the existence of target stack heights is guaranteed for a backwards jump.
393
394
394
395
- Compute the maximum stack height `max_stack_height` as the maximum of all recorded stack height upper bounds.
395
396
- Compute the maximum stack height increase `max_stack_increase` as `max_stack_height - type[current_section_index].inputs`.
0 commit comments