aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/director/lingo/lingo-code.cpp19
-rw-r--r--engines/director/lingo/lingo-codegen.cpp12
-rw-r--r--engines/director/lingo/lingo.cpp4
-rw-r--r--engines/director/lingo/lingo.h16
4 files changed, 29 insertions, 22 deletions
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<int32, ScriptData *> ScriptHash;
typedef Common::Array<Datum> StackData;
typedef Common::HashMap<Common::String, Symbol *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> 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<Common::String, bool, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _localvars;
+ SymbolHash *_localvars;
SymbolHash _handlers;
- Common::Array<Context *> _contexts;
-
int _pc;
StackData _stack;