diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 4bb14bc0d07..f18525f2b23 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -2995,10 +2995,18 @@ bool Console::cmdStack(int argc, const char **argv) { int nr = atoi(argv[1]); for (int i = nr; i > 0; i--) { - if ((xs.sp - xs.fp - i) == 0) + bool isArgc = (xs.sp - xs.variables_argp - i == 0); + if (isArgc) + debugPrintf("-- parameters --\n"); + if (xs.tempCount && ((xs.sp - xs.fp - i) == 0)) debugPrintf("-- temp variables --\n"); + if (xs.sp - xs.fp - xs.tempCount - i == 0) + debugPrintf("-- local stack --\n"); if (xs.sp - i >= _engine->_gamestate->stack_base) - debugPrintf("ST:%04x = %04x:%04x\n", (unsigned)(xs.sp - i - _engine->_gamestate->stack_base), PRINT_REG(xs.sp[-i])); + debugPrintf("ST:%04x = %04x:%04x%s\n", + (unsigned)(xs.sp - i - _engine->_gamestate->stack_base), + PRINT_REG(xs.sp[-i]), + (isArgc ? " argc" : "")); } return true; diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 9aa92e4bd16..fe71615bbda 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -596,7 +596,7 @@ void run_vm(EngineState *s) { s->variablesSegment[VAR_LOCAL] = local_script->getLocalsSegment(); s->variablesBase[VAR_LOCAL] = s->variables[VAR_LOCAL] = local_script->getLocalsBegin(); s->variablesMax[VAR_LOCAL] = local_script->getLocalsCount(); - s->variablesMax[VAR_TEMP] = s->xs->sp - s->xs->fp; + s->variablesMax[VAR_TEMP] = s->xs->tempCount; s->variablesMax[VAR_PARAM] = s->xs->argc + 1; } s->variables[VAR_TEMP] = s->xs->fp; @@ -621,8 +621,6 @@ void run_vm(EngineState *s) { error("run_vm(): stack underflow, sp: %04x:%04x, fp: %04x:%04x", PRINT_REG(*s->xs->sp), PRINT_REG(*s->xs->fp)); - s->variablesMax[VAR_TEMP] = s->xs->sp - s->xs->fp; - if (s->xs->addr.pc.getOffset() >= scr->getBufSize()) error("run_vm(): program counter gone astray, addr: %d, code buffer size: %d", s->xs->addr.pc.getOffset(), scr->getBufSize()); @@ -817,6 +815,8 @@ void run_vm(EngineState *s) { break; case op_link: // 0x1f (31) + s->variablesMax[VAR_TEMP] = s->xs->tempCount = opparams[0]; + // We shouldn't initialize temp variables at all // We put special segment 0xFFFF in there, so that uninitialized reads can get detected for (int i = 0; i < opparams[0]; i++) @@ -919,8 +919,7 @@ void run_vm(EngineState *s) { case op_ret: // 0x24 (36) // Return from an execution loop started by call, calle, callb, send, self or super do { - StackPtr old_sp2 = s->xs->sp; - StackPtr old_fp = s->xs->fp; + StackPtr old_sp = s->xs->sp; ExecStack *old_xs = &(s->_executionStack.back()); if ((int)s->_executionStack.size() - 1 == s->executionStackBase) { // Have we reached the base? @@ -952,8 +951,8 @@ void run_vm(EngineState *s) { if (s->xs->sp == CALL_SP_CARRY // Used in sends to 'carry' the stack pointer || s->xs->type != EXEC_STACK_TYPE_CALL) { - s->xs->sp = old_sp2; - s->xs->fp = old_fp; + s->xs->sp = old_sp; + s->xs->fp = old_sp; } } while (s->xs->type == EXEC_STACK_TYPE_VARSELECTOR); diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index 53485c129c5..7a8abe9c32b 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -91,6 +91,8 @@ struct ExecStack { int argc; StackPtr variables_argp; // Argument pointer + int tempCount; // Number of temp variables allocated by link opcode + SegmentId local_segment; // local variables etc Selector debugSelector; // The selector which was used to call or -1 if not applicable @@ -115,6 +117,7 @@ struct ExecStack { fp = sp = sp_; argc = argc_; variables_argp = argp_; + tempCount = 0; if (localsSegment_ != kUninitializedSegment) local_segment = localsSegment_; else