| @@ -1,339 +1,341 @@ | | | @@ -1,339 +1,341 @@ |
1 | /* $NetBSD: lundump.c,v 1.9 2023/04/16 20:46:17 nikita Exp $ */ | | 1 | /* $NetBSD: lundump.c,v 1.10 2023/04/17 21:17:57 nikita Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | ** Id: lundump.c | | 4 | ** Id: lundump.c |
5 | ** load precompiled Lua chunks | | 5 | ** load precompiled Lua chunks |
6 | ** See Copyright Notice in lua.h | | 6 | ** See Copyright Notice in lua.h |
7 | */ | | 7 | */ |
8 | | | 8 | |
9 | #define lundump_c | | 9 | #define lundump_c |
10 | #define LUA_CORE | | 10 | #define LUA_CORE |
11 | | | 11 | |
12 | #include "lprefix.h" | | 12 | #include "lprefix.h" |
13 | | | 13 | |
14 | | | 14 | |
15 | #ifndef _KERNEL | | 15 | #ifndef _KERNEL |
16 | #include <limits.h> | | 16 | #include <limits.h> |
17 | #include <string.h> | | 17 | #include <string.h> |
18 | #endif /* _KERNEL */ | | 18 | #endif /* _KERNEL */ |
19 | | | 19 | |
20 | #include "lua.h" | | 20 | #include "lua.h" |
21 | | | 21 | |
22 | #include "ldebug.h" | | 22 | #include "ldebug.h" |
23 | #include "ldo.h" | | 23 | #include "ldo.h" |
24 | #include "lfunc.h" | | 24 | #include "lfunc.h" |
25 | #include "lmem.h" | | 25 | #include "lmem.h" |
26 | #include "lobject.h" | | 26 | #include "lobject.h" |
27 | #include "lstring.h" | | 27 | #include "lstring.h" |
28 | #include "lundump.h" | | 28 | #include "lundump.h" |
29 | #include "lzio.h" | | 29 | #include "lzio.h" |
30 | | | 30 | |
31 | | | 31 | |
32 | #if !defined(luai_verifycode) | | 32 | #if !defined(luai_verifycode) |
33 | #define luai_verifycode(L,f) /* empty */ | | 33 | #define luai_verifycode(L,f) /* empty */ |
34 | #endif | | 34 | #endif |
35 | | | 35 | |
36 | | | 36 | |
37 | typedef struct { | | 37 | typedef struct { |
38 | lua_State *L; | | 38 | lua_State *L; |
39 | ZIO *Z; | | 39 | ZIO *Z; |
40 | const char *name; | | 40 | const char *name; |
41 | } LoadState; | | 41 | } LoadState; |
42 | | | 42 | |
43 | | | 43 | |
44 | static l_noret error (LoadState *S, const char *why) { | | 44 | static l_noret error (LoadState *S, const char *why) { |
45 | luaO_pushfstring(S->L, "%s: bad binary format (%s)", S->name, why); | | 45 | luaO_pushfstring(S->L, "%s: bad binary format (%s)", S->name, why); |
46 | luaD_throw(S->L, LUA_ERRSYNTAX); | | 46 | luaD_throw(S->L, LUA_ERRSYNTAX); |
47 | } | | 47 | } |
48 | | | 48 | |
49 | | | 49 | |
50 | /* | | 50 | /* |
51 | ** All high-level loads go through loadVector; you can change it to | | 51 | ** All high-level loads go through loadVector; you can change it to |
52 | ** adapt to the endianness of the input | | 52 | ** adapt to the endianness of the input |
53 | */ | | 53 | */ |
54 | #define loadVector(S,b,n) loadBlock(S,b,(n)*sizeof((b)[0])) | | 54 | #define loadVector(S,b,n) loadBlock(S,b,(n)*sizeof((b)[0])) |
55 | | | 55 | |
56 | static void loadBlock (LoadState *S, void *b, size_t size) { | | 56 | static void loadBlock (LoadState *S, void *b, size_t size) { |
57 | if (luaZ_read(S->Z, b, size) != 0) | | 57 | if (luaZ_read(S->Z, b, size) != 0) |
58 | error(S, "truncated chunk"); | | 58 | error(S, "truncated chunk"); |
59 | } | | 59 | } |
60 | | | 60 | |
61 | | | 61 | |
62 | #define loadVar(S,x) loadVector(S,&x,1) | | 62 | #define loadVar(S,x) loadVector(S,&x,1) |
63 | | | 63 | |
64 | | | 64 | |
65 | static lu_byte loadByte (LoadState *S) { | | 65 | static lu_byte loadByte (LoadState *S) { |
66 | int b = zgetc(S->Z); | | 66 | int b = zgetc(S->Z); |
67 | if (b == EOZ) | | 67 | if (b == EOZ) |
68 | error(S, "truncated chunk"); | | 68 | error(S, "truncated chunk"); |
69 | return cast_byte(b); | | 69 | return cast_byte(b); |
70 | } | | 70 | } |
71 | | | 71 | |
72 | | | 72 | |
73 | static size_t loadUnsigned (LoadState *S, size_t limit) { | | 73 | static size_t loadUnsigned (LoadState *S, size_t limit) { |
74 | size_t x = 0; | | 74 | size_t x = 0; |
75 | int b; | | 75 | int b; |
76 | limit >>= 7; | | 76 | limit >>= 7; |
77 | do { | | 77 | do { |
78 | b = loadByte(S); | | 78 | b = loadByte(S); |
79 | if (x >= limit) | | 79 | if (x >= limit) |
80 | error(S, "integer overflow"); | | 80 | error(S, "integer overflow"); |
81 | x = (x << 7) | (b & 0x7f); | | 81 | x = (x << 7) | (b & 0x7f); |
82 | } while ((b & 0x80) == 0); | | 82 | } while ((b & 0x80) == 0); |
83 | return x; | | 83 | return x; |
84 | } | | 84 | } |
85 | | | 85 | |
86 | | | 86 | |
87 | static size_t loadSize (LoadState *S) { | | 87 | static size_t loadSize (LoadState *S) { |
88 | return loadUnsigned(S, ~(size_t)0); | | 88 | return loadUnsigned(S, ~(size_t)0); |
89 | } | | 89 | } |
90 | | | 90 | |
91 | | | 91 | |
92 | static int loadInt (LoadState *S) { | | 92 | static int loadInt (LoadState *S) { |
93 | return cast_int(loadUnsigned(S, INT_MAX)); | | 93 | return cast_int(loadUnsigned(S, INT_MAX)); |
94 | } | | 94 | } |
95 | | | 95 | |
96 | | | 96 | |
97 | static lua_Number loadNumber (LoadState *S) { | | 97 | static lua_Number loadNumber (LoadState *S) { |
98 | lua_Number x; | | 98 | lua_Number x; |
99 | loadVar(S, x); | | 99 | loadVar(S, x); |
100 | return x; | | 100 | return x; |
101 | } | | 101 | } |
102 | | | 102 | |
103 | | | 103 | |
104 | static lua_Integer loadInteger (LoadState *S) { | | 104 | static lua_Integer loadInteger (LoadState *S) { |
105 | lua_Integer x; | | 105 | lua_Integer x; |
106 | loadVar(S, x); | | 106 | loadVar(S, x); |
107 | return x; | | 107 | return x; |
108 | } | | 108 | } |
109 | | | 109 | |
110 | | | 110 | |
111 | /* | | 111 | /* |
112 | ** Load a nullable string into prototype 'p'. | | 112 | ** Load a nullable string into prototype 'p'. |
113 | */ | | 113 | */ |
114 | static TString *loadStringN (LoadState *S, Proto *p) { | | 114 | static TString *loadStringN (LoadState *S, Proto *p) { |
115 | lua_State *L = S->L; | | 115 | lua_State *L = S->L; |
116 | TString *ts; | | 116 | TString *ts; |
117 | size_t size = loadSize(S); | | 117 | size_t size = loadSize(S); |
118 | if (size == 0) /* no string? */ | | 118 | if (size == 0) /* no string? */ |
119 | return NULL; | | 119 | return NULL; |
120 | else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ | | 120 | else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ |
121 | char buff[LUAI_MAXSHORTLEN]; | | 121 | char buff[LUAI_MAXSHORTLEN]; |
122 | loadVector(S, buff, size); /* load string into buffer */ | | 122 | loadVector(S, buff, size); /* load string into buffer */ |
123 | ts = luaS_newlstr(L, buff, size); /* create string */ | | 123 | ts = luaS_newlstr(L, buff, size); /* create string */ |
124 | } | | 124 | } |
125 | else { /* long string */ | | 125 | else { /* long string */ |
126 | ts = luaS_createlngstrobj(L, size); /* create string */ | | 126 | ts = luaS_createlngstrobj(L, size); /* create string */ |
127 | setsvalue2s(L, L->top, ts); /* anchor it ('loadVector' can GC) */ | | 127 | setsvalue2s(L, L->top, ts); /* anchor it ('loadVector' can GC) */ |
128 | luaD_inctop(L); | | 128 | luaD_inctop(L); |
129 | loadVector(S, getstr(ts), size); /* load directly in final place */ | | 129 | loadVector(S, getstr(ts), size); /* load directly in final place */ |
130 | L->top--; /* pop string */ | | 130 | L->top--; /* pop string */ |
131 | } | | 131 | } |
132 | luaC_objbarrier(L, p, ts); | | 132 | luaC_objbarrier(L, p, ts); |
133 | return ts; | | 133 | return ts; |
134 | } | | 134 | } |
135 | | | 135 | |
136 | | | 136 | |
137 | /* | | 137 | /* |
138 | ** Load a non-nullable string into prototype 'p'. | | 138 | ** Load a non-nullable string into prototype 'p'. |
139 | */ | | 139 | */ |
140 | static TString *loadString (LoadState *S, Proto *p) { | | 140 | static TString *loadString (LoadState *S, Proto *p) { |
141 | TString *st = loadStringN(S, p); | | 141 | TString *st = loadStringN(S, p); |
142 | if (st == NULL) | | 142 | if (st == NULL) |
143 | error(S, "bad format for constant string"); | | 143 | error(S, "bad format for constant string"); |
144 | return st; | | 144 | return st; |
145 | } | | 145 | } |
146 | | | 146 | |
147 | | | 147 | |
148 | static void loadCode (LoadState *S, Proto *f) { | | 148 | static void loadCode (LoadState *S, Proto *f) { |
149 | int n = loadInt(S); | | 149 | int n = loadInt(S); |
150 | f->code = luaM_newvectorchecked(S->L, n, Instruction); | | 150 | f->code = luaM_newvectorchecked(S->L, n, Instruction); |
151 | f->sizecode = n; | | 151 | f->sizecode = n; |
152 | loadVector(S, f->code, n); | | 152 | loadVector(S, f->code, n); |
153 | } | | 153 | } |
154 | | | 154 | |
155 | | | 155 | |
156 | static void loadFunction(LoadState *S, Proto *f, TString *psource); | | 156 | static void loadFunction(LoadState *S, Proto *f, TString *psource); |
157 | | | 157 | |
158 | | | 158 | |
159 | static void loadConstants (LoadState *S, Proto *f) { | | 159 | static void loadConstants (LoadState *S, Proto *f) { |
160 | int i; | | 160 | int i; |
161 | int n = loadInt(S); | | 161 | int n = loadInt(S); |
162 | f->k = luaM_newvectorchecked(S->L, n, TValue); | | 162 | f->k = luaM_newvectorchecked(S->L, n, TValue); |
163 | f->sizek = n; | | 163 | f->sizek = n; |
164 | for (i = 0; i < n; i++) | | 164 | for (i = 0; i < n; i++) |
165 | setnilvalue(&f->k[i]); | | 165 | setnilvalue(&f->k[i]); |
166 | for (i = 0; i < n; i++) { | | 166 | for (i = 0; i < n; i++) { |
167 | TValue *o = &f->k[i]; | | 167 | TValue *o = &f->k[i]; |
168 | int t = loadByte(S); | | 168 | int t = loadByte(S); |
169 | switch (t) { | | 169 | switch (t) { |
170 | case LUA_VNIL: | | 170 | case LUA_VNIL: |
171 | setnilvalue(o); | | 171 | setnilvalue(o); |
172 | break; | | 172 | break; |
173 | case LUA_VFALSE: | | 173 | case LUA_VFALSE: |
174 | setbfvalue(o); | | 174 | setbfvalue(o); |
175 | break; | | 175 | break; |
176 | case LUA_VTRUE: | | 176 | case LUA_VTRUE: |
177 | setbtvalue(o); | | 177 | setbtvalue(o); |
178 | break; | | 178 | break; |
179 | #ifndef _KERNEL | | 179 | #ifndef _KERNEL |
180 | case LUA_VNUMFLT: | | 180 | case LUA_VNUMFLT: |
181 | setfltvalue(o, loadNumber(S)); | | 181 | setfltvalue(o, loadNumber(S)); |
182 | break; | | 182 | break; |
183 | #endif /* _KERNEL */ | | 183 | #endif /* _KERNEL */ |
184 | case LUA_VNUMINT: | | 184 | case LUA_VNUMINT: |
185 | setivalue(o, loadInteger(S)); | | 185 | setivalue(o, loadInteger(S)); |
186 | break; | | 186 | break; |
187 | case LUA_VSHRSTR: | | 187 | case LUA_VSHRSTR: |
188 | case LUA_VLNGSTR: | | 188 | case LUA_VLNGSTR: |
189 | setsvalue2n(S->L, o, loadString(S, f)); | | 189 | setsvalue2n(S->L, o, loadString(S, f)); |
190 | break; | | 190 | break; |
191 | default: lua_assert(0); | | 191 | default: lua_assert(0); |
192 | } | | 192 | } |
193 | } | | 193 | } |
194 | } | | 194 | } |
195 | | | 195 | |
196 | | | 196 | |
197 | static void loadProtos (LoadState *S, Proto *f) { | | 197 | static void loadProtos (LoadState *S, Proto *f) { |
198 | int i; | | 198 | int i; |
199 | int n = loadInt(S); | | 199 | int n = loadInt(S); |
200 | f->p = luaM_newvectorchecked(S->L, n, Proto *); | | 200 | f->p = luaM_newvectorchecked(S->L, n, Proto *); |
201 | f->sizep = n; | | 201 | f->sizep = n; |
202 | for (i = 0; i < n; i++) | | 202 | for (i = 0; i < n; i++) |
203 | f->p[i] = NULL; | | 203 | f->p[i] = NULL; |
204 | for (i = 0; i < n; i++) { | | 204 | for (i = 0; i < n; i++) { |
205 | f->p[i] = luaF_newproto(S->L); | | 205 | f->p[i] = luaF_newproto(S->L); |
206 | luaC_objbarrier(S->L, f, f->p[i]); | | 206 | luaC_objbarrier(S->L, f, f->p[i]); |
207 | loadFunction(S, f->p[i], f->source); | | 207 | loadFunction(S, f->p[i], f->source); |
208 | } | | 208 | } |
209 | } | | 209 | } |
210 | | | 210 | |
211 | | | 211 | |
212 | /* | | 212 | /* |
213 | ** Load the upvalues for a function. The names must be filled first, | | 213 | ** Load the upvalues for a function. The names must be filled first, |
214 | ** because the filling of the other fields can raise read errors and | | 214 | ** because the filling of the other fields can raise read errors and |
215 | ** the creation of the error message can call an emergency collection; | | 215 | ** the creation of the error message can call an emergency collection; |
216 | ** in that case all prototypes must be consistent for the GC. | | 216 | ** in that case all prototypes must be consistent for the GC. |
217 | */ | | 217 | */ |
218 | static void loadUpvalues (LoadState *S, Proto *f) { | | 218 | static void loadUpvalues (LoadState *S, Proto *f) { |
219 | int i, n; | | 219 | int i, n; |
220 | n = loadInt(S); | | 220 | n = loadInt(S); |
221 | f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc); | | 221 | f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc); |
222 | f->sizeupvalues = n; | | 222 | f->sizeupvalues = n; |
223 | for (i = 0; i < n; i++) /* make array valid for GC */ | | 223 | for (i = 0; i < n; i++) /* make array valid for GC */ |
224 | f->upvalues[i].name = NULL; | | 224 | f->upvalues[i].name = NULL; |
225 | for (i = 0; i < n; i++) { /* following calls can raise errors */ | | 225 | for (i = 0; i < n; i++) { /* following calls can raise errors */ |
226 | f->upvalues[i].instack = loadByte(S); | | 226 | f->upvalues[i].instack = loadByte(S); |
227 | f->upvalues[i].idx = loadByte(S); | | 227 | f->upvalues[i].idx = loadByte(S); |
228 | f->upvalues[i].kind = loadByte(S); | | 228 | f->upvalues[i].kind = loadByte(S); |
229 | } | | 229 | } |
230 | } | | 230 | } |
231 | | | 231 | |
232 | | | 232 | |
233 | static void loadDebug (LoadState *S, Proto *f) { | | 233 | static void loadDebug (LoadState *S, Proto *f) { |
234 | int i, n; | | 234 | int i, n; |
235 | n = loadInt(S); | | 235 | n = loadInt(S); |
236 | f->lineinfo = luaM_newvectorchecked(S->L, n, ls_byte); | | 236 | f->lineinfo = luaM_newvectorchecked(S->L, n, ls_byte); |
237 | f->sizelineinfo = n; | | 237 | f->sizelineinfo = n; |
238 | loadVector(S, f->lineinfo, n); | | 238 | loadVector(S, f->lineinfo, n); |
239 | n = loadInt(S); | | 239 | n = loadInt(S); |
240 | f->abslineinfo = luaM_newvectorchecked(S->L, n, AbsLineInfo); | | 240 | f->abslineinfo = luaM_newvectorchecked(S->L, n, AbsLineInfo); |
241 | f->sizeabslineinfo = n; | | 241 | f->sizeabslineinfo = n; |
242 | for (i = 0; i < n; i++) { | | 242 | for (i = 0; i < n; i++) { |
243 | f->abslineinfo[i].pc = loadInt(S); | | 243 | f->abslineinfo[i].pc = loadInt(S); |
244 | f->abslineinfo[i].line = loadInt(S); | | 244 | f->abslineinfo[i].line = loadInt(S); |
245 | } | | 245 | } |
246 | n = loadInt(S); | | 246 | n = loadInt(S); |
247 | f->locvars = luaM_newvectorchecked(S->L, n, LocVar); | | 247 | f->locvars = luaM_newvectorchecked(S->L, n, LocVar); |
248 | f->sizelocvars = n; | | 248 | f->sizelocvars = n; |
249 | for (i = 0; i < n; i++) | | 249 | for (i = 0; i < n; i++) |
250 | f->locvars[i].varname = NULL; | | 250 | f->locvars[i].varname = NULL; |
251 | for (i = 0; i < n; i++) { | | 251 | for (i = 0; i < n; i++) { |
252 | f->locvars[i].varname = loadStringN(S, f); | | 252 | f->locvars[i].varname = loadStringN(S, f); |
253 | f->locvars[i].startpc = loadInt(S); | | 253 | f->locvars[i].startpc = loadInt(S); |
254 | f->locvars[i].endpc = loadInt(S); | | 254 | f->locvars[i].endpc = loadInt(S); |
255 | } | | 255 | } |
256 | n = loadInt(S); | | 256 | n = loadInt(S); |
| | | 257 | if (n != 0) /* does it have debug information? */ |
| | | 258 | n = f->sizeupvalues; /* must be this many */ |
257 | for (i = 0; i < n; i++) | | 259 | for (i = 0; i < n; i++) |
258 | f->upvalues[i].name = loadStringN(S, f); | | 260 | f->upvalues[i].name = loadStringN(S, f); |
259 | } | | 261 | } |
260 | | | 262 | |
261 | | | 263 | |
262 | static void loadFunction (LoadState *S, Proto *f, TString *psource) { | | 264 | static void loadFunction (LoadState *S, Proto *f, TString *psource) { |
263 | f->source = loadStringN(S, f); | | 265 | f->source = loadStringN(S, f); |
264 | if (f->source == NULL) /* no source in dump? */ | | 266 | if (f->source == NULL) /* no source in dump? */ |
265 | f->source = psource; /* reuse parent's source */ | | 267 | f->source = psource; /* reuse parent's source */ |
266 | f->linedefined = loadInt(S); | | 268 | f->linedefined = loadInt(S); |
267 | f->lastlinedefined = loadInt(S); | | 269 | f->lastlinedefined = loadInt(S); |
268 | f->numparams = loadByte(S); | | 270 | f->numparams = loadByte(S); |
269 | f->is_vararg = loadByte(S); | | 271 | f->is_vararg = loadByte(S); |
270 | f->maxstacksize = loadByte(S); | | 272 | f->maxstacksize = loadByte(S); |
271 | loadCode(S, f); | | 273 | loadCode(S, f); |
272 | loadConstants(S, f); | | 274 | loadConstants(S, f); |
273 | loadUpvalues(S, f); | | 275 | loadUpvalues(S, f); |
274 | loadProtos(S, f); | | 276 | loadProtos(S, f); |
275 | loadDebug(S, f); | | 277 | loadDebug(S, f); |
276 | } | | 278 | } |
277 | | | 279 | |
278 | | | 280 | |
279 | static void checkliteral (LoadState *S, const char *s, const char *msg) { | | 281 | static void checkliteral (LoadState *S, const char *s, const char *msg) { |
280 | char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */ | | 282 | char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */ |
281 | size_t len = strlen(s); | | 283 | size_t len = strlen(s); |
282 | loadVector(S, buff, len); | | 284 | loadVector(S, buff, len); |
283 | if (memcmp(s, buff, len) != 0) | | 285 | if (memcmp(s, buff, len) != 0) |
284 | error(S, msg); | | 286 | error(S, msg); |
285 | } | | 287 | } |
286 | | | 288 | |
287 | | | 289 | |
288 | static void fchecksize (LoadState *S, size_t size, const char *tname) { | | 290 | static void fchecksize (LoadState *S, size_t size, const char *tname) { |
289 | if (loadByte(S) != size) | | 291 | if (loadByte(S) != size) |
290 | error(S, luaO_pushfstring(S->L, "%s size mismatch", tname)); | | 292 | error(S, luaO_pushfstring(S->L, "%s size mismatch", tname)); |
291 | } | | 293 | } |
292 | | | 294 | |
293 | | | 295 | |
294 | #define checksize(S,t) fchecksize(S,sizeof(t),#t) | | 296 | #define checksize(S,t) fchecksize(S,sizeof(t),#t) |
295 | | | 297 | |
296 | static void checkHeader (LoadState *S) { | | 298 | static void checkHeader (LoadState *S) { |
297 | /* skip 1st char (already read and checked) */ | | 299 | /* skip 1st char (already read and checked) */ |
298 | checkliteral(S, &LUA_SIGNATURE[1], "not a binary chunk"); | | 300 | checkliteral(S, &LUA_SIGNATURE[1], "not a binary chunk"); |
299 | if (loadByte(S) != LUAC_VERSION) | | 301 | if (loadByte(S) != LUAC_VERSION) |
300 | error(S, "version mismatch"); | | 302 | error(S, "version mismatch"); |
301 | if (loadByte(S) != LUAC_FORMAT) | | 303 | if (loadByte(S) != LUAC_FORMAT) |
302 | error(S, "format mismatch"); | | 304 | error(S, "format mismatch"); |
303 | checkliteral(S, LUAC_DATA, "corrupted chunk"); | | 305 | checkliteral(S, LUAC_DATA, "corrupted chunk"); |
304 | checksize(S, Instruction); | | 306 | checksize(S, Instruction); |
305 | checksize(S, lua_Integer); | | 307 | checksize(S, lua_Integer); |
306 | checksize(S, lua_Number); | | 308 | checksize(S, lua_Number); |
307 | if (loadInteger(S) != LUAC_INT) | | 309 | if (loadInteger(S) != LUAC_INT) |
308 | error(S, "integer format mismatch"); | | 310 | error(S, "integer format mismatch"); |
309 | if (loadNumber(S) != LUAC_NUM) | | 311 | if (loadNumber(S) != LUAC_NUM) |
310 | error(S, "float format mismatch"); | | 312 | error(S, "float format mismatch"); |
311 | } | | 313 | } |
312 | | | 314 | |
313 | | | 315 | |
314 | /* | | 316 | /* |
315 | ** Load precompiled chunk. | | 317 | ** Load precompiled chunk. |
316 | */ | | 318 | */ |
317 | LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { | | 319 | LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { |
318 | LoadState S; | | 320 | LoadState S; |
319 | LClosure *cl; | | 321 | LClosure *cl; |
320 | if (*name == '@' || *name == '=') | | 322 | if (*name == '@' || *name == '=') |
321 | S.name = name + 1; | | 323 | S.name = name + 1; |
322 | else if (*name == LUA_SIGNATURE[0]) | | 324 | else if (*name == LUA_SIGNATURE[0]) |
323 | S.name = "binary string"; | | 325 | S.name = "binary string"; |
324 | else | | 326 | else |
325 | S.name = name; | | 327 | S.name = name; |
326 | S.L = L; | | 328 | S.L = L; |
327 | S.Z = Z; | | 329 | S.Z = Z; |
328 | checkHeader(&S); | | 330 | checkHeader(&S); |
329 | cl = luaF_newLclosure(L, loadByte(&S)); | | 331 | cl = luaF_newLclosure(L, loadByte(&S)); |
330 | setclLvalue2s(L, L->top, cl); | | 332 | setclLvalue2s(L, L->top, cl); |
331 | luaD_inctop(L); | | 333 | luaD_inctop(L); |
332 | cl->p = luaF_newproto(L); | | 334 | cl->p = luaF_newproto(L); |
333 | luaC_objbarrier(L, cl, cl->p); | | 335 | luaC_objbarrier(L, cl, cl->p); |
334 | loadFunction(&S, cl->p, NULL); | | 336 | loadFunction(&S, cl->p, NULL); |
335 | lua_assert(cl->nupvalues == cl->p->sizeupvalues); | | 337 | lua_assert(cl->nupvalues == cl->p->sizeupvalues); |
336 | luai_verifycode(L, cl->p); | | 338 | luai_verifycode(L, cl->p); |
337 | return cl; | | 339 | return cl; |
338 | } | | 340 | } |
339 | | | 341 | |