[Scummvm-cvs-logs] SF.net SVN: scummvm:[50308] scummvm/trunk/engines/sci/engine

m_kiewitz at users.sourceforge.net m_kiewitz at users.sourceforge.net
Sat Jun 26 10:29:56 CEST 2010


Revision: 50308
          http://scummvm.svn.sourceforge.net/scummvm/?rev=50308&view=rev
Author:   m_kiewitz
Date:     2010-06-26 08:29:55 +0000 (Sat, 26 Jun 2010)

Log Message:
-----------
SCI: adding capability to resolve local calls as well for valgrind-sci, adding another workaround for a script bug in sq1 (this time export 1 gets called locally)

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/vm.cpp
    scummvm/trunk/engines/sci/engine/vm.h

Modified: scummvm/trunk/engines/sci/engine/vm.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/vm.cpp	2010-06-26 07:30:20 UTC (rev 50307)
+++ scummvm/trunk/engines/sci/engine/vm.cpp	2010-06-26 08:29:55 UTC (rev 50308)
@@ -72,7 +72,7 @@
  * @return 					A pointer to the new exec stack TOS entry
  */
 static ExecStack *add_exec_stack_entry(Common::List<ExecStack> &execStack, reg_t pc, StackPtr sp,
-		reg_t objp, int argc, StackPtr argp, Selector selector, int exportId,
+		reg_t objp, int argc, StackPtr argp, Selector selector, int exportId, int localCallOffset,
 		reg_t sendp, int origin, SegmentId local_segment);
 
 
@@ -188,19 +188,22 @@
 	int scriptNr;
 	const char *objectName;
 	const char *methodName;
