aboutsummaryrefslogtreecommitdiff
path: root/ldump.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldump.c')
-rw-r--r--ldump.c68
1 files changed, 54 insertions, 14 deletions
diff --git a/ldump.c b/ldump.c
index f231691b..01169c12 100644
--- a/ldump.c
+++ b/ldump.c
@@ -15,8 +15,10 @@
15 15
16#include "lua.h" 16#include "lua.h"
17 17
18#include "lgc.h"
18#include "lobject.h" 19#include "lobject.h"
19#include "lstate.h" 20#include "lstate.h"
21#include "ltable.h"
20#include "lundump.h" 22#include "lundump.h"
21 23
22 24
@@ -24,8 +26,11 @@ typedef struct {
24 lua_State *L; 26 lua_State *L;
25 lua_Writer writer; 27 lua_Writer writer;
26 void *data; 28 void *data;
29 lu_mem offset; /* current position relative to beginning of dump */
27 int strip; 30 int strip;
28 int status; 31 int status;
32 Table *h; /* table to track saved strings */
33 lua_Integer nstr; /* counter to number saved strings */
29} DumpState; 34} DumpState;
30 35
31 36
@@ -43,6 +48,17 @@ static void dumpBlock (DumpState *D, const void *b, size_t size) {
43 lua_unlock(D->L); 48 lua_unlock(D->L);
44 D->status = (*D->writer)(D->L, b, size, D->data); 49 D->status = (*D->writer)(D->L, b, size, D->data);
45 lua_lock(D->L); 50 lua_lock(D->L);
51 D->offset += size;
52 }
53}
54
55
56static void dumpAlign (DumpState *D, int align) {
57 int padding = align - (D->offset % align);
58 if (padding < align) { /* apd == align means no padding */
59 static lua_Integer paddingContent = 0;
60 dumpBlock(D, &paddingContent, padding);
61 lua_assert(D->offset % align == 0);
46 } 62 }
47} 63}
48 64
@@ -89,25 +105,46 @@ static void dumpInteger (DumpState *D, lua_Integer x) {
89} 105}
90 106
91 107
92static void dumpString (DumpState *D, const TString *s) { 108/*
93 if (s == NULL) 109** Dump a String. First dump its "size": size==0 means NULL;
110** size==1 is followed by an index and means "reuse saved string with
111** that index"; size>=2 is followed by the string contents with real
112** size==size-2 and means that string, which will be saved with
113** the next available index.
114*/
115static void dumpString (DumpState *D, TString *ts) {
116 if (ts == NULL)
94 dumpSize(D, 0); 117 dumpSize(D, 0);
95 else { 118 else {
96 size_t size = tsslen(s); 119 const TValue *idx = luaH_getstr(D->h, ts);
97 const char *str = getstr(s); 120 if (ttisinteger(idx)) { /* string already saved? */
98 dumpSize(D, size + 1); 121 dumpSize(D, 1); /* reuse a saved string */
99 dumpVector(D, str, size); 122 dumpInt(D, ivalue(idx)); /* index of saved string */
123 }
124 else { /* must write and save the string */
125 TValue key, value; /* to save the string in the hash */
126 size_t size;
127 const char *s = getlstr(ts, size);
128 dumpSize(D, size + 2);
129 dumpVector(D, s, size);
130 D->nstr++; /* one more saved string */
131 setsvalue(D->L, &key, ts); /* the string is the key */
132 setivalue(&value, D->nstr); /* its index is the value */
133 luaH_finishset(D->L, D->h, &key, idx, &value); /* h[ts] = nstr */
134 /* integer value does not need barrier */
135 }
100 } 136 }
101} 137}
102 138
103 139
104static void dumpCode (DumpState *D, const Proto *f) { 140static void dumpCode (DumpState *D, const Proto *f) {
105 dumpInt(D, f->sizecode); 141 dumpInt(D, f->sizecode);
142 dumpAlign(D, sizeof(f->code[0]));
106 dumpVector(D, f->code, f->sizecode); 143 dumpVector(D, f->code, f->sizecode);
107} 144}
108 145
109 146
110static void dumpFunction(DumpState *D, const Proto *f, TString *psource); 147static void dumpFunction(DumpState *D, const Proto *f);
111 148
112static void dumpConstants (DumpState *D, const Proto *f) { 149static void dumpConstants (DumpState *D, const Proto *f) {
113 int i; 150 int i;
@@ -140,7 +177,7 @@ static void dumpProtos (DumpState *D, const Proto *f) {
140 int n = f->sizep; 177 int n = f->sizep;
141 dumpInt(D, n); 178 dumpInt(D, n);
142 for (i = 0; i < n; i++) 179 for (i = 0; i < n; i++)
143 dumpFunction(D, f->p[i], f->source); 180 dumpFunction(D, f->p[i]);
144} 181}
145 182
146 183
@@ -180,15 +217,15 @@ static void dumpDebug (DumpState *D, const Proto *f) {
180} 217}
181 218
182 219
183static void dumpFunction (DumpState *D, const Proto *f, TString *psource) { 220static void dumpFunction (DumpState *D, const Proto *f) {
184 if (D->strip || f->source == psource) 221 if (D->strip)
185 dumpString(D, NULL); /* no debug info or same source as its parent */ 222 dumpString(D, NULL); /* no debug info */
186 else 223 else
187 dumpString(D, f->source); 224 dumpString(D, f->source);
188 dumpInt(D, f->linedefined); 225 dumpInt(D, f->linedefined);
189 dumpInt(D, f->lastlinedefined); 226 dumpInt(D, f->lastlinedefined);
190 dumpByte(D, f->numparams); 227 dumpByte(D, f->numparams);
191 dumpByte(D, f->is_vararg); 228 dumpByte(D, f->flag);
192 dumpByte(D, f->maxstacksize); 229 dumpByte(D, f->maxstacksize);
193 dumpCode(D, f); 230 dumpCode(D, f);
194 dumpConstants(D, f); 231 dumpConstants(D, f);
@@ -215,16 +252,19 @@ static void dumpHeader (DumpState *D) {
215** dump Lua function as precompiled chunk 252** dump Lua function as precompiled chunk
216*/ 253*/
217int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, 254int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
218 int strip) { 255 int strip, Table *h) {
219 DumpState D; 256 DumpState D;
220 D.L = L; 257 D.L = L;
221 D.writer = w; 258 D.writer = w;
259 D.offset = 0;
222 D.data = data; 260 D.data = data;
223 D.strip = strip; 261 D.strip = strip;
224 D.status = 0; 262 D.status = 0;
263 D.h = h;
264 D.nstr = 0;
225 dumpHeader(&D); 265 dumpHeader(&D);
226 dumpByte(&D, f->sizeupvalues); 266 dumpByte(&D, f->sizeupvalues);
227 dumpFunction(&D, f, NULL); 267 dumpFunction(&D, f);
228 return D.status; 268 return D.status;
229} 269}
230 270