cfx_executor/stack/
mod.rs1mod executable;
2mod frame_invoke;
3mod frame_local;
4mod frame_return;
5mod frame_start;
6mod resources;
7mod resumable;
8mod stack_info;
9
10pub use crate::context::Context;
11pub use executable::{Executable, ExecutableOutcome};
12pub use frame_local::FrameLocal;
13pub use frame_return::{FrameResult, FrameReturn};
14pub use frame_start::FreshFrame;
15pub use resources::RuntimeRes;
16pub use resumable::Resumable;
17pub use stack_info::CallStackInfo;
18
19#[cfg(test)]
20pub use resources::runtime_res_test::OwnedRuntimeRes;
21
22use crate::{substate::Substate, unwrap_or_return};
23use cfx_statedb::Result as DbResult;
24
25use frame_invoke::{InvokeInfo, SuspendedFrame};
26
27enum FrameStackAction<'a> {
34 Return(FrameResult),
36
37 Invoke(InvokeInfo<'a>),
39}
40
41pub fn exec_main_frame<'a>(
48 main_frame: FreshFrame<'a>, mut resources: RuntimeRes<'a>,
49) -> DbResult<FrameResult> {
50 let mut frame_stack: Vec<SuspendedFrame> = Vec::new();
51 let mut last_result = main_frame.init_and_exec(&mut resources)?;
52
53 loop {
54 last_result = match last_result {
55 FrameStackAction::Return(result) => {
56 let frame = unwrap_or_return!(frame_stack.pop(), Ok(result));
57 frame.resume(result, &mut resources)?
58 }
59 FrameStackAction::Invoke(InvokeInfo { callee, caller }) => {
60 frame_stack.push(caller);
61 callee.init_and_exec(&mut resources)?
62 }
63 }
64 }
65}
66
67#[inline]
72fn run_executable<'a>(
73 executable: Box<dyn 'a + Executable>, mut frame_local: FrameLocal<'a>,
74 resources: &mut RuntimeRes<'a>,
75) -> DbResult<FrameStackAction<'a>> {
76 let vm_context = frame_local.make_vm_context(resources);
77 let output = executable.execute(vm_context)?;
78
79 let exec_result = match output {
80 ExecutableOutcome::Return(result) => FrameStackAction::Return(
81 frame_return::process_return(frame_local, result, resources),
82 ),
83
84 ExecutableOutcome::Invoke(params, resumer) => FrameStackAction::Invoke(
85 frame_invoke::process_invoke(frame_local, params, resumer),
86 ),
87 };
88 Ok(exec_result)
89}
90
91pub fn accrue_substate(substate: &mut Substate, result: &mut FrameResult) {
94 if let Ok(frame_return) = result {
95 if let Some(child_substate) = std::mem::take(&mut frame_return.substate)
96 {
97 substate.accrue(child_substate);
98 }
99 }
100}