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