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 {
|
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.
|
//Executing beyond the end of a function constitutes an implicit return.
|
||||||
Ok(FrameControl::Return(ReturnType::Implicit))
|
Ok(FrameControl::Return(ReturnType::Implicit))
|
||||||
} else if let Some(action) = reader.read_action()? {
|
} else {
|
||||||
|
let action = reader.read_action()?;
|
||||||
avm_debug!(
|
avm_debug!(
|
||||||
self.context.avm1,
|
self.context.avm1,
|
||||||
"({}) Action: {:?}",
|
"({}) Action: {:?}",
|
||||||
|
@ -492,6 +493,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
||||||
Action::Delete => self.action_delete(),
|
Action::Delete => self.action_delete(),
|
||||||
Action::Delete2 => self.action_delete_2(),
|
Action::Delete2 => self.action_delete_2(),
|
||||||
Action::Divide => self.action_divide(),
|
Action::Divide => self.action_divide(),
|
||||||
|
Action::End => self.action_end(),
|
||||||
Action::EndDrag => self.action_end_drag(),
|
Action::EndDrag => self.action_end_drag(),
|
||||||
Action::Enumerate => self.action_enumerate(),
|
Action::Enumerate => self.action_enumerate(),
|
||||||
Action::Enumerate2 => self.action_enumerate_2(),
|
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),
|
Action::With(action) => self.action_with(action, data),
|
||||||
_ => self.unknown_op(action),
|
_ => 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)
|
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>> {
|
fn action_end_drag(&mut self) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||||
*self.context.drag_object = None;
|
*self.context.drag_object = None;
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
|
|
|
@ -49,7 +49,7 @@ impl<'a> Reader<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[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 (opcode, mut length) = self.read_opcode_and_length()?;
|
||||||
let start = self.input;
|
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 `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.
|
/// The final `length` returned will be total length of the action, including sub-blocks.
|
||||||
#[inline]
|
#[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) {
|
let action = if let Some(op) = OpCode::from_u8(opcode) {
|
||||||
match op {
|
match op {
|
||||||
OpCode::End => return Ok(None),
|
|
||||||
|
|
||||||
OpCode::Add => Action::Add,
|
OpCode::Add => Action::Add,
|
||||||
OpCode::Add2 => Action::Add2,
|
OpCode::Add2 => Action::Add2,
|
||||||
OpCode::And => Action::And,
|
OpCode::And => Action::And,
|
||||||
|
@ -124,6 +122,7 @@ impl<'a> Reader<'a> {
|
||||||
OpCode::EndDrag => Action::EndDrag,
|
OpCode::EndDrag => Action::EndDrag,
|
||||||
OpCode::Enumerate => Action::Enumerate,
|
OpCode::Enumerate => Action::Enumerate,
|
||||||
OpCode::Enumerate2 => Action::Enumerate2,
|
OpCode::Enumerate2 => Action::Enumerate2,
|
||||||
|
OpCode::End => Action::End,
|
||||||
OpCode::Equals => Action::Equals,
|
OpCode::Equals => Action::Equals,
|
||||||
OpCode::Equals2 => Action::Equals2,
|
OpCode::Equals2 => Action::Equals2,
|
||||||
OpCode::Extends => Action::Extends,
|
OpCode::Extends => Action::Extends,
|
||||||
|
@ -200,7 +199,7 @@ impl<'a> Reader<'a> {
|
||||||
Action::Unknown(self.read_unknown_action(opcode, *length)?)
|
Action::Unknown(self.read_unknown_action(opcode, *length)?)
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Some(action))
|
Ok(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_constant_pool(&mut self) -> Result<ConstantPool<'a>> {
|
fn read_constant_pool(&mut self) -> Result<ConstantPool<'a>> {
|
||||||
|
@ -420,7 +419,7 @@ pub mod tests {
|
||||||
fn read_action() {
|
fn read_action() {
|
||||||
for (swf_version, expected_action, action_bytes) in test_data::avm1_tests() {
|
for (swf_version, expected_action, action_bytes) in test_data::avm1_tests() {
|
||||||
let mut reader = Reader::new(&action_bytes[..], swf_version);
|
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!(
|
assert_eq!(
|
||||||
parsed_action, expected_action,
|
parsed_action, expected_action,
|
||||||
"Incorrectly parsed action.\nRead:\n{:?}\n\nExpected:\n{:?}",
|
"Incorrectly parsed action.\nRead:\n{:?}\n\nExpected:\n{:?}",
|
||||||
|
@ -450,7 +449,7 @@ pub mod tests {
|
||||||
0x00, 0x74, 0x65, 0x73, 0x74, 0x00, 0x26, 0x00,
|
0x00, 0x74, 0x65, 0x73, 0x74, 0x00, 0x26, 0x00,
|
||||||
];
|
];
|
||||||
let mut reader = Reader::new(&action_bytes[..], 5);
|
let mut reader = Reader::new(&action_bytes[..], 5);
|
||||||
let action = reader.read_action().unwrap().unwrap();
|
let action = reader.read_action().unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
action,
|
action,
|
||||||
Action::DefineFunction(DefineFunction {
|
Action::DefineFunction(DefineFunction {
|
||||||
|
@ -462,7 +461,7 @@ pub mod tests {
|
||||||
|
|
||||||
if let Action::DefineFunction(DefineFunction { actions, .. }) = action {
|
if let Action::DefineFunction(DefineFunction { actions, .. }) = action {
|
||||||
let mut reader = Reader::new(actions, 5);
|
let mut reader = Reader::new(actions, 5);
|
||||||
let action = reader.read_action().unwrap().unwrap();
|
let action = reader.read_action().unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
action,
|
action,
|
||||||
Action::Push(Push {
|
Action::Push(Push {
|
||||||
|
@ -480,7 +479,7 @@ pub mod tests {
|
||||||
// until the end of the action. Ensure we don't read extra values.
|
// 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 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 mut reader = Reader::new(&action_bytes[..], 5);
|
||||||
let action = reader.read_action().unwrap().unwrap();
|
let action = reader.read_action().unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
action,
|
action,
|
||||||
Action::Push(Push {
|
Action::Push(Push {
|
||||||
|
@ -504,7 +503,7 @@ pub mod tests {
|
||||||
];
|
];
|
||||||
let mut reader = Reader::new(&action_bytes[..], 5);
|
let mut reader = Reader::new(&action_bytes[..], 5);
|
||||||
|
|
||||||
let action = reader.read_action().unwrap().unwrap();
|
let action = reader.read_action().unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
action,
|
action,
|
||||||
Action::ConstantPool(ConstantPool {
|
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);
|
assert_eq!(action, Action::Subtract);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ pub enum Action<'a> {
|
||||||
Delete,
|
Delete,
|
||||||
Delete2,
|
Delete2,
|
||||||
Divide,
|
Divide,
|
||||||
|
End,
|
||||||
EndDrag,
|
EndDrag,
|
||||||
Enumerate,
|
Enumerate,
|
||||||
Enumerate2,
|
Enumerate2,
|
||||||
|
|
|
@ -103,6 +103,7 @@ impl<W: Write> Writer<W> {
|
||||||
Action::Divide => self.write_small_action(OpCode::Divide),
|
Action::Divide => self.write_small_action(OpCode::Divide),
|
||||||
Action::Delete => self.write_small_action(OpCode::Delete),
|
Action::Delete => self.write_small_action(OpCode::Delete),
|
||||||
Action::Delete2 => self.write_small_action(OpCode::Delete2),
|
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::EndDrag => self.write_small_action(OpCode::EndDrag),
|
||||||
Action::Enumerate => self.write_small_action(OpCode::Enumerate),
|
Action::Enumerate => self.write_small_action(OpCode::Enumerate),
|
||||||
Action::Enumerate2 => self.write_small_action(OpCode::Enumerate2),
|
Action::Enumerate2 => self.write_small_action(OpCode::Enumerate2),
|
||||||
|
|
Loading…
Reference in New Issue