Remove uses of `as_string` in various places.

These include:

 * Name resolution in `newobject`
 * All runtime & late-bound multinames
 * `Object.hasOwnProperty`
 * `Object.propertyIsEnumerable`
 * `Object.setPropertyIsEnumerable`
This commit is contained in:
David Wendt 2020-07-28 21:31:58 -04:00 committed by Mike Welsh
parent c040997be2
commit 4906c5a3f1
4 changed files with 46 additions and 47 deletions

View File

@ -343,9 +343,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
&mut self,
method: Gc<'gc, BytecodeMethod<'gc>>,
index: Index<AbcMultiname>,
mc: MutationContext<'gc, '_>,
) -> Result<Multiname<'gc>, Error> {
Multiname::from_abc_multiname(method.translation_unit(), index, self.context.avm2, mc)
Multiname::from_abc_multiname(method.translation_unit(), index, self)
}
/// Retrieve a static, or non-runtime, multiname from the current constant
@ -706,7 +705,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
arg_count: u32,
) -> Result<FrameControl<'gc>, Error> {
let args = self.context.avm2.pop_args(arg_count);
let multiname = self.pool_multiname(method, index, self.context.gc_context)?;
let multiname = self.pool_multiname(method, index)?;
let mut receiver = self.context.avm2.pop().coerce_to_object(self)?;
let name: Result<QName, Error> = receiver
.resolve_multiname(&multiname)?
@ -730,7 +729,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
arg_count: u32,
) -> Result<FrameControl<'gc>, Error> {
let args = self.context.avm2.pop_args(arg_count);
let multiname = self.pool_multiname(method, index, self.context.gc_context)?;
let multiname = self.pool_multiname(method, index)?;
let mut receiver = self.context.avm2.pop().coerce_to_object(self)?;
let name: Result<QName, Error> = receiver
.resolve_multiname(&multiname)?
@ -752,7 +751,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
arg_count: u32,
) -> Result<FrameControl<'gc>, Error> {
let args = self.context.avm2.pop_args(arg_count);
let multiname = self.pool_multiname(method, index, self.context.gc_context)?;
let multiname = self.pool_multiname(method, index)?;
let mut receiver = self.context.avm2.pop().coerce_to_object(self)?;
let name: Result<QName, Error> = receiver
.resolve_multiname(&multiname)?
@ -799,7 +798,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
arg_count: u32,
) -> Result<FrameControl<'gc>, Error> {
let args = self.context.avm2.pop_args(arg_count);
let multiname = self.pool_multiname(method, index, self.context.gc_context)?;
let multiname = self.pool_multiname(method, index)?;
let receiver = self.context.avm2.pop().coerce_to_object(self)?;
let name: Result<QName, Error> = receiver
.resolve_multiname(&multiname)?
@ -831,7 +830,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
arg_count: u32,
) -> Result<FrameControl<'gc>, Error> {
let args = self.context.avm2.pop_args(arg_count);
let multiname = self.pool_multiname(method, index, self.context.gc_context)?;
let multiname = self.pool_multiname(method, index)?;
let receiver = self.context.avm2.pop().coerce_to_object(self)?;
let name: Result<QName, Error> = receiver
.resolve_multiname(&multiname)?
@ -869,7 +868,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
method: Gc<'gc, BytecodeMethod<'gc>>,
index: Index<AbcMultiname>,
) -> Result<FrameControl<'gc>, Error> {
let multiname = self.pool_multiname(method, index, self.context.gc_context)?;
let multiname = self.pool_multiname(method, index)?;
let mut object = self.context.avm2.pop().coerce_to_object(self)?;
let name: Result<QName, Error> = object.resolve_multiname(&multiname)?.ok_or_else(|| {
@ -888,7 +887,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
index: Index<AbcMultiname>,
) -> Result<FrameControl<'gc>, Error> {
let value = self.context.avm2.pop();
let multiname = self.pool_multiname(method, index, self.context.gc_context)?;
let multiname = self.pool_multiname(method, index)?;
let mut object = self.context.avm2.pop().coerce_to_object(self)?;
if let Some(name) = object.resolve_multiname(&multiname)? {
@ -912,7 +911,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
index: Index<AbcMultiname>,
) -> Result<FrameControl<'gc>, Error> {
let value = self.context.avm2.pop();
let multiname = self.pool_multiname(method, index, self.context.gc_context)?;
let multiname = self.pool_multiname(method, index)?;
let mut object = self.context.avm2.pop().coerce_to_object(self)?;
if let Some(name) = object.resolve_multiname(&multiname)? {
@ -935,7 +934,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
method: Gc<'gc, BytecodeMethod<'gc>>,
index: Index<AbcMultiname>,
) -> Result<FrameControl<'gc>, Error> {
let multiname = self.pool_multiname(method, index, self.context.gc_context)?;
let multiname = self.pool_multiname(method, index)?;
let object = self.context.avm2.pop().coerce_to_object(self)?;
if let Some(name) = object.resolve_multiname(&multiname)? {
@ -954,7 +953,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
method: Gc<'gc, BytecodeMethod<'gc>>,
index: Index<AbcMultiname>,
) -> Result<FrameControl<'gc>, Error> {
let multiname = self.pool_multiname(method, index, self.context.gc_context)?;
let multiname = self.pool_multiname(method, index)?;
let object = self.context.avm2.pop().coerce_to_object(self)?;
let base_proto: Result<Object<'gc>, Error> = self
.base_proto()
@ -984,7 +983,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
index: Index<AbcMultiname>,
) -> Result<FrameControl<'gc>, Error> {
let value = self.context.avm2.pop();
let multiname = self.pool_multiname(method, index, self.context.gc_context)?;
let multiname = self.pool_multiname(method, index)?;
let object = self.context.avm2.pop().coerce_to_object(self)?;
let base_proto: Result<Object<'gc>, Error> = self
.base_proto()
@ -1081,8 +1080,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
method: Gc<'gc, BytecodeMethod<'gc>>,
index: Index<AbcMultiname>,
) -> Result<FrameControl<'gc>, Error> {
let multiname = self.pool_multiname(method, index, self.context.gc_context)?;
avm_debug!(self.avm2(), "Resolving {:?}", multiname);
let multiname = self.pool_multiname(method, index)?;
avm_debug!(self.context.avm2, "Resolving {:?}", multiname);
let result = if let Some(scope) = self.scope() {
scope.read().find(&multiname, self)?
} else {
@ -1101,8 +1100,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
method: Gc<'gc, BytecodeMethod<'gc>>,
index: Index<AbcMultiname>,
) -> Result<FrameControl<'gc>, Error> {
let multiname = self.pool_multiname(method, index, self.context.gc_context)?;
avm_debug!(self.avm2(), "Resolving {:?}", multiname);
let multiname = self.pool_multiname(method, index)?;
avm_debug!(self.context.avm2, "Resolving {:?}", multiname);
let found: Result<Object<'gc>, Error> = if let Some(scope) = self.scope() {
scope.read().find(&multiname, self)?
} else {
@ -1202,7 +1201,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
arg_count: u32,
) -> Result<FrameControl<'gc>, Error> {
let args = self.context.avm2.pop_args(arg_count);
let multiname = self.pool_multiname(method, index, self.context.gc_context)?;
let multiname = self.pool_multiname(method, index)?;
let mut source = self.context.avm2.pop().coerce_to_object(self)?;
let ctor_name: Result<QName, Error> =
@ -1269,7 +1268,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
object.set_property(
object,
&QName::new(Namespace::public_namespace(), name.as_string()?),
&QName::new(Namespace::public_namespace(), name.coerce_to_string(self)?),
value,
self,
)?;

