mirror of
https://github.com/kevinbentley/Descent3.git
synced 2026-04-06 08:00:04 -04:00
clang-format on everything.
This commit is contained in:
@@ -28,7 +28,6 @@
|
||||
andreas@angelcode.com
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// as_callfunc_arm.cpp
|
||||
//
|
||||
@@ -36,7 +35,6 @@
|
||||
//
|
||||
// Written by Fredrik Ehnbom in June 2009, based on as_callfunc_x86.cpp
|
||||
|
||||
|
||||
#include "as_config.h"
|
||||
|
||||
#ifndef AS_MAX_PORTABILITY
|
||||
@@ -67,278 +65,238 @@ extern "C" asQWORD armFuncR0ObjLast(const asDWORD *, int, size_t, asDWORD r0, as
|
||||
// calling convention.
|
||||
//
|
||||
// This should be done for all supported platforms.
|
||||
int CallSystemFunction(int id, asCContext *context, void *objectPointer)
|
||||
{
|
||||
asCScriptEngine *engine = context->engine;
|
||||
asCScriptFunction *descr = engine->scriptFunctions[id];
|
||||
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
|
||||
int callConv = sysFunc->callConv;
|
||||
if( callConv == ICC_GENERIC_FUNC || callConv == ICC_GENERIC_METHOD )
|
||||
return context->CallGeneric(id, objectPointer);
|
||||
int CallSystemFunction(int id, asCContext *context, void *objectPointer) {
|
||||
asCScriptEngine *engine = context->engine;
|
||||
asCScriptFunction *descr = engine->scriptFunctions[id];
|
||||
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
|
||||
int callConv = sysFunc->callConv;
|
||||
if (callConv == ICC_GENERIC_FUNC || callConv == ICC_GENERIC_METHOD)
|
||||
return context->CallGeneric(id, objectPointer);
|
||||
|
||||
asQWORD retQW = 0;
|
||||
void *func = (void*)sysFunc->func;
|
||||
int paramSize = sysFunc->paramSize;
|
||||
asDWORD *args = context->regs.stackPointer;
|
||||
void *retPointer = 0;
|
||||
void *obj = 0;
|
||||
asDWORD *vftable;
|
||||
int popSize = paramSize;
|
||||
asQWORD retQW = 0;
|
||||
void *func = (void *)sysFunc->func;
|
||||
int paramSize = sysFunc->paramSize;
|
||||
asDWORD *args = context->regs.stackPointer;
|
||||
void *retPointer = 0;
|
||||
void *obj = 0;
|
||||
asDWORD *vftable;
|
||||
int popSize = paramSize;
|
||||
|
||||
context->regs.objectType = descr->returnType.GetObjectType();
|
||||
if( descr->returnType.IsObject() && !descr->returnType.IsReference() && !descr->returnType.IsObjectHandle() )
|
||||
{
|
||||
// Allocate the memory for the object
|
||||
retPointer = engine->CallAlloc(descr->returnType.GetObjectType());
|
||||
context->regs.objectType = descr->returnType.GetObjectType();
|
||||
if (descr->returnType.IsObject() && !descr->returnType.IsReference() && !descr->returnType.IsObjectHandle()) {
|
||||
// Allocate the memory for the object
|
||||
retPointer = engine->CallAlloc(descr->returnType.GetObjectType());
|
||||
|
||||
if( sysFunc->hostReturnInMemory )
|
||||
{
|
||||
// The return is made in memory
|
||||
callConv++;
|
||||
}
|
||||
}
|
||||
if (sysFunc->hostReturnInMemory) {
|
||||
// The return is made in memory
|
||||
callConv++;
|
||||
}
|
||||
}
|
||||
|
||||
if( callConv >= ICC_THISCALL )
|
||||
{
|
||||
if( objectPointer )
|
||||
{
|
||||
obj = objectPointer;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The object pointer should be popped from the context stack
|
||||
popSize++;
|
||||
if (callConv >= ICC_THISCALL) {
|
||||
if (objectPointer) {
|
||||
obj = objectPointer;
|
||||
} else {
|
||||
// The object pointer should be popped from the context stack
|
||||
popSize++;
|
||||
|
||||
// Check for null pointer
|
||||
obj = (void*)*(size_t*)(args);
|
||||
if( obj == 0 )
|
||||
{
|
||||
context->SetInternalException(TXT_NULL_POINTER_ACCESS);
|
||||
if( retPointer )
|
||||
engine->CallFree(retPointer);
|
||||
return 0;
|
||||
}
|
||||
// Check for null pointer
|
||||
obj = (void *)*(size_t *)(args);
|
||||
if (obj == 0) {
|
||||
context->SetInternalException(TXT_NULL_POINTER_ACCESS);
|
||||
if (retPointer)
|
||||
engine->CallFree(retPointer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Add the base offset for multiple inheritance
|
||||
// Add the base offset for multiple inheritance
|
||||
#ifdef __GNUC__
|
||||
// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
|
||||
// and the whole offset is thus shifted one bit left to keep the original
|
||||
// offset resolution
|
||||
obj = (void*)(size_t(obj) + (sysFunc->baseOffset>>1));
|
||||
// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
|
||||
// and the whole offset is thus shifted one bit left to keep the original
|
||||
// offset resolution
|
||||
obj = (void *)(size_t(obj) + (sysFunc->baseOffset >> 1));
|
||||
#else
|
||||
obj = (void*)(size_t(obj) + sysFunc->baseOffset);
|
||||
obj = (void *)(size_t(obj) + sysFunc->baseOffset);
|
||||
#endif
|
||||
|
||||
// Skip the object pointer
|
||||
args++;
|
||||
}
|
||||
}
|
||||
// Skip the object pointer
|
||||
args++;
|
||||
}
|
||||
}
|
||||
|
||||
asDWORD paramBuffer[64];
|
||||
if( sysFunc->takesObjByVal )
|
||||
{
|
||||
paramSize = 0;
|
||||
int spos = 0;
|
||||
int dpos = 1;
|
||||
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
|
||||
{
|
||||
asDWORD paramBuffer[64];
|
||||
if (sysFunc->takesObjByVal) {
|
||||
paramSize = 0;
|
||||
int spos = 0;
|
||||
int dpos = 1;
|
||||
for (asUINT n = 0; n < descr->parameterTypes.GetLength(); n++) {
|
||||
if (descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() &&
|
||||
!descr->parameterTypes[n].IsReference()) {
|
||||
#ifdef COMPLEX_OBJS_PASSED_BY_REF
|
||||
if( descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK )
|
||||
{
|
||||
paramBuffer[dpos++] = args[spos++];
|
||||
paramSize++;
|
||||
}
|
||||
else
|
||||
if (descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK) {
|
||||
paramBuffer[dpos++] = args[spos++];
|
||||
paramSize++;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// Copy the object's memory to the buffer
|
||||
memcpy(¶mBuffer[dpos], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
|
||||
{
|
||||
// Copy the object's memory to the buffer
|
||||
memcpy(¶mBuffer[dpos], *(void **)(args + spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
|
||||
|
||||
// Delete the original memory
|
||||
engine->CallFree(*(char**)(args+spos));
|
||||
spos++;
|
||||
dpos += descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
paramSize += descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy the value directly
|
||||
paramBuffer[dpos++] = args[spos++];
|
||||
if( descr->parameterTypes[n].GetSizeOnStackDWords() > 1 )
|
||||
paramBuffer[dpos++] = args[spos++];
|
||||
paramSize += descr->parameterTypes[n].GetSizeOnStackDWords();
|
||||
}
|
||||
}
|
||||
// Keep a free location at the beginning
|
||||
args = ¶mBuffer[1];
|
||||
}
|
||||
|
||||
context->isCallingSystemFunction = true;
|
||||
|
||||
switch( callConv )
|
||||
{
|
||||
case ICC_CDECL_RETURNINMEM: // fall through
|
||||
case ICC_STDCALL_RETURNINMEM:
|
||||
retQW = armFuncR0(args, paramSize<<2, (asDWORD)func, (asDWORD) retPointer);
|
||||
break;
|
||||
case ICC_CDECL: // fall through
|
||||
case ICC_STDCALL:
|
||||
retQW = armFunc(args, paramSize<<2, (asDWORD)func);
|
||||
break;
|
||||
case ICC_THISCALL: // fall through
|
||||
case ICC_CDECL_OBJFIRST:
|
||||
retQW = armFuncR0(args, paramSize<<2, (asDWORD)func, (asDWORD) obj);
|
||||
break;
|
||||
case ICC_THISCALL_RETURNINMEM:
|
||||
#ifndef __GNUC__
|
||||
retQW = armFuncR0R1(args, paramSize<<2, (asDWORD)func, (asDWORD) obj, (asDWORD) retPointer);
|
||||
break;
|
||||
#endif
|
||||
case ICC_CDECL_OBJFIRST_RETURNINMEM:
|
||||
retQW = armFuncR0R1(args, paramSize<<2, (asDWORD)func, (asDWORD) retPointer, (asDWORD) obj);
|
||||
break;
|
||||
case ICC_VIRTUAL_THISCALL:
|
||||
// Get virtual function table from the object pointer
|
||||
vftable = *(asDWORD**)obj;
|
||||
retQW = armFuncR0(args, paramSize<<2, vftable[asDWORD(func)>>2], (asDWORD) obj);
|
||||
break;
|
||||
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
|
||||
// Get virtual function table from the object pointer
|
||||
vftable = *(asDWORD**)obj;
|
||||
#ifndef __GNUC__
|
||||
retQW = armFuncR0R1(args, (paramSize+1)<<2, vftable[asDWORD(func)>>2], (asDWORD) retPointer, (asDWORD) obj);
|
||||
#else
|
||||
retQW = armFuncR0R1(args, (paramSize+1)<<2, vftable[asDWORD(func)>>2], (asDWORD) obj, (asDWORD) retPointer);
|
||||
#endif
|
||||
break;
|
||||
case ICC_CDECL_OBJLAST:
|
||||
retQW = armFuncObjLast(args, paramSize<<2, (asDWORD)func, (asDWORD) obj);
|
||||
break;
|
||||
case ICC_CDECL_OBJLAST_RETURNINMEM:
|
||||
retQW = armFuncR0ObjLast(args, paramSize<<2, (asDWORD)func, (asDWORD) retPointer, (asDWORD) obj);
|
||||
break;
|
||||
default:
|
||||
context->SetInternalException(TXT_INVALID_CALLING_CONVENTION);
|
||||
}
|
||||
context->isCallingSystemFunction = false;
|
||||
#ifdef COMPLEX_OBJS_PASSED_BY_REF
|
||||
if( sysFunc->takesObjByVal )
|
||||
{
|
||||
// Need to free the complex objects passed by value
|
||||
args = context->regs.stackPointer;
|
||||
if( callConv >= ICC_THISCALL && !objectPointer )
|
||||
args++;
|
||||
|
||||
int spos = 0;
|
||||
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
if( descr->parameterTypes[n].IsObject() &&
|
||||
!descr->parameterTypes[n].IsReference() &&
|
||||
!descr->parameterTypes[n].IsObjectHandle()
|
||||
)
|
||||
{
|
||||
if (descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK)
|
||||
{
|
||||
void *obj = (void*)args[spos++];
|
||||
|
||||
// Running the destructor here results in the destructor being
|
||||
// run twice as it has already been called in the native function.
|
||||
// TODO: Should this be an ifdef or removed completely?
|
||||
// asSTypeBehaviour *beh = &descr->parameterTypes[n].GetObjectType()->beh;
|
||||
// if( beh->destruct )
|
||||
// engine->CallObjectMethod(obj, beh->destruct);
|
||||
|
||||
engine->CallFree(obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The original data was already freed earlier
|
||||
spos += descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
spos += descr->parameterTypes[n].GetSizeOnStackDWords();
|
||||
}
|
||||
// Delete the original memory
|
||||
engine->CallFree(*(char **)(args + spos));
|
||||
spos++;
|
||||
dpos += descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
paramSize += descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Copy the value directly
|
||||
paramBuffer[dpos++] = args[spos++];
|
||||
if (descr->parameterTypes[n].GetSizeOnStackDWords() > 1)
|
||||
paramBuffer[dpos++] = args[spos++];
|
||||
paramSize += descr->parameterTypes[n].GetSizeOnStackDWords();
|
||||
}
|
||||
}
|
||||
// Keep a free location at the beginning
|
||||
args = ¶mBuffer[1];
|
||||
}
|
||||
|
||||
context->isCallingSystemFunction = true;
|
||||
|
||||
switch (callConv) {
|
||||
case ICC_CDECL_RETURNINMEM: // fall through
|
||||
case ICC_STDCALL_RETURNINMEM:
|
||||
retQW = armFuncR0(args, paramSize << 2, (asDWORD)func, (asDWORD)retPointer);
|
||||
break;
|
||||
case ICC_CDECL: // fall through
|
||||
case ICC_STDCALL:
|
||||
retQW = armFunc(args, paramSize << 2, (asDWORD)func);
|
||||
break;
|
||||
case ICC_THISCALL: // fall through
|
||||
case ICC_CDECL_OBJFIRST:
|
||||
retQW = armFuncR0(args, paramSize << 2, (asDWORD)func, (asDWORD)obj);
|
||||
break;
|
||||
case ICC_THISCALL_RETURNINMEM:
|
||||
#ifndef __GNUC__
|
||||
retQW = armFuncR0R1(args, paramSize << 2, (asDWORD)func, (asDWORD)obj, (asDWORD)retPointer);
|
||||
break;
|
||||
#endif
|
||||
case ICC_CDECL_OBJFIRST_RETURNINMEM:
|
||||
retQW = armFuncR0R1(args, paramSize << 2, (asDWORD)func, (asDWORD)retPointer, (asDWORD)obj);
|
||||
break;
|
||||
case ICC_VIRTUAL_THISCALL:
|
||||
// Get virtual function table from the object pointer
|
||||
vftable = *(asDWORD **)obj;
|
||||
retQW = armFuncR0(args, paramSize << 2, vftable[asDWORD(func) >> 2], (asDWORD)obj);
|
||||
break;
|
||||
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
|
||||
// Get virtual function table from the object pointer
|
||||
vftable = *(asDWORD **)obj;
|
||||
#ifndef __GNUC__
|
||||
retQW = armFuncR0R1(args, (paramSize + 1) << 2, vftable[asDWORD(func) >> 2], (asDWORD)retPointer, (asDWORD)obj);
|
||||
#else
|
||||
retQW = armFuncR0R1(args, (paramSize + 1) << 2, vftable[asDWORD(func) >> 2], (asDWORD)obj, (asDWORD)retPointer);
|
||||
#endif
|
||||
break;
|
||||
case ICC_CDECL_OBJLAST:
|
||||
retQW = armFuncObjLast(args, paramSize << 2, (asDWORD)func, (asDWORD)obj);
|
||||
break;
|
||||
case ICC_CDECL_OBJLAST_RETURNINMEM:
|
||||
retQW = armFuncR0ObjLast(args, paramSize << 2, (asDWORD)func, (asDWORD)retPointer, (asDWORD)obj);
|
||||
break;
|
||||
default:
|
||||
context->SetInternalException(TXT_INVALID_CALLING_CONVENTION);
|
||||
}
|
||||
context->isCallingSystemFunction = false;
|
||||
#ifdef COMPLEX_OBJS_PASSED_BY_REF
|
||||
if (sysFunc->takesObjByVal) {
|
||||
// Need to free the complex objects passed by value
|
||||
args = context->regs.stackPointer;
|
||||
if (callConv >= ICC_THISCALL && !objectPointer)
|
||||
args++;
|
||||
|
||||
int spos = 0;
|
||||
for (asUINT n = 0; n < descr->parameterTypes.GetLength(); n++) {
|
||||
if (descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsReference() &&
|
||||
!descr->parameterTypes[n].IsObjectHandle()) {
|
||||
if (descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK) {
|
||||
void *obj = (void *)args[spos++];
|
||||
|
||||
// Running the destructor here results in the destructor being
|
||||
// run twice as it has already been called in the native function.
|
||||
// TODO: Should this be an ifdef or removed completely?
|
||||
// asSTypeBehaviour *beh = &descr->parameterTypes[n].GetObjectType()->beh;
|
||||
// if( beh->destruct )
|
||||
// engine->CallObjectMethod(obj, beh->destruct);
|
||||
|
||||
engine->CallFree(obj);
|
||||
} else {
|
||||
// The original data was already freed earlier
|
||||
spos += descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
}
|
||||
} else {
|
||||
spos += descr->parameterTypes[n].GetSizeOnStackDWords();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Store the returned value in our stack
|
||||
if( descr->returnType.IsObject() && !descr->returnType.IsReference() )
|
||||
{
|
||||
if( descr->returnType.IsObjectHandle() )
|
||||
{
|
||||
context->regs.objectRegister = (void*)(size_t)retQW;
|
||||
// Store the returned value in our stack
|
||||
if (descr->returnType.IsObject() && !descr->returnType.IsReference()) {
|
||||
if (descr->returnType.IsObjectHandle()) {
|
||||
context->regs.objectRegister = (void *)(size_t)retQW;
|
||||
|
||||
if( sysFunc->returnAutoHandle && context->regs.objectRegister )
|
||||
engine->CallObjectMethod(context->regs.objectRegister, descr->returnType.GetObjectType()->beh.addref);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !sysFunc->hostReturnInMemory )
|
||||
{
|
||||
// Copy the returned value to the pointer sent by the script engine
|
||||
if( sysFunc->hostReturnSize == 1 )
|
||||
*(asDWORD*)retPointer = (asDWORD)retQW;
|
||||
else
|
||||
*(asQWORD*)retPointer = retQW;
|
||||
}
|
||||
if (sysFunc->returnAutoHandle && context->regs.objectRegister)
|
||||
engine->CallObjectMethod(context->regs.objectRegister, descr->returnType.GetObjectType()->beh.addref);
|
||||
} else {
|
||||
if (!sysFunc->hostReturnInMemory) {
|
||||
// Copy the returned value to the pointer sent by the script engine
|
||||
if (sysFunc->hostReturnSize == 1)
|
||||
*(asDWORD *)retPointer = (asDWORD)retQW;
|
||||
else
|
||||
*(asQWORD *)retPointer = retQW;
|
||||
}
|
||||
|
||||
// Store the object in the register
|
||||
context->regs.objectRegister = retPointer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Store value in valueRegister
|
||||
if( sysFunc->hostReturnFloat )
|
||||
{
|
||||
if( sysFunc->hostReturnSize == 1 )
|
||||
*(asDWORD*)&context->regs.valueRegister = (asDWORD) retQW;
|
||||
else
|
||||
context->regs.valueRegister = retQW;
|
||||
}
|
||||
else if( sysFunc->hostReturnSize == 1 )
|
||||
*(asDWORD*)&context->regs.valueRegister = (asDWORD)retQW;
|
||||
else
|
||||
context->regs.valueRegister = retQW;
|
||||
}
|
||||
// Store the object in the register
|
||||
context->regs.objectRegister = retPointer;
|
||||
}
|
||||
} else {
|
||||
// Store value in valueRegister
|
||||
if (sysFunc->hostReturnFloat) {
|
||||
if (sysFunc->hostReturnSize == 1)
|
||||
*(asDWORD *)&context->regs.valueRegister = (asDWORD)retQW;
|
||||
else
|
||||
context->regs.valueRegister = retQW;
|
||||
} else if (sysFunc->hostReturnSize == 1)
|
||||
*(asDWORD *)&context->regs.valueRegister = (asDWORD)retQW;
|
||||
else
|
||||
context->regs.valueRegister = retQW;
|
||||
}
|
||||
|
||||
if( sysFunc->hasAutoHandles )
|
||||
{
|
||||
args = context->regs.stackPointer;
|
||||
if( callConv >= ICC_THISCALL && !objectPointer )
|
||||
args++;
|
||||
if (sysFunc->hasAutoHandles) {
|
||||
args = context->regs.stackPointer;
|
||||
if (callConv >= ICC_THISCALL && !objectPointer)
|
||||
args++;
|
||||
|
||||
int spos = 0;
|
||||
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
if( sysFunc->paramAutoHandles[n] && args[spos] )
|
||||
{
|
||||
// Call the release method on the type
|
||||
engine->CallObjectMethod((void*)*(size_t*)&args[spos], descr->parameterTypes[n].GetObjectType()->beh.release);
|
||||
args[spos] = 0;
|
||||
}
|
||||
int spos = 0;
|
||||
for (asUINT n = 0; n < descr->parameterTypes.GetLength(); n++) {
|
||||
if (sysFunc->paramAutoHandles[n] && args[spos]) {
|
||||
// Call the release method on the type
|
||||
engine->CallObjectMethod((void *)*(size_t *)&args[spos], descr->parameterTypes[n].GetObjectType()->beh.release);
|
||||
args[spos] = 0;
|
||||
}
|
||||
|
||||
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
|
||||
spos++;
|
||||
else
|
||||
spos += descr->parameterTypes[n].GetSizeOnStackDWords();
|
||||
}
|
||||
}
|
||||
if (descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() &&
|
||||
!descr->parameterTypes[n].IsReference())
|
||||
spos++;
|
||||
else
|
||||
spos += descr->parameterTypes[n].GetSizeOnStackDWords();
|
||||
}
|
||||
}
|
||||
|
||||
return popSize;
|
||||
return popSize;
|
||||
}
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif // AS_ARM
|
||||
#endif // AS_MAX_PORTABILITY
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user