diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-12-14 11:41:57 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-12-14 11:41:57 -0300 |
| commit | 4eda1acafa1a69224b2d4f786cf1ec8f7a4d9ac5 (patch) | |
| tree | 474a56c1cbb1b109f945cb3765c6ebc918d35b37 /ldump.c | |
| parent | ad73b332240ef5b9bab1517517f63a1425dc7545 (diff) | |
| download | lua-4eda1acafa1a69224b2d4f786cf1ec8f7a4d9ac5.tar.gz lua-4eda1acafa1a69224b2d4f786cf1ec8f7a4d9ac5.tar.bz2 lua-4eda1acafa1a69224b2d4f786cf1ec8f7a4d9ac5.zip | |
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.
Diffstat (limited to 'ldump.c')
| -rw-r--r-- | ldump.c | 30 |
1 files changed, 23 insertions, 7 deletions
| @@ -43,8 +43,13 @@ typedef struct { | |||
| 43 | #define dumpLiteral(D, s) dumpBlock(D,s,sizeof(s) - sizeof(char)) | 43 | #define dumpLiteral(D, s) dumpBlock(D,s,sizeof(s) - sizeof(char)) |
| 44 | 44 | ||
| 45 | 45 | ||
| 46 | /* | ||
| 47 | ** Dump the block of memory pointed by 'b' with given 'size'. | ||
| 48 | ** 'b' should not be NULL, except for the last call signaling the end | ||
| 49 | ** of the dump. | ||
| 50 | */ | ||
| 46 | static void dumpBlock (DumpState *D, const void *b, size_t size) { | 51 | static void dumpBlock (DumpState *D, const void *b, size_t size) { |
| 47 | if (D->status == 0 && size > 0) { | 52 | if (D->status == 0) { /* do not write anything after an error */ |
| 48 | lua_unlock(D->L); | 53 | lua_unlock(D->L); |
| 49 | D->status = (*D->writer)(D->L, b, size, D->data); | 54 | D->status = (*D->writer)(D->L, b, size, D->data); |
| 50 | lua_lock(D->L); | 55 | lua_lock(D->L); |
| @@ -53,13 +58,18 @@ static void dumpBlock (DumpState *D, const void *b, size_t size) { | |||
| 53 | } | 58 | } |
| 54 | 59 | ||
| 55 | 60 | ||
| 61 | /* | ||
| 62 | ** Dump enough zeros to ensure that current position is a multiple of | ||
| 63 | ** 'align'. | ||
| 64 | */ | ||
| 56 | static void dumpAlign (DumpState *D, int align) { | 65 | static void dumpAlign (DumpState *D, int align) { |
| 57 | int padding = align - (D->offset % align); | 66 | int padding = align - (D->offset % align); |
| 58 | if (padding < align) { /* apd == align means no padding */ | 67 | if (padding < align) { /* padding == align means no padding */ |
| 59 | static lua_Integer paddingContent = 0; | 68 | static lua_Integer paddingContent = 0; |
| 69 | lua_assert(cast_uint(align) <= sizeof(lua_Integer)); | ||
| 60 | dumpBlock(D, &paddingContent, padding); | 70 | dumpBlock(D, &paddingContent, padding); |
| 61 | lua_assert(D->offset % align == 0); | ||
| 62 | } | 71 | } |
| 72 | lua_assert(D->offset % align == 0); | ||
| 63 | } | 73 | } |
| 64 | 74 | ||
| 65 | 75 | ||
| @@ -91,6 +101,7 @@ static void dumpSize (DumpState *D, size_t x) { | |||
| 91 | 101 | ||
| 92 | 102 | ||
| 93 | static void dumpInt (DumpState *D, int x) { | 103 | static void dumpInt (DumpState *D, int x) { |
| 104 | lua_assert(x >= 0); | ||
| 94 | dumpSize(D, x); | 105 | dumpSize(D, x); |
| 95 | } | 106 | } |
| 96 | 107 | ||
| @@ -140,6 +151,7 @@ static void dumpString (DumpState *D, TString *ts) { | |||
| 140 | static void dumpCode (DumpState *D, const Proto *f) { | 151 | static void dumpCode (DumpState *D, const Proto *f) { |
| 141 | dumpInt(D, f->sizecode); | 152 | dumpInt(D, f->sizecode); |
| 142 | dumpAlign(D, sizeof(f->code[0])); | 153 | dumpAlign(D, sizeof(f->code[0])); |
| 154 | lua_assert(f->code != NULL); | ||
| 143 | dumpVector(D, f->code, f->sizecode); | 155 | dumpVector(D, f->code, f->sizecode); |
| 144 | } | 156 | } |
| 145 | 157 | ||
| @@ -196,7 +208,8 @@ static void dumpDebug (DumpState *D, const Proto *f) { | |||
| 196 | int i, n; | 208 | int i, n; |
| 197 | n = (D->strip) ? 0 : f->sizelineinfo; | 209 | n = (D->strip) ? 0 : f->sizelineinfo; |
| 198 | dumpInt(D, n); | 210 | dumpInt(D, n); |
| 199 | dumpVector(D, f->lineinfo, n); | 211 | if (f->lineinfo != NULL) |
| 212 | dumpVector(D, f->lineinfo, n); | ||
| 200 | n = (D->strip) ? 0 : f->sizeabslineinfo; | 213 | n = (D->strip) ? 0 : f->sizeabslineinfo; |
| 201 | dumpInt(D, n); | 214 | dumpInt(D, n); |
| 202 | for (i = 0; i < n; i++) { | 215 | for (i = 0; i < n; i++) { |
| @@ -248,20 +261,23 @@ static void dumpHeader (DumpState *D) { | |||
| 248 | /* | 261 | /* |
| 249 | ** dump Lua function as precompiled chunk | 262 | ** dump Lua function as precompiled chunk |
| 250 | */ | 263 | */ |
| 251 | int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, | 264 | int luaU_dump (lua_State *L, const Proto *f, lua_Writer w, void *data, |
| 252 | int strip, Table *h) { | 265 | int strip) { |
| 253 | DumpState D; | 266 | DumpState D; |
| 267 | D.h = luaH_new(L); /* aux. table to keep strings already dumped */ | ||
| 268 | sethvalue2s(L, L->top.p, D.h); /* anchor it */ | ||
| 269 | L->top.p++; | ||
| 254 | D.L = L; | 270 | D.L = L; |
| 255 | D.writer = w; | 271 | D.writer = w; |
| 256 | D.offset = 0; | 272 | D.offset = 0; |
| 257 | D.data = data; | 273 | D.data = data; |
| 258 | D.strip = strip; | 274 | D.strip = strip; |
| 259 | D.status = 0; | 275 | D.status = 0; |
| 260 | D.h = h; | ||
| 261 | D.nstr = 0; | 276 | D.nstr = 0; |
| 262 | dumpHeader(&D); | 277 | dumpHeader(&D); |
| 263 | dumpByte(&D, f->sizeupvalues); | 278 | dumpByte(&D, f->sizeupvalues); |
| 264 | dumpFunction(&D, f); | 279 | dumpFunction(&D, f); |
| 280 | dumpBlock(&D, NULL, 0); /* signal end of dump */ | ||
| 265 | return D.status; | 281 | return D.status; |
| 266 | } | 282 | } |
| 267 | 283 | ||
