avm1: Merge #83, add better support for comparison ops
Enhanced comparison support
This commit is contained in:
commit
8063d9e55c
|
@ -319,6 +319,7 @@ impl<'gc> Avm1<'gc> {
|
|||
set_playing,
|
||||
scene_offset,
|
||||
} => self.action_goto_frame_2(context, set_playing, scene_offset),
|
||||
Action::Greater => self.action_greater(context),
|
||||
Action::GotoLabel(label) => self.action_goto_label(context, &label),
|
||||
Action::If { offset } => self.action_if(context, offset, reader),
|
||||
Action::Increment => self.action_increment(context),
|
||||
|
@ -356,9 +357,11 @@ impl<'gc> Avm1<'gc> {
|
|||
Action::Stop => self.action_stop(context),
|
||||
Action::StopSounds => self.action_stop_sounds(context),
|
||||
Action::StoreRegister(register) => self.action_store_register(context, register),
|
||||
Action::StrictEquals => self.action_strict_equals(context),
|
||||
Action::StringAdd => self.action_string_add(context),
|
||||
Action::StringEquals => self.action_string_equals(context),
|
||||
Action::StringExtract => self.action_string_extract(context),
|
||||
Action::StringGreater => self.action_string_greater(context),
|
||||
Action::StringLength => self.action_string_length(context),
|
||||
Action::StringLess => self.action_string_less(context),
|
||||
Action::Subtract => self.action_subtract(context),
|
||||
|
@ -910,7 +913,9 @@ impl<'gc> Avm1<'gc> {
|
|||
(Value::Null, Value::Null) => true,
|
||||
(Value::Null, Value::Undefined) => true,
|
||||
(Value::Undefined, Value::Null) => true,
|
||||
(Value::Number(a), Value::Number(b)) => a == b,
|
||||
// The result of NaN equality appears to change depending on flash player version (not swf version).
|
||||
// This comparison might need to be conditional on targeted version.
|
||||
(Value::Number(a), Value::Number(b)) => a == b || (a.is_nan() && b.is_nan()),
|
||||
(Value::String(a), Value::String(b)) => a == b,
|
||||
(Value::Object(_a), Value::Object(_b)) => false, // TODO(Herschel)
|
||||
(Value::String(a), Value::Number(b)) => a.parse().unwrap_or(std::f64::NAN) == b,
|
||||
|
@ -1246,6 +1251,18 @@ impl<'gc> Avm1<'gc> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn action_greater(&mut self, _context: &mut ActionContext) -> Result<(), Error> {
|
||||
// AS1 less than
|
||||
let a = self.pop()?;
|
||||
let b = self.pop()?;
|
||||
let result = b.into_number_v1() > a.into_number_v1();
|
||||
self.push(Value::from_bool_v1(
|
||||
result,
|
||||
self.current_swf_version().unwrap(),
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn action_mb_ascii_to_char(&mut self, _context: &mut ActionContext) -> Result<(), Error> {
|
||||
// TODO(Herschel): Results on incorrect operands?
|
||||
use std::convert::TryFrom;
|
||||
|
@ -1503,6 +1520,16 @@ impl<'gc> Avm1<'gc> {
|
|||
self.set_variable(context, var_path.as_string()?, value)
|
||||
}
|
||||
|
||||
#[allow(clippy::float_cmp)]
|
||||
fn action_strict_equals(&mut self, _context: &mut ActionContext) -> Result<(), Error> {
|
||||
// The same as normal equality but types must match
|
||||
let a = self.pop()?;
|
||||
let b = self.pop()?;
|
||||
let result = a == b;
|
||||
self.push(Value::Bool(result));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_variable(
|
||||
&mut self,
|
||||
context: &mut ActionContext<'_, 'gc, '_>,
|
||||
|
@ -1689,6 +1716,19 @@ impl<'gc> Avm1<'gc> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn action_string_greater(&mut self, _context: &mut ActionContext) -> Result<(), Error> {
|
||||
// AS1 strcmp
|
||||
let a = self.pop()?;
|
||||
let b = self.pop()?;
|
||||
// This is specifically a non-UTF8 aware comparison.
|
||||
let result = b.into_string().bytes().gt(a.into_string().bytes());
|
||||
self.push(Value::from_bool_v1(
|
||||
result,
|
||||
self.current_swf_version().unwrap(),
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn action_string_length(&mut self, _context: &mut ActionContext) -> Result<(), Error> {
|
||||
// AS1 strlen
|
||||
// Only returns byte length.
|
||||
|
|
|
@ -41,6 +41,9 @@ swf_tests! {
|
|||
(goto_rewind1, "avm1/goto_rewind1", 10),
|
||||
(goto_rewind2, "avm1/goto_rewind2", 10),
|
||||
(goto_rewind3, "avm1/goto_rewind3", 10),
|
||||
(greaterthan_swf5, "avm1/greaterthan_swf5", 1),
|
||||
(greaterthan_swf8, "avm1/greaterthan_swf8", 1),
|
||||
(strictly_equals, "avm1/strictly_equals", 1),
|
||||
(tell_target, "avm1/tell_target", 3),
|
||||
(typeofs, "avm1/typeof", 1),
|
||||
(typeof_globals, "avm1/typeof_globals", 1),
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
fail
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
success
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,7 @@
|
|||
2 === 2
|
||||
true === true
|
||||
false === false
|
||||
"abc" === "abc"
|
||||
undefined === undefined
|
||||
NaN === NaN
|
||||
null === null
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue