avm1: Introduce parents to StackFrame, and move run_activation from avm1 to StackFrame

This commit is contained in:
Nathan Adams 2020-06-28 18:32:38 +02:00
parent 9b630bd305
commit 0dd2ece371
3 changed files with 26 additions and 25 deletions

View File

@ -42,7 +42,7 @@ mod tests;
use crate::avm1::error::Error;
use crate::avm1::listeners::SystemListener;
use crate::avm1::stack_frame::{ReturnType, StackFrame};
use crate::avm1::stack_frame::StackFrame;
pub use activation::Activation;
pub use globals::SystemPrototypes;
pub use object::{Object, ObjectPtr, TObject};
@ -174,7 +174,7 @@ impl<'gc> Avm1<'gc> {
None,
),
);
if let Err(e) = activation.avm().run_activation(context, child_activation) {
if let Err(e) = activation.run_child_activation(child_activation, context) {
root_error_handler(activation, context, e);
}
});
@ -270,7 +270,7 @@ impl<'gc> Avm1<'gc> {
None,
),
);
if let Err(e) = activation.avm().run_activation(context, child_activation) {
if let Err(e) = activation.run_child_activation(child_activation, context) {
root_error_handler(activation, context, e);
}
});
@ -325,8 +325,7 @@ impl<'gc> Avm1<'gc> {
where
for<'b> F: FnOnce(&mut StackFrame<'b, 'gc>, &mut UpdateContext<'a, 'gc, '_>) -> R,
{
let mut stack_frame = StackFrame::new(self, activation);
// TODO: Handle
let mut stack_frame = StackFrame::new(self, None, activation);
function(&mut stack_frame, context)
}
@ -353,22 +352,6 @@ impl<'gc> Avm1<'gc> {
});
}
/// Execute the AVM stack until a given activation returns.
pub fn run_activation(
&mut self,
context: &mut UpdateContext<'_, 'gc, '_>,
activation: GcCell<'gc, Activation<'gc>>,
) -> Result<ReturnType<'gc>, Error<'gc>> {
let mut stack_frame = StackFrame::new(self, activation);
let result = stack_frame.run(context);
if let Err(error) = &result {
if error.is_halting() {
stack_frame.avm().halt();
}
}
result
}
/// Halts the AVM, preventing execution of any further actions.
///
/// If the AVM is currently evaluating an action, it will continue until it realizes that it has

View File

@ -364,7 +364,7 @@ impl<'gc> Executable<'gc> {
}
drop(frame);
Ok(activation.avm().run_activation(ac, frame_cell)?.value())
Ok(activation.run_child_activation(frame_cell, ac)?.value())
}
}
}

View File

@ -54,12 +54,30 @@ enum FrameControl<'gc> {
#[collect(no_drop)]
pub struct StackFrame<'a, 'gc: 'a> {
avm: &'a mut Avm1<'gc>,
parent: Option<GcCell<'gc, Activation<'gc>>>,
activation: GcCell<'gc, Activation<'gc>>,
}
impl<'a, 'gc: 'a> StackFrame<'a, 'gc> {
pub fn new(avm: &'a mut Avm1<'gc>, activation: GcCell<'gc, Activation<'gc>>) -> Self {
Self { avm, activation }
pub fn new(
avm: &'a mut Avm1<'gc>,
parent: Option<GcCell<'gc, Activation<'gc>>>,
activation: GcCell<'gc, Activation<'gc>>,
) -> Self {
Self {
avm,
parent,
activation,
}
}
pub fn run_child_activation(
&mut self,
activation: GcCell<'gc, Activation<'gc>>,
context: &mut UpdateContext<'_, 'gc, '_>,
) -> Result<ReturnType<'gc>, Error<'gc>> {
let mut child = StackFrame::new(self.avm, Some(self.activation), activation);
child.run(context)
}
pub fn run(
@ -2060,7 +2078,7 @@ impl<'a, 'gc: 'a> StackFrame<'a, 'gc> {
context.gc_context,
self.activation.read().to_rescope(block, with_scope),
);
let _ = self.avm.run_activation(context, new_activation)?;
let _ = self.run_child_activation(new_activation, context)?;
Ok(FrameControl::Continue)
}