ruffle/core/src/avm2/object.rs

128 lines
3.8 KiB
Rust
Raw Normal View History

//! AVM2 objects.
use crate::avm2::function::FunctionObject;
use crate::avm2::names::{Multiname, QName};
2020-02-15 01:30:19 +00:00
use crate::avm2::property::Attribute;
use crate::avm2::return_value::ReturnValue;
use crate::avm2::script_object::ScriptObject;
use crate::avm2::value::Value;
use crate::avm2::{Avm2, Error};
use crate::context::UpdateContext;
2020-02-10 19:54:55 +00:00
use enumset::{EnumSet, EnumSetType};
use gc_arena::{Collect, MutationContext};
use ruffle_macros::enum_trait_object;
use std::fmt::Debug;
/// Represents an object that can be directly interacted with by the AVM2
/// runtime.
#[enum_trait_object(
#[derive(Clone, Collect, Debug, Copy)]
#[collect(no_drop)]
pub enum Object<'gc> {
ScriptObject(ScriptObject<'gc>),
FunctionObject(FunctionObject<'gc>)
}
)]
pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy {
/// Retrieve a property by it's QName.
fn get_property(
self,
name: &QName,
avm: &mut Avm2<'gc>,
context: &mut UpdateContext<'_, 'gc, '_>,
) -> Result<ReturnValue<'gc>, Error>;
/// Set a property by it's QName.
fn set_property(
2020-02-10 19:54:55 +00:00
self,
name: &QName,
value: Value<'gc>,
avm: &mut Avm2<'gc>,
context: &mut UpdateContext<'_, 'gc, '_>,
) -> Result<(), Error>;
/// Resolve a multiname into a single QName, if any of the namespaces
/// match.
fn resolve_multiname(self, multiname: &Multiname) -> Option<QName> {
for ns in multiname.namespace_set() {
let qname = QName::qualified(ns, multiname.local_name());
if self.has_property(&qname) {
return Some(qname);
}
}
None
}
2020-02-10 19:54:55 +00:00
/// Indicates whether or not a property exists on an object.
2020-02-12 00:42:47 +00:00
fn has_property(self, _name: &QName) -> bool;
2020-02-10 19:54:55 +00:00
/// Indicates whether or not a property exists on an object and is not part
/// of the prototype chain.
fn has_own_property(self, _name: &QName) -> bool {
false
}
/// Indicates whether or not a property is overwritable.
fn is_property_overwritable(self, _name: &QName) -> bool {
false
}
/// Delete a named property from the object.
///
/// Returns false if the property cannot be deleted.
fn delete(&self, gc_context: MutationContext<'gc, '_>, multiname: &QName) -> bool {
2020-02-10 19:54:55 +00:00
false
}
/// Retrieve the `__proto__` of a given object.
///
/// The proto is another object used to resolve methods across a class of
/// multiple objects. It should also be accessible as `__proto__` from
/// `get`.
2020-02-13 03:47:56 +00:00
fn proto(&self) -> Option<Object<'gc>>;
2020-02-10 19:54:55 +00:00
/// Define a value on an object.
///
/// Unlike setting a value, this function is intended to replace any
/// existing virtual or built-in properties already installed on a given
/// object. As such, this should not run any setters; the resulting name
/// slot should either be completely replaced with the value or completely
/// untouched.
///
/// It is not guaranteed that all objects accept value definitions,
/// especially if a property name conflicts with a built-in property, such
/// as `__proto__`.
fn define_value(
&self,
gc_context: MutationContext<'gc, '_>,
name: &QName,
value: Value<'gc>,
attributes: EnumSet<Attribute>,
) {
}
/// Call the object.
fn call(
self,
_reciever: Object<'gc>,
_arguments: &[Value<'gc>],
_avm: &mut Avm2<'gc>,
_context: &mut UpdateContext<'_, 'gc, '_>,
) -> Result<ReturnValue<'gc>, Error> {
Err("Object is not callable".into())
}
/// Get a raw pointer value for this object.
fn as_ptr(&self) -> *const ObjectPtr;
}
pub enum ObjectPtr {}
impl<'gc> Object<'gc> {
pub fn ptr_eq(a: Object<'gc>, b: Object<'gc>) -> bool {
a.as_ptr() == b.as_ptr()
}
}