From 1a02d163562215c87ec4d20d29c1c1a489924301 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 26 Oct 2012 04:04:06 +0000 Subject: [PATCH] - 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) --- src/namedef.h | 1 + src/thingdef/thingdef_expression.cpp | 153 ++++++++++++++------------- src/zscript/vmexec.cpp | 2 +- 3 files changed, 80 insertions(+), 76 deletions(-) diff --git a/src/namedef.h b/src/namedef.h index 95a5aca9a..48d7a6a90 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -557,3 +557,4 @@ xx(DecoFRandom) xx(DecoCallLineSpecial) xx(DecoNameToClass) xx(DecoFindMultiNameState) +xx(DecoFindSingleNameState) diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index 671bb55a8..d1c225e90 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -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 @@ -2485,18 +2508,10 @@ int DecoRandom(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, ExpEmit FxRandom::Emit(VMFunctionBuilder *build) { - // Find the DecoRandom function. If not found, create it and install it - // in Actor. + // Call DecoRandom to generate a random number. VMFunction *callfunc; - PSymbol *sym = RUNTIME_CLASS(AActor)->Symbols.FindSymbol(NAME_DecoRandom, false); - 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); - } + PSymbol *sym = FindDecorateBuiltinFunction(NAME_DecoRandom, DecoRandom); + assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction))); assert(((PSymbolVMFunction *)sym)->Function != NULL); callfunc = ((PSymbolVMFunction *)sym)->Function; @@ -2591,18 +2606,10 @@ int DecoFRandom(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret ExpEmit FxFRandom::Emit(VMFunctionBuilder *build) { - // Find the DecoFRandom function. If not found, create it and install it - // in Actor. + // Call the DecoFRandom function to generate a floating point random number.. VMFunction *callfunc; - PSymbol *sym = RUNTIME_CLASS(AActor)->Symbols.FindSymbol(NAME_DecoFRandom, false); - 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); - } + PSymbol *sym = FindDecorateBuiltinFunction(NAME_DecoFRandom, DecoFRandom); + assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction))); assert(((PSymbolVMFunction *)sym)->Function != NULL); callfunc = ((PSymbolVMFunction *)sym)->Function; @@ -2681,18 +2688,10 @@ ExpVal FxRandom2::EvalExpression (AActor *self) ExpEmit FxRandom2::Emit(VMFunctionBuilder *build) { - // Find the DecoRandom function. If not found, create it and install it - // in Actor. + // Call the DecoRandom function to generate the random number. VMFunction *callfunc; - PSymbol *sym = RUNTIME_CLASS(AActor)->Symbols.FindSymbol(NAME_DecoRandom, false); - 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); - } + PSymbol *sym = FindDecorateBuiltinFunction(NAME_DecoRandom, DecoRandom); + assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction))); assert(((PSymbolVMFunction *)sym)->Function != NULL); 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 - // in Actor. + // Call the DecoCallLineSpecial function to perform the desired special. VMFunction *callfunc; - PSymbol *sym = RUNTIME_CLASS(AActor)->Symbols.FindSymbol(NAME_DecoCallLineSpecial, false); - 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); - } + PSymbol *sym = FindDecorateBuiltinFunction(NAME_DecoCallLineSpecial, DecoCallLineSpecial); + assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction))); assert(((PSymbolVMFunction *)sym)->Function != NULL); 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, REGT_POINTER | REGT_KONST, build->GetConstantAddress(const_cast(desttype), ATAG_OBJECT)); - // Find the DecoNameToClass function. If not found, create it and install it - // in Actor. + // Call the DecoNameToClass function to convert from 'name' to class. VMFunction *callfunc; - PSymbol *sym = RUNTIME_CLASS(AActor)->Symbols.FindSymbol(NAME_DecoNameToClass, false); - 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); - } + PSymbol *sym = FindDecorateBuiltinFunction(NAME_DecoNameToClass, DecoNameToClass); + assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction))); assert(((PSymbolVMFunction *)sym)->Function != NULL); callfunc = ((PSymbolVMFunction *)sym)->Function; @@ -3964,18 +3947,8 @@ ExpVal FxMultiNameState::EvalExpression (AActor *self) 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); FState *state = self->GetClass()->FindState(numparam - 1, names); if (state == NULL) @@ -3991,6 +3964,34 @@ int DecoFindMultiNameState(VMFrameStack *stack, VMValue *param, int numparam, VM } ret->SetPointer(state, ATAG_STATE); 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) @@ -4002,18 +4003,20 @@ ExpEmit FxMultiNameState::Emit(VMFunctionBuilder *build) EmitConstantInt(build, names[i]); } - // Find the DecoFindMultiNameState function. If not found, create it and install it - // in Actor. + // For one name, use the DecoFindSingleNameState function. For more than + // one name, use the DecoFindMultiNameState function. VMFunction *callfunc; - PSymbol *sym = RUNTIME_CLASS(AActor)->Symbols.FindSymbol(NAME_DecoFindMultiNameState, false); - if (sym == NULL) + PSymbol *sym; + + if (names.Size() == 1) { - PSymbolVMFunction *symfunc = new PSymbolVMFunction(NAME_DecoFindMultiNameState); - VMNativeFunction *calldec = new VMNativeFunction(DecoFindMultiNameState, NAME_DecoFindMultiNameState); - symfunc->Function = calldec; - sym = symfunc; - RUNTIME_CLASS(AActor)->Symbols.AddSymbol(sym); + sym = FindDecorateBuiltinFunction(NAME_DecoFindSingleNameState, DecoFindSingleNameState); } + else + { + sym = FindDecorateBuiltinFunction(NAME_DecoFindMultiNameState, DecoFindMultiNameState); + } + assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction))); assert(((PSymbolVMFunction *)sym)->Function != NULL); callfunc = ((PSymbolVMFunction *)sym)->Function; diff --git a/src/zscript/vmexec.cpp b/src/zscript/vmexec.cpp index 8ad349cf7..ceecf5e01 100644 --- a/src/zscript/vmexec.cpp +++ b/src/zscript/vmexec.cpp @@ -131,8 +131,8 @@ void VMSelectEngine(EVMEngine engine) #ifdef NDEBUG VMExec = VMExec_Unchecked::Exec; #else - VMExec = VMExec_Checked::Exec; #endif + VMExec = VMExec_Checked::Exec; break; case VMEngine_Unchecked: VMExec = VMExec_Unchecked::Exec;