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)
|
||||
{
|
||||
VMCallWithDefaults(ActionFunc, params, ActionFunc->ImplicitArgs, nullptr, 0);
|
||||
VMCallAction(ActionFunc, params, ActionFunc->ImplicitArgs, nullptr, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
VMReturn ret;
|
||||
ret.PointerAt((void **)stateret);
|
||||
VMCallWithDefaults(ActionFunc, params, ActionFunc->ImplicitArgs, &ret, 1);
|
||||
VMCallAction(ActionFunc, params, ActionFunc->ImplicitArgs, &ret, 1);
|
||||
}
|
||||
}
|
||||
catch (CVMAbortException &err)
|
||||
|
|
|
@ -477,7 +477,7 @@ static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc)
|
|||
}
|
||||
DMenuItemBase *item = (DMenuItemBase*)cls->CreateNew();
|
||||
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);
|
||||
|
||||
if (cls->IsDescendantOf("ListMenuItemSelectable"))
|
||||
|
@ -917,7 +917,7 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc)
|
|||
|
||||
DMenuItemBase *item = (DMenuItemBase*)cls->CreateNew();
|
||||
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);
|
||||
|
||||
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
|
||||
if (func->Proto->ReturnTypes.Size() == 0)
|
||||
{
|
||||
VMCallWithDefaults(func, ¶ms[0], params.Size(), nullptr, 0);
|
||||
VMCallWithDefaults(func, params, nullptr, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5470,20 +5470,20 @@ static int ScriptCall(AActor *activator, unsigned argc, int32_t *args)
|
|||
{
|
||||
double d;
|
||||
VMReturn ret(&d);
|
||||
VMCallWithDefaults(func, ¶ms[0], params.Size(), &ret, 1);
|
||||
VMCallWithDefaults(func, params, &ret, 1);
|
||||
retval = DoubleToACS(d);
|
||||
}
|
||||
else if (rettype == TypeString)
|
||||
{
|
||||
FString d;
|
||||
VMReturn ret(&d);
|
||||
VMCallWithDefaults(func, ¶ms[0], params.Size(), &ret, 1);
|
||||
VMCallWithDefaults(func, params, &ret, 1);
|
||||
retval = GlobalACSStrings.AddString(d);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -209,8 +209,6 @@ struct VMValue
|
|||
const FString *sp;
|
||||
};
|
||||
|
||||
// Unfortunately, FString cannot be used directly.
|
||||
// Fortunately, it is relatively simple.
|
||||
const FString &s() const { return *sp; }
|
||||
|
||||
VMValue()
|
||||
|
@ -376,8 +374,9 @@ private:
|
|||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -577,6 +577,18 @@ int VMCall(VMFunction *func, VMValue *params, int numparams, VMReturn *results,
|
|||
#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
|
||||
// which we do not want because it increases the local stack requirements of Exec which are already too high.
|
||||
FString CVMAbortException::stacktrace;
|
||||
|
|
Loading…
Reference in a new issue