aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Snover2017-05-20 16:34:32 -0500
committerColin Snover2017-05-20 21:14:18 -0500
commitef69a594672bb1e6549269ca695d6feae3a9c579 (patch)
treebd01e138894559e5f145ab500592c1fb595da6ef
parentbc728a1c939b7a753af5885ff42860dde1b0da5d (diff)
downloadscummvm-rg350-ef69a594672bb1e6549269ca695d6feae3a9c579.tar.gz
scummvm-rg350-ef69a594672bb1e6549269ca695d6feae3a9c579.tar.bz2
scummvm-rg350-ef69a594672bb1e6549269ca695d6feae3a9c579.zip
SCI: Stop leaking locals segments during script reuse
When a game deletes a script and then loads the same script again before it has been fully deallocated, SegManager::instantiateScript tries to reuse the same script & locals segments, but it was failing to reuse the old locals segment because Script::freeScript would unconditionally clear the old locals SegmentId, which meant the old locals segment would just leak. This patch does not fix old save games which may contain orphaned locals segments, but should prevent the problem from occurring going forward. (It is possible to clean up these old save games, but this is not a big leak so it doesn't seem worth the extra effort to do so.)
-rw-r--r--engines/sci/engine/script.cpp6
-rw-r--r--engines/sci/engine/script.h2
-rw-r--r--engines/sci/engine/seg_manager.cpp2
3 files changed, 6 insertions, 4 deletions
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index 4932c16e73..5191c1a7d8 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -47,7 +47,7 @@ Script::~Script() {
freeScript();
}
-void Script::freeScript() {
+void Script::freeScript(const bool keepLocalsSegment) {
_nr = 0;
_buf.clear();
@@ -59,7 +59,9 @@ void Script::freeScript() {
_numSynonyms = 0;
_localsOffset = 0;
- _localsSegment = 0;
+ if (!keepLocalsSegment) {
+ _localsSegment = 0;
+ }
_localsBlock = NULL;
_localsCount = 0;
diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h
index b59f87f13a..1befef1c8a 100644
--- a/engines/sci/engine/script.h
+++ b/engines/sci/engine/script.h
@@ -132,7 +132,7 @@ public:
Script();
~Script();
- void freeScript();
+ void freeScript(const bool keepLocalsSegment = false);
void load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptPatcher);
virtual bool isValidOffset(uint32 offset) const;
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 168303684d..3cf9d08ceb 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -1017,7 +1017,7 @@ int SegManager::instantiateScript(int scriptNum) {
scr->incrementLockers();
return segmentId;
} else {
- scr->freeScript();
+ scr->freeScript(true);
}
} else {
scr = allocateScript(scriptNum, &segmentId);