swf: Add `avm1::Action::End`
Returning an `Action::End` instead of `None` when reading the end of an action.
This commit is contained in:
parent
d5862809c7
commit
2b2346b65e
|
@ -458,7 +458,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
if reader.get_ref().as_ptr() as usize >= data.as_ref().as_ptr_range().end as usize {
|
||||
//Executing beyond the end of a function constitutes an implicit return.
|
||||
Ok(FrameControl::Return(ReturnType::Implicit))
|
||||
} else if let Some(action) = reader.read_action()? {
|
||||
} else {
|
||||
let action = reader.read_action()?;
|
||||
avm_debug!(
|
||||
self.context.avm1,
|
||||
"({}) Action: {:?}",
|
||||
|
@ -492,6 +493,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
Action::Delete => self.action_delete(),
|
||||
Action::Delete2 => self.action_delete_2(),
|
||||
Action::Divide => self.action_divide(),
|
||||
Action::End => self.action_end(),
|
||||
Action::EndDrag => self.action_end_drag(),
|
||||
Action::Enumerate => self.action_enumerate(),
|
||||
Action::Enumerate2 => self.action_enumerate_2(),
|
||||
|
@ -568,9 +570,6 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
Action::With(action) => self.action_with(action, data),
|
||||
_ => self.unknown_op(action),
|
||||
}
|
||||
} else {
|
||||
//The explicit end opcode was encountered so return here
|
||||
Ok(FrameControl::Return(ReturnType::Implicit))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1015,6 +1014,10 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
Ok(FrameControl::Continue)
|
||||
}
|
||||
|
||||
fn action_end(&mut self) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||
Ok(FrameControl::Return(ReturnType::Implicit))
|
||||
}
|
||||
|
||||
fn action_end_drag(&mut self) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||
*self.context.drag_object = None;
|
||||
Ok(FrameControl::Continue)
|
||||
|
|
|
@ -49,7 +49,7 @@ impl<'a> Reader<'a> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_action(&mut self) -> Result<Option<Action<'a>>> {
|
||||
pub fn read_action(&mut self) -> Result<Action<'a>> {
|
||||
let (opcode, mut length) = self.read_opcode_and_length()?;
|
||||
let start = self.input;
|
||||
|
||||
|
@ -87,11 +87,9 @@ impl<'a> Reader<'a> {
|
|||
/// The `length` passed in should be the length excluding any sub-blocks.
|
||||
/// The final `length` returned will be total length of the action, including sub-blocks.
|
||||
#[inline]
|
||||
fn read_op(&mut self, opcode: u8, length: &mut usize) -> Result<Option<Action<'a>>> {
|
||||
fn read_op(&mut self, opcode: u8, length: &mut usize) -> Result<Action<'a>> {
|
||||
let action = if let Some(op) = OpCode::from_u8(opcode) {
|
||||
match op {
|
||||
OpCode::End => return Ok(None),
|
||||
|
||||
OpCode::Add => Action::Add,
|
||||
OpCode::Add2 => Action::Add2,
|
||||
OpCode::And => Action::And,
|
||||
|
@ -124,6 +122,7 @@ impl<'a> Reader<'a> {
|
|||
OpCode::EndDrag => Action::EndDrag,
|
||||
OpCode::Enumerate => Action::Enumerate,
|
||||
OpCode::Enumerate2 => Action::Enumerate2,
|
||||
OpCode::End => Action::End,
|
||||
OpCode::Equals => Action::Equals,
|
||||
OpCode::Equals2 => Action::Equals2,
|
||||
OpCode::Extends => Action::Extends,
|
||||
|
@ -200,7 +199,7 @@ impl<'a> Reader<'a> {
|
|||
Action::Unknown(self.read_unknown_action(opcode, *length)?)
|
||||
};
|
||||
|
||||
Ok(Some(action))
|
||||
Ok(action)
|
||||
}
|
||||
|
||||
fn read_constant_pool(&mut self) -> Result<ConstantPool<'a>> {
|
||||
|
@ -420,7 +419,7 @@ pub mod tests {
|
|||
fn read_action() {
|
||||
for (swf_version, expected_action, action_bytes) in test_data::avm1_tests() {
|
||||
let mut reader = Reader::new(&action_bytes[..], swf_version);
|
||||
let parsed_action = reader.read_action().unwrap().unwrap();
|
||||
let parsed_action = reader.read_action().unwrap();
|
||||
assert_eq!(
|
||||
parsed_action, expected_action,
|
||||
"Incorrectly parsed action.\nRead:\n{:?}\n\nExpected:\n{:?}",
|
||||
|
@ -450,7 +449,7 @@ pub mod tests {
|
|||
0x00, 0x74, 0x65, 0x73, 0x74, 0x00, 0x26, 0x00,
|
||||
];
|
||||
let mut reader = Reader::new(&action_bytes[..], 5);
|
||||
let action = reader.read_action().unwrap().unwrap();
|
||||
let action = reader.read_action().unwrap();
|
||||
assert_eq!(
|
||||
action,
|
||||
Action::DefineFunction(DefineFunction {
|
||||
|
@ -462,7 +461,7 @@ pub mod tests {
|
|||
|
||||
if let Action::DefineFunction(DefineFunction { actions, .. }) = action {
|
||||
let mut reader = Reader::new(actions, 5);
|
||||
let action = reader.read_action().unwrap().unwrap();
|
||||
let action = reader.read_action().unwrap();
|
||||
assert_eq!(
|
||||
action,
|
||||
Action::Push(Push {
|
||||
|
@ -480,7 +479,7 @@ pub mod tests {
|
|||
// until the end of the action. Ensure we don't read extra values.
|
||||
let action_bytes = [0x96, 2, 0, 2, 3, 3]; // Extra 3 at the end shouldn't be read.
|
||||
let mut reader = Reader::new(&action_bytes[..], 5);
|
||||
let action = reader.read_action().unwrap().unwrap();
|
||||
let action = reader.read_action().unwrap();
|
||||
assert_eq!(
|
||||
action,
|
||||
Action::Push(Push {
|
||||
|
@ -504,7 +503,7 @@ pub mod tests {
|
|||
];
|
||||
let mut reader = Reader::new(&action_bytes[..], 5);
|
||||
|
||||
let action = reader.read_action().unwrap().unwrap();
|
||||
let action = reader.read_action().unwrap();
|
||||
assert_eq!(
|
||||
action,
|
||||
Action::ConstantPool(ConstantPool {
|
||||
|
@ -512,7 +511,7 @@ pub mod tests {
|
|||
})
|
||||
);
|
||||
|
||||
let action = reader.read_action().unwrap().unwrap();
|
||||
let action = reader.read_action().unwrap();
|
||||
assert_eq!(action, Action::Subtract);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ pub enum Action<'a> {
|
|||
Delete,
|
||||
Delete2,
|
||||
Divide,
|
||||
End,
|
||||
EndDrag,
|
||||
Enumerate,
|
||||
Enumerate2,
|
||||
|
|
|
@ -103,6 +103,7 @@ impl<W: Write> Writer<W> {
|
|||
Action::Divide => self.write_small_action(OpCode::Divide),
|
||||
Action::Delete => self.write_small_action(OpCode::Delete),
|
||||
Action::Delete2 => self.write_small_action(OpCode::Delete2),
|
||||
Action::End => self.write_small_action(OpCode::End),
|
||||
Action::EndDrag => self.write_small_action(OpCode::EndDrag),
|
||||
Action::Enumerate => self.write_small_action(OpCode::Enumerate),
|
||||
Action::Enumerate2 => self.write_small_action(OpCode::Enumerate2),
|
||||
|
|
Loading…
Reference in New Issue