revm_interpreter/instructions/
control.rs1use crate::{
2 interpreter::Interpreter,
3 interpreter_types::{InterpreterTypes, Jumps, LoopControl, MemoryTr, RuntimeFlag, StackTr},
4 InstructionResult, InterpreterAction,
5};
6use primitives::{Bytes, U256};
7
8use crate::InstructionContext;
9
10pub fn jump<ITy: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, ITy>) {
14 popn!([target], context.interpreter);
16 jump_inner(context.interpreter, target);
17}
18
19pub fn jumpi<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
23 popn!([target, cond], context.interpreter);
25
26 if !cond.is_zero() {
27 jump_inner(context.interpreter, target);
28 }
29}
30
31#[inline(always)]
35fn jump_inner<WIRE: InterpreterTypes>(interpreter: &mut Interpreter<WIRE>, target: U256) {
36 let target = as_usize_or_fail!(interpreter, target, InstructionResult::InvalidJump);
37 if !interpreter.bytecode.is_valid_legacy_jump(target) {
38 interpreter.halt(InstructionResult::InvalidJump);
39 return;
40 }
41 interpreter.bytecode.absolute_jump(target);
43}
44
45pub fn jumpdest<WIRE: InterpreterTypes, H: ?Sized>(_context: InstructionContext<'_, H, WIRE>) {
49 }
51
52pub fn pc<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
56 push!(
59 context.interpreter,
60 U256::from(context.interpreter.bytecode.pc() - 1)
61 );
62}
63
64#[inline]
65fn return_inner(
69 interpreter: &mut Interpreter<impl InterpreterTypes>,
70 instruction_result: InstructionResult,
71) {
72 popn!([offset, len], interpreter);
75 let len = as_usize_or_fail!(interpreter, len);
76 let mut output = Bytes::default();
78 if len != 0 {
79 let offset = as_usize_or_fail!(interpreter, offset);
80 resize_memory!(interpreter, offset, len);
81 output = interpreter.memory.slice_len(offset, len).to_vec().into()
82 }
83
84 interpreter
85 .bytecode
86 .set_action(InterpreterAction::new_return(
87 instruction_result,
88 output,
89 interpreter.gas,
90 ));
91}
92
93pub fn ret<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
97 return_inner(context.interpreter, InstructionResult::Return);
98}
99
100pub fn revert<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
102 check!(context.interpreter, BYZANTIUM);
103 return_inner(context.interpreter, InstructionResult::Revert);
104}
105
106pub fn stop<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
108 context.interpreter.halt(InstructionResult::Stop);
109}
110
111pub fn invalid<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
113 context.interpreter.halt(InstructionResult::InvalidFEOpcode);
114}
115
116pub fn unknown<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
118 context.interpreter.halt(InstructionResult::OpcodeNotFound);
119}