COMMON: Move Lua into Common and make it into...
an engine feature
This commit is contained in:
parent
f019afa94a
commit
c1f029c6dc
71 changed files with 88 additions and 70 deletions
|
@ -1,384 +0,0 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distri8buted in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This code is heavily based on the pluto code base. Copyright below
|
||||
*/
|
||||
|
||||
/* Tamed Pluto - Heavy-duty persistence for Lua
|
||||
* Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
|
||||
* domain. People making use of this software as part of an application
|
||||
* are politely requested to email the author at sneftel@gmail.com
|
||||
* with a brief description of the application, primarily to satisfy his
|
||||
* curiosity.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Instrumented by Stefan Reich (info@luaos.net)
|
||||
* for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
|
||||
*/
|
||||
|
||||
/**
|
||||
* This code is heavily based on the Pluto code base. Copyright below
|
||||
*/
|
||||
|
||||
/* Tamed Pluto - Heavy-duty persistence for Lua
|
||||
* Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
|
||||
* domain. People making use of this software as part of an application
|
||||
* are politely requested to email the author at sneftel@gmail.com
|
||||
* with a brief description of the application, primarily to satisfy his
|
||||
* curiosity.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Instrumented by Stefan Reich (info@luaos.net)
|
||||
* for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
|
||||
*/
|
||||
|
||||
|
||||
#include "sword25/util/lua_persistence_util.h"
|
||||
|
||||
#include "common/scummsys.h"
|
||||
|
||||
#include "lua/lobject.h"
|
||||
#include "lua/lstate.h"
|
||||
#include "lua/lgc.h"
|
||||
#include "lua/lopcodes.h"
|
||||
|
||||
|
||||
namespace Lua {
|
||||
|
||||
void *lua_realloc(lua_State *luaState, void *block, size_t osize, size_t nsize) {
|
||||
global_State *globalState = G(luaState);
|
||||
|
||||
block = (*globalState->frealloc)(globalState->ud, block, osize, nsize);
|
||||
globalState->totalbytes = (globalState->totalbytes - osize) + nsize;
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
void pushObject(lua_State *luaState, TValue *obj) {
|
||||
setobj2s(luaState, luaState->top, obj);
|
||||
|
||||
api_check(luaState, luaState->top < luaState->ci->top);
|
||||
luaState->top++;
|
||||
}
|
||||
|
||||
void pushProto(lua_State *luaState, Proto *proto) {
|
||||
TValue obj;
|
||||
setptvalue(luaState, &obj, proto);
|
||||
|
||||
pushObject(luaState, &obj);
|
||||
}
|
||||
|
||||
void pushUpValue(lua_State *luaState, UpVal *upval) {
|
||||
TValue obj;
|
||||
|
||||
obj.value.gc = cast(GCObject *, upval);
|
||||
obj.tt = LUA_TUPVAL;
|
||||
checkliveness(G(L), obj);
|
||||
|
||||
pushObject(luaState, &obj);
|
||||
}
|
||||
|
||||
void pushString(lua_State *luaState, TString *str) {
|
||||
TValue o;
|
||||
setsvalue(luaState, &o, str);
|
||||
|
||||
pushObject(luaState, &o);
|
||||
}
|
||||
|
||||
/* A simple reimplementation of the unfortunately static function luaA_index.
|
||||
* Does not support the global table, registry, or upvalues. */
|
||||
StkId getObject(lua_State *luaState, int stackpos) {
|
||||
if (stackpos > 0) {
|
||||
lua_assert(luaState->base + stackpos - 1 < luaState->top);
|
||||
return luaState->base + stackpos - 1;
|
||||
} else {
|
||||
lua_assert(L->top - stackpos >= L->base);
|
||||
return luaState->top + stackpos;
|
||||
}
|
||||
}
|
||||
|
||||
void lua_linkObjToGC(lua_State *luaState, GCObject *obj, lu_byte type) {
|
||||
global_State *globalState = G(luaState);
|
||||
|
||||
obj->gch.next = globalState->rootgc;
|
||||
globalState->rootgc = obj;
|
||||
obj->gch.marked = luaC_white(globalState);
|
||||
obj->gch.tt = type;
|
||||
}
|
||||
|
||||
Closure *lua_newLclosure(lua_State *luaState, int numElements, Table *elementTable) {
|
||||
Closure *c = (Closure *)lua_malloc(luaState, sizeLclosure(numElements));
|
||||
lua_linkObjToGC(luaState, obj2gco(c), LUA_TFUNCTION);
|
||||
|
||||
c->l.isC = 0;
|
||||
c->l.env = elementTable;
|
||||
c->l.nupvalues = cast_byte(numElements);
|
||||
|
||||
while (numElements--) {
|
||||
c->l.upvals[numElements] = NULL;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void pushClosure(lua_State *luaState, Closure *closure) {
|
||||
TValue obj;
|
||||
setclvalue(luaState, &obj, closure);
|
||||
pushObject(luaState, &obj);
|
||||
}
|
||||
|
||||
Proto *createProto(lua_State *luaState) {
|
||||
Proto *newProto = (Proto *)lua_malloc(luaState, sizeof(Proto));
|
||||
lua_linkObjToGC(luaState, obj2gco(newProto), LUA_TPROTO);
|
||||
|
||||
newProto->k = NULL;
|
||||
newProto->sizek = 0;
|
||||
newProto->p = NULL;
|
||||
newProto->sizep = 0;
|
||||
newProto->code = NULL;
|
||||
newProto->sizecode = 0;
|
||||
newProto->sizelineinfo = 0;
|
||||
newProto->sizeupvalues = 0;
|
||||
newProto->nups = 0;
|
||||
newProto->upvalues = NULL;
|
||||
newProto->numparams = 0;
|
||||
newProto->is_vararg = 0;
|
||||
newProto->maxstacksize = 0;
|
||||
newProto->lineinfo = NULL;
|
||||
newProto->sizelocvars = 0;
|
||||
newProto->locvars = NULL;
|
||||
newProto->linedefined = 0;
|
||||
newProto->lastlinedefined = 0;
|
||||
newProto->source = NULL;
|
||||
|
||||
return newProto;
|
||||
}
|
||||
|
||||
TString *createString(lua_State *luaState, const char *str, size_t len) {
|
||||
TString *res;
|
||||
lua_pushlstring(luaState, str, len);
|
||||
|
||||
res = rawtsvalue(luaState->top - 1);
|
||||
lua_pop(luaState, 1);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Proto *makeFakeProto(lua_State *L, lu_byte nups) {
|
||||
Proto *p = createProto(L);
|
||||
|
||||
p->sizelineinfo = 1;
|
||||
p->lineinfo = lua_newVector(L, 1, int);
|
||||
p->lineinfo[0] = 1;
|
||||
p->sizecode = 1;
|
||||
p->code = lua_newVector(L, 1, Instruction);
|
||||
p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
|
||||
p->source = createString(L, "", 0);
|
||||
p->maxstacksize = 2;
|
||||
p->nups = nups;
|
||||
p->sizek = 0;
|
||||
p->sizep = 0;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
UpVal *createUpValue(lua_State *luaState, int stackpos) {
|
||||
UpVal *upValue = (UpVal *)lua_malloc(luaState, sizeof(UpVal));
|
||||
lua_linkObjToGC(luaState, (GCObject *)upValue, LUA_TUPVAL);
|
||||
upValue->tt = LUA_TUPVAL;
|
||||
upValue->v = &upValue->u.value;
|
||||
upValue->u.l.prev = NULL;
|
||||
upValue->u.l.next = NULL;
|
||||
|
||||
const TValue *o2 = (TValue *)getObject(luaState, stackpos);
|
||||
upValue->v->value = o2->value;
|
||||
upValue->v->tt = o2->tt;
|
||||
checkliveness(G(L), upValue->v);
|
||||
|
||||
return upValue;
|
||||
}
|
||||
|
||||
void unboxUpValue(lua_State *luaState) {
|
||||
// >>>>> ...... func
|
||||
LClosure *lcl;
|
||||
UpVal *uv;
|
||||
|
||||
lcl = (LClosure *)clvalue(getObject(luaState, -1));
|
||||
uv = lcl->upvals[0];
|
||||
|
||||
lua_pop(luaState, 1);
|
||||
// >>>>> ......
|
||||
|
||||
pushUpValue(luaState, uv);
|
||||
// >>>>> ...... upValue
|
||||
}
|
||||
|
||||
size_t appendStackToStack_reverse(lua_State *from, lua_State *to) {
|
||||
for (StkId id = from->top - 1; id >= from->stack; --id) {
|
||||
setobj2s(to, to->top, id);
|
||||
to->top++;
|
||||
}
|
||||
|
||||
return from->top - from->stack;
|
||||
}
|
||||
|
||||
void correctStack(lua_State *L, TValue *oldstack) {
|
||||
CallInfo *ci;
|
||||
GCObject *up;
|
||||
L->top = (L->top - oldstack) + L->stack;
|
||||
for (up = L->openupval; up != NULL; up = up->gch.next)
|
||||
gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
|
||||
for (ci = L->base_ci; ci <= L->ci; ci++) {
|
||||
ci->top = (ci->top - oldstack) + L->stack;
|
||||
ci->base = (ci->base - oldstack) + L->stack;
|
||||
ci->func = (ci->func - oldstack) + L->stack;
|
||||
}
|
||||
L->base = (L->base - oldstack) + L->stack;
|
||||
}
|
||||
|
||||
void lua_reallocstack(lua_State *L, int newsize) {
|
||||
TValue *oldstack = L->stack;
|
||||
int realsize = newsize + 1 + EXTRA_STACK;
|
||||
|
||||
lua_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
|
||||
L->stacksize = realsize;
|
||||
L->stack_last = L->stack + newsize;
|
||||
correctStack(L, oldstack);
|
||||
}
|
||||
|
||||
void lua_reallocCallInfo(lua_State *lauState, int newsize) {
|
||||
CallInfo *oldci = lauState->base_ci;
|
||||
lua_reallocvector(lauState, lauState->base_ci, lauState->size_ci, newsize, CallInfo);
|
||||
|
||||
lauState->size_ci = newsize;
|
||||
lauState->ci = (lauState->ci - oldci) + lauState->base_ci;
|
||||
lauState->end_ci = lauState->base_ci + lauState->size_ci - 1;
|
||||
}
|
||||
|
||||
void GCUnlink(lua_State *luaState, GCObject *gco) {
|
||||
GCObject *prevslot;
|
||||
if (G(luaState)->rootgc == gco) {
|
||||
G(luaState)->rootgc = G(luaState)->rootgc->gch.next;
|
||||
return;
|
||||
}
|
||||
|
||||
prevslot = G(luaState)->rootgc;
|
||||
while (prevslot->gch.next != gco) {
|
||||
prevslot = prevslot->gch.next;
|
||||
}
|
||||
|
||||
prevslot->gch.next = prevslot->gch.next->gch.next;
|
||||
}
|
||||
|
||||
TString *lua_newlstr(lua_State *luaState, const char *str, size_t len) {
|
||||
lua_pushlstring(luaState, str, len);
|
||||
TString *luaStr = &(luaState->top - 1)->value.gc->ts;
|
||||
|
||||
lua_pop(luaState, 1);
|
||||
|
||||
return luaStr;
|
||||
}
|
||||
|
||||
void lua_link(lua_State *luaState, GCObject *o, lu_byte tt) {
|
||||
global_State *g = G(luaState);
|
||||
o->gch.next = g->rootgc;
|
||||
g->rootgc = o;
|
||||
o->gch.marked = luaC_white(g);
|
||||
o->gch.tt = tt;
|
||||
}
|
||||
|
||||
Proto *lua_newproto(lua_State *luaState) {
|
||||
Proto *f = (Proto *)lua_malloc(luaState, sizeof(Proto));
|
||||
lua_link(luaState, obj2gco(f), LUA_TPROTO);
|
||||
f->k = NULL;
|
||||
f->sizek = 0;
|
||||
f->p = NULL;
|
||||
f->sizep = 0;
|
||||
f->code = NULL;
|
||||
f->sizecode = 0;
|
||||
f->sizelineinfo = 0;
|
||||
f->sizeupvalues = 0;
|
||||
f->nups = 0;
|
||||
f->upvalues = NULL;
|
||||
f->numparams = 0;
|
||||
f->is_vararg = 0;
|
||||
f->maxstacksize = 0;
|
||||
f->lineinfo = NULL;
|
||||
f->sizelocvars = 0;
|
||||
f->locvars = NULL;
|
||||
f->linedefined = 0;
|
||||
f->lastlinedefined = 0;
|
||||
f->source = NULL;
|
||||
return f;
|
||||
}
|
||||
|
||||
UpVal *makeUpValue(lua_State *luaState, int stackPos) {
|
||||
UpVal *uv = lua_new(luaState, UpVal);
|
||||
lua_link(luaState, (GCObject *)uv, LUA_TUPVAL);
|
||||
uv->tt = LUA_TUPVAL;
|
||||
uv->v = &uv->u.value;
|
||||
uv->u.l.prev = NULL;
|
||||
uv->u.l.next = NULL;
|
||||
|
||||
setobj(luaState, uv->v, getObject(luaState, stackPos));
|
||||
|
||||
return uv;
|
||||
}
|
||||
|
||||
void boxUpValue_start(lua_State *luaState) {
|
||||
LClosure *closure;
|
||||
closure = (LClosure *)lua_newLclosure(luaState, 1, hvalue(&luaState->l_gt));
|
||||
pushClosure(luaState, (Closure *)closure);
|
||||
// >>>>> ...... func
|
||||
closure->p = makeFakeProto(luaState, 1);
|
||||
|
||||
// Temporarily initialize the upvalue to nil
|
||||
lua_pushnil(luaState);
|
||||
closure->upvals[0] = makeUpValue(luaState, -1);
|
||||
lua_pop(luaState, 1);
|
||||
}
|
||||
|
||||
void boxUpValue_finish(lua_State *luaState) {
|
||||
// >>>>> ...... func obj
|
||||
LClosure *lcl = (LClosure *)clvalue(getObject(luaState, -2));
|
||||
|
||||
lcl->upvals[0]->u.value = *getObject(luaState, -1);
|
||||
lua_pop(luaState, 1);
|
||||
// >>>>> ...... func
|
||||
}
|
||||
|
||||
} // End of namespace Lua
|
Loading…
Add table
Add a link
Reference in a new issue