Files
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

292 lines
10 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_MethodEnv__
#define __avmplus_MethodEnv__
namespace avmplus
{
class GC_CPP_EXACT(MethodEnv, MethodEnvProcHolder)
{
friend class CodegenLIR;
friend class BaseExecMgr;
friend class halfmoon::JitFriend;
protected:
MethodEnv(MethodInfo* method, ScopeChain* scope);
public:
static MethodEnv* create(MMgc::GC* gc, MethodInfo* method, ScopeChain* scope);
/** vtable for the activation scope inside this method */
ScriptObject* newUninitializedActivation();
ScriptObject* newActivation();
/** getter lazily creates table which maps SO->MC */
WeakKeyHashtable *getMethodClosureTable();
AbcEnv* abcEnv() const;
AvmCore* core() const;
CodeContext* codeContext() const;
DomainEnv* domainEnv() const;
ScopeChain* scope() const;
MethodEnv* super_init() const;
Toplevel* toplevel() const;
Stringp traitsName() const;
Namespacep traitsNs() const;
VTable* vtable() const;
/**
* Coerces an array of actual parameters to the types
* required by a function's formal parameters, then invokes
* the method. Args are provided as an array of atoms, not
* an array of native types.
*
* It is not well documented throughout, but it is generally
* assumed that argument arrays may /always/ be modified in
* place by the callee, thus coerceEnter may modify 'argv'
* (though not the ArrayObject 'a', of course).
*
* @param instance The "this" that the function
* is being invoked with; may be
* coerced by this method.
* @param argv The array of arguments to coerce
* @param argc The number of arguments
* @throws Exception May throw an ArgumentError or
* TypeError if an argument cannot be coerced
* to the required type
*/
Atom coerceEnter(Atom thisArg);
Atom coerceEnter(int32_t argc, Atom* argv);
// Called from the interpreter
void nullcheck(Atom atom); // null pointer check
private:
MethodSignaturep get_ms();
void FASTCALL nullcheckfail(Atom atom);
VTable* getActivationVTable();
VTable* buildActivationVTable();
// helper functions used from compiled code
public:
void argcError(int32_t argc); // never returns; throws argument count error
ArrayObject* createRest(Atom* argv, int32_t argc);
Atom getpropertylate_i(Atom obj, int32_t index) const;
Atom getpropertylate_u(Atom obj, uint32_t index) const;
Atom getpropertylate_d(Atom obj, double index) const;
/*bool*/ int32_t haspropertylate_i(Atom obj, int32_t index) const;
/*bool*/ int32_t haspropertylate_u(Atom obj, uint32_t index) const;
#if defined VMCFG_NANOJIT || defined VMCFG_AOT
void setpropertyHelper(Atom obj, /* not const */ Multiname *multi, Atom value, VTable *vtable, Atom index);
void initpropertyHelper(Atom obj, /* not const */ Multiname *multi, Atom value, VTable *vtable, Atom index);
Atom getpropertyHelper(Atom obj, /* not const */ Multiname *multi, VTable *vtable, Atom index);
Atom delpropertyHelper(Atom obj, /* not const */ Multiname *multi, Atom index);
void initMultinameLateForDelete(Multiname& name, Atom index);
ArrayObject* createArgumentsHelper(int32_t argc, uint32_t *ap);
ArrayObject* createRestHelper(int32_t argc, uint32_t *ap);
#endif
ScriptObject* newcatch(Traits *traits);
/**
* used for defining and resolving imported definitions.
*/
ScriptObject* finddef(const Multiname* name) const;
/**
* implementation of object initializers
*/
ScriptObject* op_newobject(Atom* sp, int32_t argc) const;
/** Implementation of OP_nextname */
Atom nextname(Atom objAtom, int32_t index) const;
/** Implementation of OP_nextvalue */
Atom nextvalue(Atom objAtom, int32_t index) const;
/** Implementation of OP_hasnext */
int32_t hasnext(Atom objAtom, int32_t index) const;
/** Implementation of OP_hasnext2 */
int32_t hasnextproto(Atom& objAtom, int& index) const;
/**
* OP_newfunction
* see 13.2 creating function objects
*/
ClassClosure* newfunction(MethodInfo *function, Atom* scopes) const;
/**
* OP_newclass
*/
ClassClosure* newclass(Traits* ctraits,
ClassClosure* base,
ScopeChain* outer,
Atom* scopes) const;
void initproperty(Atom obj, const Multiname* multiname, Atom value, VTable* vtable) const;
void setpropertylate_i(Atom obj, int32_t index, Atom value) const;
void setpropertylate_u(Atom obj, uint32_t index, Atom value) const;
void setpropertylate_d(Atom obj, double index, Atom value) const;
#ifdef VMCFG_FLOAT
void setpropertylate_f(Atom obj, float index, Atom value) const;
#endif
/** same as callproperty but only considers the bindings in given vtable */
Atom callsuper(const Multiname* name, int32_t argc, Atom* atomv) const;
Atom delproperty(Atom obj, const Multiname* multiname) const;
/**
* Reads a property from an object, with the property
* to retrieve specified by its binding.
* The binding was likely retrieved using getBinding.
* @param obj Object to retrieve property from
* @param b The binding of the property
* @param traits The traits of the object
*/
Atom getsuper(Atom obj, const Multiname* name) const;
/**
* Write to a property of an object, with the property
* to modify specified by its binding.
* The binding was likely retrieved using getBinding.
* @param obj Object to modify property of
* @param b The binding of the property
* @param value The new value of the property
*/
void setsuper(Atom obj, const Multiname* name, Atom value) const;
/** Implementation of OP_findproperty */
Atom findproperty(ScopeChain* outer,
Atom* scopes,
int32_t extraScopes,
const Multiname* multiname,
bool strict,
Atom* withBase);
/** Like findproperty, but ignoring all lexical and 'this' scopes. Returns NULL if
* property could not be found; caller should signal strict error or return the
* target_global as appropriate.
*/
Atom findglobalproperty(Atom target_global, const Multiname* multiname);
Namespace* internRtns(Atom ns);
/** Creates the arguments array */
ArrayObject* createArguments(Atom *atomv, int32_t argc);
/**
* E4X descendants operator (..)
*/
Atom getdescendants(Atom obj, const Multiname* multiname);
/**
* E4X filter operator
*/
void checkfilter(Atom obj);
#ifdef DEBUGGER
void debugEnter(const uint8_t* frame_sst,
CallStackNode* callstack,
FramePtr framep,
volatile intptr_t *eip);
void debugEnterInner();
void debugExit(CallStackNode* callstack);
ArrayObject *getLexicalScopes();
uint64_t invocationCount() const;
#endif
private:
Atom findWithProperty(Atom obj, const Multiname* multiname);
class ActivationMethodTablePair : public MMgc::GCObject
{
public:
ActivationMethodTablePair(VTable *a, WeakKeyHashtable*wkh);
// ------------------------ DATA SECTION BEGIN
public:
VTable* const activation;
WeakKeyHashtable* const methodTable;
// ------------------------ DATA SECTION END
};
// low 2 bits of activationOrMCTable
enum { kActivation=0, kMethodTable, kActivationMethodTablePair };
ActivationMethodTablePair* getPair() const;
int32_t getType() const;
void setActivationOrMCTable(void *ptr, int32_t type);
public:
// ------------------------ DATA SECTION BEGIN
GC_DATA_BEGIN(MethodEnv)
MethodInfo* const GC_POINTER(method);
protected:
// pointers are write-once so we don't need WB's
ScopeChain* const GC_POINTER(_scope);
private:
uintptr_t GC_CONSERVATIVE(activationOrMCTable);
GC_DATA_END(MethodEnv)
// ------------------------ DATA SECTION END
};
class GC_CPP_EXACT(ScriptEnv, MethodEnv)
{
ScriptEnv(MethodInfo* _method, ScopeChain* _scope);
public:
REALLY_INLINE static ScriptEnv* create(MMgc::GC* gc, MethodInfo* _method, ScopeChain* _scope)
{
return new (gc, MMgc::kExact) ScriptEnv(_method, _scope);
}
ScriptObject* initGlobal();
static ScopeChain* createScriptScope(const ScopeTypeChain* stc, VTable* _vtable, AbcEnv* _abcEnv);
// ------------------------ DATA SECTION BEGIN
GC_DATA_BEGIN(ScriptEnv)
public:
GCMember<ScriptObject> GC_POINTER(global); // initially null, set after initialization
GC_DATA_END(ScriptEnv)
// ------------------------ DATA SECTION END
};
class GC_CPP_EXACT(FunctionEnv, MethodEnv)
{
FunctionEnv(MethodInfo* _method, ScopeChain* _scope);
public:
REALLY_INLINE static FunctionEnv* create(MMgc::GC* gc, MethodInfo* _method, ScopeChain* _scope)
{
return new (gc, MMgc::kExact) FunctionEnv(_method, _scope);
}
// ------------------------ DATA SECTION BEGIN
GC_DATA_BEGIN(FunctionEnv)
public:
GCMember<ClassClosure> GC_POINTER(closure);
GC_DATA_END(FunctionEnv)
// ------------------------ DATA SECTION END
};
}
#endif // __avmplus_MethodEnv__