mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-03 23:56:43 +00:00 
			
		
		
		
	workaround for infinite recursion during local variable access
This commit is contained in:
		
							parent
							
								
									59748a7647
								
							
						
					
					
						commit
						3472a6f180
					
				
					 2 changed files with 28 additions and 15 deletions
				
			
		| 
						 | 
				
			
			@ -139,28 +139,40 @@ namespace MWScript
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    Compiler::Locals& ScriptManager::getLocals (const std::string& name)
 | 
			
		||||
    {
 | 
			
		||||
        {
 | 
			
		||||
            ScriptCollection::iterator iter = mScripts.find (name);
 | 
			
		||||
 | 
			
		||||
        if (iter==mScripts.end())
 | 
			
		||||
        {
 | 
			
		||||
            if (!compile (name))
 | 
			
		||||
            {
 | 
			
		||||
                /// \todo Handle case of cyclic member variable access. Currently this could look up
 | 
			
		||||
                /// the whole application in an endless recursion.
 | 
			
		||||
 | 
			
		||||
                // failed -> ignore script from now on.
 | 
			
		||||
                std::vector<Interpreter::Type_Code> empty;
 | 
			
		||||
                mScripts.insert (std::make_pair (name, std::make_pair (empty, Compiler::Locals())));
 | 
			
		||||
                throw std::runtime_error ("failed to compile script " + name);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            iter = mScripts.find (name);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            if (iter!=mScripts.end())
 | 
			
		||||
                return iter->second.second;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            std::map<std::string, Compiler::Locals>::iterator iter = mOtherLocals.find (name);
 | 
			
		||||
 | 
			
		||||
            if (iter!=mOtherLocals.end())
 | 
			
		||||
                return iter->second;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Compiler::Locals locals;
 | 
			
		||||
 | 
			
		||||
        if (const ESM::Script *script = mStore.get<ESM::Script>().find (name))
 | 
			
		||||
        {
 | 
			
		||||
            int index = 0;
 | 
			
		||||
 | 
			
		||||
            for (int i=0; i<script->mData.mNumShorts; ++i)
 | 
			
		||||
                locals.declare ('s', script->mVarNames[index++]);
 | 
			
		||||
 | 
			
		||||
            for (int i=0; i<script->mData.mNumLongs; ++i)
 | 
			
		||||
                locals.declare ('l', script->mVarNames[index++]);
 | 
			
		||||
 | 
			
		||||
            for (int i=0; i<script->mData.mNumFloats; ++i)
 | 
			
		||||
                locals.declare ('f', script->mVarNames[index++]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw std::logic_error ("script " + name + " does not exist");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    GlobalScripts& ScriptManager::getGlobalScripts()
 | 
			
		||||
    {
 | 
			
		||||
        return mGlobalScripts;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,6 +47,7 @@ namespace MWScript
 | 
			
		|||
 | 
			
		||||
            ScriptCollection mScripts;
 | 
			
		||||
            GlobalScripts mGlobalScripts;
 | 
			
		||||
            std::map<std::string, Compiler::Locals> mOtherLocals;
 | 
			
		||||
 | 
			
		||||
        public:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue