avm2: Alter basic object operations to use more descriptive error messages.
This commit is contained in:
parent
4185acc5a8
commit
0f2b77c138
|
@ -274,7 +274,8 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
let result = self
|
||||
.base()
|
||||
.get_property_local(multiname, activation)?
|
||||
.coerce_to_object(activation)?;
|
||||
.as_callable(activation, Some(multiname), Some(self.into()))?;
|
||||
|
||||
result.call(Some(self.into()), arguments, activation)
|
||||
}
|
||||
|
||||
|
@ -292,10 +293,12 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
) -> Result<Value<'gc>, Error> {
|
||||
match self.vtable().and_then(|vtable| vtable.get_trait(multiname)) {
|
||||
Some(Property::Slot { slot_id }) | Some(Property::ConstSlot { slot_id }) => {
|
||||
let obj = self
|
||||
.base()
|
||||
.get_slot(slot_id)?
|
||||
.coerce_to_object(activation)?;
|
||||
let obj = self.base().get_slot(slot_id)?.as_callable(
|
||||
activation,
|
||||
Some(multiname),
|
||||
Some(self.into()),
|
||||
)?;
|
||||
|
||||
obj.call(Some(self.into()), arguments, activation)
|
||||
}
|
||||
Some(Property::Method { disp_id }) => {
|
||||
|
@ -328,9 +331,12 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
}
|
||||
}
|
||||
Some(Property::Virtual { get: Some(get), .. }) => {
|
||||
let obj = self
|
||||
.call_method(get, &[], activation)?
|
||||
.coerce_to_object(activation)?;
|
||||
let obj = self.call_method(get, &[], activation)?.as_callable(
|
||||
activation,
|
||||
Some(multiname),
|
||||
Some(self.into()),
|
||||
)?;
|
||||
|
||||
obj.call(Some(self.into()), arguments, activation)
|
||||
}
|
||||
Some(Property::Virtual { get: None, .. }) => {
|
||||
|
@ -642,9 +648,11 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
args: &[Value<'gc>],
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
) -> Result<Object<'gc>, Error> {
|
||||
let ctor = self
|
||||
.get_property(multiname, activation)?
|
||||
.coerce_to_object(activation)?;
|
||||
let ctor = self.get_property(multiname, activation)?.as_callable(
|
||||
activation,
|
||||
Some(multiname),
|
||||
Some(self.into()),
|
||||
)?;
|
||||
|
||||
ctor.construct(activation, args)
|
||||
}
|
||||
|
@ -739,9 +747,13 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
) -> Result<bool, Error> {
|
||||
let type_proto = class
|
||||
.get_property(&QName::dynamic_name("prototype").into(), activation)?
|
||||
.coerce_to_object(activation)?;
|
||||
.as_object();
|
||||
|
||||
self.has_prototype_in_chain(type_proto)
|
||||
if let Some(type_proto) = type_proto {
|
||||
self.has_prototype_in_chain(type_proto)
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
/// Determine if this object has a given prototype in its prototype chain.
|
||||
|
|
|
@ -138,13 +138,21 @@ impl<'gc> ScriptObjectData<'gc> {
|
|||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
if !multiname.contains_public_namespace() {
|
||||
return Err(
|
||||
format!("Non-public property `{:?}` not found on Object", multiname).into(),
|
||||
);
|
||||
return Err(format!(
|
||||
"Non-public property {} not found on Object",
|
||||
multiname.to_qualified_name(activation.context.gc_context)
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
let local_name = match multiname.local_name() {
|
||||
None => return Err("Unnamed property not found on Object".into()),
|
||||
None => {
|
||||
return Err(format!(
|
||||
"Unnamed property {} not found on Object",
|
||||
multiname.to_qualified_name(activation.context.gc_context)
|
||||
)
|
||||
.into())
|
||||
}
|
||||
Some(name) => name,
|
||||
};
|
||||
|
||||
|
@ -174,24 +182,36 @@ impl<'gc> ScriptObjectData<'gc> {
|
|||
&mut self,
|
||||
multiname: &Multiname<'gc>,
|
||||
value: Value<'gc>,
|
||||
_activation: &mut Activation<'_, 'gc, '_>,
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
) -> Result<(), Error> {
|
||||
if self
|
||||
.instance_of()
|
||||
.map(|cls| cls.inner_class_definition().read().is_sealed())
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return Err(
|
||||
format!("Cannot set undefined property {:?}", multiname.local_name()).into(),
|
||||
);
|
||||
return Err(format!(
|
||||
"Cannot set undefined property {}",
|
||||
multiname.to_qualified_name(activation.context.gc_context)
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
if !multiname.contains_public_namespace() {
|
||||
return Err("Non-public property not found on Object".into());
|
||||
return Err(format!(
|
||||
"Non-public property {} not found on Object",
|
||||
multiname.to_qualified_name(activation.context.gc_context)
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
let local_name = match multiname.local_name() {
|
||||
None => return Err("Unnamed property not found on Object".into()),
|
||||
None => {
|
||||
return Err(format!(
|
||||
"Unnamed property {} not found on Object",
|
||||
multiname.to_qualified_name(activation.context.gc_context)
|
||||
)
|
||||
.into())
|
||||
}
|
||||
Some(name) => name,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue