1use super::{DEF_SPEC, with_evm_context};
2use crate::{Backend, EvmCompiler, TEST_SUSPEND};
3use revm_bytecode::opcode as op;
4use revm_interpreter::InstructionResult;
5use revm_primitives::{U256, hardfork::SpecId};
6
7matrix_tests!(legacy = |compiler| run(compiler, TEST, DEF_SPEC));
8
9#[rustfmt::skip]
10const TEST: &[u8] = &[
11 op::PUSH1, 0x42,
13 TEST_SUSPEND,
14
15 op::PUSH1, 0x69,
17 TEST_SUSPEND,
18
19 op::ADD,
21 TEST_SUSPEND,
22
23 op::STOP,
25];
26
27fn run<B: Backend>(compiler: &mut EvmCompiler<B>, code: &[u8], spec_id: SpecId) {
28 let f = unsafe { compiler.jit("resume", code, spec_id) }.unwrap();
29
30 with_evm_context(code, spec_id, |ecx, stack, stack_len| {
31 assert_eq!(ecx.resume_at.get(), 0);
32
33 let r = unsafe { f.call(stack, stack_len, ecx) };
39 assert_eq!(r, InstructionResult::Stop);
40 assert_eq!(*stack_len, 1);
41 assert_eq!(unsafe { stack.as_slice(*stack_len) }[0].to_u256(), U256::from(0x42));
42 let resume_1 = ecx.resume_at;
43 assert_eq!(resume_1.get(), 1);
44
45 let r = unsafe { f.call(stack, stack_len, ecx) };
47 assert_eq!(r, InstructionResult::Stop);
48 assert_eq!(*stack_len, 2);
49 assert_eq!(unsafe { stack.as_slice(*stack_len) }[0].to_u256(), U256::from(0x42));
50 assert_eq!(unsafe { stack.as_slice(*stack_len) }[1].to_u256(), U256::from(0x69));
51 let resume_2 = ecx.resume_at;
52 assert_eq!(resume_2.get(), 2);
53
54 let r = unsafe { f.call(stack, stack_len, ecx) };
56 assert_eq!(r, InstructionResult::Stop);
57 assert_eq!(*stack_len, 1);
58 assert_eq!(unsafe { stack.as_slice(*stack_len) }[0].to_u256(), U256::from(0x42 + 0x69));
59 let resume_3 = ecx.resume_at;
60 assert_eq!(resume_3.get(), 3);
61
62 let r = unsafe { f.call(stack, stack_len, ecx) };
64 assert_eq!(r, InstructionResult::Stop);
65 assert_eq!(*stack_len, 1);
66 assert_eq!(unsafe { stack.as_slice(*stack_len) }[0].to_u256(), U256::from(0x42 + 0x69));
67 assert_eq!(ecx.resume_at, resume_3);
68
69 ecx.resume_at = resume_2;
71 let r = unsafe { f.call(stack, stack_len, ecx) };
72 assert_eq!(r, InstructionResult::StackUnderflow);
73 assert_eq!(*stack_len, 1);
74 assert_eq!(unsafe { stack.as_slice(*stack_len) }[0].to_u256(), U256::from(0x42 + 0x69));
75 assert_eq!(ecx.resume_at, resume_2);
76
77 stack.set(*stack_len, U256::from(2).into());
78 *stack_len += 1;
79
80 ecx.resume_at = resume_2;
82 let r = unsafe { f.call(stack, stack_len, ecx) };
83 assert_eq!(r, InstructionResult::Stop);
84 assert_eq!(*stack_len, 1);
85 assert_eq!(unsafe { stack.as_slice(*stack_len) }[0].to_u256(), U256::from(0x42 + 0x69 + 2));
86 assert_eq!(ecx.resume_at, resume_3);
87
88 ecx.resume_at = resume_1;
90 let r = unsafe { f.call(stack, stack_len, ecx) };
91 assert_eq!(r, InstructionResult::Stop);
92 assert_eq!(*stack_len, 2);
93 assert_eq!(unsafe { stack.as_slice(*stack_len) }[0].to_u256(), U256::from(0x42 + 0x69 + 2));
94 assert_eq!(unsafe { stack.as_slice(*stack_len) }[1].to_u256(), U256::from(0x69));
95 assert_eq!(ecx.resume_at, resume_2);
96
97 let r = unsafe { f.call(stack, stack_len, ecx) };
99 assert_eq!(r, InstructionResult::Stop);
100 assert_eq!(*stack_len, 1);
101 assert_eq!(
102 unsafe { stack.as_slice(*stack_len) }[0].to_u256(),
103 U256::from(0x42 + 0x69 + 2 + 0x69)
104 );
105 assert_eq!(ecx.resume_at, resume_3);
106
107 let r = unsafe { f.call(stack, stack_len, ecx) };
109 assert_eq!(r, InstructionResult::Stop);
110 assert_eq!(*stack_len, 1);
111 assert_eq!(
112 unsafe { stack.as_slice(*stack_len) }[0].to_u256(),
113 U256::from(0x42 + 0x69 + 2 + 0x69)
114 );
115 assert_eq!(ecx.resume_at, resume_3);
116
117 let r = unsafe { f.call(stack, stack_len, ecx) };
119 assert_eq!(r, InstructionResult::Stop);
120 assert_eq!(*stack_len, 1);
121 assert_eq!(
122 unsafe { stack.as_slice(*stack_len) }[0].to_u256(),
123 U256::from(0x42 + 0x69 + 2 + 0x69)
124 );
125 assert_eq!(ecx.resume_at, resume_3);
126 });
127}