+	int localCallOffset;
 	int index;
 	uint16 newValue;
 };
 
 static const UninitializedReadWorkaround uninitializedReadWorkarounds[] = {
-	{ GID_LAURABOW2,      24,              "gcWin", "open",         5, 0xf }, // is used as priority for game menu
-	{ GID_FREDDYPHARKAS,  24,              "gcWin", "open",         5, 0xf }, // is used as priority for game menu
-	{ GID_FREDDYPHARKAS,  31,            "quitWin", "open",         5, 0xf }, // is used as priority for game menu
-	{ GID_LSL1,          720,              "rm720", "init",         0,   0 }, // age check room
-	{ GID_ISLANDBRAIN,   140,              "piece", "init",         3,   1 }, // some initialization variable. bnt is done on it, and it should be non-0
-	{ GID_SQ1,           703,                   "", "export 1",     0,   0 }, // sub that's called from several objects
-	{ GID_SQ4,           928,           "Narrator", "startText", 1000,   1 }, // sq4cd: method returns this to the caller
-	{ (SciGameId)0,       -1,                 NULL, NULL,           0,   0 }
+	{ GID_LAURABOW2,      24,              "gcWin", "open",           -1,    5, 0xf }, // is used as priority for game menu
+	{ GID_FREDDYPHARKAS,  24,              "gcWin", "open",           -1,    5, 0xf }, // is used as priority for game menu
+	{ GID_FREDDYPHARKAS,  31,            "quitWin", "open",           -1,    5, 0xf }, // is used as priority for game menu
+	{ GID_LSL1,          720,              "rm720", "init",           -1,    0,   0 }, // age check room
+	{ GID_ISLANDBRAIN,   140,              "piece", "init",           -1,    3,   1 }, // some initialization variable. bnt is done on it, and it should be non-0
+	{ GID_SQ1,           703,                   "", "export 1",       -1,    0,   0 }, // sub that's called from several objects
+	{ GID_SQ1,           703,         "firePulsar", "changeState", 0x18a,    0,   0 }, // export 1, but called locally
+	{ GID_SQ1,           703,                   "", "export 1",       -1,    0,   0 }, // export 1 sub, but called locally
+	{ GID_SQ4,           928,           "Narrator", "startText",      -1, 1000,   1 }, // sq4cd: method returns this to the caller
+	{ (SciGameId)0,       -1,                 NULL, NULL,             -1,    0,   0 }
 };
 
 static reg_t validate_read_var(reg_t *r, reg_t *stack_base, int type, int max, int index, int line, reg_t default_value) {
@@ -209,20 +212,34 @@
 			// Uninitialized read on a temp
 			//  We need to find correct replacements for each situation manually
 			EngineState *state = g_sci->getEngineState();
-			ExecStack *call = state->xs;
-			Script *local_script = state->_segMan->getScriptIfLoaded(call->local_segment);
+			ExecStack *lastCall = state->xs;
+			Script *local_script = state->_segMan->getScriptIfLoaded(lastCall->local_segment);
 			int curScriptNr = local_script->_nr;
 
-			Common::String curObjectName = state->_segMan->getObjectName(call->sendp);
+			if (lastCall->localCallOffset != -1) {
+				// if lastcall was actually a local call search back for a real call
+				Common::List<ExecStack>::iterator callIterator = state->_executionStack.end();
+				while (callIterator != state->_executionStack.begin()) {
+					callIterator--;
+					ExecStack loopCall = *callIterator;
+					if ((loopCall.selector != -1) || (loopCall.exportId != -1)) {
+						lastCall->selector = loopCall.selector;
+						lastCall->exportId = loopCall.exportId;
+						break;
+					}
+				}
+			}
+
+			Common::String curObjectName = state->_segMan->getObjectName(lastCall->sendp);
 			Common::String curMethodName;
 			const SciGameId gameId = g_sci->getGameId();
 
-			if (call->type == EXEC_STACK_TYPE_CALL) {
-				if (call->selector != -1) {
-					curMethodName = g_sci->getKernel()->getSelectorName(call->selector);
-				} else if (call->exportId != -1) {
+			if (lastCall->type == EXEC_STACK_TYPE_CALL) {
+				if (lastCall->selector != -1) {
+					curMethodName = g_sci->getKernel()->getSelectorName(lastCall->selector);
+				} else if (lastCall->exportId != -1) {
 					curObjectName = "";
-					curMethodName = curMethodName.printf("export %d", call->exportId);
+					curMethodName = curMethodName.printf("export %d", lastCall->exportId);
 				}
 			}
 
@@ -230,14 +247,14 @@
 			const UninitializedReadWorkaround *workaround = uninitializedReadWorkarounds;
 			while (workaround->objectName) {
 				if (workaround->gameId == gameId && workaround->scriptNr == curScriptNr && workaround->objectName == curObjectName
-						&& workaround->methodName == curMethodName && workaround->index == index) {
+						&& workaround->methodName == curMethodName && workaround->localCallOffset == lastCall->localCallOffset && workaround->index == index) {
 					// Workaround found
 					r[index] = make_reg(0, workaround->newValue);
 					return r[index];
 				}
 				workaround++;
 			}
-			error("Uninitialized read for temp %d from method %s::%s (script %d)", index, curObjectName.c_str(), curMethodName.c_str(), curScriptNr);
+			error("Uninitialized read for temp %d from method %s::%s (script %d, localCall %lx)", index, curObjectName.c_str(), curMethodName.c_str(), curScriptNr, lastCall->localCallOffset);
 		}
 		return r[index];
 	} else
@@ -345,7 +362,7 @@
 		}
 	}
 
-	return add_exec_stack_entry(s->_executionStack, make_reg(seg, temp), sp, calling_obj, argc, argp, -1, pubfunct, calling_obj, s->_executionStack.size()-1, seg);
+	return add_exec_stack_entry(s->_executionStack, make_reg(seg, temp), sp, calling_obj, argc, argp, -1, pubfunct, -1, calling_obj, s->_executionStack.size()-1, seg);
 }
 
 
@@ -543,7 +560,7 @@
 		else
 			add_exec_stack_entry(s->_executionStack, call.address.func, call.sp, work_obj,
 			                         call.argc, call.argp,
-			                         call.selector, -1, send_obj, origin, SCI_XS_CALLEE_LOCALS);
+			                         call.selector, -1, -1, send_obj, origin, SCI_XS_CALLEE_LOCALS);
 	}
 
 	_exec_varselectors(s);
