diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-09-05 15:30:45 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-09-05 15:30:45 -0300 |
| commit | 14e416355f83cf0a1b871eedec2c92b86dbe76d6 (patch) | |
| tree | 620c7fa0b811d5f91d3d2f9b4879b289df6d137c /lundump.c | |
| parent | f33cda8d6eb1cac5b9042429e85f1096175c7ca5 (diff) | |
| download | lua-14e416355f83cf0a1b871eedec2c92b86dbe76d6.tar.gz lua-14e416355f83cf0a1b871eedec2c92b86dbe76d6.tar.bz2 lua-14e416355f83cf0a1b871eedec2c92b86dbe76d6.zip | |
Added suport for Fixed Buffers
A fixed buffer keeps a binary chunk "forever", so that the program
does not need to copy some of its parts when loading it.
Diffstat (limited to 'lundump.c')
| -rw-r--r-- | lundump.c | 42 |
1 files changed, 34 insertions, 8 deletions
| @@ -38,6 +38,7 @@ typedef struct { | |||
| 38 | Table *h; /* list for string reuse */ | 38 | Table *h; /* list for string reuse */ |
| 39 | lu_mem offset; /* current position relative to beginning of dump */ | 39 | lu_mem offset; /* current position relative to beginning of dump */ |
| 40 | lua_Integer nstr; /* number of strings in the list */ | 40 | lua_Integer nstr; /* number of strings in the list */ |
| 41 | lu_byte fixed; /* dump is fixed in memory */ | ||
| 41 | } LoadState; | 42 | } LoadState; |
| 42 | 43 | ||
| 43 | 44 | ||
| @@ -70,6 +71,16 @@ static void loadAlign (LoadState *S, int align) { | |||
| 70 | } | 71 | } |
| 71 | 72 | ||
| 72 | 73 | ||
| 74 | #define getaddr(S,n,t) cast(t *, getaddr_(S,n,sizeof(t))) | ||
| 75 | |||
| 76 | static const void *getaddr_ (LoadState *S, int n, int sz) { | ||
| 77 | const void *block = luaZ_getaddr(S->Z, n * sz); | ||
| 78 | if (block == NULL) | ||
| 79 | error(S, "truncated fixed buffer"); | ||
| 80 | return block; | ||
| 81 | } | ||
| 82 | |||
| 83 | |||
| 73 | #define loadVar(S,x) loadVector(S,&x,1) | 84 | #define loadVar(S,x) loadVector(S,&x,1) |
| 74 | 85 | ||
| 75 | 86 | ||
| @@ -169,10 +180,16 @@ static TString *loadString (LoadState *S, Proto *p) { | |||
| 169 | 180 | ||
| 170 | static void loadCode (LoadState *S, Proto *f) { | 181 | static void loadCode (LoadState *S, Proto *f) { |
| 171 | int n = loadInt(S); | 182 | int n = loadInt(S); |
| 172 | f->code = luaM_newvectorchecked(S->L, n, Instruction); | ||
| 173 | f->sizecode = n; | ||
| 174 | loadAlign(S, sizeof(f->code[0])); | 183 | loadAlign(S, sizeof(f->code[0])); |
| 175 | loadVector(S, f->code, n); | 184 | if (S->fixed) { |
| 185 | f->code = getaddr(S, n, Instruction); | ||
| 186 | f->sizecode = n; | ||
| 187 | } | ||
| 188 | else { | ||
| 189 | f->code = luaM_newvectorchecked(S->L, n, Instruction); | ||
| 190 | f->sizecode = n; | ||
| 191 | loadVector(S, f->code, n); | ||
| 192 | } | ||
| 176 | } | 193 | } |
| 177 | 194 | ||
| 178 | 195 | ||
| @@ -254,9 +271,15 @@ static void loadUpvalues (LoadState *S, Proto *f) { | |||
| 254 | static void loadDebug (LoadState *S, Proto *f) { | 271 | static void loadDebug (LoadState *S, Proto *f) { |
| 255 | int i, n; | 272 | int i, n; |
| 256 | n = loadInt(S); | 273 | n = loadInt(S); |
| 257 | f->lineinfo = luaM_newvectorchecked(S->L, n, ls_byte); | 274 | if (S->fixed) { |
| 258 | f->sizelineinfo = n; | 275 | f->lineinfo = getaddr(S, n, ls_byte); |
| 259 | loadVector(S, f->lineinfo, n); | 276 | f->sizelineinfo = n; |
| 277 | } | ||
| 278 | else { | ||
| 279 | f->lineinfo = luaM_newvectorchecked(S->L, n, ls_byte); | ||
| 280 | f->sizelineinfo = n; | ||
| 281 | loadVector(S, f->lineinfo, n); | ||
| 282 | } | ||
| 260 | n = loadInt(S); | 283 | n = loadInt(S); |
| 261 | f->abslineinfo = luaM_newvectorchecked(S->L, n, AbsLineInfo); | 284 | f->abslineinfo = luaM_newvectorchecked(S->L, n, AbsLineInfo); |
| 262 | f->sizeabslineinfo = n; | 285 | f->sizeabslineinfo = n; |
| @@ -287,7 +310,9 @@ static void loadFunction (LoadState *S, Proto *f) { | |||
| 287 | f->linedefined = loadInt(S); | 310 | f->linedefined = loadInt(S); |
| 288 | f->lastlinedefined = loadInt(S); | 311 | f->lastlinedefined = loadInt(S); |
| 289 | f->numparams = loadByte(S); | 312 | f->numparams = loadByte(S); |
| 290 | f->flag = loadByte(S) & PF_ISVARARG; /* keep only the meaningful flags */ | 313 | f->flag = loadByte(S) & PF_ISVARARG; /* get only the meaningful flags */ |
| 314 | if (S->fixed) | ||
| 315 | f->flag |= PF_FIXED; /* signal that code is fixed */ | ||
| 291 | f->maxstacksize = loadByte(S); | 316 | f->maxstacksize = loadByte(S); |
| 292 | loadCode(S, f); | 317 | loadCode(S, f); |
| 293 | loadConstants(S, f); | 318 | loadConstants(S, f); |
| @@ -335,7 +360,7 @@ static void checkHeader (LoadState *S) { | |||
| 335 | /* | 360 | /* |
| 336 | ** Load precompiled chunk. | 361 | ** Load precompiled chunk. |
| 337 | */ | 362 | */ |
| 338 | LClosure *luaU_undump (lua_State *L, ZIO *Z, const char *name) { | 363 | LClosure *luaU_undump (lua_State *L, ZIO *Z, const char *name, int fixed) { |
| 339 | LoadState S; | 364 | LoadState S; |
| 340 | LClosure *cl; | 365 | LClosure *cl; |
| 341 | if (*name == '@' || *name == '=') | 366 | if (*name == '@' || *name == '=') |
| @@ -346,6 +371,7 @@ LClosure *luaU_undump (lua_State *L, ZIO *Z, const char *name) { | |||
| 346 | S.name = name; | 371 | S.name = name; |
| 347 | S.L = L; | 372 | S.L = L; |
| 348 | S.Z = Z; | 373 | S.Z = Z; |
| 374 | S.fixed = fixed; | ||
| 349 | S.offset = 1; /* fist byte was already read */ | 375 | S.offset = 1; /* fist byte was already read */ |
| 350 | checkHeader(&S); | 376 | checkHeader(&S); |
| 351 | cl = luaF_newLclosure(L, loadByte(&S)); | 377 | cl = luaF_newLclosure(L, loadByte(&S)); |
