Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/hx/Scriptable.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ class CppiaLoadedModule_obj : public ::hx::Object
virtual void run() = 0;
virtual void boot() = 0;
virtual ::hx::Class resolveClass( ::String inName) = 0;
virtual void unload() { }
};
typedef ::hx::ObjectPtr<CppiaLoadedModule_obj> CppiaLoadedModule;

Expand Down
81 changes: 71 additions & 10 deletions src/hx/cppia/Cppia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1696,6 +1696,22 @@ inline void SetVal(String &out, const T &value) { out = String(value); }
template<typename T>
inline void SetVal(Dynamic &out, const T &value) { out = value; }

struct SuperVTableSwap
{
void ***location;
void **restore;

SuperVTableSwap(hx::Object *inObj, int inOffset, void **inVTable, void **inSuper)
{
location = (void ***)((char *)inObj + inOffset);
restore = inVTable;
*location = inSuper;
}

~SuperVTableSwap() { *location = restore; }
};


//template<typname RETURN>
struct CallHaxe : public CppiaExpr
{
Expand All @@ -1705,15 +1721,44 @@ struct CallHaxe : public CppiaExpr
ExprType returnType;
bool isStatic;
bool isSuper;
int superSlot;

CallHaxe(CppiaExpr *inSrc,ScriptNamedFunction inFunction, CppiaExpr *inThis, Expressions &ioArgs, bool inIsStatic=false, bool inIsSuper = false )
CallHaxe(CppiaExpr *inSrc,ScriptNamedFunction inFunction, CppiaExpr *inThis, Expressions &ioArgs, bool inIsStatic=false, bool inIsSuper = false, int inSuperSlot = -1 )
: CppiaExpr(inSrc)
{
args.swap(ioArgs);
thisExpr = inThis;
function = inFunction;
isStatic = inIsStatic;
isSuper = inIsSuper;
superSlot = inSuperSlot;
}

void invoke(CppiaCtx *ctx, hx::Object *thisVal)
{
if (superSlot >= 0 && thisVal)
{
void **vtable = thisVal->__GetScriptVTable();

if (vtable)
{
CppiaClassInfo *info = (CppiaClassInfo *)vtable[-1];
void **super = info ? info->getSuperVTable(superSlot) : 0;
int offset = info ? info->getScriptVTableOffset() : 0;

if (super && *(void ***)((char *)thisVal + offset) == vtable)
{
SuperVTableSwap swap(thisVal, offset, vtable, super);
function.execute(ctx);
return;
}
}
}

if (isSuper)
function.superExecute(ctx);
else
function.execute(ctx);
}
ExprType getType() HXCPP_OVERRIDE { return returnType; }
CppiaExpr *link(CppiaModule &inModule) HXCPP_OVERRIDE
Expand Down Expand Up @@ -1762,7 +1807,8 @@ struct CallHaxe : public CppiaExpr
void run(CppiaCtx *ctx,T &outValue)
{
unsigned char *pointer = ctx->pointer;
ctx->pushObject(isStatic ? 0: thisExpr ? thisExpr->runObject(ctx) : ctx->getThis(false));
hx::Object *thisVal = isStatic ? 0: thisExpr ? thisExpr->runObject(ctx) : ctx->getThis(false);
ctx->pushObject(thisVal);
BCR_VCHECK;

const char *s = function.signature+1;
Expand All @@ -1783,10 +1829,7 @@ struct CallHaxe : public CppiaExpr
}

AutoStack a(ctx,pointer);
if (isSuper)
function.superExecute(ctx);
else
function.execute(ctx);
invoke(ctx, thisVal);

#ifdef DEBUG_RETURN_TYPE
gLastRet = returnType;
Expand Down Expand Up @@ -1851,6 +1894,13 @@ struct CallHaxe : public CppiaExpr
CATCH_NATIVE
}

static void SLJIT_CALL tryCallHaxeSuper( CallHaxe *expr, StackContext *ctx )
{
TRY_NATIVE
expr->invoke(ctx, ctx->getThis(false));
CATCH_NATIVE
}