View File

@ -52,14 +52,14 @@ fn value_of<'gc>(
/// `Object.prototype.hasOwnProperty`
pub fn has_own_property<'gc>(
_activation: &mut Activation<'_, 'gc, '_>,
activation: &mut Activation<'_, 'gc, '_>,
this: Option<Object<'gc>>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
let this: Result<Object<'gc>, Error> = this.ok_or_else(|| "No valid this parameter".into());
let this = this?;
let name: Result<&Value<'gc>, Error> = args.get(0).ok_or_else(|| "No name specified".into());
let name = name?.as_string()?;
let name = name?.coerce_to_string(activation)?;
if let Some(ns) = this.resolve_any(name)? {
if !ns.is_private() {
@ -95,14 +95,14 @@ pub fn is_prototype_of<'gc>(
/// `Object.prototype.propertyIsEnumerable`
pub fn property_is_enumerable<'gc>(
_activation: &mut Activation<'_, 'gc, '_>,
activation: &mut Activation<'_, 'gc, '_>,
this: Option<Object<'gc>>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
let this: Result<Object<'gc>, Error> = this.ok_or_else(|| "No valid this parameter".into());
let this = this?;
let name: Result<&Value<'gc>, Error> = args.get(0).ok_or_else(|| "No name specified".into());
let name = name?.as_string()?;
let name = name?.coerce_to_string(activation)?;
if let Some(ns) = this.resolve_any(name)? {
if !ns.is_private() {
@ -123,7 +123,7 @@ pub fn set_property_is_enumerable<'gc>(
let this: Result<Object<'gc>, Error> = this.ok_or_else(|| "No valid this parameter".into());
let this = this?;
let name: Result<&Value<'gc>, Error> = args.get(0).ok_or_else(|| "No name specified".into());
let name = name?.as_string()?;
let name = name?.coerce_to_string(activation)?;
if let Some(Value::Bool(is_enum)) = args.get(1) {
if let Some(ns) = this.resolve_any(name)? {

View File

@ -1,8 +1,9 @@
//! AVM2 names & namespacing
use crate::avm2::activation::Activation;
use crate::avm2::script::TranslationUnit;
use crate::avm2::string::AvmString;
use crate::avm2::{Avm2, Error};
use crate::avm2::Error;
use gc_arena::{Collect, MutationContext};
use swf::avm2::types::{
Index, Multiname as AbcMultiname, Namespace as AbcNamespace, NamespaceSet as AbcNamespaceSet,
@ -222,8 +223,7 @@ impl<'gc> Multiname<'gc> {
pub fn from_abc_multiname(
translation_unit: TranslationUnit<'gc>,
multiname_index: Index<AbcMultiname>,
avm: &mut Avm2<'gc>,
mc: MutationContext<'gc, '_>,
activation: &mut Activation<'_, 'gc, '_>,
) -> Result<Self, Error> {
let actual_index: Result<usize, Error> = (multiname_index.0 as usize)
.checked_sub(1)
@ -242,21 +242,23 @@ impl<'gc> Multiname<'gc> {
ns: vec![Namespace::from_abc_namespace(
translation_unit,
namespace.clone(),
mc,
activation.context.gc_context,
)?],
name: translation_unit.pool_string_option(name.0, mc)?,
name: translation_unit
.pool_string_option(name.0, activation.context.gc_context)?,
}
}
AbcMultiname::RTQName { name } | AbcMultiname::RTQNameA { name } => {
let ns = avm.pop().as_namespace()?.clone();
let ns = activation.avm2().pop().as_namespace()?.clone();
Self {
ns: vec![ns],
name: translation_unit.pool_string_option(name.0, mc)?,
name: translation_unit
.pool_string_option(name.0, activation.context.gc_context)?,
}
}
AbcMultiname::RTQNameL | AbcMultiname::RTQNameLA => {
let ns = avm.pop().as_namespace()?.clone();
let name = avm.pop().as_string()?;
let ns = activation.avm2().pop().as_namespace()?.clone();
let name = activation.avm2().pop().coerce_to_string(activation)?;
Self {
ns: vec![ns],
name: Some(name),
@ -270,14 +272,22 @@ impl<'gc> Multiname<'gc> {
namespace_set,
name,
} => Self {
ns: Self::abc_namespace_set(translation_unit, namespace_set.clone(), mc)?,
name: translation_unit.pool_string_option(name.0, mc)?,
ns: Self::abc_namespace_set(
translation_unit,
namespace_set.clone(),
activation.context.gc_context,
)?,
name: translation_unit.pool_string_option(name.0, activation.context.gc_context)?,
},
AbcMultiname::MultinameL { namespace_set }
| AbcMultiname::MultinameLA { namespace_set } => {
let name = avm.pop().as_string()?;
let name = activation.avm2().pop().coerce_to_string(activation)?;
Self {
ns: Self::abc_namespace_set(translation_unit, namespace_set.clone(), mc)?,
ns: Self::abc_namespace_set(
translation_unit,
namespace_set.clone(),
activation.context.gc_context,
)?,
name: Some(name),
}
}

View File

@ -206,16 +206,6 @@ pub fn abc_default_value<'gc>(
}
impl<'gc> Value<'gc> {
/// Demand a string value, erroring out if one is not found.
///
/// TODO: This should be replaced with `coerce_string` where possible.
pub fn as_string(&self) -> Result<AvmString<'gc>, Error> {
match self {
Value::String(s) => Ok(*s),
_ => Err(format!("Expected String, found {:?}", self).into()),
}
}
pub fn as_number(&self) -> Result<f64, Error> {
match self {
Value::Number(f) => Ok(*f),