246 lines
8.5 KiB
C++
246 lines
8.5 KiB
C++
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
* for the specific language governing rights and limitations under the
|
|
* License.
|
|
*
|
|
* The Original Code is [Open Source Virtual Machine.].
|
|
*
|
|
* The Initial Developer of the Original Code is
|
|
* Adobe System Incorporated.
|
|
* Portions created by the Initial Developer are Copyright (C) 1993-2006
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Adobe AS3 Team
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
|
|
#ifndef __avmplus_NativeFunction__
|
|
#define __avmplus_NativeFunction__
|
|
|
|
namespace avmplus
|
|
{
|
|
|
|
/**
|
|
* The NativeMethod class is a wrapper to bind a native C++ function
|
|
* to a class method surfaced into the ActionScript world.
|
|
* The class method must be defined with the "native" attribute.
|
|
*
|
|
* NativeMethod uses C++ calling conventions when calling the
|
|
* native C++ code. Incoming parameters are coerced to the
|
|
* proper type before the call as follows:
|
|
*
|
|
* AS type C++ type
|
|
* ------- --------
|
|
* Void Atom, if parameter, void if return type
|
|
* Object Atom
|
|
* Boolean bool
|
|
* Number double
|
|
* String Stringp (String *)
|
|
* Class ClassClosure*
|
|
* MovieClip MovieClipObject* (similar for any other class)
|
|
*/
|
|
class NativeMethod : public AbstractFunction
|
|
{
|
|
public:
|
|
typedef void (ScriptObject::*Handler)();
|
|
typedef Atom (ScriptObject::*GetHandler)();
|
|
typedef void (ScriptObject::*SetHandler)(Atom);
|
|
|
|
/**
|
|
* invoke handler as handler(...) with native typed args
|
|
*/
|
|
NativeMethod(int flags, Handler handler);
|
|
|
|
/**
|
|
* invoke handler as handler(int cookie, ...) with native typed args
|
|
*/
|
|
NativeMethod(int flags, Handler handler, int cookie);
|
|
|
|
// we have virtual functions, so we probably need a virtual dtor
|
|
virtual ~NativeMethod() {}
|
|
|
|
static Atom verifyEnter(MethodEnv* env, int argc, uint32 *ap);
|
|
|
|
virtual void verify(Toplevel* toplevel);
|
|
|
|
int m_cookie;
|
|
union {
|
|
Handler m_handler;
|
|
uintptr m_handler_addr;
|
|
};
|
|
|
|
};
|
|
|
|
/**
|
|
* NativeMethodV is similar to NativeMethod but does not coerce
|
|
* arguments automatically to appropriate C++ types.
|
|
* Instead, the C++ code always receives arguments in the
|
|
* form: Atom method(Atom *argv, int argc);
|
|
*
|
|
* NativeMethodV is deprecated and will eventually be removed.
|
|
*/
|
|
class NativeMethodV : public AbstractFunction
|
|
{
|
|
public:
|
|
typedef int (ScriptObject::*Handler32)(Atom *argv, int argc);
|
|
typedef int (ScriptObject::*CookieHandler32)(int cookie, Atom *argv, int argc);
|
|
typedef double (ScriptObject::*HandlerN)(Atom *argv, int argc);
|
|
typedef double (ScriptObject::*CookieHandlerN)(int cookie, Atom *argv, int argc);
|
|
|
|
/**
|
|
* invoke handler as handler(...) with native typed args
|
|
*/
|
|
NativeMethodV(Handler32 handler, int flgs)
|
|
: AbstractFunction()
|
|
{
|
|
m_handler = handler;
|
|
this->flags |= (flgs | NEED_REST);
|
|
this->impl32 = verifyEnter;
|
|
}
|
|
|
|
/**
|
|
* invoke handler as handler(int cookie, ...) with native typed args
|
|
*/
|
|
NativeMethodV(Handler32 handler, int cookie, int flgs)
|
|
: AbstractFunction()
|
|
{
|
|
m_handler = handler;
|
|
m_cookie = cookie;
|
|
m_haveCookie = true;
|
|
this->impl32 = verifyEnter;
|
|
this->flags = flgs;
|
|
}
|
|
|
|
void verify(Toplevel* toplevel)
|
|
{
|
|
AvmAssert(declaringTraits->linked);
|
|
resolveSignature(toplevel);
|
|
AvmCore* core = this->core();
|
|
if (returnTraits() == NUMBER_TYPE)
|
|
impl32 = implv32;
|
|
else
|
|
implN = implvN;
|
|
}
|
|
|
|
static Atom verifyEnter(MethodEnv* env, int argc, uint32 *ap);
|
|
|
|
static Atom implv32(MethodEnv* env,
|
|
int argc, uint32 *ap);
|
|
static double implvN(MethodEnv* env,
|
|
int argc, uint32 *ap);
|
|
|
|
private:
|
|
bool m_haveCookie;
|
|
int m_cookie;
|
|
Handler32 m_handler;
|
|
};
|
|
|
|
|
|
/**
|
|
* NativeTableEntry is an internal structure used for native
|
|
* method tables. It is wrapped by the NATIVE_METHOD() macros
|
|
* below.
|
|
*/
|
|
struct NativeTableEntry
|
|
{
|
|
typedef void (ScriptObject::*Handler)();
|
|
int method_id;
|
|
enum {
|
|
kNativePrefix,
|
|
kNativeMethod,
|
|
kNativeMethod1,
|
|
kNativeMethodRest,
|
|
kNativeMethodV,
|
|
kNativeMethodV1
|
|
} type;
|
|
Handler handler;
|
|
int cookie;
|
|
int flags;
|
|
};
|
|
|
|
/**
|
|
* Macros for declaring native methods
|
|
*/
|
|
#define BEGIN_NATIVE_MAP(_Class) NativeTableEntry _Class::natives[] = {
|
|
|
|
#define DECLARE_NATIVE_MAP(_Class) static ClassClosure* createClassClosure(VTable* cvtable) \
|
|
{ return new (cvtable->gc(), cvtable->getExtraSize()) _Class(cvtable); } \
|
|
static NativeTableEntry natives[];
|
|
|
|
#define DECLARE_NATIVE_SCRIPT(_Script) static ScriptObject* createGlobalObject(VTable* vtable, ScriptObject* delegate) \
|
|
{ return new (vtable->gc(), vtable->getExtraSize()) _Script(vtable, delegate); } \
|
|
static NativeTableEntry natives[];
|
|
|
|
#define NATIVE_METHOD(method_id, handler) { avmplus::NativeID::method_id, NativeTableEntry::kNativeMethod, (NativeTableEntry::Handler)&handler, 0, AbstractFunction::NEEDS_CODECONTEXT | AbstractFunction::NEEDS_DXNS },
|
|
#define NATIVE_METHOD_FLAGS(method_id, handler, fl) { avmplus::NativeID::method_id, NativeTableEntry::kNativeMethod, (NativeTableEntry::Handler)&handler, 0, fl },
|
|
|
|
#define NATIVE_METHOD2(method_id, handler) { avmplus::NativeID::method_id, NativeTableEntry::kNativeMethod, (NativeTableEntry::Handler)(handler), 0, AbstractFunction::NEEDS_CODECONTEXT | AbstractFunction::NEEDS_DXNS },
|
|
#define NATIVE_METHOD2_FLAGS(method_id, handler,fl) { avmplus::NativeID::method_id, NativeTableEntry::kNativeMethod, (NativeTableEntry::Handler)(handler), 0, fl },
|
|
|
|
#define NATIVE_METHOD1(method_id, handler, cookie) { avmplus::NativeID::method_id, NativeTableEntry::kNativeMethod1, (NativeTableEntry::Handler)&handler, cookie, AbstractFunction::NEEDS_CODECONTEXT | AbstractFunction::NEEDS_DXNS },
|
|
#define NATIVE_METHOD1_FLAGS(method_id, handler, cookie, fl) { avmplus::NativeID::method_id, NativeTableEntry::kNativeMethod1, (NativeTableEntry::Handler)&handler, cookie, fl },
|
|
|
|
#define NATIVE_METHODV(method_id, handler) { avmplus::NativeID::method_id, NativeTableEntry::kNativeMethodV, (NativeTableEntry::Handler)&handler, 0, AbstractFunction::NEEDS_CODECONTEXT | AbstractFunction::NEEDS_DXNS },
|
|
#define NATIVE_METHODV_FLAGS(method_id, handler, fl) { avmplus::NativeID::method_id, NativeTableEntry::kNativeMethodV, (NativeTableEntry::Handler)&handler, 0, fl },
|
|
|
|
#define NATIVE_METHODV1(method_id, handler, cookie) { avmplus::NativeID::method_id, NativeTableEntry::kNativeMethodV1, (NativeTableEntry::Handler)&handler, cookie, AbstractFunction::NEEDS_CODECONTEXT | AbstractFunction::NEEDS_DXNS },
|
|
#define NATIVE_METHODV1_FLAGS(method_id, handler, cookie, fl) { avmplus::NativeID::method_id, NativeTableEntry::kNativeMethodV1, (NativeTableEntry::Handler)&handler, cookie, fl },
|
|
|
|
|
|
#define END_NATIVE_MAP() { -1, NativeTableEntry::kNativeMethod, NULL, 0 } };
|
|
|
|
/**
|
|
* NativeScriptInfo is an internal structure used for
|
|
* native script tables. It is wrapped by the
|
|
* NATIVE_SCRIPT() macro.
|
|
*/
|
|
struct NativeScriptInfo
|
|
{
|
|
typedef ScriptObject* (*Handler)(VTable*, ScriptObject*);
|
|
|
|
int script_id;
|
|
Handler handler;
|
|
NativeTableEntry *nativeMap;
|
|
int sizeofInstance;
|
|
};
|
|
|
|
/**
|
|
* NativeClassInfo is an internal structure used for native
|
|
* method tables. It is wrapped by the NATIVE_CLASS() macro.
|
|
*/
|
|
struct NativeClassInfo
|
|
{
|
|
typedef ClassClosure* (*Handler)(VTable*);
|
|
|
|
int class_id;
|
|
Handler handler;
|
|
NativeTableEntry *nativeMap;
|
|
int sizeofClass;
|
|
int sizeofInstance;
|
|
};
|
|
}
|
|
|
|
#endif /* __avmplus_NativeFunction__ */
|