/* -*- 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 delegate; // __proto__ in AS2, archetype in semantics // ------------------------ DATA SECTION END }; } #endif /* __avmplus_ScriptObject__ */