mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 07:12:16 +00:00
- generate register type info for the parameter lists of all functions.
Currently used for loading parameters into registers. For checking parameters of native functions some more work is needed to get the info to the function. Currently it doesn't receive the function descriptor.
This commit is contained in:
parent
1ef772d017
commit
a981737855
11 changed files with 84 additions and 46 deletions
|
@ -749,6 +749,7 @@ static void (*MBFCodePointerFactories[])(FunctionCallEmitter&, int, int) =
|
|||
|
||||
void SetDehParams(FState *state, int codepointer)
|
||||
{
|
||||
static uint8_t regts[] = { REGT_POINTER, REGT_POINTER, REGT_POINTER };
|
||||
int value1 = state->GetMisc1();
|
||||
int value2 = state->GetMisc2();
|
||||
if (!(value1|value2)) return;
|
||||
|
@ -788,6 +789,7 @@ void SetDehParams(FState *state, int codepointer)
|
|||
buildit.Emit(OP_RET, RET_FINAL, REGT_NIL, 0);
|
||||
// Attach it to the state.
|
||||
VMScriptFunction *sfunc = new VMScriptFunction;
|
||||
sfunc->RegTypes = regts; // These functions are built after running the script compiler so they don't get this info.
|
||||
buildit.MakeFunction(sfunc);
|
||||
sfunc->NumArgs = numargs;
|
||||
sfunc->ImplicitArgs = numargs;
|
||||
|
|
|
@ -688,7 +688,7 @@ DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLineDamaged);
|
|||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLightning)
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldTick)
|
||||
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, RenderFrame)
|
||||
//DEFINE_EMPTY_HANDLER(DStaticEventHandler, RenderFrame)
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, RenderOverlay)
|
||||
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, PlayerEntered)
|
||||
|
@ -972,6 +972,7 @@ static FRenderEvent E_SetupRenderEvent()
|
|||
|
||||
void DStaticEventHandler::RenderFrame()
|
||||
{
|
||||
/* This is intentionally and permanently disabled.
|
||||
IFVIRTUAL(DStaticEventHandler, RenderFrame)
|
||||
{
|
||||
// don't create excessive DObjects if not going to be processed anyway
|
||||
|
@ -981,6 +982,7 @@ void DStaticEventHandler::RenderFrame()
|
|||
VMValue params[2] = { (DStaticEventHandler*)this, &e };
|
||||
VMCall(func, params, 2, nullptr, 0);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void DStaticEventHandler::RenderOverlay(EHudState state)
|
||||
|
|
|
@ -4689,14 +4689,6 @@ void AActor::Tick ()
|
|||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, Tick)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
self->Tick();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// AActor :: CheckNoDelay
|
||||
|
@ -8282,13 +8274,6 @@ DEFINE_ACTION_FUNCTION(AActor, SetDamage)
|
|||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetDefaultByType)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_CLASS(cls, AActor);
|
||||
ACTION_RETURN_OBJECT(cls == nullptr? nullptr : GetDefaultByType(cls));
|
||||
}
|
||||
|
||||
// This combines all 3 variations of the internal function
|
||||
DEFINE_ACTION_FUNCTION(AActor, VelFromAngle)
|
||||
{
|
||||
|
|
|
@ -1899,13 +1899,6 @@ DEFINE_ACTION_FUNCTION(_Sector, NextLowestFloorAt)
|
|||
ACTION_RETURN_INT(self->GetLightLevel());
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Sector, ClearSpecial)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(sector_t);
|
||||
self->ClearSpecial();
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Sector, PortalBlocksView)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(sector_t);
|
||||
|
|
|
@ -259,7 +259,7 @@ void ExpEmit::Reuse(VMFunctionBuilder *build)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static PSymbol *FindBuiltinFunction(FName funcname, VMNativeFunction::NativeCallType func)
|
||||
static PSymbol *FindBuiltinFunction(FName funcname, VMNativeFunction::NativeCallType func, const uint8_t *reginfo)
|
||||
{
|
||||
PSymbol *sym = Namespaces.GlobalNamespace->Symbols.FindSymbol(funcname, false);
|
||||
if (sym == nullptr)
|
||||
|
@ -267,6 +267,7 @@ static PSymbol *FindBuiltinFunction(FName funcname, VMNativeFunction::NativeCall
|
|||
PSymbolVMFunction *symfunc = Create<PSymbolVMFunction>(funcname);
|
||||
VMNativeFunction *calldec = new VMNativeFunction(func, funcname);
|
||||
calldec->PrintableName = funcname.GetChars();
|
||||
calldec->RegTypes = reginfo;
|
||||
symfunc->Function = calldec;
|
||||
sym = symfunc;
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(sym);
|
||||
|
@ -5487,7 +5488,8 @@ ExpEmit FxRandom::Emit(VMFunctionBuilder *build)
|
|||
{
|
||||
// Call DecoRandom to generate a random number.
|
||||
VMFunction *callfunc;
|
||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinRandom, BuiltinRandom);
|
||||
static const uint8_t reginfo[] = { REGT_POINTER, REGT_INT, REGT_INT };
|
||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinRandom, BuiltinRandom, reginfo);
|
||||
|
||||
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
||||
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
||||
|
@ -5595,7 +5597,8 @@ ExpEmit FxRandomPick::Emit(VMFunctionBuilder *build)
|
|||
|
||||
// Call BuiltinRandom to generate a random number.
|
||||
VMFunction *callfunc;
|
||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinRandom, BuiltinRandom);
|
||||
static const uint8_t reginfo[] = { REGT_POINTER, REGT_INT, REGT_INT };
|
||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinRandom, BuiltinRandom, reginfo);
|
||||
|
||||
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
||||
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
||||
|
@ -5714,7 +5717,8 @@ ExpEmit FxFRandom::Emit(VMFunctionBuilder *build)
|
|||
{
|
||||
// Call the BuiltinFRandom function to generate a floating point random number..
|
||||
VMFunction *callfunc;
|
||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinFRandom, BuiltinFRandom);
|
||||
static uint8_t reginfo[] = { REGT_POINTER, REGT_FLOAT, REGT_FLOAT };
|
||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinFRandom, BuiltinFRandom, reginfo);
|
||||
|
||||
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
||||
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
||||
|
@ -5793,7 +5797,8 @@ ExpEmit FxRandom2::Emit(VMFunctionBuilder *build)
|
|||
{
|
||||
// Call the BuiltinRandom function to generate the random number.
|
||||
VMFunction *callfunc;
|
||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinRandom2, BuiltinRandom2);
|
||||
static uint8_t reginfo[] = { REGT_POINTER, REGT_INT };
|
||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinRandom2, BuiltinRandom2, reginfo);
|
||||
|
||||
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
||||
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
||||
|
@ -5865,7 +5870,8 @@ ExpEmit FxRandomSeed::Emit(VMFunctionBuilder *build)
|
|||
{
|
||||
// Call DecoRandom to generate a random number.
|
||||
VMFunction *callfunc;
|
||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinRandomSeed, BuiltinRandomSeed);
|
||||
static uint8_t reginfo[] = { REGT_POINTER, REGT_INT };
|
||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinRandomSeed, BuiltinRandomSeed, reginfo);
|
||||
|
||||
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
||||
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
||||
|
@ -8567,7 +8573,8 @@ ExpEmit FxActionSpecialCall::Emit(VMFunctionBuilder *build)
|
|||
}
|
||||
// Call the BuiltinCallLineSpecial function to perform the desired special.
|
||||
VMFunction *callfunc;
|
||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinCallLineSpecial, BuiltinCallLineSpecial);
|
||||
static uint8_t reginfo[] = { REGT_INT, REGT_POINTER, REGT_INT, REGT_INT, REGT_INT, REGT_INT, REGT_INT };
|
||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinCallLineSpecial, BuiltinCallLineSpecial, reginfo);
|
||||
|
||||
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
||||
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
||||
|
@ -10776,7 +10783,8 @@ ExpEmit FxClassTypeCast::Emit(VMFunctionBuilder *build)
|
|||
|
||||
// Call the BuiltinNameToClass function to convert from 'name' to class.
|
||||
VMFunction *callfunc;
|
||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinNameToClass, BuiltinNameToClass);
|
||||
static uint8_t reginfo[] = { REGT_INT, REGT_POINTER };
|
||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinNameToClass, BuiltinNameToClass, reginfo);
|
||||
|
||||
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
||||
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
||||
|
@ -10885,7 +10893,8 @@ ExpEmit FxClassPtrCast::Emit(VMFunctionBuilder *build)
|
|||
emitters.AddParameterPointerConst(desttype);
|
||||
|
||||
VMFunction *callfunc;
|
||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinClassCast, BuiltinClassCast);
|
||||
static uint8_t reginfo[] = { REGT_POINTER, REGT_POINTER };
|
||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinClassCast, BuiltinClassCast, reginfo);
|
||||
|
||||
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
||||
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
||||
|
|
|
@ -909,6 +909,7 @@ void FFunctionBuildList::Build()
|
|||
fprintf(dump, "\n*************************************************************************\n%i code bytes\n%i data bytes", codesize * 4, datasize);
|
||||
fclose(dump);
|
||||
}
|
||||
VMFunction::CreateRegUseInfo();
|
||||
FScriptPosition::StrictErrors = false;
|
||||
if (Args->CheckParm("-dumpjit")) DumpJit();
|
||||
mItems.Clear();
|
||||
|
|
|
@ -943,6 +943,8 @@ void InitThingdef()
|
|||
auto fcp = NewStruct("FCheckPosition", nullptr);
|
||||
fcp->mConstructor = *FindFunction(fcp, "_Constructor")->VMPointer;
|
||||
fcp->mDestructor = *FindFunction(fcp, "_Destructor")->VMPointer;
|
||||
static const uint8_t reguse[] = { REGT_POINTER };
|
||||
fcp->mConstructor->RegTypes = fcp->mDestructor->RegTypes = reguse;
|
||||
fcp->Size = sizeof(FCheckPosition);
|
||||
fcp->Align = alignof(FCheckPosition);
|
||||
|
||||
|
@ -991,11 +993,6 @@ void SynthesizeFlagFields()
|
|||
}
|
||||
}
|
||||
}
|
||||
DEFINE_ACTION_FUNCTION(DObject, GameType)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
ACTION_RETURN_INT(gameinfo.gametype);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DObject, BAM)
|
||||
{
|
||||
|
|
|
@ -319,10 +319,11 @@ class VMFunction
|
|||
{
|
||||
public:
|
||||
bool Unsafe = false;
|
||||
int VarFlags = 0; // [ZZ] this replaces 5+ bool fields
|
||||
uint8_t ImplicitArgs = 0; // either 0 for static, 1 for method or 3 for action
|
||||
int VarFlags = 0; // [ZZ] this replaces 5+ bool fields
|
||||
unsigned VirtualIndex = ~0u;
|
||||
FName Name;
|
||||
const uint8_t *RegTypes = nullptr;
|
||||
TArray<VMValue> DefaultArgs;
|
||||
FString PrintableName; // so that the VM can print meaningful info if something in this function goes wrong.
|
||||
|
||||
|
@ -352,8 +353,16 @@ public:
|
|||
}
|
||||
AllFunctions.Clear();
|
||||
}
|
||||
static void CreateRegUseInfo()
|
||||
{
|
||||
for (auto f : AllFunctions)
|
||||
{
|
||||
f->CreateRegUse();
|
||||
}
|
||||
}
|
||||
static TArray<VMFunction *> AllFunctions;
|
||||
protected:
|
||||
void CreateRegUse();
|
||||
};
|
||||
|
||||
class VMNativeFunction : public VMFunction
|
||||
|
|
|
@ -193,17 +193,20 @@ void VMFillParams(VMValue *params, VMFrame *callee, int numparam)
|
|||
const VMRegisters calleereg(callee);
|
||||
|
||||
assert(calleefunc != NULL && !(calleefunc->VarFlags & VARF_Native));
|
||||
assert(numparam == calleefunc->NumArgs || ((int)calleefunc->DefaultArgs.Size() == calleefunc->NumArgs));
|
||||
assert(numparam == calleefunc->NumArgs);
|
||||
assert(REGT_INT == 0 && REGT_FLOAT == 1 && REGT_STRING == 2 && REGT_POINTER == 3);
|
||||
|
||||
regd = regf = regs = rega = 0;
|
||||
for (int i = 0; i < calleefunc->NumArgs; ++i)
|
||||
const uint8_t *reginfo = calleefunc->RegTypes;
|
||||
assert(reginfo != nullptr);
|
||||
for (int i = 0; i < calleefunc->NumArgs; ++i, reginfo++)
|
||||
{
|
||||
// get all actual parameters and fill the rest from the defaults.
|
||||
VMValue &p = i < numparam? params[i] : calleefunc->DefaultArgs[i];
|
||||
if (p.Type < REGT_STRING)
|
||||
// copy all parameters to the local registers.
|
||||
VMValue &p = params[i];
|
||||
assert(*reginfo == p.Type);
|
||||
if (*reginfo < REGT_STRING)
|
||||
{
|
||||
if (p.Type == REGT_INT)
|
||||
if (*reginfo == REGT_INT)
|
||||
{
|
||||
calleereg.d[regd++] = p.i;
|
||||
}
|
||||
|
@ -212,13 +215,13 @@ void VMFillParams(VMValue *params, VMFrame *callee, int numparam)
|
|||
calleereg.f[regf++] = p.f;
|
||||
}
|
||||
}
|
||||
else if (p.Type == REGT_STRING)
|
||||
else if (*reginfo == REGT_STRING)
|
||||
{
|
||||
calleereg.s[regs++] = p.s();
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(p.Type == REGT_POINTER);
|
||||
assert(*reginfo == REGT_POINTER);
|
||||
calleereg.a[rega++] = p.a;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,6 +65,42 @@ IMPLEMENT_CLASS(VMException, false, false)
|
|||
|
||||
TArray<VMFunction *> VMFunction::AllFunctions;
|
||||
|
||||
// Creates the register type list for a function.
|
||||
// Native functions only need this to assert their parameters in debug mode, script functions use this to load their registers from the VMValues.
|
||||
void VMFunction::CreateRegUse()
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
if (VarFlags & VARF_Native) return; // we do not need this for native functions in release builds.
|
||||
#endif
|
||||
int count = 0;
|
||||
if (!Proto)
|
||||
{
|
||||
if (RegTypes) return;
|
||||
Printf(TEXTCOLOR_ORANGE "Function without prototype needs register info manually set: %s\n", PrintableName.GetChars());
|
||||
return;
|
||||
}
|
||||
assert(Proto->isPrototype());
|
||||
for (auto arg : Proto->ArgumentTypes)
|
||||
{
|
||||
count += arg? arg->GetRegCount() : 1;
|
||||
}
|
||||
uint8_t *regp;
|
||||
RegTypes = regp = (uint8_t*)ClassDataAllocator.Alloc(count);
|
||||
count = 0;
|
||||
for (auto arg : Proto->ArgumentTypes)
|
||||
{
|
||||
if (arg == nullptr)
|
||||
{
|
||||
// Marker for start of varargs.
|
||||
*regp++ = REGT_NIL;
|
||||
}
|
||||
else for (int i = 0; i < arg->GetRegCount(); i++)
|
||||
{
|
||||
*regp++ = arg->GetRegType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VMScriptFunction::VMScriptFunction(FName name)
|
||||
{
|
||||
Name = name;
|
||||
|
|
|
@ -34,6 +34,7 @@ struct SectorPortal native play
|
|||
struct Vertex native play
|
||||
{
|
||||
native readonly Vector2 p;
|
||||
native int Index();
|
||||
}
|
||||
|
||||
struct Side native play
|
||||
|
|
Loading…
Reference in a new issue