avm1: Merge #83, add better support for comparison ops

Enhanced comparison support
This commit is contained in:
Mike Welsh 2019-10-09 10:15:47 -07:00 committed by GitHub
commit 8063d9e55c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 53 additions and 1 deletions

View File

@ -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.

View File

@ -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),

View File

@ -0,0 +1 @@
fail

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
success

Binary file not shown.

Binary file not shown.

View File

@ -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.