|
|
@@ -62,7 +62,7 @@ const int RESERVE_STACK = 2*AS_PTR_SIZE;
|
|
|
const int CALLSTACK_FRAME_SIZE = 5;
|
|
|
|
|
|
|
|
|
-#ifdef AS_DEBUG
|
|
|
+#if defined(AS_DEBUG) && defined(AS_DEBUG_STATS)
|
|
|
// Instruction statistics
|
|
|
int instrCount[256];
|
|
|
|
|
|
@@ -79,33 +79,36 @@ public:
|
|
|
|
|
|
~asCDebugStats()
|
|
|
{
|
|
|
-/*
|
|
|
// This code writes out some statistics for the VM.
|
|
|
// It's useful for determining what needs to be optimized.
|
|
|
|
|
|
_mkdir("AS_DEBUG");
|
|
|
- FILE *f = fopen("AS_DEBUG/total.txt", "at");
|
|
|
+ #if _MSC_VER >= 1500
|
|
|
+ FILE *f;
|
|
|
+ fopen_s(&f, "AS_DEBUG/total.txt", "at");
|
|
|
+ #else
|
|
|
+ FILE *f = fopen("AS_DEBUG/total.txt", "at");
|
|
|
+ #endif
|
|
|
if( f )
|
|
|
{
|
|
|
// Output instruction statistics
|
|
|
fprintf(f, "\nTotal count\n");
|
|
|
int n;
|
|
|
- for( n = 0; n < BC_MAXBYTECODE; n++ )
|
|
|
+ for( n = 0; n < asBC_MAXBYTECODE; n++ )
|
|
|
{
|
|
|
- if( bcName[n].name && instrCount[n] > 0 )
|
|
|
- fprintf(f, "%-10.10s : %.0f\n", bcName[n].name, instrCount[n]);
|
|
|
+ if( asBCInfo[n].name && instrCount[n] > 0 )
|
|
|
+ fprintf(f, "%-10.10s : %.0f\n", asBCInfo[n].name, instrCount[n]);
|
|
|
}
|
|
|
|
|
|
fprintf(f, "\nNever executed\n");
|
|
|
- for( n = 0; n < BC_MAXBYTECODE; n++ )
|
|
|
+ for( n = 0; n < asBC_MAXBYTECODE; n++ )
|
|
|
{
|
|
|
- if( bcName[n].name && instrCount[n] == 0 )
|
|
|
- fprintf(f, "%-10.10s\n", bcName[n].name);
|
|
|
+ if( asBCInfo[n].name && instrCount[n] == 0 )
|
|
|
+ fprintf(f, "%-10.10s\n", asBCInfo[n].name);
|
|
|
}
|
|
|
|
|
|
fclose(f);
|
|
|
}
|
|
|
-*/
|
|
|
}
|
|
|
|
|
|
double instrCount[256];
|
|
|
@@ -142,7 +145,7 @@ void asPopActiveContext(asIScriptContext *ctx)
|
|
|
|
|
|
asCContext::asCContext(asCScriptEngine *engine, bool holdRef)
|
|
|
{
|
|
|
-#ifdef AS_DEBUG
|
|
|
+#if defined(AS_DEBUG) && defined(AS_DEBUG_STATS)
|
|
|
memset(instrCount, 0, sizeof(instrCount));
|
|
|
|
|
|
memset(instrCount2, 0, sizeof(instrCount2));
|
|
|
@@ -162,6 +165,7 @@ asCContext::asCContext(asCScriptEngine *engine, bool holdRef)
|
|
|
isStackMemoryNotAllocated = false;
|
|
|
|
|
|
currentFunction = 0;
|
|
|
+ callingSystemFunction = 0;
|
|
|
regs.objectRegister = 0;
|
|
|
initialFunction = 0;
|
|
|
|
|
|
@@ -262,6 +266,12 @@ int asCContext::Prepare(int funcId)
|
|
|
return Prepare(engine->GetFunctionById(funcId));
|
|
|
}
|
|
|
|
|
|
+// interface
|
|
|
+asIScriptFunction *asCContext::GetSystemFunction()
|
|
|
+{
|
|
|
+ return callingSystemFunction;
|
|
|
+}
|
|
|
+
|
|
|
// interface
|
|
|
int asCContext::Prepare(asIScriptFunction *func)
|
|
|
{
|
|
|
@@ -336,7 +346,6 @@ int asCContext::Prepare(asIScriptFunction *func)
|
|
|
{
|
|
|
exceptionLine = -1;
|
|
|
exceptionFunction = 0;
|
|
|
- isCallingSystemFunction = false;
|
|
|
doAbort = false;
|
|
|
doSuspend = false;
|
|
|
regs.doProcessSuspend = lineCallback;
|
|
|
@@ -372,7 +381,7 @@ int asCContext::Prepare(asIScriptFunction *func)
|
|
|
if( !currentFunction->objVariableIsOnHeap[n] ) continue;
|
|
|
|
|
|
int pos = currentFunction->objVariablePos[n];
|
|
|
- *(size_t*)®s.stackFramePointer[-pos] = 0;
|
|
|
+ *(asPWORD*)®s.stackFramePointer[-pos] = 0;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
@@ -509,7 +518,7 @@ void *asCContext::GetReturnObject()
|
|
|
if( !dt->IsObject() ) return 0;
|
|
|
|
|
|
if( dt->IsReference() )
|
|
|
- return *(void**)(size_t)regs.valueRegister;
|
|
|
+ return *(void**)(asPWORD)regs.valueRegister;
|
|
|
else
|
|
|
{
|
|
|
if( initialFunction->DoesReturnOnStack() )
|
|
|
@@ -554,7 +563,7 @@ int asCContext::SetObject(void *obj)
|
|
|
return asERROR;
|
|
|
}
|
|
|
|
|
|
- *(size_t*)®s.stackFramePointer[0] = (size_t)obj;
|
|
|
+ *(asPWORD*)®s.stackFramePointer[0] = (asPWORD)obj;
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
@@ -849,7 +858,7 @@ int asCContext::SetArgAddress(asUINT arg, void *value)
|
|
|
offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
|
|
|
|
|
|
// Set the value
|
|
|
- *(size_t*)(®s.stackFramePointer[offset]) = (size_t)value;
|
|
|
+ *(asPWORD*)(®s.stackFramePointer[offset]) = (asPWORD)value;
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
@@ -902,7 +911,7 @@ int asCContext::SetArgObject(asUINT arg, void *obj)
|
|
|
offset += initialFunction->parameterTypes[n].GetSizeOnStackDWords();
|
|
|
|
|
|
// Set the value
|
|
|
- *(size_t*)(®s.stackFramePointer[offset]) = (size_t)obj;
|
|
|
+ *(asPWORD*)(®s.stackFramePointer[offset]) = (asPWORD)obj;
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
@@ -941,10 +950,10 @@ void *asCContext::GetAddressOfArg(asUINT arg)
|
|
|
|
|
|
int asCContext::Abort()
|
|
|
{
|
|
|
- // TODO: multithread: Make thread safe
|
|
|
-
|
|
|
if( engine == 0 ) return asERROR;
|
|
|
|
|
|
+ // TODO: multithread: Make thread safe. There is a chance that the status
|
|
|
+ // changes to something else after being set to ABORTED here.
|
|
|
if( status == asEXECUTION_SUSPENDED )
|
|
|
status = asEXECUTION_ABORTED;
|
|
|
|
|
|
@@ -992,7 +1001,7 @@ int asCContext::Execute()
|
|
|
// The currentFunction is a virtual method
|
|
|
|
|
|
// Determine the true function from the object
|
|
|
- asCScriptObject *obj = *(asCScriptObject**)(size_t*)regs.stackFramePointer;
|
|
|
+ asCScriptObject *obj = *(asCScriptObject**)(asPWORD*)regs.stackFramePointer;
|
|
|
if( obj == 0 )
|
|
|
{
|
|
|
SetInternalException(TXT_NULL_POINTER_ACCESS);
|
|
|
@@ -1041,7 +1050,7 @@ int asCContext::Execute()
|
|
|
for( asUINT n = 0; n < currentFunction->objVariablePos.GetLength(); n++ )
|
|
|
{
|
|
|
int pos = currentFunction->objVariablePos[n];
|
|
|
- *(size_t*)®s.stackFramePointer[-pos] = 0;
|
|
|
+ *(asPWORD*)®s.stackFramePointer[-pos] = 0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -1076,20 +1085,24 @@ int asCContext::Execute()
|
|
|
asPopActiveContext((asIScriptContext *)this);
|
|
|
|
|
|
|
|
|
-#ifdef AS_DEBUG
|
|
|
-/*
|
|
|
+#if defined(AS_DEBUG) && defined(AS_DEBUG_STATS)
|
|
|
// Output instruction statistics
|
|
|
// This is useful for determining what needs to be optimized.
|
|
|
|
|
|
_mkdir("AS_DEBUG");
|
|
|
- FILE *f = fopen("AS_DEBUG/stats.txt", "at");
|
|
|
+ #if _MSC_VER >= 1500
|
|
|
+ FILE *f;
|
|
|
+ fopen_s(&f, "AS_DEBUG/stats.txt", "at");
|
|
|
+ #else
|
|
|
+ FILE *f = fopen("AS_DEBUG/stats.txt", "at");
|
|
|
+ #endif
|
|
|
fprintf(f, "\n");
|
|
|
asQWORD total = 0;
|
|
|
int n;
|
|
|
for( n = 0; n < 256; n++ )
|
|
|
{
|
|
|
- if( bcName[n].name && instrCount[n] )
|
|
|
- fprintf(f, "%-10.10s : %d\n", bcName[n].name, instrCount[n]);
|
|
|
+ if( asBCInfo[n].name && instrCount[n] )
|
|
|
+ fprintf(f, "%-10.10s : %d\n", asBCInfo[n].name, instrCount[n]);
|
|
|
|
|
|
total += instrCount[n];
|
|
|
}
|
|
|
@@ -1099,17 +1112,16 @@ int asCContext::Execute()
|
|
|
fprintf(f, "\n");
|
|
|
for( n = 0; n < 256; n++ )
|
|
|
{
|
|
|
- if( bcName[n].name )
|
|
|
+ if( asBCInfo[n].name )
|
|
|
{
|
|
|
for( int m = 0; m < 256; m++ )
|
|
|
{
|
|
|
if( instrCount2[n][m] )
|
|
|
- fprintf(f, "%-10.10s, %-10.10s : %d\n", bcName[n].name, bcName[m].name, instrCount2[n][m]);
|
|
|
+ fprintf(f, "%-10.10s, %-10.10s : %d\n", asBCInfo[n].name, asBCInfo[m].name, instrCount2[n][m]);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
fclose(f);
|
|
|
-*/
|
|
|
#endif
|
|
|
|
|
|
if( status == asEXECUTION_FINISHED )
|
|
|
@@ -1146,14 +1158,14 @@ void asCContext::PushCallState()
|
|
|
// for all the compiler knows. So introducing the local variable s, which is never referred to by
|
|
|
// its address we avoid this issue.
|
|
|
|
|
|
- size_t s[5];
|
|
|
- s[0] = (size_t)regs.stackFramePointer;
|
|
|
- s[1] = (size_t)currentFunction;
|
|
|
- s[2] = (size_t)regs.programPointer;
|
|
|
- s[3] = (size_t)regs.stackPointer;
|
|
|
+ asPWORD s[5];
|
|
|
+ s[0] = (asPWORD)regs.stackFramePointer;
|
|
|
+ s[1] = (asPWORD)currentFunction;
|
|
|
+ s[2] = (asPWORD)regs.programPointer;
|
|
|
+ s[3] = (asPWORD)regs.stackPointer;
|
|
|
s[4] = stackIndex;
|
|
|
|
|
|
- size_t *tmp = callStack.AddressOf() + callStack.GetLength() - CALLSTACK_FRAME_SIZE;
|
|
|
+ asPWORD *tmp = callStack.AddressOf() + callStack.GetLength() - CALLSTACK_FRAME_SIZE;
|
|
|
tmp[0] = s[0];
|
|
|
tmp[1] = s[1];
|
|
|
tmp[2] = s[2];
|
|
|
@@ -1164,8 +1176,8 @@ void asCContext::PushCallState()
|
|
|
void asCContext::PopCallState()
|
|
|
{
|
|
|
// See comments in PushCallState about pointer aliasing and data cache trashing
|
|
|
- size_t *tmp = callStack.AddressOf() + callStack.GetLength() - CALLSTACK_FRAME_SIZE;
|
|
|
- size_t s[5];
|
|
|
+ asPWORD *tmp = callStack.AddressOf() + callStack.GetLength() - CALLSTACK_FRAME_SIZE;
|
|
|
+ asPWORD s[5];
|
|
|
s[0] = tmp[0];
|
|
|
s[1] = tmp[1];
|
|
|
s[2] = tmp[2];
|
|
|
@@ -1197,7 +1209,7 @@ asIScriptFunction *asCContext::GetFunction(asUINT stackLevel)
|
|
|
|
|
|
if( stackLevel == 0 ) return currentFunction;
|
|
|
|
|
|
- size_t *s = callStack.AddressOf() + (GetCallstackSize() - stackLevel - 1)*CALLSTACK_FRAME_SIZE;
|
|
|
+ asPWORD *s = callStack.AddressOf() + (GetCallstackSize() - stackLevel - 1)*CALLSTACK_FRAME_SIZE;
|
|
|
asCScriptFunction *func = (asCScriptFunction*)s[1];
|
|
|
|
|
|
return func;
|
|
|
@@ -1217,7 +1229,7 @@ int asCContext::GetLineNumber(asUINT stackLevel, int *column, const char **secti
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- size_t *s = callStack.AddressOf() + (GetCallstackSize()-stackLevel-1)*CALLSTACK_FRAME_SIZE;
|
|
|
+ asPWORD *s = callStack.AddressOf() + (GetCallstackSize()-stackLevel-1)*CALLSTACK_FRAME_SIZE;
|
|
|
func = (asCScriptFunction*)s[1];
|
|
|
bytePos = (asDWORD*)s[2];
|
|
|
}
|
|
|
@@ -1291,14 +1303,14 @@ void asCContext::CallScriptFunction(asCScriptFunction *func)
|
|
|
if( !currentFunction->objVariableIsOnHeap[n] ) continue;
|
|
|
|
|
|
int pos = currentFunction->objVariablePos[n];
|
|
|
- *(size_t*)®s.stackFramePointer[-pos] = 0;
|
|
|
+ *(asPWORD*)®s.stackFramePointer[-pos] = 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void asCContext::CallInterfaceMethod(asCScriptFunction *func)
|
|
|
{
|
|
|
// Resolve the interface method using the current script type
|
|
|
- asCScriptObject *obj = *(asCScriptObject**)(size_t*)regs.stackPointer;
|
|
|
+ asCScriptObject *obj = *(asCScriptObject**)(asPWORD*)regs.stackPointer;
|
|
|
if( obj == 0 )
|
|
|
{
|
|
|
SetInternalException(TXT_NULL_POINTER_ACCESS);
|
|
|
@@ -1358,13 +1370,14 @@ void asCContext::ExecuteNext()
|
|
|
{
|
|
|
|
|
|
#ifdef AS_DEBUG
|
|
|
+#ifdef AS_DEBUG_STATS
|
|
|
++stats.instrCount[*(asBYTE*)l_bc];
|
|
|
|
|
|
++instrCount[*(asBYTE*)l_bc];
|
|
|
|
|
|
++instrCount2[lastBC][*(asBYTE*)l_bc];
|
|
|
lastBC = *(asBYTE*)l_bc;
|
|
|
-
|
|
|
+#endif
|
|
|
// Used to verify that the size of the instructions are correct
|
|
|
asDWORD *old = l_bc;
|
|
|
#endif
|
|
|
@@ -1409,16 +1422,16 @@ void asCContext::ExecuteNext()
|
|
|
// Push the address of a variable on the stack
|
|
|
case asBC_PSF:
|
|
|
l_sp -= AS_PTR_SIZE;
|
|
|
- *(asPTRWORD*)l_sp = (asPTRWORD)size_t(l_fp - asBC_SWORDARG0(l_bc));
|
|
|
+ *(asPWORD*)l_sp = asPWORD(l_fp - asBC_SWORDARG0(l_bc));
|
|
|
l_bc++;
|
|
|
break;
|
|
|
|
|
|
// Swap the top 2 pointers on the stack
|
|
|
case asBC_SwapPtr:
|
|
|
{
|
|
|
- asPTRWORD p = (asPTRWORD)*l_sp;
|
|
|
- *(asPTRWORD*)l_sp = *(asPTRWORD*)(l_sp+AS_PTR_SIZE);
|
|
|
- *(asDWORD*)(l_sp+AS_PTR_SIZE) = p;
|
|
|
+ asPWORD p = (asPWORD)*l_sp;
|
|
|
+ *(asPWORD*)l_sp = *(asPWORD*)(l_sp+AS_PTR_SIZE);
|
|
|
+ *(asPWORD*)(l_sp+AS_PTR_SIZE) = p;
|
|
|
l_bc++;
|
|
|
}
|
|
|
break;
|
|
|
@@ -1448,14 +1461,14 @@ void asCContext::ExecuteNext()
|
|
|
// Push the dword value of a global variable on the stack
|
|
|
case asBC_PshG4:
|
|
|
--l_sp;
|
|
|
- *l_sp = *(asDWORD*)(size_t)asBC_PTRARG(l_bc);
|
|
|
+ *l_sp = *(asDWORD*)asBC_PTRARG(l_bc);
|
|
|
l_bc += 1 + AS_PTR_SIZE;
|
|
|
break;
|
|
|
|
|
|
// Load the address of a global variable in the register, then
|
|
|
// copy the value of the global variable into a local variable
|
|
|
case asBC_LdGRdR4:
|
|
|
- *(void**)®s.valueRegister = (void*)(size_t)asBC_PTRARG(l_bc);
|
|
|
+ *(void**)®s.valueRegister = (void*)asBC_PTRARG(l_bc);
|
|
|
*(l_fp - asBC_SWORDARG0(l_bc)) = **(asDWORD**)®s.valueRegister;
|
|
|
l_bc += 1+AS_PTR_SIZE;
|
|
|
break;
|
|
|
@@ -1877,8 +1890,8 @@ void asCContext::ExecuteNext()
|
|
|
|
|
|
case asBC_COPY:
|
|
|
{
|
|
|
- void *d = (void*)*(size_t*)l_sp; l_sp += AS_PTR_SIZE;
|
|
|
- void *s = (void*)*(size_t*)l_sp;
|
|
|
+ void *d = (void*)*(asPWORD*)l_sp; l_sp += AS_PTR_SIZE;
|
|
|
+ void *s = (void*)*(asPWORD*)l_sp;
|
|
|
if( s == 0 || d == 0 )
|
|
|
{
|
|
|
// Need to move the values back to the context
|
|
|
@@ -1893,7 +1906,7 @@ void asCContext::ExecuteNext()
|
|
|
memcpy(d, s, asBC_WORDARG0(l_bc)*4);
|
|
|
|
|
|
// replace the pointer on the stack with the lvalue
|
|
|
- *(size_t**)l_sp = (size_t*)d;
|
|
|
+ *(asPWORD**)l_sp = (asPWORD*)d;
|
|
|
}
|
|
|
l_bc += 2;
|
|
|
break;
|
|
|
@@ -1906,13 +1919,13 @@ void asCContext::ExecuteNext()
|
|
|
|
|
|
case asBC_PshVPtr:
|
|
|
l_sp -= AS_PTR_SIZE;
|
|
|
- *(asPTRWORD*)l_sp = *(asPTRWORD*)(l_fp - asBC_SWORDARG0(l_bc));
|
|
|
+ *(asPWORD*)l_sp = *(asPWORD*)(l_fp - asBC_SWORDARG0(l_bc));
|
|
|
l_bc++;
|
|
|
break;
|
|
|
|
|
|
case asBC_RDSPtr:
|
|
|
// Pop an address from the stack, read a pointer from that address and push it on the stack
|
|
|
- *(asPTRWORD*)l_sp = *(asPTRWORD*)*(size_t*)l_sp;
|
|
|
+ *(asPWORD*)l_sp = *(asPWORD*)*(asPWORD*)l_sp;
|
|
|
l_bc++;
|
|
|
break;
|
|
|
|
|
|
@@ -1997,14 +2010,14 @@ void asCContext::ExecuteNext()
|
|
|
break;
|
|
|
|
|
|
case asBC_PopRPtr:
|
|
|
- *(asPTRWORD*)®s.valueRegister = *(asPTRWORD*)l_sp;
|
|
|
+ *(asPWORD*)®s.valueRegister = *(asPWORD*)l_sp;
|
|
|
l_sp += AS_PTR_SIZE;
|
|
|
l_bc++;
|
|
|
break;
|
|
|
|
|
|
case asBC_PshRPtr:
|
|
|
l_sp -= AS_PTR_SIZE;
|
|
|
- *(asPTRWORD*)l_sp = *(asPTRWORD*)®s.valueRegister;
|
|
|
+ *(asPWORD*)l_sp = *(asPWORD*)®s.valueRegister;
|
|
|
l_bc++;
|
|
|
break;
|
|
|
|
|
|
@@ -2015,7 +2028,7 @@ void asCContext::ExecuteNext()
|
|
|
// Push the string pointer on the stack
|
|
|
const asCString &b = engine->GetConstantString(w);
|
|
|
l_sp -= AS_PTR_SIZE;
|
|
|
- *(asPTRWORD*)l_sp = (asPTRWORD)(size_t)b.AddressOf();
|
|
|
+ *(asPWORD*)l_sp = (asPWORD)b.AddressOf();
|
|
|
// Push the string length on the stack
|
|
|
--l_sp;
|
|
|
*l_sp = (asDWORD)b.GetLength();
|
|
|
@@ -2132,7 +2145,7 @@ void asCContext::ExecuteNext()
|
|
|
|
|
|
case asBC_ALLOC:
|
|
|
{
|
|
|
- asCObjectType *objType = (asCObjectType*)(size_t)asBC_PTRARG(l_bc);
|
|
|
+ asCObjectType *objType = (asCObjectType*)asBC_PTRARG(l_bc);
|
|
|
int func = asBC_INTARG(l_bc+AS_PTR_SIZE);
|
|
|
|
|
|
if( objType->flags & asOBJ_SCRIPT_OBJECT )
|
|
|
@@ -2146,12 +2159,12 @@ void asCContext::ExecuteNext()
|
|
|
// Call the constructor to initalize the memory
|
|
|
asCScriptFunction *f = engine->scriptFunctions[func];
|
|
|
|
|
|
- asDWORD **a = (asDWORD**)*(size_t*)(l_sp + f->GetSpaceNeededForArguments());
|
|
|
+ asDWORD **a = (asDWORD**)*(asPWORD*)(l_sp + f->GetSpaceNeededForArguments());
|
|
|
if( a ) *a = mem;
|
|
|
|
|
|
// Push the object pointer on the stack
|
|
|
l_sp -= AS_PTR_SIZE;
|
|
|
- *(size_t*)l_sp = (size_t)mem;
|
|
|
+ *(asPWORD*)l_sp = (asPWORD)mem;
|
|
|
|
|
|
l_bc += 2+AS_PTR_SIZE;
|
|
|
|
|
|
@@ -2188,7 +2201,7 @@ void asCContext::ExecuteNext()
|
|
|
}
|
|
|
|
|
|
// Pop the variable address from the stack
|
|
|
- asDWORD **a = (asDWORD**)*(size_t*)l_sp;
|
|
|
+ asDWORD **a = (asDWORD**)*(asPWORD*)l_sp;
|
|
|
l_sp += AS_PTR_SIZE;
|
|
|
if( a ) *a = mem;
|
|
|
|
|
|
@@ -2226,10 +2239,10 @@ void asCContext::ExecuteNext()
|
|
|
case asBC_FREE:
|
|
|
{
|
|
|
// Get the variable that holds the object handle/reference
|
|
|
- asPTRWORD *a = (asPTRWORD*)size_t(l_fp - asBC_SWORDARG0(l_bc));
|
|
|
+ asPWORD *a = (asPWORD*)asPWORD(l_fp - asBC_SWORDARG0(l_bc));
|
|
|
if( *a )
|
|
|
{
|
|
|
- asCObjectType *objType = (asCObjectType*)(size_t)asBC_PTRARG(l_bc);
|
|
|
+ asCObjectType *objType = (asCObjectType*)asBC_PTRARG(l_bc);
|
|
|
asSTypeBehaviour *beh = &objType->beh;
|
|
|
|
|
|
// Need to move the values back to the context as the called functions
|
|
|
@@ -2238,18 +2251,18 @@ void asCContext::ExecuteNext()
|
|
|
regs.stackPointer = l_sp;
|
|
|
regs.stackFramePointer = l_fp;
|
|
|
|
|
|
- if( beh->release )
|
|
|
+ if( objType->flags & asOBJ_REF )
|
|
|
{
|
|
|
- engine->CallObjectMethod((void*)(size_t)*a, beh->release);
|
|
|
+ asASSERT( (objType->flags & asOBJ_NOCOUNT) || beh->release );
|
|
|
+ if( beh->release )
|
|
|
+ engine->CallObjectMethod((void*)(asPWORD)*a, beh->release);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if( beh->destruct )
|
|
|
- {
|
|
|
- engine->CallObjectMethod((void*)(size_t)*a, beh->destruct);
|
|
|
- }
|
|
|
+ engine->CallObjectMethod((void*)(asPWORD)*a, beh->destruct);
|
|
|
|
|
|
- engine->CallFree((void*)(size_t)*a);
|
|
|
+ engine->CallFree((void*)(asPWORD)*a);
|
|
|
}
|
|
|
|
|
|
// Clear the variable
|
|
|
@@ -2272,7 +2285,7 @@ void asCContext::ExecuteNext()
|
|
|
|
|
|
case asBC_STOREOBJ:
|
|
|
// Move the object pointer from the object register to the object variable
|
|
|
- *(size_t*)(l_fp - asBC_SWORDARG0(l_bc)) = size_t(regs.objectRegister);
|
|
|
+ *(asPWORD*)(l_fp - asBC_SWORDARG0(l_bc)) = asPWORD(regs.objectRegister);
|
|
|
regs.objectRegister = 0;
|
|
|
l_bc++;
|
|
|
break;
|
|
|
@@ -2280,10 +2293,10 @@ void asCContext::ExecuteNext()
|
|
|
case asBC_GETOBJ:
|
|
|
{
|
|
|
// Read variable index from location on stack
|
|
|
- size_t *a = (size_t*)(l_sp + asBC_WORDARG0(l_bc));
|
|
|
+ asPWORD *a = (asPWORD*)(l_sp + asBC_WORDARG0(l_bc));
|
|
|
asDWORD offset = *(asDWORD*)a;
|
|
|
// Move pointer from variable to the same location on the stack
|
|
|
- size_t *v = (size_t*)(l_fp - offset);
|
|
|
+ asPWORD *v = (asPWORD*)(l_fp - offset);
|
|
|
*a = *v;
|
|
|
// Clear variable
|
|
|
*v = 0;
|
|
|
@@ -2293,15 +2306,15 @@ void asCContext::ExecuteNext()
|
|
|
|
|
|
case asBC_REFCPY:
|
|
|
{
|
|
|
- asCObjectType *objType = (asCObjectType*)(size_t)asBC_PTRARG(l_bc);
|
|
|
+ asCObjectType *objType = (asCObjectType*)asBC_PTRARG(l_bc);
|
|
|
asSTypeBehaviour *beh = &objType->beh;
|
|
|
|
|
|
// Pop address of destination pointer from the stack
|
|
|
- void **d = (void**)*(size_t*)l_sp;
|
|
|
+ void **d = (void**)*(asPWORD*)l_sp;
|
|
|
l_sp += AS_PTR_SIZE;
|
|
|
|
|
|
// Read wanted pointer from the stack
|
|
|
- void *s = (void*)*(size_t*)l_sp;
|
|
|
+ void *s = (void*)*(asPWORD*)l_sp;
|
|
|
|
|
|
// Need to move the values back to the context as the called functions
|
|
|
// may use the debug interface to inspect the registers
|
|
|
@@ -2309,12 +2322,15 @@ void asCContext::ExecuteNext()
|
|
|
regs.stackPointer = l_sp;
|
|
|
regs.stackFramePointer = l_fp;
|
|
|
|
|
|
- // Release previous object held by destination pointer
|
|
|
- if( *d != 0 )
|
|
|
- engine->CallObjectMethod(*d, beh->release);
|
|
|
- // Increase ref counter of wanted object
|
|
|
- if( s != 0 )
|
|
|
- engine->CallObjectMethod(s, beh->addref);
|
|
|
+ if( !(objType->flags & asOBJ_NOCOUNT) )
|
|
|
+ {
|
|
|
+ // Release previous object held by destination pointer
|
|
|
+ if( *d != 0 )
|
|
|
+ engine->CallObjectMethod(*d, beh->release);
|
|
|
+ // Increase ref counter of wanted object
|
|
|
+ if( s != 0 )
|
|
|
+ engine->CallObjectMethod(s, beh->addref);
|
|
|
+ }
|
|
|
|
|
|
// Set the new object in the destination
|
|
|
*d = s;
|
|
|
@@ -2326,7 +2342,7 @@ void asCContext::ExecuteNext()
|
|
|
{
|
|
|
// Verify if the pointer on the stack is null
|
|
|
// This is used when validating a pointer that an operator will work on
|
|
|
- size_t a = *(size_t*)l_sp;
|
|
|
+ asPWORD a = *(asPWORD*)l_sp;
|
|
|
if( a == 0 )
|
|
|
{
|
|
|
regs.programPointer = l_bc;
|
|
|
@@ -2343,10 +2359,10 @@ void asCContext::ExecuteNext()
|
|
|
case asBC_GETOBJREF:
|
|
|
{
|
|
|
// Get the location on the stack where the reference will be placed
|
|
|
- size_t *a = (size_t*)(l_sp + asBC_WORDARG0(l_bc));
|
|
|
+ asPWORD *a = (asPWORD*)(l_sp + asBC_WORDARG0(l_bc));
|
|
|
|
|
|
// Replace the variable index with the object handle held in the variable
|
|
|
- *(size_t**)a = *(size_t**)(l_fp - *a);
|
|
|
+ *(asPWORD**)a = *(asPWORD**)(l_fp - *a);
|
|
|
}
|
|
|
l_bc++;
|
|
|
break;
|
|
|
@@ -2354,10 +2370,10 @@ void asCContext::ExecuteNext()
|
|
|
case asBC_GETREF:
|
|
|
{
|
|
|
// Get the location on the stack where the reference will be placed
|
|
|
- size_t *a = (size_t*)(l_sp + asBC_WORDARG0(l_bc));
|
|
|
+ asPWORD *a = (asPWORD*)(l_sp + asBC_WORDARG0(l_bc));
|
|
|
|
|
|
// Replace the variable index with the address of the variable
|
|
|
- *(size_t**)a = (size_t*)(l_fp - (int)*a);
|
|
|
+ *(asPWORD**)a = (asPWORD*)(l_fp - (int)*a);
|
|
|
}
|
|
|
l_bc++;
|
|
|
break;
|
|
|
@@ -2365,20 +2381,20 @@ void asCContext::ExecuteNext()
|
|
|
case asBC_PshNull:
|
|
|
// Push a null pointer on the stack
|
|
|
l_sp -= AS_PTR_SIZE;
|
|
|
- *(asPTRWORD*)l_sp = 0;
|
|
|
+ *(asPWORD*)l_sp = 0;
|
|
|
l_bc++;
|
|
|
break;
|
|
|
|
|
|
case asBC_ClrVPtr:
|
|
|
// Clear pointer variable
|
|
|
- *(asPTRWORD*)(l_fp - asBC_SWORDARG0(l_bc)) = 0;
|
|
|
+ *(asPWORD*)(l_fp - asBC_SWORDARG0(l_bc)) = 0;
|
|
|
l_bc++;
|
|
|
break;
|
|
|
|
|
|
case asBC_OBJTYPE:
|
|
|
// Push the object type on the stack
|
|
|
l_sp -= AS_PTR_SIZE;
|
|
|
- *(asPTRWORD*)l_sp = asBC_PTRARG(l_bc);
|
|
|
+ *(asPWORD*)l_sp = asBC_PTRARG(l_bc);
|
|
|
l_bc += 1+AS_PTR_SIZE;
|
|
|
break;
|
|
|
|
|
|
@@ -2400,7 +2416,7 @@ void asCContext::ExecuteNext()
|
|
|
break;
|
|
|
|
|
|
case asBC_ADDSi:
|
|
|
- *(size_t*)l_sp = size_t(asPTRWORD(*(size_t*)l_sp) + asBC_SWORDARG0(l_bc));
|
|
|
+ *(asPWORD*)l_sp = asPWORD(*(asPWORD*)l_sp) + asBC_SWORDARG0(l_bc);
|
|
|
l_bc += 2;
|
|
|
break;
|
|
|
|
|
|
@@ -2425,7 +2441,7 @@ void asCContext::ExecuteNext()
|
|
|
break;
|
|
|
|
|
|
case asBC_CpyVtoG4:
|
|
|
- *(asDWORD*)(size_t)asBC_PTRARG(l_bc) = *(asDWORD*)(l_fp - asBC_SWORDARG0(l_bc));
|
|
|
+ *(asDWORD*)asBC_PTRARG(l_bc) = *(asDWORD*)(l_fp - asBC_SWORDARG0(l_bc));
|
|
|
l_bc += 1 + AS_PTR_SIZE;
|
|
|
break;
|
|
|
|
|
|
@@ -2440,7 +2456,7 @@ void asCContext::ExecuteNext()
|
|
|
break;
|
|
|
|
|
|
case asBC_CpyGtoV4:
|
|
|
- *(asDWORD*)(l_fp - asBC_SWORDARG0(l_bc)) = *(asDWORD*)(size_t)asBC_PTRARG(l_bc);
|
|
|
+ *(asDWORD*)(l_fp - asBC_SWORDARG0(l_bc)) = *(asDWORD*)asBC_PTRARG(l_bc);
|
|
|
l_bc += 1 + AS_PTR_SIZE;
|
|
|
break;
|
|
|
|
|
|
@@ -2499,7 +2515,7 @@ void asCContext::ExecuteNext()
|
|
|
break;
|
|
|
|
|
|
case asBC_LDG:
|
|
|
- *(asPTRWORD*)®s.valueRegister = asBC_PTRARG(l_bc);
|
|
|
+ *(asPWORD*)®s.valueRegister = asBC_PTRARG(l_bc);
|
|
|
l_bc += 1+AS_PTR_SIZE;
|
|
|
break;
|
|
|
|
|
|
@@ -2510,23 +2526,26 @@ void asCContext::ExecuteNext()
|
|
|
|
|
|
case asBC_PGA:
|
|
|
l_sp -= AS_PTR_SIZE;
|
|
|
- *(asPTRWORD*)l_sp = asBC_PTRARG(l_bc);
|
|
|
+ *(asPWORD*)l_sp = asBC_PTRARG(l_bc);
|
|
|
l_bc += 1+AS_PTR_SIZE;
|
|
|
break;
|
|
|
|
|
|
case asBC_CmpPtr:
|
|
|
{
|
|
|
- asPTRWORD i = *(asPTRWORD*)(l_fp - asBC_SWORDARG0(l_bc)) - *(asPTRWORD*)(l_fp - asBC_SWORDARG1(l_bc));
|
|
|
- if( i == 0 ) *(int*)®s.valueRegister = 0;
|
|
|
- else if( i < 0 ) *(int*)®s.valueRegister = -1;
|
|
|
- else *(int*)®s.valueRegister = 1;
|
|
|
+ // TODO: optimize: This instruction should really just be an equals, and return true or false.
|
|
|
+ // The instruction is only used for is and !is tests anyway.
|
|
|
+ asPWORD p1 = *(asPWORD*)(l_fp - asBC_SWORDARG0(l_bc));
|
|
|
+ asPWORD p2 = *(asPWORD*)(l_fp - asBC_SWORDARG1(l_bc));
|
|
|
+ if( p1 == p2 ) *(int*)®s.valueRegister = 0;
|
|
|
+ else if( p1 < p2 ) *(int*)®s.valueRegister = -1;
|
|
|
+ else *(int*)®s.valueRegister = 1;
|
|
|
l_bc += 2;
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case asBC_VAR:
|
|
|
l_sp -= AS_PTR_SIZE;
|
|
|
- *(size_t*)l_sp = (size_t)asBC_SWORDARG0(l_bc);
|
|
|
+ *(asPWORD*)l_sp = (asPWORD)asBC_SWORDARG0(l_bc);
|
|
|
l_bc++;
|
|
|
break;
|
|
|
|
|
|
@@ -2805,7 +2824,7 @@ void asCContext::ExecuteNext()
|
|
|
|
|
|
//-----------------------------------
|
|
|
case asBC_SetG4:
|
|
|
- *(asDWORD*)(size_t)asBC_PTRARG(l_bc) = asBC_DWORDARG(l_bc+AS_PTR_SIZE);
|
|
|
+ *(asDWORD*)asBC_PTRARG(l_bc) = asBC_DWORDARG(l_bc+AS_PTR_SIZE);
|
|
|
l_bc += 2 + AS_PTR_SIZE;
|
|
|
break;
|
|
|
|
|
|
@@ -2813,7 +2832,7 @@ void asCContext::ExecuteNext()
|
|
|
{
|
|
|
// Verify if the pointer on the stack refers to a non-null value
|
|
|
// This is used to validate a reference to a handle
|
|
|
- asDWORD *a = (asDWORD*)*(size_t*)l_sp;
|
|
|
+ asDWORD *a = (asDWORD*)*(asPWORD*)l_sp;
|
|
|
if( *a == 0 )
|
|
|
{
|
|
|
regs.programPointer = l_bc;
|
|
|
@@ -2925,7 +2944,7 @@ void asCContext::ExecuteNext()
|
|
|
case asBC_Cast:
|
|
|
// Cast the handle at the top of the stack to the type in the argument
|
|
|
{
|
|
|
- asDWORD **a = (asDWORD**)*(size_t*)l_sp;
|
|
|
+ asDWORD **a = (asDWORD**)*(asPWORD*)l_sp;
|
|
|
if( a && *a )
|
|
|
{
|
|
|
asDWORD typeId = asBC_DWORDARG(l_bc);
|
|
|
@@ -3161,7 +3180,7 @@ void asCContext::ExecuteNext()
|
|
|
{
|
|
|
// Verify if the pointer on the stack is null
|
|
|
// This is used for example when validating handles passed as function arguments
|
|
|
- size_t a = *(size_t*)(l_sp + asBC_WORDARG0(l_bc));
|
|
|
+ asPWORD a = *(asPWORD*)(l_sp + asBC_WORDARG0(l_bc));
|
|
|
if( a == 0 )
|
|
|
{
|
|
|
regs.programPointer = l_bc;
|
|
|
@@ -3275,20 +3294,20 @@ void asCContext::ExecuteNext()
|
|
|
case asBC_FuncPtr:
|
|
|
// Push the function pointer on the stack. The pointer is in the argument
|
|
|
l_sp -= AS_PTR_SIZE;
|
|
|
- *(asPTRWORD*)l_sp = asBC_PTRARG(l_bc);
|
|
|
+ *(asPWORD*)l_sp = asBC_PTRARG(l_bc);
|
|
|
l_bc += 1+AS_PTR_SIZE;
|
|
|
break;
|
|
|
|
|
|
case asBC_LoadThisR:
|
|
|
{
|
|
|
// PshVPtr 0
|
|
|
- asPTRWORD tmp = *(asPTRWORD*)l_fp;
|
|
|
+ asPWORD tmp = *(asPWORD*)l_fp;
|
|
|
|
|
|
// ADDSi
|
|
|
tmp = tmp + asBC_SWORDARG0(l_bc);
|
|
|
|
|
|
// PopRPtr
|
|
|
- *(asPTRWORD*)®s.valueRegister = tmp;
|
|
|
+ *(asPWORD*)®s.valueRegister = tmp;
|
|
|
l_bc += 2;
|
|
|
}
|
|
|
break;
|
|
|
@@ -3379,13 +3398,13 @@ void asCContext::ExecuteNext()
|
|
|
case asBC_LoadRObjR:
|
|
|
{
|
|
|
// PshVPtr x
|
|
|
- asPTRWORD tmp = *(asPTRWORD*)(l_fp - asBC_SWORDARG0(l_bc));
|
|
|
+ asPWORD tmp = *(asPWORD*)(l_fp - asBC_SWORDARG0(l_bc));
|
|
|
|
|
|
// ADDSi y
|
|
|
tmp = tmp + asBC_SWORDARG1(l_bc);
|
|
|
|
|
|
// PopRPtr
|
|
|
- *(asPTRWORD*)®s.valueRegister = tmp;
|
|
|
+ *(asPWORD*)®s.valueRegister = tmp;
|
|
|
l_bc += 3;
|
|
|
}
|
|
|
break;
|
|
|
@@ -3393,13 +3412,13 @@ void asCContext::ExecuteNext()
|
|
|
case asBC_LoadVObjR:
|
|
|
{
|
|
|
// PSF x
|
|
|
- asPTRWORD tmp = (asPTRWORD)(size_t)(l_fp - asBC_SWORDARG0(l_bc));
|
|
|
+ asPWORD tmp = (asPWORD)(l_fp - asBC_SWORDARG0(l_bc));
|
|
|
|
|
|
// ADDSi y
|
|
|
tmp = tmp + asBC_SWORDARG1(l_bc);
|
|
|
|
|
|
// PopRPtr
|
|
|
- *(asPTRWORD*)®s.valueRegister = tmp;
|
|
|
+ *(asPWORD*)®s.valueRegister = tmp;
|
|
|
l_bc += 3;
|
|
|
}
|
|
|
break;
|
|
|
@@ -3480,6 +3499,7 @@ void asCContext::ExecuteNext()
|
|
|
#ifdef AS_DEBUG
|
|
|
default:
|
|
|
asASSERT(false);
|
|
|
+ SetInternalException(TXT_UNRECOGNIZED_BYTE_CODE);
|
|
|
#endif
|
|
|
/*
|
|
|
default:
|
|
|
@@ -3500,14 +3520,12 @@ void asCContext::ExecuteNext()
|
|
|
}
|
|
|
#endif
|
|
|
}
|
|
|
-
|
|
|
- SetInternalException(TXT_UNRECOGNIZED_BYTE_CODE);
|
|
|
}
|
|
|
|
|
|
int asCContext::SetException(const char *descr)
|
|
|
{
|
|
|
// Only allow this if we're executing a CALL byte code
|
|
|
- if( !isCallingSystemFunction ) return asERROR;
|
|
|
+ if( callingSystemFunction == 0 ) return asERROR;
|
|
|
|
|
|
SetInternalException(descr);
|
|
|
|
|
|
@@ -3554,12 +3572,14 @@ void asCContext::CleanReturnObject()
|
|
|
{
|
|
|
// Call the destructor on the object
|
|
|
asSTypeBehaviour *beh = &((asCObjectType*)regs.objectType)->beh;
|
|
|
- if( beh->release )
|
|
|
+ if( regs.objectType->GetFlags() & asOBJ_REF )
|
|
|
{
|
|
|
- engine->CallObjectMethod(regs.objectRegister, beh->release);
|
|
|
- regs.objectRegister = 0;
|
|
|
+ asASSERT( beh->release || (regs.objectType->GetFlags() & asOBJ_NOCOUNT) );
|
|
|
|
|
|
- // The release method is responsible for freeing the memory
|
|
|
+ if( beh->release )
|
|
|
+ engine->CallObjectMethod(regs.objectRegister, beh->release);
|
|
|
+
|
|
|
+ regs.objectRegister = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -3604,7 +3624,7 @@ bool asCContext::IsVarInScope(asUINT varIndex, asUINT stackLevel)
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- size_t *s = callStack.AddressOf() + (GetCallstackSize()-stackLevel-1)*CALLSTACK_FRAME_SIZE;
|
|
|
+ asPWORD *s = callStack.AddressOf() + (GetCallstackSize()-stackLevel-1)*CALLSTACK_FRAME_SIZE;
|
|
|
func = (asCScriptFunction*)s[1];
|
|
|
pos = asUINT((asDWORD*)s[2] - func->byteCode.AddressOf());
|
|
|
}
|
|
|
@@ -3658,7 +3678,7 @@ void asCContext::DetermineLiveObjects(asCArray<int> &liveObjects, asUINT stackLe
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- size_t *s = callStack.AddressOf() + (GetCallstackSize()-stackLevel-1)*CALLSTACK_FRAME_SIZE;
|
|
|
+ asPWORD *s = callStack.AddressOf() + (GetCallstackSize()-stackLevel-1)*CALLSTACK_FRAME_SIZE;
|
|
|
func = (asCScriptFunction*)s[1];
|
|
|
pos = asUINT((asDWORD*)s[2] - func->byteCode.AddressOf());
|
|
|
}
|
|
|
@@ -3758,23 +3778,25 @@ void asCContext::CleanStackFrame()
|
|
|
if( currentFunction->objVariableIsOnHeap[n] )
|
|
|
{
|
|
|
// Check if the pointer is initialized
|
|
|
- if( *(size_t*)®s.stackFramePointer[-pos] )
|
|
|
+ if( *(asPWORD*)®s.stackFramePointer[-pos] )
|
|
|
{
|
|
|
// Call the object's destructor
|
|
|
asSTypeBehaviour *beh = ¤tFunction->objVariableTypes[n]->beh;
|
|
|
- if( beh->release )
|
|
|
+ if( currentFunction->objVariableTypes[n]->flags & asOBJ_REF )
|
|
|
{
|
|
|
- engine->CallObjectMethod((void*)*(size_t*)®s.stackFramePointer[-pos], beh->release);
|
|
|
- *(size_t*)®s.stackFramePointer[-pos] = 0;
|
|
|
+ asASSERT( (currentFunction->objVariableTypes[n]->flags & asOBJ_NOCOUNT) || beh->release );
|
|
|
+ if( beh->release )
|
|
|
+ engine->CallObjectMethod((void*)*(asPWORD*)®s.stackFramePointer[-pos], beh->release);
|
|
|
+ *(asPWORD*)®s.stackFramePointer[-pos] = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if( beh->destruct )
|
|
|
- engine->CallObjectMethod((void*)*(size_t*)®s.stackFramePointer[-pos], beh->destruct);
|
|
|
+ engine->CallObjectMethod((void*)*(asPWORD*)®s.stackFramePointer[-pos], beh->destruct);
|
|
|
|
|
|
// Free the memory
|
|
|
- engine->CallFree((void*)*(size_t*)®s.stackFramePointer[-pos]);
|
|
|
- *(size_t*)®s.stackFramePointer[-pos] = 0;
|
|
|
+ engine->CallFree((void*)*(asPWORD*)®s.stackFramePointer[-pos]);
|
|
|
+ *(asPWORD*)®s.stackFramePointer[-pos] = 0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -3787,7 +3809,7 @@ void asCContext::CleanStackFrame()
|
|
|
{
|
|
|
asSTypeBehaviour *beh = ¤tFunction->objVariableTypes[n]->beh;
|
|
|
if( beh->destruct )
|
|
|
- engine->CallObjectMethod((void*)(size_t*)®s.stackFramePointer[-pos], beh->destruct);
|
|
|
+ engine->CallObjectMethod((void*)(asPWORD*)®s.stackFramePointer[-pos], beh->destruct);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -3798,10 +3820,10 @@ void asCContext::CleanStackFrame()
|
|
|
if( currentFunction->objectType && regs.programPointer != currentFunction->byteCode.AddressOf() )
|
|
|
{
|
|
|
asSTypeBehaviour *beh = ¤tFunction->objectType->beh;
|
|
|
- if( beh->release && *(size_t*)®s.stackFramePointer[0] != 0 )
|
|
|
+ if( beh->release && *(asPWORD*)®s.stackFramePointer[0] != 0 )
|
|
|
{
|
|
|
- engine->CallObjectMethod((void*)*(size_t*)®s.stackFramePointer[0], beh->release);
|
|
|
- *(size_t*)®s.stackFramePointer[0] = 0;
|
|
|
+ engine->CallObjectMethod((void*)*(asPWORD*)®s.stackFramePointer[0], beh->release);
|
|
|
+ *(asPWORD*)®s.stackFramePointer[0] = 0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -3822,23 +3844,26 @@ void asCContext::CleanStackFrame()
|
|
|
{
|
|
|
if( currentFunction->parameterTypes[n].IsObject() && !currentFunction->parameterTypes[n].IsReference() )
|
|
|
{
|
|
|
- if( *(size_t*)®s.stackFramePointer[offset] )
|
|
|
+ if( *(asPWORD*)®s.stackFramePointer[offset] )
|
|
|
{
|
|
|
// Call the object's destructor
|
|
|
asSTypeBehaviour *beh = currentFunction->parameterTypes[n].GetBehaviour();
|
|
|
- if( beh->release )
|
|
|
+ if( currentFunction->parameterTypes[n].GetObjectType()->flags & asOBJ_REF )
|
|
|
{
|
|
|
- engine->CallObjectMethod((void*)*(size_t*)®s.stackFramePointer[offset], beh->release);
|
|
|
- *(size_t*)®s.stackFramePointer[offset] = 0;
|
|
|
+ asASSERT( (currentFunction->parameterTypes[n].GetObjectType()->flags & asOBJ_NOCOUNT) || beh->release );
|
|
|
+
|
|
|
+ if( beh->release )
|
|
|
+ engine->CallObjectMethod((void*)*(asPWORD*)®s.stackFramePointer[offset], beh->release);
|
|
|
+ *(asPWORD*)®s.stackFramePointer[offset] = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if( beh->destruct )
|
|
|
- engine->CallObjectMethod((void*)*(size_t*)®s.stackFramePointer[offset], beh->destruct);
|
|
|
+ engine->CallObjectMethod((void*)*(asPWORD*)®s.stackFramePointer[offset], beh->destruct);
|
|
|
|
|
|
// Free the memory
|
|
|
- engine->CallFree((void*)*(size_t*)®s.stackFramePointer[offset]);
|
|
|
- *(size_t*)®s.stackFramePointer[offset] = 0;
|
|
|
+ engine->CallFree((void*)*(asPWORD*)®s.stackFramePointer[offset]);
|
|
|
+ *(asPWORD*)®s.stackFramePointer[offset] = 0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -3860,11 +3885,11 @@ int asCContext::GetExceptionLineNumber(int *column, const char **sectionName)
|
|
|
}
|
|
|
|
|
|
// interface
|
|
|
-int asCContext::GetExceptionFunction()
|
|
|
+asIScriptFunction *asCContext::GetExceptionFunction()
|
|
|
{
|
|
|
- if( GetState() != asEXECUTION_EXCEPTION ) return asERROR;
|
|
|
+ if( GetState() != asEXECUTION_EXCEPTION ) return 0;
|
|
|
|
|
|
- return exceptionFunction;
|
|
|
+ return engine->scriptFunctions[exceptionFunction];
|
|
|
}
|
|
|
|
|
|
// interface
|
|
|
@@ -3989,7 +4014,7 @@ int asCContext::CallGeneric(int id, void *objectPointer)
|
|
|
popSize += AS_PTR_SIZE;
|
|
|
|
|
|
// Check for null pointer
|
|
|
- currentObject = (void*)*(size_t*)(args);
|
|
|
+ currentObject = (void*)*(asPWORD*)(args);
|
|
|
if( currentObject == 0 )
|
|
|
{
|
|
|
SetInternalException(TXT_NULL_POINTER_ACCESS);
|
|
|
@@ -3997,7 +4022,7 @@ int asCContext::CallGeneric(int id, void *objectPointer)
|
|
|
}
|
|
|
|
|
|
// Add the base offset for multiple inheritance
|
|
|
- currentObject = (void*)(size_t(currentObject) + sysFunc->baseOffset);
|
|
|
+ currentObject = (void*)(asPWORD(currentObject) + sysFunc->baseOffset);
|
|
|
|
|
|
// Skip object pointer
|
|
|
args += AS_PTR_SIZE;
|
|
|
@@ -4013,9 +4038,9 @@ int asCContext::CallGeneric(int id, void *objectPointer)
|
|
|
|
|
|
asCGeneric gen(engine, sysFunction, currentObject, args);
|
|
|
|
|
|
- isCallingSystemFunction = true;
|
|
|
+ callingSystemFunction = sysFunction;
|
|
|
func(&gen);
|
|
|
- isCallingSystemFunction = false;
|
|
|
+ callingSystemFunction = 0;
|
|
|
|
|
|
regs.valueRegister = gen.returnVal;
|
|
|
regs.objectRegister = gen.objectRegister;
|
|
|
@@ -4032,8 +4057,12 @@ int asCContext::CallGeneric(int id, void *objectPointer)
|
|
|
{
|
|
|
// Release the object
|
|
|
asSTypeBehaviour *beh = &sysFunction->parameterTypes[n].GetObjectType()->beh;
|
|
|
- if( beh->release )
|
|
|
- engine->CallObjectMethod(obj, beh->release);
|
|
|
+ if( sysFunction->parameterTypes[n].GetObjectType()->flags & asOBJ_REF )
|
|
|
+ {
|
|
|
+ asASSERT( (sysFunction->parameterTypes[n].GetObjectType()->flags & asOBJ_NOCOUNT) || beh->release );
|
|
|
+ if( beh->release )
|
|
|
+ engine->CallObjectMethod(obj, beh->release);
|
|
|
+ }
|
|
|
else
|
|
|
{
|
|
|
// Call the destructor then free the memory
|
|
|
@@ -4105,7 +4134,7 @@ void *asCContext::GetAddressOfVar(asUINT varIndex, asUINT stackLevel)
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- size_t *s = callStack.AddressOf() + (GetCallstackSize()-stackLevel-1)*CALLSTACK_FRAME_SIZE;
|
|
|
+ asPWORD *s = callStack.AddressOf() + (GetCallstackSize()-stackLevel-1)*CALLSTACK_FRAME_SIZE;
|
|
|
func = (asCScriptFunction*)s[1];
|
|
|
sf = (asDWORD*)s[0];
|
|
|
}
|
|
|
@@ -4187,7 +4216,7 @@ void *asCContext::GetThisPointer(asUINT stackLevel)
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- size_t *s = callStack.AddressOf() + (GetCallstackSize()-stackLevel-1)*CALLSTACK_FRAME_SIZE;
|
|
|
+ asPWORD *s = callStack.AddressOf() + (GetCallstackSize()-stackLevel-1)*CALLSTACK_FRAME_SIZE;
|
|
|
func = (asCScriptFunction*)s[1];
|
|
|
sf = (asDWORD*)s[0];
|
|
|
}
|
|
|
@@ -4198,7 +4227,7 @@ void *asCContext::GetThisPointer(asUINT stackLevel)
|
|
|
if( func->objectType == 0 )
|
|
|
return 0; // not in a method
|
|
|
|
|
|
- void *thisPointer = (void*)*(size_t*)(sf);
|
|
|
+ void *thisPointer = (void*)*(asPWORD*)(sf);
|
|
|
if( thisPointer == 0 )
|
|
|
{
|
|
|
return 0;
|