From 0b6d950729296c177ad502328fd5b5e3b0bb04c9 Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Thu, 30 Jun 2016 10:24:01 +0200 Subject: DIRECTOR: Lingo: Store and restore local variables in scope. --- engines/director/lingo/lingo-code.cpp | 19 +++++++++++++++++++ engines/director/lingo/lingo-codegen.cpp | 12 +----------- engines/director/lingo/lingo.cpp | 4 ++++ engines/director/lingo/lingo.h | 16 +++++----------- 4 files changed, 29 insertions(+), 22 deletions(-) (limited to 'engines/director/lingo') diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp index 31aeac6716..9bc6b48b90 100644 --- a/engines/director/lingo/lingo-code.cpp +++ b/engines/director/lingo/lingo-code.cpp @@ -404,6 +404,13 @@ void Lingo::c_call() { fp->sp = sym; fp->retpc = g_lingo->_pc; fp->retscript = g_lingo->_currentScript; + fp->localvars = g_lingo->_localvars; + + // Clean up current scope local variables + for (SymbolHash::const_iterator h = g_lingo->_localvars->begin(); h != g_lingo->_localvars->end(); ++h) + g_lingo->_vars.erase(h->_key); + + g_lingo->_localvars = new SymbolHash; g_lingo->_callstack.push_back(fp); @@ -419,6 +426,18 @@ void Lingo::c_procret() { g_lingo->_currentScript = fp->retscript; g_lingo->_pc = fp->retpc; + // Clean up current scope local variables and clean up memory + for (SymbolHash::const_iterator h = g_lingo->_localvars->begin(); h != g_lingo->_localvars->end(); ++h) { + g_lingo->_vars.erase(h->_key); + delete h->_value; + } + delete g_lingo->_localvars; + + // Restore local variables + g_lingo->_localvars = fp->localvars; + for (SymbolHash::const_iterator h = g_lingo->_localvars->begin(); h != g_lingo->_localvars->end(); ++h) + g_lingo->_vars[h->_key] = h->_value; + delete fp; g_lingo->_returning = true; diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp index b5bc8014c1..ae6242867a 100644 --- a/engines/director/lingo/lingo-codegen.cpp +++ b/engines/director/lingo/lingo-codegen.cpp @@ -64,16 +64,6 @@ void Lingo::execute(int pc) { } } -void Lingo::pushContext() { - Context *con = new Context; - - _contexts.push_back(con); -} - -void Lingo::popContext() { - _contexts.pop_back(); -} - Symbol *Lingo::lookupVar(const char *name, bool create, bool putInLocalList) { Symbol *sym; @@ -93,7 +83,7 @@ Symbol *Lingo::lookupVar(const char *name, bool create, bool putInLocalList) { } if (putInLocalList) - _localvars[name] = true; + (*_localvars)[name] = sym; return sym; } diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp index cbf0d9ba6c..accd9a113d 100644 --- a/engines/director/lingo/lingo.cpp +++ b/engines/director/lingo/lingo.cpp @@ -163,7 +163,11 @@ void Lingo::executeScript(ScriptType type, uint16 id) { _pc = 0; _returning = false; + _localvars = new SymbolHash; + execute(_pc); + + delete _localvars; } void Lingo::processEvent(LEvent event, int entityId) { diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h index bec14f2b59..e30d8a465a 100644 --- a/engines/director/lingo/lingo.h +++ b/engines/director/lingo/lingo.h @@ -103,18 +103,14 @@ struct Datum { /* interpreter stack type */ Datum() { u.sym = NULL; type = VOID; } }; -struct CFrame { /* proc/func call stack frame */ - Symbol *sp; /* symbol table entry */ - int retpc; /* where to resume after return */ - ScriptData *retscript; /* which script to resume after return */ -}; - typedef Common::HashMap ScriptHash; typedef Common::Array StackData; typedef Common::HashMap SymbolHash; -struct Context { /* execution context */ - Symbol *handler; +struct CFrame { /* proc/func call stack frame */ + Symbol *sp; /* symbol table entry */ + int retpc; /* where to resume after return */ + ScriptData *retscript; /* which script to resume after return */ SymbolHash *localvars; }; @@ -209,11 +205,9 @@ private: ScriptHash _scripts[kMaxScriptType + 1]; SymbolHash _vars; - Common::HashMap _localvars; + SymbolHash *_localvars; SymbolHash _handlers; - Common::Array _contexts; - int _pc; StackData _stack; -- cgit v1.2.3