Files
avmplus/core/ScriptObject.h
T
dmcallis 65a0592776 Initial source code drop
Source code drop for the Actionscript virtual machine in the Adobe
Flash Player for December 2013
2013-12-02 16:04:04 -08:00

230 lines
9.5 KiB
C++

/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef __avmplus_ScriptObject__
#define __avmplus_ScriptObject__
namespace avmplus
{
#define avmplus_ScriptObject_isExactInterlock 1
/**
* one actionscript object. might or might not be a function.
* Base class for all objects visible to script code.
*/
class ScriptObject : public AvmPlusScriptableObject
{
protected:
ScriptObject(VTable* vtable, ScriptObject* delegate);
ScriptObject(VTable* vtable, ScriptObject* delegate, int htCapacity);
public:
REALLY_INLINE static ScriptObject* create(MMgc::GC* gc, VTable* vtable, ScriptObject* delegate);
REALLY_INLINE static ScriptObject* create(MMgc::GC* gc, VTable* vtable, ScriptObject* delegate, int htCapacity);
// Not actually entirely trivial, as it decrements reference counts
// manually, not just by GCMember smart pointer destructors.
#ifdef DRC_TRIVIAL_DESTRUCTOR
~ScriptObject();
#endif
virtual bool gcTrace(MMgc::GC* gc, size_t cursor);
ScriptObject* getDelegate() const;
void setDelegate(ScriptObject *d);
Atom atom() const;
virtual Atom toAtom() const;
Traits* traits() const;
AvmCore* core() const;
MMgc::GC* gc() const;
Toplevel* toplevel() const;
/**
* Returns a pointer to hashtable to use for dynamic
* properties, this is a derived pointer and can never be
* NULL. This method should not be called until the full
* construction sequence (C++ and AS3) is complete and will
* assert if called on a Dictionary before its init method has
* run.
*/
InlineHashtable* getTable() const;
/**
* Like getTable but doesn't init the table if its empty, and
* will return NULL and not assert on a yet to be initialized
* Dictionary.
*/
InlineHashtable* getTableNoInit() const;
Atom getSlotAtom(uint32_t slot, AvmCore *core);
Atom getSlotAtom(uint32_t slot);
// like getSlotAtom, but assume the resulting Atom is a ScriptObject...
// if it is not, return NULL. useful for callers that expect only
// a ScriptObject and reject other types (eg callproperty). If the
// slot in question is usually a ScriptObject, it's substantially faster
// to call this (vs getSlotAtom).
ScriptObject* getSlotObject(uint32_t slot);
// NOTE, this now does the equivalent of Toplevel::coerce() internally;
// it is not necessary to call coerce() prior to calling this!
void coerceAndSetSlotAtom(uint32_t slot, Atom atom);
virtual Atom getDescendants(const Multiname* name) const;
// argv[0] = receiver
virtual Atom callProperty(const Multiname* name, int argc, Atom* argv);
// common set/set/has/delete/etc virtual methods renamed to explicitly name the expected arg types,
// to avoid potentially hidden virtual functions
virtual Atom getAtomProperty(Atom name) const;
virtual void setAtomProperty(Atom name, Atom value);
virtual bool deleteAtomProperty(Atom name);
virtual bool hasAtomProperty(Atom name) const;
virtual bool getAtomPropertyIsEnumerable(Atom name) const;
virtual void setAtomPropertyIsEnumerable(Atom name, bool enumerable);
virtual Atom getMultinameProperty(const Multiname* name) const;
virtual void setMultinameProperty(const Multiname* name, Atom value);
virtual bool deleteMultinameProperty(const Multiname* name);
virtual bool hasMultinameProperty(const Multiname* name) const;
virtual Atom getUintProperty(uint32_t i) const;
virtual void setUintProperty(uint32_t i, Atom value);
virtual bool delUintProperty(uint32_t i);
virtual bool hasUintProperty(uint32_t i) const;
// convenience wrappers for passing Stringp instead of Atom
// inline, not virtual (should never need overriding)
Atom getStringProperty(Stringp name) const;
Atom getStringPropertyFromProtoChain(Stringp name, ScriptObject* protochain, Traits *origObjTraits) const;
void setStringProperty(Stringp name, Atom value);
bool deleteStringProperty(Stringp name);
bool hasStringProperty(Stringp name) const;
bool getStringPropertyIsEnumerable(Stringp name) const;
void setStringPropertyIsEnumerable(Stringp name, bool enumerable);
virtual Atom defaultValue(); // ECMA [[DefaultValue]]
virtual Stringp toString();
/**
* Implmenets the behavior of this object when called as a function.
* This function is only intended to be called by the VM, not from
* C++ host code. For the latter, use one of the avm::callFunction()
* wrappers.
*
* argv[0] is not counted in argc and is the receiver (this) parameter
* argc[1+] are the normal arguments
*/
virtual Atom call(int argc, Atom* argv);
/**
* argv[0] = receiver(ignored)
* arg1 = argv[1]
* argN = argv[argc]
*
* called as constructor, as in new C(). for user classes this
* invokes the implicit constructor followed by the user's constructor
* if any.
*
* NOTE: The contents of the given argument list can be modified during
* invocation of the constructor without further warning.
* Do not reuse an argument list AS-IS for multiple constructor calls,
* unless you make sure to reinitialize the contents of the argument list after each call.
*
* NOTE: subclasses should never need to declare this method in their class;
* an override declaration will be provided for them iff
* construct="override" or construct="instance" is specified in the AS3 file.
*/
virtual Atom construct(int argc, Atom* argv);
// TODO make this const
virtual Atom nextName(int index);
// TODO make this const
virtual Atom nextValue(int index);
// TODO make this const
virtual int nextNameIndex(int index);
virtual Atom applyTypeArgs(int argc, Atom* argv);
// This is a fast way to implement "istype(MethodClosure)"; it returns non-null if
// this is an MethodClosure (or subclass thereof)
virtual MethodClosure* toMethodClosure() const;
bool isMethodClosure() const;
// The maximum integer key we can use with our ScriptObject
// HashTable must fit within 28 bits. Any integer larger
// than 28 bits will use a string key.
static const uint32_t MAX_INTEGER_MASK = 0xF0000000;
// return true iff the object is a toplevel script init object.
bool isGlobalObject() const;
virtual Stringp implToString() const;
// this really shouldn't exist here, but AIR currently plays some games with subclassing
// "Function" that use C++ classes that don't descend from FunctionObject. Easier to fix
// by rooting this method here than by fixing AIR at this time.
virtual CodeContext* getFunctionCodeContext() const;
// This is a fast way to implement "istype(ARRAY)"; it returns non-null if
// this is an ArrayObject (or subclass thereof)
virtual ArrayObject* toArrayObject();
// This gets the property named "length" (if any) on the object, coerces it to a uint,
// and returns the value. (Since uint(undefined) == 0, undefined length is zero.)
virtual uint32_t getLengthProperty();
// This sets the property named "length" to the given uint value. If this
// is a nondynamic object, or there is a read-only length property, or uint
// can't be coerced to the type of "length", an exception will be thrown.
virtual void setLengthProperty(uint32_t newLen);
virtual ClassClosure* toClassClosure();
#ifdef AVMPLUS_VERBOSE
public:
virtual PrintWriter& print(PrintWriter& prw) const;
#endif
#ifdef DEBUGGER
public:
virtual uint64_t bytesUsed() const;
virtual void registerDependentObjects(IMemorySampler *memSampler);
#endif
#if defined(DEBUGGER) || defined(VMCFG_AOT)
public:
virtual MethodEnv* getCallMethodEnv();
#endif
protected:
Atom getAtomPropertyFromProtoChain(Atom name, ScriptObject* protochain, Traits *origObjTraits) const;
// If name defined in this (not its prototype chain), sets
// *recv to this[name] and returns true. Else returns false.
// (Assumes this is dynamic; do not call on sealed instances.)
virtual bool isOwnAtomPropertyHere(Atom name, Atom *recv) const;
void throwWriteSealedError(Atom name);
void throwWriteSealedError(const Multiname& name);
public:
void throwCantInstantiateError();
private:
void initHashtable(int capacity = InlineHashtable::kDefaultCapacity);
// ------------------------ DATA SECTION BEGIN
public: VTable* const vtable;
private: GCMember<ScriptObject> delegate; // __proto__ in AS2, archetype in semantics
// ------------------------ DATA SECTION END
};
}
#endif /* __avmplus_ScriptObject__ */