|
1 |
| -use revm_primitives::Bytes; |
2 |
| - |
3 | 1 | use crate::{
|
4 | 2 | gas,
|
5 |
| - primitives::{Spec, U256}, |
| 3 | + primitives::{Bytes, Spec, U256}, |
6 | 4 | Host, InstructionResult, Interpreter, InterpreterResult,
|
7 | 5 | };
|
8 | 6 |
|
9 | 7 | pub fn jump<H: Host>(interpreter: &mut Interpreter, _host: &mut H) {
|
10 | 8 | gas!(interpreter, gas::MID);
|
11 | 9 | pop!(interpreter, dest);
|
12 |
| - let dest = as_usize_or_fail!(interpreter, dest, InstructionResult::InvalidJump); |
13 |
| - if interpreter.contract.is_valid_jump(dest) { |
14 |
| - // SAFETY: In analysis we are checking create our jump table and we do check above to be |
15 |
| - // sure that jump is safe to execute. |
16 |
| - interpreter.instruction_pointer = |
17 |
| - unsafe { interpreter.contract.bytecode.as_ptr().add(dest) }; |
18 |
| - } else { |
19 |
| - interpreter.instruction_result = InstructionResult::InvalidJump; |
20 |
| - } |
| 10 | + jump_inner(interpreter, dest); |
21 | 11 | }
|
22 | 12 |
|
23 | 13 | pub fn jumpi<H: Host>(interpreter: &mut Interpreter, _host: &mut H) {
|
24 | 14 | gas!(interpreter, gas::HIGH);
|
25 | 15 | pop!(interpreter, dest, value);
|
26 | 16 | if value != U256::ZERO {
|
27 |
| - let dest = as_usize_or_fail!(interpreter, dest, InstructionResult::InvalidJump); |
28 |
| - if interpreter.contract.is_valid_jump(dest) { |
29 |
| - // SAFETY: In analysis we are checking if jump is valid destination and |
30 |
| - // this `if` makes this unsafe block safe. |
31 |
| - interpreter.instruction_pointer = |
32 |
| - unsafe { interpreter.contract.bytecode.as_ptr().add(dest) }; |
33 |
| - } else { |
34 |
| - interpreter.instruction_result = InstructionResult::InvalidJump |
35 |
| - } |
| 17 | + jump_inner(interpreter, dest); |
| 18 | + } |
| 19 | +} |
| 20 | + |
| 21 | +#[inline(always)] |
| 22 | +fn jump_inner(interpreter: &mut Interpreter, dest: U256) { |
| 23 | + let dest = as_usize_or_fail!(interpreter, dest, InstructionResult::InvalidJump); |
| 24 | + if !interpreter.contract.is_valid_jump(dest) { |
| 25 | + interpreter.instruction_result = InstructionResult::InvalidJump; |
| 26 | + return; |
36 | 27 | }
|
| 28 | + // SAFETY: `is_valid_jump` ensures that `dest` is in bounds. |
| 29 | + interpreter.instruction_pointer = unsafe { interpreter.contract.bytecode.as_ptr().add(dest) }; |
37 | 30 | }
|
38 | 31 |
|
39 | 32 | pub fn jumpdest<H: Host>(interpreter: &mut Interpreter, _host: &mut H) {
|
|
0 commit comments