use cfx_vm_types::ActionParams;
use cfx_statedb::Result as DbResult;
use super::{
accrue_substate, run_executable, FrameLocal, FrameResult, FrameStackAction,
FreshFrame, Resumable, RuntimeRes,
};
pub(super) struct InvokeInfo<'a> {
pub callee: FreshFrame<'a>,
pub caller: SuspendedFrame<'a>,
}
pub(super) struct SuspendedFrame<'a> {
resumer: Box<dyn Resumable>,
frame_local: FrameLocal<'a>,
}
pub(super) fn process_invoke<'a>(
frame_local: FrameLocal<'a>, params: ActionParams,
resumer: Box<dyn Resumable>,
) -> InvokeInfo<'a> {
let callee = FreshFrame::new(
params,
frame_local.env,
frame_local.machine,
frame_local.spec,
frame_local.depth + 1,
frame_local.static_flag,
);
let caller = SuspendedFrame {
frame_local,
resumer,
};
InvokeInfo { callee, caller }
}
impl<'a> SuspendedFrame<'a> {
pub fn resume(
self, mut result: FrameResult, resources: &mut RuntimeRes<'a>,
) -> DbResult<FrameStackAction<'a>> {
let SuspendedFrame {
mut frame_local,
resumer,
} = self;
accrue_substate(&mut frame_local.substate, &mut result);
let executable = resumer.resume(result);
run_executable(executable, frame_local, resources)
}
}