diff --git a/CMakeLists.txt b/CMakeLists.txt index 91a862c5..bc287243 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -133,7 +133,6 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") message(STATUS "Detected GCC version 4.7+") set(NORMAL_CXX_FLAGS "-std=gnu++11 -Wall -Wold-style-cast -pedantic-errors") - set(NORMAL_CXX_FLAGS "${NORMAL_CXX_FLAGS} -fno-delete-null-pointer-checks") # Temporary hack, see #828 set(RELEASE_CXX_FLAGS "-O2") set(DEBUG_CXX_FLAGS "-g -O0") set(TEST_CXX_FLAGS "-pthread") diff --git a/src/CBot/CBotCStack.cpp b/src/CBot/CBotCStack.cpp index c8c01346..044a473e 100644 --- a/src/CBot/CBotCStack.cpp +++ b/src/CBot/CBotCStack.cpp @@ -350,7 +350,7 @@ CBotTypResult CBotCStack::CompileCall(CBotToken* &p, CBotVar** ppVars, long& nId val = m_prog->GetExternalCalls()->CompileCall(p, nullptr, ppVars, this); if (val.GetType() < 0) { - val = m_prog->GetFunctions()->CompileCall(p->GetString(), ppVars, nIdent); + val = CBotFunction::CompileCall(m_prog->GetFunctions(), p->GetString(), ppVars, nIdent); if ( val.GetType() < 0 ) { // pVar = nullptr; // the error is not on a particular parameter diff --git a/src/CBot/CBotClass.cpp b/src/CBot/CBotClass.cpp index 8efc4af8..0eb86db0 100644 --- a/src/CBot/CBotClass.cpp +++ b/src/CBot/CBotClass.cpp @@ -331,7 +331,7 @@ CBotTypResult CBotClass::CompileMethode(const std::string& name, // find the methods declared by user - r = m_pMethod->CompileCall(name, ppParams, nIdent); + r = CBotFunction::CompileCall(m_pMethod, name, ppParams, nIdent); if ( r.Eq(CBotErrUndefCall) && m_parent != nullptr ) return m_parent->CompileMethode(name, pThis, ppParams, pStack, nIdent); return r; @@ -349,7 +349,7 @@ bool CBotClass::ExecuteMethode(long& nIdent, int ret = m_pCalls->DoCall(name, pThis, ppParams, pResult, pStack, pToken); if (ret>=0) return ret; - ret = m_pMethod->DoCall(nIdent, name, pThis, ppParams, pStack, pToken, this); + ret = CBotFunction::DoCall(m_pMethod, nIdent, name, pThis, ppParams, pStack, pToken, this); if (ret >= 0) return ret; if (m_parent != nullptr) @@ -369,7 +369,7 @@ void CBotClass::RestoreMethode(long& nIdent, CBotClass* pClass = this; while (pClass != nullptr) { - bool ok = pClass->m_pMethod->RestoreCall(nIdent, name, pThis, ppParams, pStack, pClass); + bool ok = CBotFunction::RestoreCall(pClass->m_pMethod, nIdent, name, pThis, ppParams, pStack, pClass); if (ok) return; pClass = pClass->m_parent; } diff --git a/src/CBot/CBotInstr/CBotFunction.cpp b/src/CBot/CBotInstr/CBotFunction.cpp index 0b1e05b5..2885f1a9 100644 --- a/src/CBot/CBotInstr/CBotFunction.cpp +++ b/src/CBot/CBotInstr/CBotFunction.cpp @@ -421,26 +421,27 @@ void CBotFunction::AddNext(CBotFunction* p) } //////////////////////////////////////////////////////////////////////////////// -CBotTypResult CBotFunction::CompileCall(const std::string& name, CBotVar** ppVars, long& nIdent) +CBotTypResult CBotFunction::CompileCall(CBotFunction* localFunctionList, const std::string &name, CBotVar** ppVars, long &nIdent) { - nIdent = 0; - CBotTypResult type; - -// CBotFunction* pt = FindLocalOrPublic(nIdent, name, ppVars, type); - FindLocalOrPublic(nIdent, name, ppVars, type); + CBotTypResult type; + if (!FindLocalOrPublic(localFunctionList, nIdent, name, ppVars, type)) + { + // Reset the identifier to "not found" value + nIdent = 0; + } return type; } //////////////////////////////////////////////////////////////////////////////// -CBotFunction* CBotFunction::FindLocalOrPublic(long& nIdent, const std::string& name, CBotVar** ppVars, - CBotTypResult& TypeOrError, bool bPublic) +CBotFunction* CBotFunction::FindLocalOrPublic(CBotFunction* localFunctionList, long &nIdent, const std::string &name, + CBotVar** ppVars, CBotTypResult &TypeOrError, bool bPublic) { TypeOrError.SetType(CBotErrUndefCall); // no routine of the name CBotFunction* pt; if ( nIdent ) { - if ( this != nullptr ) for ( pt = this ; pt != nullptr ; pt = pt->m_next ) + if ( localFunctionList != nullptr ) for ( pt = localFunctionList ; pt != nullptr ; pt = pt->m_next ) { if ( pt->m_nFuncIdent == nIdent ) { @@ -464,9 +465,9 @@ CBotFunction* CBotFunction::FindLocalOrPublic(long& nIdent, const std::string& n std::map funcMap; - if ( this != nullptr ) + if ( localFunctionList != nullptr ) { - for ( pt = this ; pt != nullptr ; pt = pt->m_next ) + for ( pt = localFunctionList ; pt != nullptr ; pt = pt->m_next ) { if ( pt->m_token.GetString() == name ) { @@ -610,12 +611,13 @@ CBotFunction* CBotFunction::FindLocalOrPublic(long& nIdent, const std::string& n } //////////////////////////////////////////////////////////////////////////////// -int CBotFunction::DoCall(long& nIdent, const std::string& name, CBotVar** ppVars, CBotStack* pStack, CBotToken* pToken) +int CBotFunction::DoCall(CBotProgram* program, CBotFunction* localFunctionList, long &nIdent, const std::string &name, + CBotVar** ppVars, CBotStack* pStack, CBotToken* pToken) { CBotTypResult type; CBotFunction* pt = nullptr; - pt = FindLocalOrPublic(nIdent, name, ppVars, type); + pt = FindLocalOrPublic(localFunctionList, nIdent, name, ppVars, type); if ( pt != nullptr ) { @@ -634,7 +636,7 @@ int CBotFunction::DoCall(long& nIdent, const std::string& name, CBotVar** ppVars { if ( !pt->m_MasterClass.empty() ) { - CBotVar* pInstance = m_pProg->m_thisVar; + CBotVar* pInstance = program->m_thisVar; // make "this" known CBotVar* pThis ; if ( pInstance == nullptr ) @@ -670,7 +672,7 @@ int CBotFunction::DoCall(long& nIdent, const std::string& name, CBotVar** ppVars if ( !pStk3->GetRetVar( // puts the result on the stack pt->m_block->Execute(pStk3) )) // GetRetVar said if it is interrupted { - if ( !pStk3->IsOk() && pt->m_pProg != m_pProg ) + if ( !pStk3->IsOk() && pt->m_pProg != program ) { pStk3->SetPosError(pToken); // indicates the error on the procedure call } @@ -683,7 +685,8 @@ int CBotFunction::DoCall(long& nIdent, const std::string& name, CBotVar** ppVars } //////////////////////////////////////////////////////////////////////////////// -void CBotFunction::RestoreCall(long& nIdent, const std::string& name, CBotVar** ppVars, CBotStack* pStack) +void CBotFunction::RestoreCall(CBotFunction* localFunctionList, + long &nIdent, const std::string &name, CBotVar** ppVars, CBotStack* pStack) { CBotTypResult type; CBotFunction* pt = nullptr; @@ -692,7 +695,7 @@ void CBotFunction::RestoreCall(long& nIdent, const std::string& name, CBotVar** // search function to return the ok identifier - pt = FindLocalOrPublic(nIdent, name, ppVars, type); + pt = FindLocalOrPublic(localFunctionList, nIdent, name, ppVars, type); if ( pt != nullptr ) { @@ -740,13 +743,13 @@ void CBotFunction::RestoreCall(long& nIdent, const std::string& name, CBotVar** } //////////////////////////////////////////////////////////////////////////////// -int CBotFunction::DoCall(long& nIdent, const std::string& name, CBotVar* pThis, CBotVar** ppVars, CBotStack* pStack, - CBotToken* pToken, CBotClass* pClass) +int CBotFunction::DoCall(CBotFunction* localFunctionList, long &nIdent, const std::string &name, CBotVar* pThis, + CBotVar** ppVars, CBotStack* pStack, CBotToken* pToken, CBotClass* pClass) { CBotTypResult type; CBotProgram* pProgCurrent = pStack->GetProgram(); - CBotFunction* pt = FindLocalOrPublic(nIdent, name, ppVars, type, false); + CBotFunction* pt = FindLocalOrPublic(localFunctionList, nIdent, name, ppVars, type, false); if ( pt != nullptr ) { @@ -822,11 +825,11 @@ int CBotFunction::DoCall(long& nIdent, const std::string& name, CBotVar* pThis, } //////////////////////////////////////////////////////////////////////////////// -bool CBotFunction::RestoreCall(long& nIdent, const std::string& name, CBotVar* pThis, CBotVar** ppVars, - CBotStack* pStack, CBotClass* pClass) +bool CBotFunction::RestoreCall(CBotFunction* localFunctionList, long &nIdent, const std::string &name, CBotVar* pThis, + CBotVar** ppVars, CBotStack* pStack, CBotClass* pClass) { CBotTypResult type; - CBotFunction* pt = FindLocalOrPublic(nIdent, name, ppVars, type); + CBotFunction* pt = FindLocalOrPublic(localFunctionList, nIdent, name, ppVars, type); if ( pt != nullptr ) { diff --git a/src/CBot/CBotInstr/CBotFunction.h b/src/CBot/CBotInstr/CBotFunction.h index 76a02bc0..d2f766c7 100644 --- a/src/CBot/CBotInstr/CBotFunction.h +++ b/src/CBot/CBotInstr/CBotFunction.h @@ -98,33 +98,43 @@ public: void AddNext(CBotFunction* p); /*! - * \brief CompileCall - * \param name - * \param ppVars - * \param nIdent - * \return + * \brief Compile a function call + * + * See FindLocalOrPublic for more detailed explanation + * + * \param localFunctionList Linked list of local functions to search in, can be null + * \param name Name of the function + * \param ppVars List of function arguments + * \param nIdent[in, out] Unique identifier of the function + * \return Type returned by the function or error code + * \see FindLocalOrPublic */ - CBotTypResult CompileCall(const std::string& name, - CBotVar** ppVars, - long& nIdent); + static CBotTypResult CompileCall(CBotFunction* localFunctionList, + const std::string &name, CBotVar** ppVars, long &nIdent); /*! - * \brief FindLocalOrPublic Is a function according to its unique identifier - * if the identifier is not found, looking by name and parameters. - * \param nIdent - * \param name - * \param ppVars - * \param TypeOrError - * \param bPublic - * \return + * \brief Finds a local or public function + * + *