void genCode(CppiaCompiler *compiler, const JitVal &inDest,ExprType destType) HXCPP_OVERRIDE
{
int framePos = compiler->getCurrentFrameSize();
Expand Down Expand Up @@ -1893,8 +1943,15 @@ struct CallHaxe : public CppiaExpr
// Store new frame in context ...
compiler->add( sJitCtxFrame, sJitFrame.as(jtPointer), JitVal(framePos) );

void *func = (void *) ( isSuper ? function.superExecute : function.execute);
compiler->callNative( (void *)tryCallHaxe, JitVal(func), sJitCtx );
if (superSlot >= 0)
{
compiler->callNative( (void *)tryCallHaxeSuper, JitVal((void *)this), sJitCtx );
}
else
{
void *func = (void *) ( isSuper ? function.superExecute : function.execute);
compiler->callNative( (void *)tryCallHaxe, JitVal(func), sJitCtx );
}

genFunctionResult(compiler, inDest, destType, returnType, isBoolInt());
}
Expand Down Expand Up @@ -3356,11 +3413,15 @@ struct CallMember : public CppiaExpr
ScriptNamedFunction func = type->haxeBase->findFunction(field.utf8_str());
if (func.signature)
{
if (callSuperField && !func.superExecute)
int superSlot = -1;
if (callSuperField && inModule.linkingClass)
superSlot = inModule.linkingClass->findFunctionSlot(fieldId);

if (callSuperField && superSlot < 0 && !func.superExecute)
CPPIALOG("Warning - calling super host '%s' from cppia can lead to infinte recursion\n", field.utf8_str());

//CPPIALOG(" found function %s\n", func.signature );
replace = new CallHaxe( this, func, thisExpr, args, false, callSuperField && func.superExecute);
replace = new CallHaxe( this, func, thisExpr, args, false, callSuperField && func.superExecute, superSlot);
}
}

Expand Down
29 changes: 29 additions & 0 deletions src/hx/cppia/Cppia.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ typedef std::map<int,CppiaStackVar *> CppiaStackVarMap;

extern String sInvalidArgCount;

void _hx_cppia_track_expr(void *inExpr);
void _hx_cppia_untrack_expr(void *inExpr);

struct CppiaExpr
{
int line;
Expand All @@ -161,6 +164,18 @@ struct CppiaExpr
const char *functionName;
int haxeTypeId;

void *operator new(size_t inSize)
{
void *result = ::operator new(inSize);
_hx_cppia_track_expr(result);
return result;
}

void operator delete(void *inPtr)
{
_hx_cppia_untrack_expr(inPtr);
::operator delete(inPtr);
}

CppiaExpr() : line(0), filename(0), className(0), functionName(0)
{
Expand Down Expand Up @@ -283,6 +298,8 @@ struct ScriptCallable : public CppiaDynamicExpr
int captureSize;


void deactivate();

ScriptCallable(CppiaStream &stream);
ScriptCallable(CppiaExpr *inBody);
ScriptCallable(CppiaModule &inModule,ScriptNamedFunction *inFunction);
Expand Down Expand Up @@ -372,7 +389,10 @@ class CppiaModule
std::vector< TypeData * > types;
std::vector< CppiaClassInfo * > classes;
std::vector< CppiaExpr * > markable;

hx::UnorderedSet< CppiaExpr * > allExprs;
hx::UnorderedSet<int> allFileIds;

typedef std::map< std::string, int > InterfaceSlots;
InterfaceSlots interfaceSlots;

Expand All @@ -384,9 +404,12 @@ class CppiaModule

ScriptCallable *main;

bool unloaded;

CppiaModule();
~CppiaModule();

void unload();
void link();
void compile();
void setDebug(CppiaExpr *outExpr, int inFileId, int inLine);
Expand Down Expand Up @@ -650,7 +673,10 @@ class CppiaClassInfo
bool containsPointers;
int dynamicMapOffset;
int interfaceSlotSize;
int vtableSlotCount;
bool unloaded;
void **vtable;
std::vector<void **> superVtables;
std::string name;
std::map<int, void *> interfaceScriptTables;
std::vector<ScriptNamedFunction *> nativeInterfaceFunctions;
Expand Down Expand Up @@ -704,6 +730,7 @@ class CppiaClassInfo

void link();
void linkTypes();
void deactivate();


inline bool isNativeProperty(const String &inString);
Expand All @@ -730,6 +757,8 @@ class CppiaClassInfo

void *getHaxeBaseVTable();
int getScriptVTableOffset();
void **getSuperVTable(int inSlot);
void freeSuperVTables();

Dynamic getStaticValue(const String &inName,hx::PropertyAccess inCallProp);
bool hasStaticValue(const String &inName);
Expand Down
Loading
Loading