avm1: Use proper bool conversions for logical ops
ActionAnd, ActionOr, and ActionNot were incorrectly comparing to 0. This only works for SWF<4. Now they all go through the Value::as_bool method to handle version specific behavior. Value::from_bool_v1 was also renamed to Value::from_bool.
This commit is contained in:
parent
00fdc74f1f
commit
a4a307cf9a
|
@ -763,8 +763,9 @@ impl<'gc> Avm1<'gc> {
|
||||||
// AS1 logical and
|
// AS1 logical and
|
||||||
let a = self.pop()?;
|
let a = self.pop()?;
|
||||||
let b = self.pop()?;
|
let b = self.pop()?;
|
||||||
let result = b.into_number_v1() != 0.0 && a.into_number_v1() != 0.0;
|
let version = self.current_swf_version();
|
||||||
self.push(Value::from_bool_v1(result, self.current_swf_version()));
|
let result = b.as_bool(version) && a.as_bool(version);
|
||||||
|
self.push(Value::from_bool(result, self.current_swf_version()));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1208,7 +1209,7 @@ impl<'gc> Avm1<'gc> {
|
||||||
let a = self.pop()?;
|
let a = self.pop()?;
|
||||||
let b = self.pop()?;
|
let b = self.pop()?;
|
||||||
let result = b.into_number_v1() == a.into_number_v1();
|
let result = b.into_number_v1() == a.into_number_v1();
|
||||||
self.push(Value::from_bool_v1(result, self.current_swf_version()));
|
self.push(Value::from_bool(result, self.current_swf_version()));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1275,7 +1276,7 @@ impl<'gc> Avm1<'gc> {
|
||||||
Value::Undefined
|
Value::Undefined
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log::warn!("GetProperty: Invalid target {}", path);
|
//log::warn!("GetProperty: Invalid target {}", path);
|
||||||
Value::Undefined
|
Value::Undefined
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1593,7 +1594,7 @@ impl<'gc> Avm1<'gc> {
|
||||||
let a = self.pop()?;
|
let a = self.pop()?;
|
||||||
let b = self.pop()?;
|
let b = self.pop()?;
|
||||||
let result = b.into_number_v1() < a.into_number_v1();
|
let result = b.into_number_v1() < a.into_number_v1();
|
||||||
self.push(Value::from_bool_v1(result, self.current_swf_version()));
|
self.push(Value::from_bool(result, self.current_swf_version()));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1669,10 +1670,9 @@ impl<'gc> Avm1<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn action_not(&mut self, _context: &mut UpdateContext<'_, 'gc, '_>) -> Result<(), Error> {
|
fn action_not(&mut self, _context: &mut UpdateContext<'_, 'gc, '_>) -> Result<(), Error> {
|
||||||
// AS1 logical not
|
let version = self.current_swf_version();
|
||||||
let val = self.pop()?;
|
let val = !self.pop()?.as_bool(version);
|
||||||
let result = val.into_number_v1() == 0.0;
|
self.push(Value::from_bool(val, version));
|
||||||
self.push(Value::from_bool_v1(result, self.current_swf_version()));
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1769,8 +1769,9 @@ impl<'gc> Avm1<'gc> {
|
||||||
// AS1 logical or
|
// AS1 logical or
|
||||||
let a = self.pop()?;
|
let a = self.pop()?;
|
||||||
let b = self.pop()?;
|
let b = self.pop()?;
|
||||||
let result = b.into_number_v1() != 0.0 || a.into_number_v1() != 0.0;
|
let version = self.current_swf_version();
|
||||||
self.push(Value::from_bool_v1(result, self.current_swf_version()));
|
let result = b.as_bool(version) || a.as_bool(version);
|
||||||
|
self.push(Value::from_bool(result, version));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2163,7 +2164,7 @@ impl<'gc> Avm1<'gc> {
|
||||||
let a = self.pop()?;
|
let a = self.pop()?;
|
||||||
let b = self.pop()?;
|
let b = self.pop()?;
|
||||||
let result = b.coerce_to_string(self, context)? == a.coerce_to_string(self, context)?;
|
let result = b.coerce_to_string(self, context)? == a.coerce_to_string(self, context)?;
|
||||||
self.push(Value::from_bool_v1(result, self.current_swf_version()));
|
self.push(Value::from_bool(result, self.current_swf_version()));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2197,7 +2198,7 @@ impl<'gc> Avm1<'gc> {
|
||||||
.coerce_to_string(self, context)?
|
.coerce_to_string(self, context)?
|
||||||
.bytes()
|
.bytes()
|
||||||
.gt(a.coerce_to_string(self, context)?.bytes());
|
.gt(a.coerce_to_string(self, context)?.bytes());
|
||||||
self.push(Value::from_bool_v1(result, self.current_swf_version()));
|
self.push(Value::from_bool(result, self.current_swf_version()));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2222,7 +2223,7 @@ impl<'gc> Avm1<'gc> {
|
||||||
.coerce_to_string(self, context)?
|
.coerce_to_string(self, context)?
|
||||||
.bytes()
|
.bytes()
|
||||||
.lt(a.coerce_to_string(self, context)?.bytes());
|
.lt(a.coerce_to_string(self, context)?.bytes());
|
||||||
self.push(Value::from_bool_v1(result, self.current_swf_version()));
|
self.push(Value::from_bool(result, self.current_swf_version()));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -368,7 +368,10 @@ impl<'gc> Value<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_bool_v1(value: bool, swf_version: u8) -> Value<'gc> {
|
/// Converts a bool value into the appropriate value for the platform.
|
||||||
|
/// This should be used when pushing a bool onto the stack.
|
||||||
|
/// This handles SWFv4 pushing a Number, 0 or 1.
|
||||||
|
pub fn from_bool(value: bool, swf_version: u8) -> Value<'gc> {
|
||||||
// SWF version 4 did not have true bools and will push bools as 0 or 1.
|
// SWF version 4 did not have true bools and will push bools as 0 or 1.
|
||||||
// e.g. SWF19 p. 72:
|
// e.g. SWF19 p. 72:
|
||||||
// "If the numbers are equal, true is pushed to the stack for SWF 5 and later. For SWF 4, 1 is pushed to the stack."
|
// "If the numbers are equal, true is pushed to the stack for SWF 5 and later. For SWF 4, 1 is pushed to the stack."
|
||||||
|
|
Loading…
Reference in New Issue