Finds a local or (if bPublic is true) public function to call + * + *

First, it looks for a function according to its unique identifier.
+ * If the identifier is not found, looks by name and parameters. + * + * \param localFunctionList Linked list of local functions to search in, can be null + * \param nIdent[in, out] Unique identifier of the function + * \param name Name of the function + * \param ppVars List of function arguments + * \param TypeOrError Type returned by the function or error code + * \param bPublic Whether to look in public functions or not + * \return Pointer to found CBotFunction instance, or nullptr in case of no match or ambiguity (see TypeOrError for error code) */ - CBotFunction* FindLocalOrPublic(long& nIdent, const std::string& name, - CBotVar** ppVars, - CBotTypResult& TypeOrError, - bool bPublic = true); + static CBotFunction* FindLocalOrPublic(CBotFunction* localFunctionList, long &nIdent, const std::string &name, + CBotVar** ppVars, CBotTypResult &TypeOrError, bool bPublic = true); /*! * \brief DoCall Fait un appel à une fonction. + * \param program + * \param localFunctionList * \param nIdent * \param name * \param ppVars @@ -133,27 +143,24 @@ public: * \return */ - int DoCall(long& nIdent, - const std::string& name, - CBotVar** ppVars, - CBotStack* pStack, - CBotToken* pToken); + static int DoCall(CBotProgram* program, CBotFunction* localFunctionList, long &nIdent, const std::string &name, + CBotVar** ppVars, CBotStack* pStack, CBotToken* pToken); /*! * \brief RestoreCall + * \param localFunctionList * \param nIdent * \param name * \param ppVars * \param pStack */ - void RestoreCall(long& nIdent, - const std::string& name, - CBotVar** ppVars, - CBotStack* pStack); + static void RestoreCall(CBotFunction* localFunctionList, + long &nIdent, const std::string &name, CBotVar** ppVars, CBotStack* pStack); /*! - * \brief DoCall Makes call of a method note: this is already on the stack, - * the pointer pThis is just to simplify. + * \brief DoCall Makes call of a method + * note: this is already on the stack, the pointer pThis is just to simplify. + * \param localFunctionList * \param nIdent * \param name * \param pThis @@ -163,16 +170,12 @@ public: * \param pClass * \return */ - int DoCall(long& nIdent, - const std::string& name, - CBotVar* pThis, - CBotVar** ppVars, - CBotStack* pStack, - CBotToken* pToken, - CBotClass* pClass); + static int DoCall(CBotFunction* localFunctionList, long &nIdent, const std::string &name, CBotVar* pThis, + CBotVar** ppVars, CBotStack* pStack, CBotToken* pToken, CBotClass* pClass); /*! * \brief RestoreCall + * \param localFunctionList * \param nIdent * \param name * \param pThis @@ -181,12 +184,8 @@ public: * \param pClass * \return Returns true if the method call was restored. */ - bool RestoreCall(long& nIdent, - const std::string& name, - CBotVar* pThis, - CBotVar** ppVars, - CBotStack* pStack, - CBotClass* pClass); + static bool RestoreCall(CBotFunction* localFunctionList, long &nIdent, const std::string &name, CBotVar* pThis, + CBotVar** ppVars, CBotStack* pStack, CBotClass* pClass); /*! * \brief CheckParam See if the "signature" of parameters is identical. diff --git a/src/CBot/CBotStack.cpp b/src/CBot/CBotStack.cpp index 94697b4a..c554d7ca 100644 --- a/src/CBot/CBotStack.cpp +++ b/src/CBot/CBotStack.cpp @@ -568,7 +568,7 @@ bool CBotStack::ExecuteCall(long& nIdent, CBotToken* token, CBotVar** ppVar, con res = m_prog->GetExternalCalls()->DoCall(nullptr, nullptr, ppVar, this, rettype); if (res >= 0) return res; - res = m_prog->GetFunctions()->DoCall(nIdent, "", ppVar, this, token ); + res = CBotFunction::DoCall(m_prog, m_prog->GetFunctions(), nIdent, "", ppVar, this, token); if (res >= 0) return res; // if not found (recompile?) seeks by name @@ -577,7 +577,7 @@ bool CBotStack::ExecuteCall(long& nIdent, CBotToken* token, CBotVar** ppVar, con res = m_prog->GetExternalCalls()->DoCall(token, nullptr, ppVar, this, rettype); if (res >= 0) return res; - res = m_prog->GetFunctions()->DoCall(nIdent, token->GetString(), ppVar, this, token ); + res = CBotFunction::DoCall(m_prog, m_prog->GetFunctions(), nIdent, token->GetString(), ppVar, this, token); if (res >= 0) return res; SetError(CBotErrUndefFunc, token); @@ -592,7 +592,7 @@ void CBotStack::RestoreCall(long& nIdent, CBotToken* token, CBotVar** ppVar) if (m_prog->GetExternalCalls()->RestoreCall(token, nullptr, ppVar, this)) return; - m_prog->GetFunctions()->RestoreCall(nIdent, token->GetString(), ppVar, this); + CBotFunction::RestoreCall(m_prog->GetFunctions(), nIdent, token->GetString(), ppVar, this); } ////////////////////////////////////////////////////////////////////////////////