mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-20 00:45:10 +00:00
DIRECTOR: LINGO: Add previous script context to call frame
This commit is contained in:
parent
329b77bd82
commit
87f6d6257d
@ -215,15 +215,15 @@ void LC::cb_field() {
|
||||
|
||||
|
||||
void LC::cb_localcall() {
|
||||
int nameId = g_lingo->readInt();
|
||||
Common::String name = g_lingo->_namelist[nameId];
|
||||
int functionId = g_lingo->readInt();
|
||||
|
||||
Datum nargs = g_lingo->pop();
|
||||
if ((nargs.type == ARGC) || (nargs.type == ARGCNORET)) {
|
||||
warning("STUB: cb_localcall(%s)", name.c_str());
|
||||
for (int i = 0; i < nargs.u.i; i++) {
|
||||
g_lingo->pop();
|
||||
}
|
||||
Symbol *sym = g_lingo->_currentScriptContext->functions[functionId];
|
||||
if (debugChannelSet(3, kDebugLingoExec))
|
||||
g_lingo->printSTUBWithArglist(sym->name.c_str(), nargs.u.i, "call:");
|
||||
|
||||
LC::call(sym, nargs.u.i);
|
||||
|
||||
} else {
|
||||
warning("cb_localcall: first arg should be of type ARGC or ARGCNORET, not %s", nargs.type2str());
|
||||
@ -565,8 +565,7 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
|
||||
}
|
||||
|
||||
_currentScriptFunction = i;
|
||||
_currentScriptContext->functions.push_back(new ScriptData);
|
||||
_currentScript = _currentScriptContext->functions[_currentScriptFunction];
|
||||
_currentScript = new ScriptData;
|
||||
|
||||
uint16 nameIndex = stream.readUint16();
|
||||
stream.readUint16();
|
||||
@ -742,12 +741,20 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
|
||||
}
|
||||
|
||||
// Attach to handlers
|
||||
Symbol *sym = NULL;
|
||||
if (nameIndex < _namelist.size()) {
|
||||
g_lingo->define(_namelist[nameIndex], argCount, new ScriptData(&(*_currentScript)[0], _currentScript->size()));
|
||||
|
||||
sym = g_lingo->define(_namelist[nameIndex], argCount, _currentScript);
|
||||
_currentScriptContext->functions.push_back(sym);
|
||||
} else {
|
||||
warning("Function has unknown name id %d, skipping define", nameIndex);
|
||||
sym = new Symbol;
|
||||
sym->type = HANDLER;
|
||||
sym->u.defn = _currentScript;
|
||||
sym->nargs = argCount;
|
||||
sym->maxArgs = argCount;
|
||||
}
|
||||
_currentScriptContext->functions.push_back(sym);
|
||||
|
||||
}
|
||||
|
||||
free(codeStore);
|
||||
|
@ -1164,8 +1164,6 @@ void LC::c_call() {
|
||||
}
|
||||
|
||||
void LC::call(Common::String name, int nargs) {
|
||||
bool dropArgs = false;
|
||||
|
||||
if (debugChannelSet(3, kDebugLingoExec))
|
||||
g_lingo->printSTUBWithArglist(name.c_str(), nargs, "call:");
|
||||
|
||||
@ -1180,16 +1178,22 @@ void LC::call(Common::String name, int nargs) {
|
||||
}
|
||||
}
|
||||
|
||||
call(sym, nargs);
|
||||
}
|
||||
|
||||
void LC::call(Symbol *sym, int nargs) {
|
||||
bool dropArgs = false;
|
||||
|
||||
if (sym == NULL) {
|
||||
warning("Call to undefined handler '%s'. Dropping %d stack items", name.c_str(), nargs);
|
||||
warning("Call to undefined handler. Dropping %d stack items", nargs);
|
||||
dropArgs = true;
|
||||
} else {
|
||||
if ((sym->type == BLTIN || sym->type == FBLTIN || sym->type == RBLTIN)
|
||||
&& sym->nargs != -1 && sym->nargs != nargs && sym->maxArgs != nargs) {
|
||||
if (sym->nargs == sym->maxArgs)
|
||||
warning("Incorrect number of arguments to handler '%s', expecting %d. Dropping %d stack items", name.c_str(), sym->nargs, nargs);
|
||||
warning("Incorrect number of arguments to handler '%s', expecting %d. Dropping %d stack items", sym->name.c_str(), sym->nargs, nargs);
|
||||
else
|
||||
warning("Incorrect number of arguments to handler '%s', expecting %d or %d. Dropping %d stack items", name.c_str(), sym->nargs, sym->maxArgs, nargs);
|
||||
warning("Incorrect number of arguments to handler '%s', expecting %d or %d. Dropping %d stack items", sym->name.c_str(), sym->nargs, sym->maxArgs, nargs);
|
||||
|
||||
dropArgs = true;
|
||||
}
|
||||
@ -1207,14 +1211,14 @@ void LC::call(Common::String name, int nargs) {
|
||||
|
||||
if (sym->nargs != -1 && sym->maxArgs < nargs) {
|
||||
warning("Incorrect number of arguments for function %s (%d, expected %d to %d). Dropping extra %d",
|
||||
name.c_str(), nargs, sym->nargs, sym->maxArgs, nargs - sym->nargs);
|
||||
sym->name.c_str(), nargs, sym->nargs, sym->maxArgs, nargs - sym->nargs);
|
||||
for (int i = 0; i < nargs - sym->maxArgs; i++)
|
||||
g_lingo->pop();
|
||||
}
|
||||
|
||||
if (sym->type == BLTIN || sym->type == FBLTIN || sym->type == RBLTIN) {
|
||||
if (sym->u.bltin == LB::b_factory) {
|
||||
g_lingo->factoryCall(name, nargs);
|
||||
g_lingo->factoryCall(sym->name, nargs);
|
||||
} else {
|
||||
int stackSize = g_lingo->_stack.size() - nargs;
|
||||
|
||||
@ -1224,10 +1228,10 @@ void LC::call(Common::String name, int nargs) {
|
||||
|
||||
if (sym->type == FBLTIN || sym->type == RBLTIN) {
|
||||
if (stackNewSize - stackSize != 1)
|
||||
warning("built-in function %s did not return value", name.c_str());
|
||||
warning("built-in function %s did not return value", sym->name.c_str());
|
||||
} else {
|
||||
if (stackNewSize - stackSize != 0)
|
||||
warning("built-in procedure %s returned extra %d values", name.c_str(), stackNewSize - stackSize);
|
||||
warning("built-in procedure %s returned extra %d values", sym->name.c_str(), stackNewSize - stackSize);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1248,6 +1252,7 @@ void LC::call(Common::String name, int nargs) {
|
||||
fp->sp = sym;
|
||||
fp->retpc = g_lingo->_pc;
|
||||
fp->retscript = g_lingo->_currentScript;
|
||||
fp->retctx = g_lingo->_currentScriptContext;
|
||||
fp->localvars = g_lingo->_localvars;
|
||||
|
||||
// Create new set of local variables
|
||||
@ -1274,6 +1279,7 @@ void LC::c_procret() {
|
||||
g_lingo->_callstack.pop_back();
|
||||
|
||||
g_lingo->_currentScript = fp->retscript;
|
||||
g_lingo->_currentScriptContext = fp->retctx;
|
||||
g_lingo->_pc = fp->retpc;
|
||||
|
||||
g_lingo->cleanLocalVars();
|
||||
|
@ -101,6 +101,7 @@ namespace LC {
|
||||
void c_jumpifz();
|
||||
void c_call();
|
||||
|
||||
void call(Symbol *, int nargs);
|
||||
void call(Common::String name, int nargs);
|
||||
|
||||
void c_procret();
|
||||
|
@ -142,8 +142,9 @@ void Lingo::addCode(const char *code, ScriptType type, uint16 id) {
|
||||
|
||||
// FIXME: unpack into seperate functions
|
||||
_currentScriptFunction = 0;
|
||||
_currentScriptContext->functions.push_back(new ScriptData);
|
||||
_currentScript = _currentScriptContext->functions[_currentScriptFunction];
|
||||
_currentScriptContext->functions.push_back(new Symbol);
|
||||
_currentScript = new ScriptData;
|
||||
_currentScriptContext->functions[_currentScriptFunction]->u.defn = _currentScript;
|
||||
|
||||
_linenumber = _colnumber = 1;
|
||||
_hadError = false;
|
||||
@ -232,7 +233,7 @@ void Lingo::executeScript(ScriptType type, uint16 id, uint16 function) {
|
||||
debugC(1, kDebugLingoExec, "Executing script type: %s, id: %d, function: %d", scriptType2str(type), id, function);
|
||||
|
||||
_currentScriptContext = _scriptContexts[type][id];
|
||||
_currentScript = _currentScriptContext->functions[function];
|
||||
_currentScript = _currentScriptContext->functions[function]->u.defn;
|
||||
_pc = 0;
|
||||
_returning = false;
|
||||
|
||||
|
@ -82,7 +82,7 @@ struct Symbol { /* symbol table entry */
|
||||
int nargs; /* number of arguments */
|
||||
int maxArgs; /* maximal number of arguments, for builtins */
|
||||
bool parens; /* whether parens required or not, for builitins */
|
||||
|
||||
|
||||
bool global;
|
||||
|
||||
Symbol();
|
||||
@ -119,7 +119,7 @@ struct Builtin {
|
||||
};
|
||||
|
||||
struct ScriptContext {
|
||||
Common::Array<ScriptData *> functions;
|
||||
Common::Array<Symbol *> functions;
|
||||
Common::Array<Datum> constants;
|
||||
};
|
||||
|
||||
@ -135,6 +135,7 @@ 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 */
|
||||
ScriptContext *retctx; /* which script context to use after return */
|
||||
SymbolHash *localvars;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user