@@ -552,7 +569,7 @@
 }
 
 static ExecStack *add_exec_stack_varselector(Common::List<ExecStack> &execStack, reg_t objp, int argc, StackPtr argp, Selector selector, const ObjVarRef& address, int origin) {
-	ExecStack *xstack = add_exec_stack_entry(execStack, NULL_REG, 0, objp, argc, argp, selector, -1, objp, origin, SCI_XS_CALLEE_LOCALS);
+	ExecStack *xstack = add_exec_stack_entry(execStack, NULL_REG, 0, objp, argc, argp, selector, -1, -1, objp, origin, SCI_XS_CALLEE_LOCALS);
 	// Store selector address in sp
 
 	xstack->addr.varp = address;
@@ -562,7 +579,7 @@
 }
 
 static ExecStack *add_exec_stack_entry(Common::List<ExecStack> &execStack, reg_t pc, StackPtr sp, reg_t objp, int argc,
-								   StackPtr argp, Selector selector, int exportId, reg_t sendp, int origin, SegmentId _localsSegment) {
+								   StackPtr argp, Selector selector, int exportId, int localCallOffset, reg_t sendp, int origin, SegmentId _localsSegment) {
 	// Returns new TOS element for the execution stack
 	// _localsSegment may be -1 if derived from the called object
 
@@ -588,6 +605,7 @@
 	// Additional debug information
 	xstack.selector = selector;
 	xstack.exportId = exportId;
+	xstack.localCallOffset = localCallOffset;
 	xstack.origin = origin;
 
 	xstack.type = EXEC_STACK_TYPE_CALL; // Normal call
@@ -642,7 +660,7 @@
 		// This is useful in debugger backtraces if this
 		// kernel function calls a script itself.
 		ExecStack *xstack;
-		xstack = add_exec_stack_entry(s->_executionStack, NULL_REG, NULL, NULL_REG, argc, argv - 1, 0, -1, NULL_REG,
+		xstack = add_exec_stack_entry(s->_executionStack, NULL_REG, NULL, NULL_REG, argc, argv - 1, 0, -1, -1, NULL_REG,
 				  s->_executionStack.size()-1, SCI_XS_CALLEE_LOCALS);
 		xstack->selector = kernelFuncNum;
 		xstack->type = EXEC_STACK_TYPE_KERNEL;
@@ -1199,11 +1217,13 @@
 			StackPtr call_base = s->xs->sp - argc;
 			s->xs->sp[1].offset += s->restAdjust;
 
+			uint16 localCallOffset = s->xs->addr.pc.offset + opparams[0];
+
 			xs_new = add_exec_stack_entry(s->_executionStack, make_reg(s->xs->addr.pc.segment,
-											s->xs->addr.pc.offset + opparams[0]),
+											localCallOffset),
 											s->xs->sp, s->xs->objp,
 											(validate_arithmetic(*call_base)) + s->restAdjust,
-											call_base, NULL_SELECTOR, -1, s->xs->objp,
+											call_base, NULL_SELECTOR, -1, localCallOffset, s->xs->objp,
 											s->_executionStack.size()-1, s->xs->local_segment);
 			s->restAdjust = 0; // Used up the &rest adjustment
 			s->xs->sp = call_base;

Modified: scummvm/trunk/engines/sci/engine/vm.h
===================================================================
--- scummvm/trunk/engines/sci/engine/vm.h	2010-06-26 07:30:20 UTC (rev 50307)
+++ scummvm/trunk/engines/sci/engine/vm.h	2010-06-26 08:29:55 UTC (rev 50308)
@@ -104,6 +104,7 @@
 
 	Selector selector;      // The selector which was used to call or -1 if not applicable
 	int exportId;           // The exportId which was called or -1 if not applicable
+	int localCallOffset;    // Local call offset or -1 if not applicable
 	int origin;             // The stack frame position the call was made from, or -1 if it was the initial call
 	ExecStackType type;
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list