aboutsummaryrefslogtreecommitdiff
path: root/engines/sword25/util/pluto
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sword25/util/pluto')
-rw-r--r--engines/sword25/util/pluto/CHANGELOG37
-rw-r--r--engines/sword25/util/pluto/FILEFORMAT168
-rw-r--r--engines/sword25/util/pluto/README133
-rw-r--r--engines/sword25/util/pluto/THANKS9
-rw-r--r--engines/sword25/util/pluto/pdep.cpp112
-rw-r--r--engines/sword25/util/pluto/pdep/README5
-rw-r--r--engines/sword25/util/pluto/pdep/lzio.h65
-rw-r--r--engines/sword25/util/pluto/pdep/pdep.h42
-rw-r--r--engines/sword25/util/pluto/pluto.cpp2083
-rw-r--r--engines/sword25/util/pluto/pluto.h25
-rw-r--r--engines/sword25/util/pluto/plzio.cpp74
11 files changed, 0 insertions, 2753 deletions
diff --git a/engines/sword25/util/pluto/CHANGELOG b/engines/sword25/util/pluto/CHANGELOG
deleted file mode 100644
index 1be321f898..0000000000
--- a/engines/sword25/util/pluto/CHANGELOG
+++ /dev/null
@@ -1,37 +0,0 @@
-$Id$
-
--- 2.4 --
-* Changed upval unboxing to allow upvals which contain func-housed cycles
-* Added stack checking to all stack-growing functions
-* Serialized debug information for functions
-
--- 2.3 --
-* Added LUALIB_API declaration for luaopen_pluto
-
--- 2.2 --
-* Rolled all internal Lua dependencies into the Pluto distribution
-* Made the unit tests depend on dynamically loading Pluto
-
--- 2.1 --
-* Various fixes to make the GC happy
-* stack size always expanded where necessary
-* fixed some memory leaks
-* GC disabled during unpersist
-* callstack initialized for traversal
-
-This changelog is maintained as of version 2.0alpha1.
-Earlier versions are changelogged on the LuaForge site.
-
--- 2.0 --
-* Fixed a few format changes to 5.1.3
-* Fixed myriad warnings
-* GCC compliance: not incrementing cast results
-* Fix for self-referring upvals
-* Renamed loading function to work with Lua module system
-* Loading tables with __newindex works
-* unpersist makes buffer copy
-
--- 2.0alpha1 --
-* Fixed all outstanding 5.0->5.1 conversion issues
-* Made heavier use of size_t in preference to int
-* Fixed GC/Upval issue (thanks to Eric Jacobs)
diff --git a/engines/sword25/util/pluto/FILEFORMAT b/engines/sword25/util/pluto/FILEFORMAT
deleted file mode 100644
index e7716675c7..0000000000
--- a/engines/sword25/util/pluto/FILEFORMAT
+++ /dev/null
@@ -1,168 +0,0 @@
-$Id$
-
-pluto_persist() produces a "hunk" of objects. Here's the file format adhered
-to by the function, and expected by pluto_unpersist().
-
-As a developer, I feel that where file format information is given it is of
-utmost importance that that information precisely and accurately reflects the
-actual operation of the application. Therefore, if you find any discrepancy
-between this and actual operation, please lambast me thoroughly over email.
-
-Pseudo-C is used to express the file format. Padding is assumed to be
-nonexistent. The keyword "one_of" is used to express a concept similar to
-"union", except that its size is the size of the actual datatype chosen. Thus,
-objects which contain, directly or indirectly, a one_of, may vary in size.
-
-
-struct Object {
- int firstTime; /* Whether this is the first time the object
- is being referenced */
- one_of {
- RealObject o; /* if firstTime == 1 */
- Reference r; /* if firstTime == 0 */
- };
-};
-
-struct Reference {
- int ref; /* The index the object was registered with */
-};
-
-struct RealObject {
- int type; /* The type of the object */
- one_of {
- Boolean b; /* If type == LUA_TBOOLEAN */
- LightUserData l; /* If type == LUA_TLIGHTUSERDATA */
- Number n; /* If type == LUA_TNUMBER */
- String s; /* If type == LUA_TSTRING */
- Table t; /* If type == LUA_TTABLE */
- Function f; /* If type == LUA_TFUNCTION */
- Userdata u; /* If type == LUA_TUSERDATA */
- Thread th; /* If type == LUA_TTHREAD */
- Proto p; /* If type == LUA_TPROTO (from lobject.h) */
- Upval uv; /* If type == LUA_TUPVAL (from lobject.h) */
- }; /* The actual object */
-};
-
-struct Boolean {
- int32 bvalue; /* 0 for false, 1 for true */
-};
-
-struct LightUserData {
- void* luvalue; /* The actual, literal pointer */
-};
-
-struct Number {
- lua_Number nvalue; /* The actual number */
-};
-
-struct String {
- int length; /* The length of the string */
- char str[length]; /* The actual string (not null terminated) */
-};
-
-struct Table {
- int isspecial; /* 1 if SP is used; 0 otherwise */
- one_of {
- Closure c; /* if isspecial == 1; closure to refill the table */
- LiteralTable t; /* if isspecial == 0; literal table info */
- };
-};
-
-struct LiteralTable {
- Object metatable; /* nil for default metatable */
- Pair p[]; /* key/value pairs */
- Object nil = nil; /* Nil reference to terminate */
-};
-
-struct Pair {
- Object key;
- Object value;
-};
-
-struct Function { /* Actually a closure */
- lu_byte nups; /* Number of upvalues the function uses */
- Object proto; /* The proto this function uses */
- Object upvals[nups]; /* All upvalues */
- Object fenv; /* The FEnv (nil for the global table)
-};
-
-struct Upval {
- Object obj; /* The object this upval refers to */
-}
-
-struct Userdata {
- int isSpecial; /* 1 for special persistence, 0 for literal
- one_of {
- LiteralUserdata lu; /* if is_special is 0 */
- SpecialUserdata su; /* if is_special is 1 */
- };
-};
-
-struct LiteralUserdata {
- Object metatable; /* The metatable (nil for default) */
- int length; /* Size of the data */
- char data[length]; /* The actual data */
-};
-
-struct SpecialUserdata {
- int length; /* The size of the data */
- Object func; /* The closure used to fill the userdata */
-};
-
-struct Thread {
- int stacksize; /* The size of the stack filled with objects,
- * including the "nil" that is hidden below
- * the bottom of the stack visible to C */
- Object stack[stacksize];/* Indices of all stack values, bottom up */
- int callinfosize; /* Number of elements in the CallInfo stack */
- CallInfo callinfostack[callinfosize]; /* The CallInfo stack */
- int base; /* base = L->base - L->stack; */
- int top; /* top = L->top - L->stack; */
- OpenUpval openupvals[]; /* Upvalues to open */
- Object nil = nil; /* To terminate the open upvalues list */
-};
-
-struct OpenUpval {
- Object upval; /* The upvalue */
- int stackpos; /* The stack position to "reopen" it to */
-
-};
-
-struct CallInfo {
- int base; /* base = ci->base - L->stack; */
- int top; /* top = ci->top - L->stack; */
- int pc; /* pc = ci->pc - proto->code; */
- int state; /* flags used by the CallInfo */
-};
-
-struct Proto {
- int sizek; /* Number of constants referenced */
- Object k[sizek]; /* Constants referenced */
- int sizep; /* Number of inner Protos referenced */
- Object p[sizep]; /* Inner Protos referenced */
- int sizecode; /* Number of instructions in code */
- Instruction code[sizecode]; /* The proto's code */
- ProtoDebug debuginfo; /* Debug information for the proto */
- lu_byte nups; /* Number of upvalues used */
- lu_byte numparams; /* Number of parameters taken */
- lu_byte is_vararg; /* 1 if function accepts varargs, 0 otherwise */
- lu_byte maxstacksize; /* Size of stack reserved for the function */
-};
-
-struct ProtoDebug {
- int sizeupvals; /* Number of upvalue names */
- Object upvals; /* Upvalue names */
- int sizelocvars; /* Number of local variable names */
- LocVar[sizelocvars]; /* Local variable names */
- Object source; /* The source code */
- int sizelineinfo; /* Number of opcode-line mappings */
- int lineinfo[sizelineinfo]; /* opcode-line mappings */
- int linedefined; /* Start of line range */
- int lastlinedefined; /* End of line range */
-};
-
-struct LocVar {
- Object name; /* Name of the local variable */
- int startpc; /* Point where variable is active */
- int endpc; /* Point where variable is dead */
-};
diff --git a/engines/sword25/util/pluto/README b/engines/sword25/util/pluto/README
deleted file mode 100644
index 838fce498b..0000000000
--- a/engines/sword25/util/pluto/README
+++ /dev/null
@@ -1,133 +0,0 @@
-$Id$
-
-PLUTO - Heavy duty persistence for Lua
-
-Pluto is a library which allows users to write arbitrarily large portions
-of the "Lua universe" into a flat file, and later read them back into the
-same or a different Lua universe. Object references are appropriately
-handled, such that the file contains everything needed to recreate the
-objects in question.
-
-Pluto has the following major features:
-* Can persist any Lua function
-* Can persist threads
-* Works with any Lua chunkreader/chunkwriter
-* Support for "invariant" permanent objects, of all datatypes
-* Can invoke metafunctions for custom persistence of tables and userdata
-
-Pluto 2.2 requires Lua 5.1.3. If you need to use Pluto with Lua
-5.0, please use version 1.2 of Pluto.
-
-Starting with version 2.2, Pluto no longer depends on the Lua sources.
-Instead, it subsumes the required headers into its own codebase.
-As a result, it may not work properly with Lua version 5.1.4 or later.
-
-Pluto may have bugs. Users are advised to define lua_assert in
-luaconf.h to something useful when compiling in debug mode, to catch
-assertions by Pluto and Lua.
-
-The Pluto library consists of two public functions.
-
-int pluto_persist(lua_State *L, lua_Chunkwriter writer, void *ud)
-
-This function recursively persists the Lua object in stack position 2
-and all other objects which are directly or indirectly referenced by
-it, except those referenced in the permanent object table. The data
-is written using the chunk-writer given, and that writer is passed
-the arbitrary pointer value ud.
-
-The Lua stack must contain exactly and only these two items, in order:
-
-1. A table of permanent objects, that should not be persisted. For each
-permanent object, the object itself should be the key, and a unique
-object of any type should be the value. Likely candidates for this table
-include Lua functions (including those in the Lua libraries) that are
-loaded at load-time. It must include all non-persistable objects that
-are referenced by the object to be persisted. The table is not modified
-by the function. Objects in this table are considered "opaque" and are
-not examined or descended into. Objects should not appear in the table
-multiple times; the result of doing this is undefined (though probably
-harmless). NOTE: If you are planning to persist threads, keep in mind
-that all yielded threads have coroutine.yield on the tops of their
-stacks. Since it's a C function, it should be put here. For complex
-permanents, it may be a good idea to use the __index meta-function of
-the permanents table to "search" for permanents.
-
-2. The single object to be persisted. In many cases, this will be the
-global table. For more flexibility, however, it may be something like a
-table built for the occasion, with various values to keep track of. The
-object may not be nil.
-
-
-int pluto_unpersist(lua_State *L, lua_Chunkreader reader, void *ud)
-
-This function loads in a Lua object and places it on top of the stack. All
-objects directly or indirectly referenced by it are also loaded.
-
-The Lua stack must contain, as its top value, a table of permanent
-objects. This table should be like the permanent object table used when
-persisting, but with the key and value of each pair reversed. These
-objects are used as substitutes for those referenced in their positions
-when persisting, and under most circumstances should be identical objects
-to those referenced in the permanents table used for persisting. It's
-okay for multiple keys to refer to the same object.
-
-
-RUNNING PLUTO FROM LUA:
-It is also possible to invoke pluto from a Lua script. The C function
-pluto_open() will register pluto.persist and pluto.unpersist, lua functions
-which operate on strings. The first takes a permanents table and a root
-object, and returns a string; the second takes a permanents table and a
-string, and returns the root object.
-
-An error will be raised if pluto.persist is called from a thread which is
-itself referenced by the root object.
-
-SPECIAL PERSISTENCE:
-Tables and userdata have special persistence semantics. These semantics are
-keyed to the value of the object's metatable's __persist member, if any. This
-member may be any of the following four values:
-1. Boolean "true": The table or userdata is persisted literally; tables are
-persisted member-by-member, and userdata are written out as literal data.
-2. Boolean "false": An error is returned, indicating that the object cannot
-be persisted.
-3. A function: This function should take one argument, the object in question,
-and return one result, a closure. This "fixup closure", in turn, will be
-persisted, and during unpersistence will be called. The closure will be
-responsible for recreating the object with the appropriate data, based on
-its upvalues.
-4. Nil, or no metatable. In the case of tables, the table is literally
-persisted. In the case of userdata, an error is returned.
-
-Here's an example of special persistence for a simple 3d vector object:
-
-vec = { x = 2, y = 1, z = 4 }
-setmetatable(vec, { __persist = function(oldtbl)
- local x = oldtbl.x
- local y = oldtbl.y
- local z = oldtbl.z
- local mt = getmetatable(oldtbl)
- return function()
- newtbl = {}
- newtbl.x = x
- newtbl.y = y
- newtbl.z = z
- setmetatable(newtbl, mt)
- return newtbl
- end
-end })
-
-Note how x, y, z, and the mt are explicitly pulled out of the table. It is
-important that the fixup closure returned not reference the original table
-directly, as that table would again be persisted as an upvalue, leading to an
-infinite loop. Also note that the object's metatable is NOT automatically
-persisted; it is necessary for the fixup closure to reset it, if it wants.
-
-LIMITATIONS/TODO:
-* Light userdata are persisted literally, as their pointer values. This
-may or may not be what you want.
-* Closures of C functions may not be persisted. Once it becomes possible
-to specify a C function "proto" as a permanent object, this restriction
-will be relaxed.
-
-BUGS: None known. Emphasis on the 'known'.
diff --git a/engines/sword25/util/pluto/THANKS b/engines/sword25/util/pluto/THANKS
deleted file mode 100644
index 443713fa61..0000000000
--- a/engines/sword25/util/pluto/THANKS
+++ /dev/null
@@ -1,9 +0,0 @@
-Pluto is surprisingly robust and useful. This would not be the case without
-the hard work and helpfulness of the following people, mentioned in no
-particular order:
-
-Ivko Stanilov
-Goran Adrinek
-Eric Jacobs
-Anolan Milanes
-Malte Thiesen
diff --git a/engines/sword25/util/pluto/pdep.cpp b/engines/sword25/util/pluto/pdep.cpp
deleted file mode 100644
index a32c43b42d..0000000000
--- a/engines/sword25/util/pluto/pdep.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/* This file is derived from the Lua source code. Please see lua.h for
-the copyright statement.
-*/
-
-#include "pdep/pdep.h"
-
-#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
-
-void pdep_pushobject (lua_State *L, const TValue *o) {
- setobj2s(L, L->top, o);
- api_incr_top(L);
-}
-
-void *pdep_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
- global_State *g = G(L);
- lua_assert((osize == 0) == (block == NULL));
- block = (*g->frealloc)(g->ud, block, osize, nsize);
- lua_assert((nsize == 0) == (block == NULL));
- g->totalbytes = (g->totalbytes - osize) + nsize;
- return block;
-}
-
-void pdep_link (lua_State *L, GCObject *o, lu_byte tt) {
- global_State *g = G(L);
- o->gch.next = g->rootgc;
- g->rootgc = o;
- o->gch.marked = luaC_white(g);
- o->gch.tt = tt;
-}
-
-Proto *pdep_newproto (lua_State *L) {
- Proto *f = pdep_new(L, Proto);
- pdep_link(L, 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;
-}
-
-Closure *pdep_newLclosure (lua_State *L, int nelems, Table *e) {
- Closure *c = cast(Closure *, pdep_malloc(L, sizeLclosure(nelems)));
- pdep_link(L, obj2gco(c), LUA_TFUNCTION);
- c->l.isC = 0;
- c->l.env = e;
- c->l.nupvalues = cast_byte(nelems);
- while (nelems--) c->l.upvals[nelems] = NULL;
- return c;
-}
-
-static 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 pdep_reallocstack (lua_State *L, int newsize) {
- TValue *oldstack = L->stack;
- int realsize = newsize + 1 + EXTRA_STACK;
- lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
- pdep_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
- L->stacksize = realsize;
- L->stack_last = L->stack+newsize;
- correctstack(L, oldstack);
-}
-
-void pdep_growstack (lua_State *L, int n) {
- if (n <= L->stacksize) /* double size is enough? */
- pdep_reallocstack(L, 2*L->stacksize);
- else
- pdep_reallocstack(L, L->stacksize + n);
-}
-
-void pdep_reallocCI (lua_State *L, int newsize) {
- CallInfo *oldci = L->base_ci;
- pdep_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
- L->size_ci = newsize;
- L->ci = (L->ci - oldci) + L->base_ci;
- L->end_ci = L->base_ci + L->size_ci - 1;
-}
-
-TString *pdep_newlstr (lua_State *L, const char *str, size_t l) {
- TString *res;
- lua_pushlstring(L, str, l);
- res = rawtsvalue(L->top-1);
- lua_pop(L, 1);
- return res;
-}
diff --git a/engines/sword25/util/pluto/pdep/README b/engines/sword25/util/pluto/pdep/README
deleted file mode 100644
index 3592754da0..0000000000
--- a/engines/sword25/util/pluto/pdep/README
+++ /dev/null
@@ -1,5 +0,0 @@
-These files are directly copied from the Lua distribution, with the
-exception of lzio.h, which is s/lua{ZM}/pdep/g and has an include removed.
-
-As such, unlike the rest of Pluto, they are released under the
-same terms as Lua. See "lua.h" for the copyright notice.
diff --git a/engines/sword25/util/pluto/pdep/lzio.h b/engines/sword25/util/pluto/pdep/lzio.h
deleted file mode 100644
index 2e37f8d202..0000000000
--- a/engines/sword25/util/pluto/pdep/lzio.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-** $Id$
-** Buffered streams
-** See Copyright Notice in lua.h
-*/
-
-
-#ifndef lzio_h
-#define lzio_h
-
-#include "sword25/util/lua/lua.h"
-
-
-#define EOZ (-1) /* end of stream */
-
-typedef struct Zio ZIO;
-
-#define char2int(c) cast(int, cast(unsigned char, (c)))
-
-#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : pdep_fill(z))
-
-typedef struct Mbuffer {
- char *buffer;
- size_t n;
- size_t buffsize;
-} Mbuffer;
-
-#define pdep_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
-
-#define pdep_buffer(buff) ((buff)->buffer)
-#define pdep_sizebuffer(buff) ((buff)->buffsize)
-#define pdep_bufflen(buff) ((buff)->n)
-
-#define pdep_resetbuffer(buff) ((buff)->n = 0)
-
-
-#define pdep_resizebuffer(L, buff, size) \
- (pdep_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \
- (buff)->buffsize = size)
-
-#define pdep_freebuffer(L, buff) pdep_resizebuffer(L, buff, 0)
-
-
-LUAI_FUNC char *pdep_openspace (lua_State *L, Mbuffer *buff, size_t n);
-LUAI_FUNC void pdep_init (lua_State *L, ZIO *z, lua_Reader reader,
- void *data);
-LUAI_FUNC size_t pdep_read (ZIO* z, void* b, size_t n); /* read next n bytes */
-LUAI_FUNC int pdep_lookahead (ZIO *z);
-
-
-
-/* --------- Private Part ------------------ */
-
-struct Zio {
- size_t n; /* bytes still unread */
- const char *p; /* current position in buffer */
- lua_Reader reader;
- void* data; /* additional data */
- lua_State *L; /* Lua state (for reader) */
-};
-
-
-LUAI_FUNC int pdep_fill (ZIO *z);
-
-#endif
diff --git a/engines/sword25/util/pluto/pdep/pdep.h b/engines/sword25/util/pluto/pdep/pdep.h
deleted file mode 100644
index 664fc812b5..0000000000
--- a/engines/sword25/util/pluto/pdep/pdep.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef PDEP_H
-#define PDEP_H
-
-#include "sword25/util/lua/lua.h"
-#include "sword25/util/pluto/pdep/lzio.h"
-#include "sword25/util/lua/ldo.h"
-#include "sword25/util/lua/lfunc.h"
-#include "sword25/util/lua/lgc.h"
-#include "sword25/util/lua/llimits.h"
-#include "sword25/util/lua/lobject.h"
-#include "sword25/util/lua/lopcodes.h"
-#include "sword25/util/lua/lstate.h"
-#include "sword25/util/lua/lstring.h"
-#include "sword25/util/lua/lauxlib.h"
-
-
-#define pdep_reallocv(L,b,on,n,e) \
- pdep_realloc_(L, (b), (on)*(e), (n)*(e))
-#define pdep_reallocvector(L, v,oldn,n,t) \
- ((v)=cast(t *, pdep_reallocv(L, v, oldn, n, sizeof(t))))
-#define pdep_freearray(L, b, n, t) pdep_reallocv(L, (b), n, 0, sizeof(t))
-#define pdep_newvector(L,n,t) \
- cast(t *, pdep_reallocv(L, NULL, 0, n, sizeof(t)))
-#define pdep_new(L,t) cast(t *, pdep_malloc(L, sizeof(t)))
-#define pdep_malloc(L,t) pdep_realloc_(L, NULL, 0, (t))
-#define pdep_checkstack(L,n) \
- if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \
- pdep_growstack(L, n); \
- else pdep_reallocstack(L, L->stacksize - EXTRA_STACK - 1);
-
-
-void pdep_pushobject (lua_State *L, const TValue *o);
-void *pdep_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize);
-void pdep_link (lua_State *L, GCObject *o, lu_byte tt);
-Proto *pdep_newproto (lua_State *L);
-Closure *pdep_newLclosure (lua_State *L, int nelems, Table *e);
-void pdep_reallocstack (lua_State *L, int newsize);
-void pdep_growstack (lua_State *L, int n);
-void pdep_reallocCI (lua_State *L, int newsize);
-TString *pdep_newlstr (lua_State *L, const char *str, size_t l);
-
-#endif
diff --git a/engines/sword25/util/pluto/pluto.cpp b/engines/sword25/util/pluto/pluto.cpp
deleted file mode 100644
index cbe16b0d5b..0000000000
--- a/engines/sword25/util/pluto/pluto.cpp
+++ /dev/null
@@ -1,2083 +0,0 @@
-/* $Id$ */
-
-/* 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/lua.h"
-#include "pluto.h"
-
-#undef TOTEXT
-
-#define USE_PDEP
-
-#ifdef USE_PDEP
-#include "pdep/pdep.h"
-#define LIF(prefix, name) pdep ## _ ## name
-#else
-#include "lapi.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lgc.h"
-#include "llimits.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "lauxlib.h"
-#define LIF(prefix, name) lua ## prefix ## _ ## name
-#endif
-
-#include <string.h>
-
-
-/* Define this if you want size_t values to be written in 64-bit
- (even on 32-bit systems). Should eliminate at least one source of
- 32/64 bit incompatibility. */
-#define SIZES64
-
-
-/* #define PLUTO_DEBUG */
-
-
-#ifdef SIZES64
-#define VERSION "Tamed Pluto 1.0 with SIZES64 flag"
-#else
-#define VERSION "Tamed Pluto 1.0"
-#endif
-
-
-#ifdef PLUTO_DEBUG
-#include <stdio.h>
-#endif
-
-#define PLUTO_TPERMANENT 101
-
-#define verify(x) { int v = (int)((x)); v=v; lua_assert(v); }
-
-#define NUMTYPES 9
-static const char* typenames[] = {
- "nil",
- "boolean",
- "lightuserdata",
- "number",
- "string",
- "table",
- "function",
- "userdata",
- "thread"
-};
-
-static int humanReadable = 0;
-#define hrBufSize 200
-static char hrBuf[hrBufSize];
-
-typedef struct PersistInfo_t {
- lua_State *L;
- int counter;
- lua_Chunkwriter writer;
- void *ud;
-#ifdef PLUTO_DEBUG
- int level;
-#endif
-} PersistInfo;
-
-#ifdef PLUTO_DEBUG
-void printindent(int indent)
-{
- int il;
- for(il=0; il<indent; il++) {
- printf(" ");
- }
-}
-#endif
-
-/* lua_Chunkwriter signature: (lua_State *L, const void *p, size_t sz, void *ud).
- ud is a pointer to the WriterInfo struct (holds the buffer pointer)
-*/
-
-static void pi_write(PersistInfo *pi, const void *p, size_t size, void *ud) {
- if (humanReadable) {
- uint i;
- snprintf(hrBuf, hrBufSize, " pi_write %d ", (int) size);
- pi->writer(pi->L, hrBuf, strlen(hrBuf), ud);
- for (i = 0; i < size; i++) {
- char b = ((char *)p)[i];
- snprintf(hrBuf, hrBufSize, "%X%X", (b >> 4) & 0xF, b & 0xF);
- pi->writer(pi->L, hrBuf, strlen(hrBuf), ud);
- }
- snprintf(hrBuf, hrBufSize, "\n");
- pi->writer(pi->L, hrBuf, strlen(hrBuf), ud);
- } else {
- pi->writer(pi->L, p, size, ud);
- }
-#ifdef TOTEXT
- int i;
- printf(" pi_write %d ", (int) size);
- for (i = 0; i < size; i++) {
- char b = ((char *)p)[i];
- printf("%X%X", (b >> 4) & 0xF, b & 0xF);
- }
- printf("\n");
-#endif
-}
-
-static void hrOut(PersistInfo *pi) {
- pi->writer(pi->L, hrBuf, strlen(hrBuf), pi->ud);
-}
-
-static void write_size(PersistInfo *pi, size_t *val)
-{
-#ifdef SIZES64
- int64 longval; /* yeah, you really need long long to get 8 bytes on win32... duh. */
- longval = *val;
- pi_write(pi, &longval, 8, pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "write_size64 %ld\n", longval);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("write_size64 %ld\n", longval);
-#endif
-#else
- pi_write(pi, val, sizeof(size_t), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "write_size %ld\n", *((size_t *)val));
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("write_size %ld\n", *val);
-#endif
-#endif
-}
-
-static void read_size(ZIO *zio, size_t *val)
-{
-#ifdef SIZES64
- int64 longval;
- verify(LIF(Z,read)(zio, &longval, 8) == 0);
- *val = longval;
-#else
- verify(LIF(Z,read)(zio, val, sizeof(size_t)) == 0);
-#endif
-}
-
-
-/* Mutual recursion requires prototype */
-static void persist(PersistInfo *pi);
-
-/* A simple reimplementation of the unfortunately static function luaA_index.
- * Does not support the global table, registry, or upvalues. */
-static StkId getobject(lua_State *L, int stackpos)
-{
- if(stackpos > 0) {
- lua_assert(L->base+stackpos-1 < L->top);
- return L->base+stackpos-1;
- } else {
- lua_assert(L->top-stackpos >= L->base);
- return L->top+stackpos;
- }
-}
-
-/* Choose whether to do a regular or special persistence based on an object's
- * metatable. "default" is whether the object, if it doesn't have a __persist
- * entry, is literally persistable or not.
- * Pushes the unpersist closure and returns true if special persistence is
- * used. */
-static int persistspecialobject(PersistInfo *pi, int defaction)
-{
- /* perms reftbl ... obj */
- lua_checkstack(pi->L, 4);
- /* Check whether we should persist literally, or via the __persist
- * metafunction */
- if(!lua_getmetatable(pi->L, -1)) {
- if(defaction) {
- {
- int zero = 0;
- pi_write(pi, &zero, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistspecialobject_write_zero\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistspecialobject_write_zero\n");
-#endif
- }
- return 0;
- } else {
- lua_pushstring(pi->L, "Type not literally persistable by default");
- lua_error(pi->L);
- }
- }
- /* perms reftbl sptbl ... obj mt */
- lua_pushstring(pi->L, "__persist");
- /* perms reftbl sptbl ... obj mt "__persist" */
- lua_rawget(pi->L, -2);
- /* perms reftbl sptbl ... obj mt __persist? */
- if(lua_isnil(pi->L, -1)) {
- /* perms reftbl sptbl ... obj mt nil */
- lua_pop(pi->L, 2);
- /* perms reftbl sptbl ... obj */
- if(defaction) {
- {
- int zero = 0;
- pi_write(pi, &zero, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistspecialobject_write_zero2\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistspecialobject_write_zero2\n");
-#endif
- }
- return 0;
- } else {
- lua_pushstring(pi->L, "Type not literally persistable by default");
- lua_error(pi->L);
- return 0; /* not reached */
- }
- } else if(lua_isboolean(pi->L, -1)) {
- /* perms reftbl sptbl ... obj mt bool */
- if(lua_toboolean(pi->L, -1)) {
- /* perms reftbl sptbl ... obj mt true */
- lua_pop(pi->L, 2);
- /* perms reftbl sptbl ... obj */
- {
- int zero = 0;
- pi_write(pi, &zero, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistspecialobject_write_zero3\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistspecialobject_write_zero3\n");
-#endif
- }
- return 0;
- } else {
- lua_pushstring(pi->L, "Metatable forbade persistence");
- lua_error(pi->L);
- return 0; /* not reached */
- }
- } else if(!lua_isfunction(pi->L, -1)) {
- lua_pushstring(pi->L, "__persist not nil, boolean, or function");
- lua_error(pi->L);
- }
- /* perms reftbl ... obj mt __persist */
- lua_pushvalue(pi->L, -3);
- /* perms reftbl ... obj mt __persist obj */
-#ifdef PLUTO_PASS_USERDATA_TO_PERSIST
- lua_pushlightuserdata(pi->L, (void *)pi->writer);
- lua_pushlightuserdata(pi->L, pi->ud);
- /* perms reftbl ... obj mt __persist obj ud */
- lua_call(pi->L, 3, 1);
- /* perms reftbl ... obj mt func? */
-#else
- lua_call(pi->L, 1, 1);
- /* perms reftbl ... obj mt func? */
-#endif
- /* perms reftbl ... obj mt func? */
- if(!lua_isfunction(pi->L, -1)) {
- lua_pushstring(pi->L, "__persist function did not return a function");
- lua_error(pi->L);
- }
- /* perms reftbl ... obj mt func */
- {
- int one = 1;
- pi_write(pi, &one, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistspecialobject_write_one\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistspecialobject_write_one\n");
-#endif
- }
- persist(pi);
- /* perms reftbl ... obj mt func */
- lua_pop(pi->L, 2);
- /* perms reftbl ... obj */
- return 1;
-}
-
-static void persisttable(PersistInfo *pi)
-{
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persisttable\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persisttable\n");
-#endif
-
- /* perms reftbl ... tbl */
- lua_checkstack(pi->L, 3);
- if(persistspecialobject(pi, 1)) {
- /* perms reftbl ... tbl */
- return;
- }
- /* perms reftbl ... tbl */
- /* First, persist the metatable (if any) */
- if(!lua_getmetatable(pi->L, -1)) {
- lua_pushnil(pi->L);
- }
- /* perms reftbl ... tbl mt/nil */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... tbl */
-
- /* Now, persist all k/v pairs */
- lua_pushnil(pi->L);
- /* perms reftbl ... tbl nil */
- while(lua_next(pi->L, -2)) {
- /* perms reftbl ... tbl k v */
- lua_pushvalue(pi->L, -2);
- /* perms reftbl ... tbl k v k */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... tbl k v */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... tbl k */
- }
- /* perms reftbl ... tbl */
- /* Terminate list */
- lua_pushnil(pi->L);
- /* perms reftbl ... tbl nil */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... tbl */
-}
-
-static void persistuserdata(PersistInfo *pi) {
- /* perms reftbl ... udata */
- lua_checkstack(pi->L, 2);
- if(persistspecialobject(pi, 0)) {
- /* perms reftbl ... udata */
- return;
- } else {
- /* Use literal persistence */
- size_t length = uvalue(getobject(pi->L, -1))->len;
- write_size(pi, &length);
- pi_write(pi, lua_touserdata(pi->L, -1), length, pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistuserdata %ld\n", (long) length);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistuserdata %ld\n", (long) length);
-#endif
- if(!lua_getmetatable(pi->L, -1)) {
- /* perms reftbl ... udata */
- lua_pushnil(pi->L);
- /* perms reftbl ... udata mt/nil */
- }
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... udata */
- }
-}
-
-
-static Proto *toproto(lua_State *L, int stackpos)
-{
- return gco2p(getobject(L, stackpos)->value.gc);
-}
-
-static UpVal *toupval(lua_State *L, int stackpos)
-{
- lua_assert(ttype(getobject(L, stackpos)) == LUA_TUPVAL);
- return gco2uv(getobject(L, stackpos)->value.gc);
-}
-
-static void pushproto(lua_State *L, Proto *proto)
-{
- TValue o;
- setptvalue(L, &o, proto);
- LIF(A,pushobject)(L, &o);
-}
-
-#define setuvvalue(L,obj,x) \
- { TValue *i_o=(obj); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUPVAL; \
- checkliveness(G(L),i_o); }
-
-static void pushupval(lua_State *L, UpVal *upval)
-{
- TValue o;
- setuvvalue(L, &o, upval);
- LIF(A,pushobject)(L, &o);
-}
-
-static void pushclosure(lua_State *L, Closure *closure)
-{
- TValue o;
- setclvalue(L, &o, closure);
- LIF(A,pushobject)(L, &o);
-}
-
-static void pushstring(lua_State *L, TString *s)
-{
- TValue o;
- setsvalue(L, &o, s);
- LIF(A,pushobject)(L, &o);
-}
-
-static void persistfunction(PersistInfo *pi)
-{
- /* perms reftbl ... func */
- Closure *cl = clvalue(getobject(pi->L, -1));
- lua_checkstack(pi->L, 2);
- if(cl->c.isC) {
- /* It's a C function. For now, we aren't going to allow
- * persistence of C closures, even if the "C proto" is
- * already in the permanents table. */
- lua_pushstring(pi->L, "Attempt to persist a C function");
- lua_error(pi->L);
- } else {
- /* It's a Lua closure. */
- {
- /* We don't really _NEED_ the number of upvals,
- * but it'll simplify things a bit */
- pi_write(pi, &cl->l.p->nups, sizeof(lu_byte), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistfunction_number_upvalues %d\n", (int) cl->l.p->nups);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistfunction_number_upvalues %d\n", (int) cl->l.p->nups);
-#endif
- }
- /* Persist prototype */
- {
- pushproto(pi->L, cl->l.p);
- /* perms reftbl ... func proto */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... func */
- }
- /* Persist upvalue values (not the upvalue objects
- * themselves) */
- {
- int i;
- for(i=0; i<cl->l.p->nups; i++) {
- /* perms reftbl ... func */
- pushupval(pi->L, cl->l.upvals[i]);
- /* perms reftbl ... func upval */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... func */
- }
- /* perms reftbl ... func */
- }
- /* Persist function environment */
- {
- lua_getfenv(pi->L, -1);
- /* perms reftbl ... func fenv */
- if(lua_equal(pi->L, -1, LUA_GLOBALSINDEX)) {
- /* Function has the default fenv */
- /* perms reftbl ... func _G */
- lua_pop(pi->L, 1);
- /* perms reftbl ... func */
- lua_pushnil(pi->L);
- /* perms reftbl ... func nil */
- }
- /* perms reftbl ... func fenv/nil */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... func */
- }
- }
-}
-
-
-/* Upvalues are tricky. Here's why.
- *
- * A particular upvalue may be either "open", in which case its member v
- * points into a thread's stack, or "closed" in which case it points to the
- * upvalue itself. An upvalue is closed under any of the following conditions:
- * -- The function that initially declared the variable "local" returns
- * -- The thread in which the closure was created is garbage collected
- *
- * To make things wackier, just because a thread is reachable by Lua doesn't
- * mean it's in our root set. We need to be able to treat an open upvalue
- * from an unreachable thread as a closed upvalue.
- *
- * The solution:
- * (a) For the purposes of persisting, don't indicate whether an upvalue is
- * closed or not.
- * (b) When unpersisting, pretend that all upvalues are closed.
- * (c) When persisting, persist all open upvalues referenced by a thread
- * that is persisted, and tag each one with the corresponding stack position
- * (d) When unpersisting, "reopen" each of these upvalues as the thread is
- * unpersisted
- */
-static void persistupval(PersistInfo *pi)
-{
- /* perms reftbl ... upval */
- UpVal *uv = toupval(pi->L, -1);
- lua_checkstack(pi->L, 1);
-
- /* We can't permit the upval to linger around on the stack, as Lua
- * will bail if its GC finds it. */
-
- lua_pop(pi->L, 1);
- /* perms reftbl ... */
- LIF(A,pushobject)(pi->L, uv->v);
- /* perms reftbl ... obj */
- persist(pi);
- /* perms reftbl ... obj */
-}
-
-static void persistproto(PersistInfo *pi)
-{
- /* perms reftbl ... proto */
- Proto *p = toproto(pi->L, -1);
- lua_checkstack(pi->L, 2);
-
- /* Persist constant refs */
- {
- int i;
- pi_write(pi, &p->sizek, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_sizek %d\n", p->sizek);
- hrOut(pi);
- }
- #ifdef TOTEXT
- printf("persistproto_sizek %d\n", p->sizek);
- #endif
- for(i=0; i<p->sizek; i++) {
- LIF(A,pushobject)(pi->L, &p->k[i]);
- /* perms reftbl ... proto const */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... proto */
- }
- }
- /* perms reftbl ... proto */
-
- /* serialize inner Proto refs */
- {
- int i;
- pi_write(pi, &p->sizep, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_sizep %d\n", p->sizep);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_sizep %d\n", p->sizep);
-#endif
- for(i=0; i<p->sizep; i++)
- {
- pushproto(pi->L, p->p[i]);
- /* perms reftbl ... proto subproto */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... proto */
- }
- }
- /* perms reftbl ... proto */
-
- /* Serialize code */
- {
- int len;
- pi_write(pi, &p->sizecode, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_sizecode %d\n", p->sizecode);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_sizecode %d\n", p->sizecode);
-#endif
- len = sizeof(Instruction) * p->sizecode;
- pi_write(pi, p->code, len, pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_code %d\n", len);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_code %d\n", len);
-#endif
- }
-
- /* Serialize upvalue names */
- {
- int i;
- pi_write(pi, &p->sizeupvalues, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_upvalues %d\n", p->sizeupvalues);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_upvalues %d\n", p->sizeupvalues);
-#endif
- for(i=0; i<p->sizeupvalues; i++)
- {
- pushstring(pi->L, p->upvalues[i]);
- persist(pi);
- lua_pop(pi->L, 1);
- }
- }
- /* Serialize local variable infos */
- {
- int i;
- pi_write(pi, &p->sizelocvars, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_sizelocvars %d\n", p->sizelocvars);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_sizelocvars %d\n", p->sizelocvars);
-#endif
- for(i=0; i<p->sizelocvars; i++)
- {
- pushstring(pi->L, p->locvars[i].varname);
- persist(pi);
- lua_pop(pi->L, 1);
-
- pi_write(pi, &p->locvars[i].startpc, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_startpc %d\n", p->locvars[i].startpc);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_startpc %d\n", p->locvars[i].startpc);
-#endif
- pi_write(pi, &p->locvars[i].endpc, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_endpc %d\n", p->locvars[i].endpc);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_endpc %d\n", p->locvars[i].endpc);
-#endif
- }
- }
-
- /* Serialize source string */
- pushstring(pi->L, p->source);
- persist(pi);
- lua_pop(pi->L, 1);
-
- /* Serialize line numbers */
- {
- pi_write(pi, &p->sizelineinfo, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_sizelineinfo %d\n", p->sizelineinfo);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_sizelineinfo %d\n", p->sizelineinfo);
-#endif
- if (p->sizelineinfo)
- {
- int len;
- len = sizeof(int) * p->sizelineinfo;
- pi_write(pi, p->lineinfo, len, pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_lineinfo %d\n", len);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_lineinfo %d\n", len);
-#endif
- }
- }
-
- /* Serialize linedefined and lastlinedefined */
- pi_write(pi, &p->linedefined, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_linedefined %d\n", p->linedefined);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_linedefined %d\n", p->linedefined);
-#endif
- pi_write(pi, &p->lastlinedefined, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_lastlinedefined %d\n", p->lastlinedefined);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_lastlinedefined %d\n", p->lastlinedefined);
-#endif
-
- /* Serialize misc values */
- {
- pi_write(pi, &p->nups, sizeof(lu_byte), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_nups %d\n", (int) p->nups);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_nups %d\n", (int) p->nups);
-#endif
- pi_write(pi, &p->numparams, sizeof(lu_byte), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_numparams %d\n", (int) p->numparams);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_numparams %d\n", (int) p->numparams);
-#endif
- pi_write(pi, &p->is_vararg, sizeof(lu_byte), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_is_vararg %d\n", (int) p->is_vararg);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_is_vararg %d\n", (int) p->is_vararg);
-#endif
- pi_write(pi, &p->maxstacksize, sizeof(lu_byte), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_maxstacksize %d\n", (int) p->maxstacksize);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_maxstacksize %d\n", (int) p->maxstacksize);
-#endif
- }
- /* We do not currently persist upvalue names, local variable names,
- * variable lifetimes, line info, or source code. */
-}
-
-/* Copies a stack, but the stack is reversed in the process
- */
-static size_t revappendstack(lua_State *from, lua_State *to)
-{
- StkId o;
- for(o=from->top-1; o>=from->stack; o--) {
- setobj2s(to, to->top, o);
- to->top++;
- }
- return from->top - from->stack;
-}
-
-/* Persist all stack members
- */
-static void persistthread(PersistInfo *pi)
-{
- size_t posremaining;
- lua_State *L2;
- /* perms reftbl ... thr */
- L2 = lua_tothread(pi->L, -1);
- lua_checkstack(pi->L, L2->top - L2->stack + 1);
- if(pi->L == L2) {
- lua_pushstring(pi->L, "Can't persist currently running thread");
- lua_error(pi->L);
- return; /* not reached */
- }
-
- /* Persist the stack */
- posremaining = revappendstack(L2, pi->L);
- /* perms reftbl ... thr (rev'ed contents of L2) */
- write_size(pi, &posremaining);
- for(; posremaining > 0; posremaining--) {
- persist(pi);
- lua_pop(pi->L, 1);
- }
- /* perms reftbl ... thr */
- /* Now, persist the CallInfo stack. */
- {
- size_t i, numframes = (L2->ci - L2->base_ci) + 1;
- write_size(pi, &numframes);
- for(i=0; i<numframes; i++) {
- CallInfo *ci = L2->base_ci + i;
- size_t stackbase = ci->base - L2->stack;
- size_t stackfunc = ci->func - L2->stack;
- size_t stacktop = ci->top - L2->stack;
- size_t savedpc = (ci != L2->base_ci) ?
- ci->savedpc - ci_func(ci)->l.p->code :
- 0;
- write_size(pi, &stackbase);
- write_size(pi, &stackfunc);
- write_size(pi, &stacktop);
- pi_write(pi, &ci->nresults, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistthread %d\n", ci->nresults);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistthread %d\n", ci->nresults);
-#endif
- write_size(pi, &savedpc);
- }
- }
-
- /* Serialize the state's other parameters, with the exception of upval stuff */
- {
- size_t stackbase = L2->base - L2->stack;
- size_t stacktop = L2->top - L2->stack;
- lua_assert(L2->nCcalls <= 1);
- pi_write(pi, &L2->status, sizeof(lu_byte), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistthread_status %d\n", (int) L2->status);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistthread_status %d\n", (int) L2->status);
-#endif
- write_size(pi, &stackbase);
- write_size(pi, &stacktop);
-
- // ptrdiff_t changes sizes based on 32/64 bit
- // Hard cast to 64 bit size if SIZE64 is defined
-#ifdef SIZES64
- uint64 ptrIndex = static_cast<uint64>(L2->errfunc);
- pi_write(pi, &ptrIndex, sizeof(uint64), pi->ud);
-#else
- pi_write(pi, &L2->errfunc, sizeof(ptrdiff_t), pi->ud);
-#endif
- //write_size(pi, (size_t *)&L2->errfunc);
- }
-
- /* Finally, record upvalues which need to be reopened */
- /* See the comment above persistupval() for why we do this */
- {
- GCObject *gco;
- UpVal *uv;
- /* perms reftbl ... thr */
- for(gco = L2->openupval; gco != NULL; gco = uv->next) {
- size_t stackpos;
- uv = gco2uv(gco);
-
- /* Make sure upvalue is really open */
- lua_assert(uv->v != &uv->u.value);
- pushupval(pi->L, uv);
- /* perms reftbl ... thr uv */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... thr */
- stackpos = uv->v - L2->stack;
- write_size(pi, &stackpos);
- }
- /* perms reftbl ... thr */
- lua_pushnil(pi->L);
- /* perms reftbl ... thr nil */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... thr */
- }
- /* perms reftbl ... thr */
-}
-
-static void persistboolean(PersistInfo *pi)
-{
- int b = lua_toboolean(pi->L, -1);
- pi_write(pi, &b, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistboolean %d\n", b);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistboolean %d\n", b);
-#endif
-}
-
-static void persistlightuserdata(PersistInfo *pi)
-{
- void *p = lua_touserdata(pi->L, -1);
- pi_write(pi, &p, sizeof(void *), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistlightuserdata %p\n", p);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistlightuserdata %d\n", (int) p);
-#endif
-}
-
-static void persistnumber(PersistInfo *pi)
-{
- lua_Number n = lua_tonumber(pi->L, -1);
- pi_write(pi, &n, sizeof(lua_Number), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistnumber %d (%d)\n", (int) n, (int) sizeof(lua_Number));
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistnumber %d (%d)\n", (int) n, (int) sizeof(lua_Number));
-#endif
-}
-
-static void persiststring(PersistInfo *pi)
-{
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persiststring\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persiststring\n");
-#endif
- size_t length = lua_strlen(pi->L, -1);
- write_size(pi, &length);
- const char* s = lua_tostring(pi->L, -1);
- pi_write(pi, s, length, pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persiststring %d \"%s\"\n", (int)length, s);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persiststring %d \"%s\"\n", length, s);
-#endif
-}
-
-/* Top-level delegating persist function
- */
-static void persist(PersistInfo *pi)
-{
- /* perms reftbl ... obj */
- lua_checkstack(pi->L, 2);
- /* If the object has already been written, write a reference to it */
- lua_pushvalue(pi->L, -1);
- /* perms reftbl ... obj obj */
- lua_rawget(pi->L, 2);
- /* perms reftbl ... obj ref? */
- if(!lua_isnil(pi->L, -1)) {
- /* perms reftbl ... obj ref */
- int zero = 0;
- pi_write(pi, &zero, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist_seenobject\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist_seenobject\n");
-#endif
- int *ref = (int *)lua_touserdata(pi->L, -1);
- pi_write(pi, ref, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist_touserdata_ref %d\n", ref);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist_touserdata_ref %d\n", ref);
-#endif
- lua_pop(pi->L, 1);
- /* perms reftbl ... obj ref */
-#ifdef PLUTO_DEBUG
- printindent(pi->level);
- printf("0 %d\n", ref);
-#endif
- return;
- }
- /* perms reftbl ... obj nil */
- lua_pop(pi->L, 1);
- /* perms reftbl ... obj */
- /* If the object is nil, write the pseudoreference 0 */
- if(lua_isnil(pi->L, -1)) {
- int zero = 0;
- /* firsttime */
- pi_write(pi, &zero, sizeof(int), pi->ud);
- /* ref */
- pi_write(pi, &zero, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist_nil (last 2 lines)\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist_nil (last 2 lines)\n");
-#endif
-#ifdef PLUTO_DEBUG
- printindent(pi->level);
- printf("0 0\n");
-#endif
- return;
- }
- {
- /* indicate that it's the first time */
- int one = 1;
- pi_write(pi, &one, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist_newobject\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist_newobject\n");
-#endif
- }
- lua_pushvalue(pi->L, -1);
- /* perms reftbl ... obj obj */
- int *ref = (int *)lua_newuserdata(pi->L, sizeof(int));
- *ref = ++(pi->counter);
- /* perms reftbl ... obj obj ref */
- lua_rawset(pi->L, 2);
- /* perms reftbl ... obj */
-
- pi_write(pi, &pi->counter, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist_counter %d\n", pi->counter);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist_counter %d\n", pi->counter);
-#endif
-
-
- /* At this point, we'll give the permanents table a chance to play. */
- {
- lua_pushvalue(pi->L, -1);
- /* perms reftbl ... obj obj */
- lua_gettable(pi->L, 1);
- /* perms reftbl ... obj permkey? */
- if(!lua_isnil(pi->L, -1)) {
- /* perms reftbl ... obj permkey */
- int type = PLUTO_TPERMANENT;
-#ifdef PLUTO_DEBUG
- printindent(pi->level);
- printf("1 %d PERM\n", pi->counter);
- pi->level++;
-#endif
- pi_write(pi, &type, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist_permtype %d\n", type);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist_permtype %d\n", type);
-#endif
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... obj */
-#ifdef PLUTO_DEBUG
- pi->level--;
-#endif
- return;
- } else {
- /* perms reftbl ... obj nil */
- lua_pop(pi->L, 1);
- /* perms reftbl ... obj */
- }
- /* perms reftbl ... obj */
- }
- {
- int type = lua_type(pi->L, -1);
- pi_write(pi, &type, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist %s\n", type >= 0 && type < NUMTYPES ? typenames[type] : "?");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist %s\n", type >= 0 && type < NUMTYPES ? typenames[type] : "?");
-#endif
-
-#ifdef PLUTO_DEBUG
- printindent(pi->level);
- printf("1 %d %d\n", pi->counter, type);
- pi->level++;
-#endif
- }
-
- switch(lua_type(pi->L, -1)) {
- case LUA_TBOOLEAN:
- persistboolean(pi);
- break;
- case LUA_TLIGHTUSERDATA:
- persistlightuserdata(pi);
- break;
- case LUA_TNUMBER:
- persistnumber(pi);
- break;
- case LUA_TSTRING:
- persiststring(pi);
- break;
- case LUA_TTABLE:
- persisttable(pi);
- break;
- case LUA_TFUNCTION:
- persistfunction(pi);
- break;
- case LUA_TTHREAD:
- persistthread(pi);
- break;
- case LUA_TPROTO:
- persistproto(pi);
- break;
- case LUA_TUPVAL:
- persistupval(pi);
- break;
- case LUA_TUSERDATA:
- persistuserdata(pi);
- break;
- default:
- lua_assert(0);
- }
-#ifdef PLUTO_DEBUG
- pi->level--;
-#endif
-}
-
-void pluto_persist(lua_State *L, lua_Chunkwriter writer, void *ud)
-{
- PersistInfo pi;
-
- pi.counter = 0;
- pi.L = L;
- pi.writer = writer;
- pi.ud = ud;
-#ifdef PLUTO_DEBUG
- pi.level = 0;
-#endif
-
- lua_checkstack(L, 4);
- /* perms? rootobj? ...? */
- lua_assert(lua_gettop(L) == 2);
- /* perms rootobj */
- lua_assert(!lua_isnil(L, 2));
- /* perms rootobj */
- lua_newtable(L);
- /* perms rootobj reftbl */
-
- /* Now we're going to make the table weakly keyed. This prevents the
- * GC from visiting it and trying to mark things it doesn't want to
- * mark in tables, e.g. upvalues. All objects in the table are
- * a priori reachable, so it doesn't matter that we do this. */
- lua_newtable(L);
- /* perms rootobj reftbl mt */
- lua_pushstring(L, "__mode");
- /* perms rootobj reftbl mt "__mode" */
- lua_pushstring(L, "k");
- /* perms rootobj reftbl mt "__mode" "k" */
- lua_settable(L, 4);
- /* perms rootobj reftbl mt */
- lua_setmetatable(L, 3);
- /* perms rootobj reftbl */
- lua_insert(L, 2);
- /* perms reftbl rootobj */
- persist(&pi);
- /* perms reftbl rootobj */
- lua_remove(L, 2);
- /* perms rootobj */
-}
-
-typedef struct WriterInfo_t {
- char* buf;
- size_t buflen;
-} WriterInfo;
-
-static int bufwriter (lua_State *L, const void *p, size_t sz, void *ud) {
- const char *cp = (const char *)p;
- WriterInfo *wi = (WriterInfo *)ud;
-
- LIF(M,reallocvector)(L, wi->buf, wi->buflen, wi->buflen+sz, char);
- while(sz)
- {
- /* how dearly I love ugly C pointer twiddling */
- wi->buf[wi->buflen++] = *cp++;
- sz--;
- }
- return 0;
-}
-
-int persist_l(lua_State *L)
-{
- /* perms? rootobj? ...? */
- WriterInfo wi;
-
- wi.buf = NULL;
- wi.buflen = 0;
-
- lua_settop(L, 2);
- /* perms? rootobj? */
- luaL_checktype(L, 1, LUA_TTABLE);
- /* perms rootobj? */
- luaL_checktype(L, 1, LUA_TTABLE);
- /* perms rootobj */
-
- pluto_persist(L, bufwriter, &wi);
-
- lua_settop(L, 0);
- /* (empty) */
- lua_pushlstring(L, wi.buf, wi.buflen);
- /* str */
- pdep_freearray(L, wi.buf, wi.buflen, char);
- return 1;
-}
-
-typedef struct UnpersistInfo_t {
- lua_State *L;
- ZIO zio;
-#ifdef PLUTO_DEBUG
- int level;
-#endif
-} UnpersistInfo;
-
-static void unpersist(UnpersistInfo *upi);
-
-/* The object is left on the stack. This is primarily used by unpersist, but
- * may be used by GCed objects that may incur cycles in order to preregister
- * the object. */
-static void registerobject(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... obj */
- lua_checkstack(upi->L, 2);
- lua_pushlightuserdata(upi->L, (void *)ref);
- /* perms reftbl ... obj ref */
- lua_pushvalue(upi->L, -2);
- /* perms reftbl ... obj ref obj */
- lua_settable(upi->L, 2);
- /* perms reftbl ... obj */
-}
-
-static void unpersistboolean(UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- int b;
- lua_checkstack(upi->L, 1);
- verify(LIF(Z,read)(&upi->zio, &b, sizeof(int)) == 0);
- lua_pushboolean(upi->L, b);
- /* perms reftbl ... bool */
-}
-
-static void unpersistlightuserdata(UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- void *p;
- lua_checkstack(upi->L, 1);
- verify(LIF(Z,read)(&upi->zio, &p, sizeof(void *)) == 0);
- lua_pushlightuserdata(upi->L, p);
- /* perms reftbl ... ludata */
-}
-
-static void unpersistnumber(UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_Number n;
- lua_checkstack(upi->L, 1);
- verify(LIF(Z,read)(&upi->zio, &n, sizeof(lua_Number)) == 0);
- lua_pushnumber(upi->L, n);
- /* perms reftbl ... num */
-}
-
-static void unpersiststring(UnpersistInfo *upi)
-{
- /* perms reftbl sptbl ref */
- /*int length;*/
- size_t length;
- char* string;
- lua_checkstack(upi->L, 1);
- /*verify(LIF(Z,read)(&upi->zio, &length, sizeof(int)) == 0);*/
- /*verify(LIF(Z,read)(&upi->zio, &length, sizeof(size_t)) == 0);*/
- read_size(&upi->zio, &length);
- string = pdep_newvector(upi->L, length, char);
- verify(LIF(Z,read)(&upi->zio, string, length) == 0);
- lua_pushlstring(upi->L, string, length);
- /* perms reftbl sptbl ref str */
- pdep_freearray(upi->L, string, length, char);
-}
-
-static void unpersistspecialtable(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_checkstack(upi->L, 1);
- unpersist(upi);
- /* perms reftbl ... spfunc? */
- lua_assert(lua_isfunction(upi->L, -1));
- /* perms reftbl ... spfunc */
- lua_call(upi->L, 0, 1);
- /* perms reftbl ... tbl? */
- lua_assert(lua_istable(upi->L, -1));
- /* perms reftbl ... tbl */
-}
-
-static void unpersistliteraltable(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_checkstack(upi->L, 3);
- /* Preregister table for handling of cycles */
- lua_newtable(upi->L);
- /* perms reftbl ... tbl */
- registerobject(ref, upi);
- /* perms reftbl ... tbl */
- /* Unpersist metatable */
- {
- unpersist(upi);
- /* perms reftbl ... tbl mt/nil? */
- if(lua_istable(upi->L, -1)) {
- /* perms reftbl ... tbl mt */
- lua_setmetatable(upi->L, -2);
- /* perms reftbl ... tbl */
- } else {
- /* perms reftbl ... tbl nil? */
- lua_assert(lua_isnil(upi->L, -1));
- /* perms reftbl ... tbl nil */
- lua_pop(upi->L, 1);
- /* perms reftbl ... tbl */
- }
- /* perms reftbl ... tbl */
- }
-
- while(1)
- {
- /* perms reftbl ... tbl */
- unpersist(upi);
- /* perms reftbl ... tbl key/nil */
- if(lua_isnil(upi->L, -1)) {
- /* perms reftbl ... tbl nil */
- lua_pop(upi->L, 1);
- /* perms reftbl ... tbl */
- break;
- }
- /* perms reftbl ... tbl key */
- unpersist(upi);
- /* perms reftbl ... tbl key value? */
- lua_assert(!lua_isnil(upi->L, -1));
- /* perms reftbl ... tbl key value */
- lua_rawset(upi->L, -3);
- /* perms reftbl ... tbl */
- }
-}
-
-static void unpersisttable(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_checkstack(upi->L, 1);
- {
- int isspecial;
- verify(LIF(Z,read)(&upi->zio, &isspecial, sizeof(int)) == 0);
- if(isspecial) {
- unpersistspecialtable(ref, upi);
- /* perms reftbl ... tbl */
- } else {
- unpersistliteraltable(ref, upi);
- /* perms reftbl ... tbl */
- }
- /* perms reftbl ... tbl */
- }
-}
-
-static UpVal *makeupval(lua_State *L, int stackpos)
-{
- UpVal *uv = pdep_new(L, UpVal);
- pdep_link(L, (GCObject *)uv, LUA_TUPVAL);
- uv->tt = LUA_TUPVAL;
- uv->v = &uv->u.value;
- uv->u.l.prev = NULL;
- uv->u.l.next = NULL;
- setobj(L, uv->v, getobject(L, stackpos));
- return uv;
-}
-
-static Proto *makefakeproto(lua_State *L, lu_byte nups)
-{
- Proto *p = pdep_newproto(L);
- p->sizelineinfo = 1;
- p->lineinfo = pdep_newvector(L, 1, int);
- p->lineinfo[0] = 1;
- p->sizecode = 1;
- p->code = pdep_newvector(L, 1, Instruction);
- p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
- p->source = pdep_newlstr(L, "", 0);
- p->maxstacksize = 2;
- p->nups = nups;
- p->sizek = 0;
- p->sizep = 0;
-
- return p;
-}
-
-/* The GC is not fond of finding upvalues in tables. We get around this
- * during persistence using a weakly keyed table, so that the GC doesn't
- * bother to mark them. This won't work in unpersisting, however, since
- * if we make the values weak they'll be collected (since nothing else
- * references them). Our solution, during unpersisting, is to represent
- * upvalues as dummy functions, each with one upvalue. */
-static void boxupval_start(lua_State *L)
-{
- LClosure *lcl;
- lcl = (LClosure *)pdep_newLclosure(L, 1, hvalue(&L->l_gt));
- pushclosure(L, (Closure *)lcl);
- /* ... func */
- lcl->p = makefakeproto(L, 1);
-
- /* Temporarily initialize the upvalue to nil */
-
- lua_pushnil(L);
- lcl->upvals[0] = makeupval(L, -1);
- lua_pop(L, 1);
-}
-
-static void boxupval_finish(lua_State *L)
-{
- /* ... func obj */
- LClosure *lcl = (LClosure *) clvalue(getobject(L, -2));
-
- lcl->upvals[0]->u.value = *getobject(L, -1);
- lua_pop(L, 1);
-}
-
-
-static void unboxupval(lua_State *L)
-{
- /* ... func */
- LClosure *lcl;
- UpVal *uv;
-
- lcl = (LClosure *)clvalue(getobject(L, -1));
- uv = lcl->upvals[0];
- lua_pop(L, 1);
- /* ... */
- pushupval(L, uv);
- /* ... upval */
-}
-
-static void unpersistfunction(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- LClosure *lcl;
- int i;
- lu_byte nupvalues;
- lua_checkstack(upi->L, 2);
-
- verify(LIF(Z,read)(&upi->zio, &nupvalues, sizeof(lu_byte)) == 0);
-
- lcl = (LClosure *)pdep_newLclosure(upi->L, nupvalues, hvalue(&upi->L->l_gt));
- pushclosure(upi->L, (Closure *)lcl);
-
- /* perms reftbl ... func */
- /* Put *some* proto in the closure, before the GC can find it */
- lcl->p = makefakeproto(upi->L, nupvalues);
-
- /* Also, we need to temporarily fill the upvalues */
- lua_pushnil(upi->L);
- /* perms reftbl ... func nil */
- for(i=0; i<nupvalues; i++) {
- lcl->upvals[i] = makeupval(upi->L, -1);
- }
- lua_pop(upi->L, 1);
- /* perms reftbl ... func */
-
- /* I can't see offhand how a function would ever get to be self-
- * referential, but just in case let's register it early */
- registerobject(ref, upi);
-
- /* Now that it's safe, we can get the real proto */
- unpersist(upi);
- /* perms reftbl ... func proto? */
- lua_assert(lua_type(upi->L, -1) == LUA_TPROTO);
- /* perms reftbl ... func proto */
- lcl->p = toproto(upi->L, -1);
- lua_pop(upi->L, 1);
- /* perms reftbl ... func */
-
- for(i=0; i<nupvalues; i++) {
- /* perms reftbl ... func */
- unpersist(upi);
- /* perms reftbl ... func func2 */
- unboxupval(upi->L);
- /* perms reftbl ... func upval */
- lcl->upvals[i] = toupval(upi->L, -1);
- lua_pop(upi->L, 1);
- /* perms reftbl ... func */
- }
- /* perms reftbl ... func */
-
- /* Finally, the fenv */
- unpersist(upi);
- /* perms reftbl ... func fenv/nil? */
- lua_assert(lua_type(upi->L, -1) == LUA_TNIL ||
- lua_type(upi->L, -1) == LUA_TTABLE);
- /* perms reftbl ... func fenv/nil */
- if(!lua_isnil(upi->L, -1)) {
- /* perms reftbl ... func fenv */
- lua_setfenv(upi->L, -2);
- /* perms reftbl ... func */
- } else {
- /* perms reftbl ... func nil */
- lua_pop(upi->L, 1);
- /* perms reftbl ... func */
- }
- /* perms reftbl ... func */
-}
-
-static void unpersistupval(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_checkstack(upi->L, 2);
-
- boxupval_start(upi->L);
- /* perms reftbl ... func */
- registerobject(ref, upi);
-
- unpersist(upi);
- /* perms reftbl ... func obj */
- boxupval_finish(upi->L);
- /* perms reftbl ... func */
-}
-
-static void unpersistproto(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- Proto *p;
- int i;
- int sizep, sizek;
-
- /* We have to be careful. The GC expects a lot out of protos. In
- * particular, we need to give the function a valid string for its
- * source, and valid code, even before we actually read in the real
- * code. */
- TString *source = pdep_newlstr(upi->L, "", 0);
- p = pdep_newproto(upi->L);
- p->source = source;
- p->sizecode=1;
- p->code = pdep_newvector(upi->L, 1, Instruction);
- p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
- p->maxstacksize = 2;
- p->sizek = 0;
- p->sizep = 0;
-
- lua_checkstack(upi->L, 2);
-
- pushproto(upi->L, p);
- /* perms reftbl ... proto */
- /* We don't need to register early, since protos can never ever be
- * involved in cyclic references */
-
- /* Read in constant references */
- {
- verify(LIF(Z,read)(&upi->zio, &sizek, sizeof(int)) == 0);
- LIF(M,reallocvector)(upi->L, p->k, 0, sizek, TValue);
- for(i=0; i<sizek; i++) {
- /* perms reftbl ... proto */
- unpersist(upi);
- /* perms reftbl ... proto k */
- setobj2s(upi->L, &p->k[i], getobject(upi->L, -1));
- p->sizek++;
- lua_pop(upi->L, 1);
- /* perms reftbl ... proto */
- }
- /* perms reftbl ... proto */
- }
- /* Read in sub-proto references */
- {
- verify(LIF(Z,read)(&upi->zio, &sizep, sizeof(int)) == 0);
- LIF(M,reallocvector)(upi->L, p->p, 0, sizep, Proto*);
- for(i=0; i<sizep; i++) {
- /* perms reftbl ... proto */
- unpersist(upi);
- /* perms reftbl ... proto subproto */
- p->p[i] = toproto(upi->L, -1);
- p->sizep++;
- lua_pop(upi->L, 1);
- /* perms reftbl ... proto */
- }
- /* perms reftbl ... proto */
- }
-
- /* Read in code */
- {
- verify(LIF(Z,read)(&upi->zio, &p->sizecode, sizeof(int)) == 0);
- LIF(M,reallocvector)(upi->L, p->code, 1, p->sizecode, Instruction);
- verify(LIF(Z,read)(&upi->zio, p->code,
- sizeof(Instruction) * p->sizecode) == 0);
- }
-
- /* Read in upvalue names */
- {
- verify(LIF(Z,read)(&upi->zio, &p->sizeupvalues, sizeof(int)) == 0);
- if (p->sizeupvalues)
- {
- LIF(M,reallocvector)(upi->L, p->upvalues, 0, p->sizeupvalues, TString *);
- for(i=0; i<p->sizeupvalues; i++)
- {
- unpersist(upi);
- p->upvalues[i] = pdep_newlstr(upi->L, lua_tostring(upi->L, -1), strlen(lua_tostring(upi->L, -1)));
- lua_pop(upi->L, 1);
- }
- }
- }
-
- /* Read in local variable infos */
- {
- verify(LIF(Z,read)(&upi->zio, &p->sizelocvars, sizeof(int)) == 0);
- if (p->sizelocvars)
- {
- LIF(M,reallocvector)(upi->L, p->locvars, 0, p->sizelocvars, LocVar);
- for(i=0; i<p->sizelocvars; i++)
- {
- unpersist(upi);
- p->locvars[i].varname = pdep_newlstr(upi->L, lua_tostring(upi->L, -1), strlen(lua_tostring(upi->L, -1)));
- lua_pop(upi->L, 1);
-
- verify(LIF(Z,read)(&upi->zio, &p->locvars[i].startpc, sizeof(int)) == 0);
- verify(LIF(Z,read)(&upi->zio, &p->locvars[i].endpc, sizeof(int)) == 0);
- }
- }
- }
-
- /* Read in source string*/
- unpersist(upi);
- p->source = pdep_newlstr(upi->L, lua_tostring(upi->L, -1), strlen(lua_tostring(upi->L, -1)));
- lua_pop(upi->L, 1);
-
- /* Read in line numbers */
- {
- verify(LIF(Z,read)(&upi->zio, &p->sizelineinfo, sizeof(int)) == 0);
- if (p->sizelineinfo)
- {
- LIF(M,reallocvector)(upi->L, p->lineinfo, 0, p->sizelineinfo, int);
- verify(LIF(Z,read)(&upi->zio, p->lineinfo,
- sizeof(int) * p->sizelineinfo) == 0);
- }
- }
-
- /* Read in linedefined and lastlinedefined */
- verify(LIF(Z,read)(&upi->zio, &p->linedefined, sizeof(int)) == 0);
- verify(LIF(Z,read)(&upi->zio, &p->lastlinedefined, sizeof(int)) == 0);
-
- /* Read in misc values */
- {
- verify(LIF(Z,read)(&upi->zio, &p->nups, sizeof(lu_byte)) == 0);
- verify(LIF(Z,read)(&upi->zio, &p->numparams, sizeof(lu_byte)) == 0);
- verify(LIF(Z,read)(&upi->zio, &p->is_vararg, sizeof(lu_byte)) == 0);
- verify(LIF(Z,read)(&upi->zio, &p->maxstacksize, sizeof(lu_byte)) == 0);
- }
-}
-
-
-/* Does basically the opposite of luaC_link().
- * Right now this function is rather inefficient; it requires traversing the
- * entire root GC set in order to find one object. If the GC list were doubly
- * linked this would be much easier, but there's no reason for Lua to have
- * that. */
-static void gcunlink(lua_State *L, GCObject *gco)
-{
- GCObject *prevslot;
- if(G(L)->rootgc == gco) {
- G(L)->rootgc = G(L)->rootgc->gch.next;
- return;
- }
-
- prevslot = G(L)->rootgc;
- while(prevslot->gch.next != gco) {
- lua_assert(prevslot->gch.next != NULL);
- prevslot = prevslot->gch.next;
- }
-
- prevslot->gch.next = prevslot->gch.next->gch.next;
-}
-
-/* FIXME __ALL__ field ordering */
-static void unpersistthread(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_State *L2;
- size_t stacklimit = 0;
- L2 = lua_newthread(upi->L);
- lua_checkstack(upi->L, 3);
- /* L1: perms reftbl ... thr */
- /* L2: (empty) */
- registerobject(ref, upi);
-
- /* First, deserialize the object stack. */
- {
- size_t i, stacksize;
- read_size(&upi->zio, &stacksize);
- LIF(D,growstack)(L2, (int)stacksize);
- /* Make sure that the first stack element (a nil, representing
- * the imaginary top-level C function) is written to the very,
- * very bottom of the stack */
- L2->top--;
- for(i=0; i<stacksize; i++) {
- unpersist(upi);
- /* L1: perms reftbl ... thr obj* */
- }
- lua_xmove(upi->L, L2, stacksize);
- /* L1: perms reftbl ... thr */
- /* L2: obj* */
- }
- /* (hereafter, stacks refer to L1) */
-
- /* Now, deserialize the CallInfo stack. */
- {
- size_t i, numframes;
- read_size(&upi->zio, &numframes);
- LIF(D,reallocCI)(L2,numframes*2);
- for(i=0; i<numframes; i++) {
- CallInfo *ci = L2->base_ci + i;
- size_t stackbase, stackfunc, stacktop, savedpc;
- read_size(&upi->zio, &stackbase);
- read_size(&upi->zio, &stackfunc);
- read_size(&upi->zio, &stacktop);
- verify(LIF(Z,read)(&upi->zio, &ci->nresults, sizeof(int)) == 0);
- read_size(&upi->zio, &savedpc);
-
- if(stacklimit < stacktop)
- stacklimit = stacktop;
-
- ci->base = L2->stack+stackbase;
- ci->func = L2->stack+stackfunc;
- ci->top = L2->stack+stacktop;
- ci->savedpc = (ci != L2->base_ci) ?
- ci_func(ci)->l.p->code+savedpc :
- 0;
- ci->tailcalls = 0;
- /* Update the pointer each time, to keep the GC
- * happy*/
- L2->ci = ci;
- }
- }
- /* perms reftbl ... thr */
- /* Deserialize the state's other parameters, with the exception of upval stuff */
- {
- size_t stackbase, stacktop;
- L2->savedpc = L2->ci->savedpc;
- verify(LIF(Z,read)(&upi->zio, &L2->status, sizeof(lu_byte)) == 0);
- read_size(&upi->zio, &stackbase);
- read_size(&upi->zio, &stacktop);
-
-#ifdef SIZES64
- uint64 value;
- verify(LIF(Z,read)(&upi->zio, &value, sizeof(uint64)) == 0);
-
- L2->errfunc = static_cast<ptrdiff_t>(value);
-#else
- verify(LIF(Z,read)(&upi->zio, &L2->errfunc, sizeof(ptrdiff_t)) == 0);
-#endif
-
- //read_size(&upi->zio, (size_t *)&L2->errfunc);
- L2->base = L2->stack + stackbase;
- L2->top = L2->stack + stacktop;
- }
- /* Finally, "reopen" upvalues (see persistupval() for why) */
- {
- UpVal* uv;
- GCObject **nextslot = &L2->openupval;
- global_State *g = G(L2);
- while(1) {
- size_t stackpos;
- unpersist(upi);
- /* perms reftbl ... thr uv/nil */
- if(lua_isnil(upi->L, -1)) {
- /* perms reftbl ... thr nil */
- lua_pop(upi->L, 1);
- /* perms reftbl ... thr */
- break;
- }
- /* perms reftbl ... thr boxeduv */
- unboxupval(upi->L);
- /* perms reftbl ... thr uv */
- uv = toupval(upi->L, -1);
- lua_pop(upi->L, 1);
- /* perms reftbl ... thr */
-
- read_size(&upi->zio, &stackpos);
- uv->v = L2->stack + stackpos;
- gcunlink(upi->L, (GCObject *)uv);
- uv->marked = luaC_white(g);
- *nextslot = (GCObject *)uv;
- nextslot = &uv->next;
- uv->u.l.prev = &G(L2)->uvhead;
- uv->u.l.next = G(L2)->uvhead.u.l.next;
- uv->u.l.next->u.l.prev = uv;
- G(L2)->uvhead.u.l.next = uv;
- lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
- }
- *nextslot = NULL;
- }
-
- /* The stack must be valid at least to the highest value among the CallInfos */
- /* 'top' and the values up to there must be filled with 'nil' */
- {
- StkId o;
- LIF(D,checkstack)(L2, (int)stacklimit);
- for (o = L2->top; o <= L2->top + stacklimit; o++)
- setnilvalue(o);
- }
-}
-
-static void unpersistuserdata(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- int isspecial;
- lua_checkstack(upi->L, 2);
- verify(LIF(Z,read)(&upi->zio, &isspecial, sizeof(int)) == 0);
- if(isspecial) {
- unpersist(upi);
- /* perms reftbl ... spfunc? */
- lua_assert(lua_isfunction(upi->L, -1));
- /* perms reftbl ... spfunc */
-#ifdef PLUTO_PASS_USERDATA_TO_PERSIST
- lua_pushlightuserdata(upi->L, &upi->zio);
- lua_call(upi->L, 1, 1);
-#else
- lua_call(upi->L, 0, 1);
-#endif
- /* perms reftbl ... udata? */
-/* This assertion might not be necessary; it's conceivable, for
- * example, that the SP function might decide to return a table
- * with equivalent functionality. For the time being, we'll
- * ignore this possibility in favor of stricter and more testable
- * requirements. */
- lua_assert(lua_isuserdata(upi->L, -1));
- /* perms reftbl ... udata */
- } else {
- size_t length;
- read_size(&upi->zio, &length);
-
- lua_newuserdata(upi->L, length);
- /* perms reftbl ... udata */
- registerobject(ref, upi);
- verify(LIF(Z,read)(&upi->zio, lua_touserdata(upi->L, -1), length) == 0);
-
- unpersist(upi);
- /* perms reftbl ... udata mt/nil? */
- lua_assert(lua_istable(upi->L, -1) || lua_isnil(upi->L, -1));
- /* perms reftbl ... udata mt/nil */
- lua_setmetatable(upi->L, -2);
- /* perms reftbl ... udata */
- }
- /* perms reftbl ... udata */
-}
-
-static void unpersistpermanent(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_checkstack(upi->L, 2);
- unpersist(upi);
- /* perms reftbl permkey */
- lua_gettable(upi->L, 1);
- /* perms reftbl perm? */
- /* We assume currently that the substituted permanent value
- * shouldn't be nil. This may be a bad assumption. Real-life
- * experience is needed to evaluate this. */
- lua_assert(!lua_isnil(upi->L, -1));
- /* perms reftbl perm */
-}
-
-#if 0
-/* For debugging only; not called when lua_assert is empty */
-static int inreftable(lua_State *L, int ref)
-{
- int res;
- lua_checkstack(L, 1);
- /* perms reftbl ... */
- lua_pushlightuserdata(L, (void *)ref);
- /* perms reftbl ... ref */
- lua_gettable(L, 2);
- /* perms reftbl ... obj? */
- res = !lua_isnil(L, -1);
- lua_pop(L, 1);
- /* perms reftbl ... */
- return res;
-}
-#endif
-
-static void unpersist(UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- int firstTime;
- int stacksize = lua_gettop(upi->L); stacksize = stacksize; /* DEBUG */
- lua_checkstack(upi->L, 2);
- LIF(Z,read)(&upi->zio, &firstTime, sizeof(int));
- if(firstTime) {
- int ref;
- int type;
- LIF(Z,read)(&upi->zio, &ref, sizeof(int));
- lua_assert(!inreftable(upi->L, ref));
- LIF(Z,read)(&upi->zio, &type, sizeof(int));
-#ifdef PLUTO_DEBUG
- printindent(upi->level);
- printf("1 %d %d\n", ref, type);
- upi->level++;
-#endif
- switch(type) {
- case LUA_TBOOLEAN:
- unpersistboolean(upi);
- break;
- case LUA_TLIGHTUSERDATA:
- unpersistlightuserdata(upi);
- break;
- case LUA_TNUMBER:
- unpersistnumber(upi);
- break;
- case LUA_TSTRING:
- unpersiststring(upi);
- break;
- case LUA_TTABLE:
- unpersisttable(ref, upi);
- break;
- case LUA_TFUNCTION:
- unpersistfunction(ref, upi);
- break;
- case LUA_TTHREAD:
- unpersistthread(ref, upi);
- break;
- case LUA_TPROTO:
- unpersistproto(ref, upi);
- break;
- case LUA_TUPVAL:
- unpersistupval(ref, upi);
- break;
- case LUA_TUSERDATA:
- unpersistuserdata(ref, upi);
- break;
- case PLUTO_TPERMANENT:
- unpersistpermanent(ref, upi);
- break;
- default:
- lua_assert(0);
- }
- /* perms reftbl ... obj */
- lua_assert(lua_type(upi->L, -1) == type ||
- type == PLUTO_TPERMANENT ||
- /* Remember, upvalues get a special dispensation, as
- * described in boxupval */
- (lua_type(upi->L, -1) == LUA_TFUNCTION &&
- type == LUA_TUPVAL));
- registerobject(ref, upi);
- /* perms reftbl ... obj */
-#ifdef PLUTO_DEBUG
- upi->level--;
-#endif
- } else {
- int ref;
- LIF(Z,read)(&upi->zio, &ref, sizeof(int));
-#ifdef PLUTO_DEBUG
- printindent(upi->level);
- printf("0 %d\n", ref);
-#endif
- if(ref == 0) {
- lua_pushnil(upi->L);
- /* perms reftbl ... nil */
- } else {
- lua_pushlightuserdata(upi->L, (void *)ref);
- /* perms reftbl ... ref */
- lua_gettable(upi->L, 2);
- /* perms reftbl ... obj? */
- lua_assert(!lua_isnil(upi->L, -1));
- }
- /* perms reftbl ... obj/nil */
- }
- /* perms reftbl ... obj/nil */
- lua_assert(lua_gettop(upi->L) == stacksize + 1);
-}
-
-void pluto_unpersist(lua_State *L, lua_Chunkreader reader, void *ud)
-{
- /* We use the graciously provided ZIO (what the heck does the Z stand
- * for?) library so that we don't have to deal with the reader directly.
- * Letting the reader function decide how much data to return can be
- * very unpleasant.
- */
- UnpersistInfo upi;
- upi.L = L;
-#ifdef PLUTO_DEBUG
- upi.level = 0;
-#endif
-
- lua_checkstack(L, 3);
- LIF(Z,init)(L, &upi.zio, reader, ud);
-
- /* perms */
- lua_newtable(L);
- /* perms reftbl */
- lua_gc(L, LUA_GCSTOP, 0);
- unpersist(&upi);
- lua_gc(L, LUA_GCRESTART, 0);
- /* perms reftbl rootobj */
- lua_replace(L, 2);
- /* perms rootobj */
-}
-
-typedef struct LoadInfo_t {
- char *buf;
- size_t size;
-} LoadInfo;
-
-
-static const char *bufreader(lua_State *L, void *ud, size_t *sz) {
- LoadInfo *li = (LoadInfo *)ud;
- if(li->size == 0) {
- return NULL;
- }
- *sz = li->size;
- li->size = 0;
- return li->buf;
-}
-
-int unpersist_l(lua_State *L)
-{
- LoadInfo li;
- char const *origbuf;
- char *tempbuf;
- size_t bufsize;
- /* perms? str? ...? */
- lua_settop(L, 2);
- /* perms? str? */
- origbuf = luaL_checklstring(L, 2, &bufsize);
- tempbuf = LIF(M,newvector)(L, bufsize, char);
- memcpy(tempbuf, origbuf, bufsize);
-
- li.buf = tempbuf;
- li.size = bufsize;
-
- /* perms? str */
- lua_pop(L, 1);
- /* perms? */
- luaL_checktype(L, 1, LUA_TTABLE);
- /* perms */
- pluto_unpersist(L, bufreader, &li);
- /* perms rootobj */
- LIF(M,freearray)(L, tempbuf, bufsize, char);
- return 1;
-}
-
-/* Stefan's first C function for Lua! :)
- Returns a string describing the Pluto version you're using. */
-
-int version_l(lua_State *L)
-{
- const char *version = VERSION;
-
- lua_settop(L, 0);
- /* (empty) */
- lua_pushlstring(L, version, strlen(version));
- /* str */
- return 1;
-}
-
-/* Set human-readable output on or off. */
-int human_l(lua_State *L)
-{
- /* flag? ...? */
- lua_settop(L, 1);
- /* flag? */
- /*luaL_checktype(L, 1, LUA_TBOOLEAN);*/
- /* flag */
-
- humanReadable = lua_toboolean(L, 1);
-
- lua_settop(L, 0);
- /* (empty) */
- return 0;
-}
-
-static luaL_reg pluto_reg[] = {
- { "persist", persist_l },
- { "unpersist", unpersist_l },
- { "version", version_l },
- { "human", human_l },
- { NULL, NULL }
-};
-
-LUALIB_API int luaopen_pluto(lua_State *L) {
- luaL_openlib(L, "pluto", pluto_reg, 0);
- return 1;
-}
diff --git a/engines/sword25/util/pluto/pluto.h b/engines/sword25/util/pluto/pluto.h
deleted file mode 100644
index 3674842d44..0000000000
--- a/engines/sword25/util/pluto/pluto.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* $Id$ */
-
-/* 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.
- */
-
-/* lua.h must be included before this file */
-
-void pluto_persist(lua_State *L, lua_Chunkwriter writer, void *ud);
-
-void pluto_unpersist(lua_State *L, lua_Chunkreader reader, void *ud);
-
-LUALIB_API int luaopen_pluto(lua_State *L);
diff --git a/engines/sword25/util/pluto/plzio.cpp b/engines/sword25/util/pluto/plzio.cpp
deleted file mode 100644
index 21f69a9e8d..0000000000
--- a/engines/sword25/util/pluto/plzio.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-** $Id$
-** a generic input stream interface
-** See Copyright Notice in lua.h
-*/
-
-
-#include <string.h>
-
-#define lzio_c
-#define LUA_CORE
-
-#include "pdep/pdep.h"
-
-int pdep_fill (ZIO *z) {
- size_t size;
- lua_State *L = z->L;
- const char *buff;
- lua_unlock(L);
- buff = z->reader(L, z->data, &size);
- lua_lock(L);
- if (buff == NULL || size == 0) return EOZ;
- z->n = size - 1;
- z->p = buff;
- return char2int(*(z->p++));
-}
-
-
-int pdep_lookahead (ZIO *z) {
- if (z->n == 0) {
- if (pdep_fill(z) == EOZ)
- return EOZ;
- else {
- z->n++; /* pdep_fill removed first byte; put back it */
- z->p--;
- }
- }
- return char2int(*z->p);
-}
-
-
-void pdep_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
- z->L = L;
- z->reader = reader;
- z->data = data;
- z->n = 0;
- z->p = NULL;
-}
-
-
-/* --------------------------------------------------------------- read --- */
-size_t pdep_read (ZIO *z, void *b, size_t n) {
- while (n) {
- size_t m;
- if (pdep_lookahead(z) == EOZ)
- return n; /* return number of missing bytes */
- m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
- memcpy(b, z->p, m);
- z->n -= m;
- z->p += m;
- b = (char *)b + m;
- n -= m;
- }
- return 0;
-}
-
-/* ------------------------------------------------------------------------ */
-char *pdep_openspace (lua_State *L, Mbuffer *buff, size_t n) {
- if (n > buff->buffsize) {
- if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
- pdep_resizebuffer(L, buff, n);
- }
- return buff->buffer;
-}