2025-01-22 16:18:30 +01:00

290 lines
8.6 KiB
C++

#ifndef INCLUDED_HX_SCRIPTABLE
#define INCLUDED_HX_SCRIPTABLE
#include <typeinfo>
#ifdef __clang__
#pragma clang diagnostic ignored "-Winvalid-offsetof"
#endif
namespace hx
{
extern bool gEnableJit;
inline void EnableJit(bool inEnable) { gEnableJit = inEnable; }
#define HXCPP_CPPIA_SUPER_ARG(x) , (x)
struct ScriptNamedFunction : public ScriptFunction
{
ScriptNamedFunction(const ScriptFunction &s) : ScriptFunction(s), name(0), isStatic(false), superExecute(0) { }
ScriptNamedFunction(const char *inName=0,StackExecute inExe=0,const char *inSig=0, bool inIsStatic=false, StackExecute superExecute=0)
: ScriptFunction(inExe, inSig), name(inName), isStatic(inIsStatic), superExecute(superExecute) { }
const char *name;
bool isStatic;
StackExecute superExecute;
};
inline void SetFloatAligned(void *inPtr, const Float &inValue)
{
#ifdef HXCPP_ALIGN_FLOAT
int *dest = (int *)inPtr;
const int *src = (const int *)&inValue;
dest[1] = src[1];
#else
*(Float *)inPtr = inValue;
#endif
}
inline Float GetFloatAligned(const void *inPtr)
{
#ifdef HXCPP_ALIGN_FLOAT
Float result;
int *dest = (int *)&result;
const int *src = (const int *)inPtr;
dest[0] = src[0];
dest[1] = src[1];
return result;
#else
return *(Float *)inPtr;
#endif
}
inline void StackContext::pushFloat(Float f)
{
SetFloatAligned(pointer, f);
pointer += sizeof(Float);
}
inline void StackContext::pushString(const String &s)
{
*(String *)pointer = s;
pointer += sizeof(String);
}
inline void StackContext::pushObject(Dynamic d)
{
*(hx::Object **)pointer = d.mPtr;
pointer += sizeof(hx::Object *);
}
inline void StackContext::returnFloat(Float f)
{
SetFloatAligned(frame, f);
}
inline void StackContext::returnString(const String &s)
{
*(String *)frame = s;
}
inline void StackContext::returnObject(Dynamic d)
{
*(hx::Object **)frame = d.mPtr;
}
inline hx::Object *StackContext::getThis(bool inCheckPtr)
{
#ifdef HXCPP_CHECK_POINTER
if (inCheckPtr)
{
if (!*(hx::Object **)frame) NullReference("This", false);
#ifdef HXCPP_GC_CHECK_POINTER
GCCheckPointer(*(hx::Object **)frame);
#endif
}
#endif
return *(hx::Object **)frame;
}
inline Float StackContext::getFloat(int inPos)
{
return GetFloatAligned(frame+inPos);
}
inline String StackContext::getString(int inPos)
{
return *(String *)(frame+inPos);
}
inline Dynamic StackContext::getObject(int inPos)
{
return *(hx::Object **)(frame+inPos);
}
enum SignatureChar
{
sigVoid = 'v',
sigBool = 'b',
sigInt = 'i',
sigFloat = 'f',
sigString = 's',
sigObject = 'o',
};
struct AutoStack
{
CppiaCtx *ctx;
unsigned char *pointer;
unsigned char *frame;
AutoStack(CppiaCtx *inCtx) : ctx(inCtx)
{
frame = ctx->frame;
pointer = ctx->pointer;
ctx->frame = pointer;
}
AutoStack(CppiaCtx *inCtx,unsigned char *inPointer) : ctx(inCtx)
{
frame = ctx->frame;
pointer = inPointer;
ctx->frame = pointer;
}
~AutoStack()
{
ctx->pointer = pointer;
ctx->frame = frame;
}
};
typedef hx::Object * (*ScriptableClassFactory)(void **inVTable,int inDataSize);
typedef hx::Object * (*ScriptableInterfaceFactory)(void **inVTable,::hx::Object *);
void ScriptableRegisterClass( String inName, int inBaseSize, ScriptNamedFunction *inFunctions, ScriptableClassFactory inFactory, ScriptFunction inConstruct);
#if (HXCPP_API_LEVEL >= 330)
void ScriptableRegisterInterface( String inName, ScriptNamedFunction *inFunctions, void *inInterfacePointers);
void ScriptableRegisterNameSlots(const char *inNames[], int inLength);
#else
void ScriptableRegisterInterface( String inName, ScriptNamedFunction *inFunctions,const hx::type_info *inType, ScriptableInterfaceFactory inFactory);
#endif
::String ScriptableToString(void *);
hx::Class ScriptableGetClass(void *);
int ScriptableGetType(void *);
void ScriptableMark(void *, hx::Object *, HX_MARK_PARAMS);
void ScriptableVisit(void *, hx::Object *, HX_VISIT_PARAMS);
bool ScriptableField(hx::Object *, const ::String &,hx::PropertyAccess inCallProp,Dynamic &outResult);
bool ScriptableField(hx::Object *, int inName,hx::PropertyAccess inCallProp,Float &outResult);
bool ScriptableField(hx::Object *, int inName,hx::PropertyAccess inCallProp,Dynamic &outResult);
void ScriptableGetFields(hx::Object *inObject, Array< ::String> &outFields);
bool ScriptableSetField(hx::Object *, const ::String &, Dynamic inValue,hx::PropertyAccess inCallProp, Dynamic &outValue);
class CppiaLoadedModule_obj : public ::hx::Object
{
public:
virtual void run() = 0;
virtual void boot() = 0;
virtual ::hx::Class resolveClass( ::String inName) = 0;
};
typedef ::hx::ObjectPtr<CppiaLoadedModule_obj> CppiaLoadedModule;
} // End namespace hx
void __scriptable_load_neko(String inName);
void __scriptable_load_cppia(String inCode);
::hx::CppiaLoadedModule __scriptable_cppia_from_string(String inCode);
::hx::CppiaLoadedModule __scriptable_cppia_from_data(Array<unsigned char> inBytes);
void __scriptable_load_neko_bytes(Array<unsigned char> inBytes);
void __scriptable_load_abc(Array<unsigned char> inBytes);
#if (HXCPP_API_LEVEL >= 330)
#define HX_SCRIPTABLE_REGISTER_INTERFACE(name,class) \
hx::ScriptableRegisterInterface( HX_CSTRING(name), __scriptableFunctions, & class##_scriptable )
#else
#define HX_SCRIPTABLE_REGISTER_INTERFACE(name,class) \
hx::ScriptableRegisterInterface( HX_CSTRING(name), __scriptableFunctions, &typeid(class), class##__scriptable::__script_create )
#endif
#define HX_SCRIPTABLE_REGISTER_CLASS(name,class) \
hx::ScriptableRegisterClass( HX_CSTRING(name), (int)offsetof(class##__scriptable,__scriptVTable) + sizeof(void *), __scriptableFunctions, class##__scriptable::__script_create, class##__scriptable::__script_construct )
#ifdef HXCPP_VISIT_ALLOCS
#define SCRIPTABLE_VISIT_FUNCTION \
void __Visit(HX_VISIT_PARAMS) { super::__Visit(HX_VISIT_ARG); hx::ScriptableVisit(__scriptVTable[-1],this,HX_VISIT_ARG); }
#else
#define SCRIPTABLE_VISIT_FUNCTION
#endif
#define HX_DEFINE_SCRIPTABLE(ARG_LIST) \
inline void *operator new( size_t inSize, int inExtraDataSize ) \
{ \
return hx::InternalNew(inSize + inExtraDataSize,true); \
} \
inline void operator delete(void *,int) {} \
public: \
void **__scriptVTable; \
static hx::Object *__script_create(void **inVTable, int inExtra) { \
__ME *result = new (inExtra) __ME(); \
result->__scriptVTable = inVTable; \
return result; } \
void ** __GetScriptVTable() { return __scriptVTable; } \
::String toString() { if (__scriptVTable[0] ) \
{ hx::CppiaCtx *ctx = hx::CppiaCtx::getCurrent(); hx::AutoStack a(ctx); ctx->pushObject(this); return ctx->runString(__scriptVTable[0]); } \
else return __superString::toString(); } \
::String __ToString() const { return hx::ScriptableToString(__scriptVTable[-1]); } \
hx::Class __GetClass() const { return hx::ScriptableGetClass(__scriptVTable[-1]); } \
int __GetType() const { return hx::ScriptableGetType(__scriptVTable[-1]); } \
void __Mark(HX_MARK_PARAMS) { super::__Mark(HX_MARK_ARG); hx::ScriptableMark(__scriptVTable[-1],this,HX_MARK_ARG); } \
SCRIPTABLE_VISIT_FUNCTION
#define HX_DEFINE_SCRIPTABLE_INTERFACE \
void **__scriptVTable; \
Dynamic mDelegate; \
hx::Object *__GetRealObject() { return mDelegate.mPtr; } \
SCRIPTABLE_VISIT_FUNCTION \
void ** __GetScriptVTable() { return __scriptVTable; } \
public: \
static hx::Object *__script_create(void **inVTable,hx::Object *inDelegate) { \
__ME *result = new __ME(); \
result->__scriptVTable = inVTable; \
result->mDelegate = inDelegate; \
return result; }
#define HX_DEFINE_SCRIPTABLE_DYNAMIC \
\
hx::Val __Field(const ::String &inName,hx::PropertyAccess inCallProp) \
{ Dynamic result; if (hx::ScriptableField(this,inName,inCallProp,result)) return result; return super::__Field(inName,inCallProp); } \
Float __INumField(int inFieldID) \
{ Float result; if (hx::ScriptableField(this,inFieldID,hx::paccAlways,result)) return result; return super::__INumField(inFieldID); } \
Dynamic __IField(int inFieldID) \
{ Dynamic result; if (hx::ScriptableField(this,inFieldID,hx::paccAlways,result)) return result; return super::__IField(inFieldID); } \
hx::Val __SetField(const ::String &inName,const hx::Val &inValue,hx::PropertyAccess inCallProp) \
{ \
Dynamic value; \
if (hx::ScriptableSetField(this, inName, inValue,inCallProp,value)) \
return value; \
return super::__SetField(inName,inValue,inCallProp); \
} \
void __GetFields(Array< ::String> &outFields) \
{ super::__GetFields(outFields); hx::ScriptableGetFields(this,outFields); }
#endif