mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 15:22:16 +00:00
- implemented VMCallWithDefaults and used it for all calls with variable arguments.
This isn't used for the 3 action function calls because it requires an array allocation which would be a bit too costly for something as frequently called as action functions. They will need a different approach.
This commit is contained in:
parent
6d7710165c
commit
97573a0452
6 changed files with 23 additions and 12 deletions
|
@ -175,13 +175,13 @@ bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info,
|
||||||
|
|
||||||
if (stateret == nullptr)
|
if (stateret == nullptr)
|
||||||
{
|
{
|
||||||
VMCallWithDefaults(ActionFunc, params, ActionFunc->ImplicitArgs, nullptr, 0);
|
VMCallAction(ActionFunc, params, ActionFunc->ImplicitArgs, nullptr, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VMReturn ret;
|
VMReturn ret;
|
||||||
ret.PointerAt((void **)stateret);
|
ret.PointerAt((void **)stateret);
|
||||||
VMCallWithDefaults(ActionFunc, params, ActionFunc->ImplicitArgs, &ret, 1);
|
VMCallAction(ActionFunc, params, ActionFunc->ImplicitArgs, &ret, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (CVMAbortException &err)
|
catch (CVMAbortException &err)
|
||||||
|
|
|
@ -477,7 +477,7 @@ static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc)
|
||||||
}
|
}
|
||||||
DMenuItemBase *item = (DMenuItemBase*)cls->CreateNew();
|
DMenuItemBase *item = (DMenuItemBase*)cls->CreateNew();
|
||||||
params[0] = item;
|
params[0] = item;
|
||||||
VMCallWithDefaults(func->Variants[0].Implementation, ¶ms[0], params.Size(), nullptr, 0);
|
VMCallWithDefaults(func->Variants[0].Implementation, params, nullptr, 0);
|
||||||
desc->mItems.Push((DMenuItemBase*)item);
|
desc->mItems.Push((DMenuItemBase*)item);
|
||||||
|
|
||||||
if (cls->IsDescendantOf("ListMenuItemSelectable"))
|
if (cls->IsDescendantOf("ListMenuItemSelectable"))
|
||||||
|
@ -917,7 +917,7 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc)
|
||||||
|
|
||||||
DMenuItemBase *item = (DMenuItemBase*)cls->CreateNew();
|
DMenuItemBase *item = (DMenuItemBase*)cls->CreateNew();
|
||||||
params[0] = item;
|
params[0] = item;
|
||||||
VMCallWithDefaults(func->Variants[0].Implementation, ¶ms[0], params.Size(), nullptr, 0);
|
VMCallWithDefaults(func->Variants[0].Implementation, params, nullptr, 0);
|
||||||
desc->mItems.Push((DMenuItemBase*)item);
|
desc->mItems.Push((DMenuItemBase*)item);
|
||||||
|
|
||||||
success = true;
|
success = true;
|
||||||
|
|
|
@ -5448,7 +5448,7 @@ static int ScriptCall(AActor *activator, unsigned argc, int32_t *args)
|
||||||
// The return value can be the same types as the parameter types, plus void
|
// The return value can be the same types as the parameter types, plus void
|
||||||
if (func->Proto->ReturnTypes.Size() == 0)
|
if (func->Proto->ReturnTypes.Size() == 0)
|
||||||
{
|
{
|
||||||
VMCallWithDefaults(func, ¶ms[0], params.Size(), nullptr, 0);
|
VMCallWithDefaults(func, params, nullptr, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -5470,20 +5470,20 @@ static int ScriptCall(AActor *activator, unsigned argc, int32_t *args)
|
||||||
{
|
{
|
||||||
double d;
|
double d;
|
||||||
VMReturn ret(&d);
|
VMReturn ret(&d);
|
||||||
VMCallWithDefaults(func, ¶ms[0], params.Size(), &ret, 1);
|
VMCallWithDefaults(func, params, &ret, 1);
|
||||||
retval = DoubleToACS(d);
|
retval = DoubleToACS(d);
|
||||||
}
|
}
|
||||||
else if (rettype == TypeString)
|
else if (rettype == TypeString)
|
||||||
{
|
{
|
||||||
FString d;
|
FString d;
|
||||||
VMReturn ret(&d);
|
VMReturn ret(&d);
|
||||||
VMCallWithDefaults(func, ¶ms[0], params.Size(), &ret, 1);
|
VMCallWithDefaults(func, params, &ret, 1);
|
||||||
retval = GlobalACSStrings.AddString(d);
|
retval = GlobalACSStrings.AddString(d);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// All other return values can not be handled so ignore them.
|
// All other return values can not be handled so ignore them.
|
||||||
VMCallWithDefaults(func, ¶ms[0], params.Size(), nullptr, 0);
|
VMCallWithDefaults(func, params, nullptr, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,7 +170,7 @@ bool AStateProvider::CallStateChain (AActor *actor, FState *state)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
state->CheckCallerType(actor, this);
|
state->CheckCallerType(actor, this);
|
||||||
VMCallWithDefaults(state->ActionFunc, params, state->ActionFunc->ImplicitArgs, wantret, numret);
|
VMCallAction(state->ActionFunc, params, state->ActionFunc->ImplicitArgs, wantret, numret);
|
||||||
}
|
}
|
||||||
catch (CVMAbortException &err)
|
catch (CVMAbortException &err)
|
||||||
{
|
{
|
||||||
|
|
|
@ -209,8 +209,6 @@ struct VMValue
|
||||||
const FString *sp;
|
const FString *sp;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Unfortunately, FString cannot be used directly.
|
|
||||||
// Fortunately, it is relatively simple.
|
|
||||||
const FString &s() const { return *sp; }
|
const FString &s() const { return *sp; }
|
||||||
|
|
||||||
VMValue()
|
VMValue()
|
||||||
|
@ -376,8 +374,9 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
int VMCall(VMFunction *func, VMValue *params, int numparams, VMReturn *results, int numresults/*, VMException **trap = NULL*/);
|
int VMCall(VMFunction *func, VMValue *params, int numparams, VMReturn *results, int numresults/*, VMException **trap = NULL*/);
|
||||||
|
int VMCallWithDefaults(VMFunction *func, TArray<VMValue> ¶ms, VMReturn *results, int numresults/*, VMException **trap = NULL*/);
|
||||||
|
|
||||||
inline int VMCallWithDefaults(VMFunction *func, VMValue *params, int numparams, VMReturn *results, int numresults/*, VMException **trap = NULL*/)
|
inline int VMCallAction(VMFunction *func, VMValue *params, int numparams, VMReturn *results, int numresults/*, VMException **trap = NULL*/)
|
||||||
{
|
{
|
||||||
return VMCall(func, params, numparams, results, numresults);
|
return VMCall(func, params, numparams, results, numresults);
|
||||||
}
|
}
|
||||||
|
|
|
@ -577,6 +577,18 @@ int VMCall(VMFunction *func, VMValue *params, int numparams, VMReturn *results,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int VMCallWithDefaults(VMFunction *func, TArray<VMValue> ¶ms, VMReturn *results, int numresults/*, VMException **trap = NULL*/)
|
||||||
|
{
|
||||||
|
if (func->DefaultArgs.Size() > params.Size())
|
||||||
|
{
|
||||||
|
auto oldp = params.Size();
|
||||||
|
params.Resize(func->DefaultArgs.Size());
|
||||||
|
memcpy(¶ms[oldp], &func->DefaultArgs[oldp], (params.Size() - oldp) * sizeof(VMValue));
|
||||||
|
}
|
||||||
|
return VMCall(func, params.Data(), params.Size(), results, numresults);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Exception stuff for the VM is intentionally placed there, because having this in vmexec.cpp would subject it to inlining
|
// Exception stuff for the VM is intentionally placed there, because having this in vmexec.cpp would subject it to inlining
|
||||||
// which we do not want because it increases the local stack requirements of Exec which are already too high.
|
// which we do not want because it increases the local stack requirements of Exec which are already too high.
|
||||||
FString CVMAbortException::stacktrace;
|
FString CVMAbortException::stacktrace;
|
||||||
|
|
Loading…
Reference in a new issue