Cleaner protocol between 'lua_dump' and writer function
'lua_dump' signals to the writer function the end of a dump, so that is has more freedom when using the stack.
This commit is contained in:
30
ldump.c
30
ldump.c
@@ -43,8 +43,13 @@ typedef struct {
|
||||
#define dumpLiteral(D, s) dumpBlock(D,s,sizeof(s) - sizeof(char))
|
||||
|
||||
|
||||
/*
|
||||
** Dump the block of memory pointed by 'b' with given 'size'.
|
||||
** 'b' should not be NULL, except for the last call signaling the end
|
||||
** of the dump.
|
||||
*/
|
||||
static void dumpBlock (DumpState *D, const void *b, size_t size) {
|
||||
if (D->status == 0 && size > 0) {
|
||||
if (D->status == 0) { /* do not write anything after an error */
|
||||
lua_unlock(D->L);
|
||||
D->status = (*D->writer)(D->L, b, size, D->data);
|
||||
lua_lock(D->L);
|
||||
@@ -53,13 +58,18 @@ static void dumpBlock (DumpState *D, const void *b, size_t size) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Dump enough zeros to ensure that current position is a multiple of
|
||||
** 'align'.
|
||||
*/
|
||||
static void dumpAlign (DumpState *D, int align) {
|
||||
int padding = align - (D->offset % align);
|
||||
if (padding < align) { /* apd == align means no padding */
|
||||
if (padding < align) { /* padding == align means no padding */
|
||||
static lua_Integer paddingContent = 0;
|
||||
lua_assert(cast_uint(align) <= sizeof(lua_Integer));
|
||||
dumpBlock(D, &paddingContent, padding);
|
||||
lua_assert(D->offset % align == 0);
|
||||
}
|
||||
lua_assert(D->offset % align == 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -91,6 +101,7 @@ static void dumpSize (DumpState *D, size_t x) {
|
||||
|
||||
|
||||
static void dumpInt (DumpState *D, int x) {
|
||||
lua_assert(x >= 0);
|
||||
dumpSize(D, x);
|
||||
}
|
||||
|
||||
@@ -140,6 +151,7 @@ static void dumpString (DumpState *D, TString *ts) {
|
||||
static void dumpCode (DumpState *D, const Proto *f) {
|
||||
dumpInt(D, f->sizecode);
|
||||
dumpAlign(D, sizeof(f->code[0]));
|
||||
lua_assert(f->code != NULL);
|
||||
dumpVector(D, f->code, f->sizecode);
|
||||
}
|
||||
|
||||
@@ -196,7 +208,8 @@ static void dumpDebug (DumpState *D, const Proto *f) {
|
||||
int i, n;
|
||||
n = (D->strip) ? 0 : f->sizelineinfo;
|
||||
dumpInt(D, n);
|
||||
dumpVector(D, f->lineinfo, n);
|
||||
if (f->lineinfo != NULL)
|
||||
dumpVector(D, f->lineinfo, n);
|
||||
n = (D->strip) ? 0 : f->sizeabslineinfo;
|
||||
dumpInt(D, n);
|
||||
for (i = 0; i < n; i++) {
|
||||
@@ -248,20 +261,23 @@ static void dumpHeader (DumpState *D) {
|
||||
/*
|
||||
** dump Lua function as precompiled chunk
|
||||
*/
|
||||
int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
|
||||
int strip, Table *h) {
|
||||
int luaU_dump (lua_State *L, const Proto *f, lua_Writer w, void *data,
|
||||
int strip) {
|
||||
DumpState D;
|
||||
D.h = luaH_new(L); /* aux. table to keep strings already dumped */
|
||||
sethvalue2s(L, L->top.p, D.h); /* anchor it */
|
||||
L->top.p++;
|
||||
D.L = L;
|
||||
D.writer = w;
|
||||
D.offset = 0;
|
||||
D.data = data;
|
||||
D.strip = strip;
|
||||
D.status = 0;
|
||||
D.h = h;
|
||||
D.nstr = 0;
|
||||
dumpHeader(&D);
|
||||
dumpByte(&D, f->sizeupvalues);
|
||||
dumpFunction(&D, f);
|
||||
dumpBlock(&D, NULL, 0); /* signal end of dump */
|
||||
return D.status;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user