diff options
Diffstat (limited to 'ldump.c')
-rw-r--r-- | ldump.c | 68 |
1 files changed, 54 insertions, 14 deletions
@@ -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 | |||
56 | static 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 | ||
92 | static 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 | */ | ||
115 | static 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 | ||
104 | static void dumpCode (DumpState *D, const Proto *f) { | 140 | static 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 | ||
110 | static void dumpFunction(DumpState *D, const Proto *f, TString *psource); | 147 | static void dumpFunction(DumpState *D, const Proto *f); |
111 | 148 | ||
112 | static void dumpConstants (DumpState *D, const Proto *f) { | 149 | static 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 | ||
183 | static void dumpFunction (DumpState *D, const Proto *f, TString *psource) { | 220 | static 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 | */ |
217 | int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, | 254 | int 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 | ||