[Scummvm-git-logs] scummvm master -> 44ad31a043702b073990a69c65a4f78cc81454e0

djsrv dservilla at gmail.com
Thu Jul 22 01:07:48 UTC 2021


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
5a7c191ac4 DIRECTOR: LINGO: Create one call stack per window
44ad31a043 DIRECTOR: LINGO: Only freeze one context at a time


Commit: 5a7c191ac4b013ad9123a664b23ad19e7c51c611
    https://github.com/scummvm/scummvm/commit/5a7c191ac4b013ad9123a664b23ad19e7c51c611
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-21T20:35:40-04:00

Commit Message:
DIRECTOR: LINGO: Create one call stack per window

Since there may be frames left on the call stack after Lingo::execute()
is called now, it isn't safe to share one call stack between several
movies executing in parallel.

Changed paths:
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-bytecode.cpp
    engines/director/lingo/lingo-code.cpp
    engines/director/lingo/lingo.cpp
    engines/director/lingo/lingo.h
    engines/director/score.cpp
    engines/director/window.h


diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index a381d3ed25..7f00d8eea8 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -1289,7 +1289,7 @@ void LB::b_quit(int nargs) {
 }
 
 void LB::b_return(int nargs) {
-	CFrame *fp = g_lingo->_callstack.back();
+	CFrame *fp = g_director->getCurrentWindow()->_callstack.back();
 
 	Datum retVal;
 	if (nargs > 0) {
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 4ebaee00d2..e6e855ddea 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -29,6 +29,7 @@
 #include "director/castmember.h"
 #include "director/movie.h"
 #include "director/util.h"
+#include "director/window.h"
 #include "director/lingo/lingo.h"
 #include "director/lingo/lingo-code.h"
 #include "director/lingo/lingo-codegen.h"
@@ -336,7 +337,8 @@ Datum Lingo::findVarV4(int varType, const Datum &id) {
 	case 4: // arg
 	case 5: // local
 		{
-			if (g_lingo->_callstack.empty()) {
+			Common::Array<CFrame *> &callstack = _vm->getCurrentWindow()->_callstack;
+			if (callstack.empty()) {
 				warning("BUILDBOT: findVarV4: no call frame");
 				return res;
 			}
@@ -346,8 +348,8 @@ Datum Lingo::findVarV4(int varType, const Datum &id) {
 			}
 			int varIndex = id.asInt() / 6;
 			Common::Array<Common::String> *varNames = (varType == 4)
-				? _callstack.back()->sp.argNames
-				: _callstack.back()->sp.varNames;
+				? callstack.back()->sp.argNames
+				: callstack.back()->sp.varNames;
 
 			if (varIndex < (int)varNames->size()) {
 				res = (*varNames)[varIndex];
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 08b471865a..cac2fde665 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -221,7 +221,9 @@ void LC::c_xpop() {
 }
 
 void Lingo::pushContext(const Symbol funcSym, bool allowRetVal, Datum defaultRetVal) {
-	debugC(5, kDebugLingoExec, "Pushing frame %d", g_lingo->_callstack.size() + 1);
+	Common::Array<CFrame *> &callstack = _vm->getCurrentWindow()->_callstack;
+
+	debugC(5, kDebugLingoExec, "Pushing frame %d", callstack.size() + 1);
 	CFrame *fp = new CFrame;
 
 	fp->retpc = g_lingo->_pc;
@@ -288,7 +290,7 @@ void Lingo::pushContext(const Symbol funcSym, bool allowRetVal, Datum defaultRet
 
 	fp->stackSizeBefore = _stack.size();
 
-	g_lingo->_callstack.push_back(fp);
+	callstack.push_back(fp);
 
 	if (debugChannelSet(2, kDebugLingoExec)) {
 		g_lingo->printCallStack(0);
@@ -296,9 +298,11 @@ void Lingo::pushContext(const Symbol funcSym, bool allowRetVal, Datum defaultRet
 }
 
 void Lingo::popContext() {
-	debugC(5, kDebugLingoExec, "Popping frame %d", g_lingo->_callstack.size());
-	CFrame *fp = g_lingo->_callstack.back();
-	g_lingo->_callstack.pop_back();
+	Common::Array<CFrame *> &callstack = _vm->getCurrentWindow()->_callstack;
+
+	debugC(5, kDebugLingoExec, "Popping frame %d", callstack.size());
+	CFrame *fp = callstack.back();
+	callstack.pop_back();
 
 	if (_stack.size() == fp->stackSizeBefore + 1) {
 		if (!fp->allowRetVal) {
@@ -1560,7 +1564,9 @@ void LC::call(const Symbol &funcSym, int nargs, bool allowRetVal) {
 }
 
 void LC::c_procret() {
-	if (g_lingo->_callstack.size() == 0) {
+	Common::Array<CFrame *> &callstack = g_director->getCurrentWindow()->_callstack;
+
+	if (callstack.size() == 0) {
 		warning("LC::c_procret(): Call stack underflow");
 		g_lingo->_abort = true;
 		return;
@@ -1568,7 +1574,7 @@ void LC::c_procret() {
 
 	g_lingo->popContext();
 
-	if (g_lingo->_callstack.size() == 0) {
+	if (callstack.size() == 0) {
 		debugC(5, kDebugLingoExec, "Call stack empty, returning");
 		g_lingo->_abort = true;
 		return;
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 39a814c594..9d21a0839f 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -281,20 +281,21 @@ void Lingo::printStack(const char *s, uint pc) {
 }
 
 void Lingo::printCallStack(uint pc) {
-	if (g_lingo->_callstack.size() == 0) {
+	Common::Array<CFrame *> &callstack = _vm->getCurrentWindow()->_callstack;
+	if (callstack.size() == 0) {
 		debugC(2, kDebugLingoExec, "\nEnd of execution");
 		return;
 	}
 	debugC(2, kDebugLingoExec, "\nCall stack:");
-	for (int i = 0; i < (int)g_lingo->_callstack.size(); i++) {
-		CFrame *frame = g_lingo->_callstack[i];
+	for (int i = 0; i < (int)callstack.size(); i++) {
+		CFrame *frame = callstack[i];
 		uint framePc = pc;
-		if (i < (int)g_lingo->_callstack.size() - 1)
-			framePc = g_lingo->_callstack[i + 1]->retpc;
+		if (i < (int)callstack.size() - 1)
+			framePc = callstack[i + 1]->retpc;
 
 		if (frame->sp.type != VOIDSYM) {
 			debugC(2, kDebugLingoExec, "#%d %s:%d", i + 1,
-				g_lingo->_callstack[i]->sp.name->c_str(),
+				callstack[i]->sp.name->c_str(),
 				framePc
 			);
 		} else {
@@ -438,7 +439,7 @@ void Lingo::execute() {
 
 	if (_abort) {
 		// Clean up call stack
-		while (_callstack.size()) {
+		while (_vm->getCurrentWindow()->_callstack.size()) {
 			popContext();
 		}
 	}
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index b7c9435257..c1248ffc68 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -373,7 +373,6 @@ public:
 	bool _expectError;
 	bool _caughtError;
 
-	Common::Array<CFrame *> _callstack;
 	TheEntityHash _theEntities;
 	TheEntityFieldHash _theEntityFields;
 
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index fcd2563a02..40de8d0358 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -403,7 +403,7 @@ void Score::update() {
 
 	debugC(1, kDebugImages, "******************************  Current frame: %d", _currentFrame);
 
-	uint initialCallStackSize = g_lingo->_callstack.size();
+	uint initialCallStackSize = _window->_callstack.size();
 
 	_lingo->executeImmediateScripts(_frames[_currentFrame]);
 
@@ -432,7 +432,7 @@ void Score::update() {
 
 	// If we have more call stack frames than we started with, then we have a newly
 	// added frozen context. We'll deal with that later.
-	if (g_lingo->_callstack.size() == initialCallStackSize) {
+	if (_window->_callstack.size() == initialCallStackSize) {
 		// We may have frozen Lingo context(s) from func_goto.
 		// Now that we've entered a new frame and we don't have any new frozen
 		// contexts just added on, let's unfreeze all the contexts.
diff --git a/engines/director/window.h b/engines/director/window.h
index c2a4266070..3c34d94976 100644
--- a/engines/director/window.h
+++ b/engines/director/window.h
@@ -172,6 +172,8 @@ public:
 	Common::List<MovieReference> _movieStack;
 	bool _newMovieStarted;
 
+	Common::Array<CFrame *> _callstack;
+
 private:
 	uint32 _stageColor;
 


Commit: 44ad31a043702b073990a69c65a4f78cc81454e0
    https://github.com/scummvm/scummvm/commit/44ad31a043702b073990a69c65a4f78cc81454e0
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-21T20:41:36-04:00

Commit Message:
DIRECTOR: LINGO: Only freeze one context at a time

Changed paths:
    engines/director/lingo/lingo-funcs.cpp
    engines/director/score.cpp
    engines/director/window.cpp
    engines/director/window.h


diff --git a/engines/director/lingo/lingo-funcs.cpp b/engines/director/lingo/lingo-funcs.cpp
index 7c23590522..cd8ae4fc7a 100644
--- a/engines/director/lingo/lingo-funcs.cpp
+++ b/engines/director/lingo/lingo-funcs.cpp
@@ -190,16 +190,20 @@ void Lingo::func_goto(Datum &frame, Datum &movie) {
 	if (movie.type == VOID && frame.type == VOID)
 		return;
 
+	Window *stage = _vm->getCurrentWindow();
 	Score *score = _vm->getCurrentMovie()->getScore();
 
 	_vm->_skipFrameAdvance = true;
 
-	// Freeze this script context. We'll return to it after entering the next frame.
-	g_lingo->_freezeContext = true;
+	// If there isn't already frozen Lingo (e.g. from a previous func_goto we haven't yet unfrozen),
+	// freeze this script context. We'll return to it after entering the next frame.
+	if (!stage->_hasFrozenLingo) {
+		g_lingo->_freezeContext = true;
+		stage->_hasFrozenLingo = true;
+	}
 
 	if (movie.type != VOID) {
 		Common::String movieFilenameRaw = movie.asString();
-		Window *stage = _vm->getCurrentWindow();
 
 		if (!stage->setNextMovie(movieFilenameRaw))
 			return;
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 40de8d0358..5db7f1725c 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -433,14 +433,14 @@ void Score::update() {
 	// If we have more call stack frames than we started with, then we have a newly
 	// added frozen context. We'll deal with that later.
 	if (_window->_callstack.size() == initialCallStackSize) {
-		// We may have frozen Lingo context(s) from func_goto.
-		// Now that we've entered a new frame and we don't have any new frozen
-		// contexts just added on, let's unfreeze all the contexts.
-		while (g_lingo->_freezeContext) {
+		// We may have a frozen Lingo context from func_goto.
+		// Now that we've entered a new frame, let's unfreeze that context.
+		if (g_lingo->_freezeContext) {
 			debugC(1, kDebugLingoExec, "Score::update(): Unfreezing Lingo context");
 			g_lingo->_freezeContext = false;
 			g_lingo->execute();
 		}
+		_window->_hasFrozenLingo = false;
 	}
 
 	byte tempo = _frames[_currentFrame]->_tempo;
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index 929765d599..f1322c8483 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -61,6 +61,8 @@ Window::Window(int id, bool scrollable, bool resizable, bool editable, Graphics:
 	_windowType = -1;
 	_titleVisible = true;
 	updateBorderType();
+
+	_hasFrozenLingo = false;
 }
 
 Window::~Window() {
diff --git a/engines/director/window.h b/engines/director/window.h
index 3c34d94976..1375800376 100644
--- a/engines/director/window.h
+++ b/engines/director/window.h
@@ -173,6 +173,7 @@ public:
 	bool _newMovieStarted;
 
 	Common::Array<CFrame *> _callstack;
+	bool _hasFrozenLingo;
 
 private:
 	uint32 _stageColor;




More information about the Scummvm-git-logs mailing list