2812
+ − 1
/*
+ − 2
** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
+ − 3
** save precompiled Lua chunks
+ − 4
** See Copyright Notice in lua.h
+ − 5
*/
+ − 6
+ − 7
#include <stddef.h>
+ − 8
+ − 9
#define ldump_c
+ − 10
#define LUA_CORE
+ − 11
+ − 12
#include "lua.h"
+ − 13
+ − 14
#include "lobject.h"
+ − 15
#include "lstate.h"
+ − 16
#include "lundump.h"
+ − 17
+ − 18
typedef struct {
+ − 19
lua_State* L;
+ − 20
lua_Writer writer;
+ − 21
void* data;
+ − 22
int strip;
+ − 23
int status;
+ − 24
} DumpState;
+ − 25
+ − 26
#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D)
+ − 27
#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D)
+ − 28
+ − 29
static void DumpBlock(const void* b, size_t size, DumpState* D)
+ − 30
{
+ − 31
if (D->status==0)
+ − 32
{
+ − 33
lua_unlock(D->L);
+ − 34
D->status=(*D->writer)(D->L,b,size,D->data);
+ − 35
lua_lock(D->L);
+ − 36
}
+ − 37
}
+ − 38
+ − 39
static void DumpChar(int y, DumpState* D)
+ − 40
{
+ − 41
char x=(char)y;
+ − 42
DumpVar(x,D);
+ − 43
}
+ − 44
+ − 45
static void DumpInt(int x, DumpState* D)
+ − 46
{
+ − 47
DumpVar(x,D);
+ − 48
}
+ − 49
+ − 50
static void DumpNumber(lua_Number x, DumpState* D)
+ − 51
{
+ − 52
DumpVar(x,D);
+ − 53
}
+ − 54
+ − 55
static void DumpVector(const void* b, int n, size_t size, DumpState* D)
+ − 56
{
+ − 57
DumpInt(n,D);
+ − 58
DumpMem(b,n,size,D);
+ − 59
}
+ − 60
+ − 61
static void DumpString(const TString* s, DumpState* D)
+ − 62
{
+ − 63
if (s==NULL || getstr(s)==NULL)
+ − 64
{
+ − 65
size_t size=0;
+ − 66
DumpVar(size,D);
+ − 67
}
+ − 68
else
+ − 69
{
+ − 70
size_t size=s->tsv.len+1; /* include trailing '\0' */
+ − 71
DumpVar(size,D);
+ − 72
DumpBlock(getstr(s),size,D);
+ − 73
}
+ − 74
}
+ − 75
+ − 76
#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D)
+ − 77
+ − 78
static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
+ − 79
+ − 80
static void DumpConstants(const Proto* f, DumpState* D)
+ − 81
{
+ − 82
int i,n=f->sizek;
+ − 83
DumpInt(n,D);
+ − 84
for (i=0; i<n; i++)
+ − 85
{
+ − 86
const TValue* o=&f->k[i];
+ − 87
DumpChar(ttype(o),D);
+ − 88
switch (ttype(o))
+ − 89
{
+ − 90
case LUA_TNIL:
+ − 91
break;
+ − 92
case LUA_TBOOLEAN:
+ − 93
DumpChar(bvalue(o),D);
+ − 94
break;
+ − 95
case LUA_TNUMBER:
+ − 96
DumpNumber(nvalue(o),D);
+ − 97
break;
+ − 98
case LUA_TSTRING:
+ − 99
DumpString(rawtsvalue(o),D);
+ − 100
break;
+ − 101
default:
+ − 102
lua_assert(0); /* cannot happen */
+ − 103
break;
+ − 104
}
+ − 105
}
+ − 106
n=f->sizep;
+ − 107
DumpInt(n,D);
+ − 108
for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
+ − 109
}
+ − 110
+ − 111
static void DumpDebug(const Proto* f, DumpState* D)
+ − 112
{
+ − 113
int i,n;
+ − 114
n= (D->strip) ? 0 : f->sizelineinfo;
+ − 115
DumpVector(f->lineinfo,n,sizeof(int),D);
+ − 116
n= (D->strip) ? 0 : f->sizelocvars;
+ − 117
DumpInt(n,D);
+ − 118
for (i=0; i<n; i++)
+ − 119
{
+ − 120
DumpString(f->locvars[i].varname,D);
+ − 121
DumpInt(f->locvars[i].startpc,D);
+ − 122
DumpInt(f->locvars[i].endpc,D);
+ − 123
}
+ − 124
n= (D->strip) ? 0 : f->sizeupvalues;
+ − 125
DumpInt(n,D);
+ − 126
for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
+ − 127
}
+ − 128
+ − 129
static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
+ − 130
{
+ − 131
DumpString((f->source==p || D->strip) ? NULL : f->source,D);
+ − 132
DumpInt(f->linedefined,D);
+ − 133
DumpInt(f->lastlinedefined,D);
+ − 134
DumpChar(f->nups,D);
+ − 135
DumpChar(f->numparams,D);
+ − 136
DumpChar(f->is_vararg,D);
+ − 137
DumpChar(f->maxstacksize,D);
+ − 138
DumpCode(f,D);
+ − 139
DumpConstants(f,D);
+ − 140
DumpDebug(f,D);
+ − 141
}
+ − 142
+ − 143
static void DumpHeader(DumpState* D)
+ − 144
{
+ − 145
char h[LUAC_HEADERSIZE];
+ − 146
luaU_header(h);
+ − 147
DumpBlock(h,LUAC_HEADERSIZE,D);
+ − 148
}
+ − 149
+ − 150
/*
+ − 151
** dump Lua function as precompiled chunk
+ − 152
*/
+ − 153
int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
+ − 154
{
+ − 155
DumpState D;
+ − 156
D.L=L;
+ − 157
D.writer=w;
+ − 158
D.data=data;
+ − 159
D.strip=strip;
+ − 160
D.status=0;
+ − 161
DumpHeader(&D);
+ − 162
DumpFunction(f,NULL,&D);
+ − 163
return D.status;
+ − 164
}