avm2: Split out enumerant values into a separate method as well.
This commit is contained in:
parent
297526269c
commit
4289f89350
|
@ -2502,13 +2502,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
let cur_index = self.context.avm2.pop().coerce_to_number(self)?;
|
||||
let object = self.context.avm2.pop().coerce_to_object(self)?;
|
||||
|
||||
let name = object.get_enumerant_name(cur_index as u32);
|
||||
let value = if let Some(name) = name {
|
||||
let name = name.coerce_to_string(self)?;
|
||||
object.get_property(object, &QName::dynamic_name(name).into(), self)?
|
||||
} else {
|
||||
Value::Undefined
|
||||
};
|
||||
let value = object.get_enumerant_value(cur_index as u32, self)?;
|
||||
|
||||
self.context.avm2.push(value);
|
||||
|
||||
|
|
|
@ -794,7 +794,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
/// Repeated calls to this function with prior return values must
|
||||
/// eventually return `None`. Furthermore, returning `0`, while valid, is
|
||||
/// treated by AVM2 code as signalling `None`.
|
||||
fn get_next_enumerant(&self, last_index: u32) -> Option<u32> {
|
||||
fn get_next_enumerant(self, last_index: u32) -> Option<u32> {
|
||||
let base = self.base();
|
||||
|
||||
base.get_next_enumerant(last_index)
|
||||
|
@ -802,19 +802,34 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
|
||||
/// Retrieve a given enumerable name by index.
|
||||
///
|
||||
/// Enumerants are listed by index, starting from zero. A value of `None`
|
||||
/// indicates that no enumerant with that index, or any greater index,
|
||||
/// exists. (In other words, it means stop.)
|
||||
///
|
||||
/// Objects are responsible for maintaining a consistently ordered and
|
||||
/// indexed list of enumerable names which can be queried by this
|
||||
/// mechanism.
|
||||
fn get_enumerant_name(&self, index: u32) -> Option<Value<'gc>> {
|
||||
/// Enumerants are listed by index, starting from zero and iterated via
|
||||
/// `get_next_enumerant`. Only enumerants returned by that function are
|
||||
/// valid here. A value of `None` indicates that no enumerant with that
|
||||
/// index exists.
|
||||
fn get_enumerant_name(self, index: u32) -> Option<Value<'gc>> {
|
||||
let base = self.base();
|
||||
|
||||
base.get_enumerant_name(index)
|
||||
}
|
||||
|
||||
/// Retrieve a given enumerable value by index.
|
||||
///
|
||||
/// This default implementation of value retrieval assumes that the names
|
||||
/// of enumerants are also valid local names in the public namespace.
|
||||
fn get_enumerant_value(
|
||||
self,
|
||||
index: u32,
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
let name = self.get_enumerant_name(index);
|
||||
if let Some(name) = name {
|
||||
let name = name.coerce_to_string(activation)?;
|
||||
Ok(self.get_property(self.into(), &QName::dynamic_name(name).into(), activation)?)
|
||||
} else {
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
}
|
||||
|
||||
/// Determine if a property is currently enumerable.
|
||||
///
|
||||
/// Properties that do not exist are also not enumerable.
|
||||
|
|
|
@ -199,7 +199,7 @@ impl<'gc> TObject<'gc> for ArrayObject<'gc> {
|
|||
self.0.read().base.resolve_any(local_name)
|
||||
}
|
||||
|
||||
fn get_next_enumerant(&self, last_index: u32) -> Option<u32> {
|
||||
fn get_next_enumerant(self, last_index: u32) -> Option<u32> {
|
||||
let read = self.0.read();
|
||||
let last_enumerant = read.base.get_last_enumerant();
|
||||
let array_length = read.array.length() as u32;
|
||||
|
@ -211,7 +211,7 @@ impl<'gc> TObject<'gc> for ArrayObject<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_enumerant_name(&self, index: u32) -> Option<Value<'gc>> {
|
||||
fn get_enumerant_name(self, index: u32) -> Option<Value<'gc>> {
|
||||
let arr_len = self.0.read().array.length() as u32;
|
||||
if arr_len >= index {
|
||||
index.checked_sub(1).map(|index| index.into())
|
||||
|
|
|
@ -111,7 +111,7 @@ impl<'gc> TObject<'gc> for DictionaryObject<'gc> {
|
|||
Some(self)
|
||||
}
|
||||
|
||||
fn get_next_enumerant(&self, last_index: u32) -> Option<u32> {
|
||||
fn get_next_enumerant(self, last_index: u32) -> Option<u32> {
|
||||
let read = self.0.read();
|
||||
let last_enumerant = read.base.get_last_enumerant();
|
||||
let object_space_length = read.object_space.keys().len() as u32;
|
||||
|
@ -123,7 +123,7 @@ impl<'gc> TObject<'gc> for DictionaryObject<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_enumerant_name(&self, index: u32) -> Option<Value<'gc>> {
|
||||
fn get_enumerant_name(self, index: u32) -> Option<Value<'gc>> {
|
||||
let read = self.0.read();
|
||||
let last_enumerant = read.base.get_last_enumerant();
|
||||
|
||||
|
|
|
@ -227,7 +227,7 @@ impl<'gc> TObject<'gc> for VectorObject<'gc> {
|
|||
self.0.read().base.resolve_any(local_name)
|
||||
}
|
||||
|
||||
fn get_next_enumerant(&self, last_index: u32) -> Option<u32> {
|
||||
fn get_next_enumerant(self, last_index: u32) -> Option<u32> {
|
||||
if last_index < self.0.read().vector.length() as u32 {
|
||||
Some(last_index.saturating_add(1))
|
||||
} else {
|
||||
|
@ -235,7 +235,7 @@ impl<'gc> TObject<'gc> for VectorObject<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_enumerant_name(&self, index: u32) -> Option<Value<'gc>> {
|
||||
fn get_enumerant_name(self, index: u32) -> Option<Value<'gc>> {
|
||||
if self.0.read().vector.length() as u32 >= index {
|
||||
index.checked_sub(1).map(|index| index.into())
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue