diff --git a/core/src/avm2/activation.rs b/core/src/avm2/activation.rs index 4134b54f9..80a003679 100644 --- a/core/src/avm2/activation.rs +++ b/core/src/avm2/activation.rs @@ -480,6 +480,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { Op::IfStrictEq { offset } => self.op_if_strict_eq(offset, reader), Op::IfStrictNe { offset } => self.op_if_strict_ne(offset, reader), Op::StrictEquals => self.op_strict_equals(), + Op::Not => self.op_not(), Op::HasNext => self.op_has_next(), Op::HasNext2 { object_register, @@ -1383,6 +1384,14 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { Ok(FrameControl::Continue) } + fn op_not(&mut self) -> Result, Error> { + let value = self.avm2.pop().coerce_to_boolean(); + + self.avm2.push(!value); + + Ok(FrameControl::Continue) + } + fn op_has_next(&mut self) -> Result, Error> { //TODO: After adding ints, change this to ints. let cur_index = self.context.avm2.pop().as_number()?; diff --git a/core/tests/regression_tests.rs b/core/tests/regression_tests.rs index 9966572c4..b60025d0e 100644 --- a/core/tests/regression_tests.rs +++ b/core/tests/regression_tests.rs @@ -275,6 +275,7 @@ swf_tests! { (as3_instanceof, "avm2/instanceof", 1), (as3_truthiness, "avm2/truthiness", 1), (as3_falsiness, "avm2/falsiness", 1), + (as3_boolean_negation, "avm2/boolean_negation", 1), } // TODO: These tests have some inaccuracies currently, so we use approx_eq to test that numeric values are close enough. diff --git a/core/tests/swfs/avm2/boolean_negation/Test.as b/core/tests/swfs/avm2/boolean_negation/Test.as new file mode 100644 index 000000000..898da3b89 --- /dev/null +++ b/core/tests/swfs/avm2/boolean_negation/Test.as @@ -0,0 +1,61 @@ +package { + public class Test { + } +} + +function assert_bool_not(val) { + var notval = !val; + + if (notval === true) { + trace("Inverse is true"); + } else if (notval === false) { + trace("Inverse is false"); + } else { + trace("TEST FAIL: Inverse is nonboolean"); + } +} + +trace("//!true"); +assert_bool_not(true); + +trace("//!false"); +assert_bool_not(false); + +trace("//!null"); +assert_bool_not(null); + +trace("//!undefined"); +assert_bool_not(undefined); + +trace("//!\"\""); +assert_bool_not(""); + +trace("//!\"str\""); +assert_bool_not("str"); + +trace("//!\"true\""); +assert_bool_not("true"); + +trace("//!\"false\""); +assert_bool_not("false"); + +trace("//!0.0"); +assert_bool_not(0.0); + +trace("//!NaN"); +assert_bool_not(NaN); + +trace("//!-0.0"); +assert_bool_not(-0.0); + +trace("//!Infinity"); +assert_bool_not(Infinity); + +trace("//!1.0"); +assert_bool_not(1.0); + +trace("//!-1.0"); +assert_bool_not(-1.0); + +trace("//!new Object()"); +assert_bool_not({}); \ No newline at end of file diff --git a/core/tests/swfs/avm2/boolean_negation/output.txt b/core/tests/swfs/avm2/boolean_negation/output.txt new file mode 100644 index 000000000..b84b7acc2 --- /dev/null +++ b/core/tests/swfs/avm2/boolean_negation/output.txt @@ -0,0 +1,30 @@ +//!true +Inverse is false +//!false +Inverse is true +//!null +Inverse is true +//!undefined +Inverse is true +//!"" +Inverse is true +//!"str" +Inverse is false +//!"true" +Inverse is false +//!"false" +Inverse is false +//!0.0 +Inverse is true +//!NaN +Inverse is true +//!-0.0 +Inverse is true +//!Infinity +Inverse is false +//!1.0 +Inverse is false +//!-1.0 +Inverse is false +//!new Object() +Inverse is false diff --git a/core/tests/swfs/avm2/boolean_negation/test.fla b/core/tests/swfs/avm2/boolean_negation/test.fla new file mode 100644 index 000000000..c41c9f293 Binary files /dev/null and b/core/tests/swfs/avm2/boolean_negation/test.fla differ diff --git a/core/tests/swfs/avm2/boolean_negation/test.swf b/core/tests/swfs/avm2/boolean_negation/test.swf new file mode 100644 index 000000000..650e155bb Binary files /dev/null and b/core/tests/swfs/avm2/boolean_negation/test.swf differ