Merge branch 'asmjit' into weapon_scriptification
# Conflicts: # src/gi.cpp # wadsrc/static/zscript/base.txt
This commit is contained in:
commit
47b1fa774d
51 changed files with 1809 additions and 1239 deletions
|
|
@ -9,6 +9,7 @@ extern PStruct *TypeVector3;
|
|||
static void OutputJitLog(const asmjit::StringLogger &logger);
|
||||
|
||||
static TArray<uint8_t*> JitBlocks;
|
||||
static TArray<uint8_t*> JitFrames;
|
||||
static size_t JitBlockPos = 0;
|
||||
static size_t JitBlockSize = 0;
|
||||
|
||||
|
|
@ -61,6 +62,25 @@ static void *AllocJitMemory(size_t size)
|
|||
#define UWOP_SAVE_XMM128_FAR 9
|
||||
#define UWOP_PUSH_MACHFRAME 10
|
||||
|
||||
|
||||
void JitRelease()
|
||||
{
|
||||
#ifdef _WIN64
|
||||
for (auto p : JitFrames)
|
||||
{
|
||||
RtlDeleteFunctionTable((PRUNTIME_FUNCTION)p);
|
||||
}
|
||||
#endif
|
||||
for (auto p : JitBlocks)
|
||||
{
|
||||
asmjit::OSUtils::releaseVirtualMemory(p, 1024 * 1024);
|
||||
}
|
||||
JitFrames.Clear();
|
||||
JitBlocks.Clear();
|
||||
JitBlockPos = 0;
|
||||
JitBlockSize = 0;
|
||||
}
|
||||
|
||||
static TArray<uint16_t> CreateUnwindInfo(asmjit::CCFunc *func)
|
||||
{
|
||||
using namespace asmjit;
|
||||
|
|
@ -276,6 +296,7 @@ static void *AddJitFunction(asmjit::CodeHolder* code, asmjit::CCFunc *func)
|
|||
table[0].EndAddress = (DWORD)(ptrdiff_t)(endaddr - baseaddr);
|
||||
table[0].UnwindInfoAddress = (DWORD)(ptrdiff_t)(unwindptr - baseaddr);
|
||||
BOOLEAN result = RtlAddFunctionTable(table, 1, (DWORD64)baseaddr);
|
||||
JitFrames.Push((uint8_t*)table);
|
||||
if (result == 0)
|
||||
I_FatalError("RtlAddFunctionTable failed");
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -317,13 +317,16 @@ void JitCompiler::EmitNativeCall(VMNativeFunction *target)
|
|||
{
|
||||
using namespace asmjit;
|
||||
|
||||
auto call = cc.call(imm_ptr(target->DirectNativeCall), CreateFuncSignature(target));
|
||||
|
||||
if ((pc - 1)->op == OP_VTBL)
|
||||
{
|
||||
I_FatalError("Native direct member function calls not implemented\n");
|
||||
}
|
||||
|
||||
asmjit::CBNode *cursorBefore = cc.getCursor();
|
||||
auto call = cc.call(imm_ptr(target->DirectNativeCall), CreateFuncSignature(target));
|
||||
asmjit::CBNode *cursorAfter = cc.getCursor();
|
||||
cc.setCursor(cursorBefore);
|
||||
|
||||
X86Gp tmp;
|
||||
X86Xmm tmp2;
|
||||
|
||||
|
|
@ -398,6 +401,8 @@ void JitCompiler::EmitNativeCall(VMNativeFunction *target)
|
|||
}
|
||||
}
|
||||
|
||||
cc.setCursor(cursorAfter);
|
||||
|
||||
if (numparams != B)
|
||||
I_FatalError("OP_CALL parameter count does not match the number of preceding OP_PARAM instructions\n");
|
||||
|
||||
|
|
@ -461,7 +466,7 @@ asmjit::FuncSignature JitCompiler::CreateFuncSignature(VMFunction *func)
|
|||
for (unsigned int i = 0; i < func->Proto->ArgumentTypes.Size(); i++)
|
||||
{
|
||||
const PType *type = func->Proto->ArgumentTypes[i];
|
||||
if (func->ArgFlags[i] & (VARF_Out | VARF_Ref))
|
||||
if (func->ArgFlags.Size() && func->ArgFlags[i] & (VARF_Out | VARF_Ref))
|
||||
{
|
||||
args.Push(TypeIdOf<void*>::kTypeId);
|
||||
key += "v";
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ extern FMemArena ClassDataAllocator;
|
|||
#define MAX_RETURNS 8 // Maximum number of results a function called by script code can return
|
||||
#define MAX_TRY_DEPTH 8 // Maximum number of nested TRYs in a single function
|
||||
|
||||
void JitRelease();
|
||||
|
||||
|
||||
typedef unsigned char VM_UBYTE;
|
||||
typedef signed char VM_SBYTE;
|
||||
|
|
@ -432,6 +434,8 @@ public:
|
|||
f->~VMFunction();
|
||||
}
|
||||
AllFunctions.Clear();
|
||||
// also release any JIT data
|
||||
JitRelease();
|
||||
}
|
||||
static void CreateRegUseInfo()
|
||||
{
|
||||
|
|
@ -511,6 +515,7 @@ bool AssertObject(void * ob);
|
|||
#define PARAM_STATE_AT(p,x) assert((p) < numparam); assert(reginfo[p] == REGT_INT); FState *x = (FState *)StateLabels.GetState(param[p].i, self->GetClass());
|
||||
#define PARAM_STATE_ACTION_AT(p,x) assert((p) < numparam); assert(reginfo[p] == REGT_INT); FState *x = (FState *)StateLabels.GetState(param[p].i, stateowner->GetClass());
|
||||
#define PARAM_POINTER_AT(p,x,type) assert((p) < numparam); assert(reginfo[p] == REGT_POINTER); type *x = (type *)param[p].a;
|
||||
#define PARAM_OUTPOINTER_AT(p,x,type) assert((p) < numparam); type *x = (type *)param[p].a;
|
||||
#define PARAM_POINTERTYPE_AT(p,x,type) assert((p) < numparam); assert(reginfo[p] == REGT_POINTER); type x = (type )param[p].a;
|
||||
#define PARAM_OBJECT_AT(p,x,type) assert((p) < numparam); assert(reginfo[p] == REGT_POINTER && AssertObject(param[p].a)); type *x = (type *)param[p].a; assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type)));
|
||||
#define PARAM_CLASS_AT(p,x,base) assert((p) < numparam); assert(reginfo[p] == REGT_POINTER); base::MetaClass *x = (base::MetaClass *)param[p].a; assert(x == NULL || x->IsDescendantOf(RUNTIME_CLASS(base)));
|
||||
|
|
@ -534,6 +539,7 @@ bool AssertObject(void * ob);
|
|||
#define PARAM_STATE(x) ++paramnum; PARAM_STATE_AT(paramnum,x)
|
||||
#define PARAM_STATE_ACTION(x) ++paramnum; PARAM_STATE_ACTION_AT(paramnum,x)
|
||||
#define PARAM_POINTER(x,type) ++paramnum; PARAM_POINTER_AT(paramnum,x,type)
|
||||
#define PARAM_OUTPOINTER(x,type) ++paramnum; PARAM_OUTPOINTER_AT(paramnum,x,type)
|
||||
#define PARAM_POINTERTYPE(x,type) ++paramnum; PARAM_POINTERTYPE_AT(paramnum,x,type)
|
||||
#define PARAM_OBJECT(x,type) ++paramnum; PARAM_OBJECT_AT(paramnum,x,type)
|
||||
#define PARAM_CLASS(x,base) ++paramnum; PARAM_CLASS_AT(paramnum,x,base)
|
||||
|
|
@ -559,6 +565,7 @@ struct AFuncDesc
|
|||
const char *FuncName;
|
||||
actionf_p Function;
|
||||
VMNativeFunction **VMPointer;
|
||||
void *DirectNative;
|
||||
};
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
|
@ -579,10 +586,19 @@ struct AFuncDesc
|
|||
// Macros to handle action functions. These are here so that I don't have to
|
||||
// change every single use in case the parameters change.
|
||||
|
||||
#define DEFINE_ACTION_FUNCTION_NATIVE(cls, name, native) \
|
||||
static int AF_##cls##_##name(VM_ARGS); \
|
||||
VMNativeFunction *cls##_##name##_VMPtr; \
|
||||
static const AFuncDesc cls##_##name##_Hook = { #cls, #name, AF_##cls##_##name, &cls##_##name##_VMPtr, reinterpret_cast<void*>(native) }; \
|
||||
extern AFuncDesc const *const cls##_##name##_HookPtr; \
|
||||
MSVC_ASEG AFuncDesc const *const cls##_##name##_HookPtr GCC_ASEG = &cls##_##name##_Hook; \
|
||||
static int AF_##cls##_##name(VM_ARGS)
|
||||
|
||||
//#define DEFINE_ACTION_FUNCTION(cls, name) DEFINE_ACTION_FUNCTION_NATIVE(cls, name, nullptr)
|
||||
#define DEFINE_ACTION_FUNCTION(cls, name) \
|
||||
static int AF_##cls##_##name(VM_ARGS); \
|
||||
VMNativeFunction *cls##_##name##_VMPtr; \
|
||||
static const AFuncDesc cls##_##name##_Hook = { #cls, #name, AF_##cls##_##name, &cls##_##name##_VMPtr }; \
|
||||
static const AFuncDesc cls##_##name##_Hook = { #cls, #name, AF_##cls##_##name, &cls##_##name##_VMPtr, nullptr }; \
|
||||
extern AFuncDesc const *const cls##_##name##_HookPtr; \
|
||||
MSVC_ASEG AFuncDesc const *const cls##_##name##_HookPtr GCC_ASEG = &cls##_##name##_Hook; \
|
||||
static int AF_##cls##_##name(VM_ARGS)
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ void VMFunction::CreateRegUse()
|
|||
return;
|
||||
}
|
||||
assert(Proto->isPrototype());
|
||||
|
||||
for (auto arg : Proto->ArgumentTypes)
|
||||
{
|
||||
count += arg? arg->GetRegCount() : 1;
|
||||
|
|
@ -87,14 +88,20 @@ void VMFunction::CreateRegUse()
|
|||
uint8_t *regp;
|
||||
RegTypes = regp = (uint8_t*)ClassDataAllocator.Alloc(count);
|
||||
count = 0;
|
||||
for (auto arg : Proto->ArgumentTypes)
|
||||
for (unsigned i = 0; i < Proto->ArgumentTypes.Size(); i++)
|
||||
{
|
||||
auto arg = Proto->ArgumentTypes[i];
|
||||
auto flg = ArgFlags.Size() > i ? ArgFlags[i] : 0;
|
||||
if (arg == nullptr)
|
||||
{
|
||||
// Marker for start of varargs.
|
||||
*regp++ = REGT_NIL;
|
||||
}
|
||||
else for (int i = 0; i < arg->GetRegCount(); i++)
|
||||
else if ((flg & VARF_Out) && !arg->isPointer())
|
||||
{
|
||||
*regp++ = REGT_POINTER;
|
||||
}
|
||||
else for (int j = 0; j < arg->GetRegCount(); j++)
|
||||
{
|
||||
*regp++ = arg->GetRegType();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue