mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 23:32:04 +00:00
- Added DecoFindSingleNameState for the extremely common case of finding a state with only
one name in its label. This avoids the alloca and security cookie calls. - Consolidated lots of copy-pasted code in thingdef_expression.cpp to install helper functions into FindDecorateBuiltinFunction(). SVN r3907 (scripting)
This commit is contained in:
parent
5c6bf0aeb4
commit
1a02d16356
3 changed files with 80 additions and 76 deletions
|
@ -557,3 +557,4 @@ xx(DecoFRandom)
|
||||||
xx(DecoCallLineSpecial)
|
xx(DecoCallLineSpecial)
|
||||||
xx(DecoNameToClass)
|
xx(DecoNameToClass)
|
||||||
xx(DecoFindMultiNameState)
|
xx(DecoFindMultiNameState)
|
||||||
|
xx(DecoFindSingleNameState)
|
||||||
|
|
|
@ -97,6 +97,29 @@ void ExpEmit::Free(VMFunctionBuilder *build)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FindDecorateBuiltinFunction
|
||||||
|
//
|
||||||
|
// Returns the symbol for a decorate utility function. If not found, create
|
||||||
|
// it and install it in Actor.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static PSymbol *FindDecorateBuiltinFunction(FName funcname, VMNativeFunction::NativeCallType func)
|
||||||
|
{
|
||||||
|
PSymbol *sym = RUNTIME_CLASS(AActor)->Symbols.FindSymbol(funcname, false);
|
||||||
|
if (sym == NULL)
|
||||||
|
{
|
||||||
|
PSymbolVMFunction *symfunc = new PSymbolVMFunction(funcname);
|
||||||
|
VMNativeFunction *calldec = new VMNativeFunction(func, funcname);
|
||||||
|
symfunc->Function = calldec;
|
||||||
|
sym = symfunc;
|
||||||
|
RUNTIME_CLASS(AActor)->Symbols.AddSymbol(sym);
|
||||||
|
}
|
||||||
|
return sym;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// EvalExpression
|
// EvalExpression
|
||||||
|
@ -2485,18 +2508,10 @@ int DecoRandom(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret,
|
||||||
|
|
||||||
ExpEmit FxRandom::Emit(VMFunctionBuilder *build)
|
ExpEmit FxRandom::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
// Find the DecoRandom function. If not found, create it and install it
|
// Call DecoRandom to generate a random number.
|
||||||
// in Actor.
|
|
||||||
VMFunction *callfunc;
|
VMFunction *callfunc;
|
||||||
PSymbol *sym = RUNTIME_CLASS(AActor)->Symbols.FindSymbol(NAME_DecoRandom, false);
|
PSymbol *sym = FindDecorateBuiltinFunction(NAME_DecoRandom, DecoRandom);
|
||||||
if (sym == NULL)
|
|
||||||
{
|
|
||||||
PSymbolVMFunction *symfunc = new PSymbolVMFunction(NAME_DecoRandom);
|
|
||||||
VMNativeFunction *calldec = new VMNativeFunction(DecoRandom, NAME_DecoRandom);
|
|
||||||
symfunc->Function = calldec;
|
|
||||||
sym = symfunc;
|
|
||||||
RUNTIME_CLASS(AActor)->Symbols.AddSymbol(sym);
|
|
||||||
}
|
|
||||||
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
||||||
assert(((PSymbolVMFunction *)sym)->Function != NULL);
|
assert(((PSymbolVMFunction *)sym)->Function != NULL);
|
||||||
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
||||||
|
@ -2591,18 +2606,10 @@ int DecoFRandom(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret
|
||||||
|
|
||||||
ExpEmit FxFRandom::Emit(VMFunctionBuilder *build)
|
ExpEmit FxFRandom::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
// Find the DecoFRandom function. If not found, create it and install it
|
// Call the DecoFRandom function to generate a floating point random number..
|
||||||
// in Actor.
|
|
||||||
VMFunction *callfunc;
|
VMFunction *callfunc;
|
||||||
PSymbol *sym = RUNTIME_CLASS(AActor)->Symbols.FindSymbol(NAME_DecoFRandom, false);
|
PSymbol *sym = FindDecorateBuiltinFunction(NAME_DecoFRandom, DecoFRandom);
|
||||||
if (sym == NULL)
|
|
||||||
{
|
|
||||||
PSymbolVMFunction *symfunc = new PSymbolVMFunction(NAME_DecoFRandom);
|
|
||||||
VMNativeFunction *calldec = new VMNativeFunction(DecoFRandom, NAME_DecoFRandom);
|
|
||||||
symfunc->Function = calldec;
|
|
||||||
sym = symfunc;
|
|
||||||
RUNTIME_CLASS(AActor)->Symbols.AddSymbol(sym);
|
|
||||||
}
|
|
||||||
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
||||||
assert(((PSymbolVMFunction *)sym)->Function != NULL);
|
assert(((PSymbolVMFunction *)sym)->Function != NULL);
|
||||||
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
||||||
|
@ -2681,18 +2688,10 @@ ExpVal FxRandom2::EvalExpression (AActor *self)
|
||||||
|
|
||||||
ExpEmit FxRandom2::Emit(VMFunctionBuilder *build)
|
ExpEmit FxRandom2::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
// Find the DecoRandom function. If not found, create it and install it
|
// Call the DecoRandom function to generate the random number.
|
||||||
// in Actor.
|
|
||||||
VMFunction *callfunc;
|
VMFunction *callfunc;
|
||||||
PSymbol *sym = RUNTIME_CLASS(AActor)->Symbols.FindSymbol(NAME_DecoRandom, false);
|
PSymbol *sym = FindDecorateBuiltinFunction(NAME_DecoRandom, DecoRandom);
|
||||||
if (sym == NULL)
|
|
||||||
{
|
|
||||||
PSymbolVMFunction *symfunc = new PSymbolVMFunction(NAME_DecoRandom);
|
|
||||||
VMNativeFunction *calldec = new VMNativeFunction(DecoRandom, NAME_DecoRandom);
|
|
||||||
symfunc->Function = calldec;
|
|
||||||
sym = symfunc;
|
|
||||||
RUNTIME_CLASS(AActor)->Symbols.AddSymbol(sym);
|
|
||||||
}
|
|
||||||
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
||||||
assert(((PSymbolVMFunction *)sym)->Function != NULL);
|
assert(((PSymbolVMFunction *)sym)->Function != NULL);
|
||||||
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
||||||
|
@ -3537,18 +3536,10 @@ ExpEmit FxActionSpecialCall::Emit(VMFunctionBuilder *build)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Find the DecoCallLineSpecial function. If not found, create it and install it
|
// Call the DecoCallLineSpecial function to perform the desired special.
|
||||||
// in Actor.
|
|
||||||
VMFunction *callfunc;
|
VMFunction *callfunc;
|
||||||
PSymbol *sym = RUNTIME_CLASS(AActor)->Symbols.FindSymbol(NAME_DecoCallLineSpecial, false);
|
PSymbol *sym = FindDecorateBuiltinFunction(NAME_DecoCallLineSpecial, DecoCallLineSpecial);
|
||||||
if (sym == NULL)
|
|
||||||
{
|
|
||||||
PSymbolVMFunction *symfunc = new PSymbolVMFunction(NAME_DecoCallLineSpecial);
|
|
||||||
VMNativeFunction *calldec = new VMNativeFunction(DecoCallLineSpecial, NAME_DecoCallLineSpecial);
|
|
||||||
symfunc->Function = calldec;
|
|
||||||
sym = symfunc;
|
|
||||||
RUNTIME_CLASS(AActor)->Symbols.AddSymbol(sym);
|
|
||||||
}
|
|
||||||
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
||||||
assert(((PSymbolVMFunction *)sym)->Function != NULL);
|
assert(((PSymbolVMFunction *)sym)->Function != NULL);
|
||||||
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
||||||
|
@ -3802,18 +3793,10 @@ ExpEmit FxClassTypeCast::Emit(VMFunctionBuilder *build)
|
||||||
build->Emit(OP_PARAM, 0, clsname.RegType, clsname.RegNum);
|
build->Emit(OP_PARAM, 0, clsname.RegType, clsname.RegNum);
|
||||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(const_cast<PClass *>(desttype), ATAG_OBJECT));
|
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(const_cast<PClass *>(desttype), ATAG_OBJECT));
|
||||||
|
|
||||||
// Find the DecoNameToClass function. If not found, create it and install it
|
// Call the DecoNameToClass function to convert from 'name' to class.
|
||||||
// in Actor.
|
|
||||||
VMFunction *callfunc;
|
VMFunction *callfunc;
|
||||||
PSymbol *sym = RUNTIME_CLASS(AActor)->Symbols.FindSymbol(NAME_DecoNameToClass, false);
|
PSymbol *sym = FindDecorateBuiltinFunction(NAME_DecoNameToClass, DecoNameToClass);
|
||||||
if (sym == NULL)
|
|
||||||
{
|
|
||||||
PSymbolVMFunction *symfunc = new PSymbolVMFunction(NAME_DecoNameToClass);
|
|
||||||
VMNativeFunction *calldec = new VMNativeFunction(DecoNameToClass, NAME_DecoNameToClass);
|
|
||||||
symfunc->Function = calldec;
|
|
||||||
sym = symfunc;
|
|
||||||
RUNTIME_CLASS(AActor)->Symbols.AddSymbol(sym);
|
|
||||||
}
|
|
||||||
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
||||||
assert(((PSymbolVMFunction *)sym)->Function != NULL);
|
assert(((PSymbolVMFunction *)sym)->Function != NULL);
|
||||||
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
||||||
|
@ -3964,18 +3947,8 @@ ExpVal FxMultiNameState::EvalExpression (AActor *self)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DecoFindMultiNameState(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret)
|
static int DoFindState(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, FName *names, int numnames)
|
||||||
{
|
{
|
||||||
assert(numparam > 1);
|
|
||||||
assert(numret == 1);
|
|
||||||
assert(ret->RegType == REGT_POINTER);
|
|
||||||
|
|
||||||
FName *names = (FName *)alloca((numparam - 1) * sizeof(FName));
|
|
||||||
for (int i = 1; i < numparam; ++i)
|
|
||||||
{
|
|
||||||
PARAM_NAME_AT(i, zaname);
|
|
||||||
names[i - 1] = zaname;
|
|
||||||
}
|
|
||||||
PARAM_OBJECT_AT(0, self, AActor);
|
PARAM_OBJECT_AT(0, self, AActor);
|
||||||
FState *state = self->GetClass()->FindState(numparam - 1, names);
|
FState *state = self->GetClass()->FindState(numparam - 1, names);
|
||||||
if (state == NULL)
|
if (state == NULL)
|
||||||
|
@ -3991,6 +3964,34 @@ int DecoFindMultiNameState(VMFrameStack *stack, VMValue *param, int numparam, VM
|
||||||
}
|
}
|
||||||
ret->SetPointer(state, ATAG_STATE);
|
ret->SetPointer(state, ATAG_STATE);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find a state with any number of dots in its name.
|
||||||
|
int DecoFindMultiNameState(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret)
|
||||||
|
{
|
||||||
|
assert(numparam > 1);
|
||||||
|
assert(numret == 1);
|
||||||
|
assert(ret->RegType == REGT_POINTER);
|
||||||
|
|
||||||
|
FName *names = (FName *)alloca((numparam - 1) * sizeof(FName));
|
||||||
|
for (int i = 1; i < numparam; ++i)
|
||||||
|
{
|
||||||
|
PARAM_NAME_AT(i, zaname);
|
||||||
|
names[i - 1] = zaname;
|
||||||
|
}
|
||||||
|
return DoFindState(stack, param, numparam, ret, names, numparam - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find a state without any dots in its name.
|
||||||
|
int DecoFindSingleNameState(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret)
|
||||||
|
{
|
||||||
|
assert(numparam == 2);
|
||||||
|
assert(numret == 1);
|
||||||
|
assert(ret->RegType == REGT_POINTER);
|
||||||
|
|
||||||
|
PARAM_NAME_AT(1, zaname);
|
||||||
|
return DoFindState(stack, param, numparam, ret, &zaname, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpEmit FxMultiNameState::Emit(VMFunctionBuilder *build)
|
ExpEmit FxMultiNameState::Emit(VMFunctionBuilder *build)
|
||||||
|
@ -4002,18 +4003,20 @@ ExpEmit FxMultiNameState::Emit(VMFunctionBuilder *build)
|
||||||
EmitConstantInt(build, names[i]);
|
EmitConstantInt(build, names[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the DecoFindMultiNameState function. If not found, create it and install it
|
// For one name, use the DecoFindSingleNameState function. For more than
|
||||||
// in Actor.
|
// one name, use the DecoFindMultiNameState function.
|
||||||
VMFunction *callfunc;
|
VMFunction *callfunc;
|
||||||
PSymbol *sym = RUNTIME_CLASS(AActor)->Symbols.FindSymbol(NAME_DecoFindMultiNameState, false);
|
PSymbol *sym;
|
||||||
if (sym == NULL)
|
|
||||||
|
if (names.Size() == 1)
|
||||||
{
|
{
|
||||||
PSymbolVMFunction *symfunc = new PSymbolVMFunction(NAME_DecoFindMultiNameState);
|
sym = FindDecorateBuiltinFunction(NAME_DecoFindSingleNameState, DecoFindSingleNameState);
|
||||||
VMNativeFunction *calldec = new VMNativeFunction(DecoFindMultiNameState, NAME_DecoFindMultiNameState);
|
|
||||||
symfunc->Function = calldec;
|
|
||||||
sym = symfunc;
|
|
||||||
RUNTIME_CLASS(AActor)->Symbols.AddSymbol(sym);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sym = FindDecorateBuiltinFunction(NAME_DecoFindMultiNameState, DecoFindMultiNameState);
|
||||||
|
}
|
||||||
|
|
||||||
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
||||||
assert(((PSymbolVMFunction *)sym)->Function != NULL);
|
assert(((PSymbolVMFunction *)sym)->Function != NULL);
|
||||||
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
||||||
|
|
|
@ -131,8 +131,8 @@ void VMSelectEngine(EVMEngine engine)
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
VMExec = VMExec_Unchecked::Exec;
|
VMExec = VMExec_Unchecked::Exec;
|
||||||
#else
|
#else
|
||||||
VMExec = VMExec_Checked::Exec;
|
|
||||||
#endif
|
#endif
|
||||||
|
VMExec = VMExec_Checked::Exec;
|
||||||
break;
|
break;
|
||||||
case VMEngine_Unchecked:
|
case VMEngine_Unchecked:
|
||||||
VMExec = VMExec_Unchecked::Exec;
|
VMExec = VMExec_Unchecked::Exec;
|
||||||
|
|
Loading…
Reference in a new issue