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);
15 jump_inner(context.interpreter, target);
16}
17
18pub fn jumpi<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
22 popn!([target, cond], context.interpreter);
23 if !cond.is_zero() {
24 jump_inner(context.interpreter, target);
25 }
26}
27
28#[inline(always)]
32fn jump_inner<WIRE: InterpreterTypes>(interpreter: &mut Interpreter<WIRE>, target: U256) {
33 let target = as_usize_or_fail!(interpreter, target, InstructionResult::InvalidJump);
34 if !interpreter.bytecode.is_valid_legacy_jump(target) {
35 interpreter.halt(InstructionResult::InvalidJump);
36 return;
37 }
38 interpreter.bytecode.absolute_jump(target);
40}
41
42pub fn jumpdest<WIRE: InterpreterTypes, H: ?Sized>(_context: InstructionContext<'_, H, WIRE>) {}
46
47pub fn pc<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
51 push!(
53 context.interpreter,
54 U256::from(context.interpreter.bytecode.pc() - 1)
55 );
56}
57
58#[inline]
59fn return_inner(
63 interpreter: &mut Interpreter<impl InterpreterTypes>,
64 instruction_result: InstructionResult,
65) {
66 popn!([offset, len], interpreter);
67 let len = as_usize_or_fail!(interpreter, len);
68 let mut output = Bytes::default();
70 if len != 0 {
71 let offset = as_usize_or_fail!(interpreter, offset);
72 if !interpreter.resize_memory(offset, len) {
73 return;
74 }
75 output = interpreter.memory.slice_len(offset, len).to_vec().into()
76 }
77
78 interpreter
79 .bytecode
80 .set_action(InterpreterAction::new_return(
81 instruction_result,
82 output,
83 interpreter.gas,
84 ));
85}
86
87pub fn ret<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
91 return_inner(context.interpreter, InstructionResult::Return);
92}
93
94pub fn revert<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
96 check!(context.interpreter, BYZANTIUM);
97 return_inner(context.interpreter, InstructionResult::Revert);
98}
99
100pub fn stop<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
102 context.interpreter.halt(InstructionResult::Stop);
103}
104
105pub fn invalid<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
107 context.interpreter.halt(InstructionResult::InvalidFEOpcode);
108}
109
110pub fn unknown<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
112 context.interpreter.halt(InstructionResult::OpcodeNotFound);
113}