1 | /* This is a heavily customized and minimized copy of Lua 5.1.5. */ |
2 | /* It's only used to build LuaJIT. It does NOT have all standard functions! */ |
3 | /****************************************************************************** |
4 | * Copyright (C) 1994-2012 Lua.org, PUC-Rio. All rights reserved. |
5 | * |
6 | * Permission is hereby granted, free of charge, to any person obtaining |
7 | * a copy of this software and associated documentation files (the |
8 | * "Software"), to deal in the Software without restriction, including |
9 | * without limitation the rights to use, copy, modify, merge, publish, |
10 | * distribute, sublicense, and/or sell copies of the Software, and to |
11 | * permit persons to whom the Software is furnished to do so, subject to |
12 | * the following conditions: |
13 | * |
14 | * The above copyright notice and this permission notice shall be |
15 | * included in all copies or substantial portions of the Software. |
16 | * |
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
24 | ******************************************************************************/ |
25 | #ifdef _MSC_VER |
26 | typedef unsigned __int64 U64; |
27 | #else |
28 | typedef unsigned long long U64; |
29 | #endif |
30 | int _CRT_glob = 0; |
31 | #include <stddef.h> |
32 | #include <stdarg.h> |
33 | #include <limits.h> |
34 | #include <math.h> |
35 | #include <ctype.h> |
36 | #include <stdio.h> |
37 | #include <stdlib.h> |
38 | #include <string.h> |
39 | #include <setjmp.h> |
40 | #include <errno.h> |
41 | #include <time.h> |
42 | typedef enum{ |
43 | TM_INDEX, |
44 | TM_NEWINDEX, |
45 | TM_GC, |
46 | TM_MODE, |
47 | TM_EQ, |
48 | TM_ADD, |
49 | TM_SUB, |
50 | TM_MUL, |
51 | TM_DIV, |
52 | TM_MOD, |
53 | TM_POW, |
54 | TM_UNM, |
55 | TM_LEN, |
56 | TM_LT, |
57 | TM_LE, |
58 | TM_CONCAT, |
59 | TM_CALL, |
60 | TM_N |
61 | }TMS; |
62 | enum OpMode{iABC,iABx,iAsBx}; |
63 | typedef enum{ |
64 | OP_MOVE, |
65 | OP_LOADK, |
66 | OP_LOADBOOL, |
67 | OP_LOADNIL, |
68 | OP_GETUPVAL, |
69 | OP_GETGLOBAL, |
70 | OP_GETTABLE, |
71 | OP_SETGLOBAL, |
72 | OP_SETUPVAL, |
73 | OP_SETTABLE, |
74 | OP_NEWTABLE, |
75 | OP_SELF, |
76 | OP_ADD, |
77 | OP_SUB, |
78 | OP_MUL, |
79 | OP_DIV, |
80 | OP_MOD, |
81 | OP_POW, |
82 | OP_UNM, |
83 | OP_NOT, |
84 | OP_LEN, |
85 | OP_CONCAT, |
86 | OP_JMP, |
87 | OP_EQ, |
88 | OP_LT, |
89 | OP_LE, |
90 | OP_TEST, |
91 | OP_TESTSET, |
92 | OP_CALL, |
93 | OP_TAILCALL, |
94 | OP_RETURN, |
95 | OP_FORLOOP, |
96 | OP_FORPREP, |
97 | OP_TFORLOOP, |
98 | OP_SETLIST, |
99 | OP_CLOSE, |
100 | OP_CLOSURE, |
101 | OP_VARARG |
102 | }OpCode; |
103 | enum OpArgMask{ |
104 | OpArgN, |
105 | OpArgU, |
106 | OpArgR, |
107 | OpArgK |
108 | }; |
109 | typedef enum{ |
110 | VVOID, |
111 | VNIL, |
112 | VTRUE, |
113 | VFALSE, |
114 | VK, |
115 | VKNUM, |
116 | VLOCAL, |
117 | VUPVAL, |
118 | VGLOBAL, |
119 | VINDEXED, |
120 | VJMP, |
121 | VRELOCABLE, |
122 | VNONRELOC, |
123 | VCALL, |
124 | VVARARG |
125 | }expkind; |
126 | enum RESERVED{ |
127 | TK_AND=257,TK_BREAK, |
128 | TK_DO,TK_ELSE,TK_ELSEIF,TK_END,TK_FALSE,TK_FOR,TK_FUNCTION, |
129 | TK_IF,TK_IN,TK_LOCAL,TK_NIL,TK_NOT,TK_OR,TK_REPEAT, |
130 | TK_RETURN,TK_THEN,TK_TRUE,TK_UNTIL,TK_WHILE, |
131 | TK_CONCAT,TK_DOTS,TK_EQ,TK_GE,TK_LE,TK_NE,TK_NUMBER, |
132 | TK_NAME,TK_STRING,TK_EOS |
133 | }; |
134 | typedef enum BinOpr{ |
135 | OPR_ADD,OPR_SUB,OPR_MUL,OPR_DIV,OPR_MOD,OPR_POW, |
136 | OPR_CONCAT, |
137 | OPR_NE,OPR_EQ, |
138 | OPR_LT,OPR_LE,OPR_GT,OPR_GE, |
139 | OPR_AND,OPR_OR, |
140 | OPR_NOBINOPR |
141 | }BinOpr; |
142 | typedef enum UnOpr{OPR_MINUS,OPR_NOT,OPR_LEN,OPR_NOUNOPR}UnOpr; |
143 | #define LUA_QL(x)"'"x"'" |
144 | #define luai_apicheck(L,o){(void)L;} |
145 | #define lua_number2str(s,n)sprintf((s),"%.14g",(n)) |
146 | #define lua_str2number(s,p)strtod((s),(p)) |
147 | #define luai_numadd(a,b)((a)+(b)) |
148 | #define luai_numsub(a,b)((a)-(b)) |
149 | #define luai_nummul(a,b)((a)*(b)) |
150 | #define luai_numdiv(a,b)((a)/(b)) |
151 | #define luai_nummod(a,b)((a)-floor((a)/(b))*(b)) |
152 | #define luai_numpow(a,b)(pow(a,b)) |
153 | #define luai_numunm(a)(-(a)) |
154 | #define luai_numeq(a,b)((a)==(b)) |
155 | #define luai_numlt(a,b)((a)<(b)) |
156 | #define luai_numle(a,b)((a)<=(b)) |
157 | #define luai_numisnan(a)(!luai_numeq((a),(a))) |
158 | #define lua_number2int(i,d)((i)=(int)(d)) |
159 | #define lua_number2integer(i,d)((i)=(lua_Integer)(d)) |
160 | #define LUAI_THROW(L,c)longjmp((c)->b,1) |
161 | #define LUAI_TRY(L,c,a)if(setjmp((c)->b)==0){a} |
162 | #define lua_pclose(L,file)((void)((void)L,file),0) |
163 | #define lua_upvalueindex(i)((-10002)-(i)) |
164 | typedef struct lua_State lua_State; |
165 | typedef int(*lua_CFunction)(lua_State*L); |
166 | typedef const char*(*lua_Reader)(lua_State*L,void*ud,size_t*sz); |
167 | typedef void*(*lua_Alloc)(void*ud,void*ptr,size_t osize,size_t nsize); |
168 | typedef double lua_Number; |
169 | typedef ptrdiff_t lua_Integer; |
170 | static void lua_settop(lua_State*L,int idx); |
171 | static int lua_type(lua_State*L,int idx); |
172 | static const char* lua_tolstring(lua_State*L,int idx,size_t*len); |
173 | static size_t lua_objlen(lua_State*L,int idx); |
174 | static void lua_pushlstring(lua_State*L,const char*s,size_t l); |
175 | static void lua_pushcclosure(lua_State*L,lua_CFunction fn,int n); |
176 | static void lua_createtable(lua_State*L,int narr,int nrec); |
177 | static void lua_setfield(lua_State*L,int idx,const char*k); |
178 | #define lua_pop(L,n)lua_settop(L,-(n)-1) |
179 | #define lua_newtable(L)lua_createtable(L,0,0) |
180 | #define lua_pushcfunction(L,f)lua_pushcclosure(L,(f),0) |
181 | #define lua_strlen(L,i)lua_objlen(L,(i)) |
182 | #define lua_isfunction(L,n)(lua_type(L,(n))==6) |
183 | #define lua_istable(L,n)(lua_type(L,(n))==5) |
184 | #define lua_isnil(L,n)(lua_type(L,(n))==0) |
185 | #define lua_isboolean(L,n)(lua_type(L,(n))==1) |
186 | #define lua_isnone(L,n)(lua_type(L,(n))==(-1)) |
187 | #define lua_isnoneornil(L,n)(lua_type(L,(n))<=0) |
188 | #define lua_pushliteral(L,s)lua_pushlstring(L,""s,(sizeof(s)/sizeof(char))-1) |
189 | #define lua_setglobal(L,s)lua_setfield(L,(-10002),(s)) |
190 | #define lua_tostring(L,i)lua_tolstring(L,(i),NULL) |
191 | typedef struct lua_Debug lua_Debug; |
192 | typedef void(*lua_Hook)(lua_State*L,lua_Debug*ar); |
193 | struct lua_Debug{ |
194 | int event; |
195 | const char*name; |
196 | const char*namewhat; |
197 | const char*what; |
198 | const char*source; |
199 | int currentline; |
200 | int nups; |
201 | int linedefined; |
202 | int lastlinedefined; |
203 | char short_src[60]; |
204 | int i_ci; |
205 | }; |
206 | typedef unsigned int lu_int32; |
207 | typedef size_t lu_mem; |
208 | typedef ptrdiff_t l_mem; |
209 | typedef unsigned char lu_byte; |
210 | #define IntPoint(p)((unsigned int)(lu_mem)(p)) |
211 | typedef union{double u;void*s;long l;}L_Umaxalign; |
212 | typedef double l_uacNumber; |
213 | #define check_exp(c,e)(e) |
214 | #define UNUSED(x)((void)(x)) |
215 | #define cast(t,exp)((t)(exp)) |
216 | #define cast_byte(i)cast(lu_byte,(i)) |
217 | #define cast_num(i)cast(lua_Number,(i)) |
218 | #define cast_int(i)cast(int,(i)) |
219 | typedef lu_int32 Instruction; |
220 | #define condhardstacktests(x)((void)0) |
221 | typedef union GCObject GCObject; |
222 | typedef struct { |
223 | GCObject*;lu_byte ;lu_byte ; |
224 | }; |
225 | typedef union{ |
226 | GCObject*gc; |
227 | void*p; |
228 | lua_Number n; |
229 | int b; |
230 | }Value; |
231 | typedef struct lua_TValue{ |
232 | Value value;int tt; |
233 | }TValue; |
234 | #define ttisnil(o)(ttype(o)==0) |
235 | #define ttisnumber(o)(ttype(o)==3) |
236 | #define ttisstring(o)(ttype(o)==4) |
237 | #define ttistable(o)(ttype(o)==5) |
238 | #define ttisfunction(o)(ttype(o)==6) |
239 | #define ttisboolean(o)(ttype(o)==1) |
240 | #define ttisuserdata(o)(ttype(o)==7) |
241 | #define ttisthread(o)(ttype(o)==8) |
242 | #define ttislightuserdata(o)(ttype(o)==2) |
243 | #define ttype(o)((o)->tt) |
244 | #define gcvalue(o)check_exp(iscollectable(o),(o)->value.gc) |
245 | #define pvalue(o)check_exp(ttislightuserdata(o),(o)->value.p) |
246 | #define nvalue(o)check_exp(ttisnumber(o),(o)->value.n) |
247 | #define rawtsvalue(o)check_exp(ttisstring(o),&(o)->value.gc->ts) |
248 | #define tsvalue(o)(&rawtsvalue(o)->tsv) |
249 | #define rawuvalue(o)check_exp(ttisuserdata(o),&(o)->value.gc->u) |
250 | #define uvalue(o)(&rawuvalue(o)->uv) |
251 | #define clvalue(o)check_exp(ttisfunction(o),&(o)->value.gc->cl) |
252 | #define hvalue(o)check_exp(ttistable(o),&(o)->value.gc->h) |
253 | #define bvalue(o)check_exp(ttisboolean(o),(o)->value.b) |
254 | #define thvalue(o)check_exp(ttisthread(o),&(o)->value.gc->th) |
255 | #define l_isfalse(o)(ttisnil(o)||(ttisboolean(o)&&bvalue(o)==0)) |
256 | #define checkconsistency(obj) |
257 | #define checkliveness(g,obj) |
258 | #define setnilvalue(obj)((obj)->tt=0) |
259 | #define setnvalue(obj,x){TValue*i_o=(obj);i_o->value.n=(x);i_o->tt=3;} |
260 | #define setbvalue(obj,x){TValue*i_o=(obj);i_o->value.b=(x);i_o->tt=1;} |
261 | #define setsvalue(L,obj,x){TValue*i_o=(obj);i_o->value.gc=cast(GCObject*,(x));i_o->tt=4;checkliveness(G(L),i_o);} |
262 | #define setuvalue(L,obj,x){TValue*i_o=(obj);i_o->value.gc=cast(GCObject*,(x));i_o->tt=7;checkliveness(G(L),i_o);} |
263 | #define setthvalue(L,obj,x){TValue*i_o=(obj);i_o->value.gc=cast(GCObject*,(x));i_o->tt=8;checkliveness(G(L),i_o);} |
264 | #define setclvalue(L,obj,x){TValue*i_o=(obj);i_o->value.gc=cast(GCObject*,(x));i_o->tt=6;checkliveness(G(L),i_o);} |
265 | #define sethvalue(L,obj,x){TValue*i_o=(obj);i_o->value.gc=cast(GCObject*,(x));i_o->tt=5;checkliveness(G(L),i_o);} |
266 | #define setptvalue(L,obj,x){TValue*i_o=(obj);i_o->value.gc=cast(GCObject*,(x));i_o->tt=(8+1);checkliveness(G(L),i_o);} |
267 | #define setobj(L,obj1,obj2){const TValue*o2=(obj2);TValue*o1=(obj1);o1->value=o2->value;o1->tt=o2->tt;checkliveness(G(L),o1);} |
268 | #define setttype(obj,tt)(ttype(obj)=(tt)) |
269 | #define iscollectable(o)(ttype(o)>=4) |
270 | typedef TValue*StkId; |
271 | typedef union TString{ |
272 | L_Umaxalign dummy; |
273 | struct{ |
274 | GCObject*next;lu_byte tt;lu_byte marked; |
275 | lu_byte reserved; |
276 | unsigned int hash; |
277 | size_t len; |
278 | }tsv; |
279 | }TString; |
280 | #define getstr(ts)cast(const char*,(ts)+1) |
281 | #define svalue(o)getstr(rawtsvalue(o)) |
282 | typedef union Udata{ |
283 | L_Umaxalign dummy; |
284 | struct{ |
285 | GCObject*next;lu_byte tt;lu_byte marked; |
286 | struct Table*metatable; |
287 | struct Table*env; |
288 | size_t len; |
289 | }uv; |
290 | }Udata; |
291 | typedef struct Proto{ |
292 | GCObject*next;lu_byte tt;lu_byte marked; |
293 | TValue*k; |
294 | Instruction*code; |
295 | struct Proto**p; |
296 | int*lineinfo; |
297 | struct LocVar*locvars; |
298 | TString**upvalues; |
299 | TString*source; |
300 | int sizeupvalues; |
301 | int sizek; |
302 | int sizecode; |
303 | int sizelineinfo; |
304 | int sizep; |
305 | int sizelocvars; |
306 | int linedefined; |
307 | int lastlinedefined; |
308 | GCObject*gclist; |
309 | lu_byte nups; |
310 | lu_byte numparams; |
311 | lu_byte is_vararg; |
312 | lu_byte maxstacksize; |
313 | }Proto; |
314 | typedef struct LocVar{ |
315 | TString*varname; |
316 | int startpc; |
317 | int endpc; |
318 | }LocVar; |
319 | typedef struct UpVal{ |
320 | GCObject*next;lu_byte tt;lu_byte marked; |
321 | TValue*v; |
322 | union{ |
323 | TValue value; |
324 | struct{ |
325 | struct UpVal*prev; |
326 | struct UpVal*next; |
327 | }l; |
328 | }u; |
329 | }UpVal; |
330 | typedef struct CClosure{ |
331 | GCObject*next;lu_byte tt;lu_byte marked;lu_byte isC;lu_byte nupvalues;GCObject*gclist;struct Table*env; |
332 | lua_CFunction f; |
333 | TValue upvalue[1]; |
334 | }CClosure; |
335 | typedef struct LClosure{ |
336 | GCObject*next;lu_byte tt;lu_byte marked;lu_byte isC;lu_byte nupvalues;GCObject*gclist;struct Table*env; |
337 | struct Proto*p; |
338 | UpVal*upvals[1]; |
339 | }LClosure; |
340 | typedef union Closure{ |
341 | CClosure c; |
342 | LClosure l; |
343 | }Closure; |
344 | #define iscfunction(o)(ttype(o)==6&&clvalue(o)->c.isC) |
345 | typedef union TKey{ |
346 | struct{ |
347 | Value value;int tt; |
348 | struct Node*next; |
349 | }nk; |
350 | TValue tvk; |
351 | }TKey; |
352 | typedef struct Node{ |
353 | TValue i_val; |
354 | TKey i_key; |
355 | }Node; |
356 | typedef struct Table{ |
357 | GCObject*next;lu_byte tt;lu_byte marked; |
358 | lu_byte flags; |
359 | lu_byte lsizenode; |
360 | struct Table*metatable; |
361 | TValue*array; |
362 | Node*node; |
363 | Node*lastfree; |
364 | GCObject*gclist; |
365 | int sizearray; |
366 | }Table; |
367 | #define lmod(s,size)(check_exp((size&(size-1))==0,(cast(int,(s)&((size)-1))))) |
368 | #define twoto(x)((size_t)1<<(x)) |
369 | #define sizenode(t)(twoto((t)->lsizenode)) |
370 | static const TValue luaO_nilobject_; |
371 | #define ceillog2(x)(luaO_log2((x)-1)+1) |
372 | static int luaO_log2(unsigned int x); |
373 | #define gfasttm(g,et,e)((et)==NULL?NULL:((et)->flags&(1u<<(e)))?NULL:luaT_gettm(et,e,(g)->tmname[e])) |
374 | #define fasttm(l,et,e)gfasttm(G(l),et,e) |
375 | static const TValue*luaT_gettm(Table*events,TMS event,TString*ename); |
376 | #define luaM_reallocv(L,b,on,n,e)((cast(size_t,(n)+1)<=((size_t)(~(size_t)0)-2)/(e))?luaM_realloc_(L,(b),(on)*(e),(n)*(e)):luaM_toobig(L)) |
377 | #define luaM_freemem(L,b,s)luaM_realloc_(L,(b),(s),0) |
378 | #define luaM_free(L,b)luaM_realloc_(L,(b),sizeof(*(b)),0) |
379 | #define luaM_freearray(L,b,n,t)luaM_reallocv(L,(b),n,0,sizeof(t)) |
380 | #define luaM_malloc(L,t)luaM_realloc_(L,NULL,0,(t)) |
381 | #define luaM_new(L,t)cast(t*,luaM_malloc(L,sizeof(t))) |
382 | #define luaM_newvector(L,n,t)cast(t*,luaM_reallocv(L,NULL,0,n,sizeof(t))) |
383 | #define luaM_growvector(L,v,nelems,size,t,limit,e)if((nelems)+1>(size))((v)=cast(t*,luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) |
384 | #define luaM_reallocvector(L,v,oldn,n,t)((v)=cast(t*,luaM_reallocv(L,v,oldn,n,sizeof(t)))) |
385 | static void*luaM_realloc_(lua_State*L,void*block,size_t oldsize, |
386 | size_t size); |
387 | static void*luaM_toobig(lua_State*L); |
388 | static void*luaM_growaux_(lua_State*L,void*block,int*size, |
389 | size_t size_elem,int limit, |
390 | const char*errormsg); |
391 | typedef struct Zio ZIO; |
392 | #define char2int(c)cast(int,cast(unsigned char,(c))) |
393 | #define zgetc(z)(((z)->n--)>0?char2int(*(z)->p++):luaZ_fill(z)) |
394 | typedef struct Mbuffer{ |
395 | char*buffer; |
396 | size_t n; |
397 | size_t buffsize; |
398 | }Mbuffer; |
399 | #define luaZ_initbuffer(L,buff)((buff)->buffer=NULL,(buff)->buffsize=0) |
400 | #define luaZ_buffer(buff)((buff)->buffer) |
401 | #define luaZ_sizebuffer(buff)((buff)->buffsize) |
402 | #define luaZ_bufflen(buff)((buff)->n) |
403 | #define luaZ_resetbuffer(buff)((buff)->n=0) |
404 | #define luaZ_resizebuffer(L,buff,size)(luaM_reallocvector(L,(buff)->buffer,(buff)->buffsize,size,char),(buff)->buffsize=size) |
405 | #define luaZ_freebuffer(L,buff)luaZ_resizebuffer(L,buff,0) |
406 | struct Zio{ |
407 | size_t n; |
408 | const char*p; |
409 | lua_Reader reader; |
410 | void*data; |
411 | lua_State*L; |
412 | }; |
413 | static int luaZ_fill(ZIO*z); |
414 | struct lua_longjmp; |
415 | #define gt(L)(&L->l_gt) |
416 | #define registry(L)(&G(L)->l_registry) |
417 | typedef struct stringtable{ |
418 | GCObject**hash; |
419 | lu_int32 nuse; |
420 | int size; |
421 | }stringtable; |
422 | typedef struct CallInfo{ |
423 | StkId base; |
424 | StkId func; |
425 | StkId top; |
426 | const Instruction*savedpc; |
427 | int nresults; |
428 | int tailcalls; |
429 | }CallInfo; |
430 | #define curr_func(L)(clvalue(L->ci->func)) |
431 | #define ci_func(ci)(clvalue((ci)->func)) |
432 | #define f_isLua(ci)(!ci_func(ci)->c.isC) |
433 | #define isLua(ci)(ttisfunction((ci)->func)&&f_isLua(ci)) |
434 | typedef struct global_State{ |
435 | stringtable strt; |
436 | lua_Alloc frealloc; |
437 | void*ud; |
438 | lu_byte currentwhite; |
439 | lu_byte gcstate; |
440 | int sweepstrgc; |
441 | GCObject*rootgc; |
442 | GCObject**sweepgc; |
443 | GCObject*gray; |
444 | GCObject*grayagain; |
445 | GCObject*weak; |
446 | GCObject*tmudata; |
447 | Mbuffer buff; |
448 | lu_mem GCthreshold; |
449 | lu_mem totalbytes; |
450 | lu_mem estimate; |
451 | lu_mem gcdept; |
452 | int gcpause; |
453 | int gcstepmul; |
454 | lua_CFunction panic; |
455 | TValue l_registry; |
456 | struct lua_State*mainthread; |
457 | UpVal uvhead; |
458 | struct Table*mt[(8+1)]; |
459 | TString*tmname[TM_N]; |
460 | }global_State; |
461 | struct lua_State{ |
462 | GCObject*next;lu_byte tt;lu_byte marked; |
463 | lu_byte status; |
464 | StkId top; |
465 | StkId base; |
466 | global_State*l_G; |
467 | CallInfo*ci; |
468 | const Instruction*savedpc; |
469 | StkId stack_last; |
470 | StkId stack; |
471 | CallInfo*end_ci; |
472 | CallInfo*base_ci; |
473 | int stacksize; |
474 | int size_ci; |
475 | unsigned short nCcalls; |
476 | unsigned short baseCcalls; |
477 | lu_byte hookmask; |
478 | lu_byte allowhook; |
479 | int basehookcount; |
480 | int hookcount; |
481 | lua_Hook hook; |
482 | TValue l_gt; |
483 | TValue env; |
484 | GCObject*openupval; |
485 | GCObject*gclist; |
486 | struct lua_longjmp*errorJmp; |
487 | ptrdiff_t errfunc; |
488 | }; |
489 | #define G(L)(L->l_G) |
490 | union GCObject{ |
491 | GCheader gch; |
492 | union TString ts; |
493 | union Udata u; |
494 | union Closure cl; |
495 | struct Table h; |
496 | struct Proto p; |
497 | struct UpVal uv; |
498 | struct lua_State th; |
499 | }; |
500 | #define rawgco2ts(o)check_exp((o)->gch.tt==4,&((o)->ts)) |
501 | #define gco2ts(o)(&rawgco2ts(o)->tsv) |
502 | #define rawgco2u(o)check_exp((o)->gch.tt==7,&((o)->u)) |
503 | #define gco2u(o)(&rawgco2u(o)->uv) |
504 | #define gco2cl(o)check_exp((o)->gch.tt==6,&((o)->cl)) |
505 | #define gco2h(o)check_exp((o)->gch.tt==5,&((o)->h)) |
506 | #define gco2p(o)check_exp((o)->gch.tt==(8+1),&((o)->p)) |
507 | #define gco2uv(o)check_exp((o)->gch.tt==(8+2),&((o)->uv)) |
508 | #define ngcotouv(o)check_exp((o)==NULL||(o)->gch.tt==(8+2),&((o)->uv)) |
509 | #define gco2th(o)check_exp((o)->gch.tt==8,&((o)->th)) |
510 | #define obj2gco(v)(cast(GCObject*,(v))) |
511 | static void luaE_freethread(lua_State*L,lua_State*L1); |
512 | #define pcRel(pc,p)(cast(int,(pc)-(p)->code)-1) |
513 | #define getline_(f,pc)(((f)->lineinfo)?(f)->lineinfo[pc]:0) |
514 | #define resethookcount(L)(L->hookcount=L->basehookcount) |
515 | static void luaG_typeerror(lua_State*L,const TValue*o, |
516 | const char*opname); |
517 | static void luaG_runerror(lua_State*L,const char*fmt,...); |
518 | #define luaD_checkstack(L,n)if((char*)L->stack_last-(char*)L->top<=(n)*(int)sizeof(TValue))luaD_growstack(L,n);else condhardstacktests(luaD_reallocstack(L,L->stacksize-5-1)); |
519 | #define incr_top(L){luaD_checkstack(L,1);L->top++;} |
520 | #define savestack(L,p)((char*)(p)-(char*)L->stack) |
521 | #define restorestack(L,n)((TValue*)((char*)L->stack+(n))) |
522 | #define saveci(L,p)((char*)(p)-(char*)L->base_ci) |
523 | #define restoreci(L,n)((CallInfo*)((char*)L->base_ci+(n))) |
524 | typedef void(*Pfunc)(lua_State*L,void*ud); |
525 | static int luaD_poscall(lua_State*L,StkId firstResult); |
526 | static void luaD_reallocCI(lua_State*L,int newsize); |
527 | static void luaD_reallocstack(lua_State*L,int newsize); |
528 | static void luaD_growstack(lua_State*L,int n); |
529 | static void luaD_throw(lua_State*L,int errcode); |
530 | static void*luaM_growaux_(lua_State*L,void*block,int*size,size_t size_elems, |
531 | int limit,const char*errormsg){ |
532 | void*newblock; |
533 | int newsize; |
534 | if(*size>=limit/2){ |
535 | if(*size>=limit) |
536 | luaG_runerror(L,errormsg); |
537 | newsize=limit; |
538 | } |
539 | else{ |
540 | newsize=(*size)*2; |
541 | if(newsize<4) |
542 | newsize=4; |
543 | } |
544 | newblock=luaM_reallocv(L,block,*size,newsize,size_elems); |
545 | *size=newsize; |
546 | return newblock; |
547 | } |
548 | static void*luaM_toobig(lua_State*L){ |
549 | luaG_runerror(L,"memory allocation error: block too big" ); |
550 | return NULL; |
551 | } |
552 | static void*luaM_realloc_(lua_State*L,void*block,size_t osize,size_t nsize){ |
553 | global_State*g=G(L); |
554 | block=(*g->frealloc)(g->ud,block,osize,nsize); |
555 | if(block==NULL&&nsize>0) |
556 | luaD_throw(L,4); |
557 | g->totalbytes=(g->totalbytes-osize)+nsize; |
558 | return block; |
559 | } |
560 | #define resetbits(x,m)((x)&=cast(lu_byte,~(m))) |
561 | #define setbits(x,m)((x)|=(m)) |
562 | #define testbits(x,m)((x)&(m)) |
563 | #define bitmask(b)(1<<(b)) |
564 | #define bit2mask(b1,b2)(bitmask(b1)|bitmask(b2)) |
565 | #define l_setbit(x,b)setbits(x,bitmask(b)) |
566 | #define resetbit(x,b)resetbits(x,bitmask(b)) |
567 | #define testbit(x,b)testbits(x,bitmask(b)) |
568 | #define set2bits(x,b1,b2)setbits(x,(bit2mask(b1,b2))) |
569 | #define reset2bits(x,b1,b2)resetbits(x,(bit2mask(b1,b2))) |
570 | #define test2bits(x,b1,b2)testbits(x,(bit2mask(b1,b2))) |
571 | #define iswhite(x)test2bits((x)->gch.marked,0,1) |
572 | #define isblack(x)testbit((x)->gch.marked,2) |
573 | #define isgray(x)(!isblack(x)&&!iswhite(x)) |
574 | #define otherwhite(g)(g->currentwhite^bit2mask(0,1)) |
575 | #define isdead(g,v)((v)->gch.marked&otherwhite(g)&bit2mask(0,1)) |
576 | #define changewhite(x)((x)->gch.marked^=bit2mask(0,1)) |
577 | #define gray2black(x)l_setbit((x)->gch.marked,2) |
578 | #define valiswhite(x)(iscollectable(x)&&iswhite(gcvalue(x))) |
579 | #define luaC_white(g)cast(lu_byte,(g)->currentwhite&bit2mask(0,1)) |
580 | #define luaC_checkGC(L){condhardstacktests(luaD_reallocstack(L,L->stacksize-5-1));if(G(L)->totalbytes>=G(L)->GCthreshold)luaC_step(L);} |
581 | #define luaC_barrier(L,p,v){if(valiswhite(v)&&isblack(obj2gco(p)))luaC_barrierf(L,obj2gco(p),gcvalue(v));} |
582 | #define luaC_barriert(L,t,v){if(valiswhite(v)&&isblack(obj2gco(t)))luaC_barrierback(L,t);} |
583 | #define luaC_objbarrier(L,p,o){if(iswhite(obj2gco(o))&&isblack(obj2gco(p)))luaC_barrierf(L,obj2gco(p),obj2gco(o));} |
584 | #define luaC_objbarriert(L,t,o){if(iswhite(obj2gco(o))&&isblack(obj2gco(t)))luaC_barrierback(L,t);} |
585 | static void luaC_step(lua_State*L); |
586 | static void luaC_link(lua_State*L,GCObject*o,lu_byte tt); |
587 | static void luaC_linkupval(lua_State*L,UpVal*uv); |
588 | static void luaC_barrierf(lua_State*L,GCObject*o,GCObject*v); |
589 | static void luaC_barrierback(lua_State*L,Table*t); |
590 | #define sizestring(s)(sizeof(union TString)+((s)->len+1)*sizeof(char)) |
591 | #define sizeudata(u)(sizeof(union Udata)+(u)->len) |
592 | #define luaS_new(L,s)(luaS_newlstr(L,s,strlen(s))) |
593 | #define luaS_newliteral(L,s)(luaS_newlstr(L,""s,(sizeof(s)/sizeof(char))-1)) |
594 | #define luaS_fix(s)l_setbit((s)->tsv.marked,5) |
595 | static TString*luaS_newlstr(lua_State*L,const char*str,size_t l); |
596 | #define tostring(L,o)((ttype(o)==4)||(luaV_tostring(L,o))) |
597 | #define tonumber(o,n)(ttype(o)==3||(((o)=luaV_tonumber(o,n))!=NULL)) |
598 | #define equalobj(L,o1,o2)(ttype(o1)==ttype(o2)&&luaV_equalval(L,o1,o2)) |
599 | static int luaV_equalval(lua_State*L,const TValue*t1,const TValue*t2); |
600 | static const TValue*luaV_tonumber(const TValue*obj,TValue*n); |
601 | static int luaV_tostring(lua_State*L,StkId obj); |
602 | static void luaV_execute(lua_State*L,int nexeccalls); |
603 | static void luaV_concat(lua_State*L,int total,int last); |
604 | static const TValue luaO_nilobject_={{NULL},0}; |
605 | static int luaO_int2fb(unsigned int x){ |
606 | int e=0; |
607 | while(x>=16){ |
608 | x=(x+1)>>1; |
609 | e++; |
610 | } |
611 | if(x<8)return x; |
612 | else return((e+1)<<3)|(cast_int(x)-8); |
613 | } |
614 | static int luaO_fb2int(int x){ |
615 | int e=(x>>3)&31; |
616 | if(e==0)return x; |
617 | else return((x&7)+8)<<(e-1); |
618 | } |
619 | static int luaO_log2(unsigned int x){ |
620 | static const lu_byte log_2[256]={ |
621 | 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, |
622 | 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, |
623 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, |
624 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, |
625 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, |
626 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, |
627 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, |
628 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 |
629 | }; |
630 | int l=-1; |
631 | while(x>=256){l+=8;x>>=8;} |
632 | return l+log_2[x]; |
633 | } |
634 | static int luaO_rawequalObj(const TValue*t1,const TValue*t2){ |
635 | if(ttype(t1)!=ttype(t2))return 0; |
636 | else switch(ttype(t1)){ |
637 | case 0: |
638 | return 1; |
639 | case 3: |
640 | return luai_numeq(nvalue(t1),nvalue(t2)); |
641 | case 1: |
642 | return bvalue(t1)==bvalue(t2); |
643 | case 2: |
644 | return pvalue(t1)==pvalue(t2); |
645 | default: |
646 | return gcvalue(t1)==gcvalue(t2); |
647 | } |
648 | } |
649 | static int luaO_str2d(const char*s,lua_Number*result){ |
650 | char*endptr; |
651 | *result=lua_str2number(s,&endptr); |
652 | if(endptr==s)return 0; |
653 | if(*endptr=='x'||*endptr=='X') |
654 | *result=cast_num(strtoul(s,&endptr,16)); |
655 | if(*endptr=='\0')return 1; |
656 | while(isspace(cast(unsigned char,*endptr)))endptr++; |
657 | if(*endptr!='\0')return 0; |
658 | return 1; |
659 | } |
660 | static void pushstr(lua_State*L,const char*str){ |
661 | setsvalue(L,L->top,luaS_new(L,str)); |
662 | incr_top(L); |
663 | } |
664 | static const char*luaO_pushvfstring(lua_State*L,const char*fmt,va_list argp){ |
665 | int n=1; |
666 | pushstr(L,"" ); |
667 | for(;;){ |
668 | const char*e=strchr(fmt,'%'); |
669 | if(e==NULL)break; |
670 | setsvalue(L,L->top,luaS_newlstr(L,fmt,e-fmt)); |
671 | incr_top(L); |
672 | switch(*(e+1)){ |
673 | case's':{ |
674 | const char*s=va_arg(argp,char*); |
675 | if(s==NULL)s="(null)" ; |
676 | pushstr(L,s); |
677 | break; |
678 | } |
679 | case'c':{ |
680 | char buff[2]; |
681 | buff[0]=cast(char,va_arg(argp,int)); |
682 | buff[1]='\0'; |
683 | pushstr(L,buff); |
684 | break; |
685 | } |
686 | case'd':{ |
687 | setnvalue(L->top,cast_num(va_arg(argp,int))); |
688 | incr_top(L); |
689 | break; |
690 | } |
691 | case'f':{ |
692 | setnvalue(L->top,cast_num(va_arg(argp,l_uacNumber))); |
693 | incr_top(L); |
694 | break; |
695 | } |
696 | case'p':{ |
697 | char buff[4*sizeof(void*)+8]; |
698 | sprintf(buff,"%p" ,va_arg(argp,void*)); |
699 | pushstr(L,buff); |
700 | break; |
701 | } |
702 | case'%':{ |
703 | pushstr(L,"%" ); |
704 | break; |
705 | } |
706 | default:{ |
707 | char buff[3]; |
708 | buff[0]='%'; |
709 | buff[1]=*(e+1); |
710 | buff[2]='\0'; |
711 | pushstr(L,buff); |
712 | break; |
713 | } |
714 | } |
715 | n+=2; |
716 | fmt=e+2; |
717 | } |
718 | pushstr(L,fmt); |
719 | luaV_concat(L,n+1,cast_int(L->top-L->base)-1); |
720 | L->top-=n; |
721 | return svalue(L->top-1); |
722 | } |
723 | static const char*luaO_pushfstring(lua_State*L,const char*fmt,...){ |
724 | const char*msg; |
725 | va_list argp; |
726 | va_start(argp,fmt); |
727 | msg=luaO_pushvfstring(L,fmt,argp); |
728 | va_end(argp); |
729 | return msg; |
730 | } |
731 | static void luaO_chunkid(char*out,const char*source,size_t bufflen){ |
732 | if(*source=='='){ |
733 | strncpy(out,source+1,bufflen); |
734 | out[bufflen-1]='\0'; |
735 | } |
736 | else{ |
737 | if(*source=='@'){ |
738 | size_t l; |
739 | source++; |
740 | bufflen-=sizeof(" '...' " ); |
741 | l=strlen(source); |
742 | strcpy(out,"" ); |
743 | if(l>bufflen){ |
744 | source+=(l-bufflen); |
745 | strcat(out,"..." ); |
746 | } |
747 | strcat(out,source); |
748 | } |
749 | else{ |
750 | size_t len=strcspn(source,"\n\r" ); |
751 | bufflen-=sizeof(" [string \"...\"] " ); |
752 | if(len>bufflen)len=bufflen; |
753 | strcpy(out,"[string \"" ); |
754 | if(source[len]!='\0'){ |
755 | strncat(out,source,len); |
756 | strcat(out,"..." ); |
757 | } |
758 | else |
759 | strcat(out,source); |
760 | strcat(out,"\"]" ); |
761 | } |
762 | } |
763 | } |
764 | #define gnode(t,i)(&(t)->node[i]) |
765 | #define gkey(n)(&(n)->i_key.nk) |
766 | #define gval(n)(&(n)->i_val) |
767 | #define gnext(n)((n)->i_key.nk.next) |
768 | #define key2tval(n)(&(n)->i_key.tvk) |
769 | static TValue*luaH_setnum(lua_State*L,Table*t,int key); |
770 | static const TValue*luaH_getstr(Table*t,TString*key); |
771 | static TValue*luaH_set(lua_State*L,Table*t,const TValue*key); |
772 | static const char*const luaT_typenames[]={ |
773 | "nil" ,"boolean" ,"userdata" ,"number" , |
774 | "string" ,"table" ,"function" ,"userdata" ,"thread" , |
775 | "proto" ,"upval" |
776 | }; |
777 | static void luaT_init(lua_State*L){ |
778 | static const char*const luaT_eventname[]={ |
779 | "__index" ,"__newindex" , |
780 | "__gc" ,"__mode" ,"__eq" , |
781 | "__add" ,"__sub" ,"__mul" ,"__div" ,"__mod" , |
782 | "__pow" ,"__unm" ,"__len" ,"__lt" ,"__le" , |
783 | "__concat" ,"__call" |
784 | }; |
785 | int i; |
786 | for(i=0;i<TM_N;i++){ |
787 | G(L)->tmname[i]=luaS_new(L,luaT_eventname[i]); |
788 | luaS_fix(G(L)->tmname[i]); |
789 | } |
790 | } |
791 | static const TValue*luaT_gettm(Table*events,TMS event,TString*ename){ |
792 | const TValue*tm=luaH_getstr(events,ename); |
793 | if(ttisnil(tm)){ |
794 | events->flags|=cast_byte(1u<<event); |
795 | return NULL; |
796 | } |
797 | else return tm; |
798 | } |
799 | static const TValue*luaT_gettmbyobj(lua_State*L,const TValue*o,TMS event){ |
800 | Table*mt; |
801 | switch(ttype(o)){ |
802 | case 5: |
803 | mt=hvalue(o)->metatable; |
804 | break; |
805 | case 7: |
806 | mt=uvalue(o)->metatable; |
807 | break; |
808 | default: |
809 | mt=G(L)->mt[ttype(o)]; |
810 | } |
811 | return(mt?luaH_getstr(mt,G(L)->tmname[event]):(&luaO_nilobject_)); |
812 | } |
813 | #define sizeCclosure(n)(cast(int,sizeof(CClosure))+cast(int,sizeof(TValue)*((n)-1))) |
814 | #define sizeLclosure(n)(cast(int,sizeof(LClosure))+cast(int,sizeof(TValue*)*((n)-1))) |
815 | static Closure*luaF_newCclosure(lua_State*L,int nelems,Table*e){ |
816 | Closure*c=cast(Closure*,luaM_malloc(L,sizeCclosure(nelems))); |
817 | luaC_link(L,obj2gco(c),6); |
818 | c->c.isC=1; |
819 | c->c.env=e; |
820 | c->c.nupvalues=cast_byte(nelems); |
821 | return c; |
822 | } |
823 | static Closure*luaF_newLclosure(lua_State*L,int nelems,Table*e){ |
824 | Closure*c=cast(Closure*,luaM_malloc(L,sizeLclosure(nelems))); |
825 | luaC_link(L,obj2gco(c),6); |
826 | c->l.isC=0; |
827 | c->l.env=e; |
828 | c->l.nupvalues=cast_byte(nelems); |
829 | while(nelems--)c->l.upvals[nelems]=NULL; |
830 | return c; |
831 | } |
832 | static UpVal*luaF_newupval(lua_State*L){ |
833 | UpVal*uv=luaM_new(L,UpVal); |
834 | luaC_link(L,obj2gco(uv),(8+2)); |
835 | uv->v=&uv->u.value; |
836 | setnilvalue(uv->v); |
837 | return uv; |
838 | } |
839 | static UpVal*luaF_findupval(lua_State*L,StkId level){ |
840 | global_State*g=G(L); |
841 | GCObject**pp=&L->openupval; |
842 | UpVal*p; |
843 | UpVal*uv; |
844 | while(*pp!=NULL&&(p=ngcotouv(*pp))->v>=level){ |
845 | if(p->v==level){ |
846 | if(isdead(g,obj2gco(p))) |
847 | changewhite(obj2gco(p)); |
848 | return p; |
849 | } |
850 | pp=&p->next; |
851 | } |
852 | uv=luaM_new(L,UpVal); |
853 | uv->tt=(8+2); |
854 | uv->marked=luaC_white(g); |
855 | uv->v=level; |
856 | uv->next=*pp; |
857 | *pp=obj2gco(uv); |
858 | uv->u.l.prev=&g->uvhead; |
859 | uv->u.l.next=g->uvhead.u.l.next; |
860 | uv->u.l.next->u.l.prev=uv; |
861 | g->uvhead.u.l.next=uv; |
862 | return uv; |
863 | } |
864 | static void unlinkupval(UpVal*uv){ |
865 | uv->u.l.next->u.l.prev=uv->u.l.prev; |
866 | uv->u.l.prev->u.l.next=uv->u.l.next; |
867 | } |
868 | static void luaF_freeupval(lua_State*L,UpVal*uv){ |
869 | if(uv->v!=&uv->u.value) |
870 | unlinkupval(uv); |
871 | luaM_free(L,uv); |
872 | } |
873 | static void luaF_close(lua_State*L,StkId level){ |
874 | UpVal*uv; |
875 | global_State*g=G(L); |
876 | while(L->openupval!=NULL&&(uv=ngcotouv(L->openupval))->v>=level){ |
877 | GCObject*o=obj2gco(uv); |
878 | L->openupval=uv->next; |
879 | if(isdead(g,o)) |
880 | luaF_freeupval(L,uv); |
881 | else{ |
882 | unlinkupval(uv); |
883 | setobj(L,&uv->u.value,uv->v); |
884 | uv->v=&uv->u.value; |
885 | luaC_linkupval(L,uv); |
886 | } |
887 | } |
888 | } |
889 | static Proto*luaF_newproto(lua_State*L){ |
890 | Proto*f=luaM_new(L,Proto); |
891 | luaC_link(L,obj2gco(f),(8+1)); |
892 | f->k=NULL; |
893 | f->sizek=0; |
894 | f->p=NULL; |
895 | f->sizep=0; |
896 | f->code=NULL; |
897 | f->sizecode=0; |
898 | f->sizelineinfo=0; |
899 | f->sizeupvalues=0; |
900 | f->nups=0; |
901 | f->upvalues=NULL; |
902 | f->numparams=0; |
903 | f->is_vararg=0; |
904 | f->maxstacksize=0; |
905 | f->lineinfo=NULL; |
906 | f->sizelocvars=0; |
907 | f->locvars=NULL; |
908 | f->linedefined=0; |
909 | f->lastlinedefined=0; |
910 | f->source=NULL; |
911 | return f; |
912 | } |
913 | static void luaF_freeproto(lua_State*L,Proto*f){ |
914 | luaM_freearray(L,f->code,f->sizecode,Instruction); |
915 | luaM_freearray(L,f->p,f->sizep,Proto*); |
916 | luaM_freearray(L,f->k,f->sizek,TValue); |
917 | luaM_freearray(L,f->lineinfo,f->sizelineinfo,int); |
918 | luaM_freearray(L,f->locvars,f->sizelocvars,struct LocVar); |
919 | luaM_freearray(L,f->upvalues,f->sizeupvalues,TString*); |
920 | luaM_free(L,f); |
921 | } |
922 | static void luaF_freeclosure(lua_State*L,Closure*c){ |
923 | int size=(c->c.isC)?sizeCclosure(c->c.nupvalues): |
924 | sizeLclosure(c->l.nupvalues); |
925 | luaM_freemem(L,c,size); |
926 | } |
927 | #define MASK1(n,p)((~((~(Instruction)0)<<n))<<p) |
928 | #define MASK0(n,p)(~MASK1(n,p)) |
929 | #define GET_OPCODE(i)(cast(OpCode,((i)>>0)&MASK1(6,0))) |
930 | #define SET_OPCODE(i,o)((i)=(((i)&MASK0(6,0))|((cast(Instruction,o)<<0)&MASK1(6,0)))) |
931 | #define GETARG_A(i)(cast(int,((i)>>(0+6))&MASK1(8,0))) |
932 | #define SETARG_A(i,u)((i)=(((i)&MASK0(8,(0+6)))|((cast(Instruction,u)<<(0+6))&MASK1(8,(0+6))))) |
933 | #define GETARG_B(i)(cast(int,((i)>>(((0+6)+8)+9))&MASK1(9,0))) |
934 | #define SETARG_B(i,b)((i)=(((i)&MASK0(9,(((0+6)+8)+9)))|((cast(Instruction,b)<<(((0+6)+8)+9))&MASK1(9,(((0+6)+8)+9))))) |
935 | #define GETARG_C(i)(cast(int,((i)>>((0+6)+8))&MASK1(9,0))) |
936 | #define SETARG_C(i,b)((i)=(((i)&MASK0(9,((0+6)+8)))|((cast(Instruction,b)<<((0+6)+8))&MASK1(9,((0+6)+8))))) |
937 | #define GETARG_Bx(i)(cast(int,((i)>>((0+6)+8))&MASK1((9+9),0))) |
938 | #define SETARG_Bx(i,b)((i)=(((i)&MASK0((9+9),((0+6)+8)))|((cast(Instruction,b)<<((0+6)+8))&MASK1((9+9),((0+6)+8))))) |
939 | #define GETARG_sBx(i)(GETARG_Bx(i)-(((1<<(9+9))-1)>>1)) |
940 | #define SETARG_sBx(i,b)SETARG_Bx((i),cast(unsigned int,(b)+(((1<<(9+9))-1)>>1))) |
941 | #define CREATE_ABC(o,a,b,c)((cast(Instruction,o)<<0)|(cast(Instruction,a)<<(0+6))|(cast(Instruction,b)<<(((0+6)+8)+9))|(cast(Instruction,c)<<((0+6)+8))) |
942 | #define CREATE_ABx(o,a,bc)((cast(Instruction,o)<<0)|(cast(Instruction,a)<<(0+6))|(cast(Instruction,bc)<<((0+6)+8))) |
943 | #define ISK(x)((x)&(1<<(9-1))) |
944 | #define INDEXK(r)((int)(r)&~(1<<(9-1))) |
945 | #define RKASK(x)((x)|(1<<(9-1))) |
946 | static const lu_byte luaP_opmodes[(cast(int,OP_VARARG)+1)]; |
947 | #define getBMode(m)(cast(enum OpArgMask,(luaP_opmodes[m]>>4)&3)) |
948 | #define getCMode(m)(cast(enum OpArgMask,(luaP_opmodes[m]>>2)&3)) |
949 | #define testTMode(m)(luaP_opmodes[m]&(1<<7)) |
950 | typedef struct expdesc{ |
951 | expkind k; |
952 | union{ |
953 | struct{int info,aux;}s; |
954 | lua_Number nval; |
955 | }u; |
956 | int t; |
957 | int f; |
958 | }expdesc; |
959 | typedef struct upvaldesc{ |
960 | lu_byte k; |
961 | lu_byte info; |
962 | }upvaldesc; |
963 | struct BlockCnt; |
964 | typedef struct FuncState{ |
965 | Proto*f; |
966 | Table*h; |
967 | struct FuncState*prev; |
968 | struct LexState*ls; |
969 | struct lua_State*L; |
970 | struct BlockCnt*bl; |
971 | int pc; |
972 | int lasttarget; |
973 | int jpc; |
974 | int freereg; |
975 | int nk; |
976 | int np; |
977 | short nlocvars; |
978 | lu_byte nactvar; |
979 | upvaldesc upvalues[60]; |
980 | unsigned short actvar[200]; |
981 | }FuncState; |
982 | static Proto*luaY_parser(lua_State*L,ZIO*z,Mbuffer*buff, |
983 | const char*name); |
984 | struct lua_longjmp{ |
985 | struct lua_longjmp*previous; |
986 | jmp_buf b; |
987 | volatile int status; |
988 | }; |
989 | static void luaD_seterrorobj(lua_State*L,int errcode,StkId oldtop){ |
990 | switch(errcode){ |
991 | case 4:{ |
992 | setsvalue(L,oldtop,luaS_newliteral(L,"not enough memory" )); |
993 | break; |
994 | } |
995 | case 5:{ |
996 | setsvalue(L,oldtop,luaS_newliteral(L,"error in error handling" )); |
997 | break; |
998 | } |
999 | case 3: |
1000 | case 2:{ |
1001 | setobj(L,oldtop,L->top-1); |
1002 | break; |
1003 | } |
1004 | } |
1005 | L->top=oldtop+1; |
1006 | } |
1007 | static void restore_stack_limit(lua_State*L){ |
1008 | if(L->size_ci>20000){ |
1009 | int inuse=cast_int(L->ci-L->base_ci); |
1010 | if(inuse+1<20000) |
1011 | luaD_reallocCI(L,20000); |
1012 | } |
1013 | } |
1014 | static void resetstack(lua_State*L,int status){ |
1015 | L->ci=L->base_ci; |
1016 | L->base=L->ci->base; |
1017 | luaF_close(L,L->base); |
1018 | luaD_seterrorobj(L,status,L->base); |
1019 | L->nCcalls=L->baseCcalls; |
1020 | L->allowhook=1; |
1021 | restore_stack_limit(L); |
1022 | L->errfunc=0; |
1023 | L->errorJmp=NULL; |
1024 | } |
1025 | static void luaD_throw(lua_State*L,int errcode){ |
1026 | if(L->errorJmp){ |
1027 | L->errorJmp->status=errcode; |
1028 | LUAI_THROW(L,L->errorJmp); |
1029 | } |
1030 | else{ |
1031 | L->status=cast_byte(errcode); |
1032 | if(G(L)->panic){ |
1033 | resetstack(L,errcode); |
1034 | G(L)->panic(L); |
1035 | } |
1036 | exit(EXIT_FAILURE); |
1037 | } |
1038 | } |
1039 | static int luaD_rawrunprotected(lua_State*L,Pfunc f,void*ud){ |
1040 | struct lua_longjmp lj; |
1041 | lj.status=0; |
1042 | lj.previous=L->errorJmp; |
1043 | L->errorJmp=&lj; |
1044 | LUAI_TRY(L,&lj, |
1045 | (*f)(L,ud); |
1046 | ); |
1047 | L->errorJmp=lj.previous; |
1048 | return lj.status; |
1049 | } |
1050 | static void correctstack(lua_State*L,TValue*oldstack){ |
1051 | CallInfo*ci; |
1052 | GCObject*up; |
1053 | L->top=(L->top-oldstack)+L->stack; |
1054 | for(up=L->openupval;up!=NULL;up=up->gch.next) |
1055 | gco2uv(up)->v=(gco2uv(up)->v-oldstack)+L->stack; |
1056 | for(ci=L->base_ci;ci<=L->ci;ci++){ |
1057 | ci->top=(ci->top-oldstack)+L->stack; |
1058 | ci->base=(ci->base-oldstack)+L->stack; |
1059 | ci->func=(ci->func-oldstack)+L->stack; |
1060 | } |
1061 | L->base=(L->base-oldstack)+L->stack; |
1062 | } |
1063 | static void luaD_reallocstack(lua_State*L,int newsize){ |
1064 | TValue*oldstack=L->stack; |
1065 | int realsize=newsize+1+5; |
1066 | luaM_reallocvector(L,L->stack,L->stacksize,realsize,TValue); |
1067 | L->stacksize=realsize; |
1068 | L->stack_last=L->stack+newsize; |
1069 | correctstack(L,oldstack); |
1070 | } |
1071 | static void luaD_reallocCI(lua_State*L,int newsize){ |
1072 | CallInfo*oldci=L->base_ci; |
1073 | luaM_reallocvector(L,L->base_ci,L->size_ci,newsize,CallInfo); |
1074 | L->size_ci=newsize; |
1075 | L->ci=(L->ci-oldci)+L->base_ci; |
1076 | L->end_ci=L->base_ci+L->size_ci-1; |
1077 | } |
1078 | static void luaD_growstack(lua_State*L,int n){ |
1079 | if(n<=L->stacksize) |
1080 | luaD_reallocstack(L,2*L->stacksize); |
1081 | else |
1082 | luaD_reallocstack(L,L->stacksize+n); |
1083 | } |
1084 | static CallInfo*growCI(lua_State*L){ |
1085 | if(L->size_ci>20000) |
1086 | luaD_throw(L,5); |
1087 | else{ |
1088 | luaD_reallocCI(L,2*L->size_ci); |
1089 | if(L->size_ci>20000) |
1090 | luaG_runerror(L,"stack overflow" ); |
1091 | } |
1092 | return++L->ci; |
1093 | } |
1094 | static StkId adjust_varargs(lua_State*L,Proto*p,int actual){ |
1095 | int i; |
1096 | int nfixargs=p->numparams; |
1097 | Table*htab=NULL; |
1098 | StkId base,fixed; |
1099 | for(;actual<nfixargs;++actual) |
1100 | setnilvalue(L->top++); |
1101 | fixed=L->top-actual; |
1102 | base=L->top; |
1103 | for(i=0;i<nfixargs;i++){ |
1104 | setobj(L,L->top++,fixed+i); |
1105 | setnilvalue(fixed+i); |
1106 | } |
1107 | if(htab){ |
1108 | sethvalue(L,L->top++,htab); |
1109 | } |
1110 | return base; |
1111 | } |
1112 | static StkId tryfuncTM(lua_State*L,StkId func){ |
1113 | const TValue*tm=luaT_gettmbyobj(L,func,TM_CALL); |
1114 | StkId p; |
1115 | ptrdiff_t funcr=savestack(L,func); |
1116 | if(!ttisfunction(tm)) |
1117 | luaG_typeerror(L,func,"call" ); |
1118 | for(p=L->top;p>func;p--)setobj(L,p,p-1); |
1119 | incr_top(L); |
1120 | func=restorestack(L,funcr); |
1121 | setobj(L,func,tm); |
1122 | return func; |
1123 | } |
1124 | #define inc_ci(L)((L->ci==L->end_ci)?growCI(L):(condhardstacktests(luaD_reallocCI(L,L->size_ci)),++L->ci)) |
1125 | static int luaD_precall(lua_State*L,StkId func,int nresults){ |
1126 | LClosure*cl; |
1127 | ptrdiff_t funcr; |
1128 | if(!ttisfunction(func)) |
1129 | func=tryfuncTM(L,func); |
1130 | funcr=savestack(L,func); |
1131 | cl=&clvalue(func)->l; |
1132 | L->ci->savedpc=L->savedpc; |
1133 | if(!cl->isC){ |
1134 | CallInfo*ci; |
1135 | StkId st,base; |
1136 | Proto*p=cl->p; |
1137 | luaD_checkstack(L,p->maxstacksize); |
1138 | func=restorestack(L,funcr); |
1139 | if(!p->is_vararg){ |
1140 | base=func+1; |
1141 | if(L->top>base+p->numparams) |
1142 | L->top=base+p->numparams; |
1143 | } |
1144 | else{ |
1145 | int nargs=cast_int(L->top-func)-1; |
1146 | base=adjust_varargs(L,p,nargs); |
1147 | func=restorestack(L,funcr); |
1148 | } |
1149 | ci=inc_ci(L); |
1150 | ci->func=func; |
1151 | L->base=ci->base=base; |
1152 | ci->top=L->base+p->maxstacksize; |
1153 | L->savedpc=p->code; |
1154 | ci->tailcalls=0; |
1155 | ci->nresults=nresults; |
1156 | for(st=L->top;st<ci->top;st++) |
1157 | setnilvalue(st); |
1158 | L->top=ci->top; |
1159 | return 0; |
1160 | } |
1161 | else{ |
1162 | CallInfo*ci; |
1163 | int n; |
1164 | luaD_checkstack(L,20); |
1165 | ci=inc_ci(L); |
1166 | ci->func=restorestack(L,funcr); |
1167 | L->base=ci->base=ci->func+1; |
1168 | ci->top=L->top+20; |
1169 | ci->nresults=nresults; |
1170 | n=(*curr_func(L)->c.f)(L); |
1171 | if(n<0) |
1172 | return 2; |
1173 | else{ |
1174 | luaD_poscall(L,L->top-n); |
1175 | return 1; |
1176 | } |
1177 | } |
1178 | } |
1179 | static int luaD_poscall(lua_State*L,StkId firstResult){ |
1180 | StkId res; |
1181 | int wanted,i; |
1182 | CallInfo*ci; |
1183 | ci=L->ci--; |
1184 | res=ci->func; |
1185 | wanted=ci->nresults; |
1186 | L->base=(ci-1)->base; |
1187 | L->savedpc=(ci-1)->savedpc; |
1188 | for(i=wanted;i!=0&&firstResult<L->top;i--) |
1189 | setobj(L,res++,firstResult++); |
1190 | while(i-->0) |
1191 | setnilvalue(res++); |
1192 | L->top=res; |
1193 | return(wanted-(-1)); |
1194 | } |
1195 | static void luaD_call(lua_State*L,StkId func,int nResults){ |
1196 | if(++L->nCcalls>=200){ |
1197 | if(L->nCcalls==200) |
1198 | luaG_runerror(L,"C stack overflow" ); |
1199 | else if(L->nCcalls>=(200+(200>>3))) |
1200 | luaD_throw(L,5); |
1201 | } |
1202 | if(luaD_precall(L,func,nResults)==0) |
1203 | luaV_execute(L,1); |
1204 | L->nCcalls--; |
1205 | luaC_checkGC(L); |
1206 | } |
1207 | static int luaD_pcall(lua_State*L,Pfunc func,void*u, |
1208 | ptrdiff_t old_top,ptrdiff_t ef){ |
1209 | int status; |
1210 | unsigned short oldnCcalls=L->nCcalls; |
1211 | ptrdiff_t old_ci=saveci(L,L->ci); |
1212 | lu_byte old_allowhooks=L->allowhook; |
1213 | ptrdiff_t old_errfunc=L->errfunc; |
1214 | L->errfunc=ef; |
1215 | status=luaD_rawrunprotected(L,func,u); |
1216 | if(status!=0){ |
1217 | StkId oldtop=restorestack(L,old_top); |
1218 | luaF_close(L,oldtop); |
1219 | luaD_seterrorobj(L,status,oldtop); |
1220 | L->nCcalls=oldnCcalls; |
1221 | L->ci=restoreci(L,old_ci); |
1222 | L->base=L->ci->base; |
1223 | L->savedpc=L->ci->savedpc; |
1224 | L->allowhook=old_allowhooks; |
1225 | restore_stack_limit(L); |
1226 | } |
1227 | L->errfunc=old_errfunc; |
1228 | return status; |
1229 | } |
1230 | struct SParser{ |
1231 | ZIO*z; |
1232 | Mbuffer buff; |
1233 | const char*name; |
1234 | }; |
1235 | static void f_parser(lua_State*L,void*ud){ |
1236 | int i; |
1237 | Proto*tf; |
1238 | Closure*cl; |
1239 | struct SParser*p=cast(struct SParser*,ud); |
1240 | luaC_checkGC(L); |
1241 | tf=luaY_parser(L,p->z, |
1242 | &p->buff,p->name); |
1243 | cl=luaF_newLclosure(L,tf->nups,hvalue(gt(L))); |
1244 | cl->l.p=tf; |
1245 | for(i=0;i<tf->nups;i++) |
1246 | cl->l.upvals[i]=luaF_newupval(L); |
1247 | setclvalue(L,L->top,cl); |
1248 | incr_top(L); |
1249 | } |
1250 | static int luaD_protectedparser(lua_State*L,ZIO*z,const char*name){ |
1251 | struct SParser p; |
1252 | int status; |
1253 | p.z=z;p.name=name; |
1254 | luaZ_initbuffer(L,&p.buff); |
1255 | status=luaD_pcall(L,f_parser,&p,savestack(L,L->top),L->errfunc); |
1256 | luaZ_freebuffer(L,&p.buff); |
1257 | return status; |
1258 | } |
1259 | static void luaS_resize(lua_State*L,int newsize){ |
1260 | GCObject**newhash; |
1261 | stringtable*tb; |
1262 | int i; |
1263 | if(G(L)->gcstate==2) |
1264 | return; |
1265 | newhash=luaM_newvector(L,newsize,GCObject*); |
1266 | tb=&G(L)->strt; |
1267 | for(i=0;i<newsize;i++)newhash[i]=NULL; |
1268 | for(i=0;i<tb->size;i++){ |
1269 | GCObject*p=tb->hash[i]; |
1270 | while(p){ |
1271 | GCObject*next=p->gch.next; |
1272 | unsigned int h=gco2ts(p)->hash; |
1273 | int h1=lmod(h,newsize); |
1274 | p->gch.next=newhash[h1]; |
1275 | newhash[h1]=p; |
1276 | p=next; |
1277 | } |
1278 | } |
1279 | luaM_freearray(L,tb->hash,tb->size,TString*); |
1280 | tb->size=newsize; |
1281 | tb->hash=newhash; |
1282 | } |
1283 | static TString*newlstr(lua_State*L,const char*str,size_t l, |
1284 | unsigned int h){ |
1285 | TString*ts; |
1286 | stringtable*tb; |
1287 | if(l+1>(((size_t)(~(size_t)0)-2)-sizeof(TString))/sizeof(char)) |
1288 | luaM_toobig(L); |
1289 | ts=cast(TString*,luaM_malloc(L,(l+1)*sizeof(char)+sizeof(TString))); |
1290 | ts->tsv.len=l; |
1291 | ts->tsv.hash=h; |
1292 | ts->tsv.marked=luaC_white(G(L)); |
1293 | ts->tsv.tt=4; |
1294 | ts->tsv.reserved=0; |
1295 | memcpy(ts+1,str,l*sizeof(char)); |
1296 | ((char*)(ts+1))[l]='\0'; |
1297 | tb=&G(L)->strt; |
1298 | h=lmod(h,tb->size); |
1299 | ts->tsv.next=tb->hash[h]; |
1300 | tb->hash[h]=obj2gco(ts); |
1301 | tb->nuse++; |
1302 | if(tb->nuse>cast(lu_int32,tb->size)&&tb->size<=(INT_MAX-2)/2) |
1303 | luaS_resize(L,tb->size*2); |
1304 | return ts; |
1305 | } |
1306 | static TString*luaS_newlstr(lua_State*L,const char*str,size_t l){ |
1307 | GCObject*o; |
1308 | unsigned int h=cast(unsigned int,l); |
1309 | size_t step=(l>>5)+1; |
1310 | size_t l1; |
1311 | for(l1=l;l1>=step;l1-=step) |
1312 | h=h^((h<<5)+(h>>2)+cast(unsigned char,str[l1-1])); |
1313 | for(o=G(L)->strt.hash[lmod(h,G(L)->strt.size)]; |
1314 | o!=NULL; |
1315 | o=o->gch.next){ |
1316 | TString*ts=rawgco2ts(o); |
1317 | if(ts->tsv.len==l&&(memcmp(str,getstr(ts),l)==0)){ |
1318 | if(isdead(G(L),o))changewhite(o); |
1319 | return ts; |
1320 | } |
1321 | } |
1322 | return newlstr(L,str,l,h); |
1323 | } |
1324 | static Udata*luaS_newudata(lua_State*L,size_t s,Table*e){ |
1325 | Udata*u; |
1326 | if(s>((size_t)(~(size_t)0)-2)-sizeof(Udata)) |
1327 | luaM_toobig(L); |
1328 | u=cast(Udata*,luaM_malloc(L,s+sizeof(Udata))); |
1329 | u->uv.marked=luaC_white(G(L)); |
1330 | u->uv.tt=7; |
1331 | u->uv.len=s; |
1332 | u->uv.metatable=NULL; |
1333 | u->uv.env=e; |
1334 | u->uv.next=G(L)->mainthread->next; |
1335 | G(L)->mainthread->next=obj2gco(u); |
1336 | return u; |
1337 | } |
1338 | #define hashpow2(t,n)(gnode(t,lmod((n),sizenode(t)))) |
1339 | #define hashstr(t,str)hashpow2(t,(str)->tsv.hash) |
1340 | #define hashboolean(t,p)hashpow2(t,p) |
1341 | #define hashmod(t,n)(gnode(t,((n)%((sizenode(t)-1)|1)))) |
1342 | #define hashpointer(t,p)hashmod(t,IntPoint(p)) |
1343 | static const Node dummynode_={ |
1344 | {{NULL},0}, |
1345 | {{{NULL},0,NULL}} |
1346 | }; |
1347 | static Node*hashnum(const Table*t,lua_Number n){ |
1348 | unsigned int a[cast_int(sizeof(lua_Number)/sizeof(int))]; |
1349 | int i; |
1350 | if(luai_numeq(n,0)) |
1351 | return gnode(t,0); |
1352 | memcpy(a,&n,sizeof(a)); |
1353 | for(i=1;i<cast_int(sizeof(lua_Number)/sizeof(int));i++)a[0]+=a[i]; |
1354 | return hashmod(t,a[0]); |
1355 | } |
1356 | static Node*mainposition(const Table*t,const TValue*key){ |
1357 | switch(ttype(key)){ |
1358 | case 3: |
1359 | return hashnum(t,nvalue(key)); |
1360 | case 4: |
1361 | return hashstr(t,rawtsvalue(key)); |
1362 | case 1: |
1363 | return hashboolean(t,bvalue(key)); |
1364 | case 2: |
1365 | return hashpointer(t,pvalue(key)); |
1366 | default: |
1367 | return hashpointer(t,gcvalue(key)); |
1368 | } |
1369 | } |
1370 | static int arrayindex(const TValue*key){ |
1371 | if(ttisnumber(key)){ |
1372 | lua_Number n=nvalue(key); |
1373 | int k; |
1374 | lua_number2int(k,n); |
1375 | if(luai_numeq(cast_num(k),n)) |
1376 | return k; |
1377 | } |
1378 | return-1; |
1379 | } |
1380 | static int findindex(lua_State*L,Table*t,StkId key){ |
1381 | int i; |
1382 | if(ttisnil(key))return-1; |
1383 | i=arrayindex(key); |
1384 | if(0<i&&i<=t->sizearray) |
1385 | return i-1; |
1386 | else{ |
1387 | Node*n=mainposition(t,key); |
1388 | do{ |
1389 | if(luaO_rawequalObj(key2tval(n),key)|| |
1390 | (ttype(gkey(n))==(8+3)&&iscollectable(key)&& |
1391 | gcvalue(gkey(n))==gcvalue(key))){ |
1392 | i=cast_int(n-gnode(t,0)); |
1393 | return i+t->sizearray; |
1394 | } |
1395 | else n=gnext(n); |
1396 | }while(n); |
1397 | luaG_runerror(L,"invalid key to " LUA_QL("next" )); |
1398 | return 0; |
1399 | } |
1400 | } |
1401 | static int luaH_next(lua_State*L,Table*t,StkId key){ |
1402 | int i=findindex(L,t,key); |
1403 | for(i++;i<t->sizearray;i++){ |
1404 | if(!ttisnil(&t->array[i])){ |
1405 | setnvalue(key,cast_num(i+1)); |
1406 | setobj(L,key+1,&t->array[i]); |
1407 | return 1; |
1408 | } |
1409 | } |
1410 | for(i-=t->sizearray;i<(int)sizenode(t);i++){ |
1411 | if(!ttisnil(gval(gnode(t,i)))){ |
1412 | setobj(L,key,key2tval(gnode(t,i))); |
1413 | setobj(L,key+1,gval(gnode(t,i))); |
1414 | return 1; |
1415 | } |
1416 | } |
1417 | return 0; |
1418 | } |
1419 | static int computesizes(int nums[],int*narray){ |
1420 | int i; |
1421 | int twotoi; |
1422 | int a=0; |
1423 | int na=0; |
1424 | int n=0; |
1425 | for(i=0,twotoi=1;twotoi/2<*narray;i++,twotoi*=2){ |
1426 | if(nums[i]>0){ |
1427 | a+=nums[i]; |
1428 | if(a>twotoi/2){ |
1429 | n=twotoi; |
1430 | na=a; |
1431 | } |
1432 | } |
1433 | if(a==*narray)break; |
1434 | } |
1435 | *narray=n; |
1436 | return na; |
1437 | } |
1438 | static int countint(const TValue*key,int*nums){ |
1439 | int k=arrayindex(key); |
1440 | if(0<k&&k<=(1<<(32-2))){ |
1441 | nums[ceillog2(k)]++; |
1442 | return 1; |
1443 | } |
1444 | else |
1445 | return 0; |
1446 | } |
1447 | static int numusearray(const Table*t,int*nums){ |
1448 | int lg; |
1449 | int ttlg; |
1450 | int ause=0; |
1451 | int i=1; |
1452 | for(lg=0,ttlg=1;lg<=(32-2);lg++,ttlg*=2){ |
1453 | int lc=0; |
1454 | int lim=ttlg; |
1455 | if(lim>t->sizearray){ |
1456 | lim=t->sizearray; |
1457 | if(i>lim) |
1458 | break; |
1459 | } |
1460 | for(;i<=lim;i++){ |
1461 | if(!ttisnil(&t->array[i-1])) |
1462 | lc++; |
1463 | } |
1464 | nums[lg]+=lc; |
1465 | ause+=lc; |
1466 | } |
1467 | return ause; |
1468 | } |
1469 | static int numusehash(const Table*t,int*nums,int*pnasize){ |
1470 | int totaluse=0; |
1471 | int ause=0; |
1472 | int i=sizenode(t); |
1473 | while(i--){ |
1474 | Node*n=&t->node[i]; |
1475 | if(!ttisnil(gval(n))){ |
1476 | ause+=countint(key2tval(n),nums); |
1477 | totaluse++; |
1478 | } |
1479 | } |
1480 | *pnasize+=ause; |
1481 | return totaluse; |
1482 | } |
1483 | static void setarrayvector(lua_State*L,Table*t,int size){ |
1484 | int i; |
1485 | luaM_reallocvector(L,t->array,t->sizearray,size,TValue); |
1486 | for(i=t->sizearray;i<size;i++) |
1487 | setnilvalue(&t->array[i]); |
1488 | t->sizearray=size; |
1489 | } |
1490 | static void setnodevector(lua_State*L,Table*t,int size){ |
1491 | int lsize; |
1492 | if(size==0){ |
1493 | t->node=cast(Node*,(&dummynode_)); |
1494 | lsize=0; |
1495 | } |
1496 | else{ |
1497 | int i; |
1498 | lsize=ceillog2(size); |
1499 | if(lsize>(32-2)) |
1500 | luaG_runerror(L,"table overflow" ); |
1501 | size=twoto(lsize); |
1502 | t->node=luaM_newvector(L,size,Node); |
1503 | for(i=0;i<size;i++){ |
1504 | Node*n=gnode(t,i); |
1505 | gnext(n)=NULL; |
1506 | setnilvalue(gkey(n)); |
1507 | setnilvalue(gval(n)); |
1508 | } |
1509 | } |
1510 | t->lsizenode=cast_byte(lsize); |
1511 | t->lastfree=gnode(t,size); |
1512 | } |
1513 | static void resize(lua_State*L,Table*t,int nasize,int nhsize){ |
1514 | int i; |
1515 | int oldasize=t->sizearray; |
1516 | int oldhsize=t->lsizenode; |
1517 | Node*nold=t->node; |
1518 | if(nasize>oldasize) |
1519 | setarrayvector(L,t,nasize); |
1520 | setnodevector(L,t,nhsize); |
1521 | if(nasize<oldasize){ |
1522 | t->sizearray=nasize; |
1523 | for(i=nasize;i<oldasize;i++){ |
1524 | if(!ttisnil(&t->array[i])) |
1525 | setobj(L,luaH_setnum(L,t,i+1),&t->array[i]); |
1526 | } |
1527 | luaM_reallocvector(L,t->array,oldasize,nasize,TValue); |
1528 | } |
1529 | for(i=twoto(oldhsize)-1;i>=0;i--){ |
1530 | Node*old=nold+i; |
1531 | if(!ttisnil(gval(old))) |
1532 | setobj(L,luaH_set(L,t,key2tval(old)),gval(old)); |
1533 | } |
1534 | if(nold!=(&dummynode_)) |
1535 | luaM_freearray(L,nold,twoto(oldhsize),Node); |
1536 | } |
1537 | static void luaH_resizearray(lua_State*L,Table*t,int nasize){ |
1538 | int nsize=(t->node==(&dummynode_))?0:sizenode(t); |
1539 | resize(L,t,nasize,nsize); |
1540 | } |
1541 | static void rehash(lua_State*L,Table*t,const TValue*ek){ |
1542 | int nasize,na; |
1543 | int nums[(32-2)+1]; |
1544 | int i; |
1545 | int totaluse; |
1546 | for(i=0;i<=(32-2);i++)nums[i]=0; |
1547 | nasize=numusearray(t,nums); |
1548 | totaluse=nasize; |
1549 | totaluse+=numusehash(t,nums,&nasize); |
1550 | nasize+=countint(ek,nums); |
1551 | totaluse++; |
1552 | na=computesizes(nums,&nasize); |
1553 | resize(L,t,nasize,totaluse-na); |
1554 | } |
1555 | static Table*luaH_new(lua_State*L,int narray,int nhash){ |
1556 | Table*t=luaM_new(L,Table); |
1557 | luaC_link(L,obj2gco(t),5); |
1558 | t->metatable=NULL; |
1559 | t->flags=cast_byte(~0); |
1560 | t->array=NULL; |
1561 | t->sizearray=0; |
1562 | t->lsizenode=0; |
1563 | t->node=cast(Node*,(&dummynode_)); |
1564 | setarrayvector(L,t,narray); |
1565 | setnodevector(L,t,nhash); |
1566 | return t; |
1567 | } |
1568 | static void luaH_free(lua_State*L,Table*t){ |
1569 | if(t->node!=(&dummynode_)) |
1570 | luaM_freearray(L,t->node,sizenode(t),Node); |
1571 | luaM_freearray(L,t->array,t->sizearray,TValue); |
1572 | luaM_free(L,t); |
1573 | } |
1574 | static Node*getfreepos(Table*t){ |
1575 | while(t->lastfree-->t->node){ |
1576 | if(ttisnil(gkey(t->lastfree))) |
1577 | return t->lastfree; |
1578 | } |
1579 | return NULL; |
1580 | } |
1581 | static TValue*newkey(lua_State*L,Table*t,const TValue*key){ |
1582 | Node*mp=mainposition(t,key); |
1583 | if(!ttisnil(gval(mp))||mp==(&dummynode_)){ |
1584 | Node*othern; |
1585 | Node*n=getfreepos(t); |
1586 | if(n==NULL){ |
1587 | rehash(L,t,key); |
1588 | return luaH_set(L,t,key); |
1589 | } |
1590 | othern=mainposition(t,key2tval(mp)); |
1591 | if(othern!=mp){ |
1592 | while(gnext(othern)!=mp)othern=gnext(othern); |
1593 | gnext(othern)=n; |
1594 | *n=*mp; |
1595 | gnext(mp)=NULL; |
1596 | setnilvalue(gval(mp)); |
1597 | } |
1598 | else{ |
1599 | gnext(n)=gnext(mp); |
1600 | gnext(mp)=n; |
1601 | mp=n; |
1602 | } |
1603 | } |
1604 | gkey(mp)->value=key->value;gkey(mp)->tt=key->tt; |
1605 | luaC_barriert(L,t,key); |
1606 | return gval(mp); |
1607 | } |
1608 | static const TValue*luaH_getnum(Table*t,int key){ |
1609 | if(cast(unsigned int,key-1)<cast(unsigned int,t->sizearray)) |
1610 | return&t->array[key-1]; |
1611 | else{ |
1612 | lua_Number nk=cast_num(key); |
1613 | Node*n=hashnum(t,nk); |
1614 | do{ |
1615 | if(ttisnumber(gkey(n))&&luai_numeq(nvalue(gkey(n)),nk)) |
1616 | return gval(n); |
1617 | else n=gnext(n); |
1618 | }while(n); |
1619 | return(&luaO_nilobject_); |
1620 | } |
1621 | } |
1622 | static const TValue*luaH_getstr(Table*t,TString*key){ |
1623 | Node*n=hashstr(t,key); |
1624 | do{ |
1625 | if(ttisstring(gkey(n))&&rawtsvalue(gkey(n))==key) |
1626 | return gval(n); |
1627 | else n=gnext(n); |
1628 | }while(n); |
1629 | return(&luaO_nilobject_); |
1630 | } |
1631 | static const TValue*luaH_get(Table*t,const TValue*key){ |
1632 | switch(ttype(key)){ |
1633 | case 0:return(&luaO_nilobject_); |
1634 | case 4:return luaH_getstr(t,rawtsvalue(key)); |
1635 | case 3:{ |
1636 | int k; |
1637 | lua_Number n=nvalue(key); |
1638 | lua_number2int(k,n); |
1639 | if(luai_numeq(cast_num(k),nvalue(key))) |
1640 | return luaH_getnum(t,k); |
1641 | } |
1642 | default:{ |
1643 | Node*n=mainposition(t,key); |
1644 | do{ |
1645 | if(luaO_rawequalObj(key2tval(n),key)) |
1646 | return gval(n); |
1647 | else n=gnext(n); |
1648 | }while(n); |
1649 | return(&luaO_nilobject_); |
1650 | } |
1651 | } |
1652 | } |
1653 | static TValue*luaH_set(lua_State*L,Table*t,const TValue*key){ |
1654 | const TValue*p=luaH_get(t,key); |
1655 | t->flags=0; |
1656 | if(p!=(&luaO_nilobject_)) |
1657 | return cast(TValue*,p); |
1658 | else{ |
1659 | if(ttisnil(key))luaG_runerror(L,"table index is nil" ); |
1660 | else if(ttisnumber(key)&&luai_numisnan(nvalue(key))) |
1661 | luaG_runerror(L,"table index is NaN" ); |
1662 | return newkey(L,t,key); |
1663 | } |
1664 | } |
1665 | static TValue*luaH_setnum(lua_State*L,Table*t,int key){ |
1666 | const TValue*p=luaH_getnum(t,key); |
1667 | if(p!=(&luaO_nilobject_)) |
1668 | return cast(TValue*,p); |
1669 | else{ |
1670 | TValue k; |
1671 | setnvalue(&k,cast_num(key)); |
1672 | return newkey(L,t,&k); |
1673 | } |
1674 | } |
1675 | static TValue*luaH_setstr(lua_State*L,Table*t,TString*key){ |
1676 | const TValue*p=luaH_getstr(t,key); |
1677 | if(p!=(&luaO_nilobject_)) |
1678 | return cast(TValue*,p); |
1679 | else{ |
1680 | TValue k; |
1681 | setsvalue(L,&k,key); |
1682 | return newkey(L,t,&k); |
1683 | } |
1684 | } |
1685 | static int unbound_search(Table*t,unsigned int j){ |
1686 | unsigned int i=j; |
1687 | j++; |
1688 | while(!ttisnil(luaH_getnum(t,j))){ |
1689 | i=j; |
1690 | j*=2; |
1691 | if(j>cast(unsigned int,(INT_MAX-2))){ |
1692 | i=1; |
1693 | while(!ttisnil(luaH_getnum(t,i)))i++; |
1694 | return i-1; |
1695 | } |
1696 | } |
1697 | while(j-i>1){ |
1698 | unsigned int m=(i+j)/2; |
1699 | if(ttisnil(luaH_getnum(t,m)))j=m; |
1700 | else i=m; |
1701 | } |
1702 | return i; |
1703 | } |
1704 | static int luaH_getn(Table*t){ |
1705 | unsigned int j=t->sizearray; |
1706 | if(j>0&&ttisnil(&t->array[j-1])){ |
1707 | unsigned int i=0; |
1708 | while(j-i>1){ |
1709 | unsigned int m=(i+j)/2; |
1710 | if(ttisnil(&t->array[m-1]))j=m; |
1711 | else i=m; |
1712 | } |
1713 | return i; |
1714 | } |
1715 | else if(t->node==(&dummynode_)) |
1716 | return j; |
1717 | else return unbound_search(t,j); |
1718 | } |
1719 | #define makewhite(g,x)((x)->gch.marked=cast_byte(((x)->gch.marked&cast_byte(~(bitmask(2)|bit2mask(0,1))))|luaC_white(g))) |
1720 | #define white2gray(x)reset2bits((x)->gch.marked,0,1) |
1721 | #define black2gray(x)resetbit((x)->gch.marked,2) |
1722 | #define stringmark(s)reset2bits((s)->tsv.marked,0,1) |
1723 | #define isfinalized(u)testbit((u)->marked,3) |
1724 | #define markfinalized(u)l_setbit((u)->marked,3) |
1725 | #define markvalue(g,o){checkconsistency(o);if(iscollectable(o)&&iswhite(gcvalue(o)))reallymarkobject(g,gcvalue(o));} |
1726 | #define markobject(g,t){if(iswhite(obj2gco(t)))reallymarkobject(g,obj2gco(t));} |
1727 | #define setthreshold(g)(g->GCthreshold=(g->estimate/100)*g->gcpause) |
1728 | static void removeentry(Node*n){ |
1729 | if(iscollectable(gkey(n))) |
1730 | setttype(gkey(n),(8+3)); |
1731 | } |
1732 | static void reallymarkobject(global_State*g,GCObject*o){ |
1733 | white2gray(o); |
1734 | switch(o->gch.tt){ |
1735 | case 4:{ |
1736 | return; |
1737 | } |
1738 | case 7:{ |
1739 | Table*mt=gco2u(o)->metatable; |
1740 | gray2black(o); |
1741 | if(mt)markobject(g,mt); |
1742 | markobject(g,gco2u(o)->env); |
1743 | return; |
1744 | } |
1745 | case(8+2):{ |
1746 | UpVal*uv=gco2uv(o); |
1747 | markvalue(g,uv->v); |
1748 | if(uv->v==&uv->u.value) |
1749 | gray2black(o); |
1750 | return; |
1751 | } |
1752 | case 6:{ |
1753 | gco2cl(o)->c.gclist=g->gray; |
1754 | g->gray=o; |
1755 | break; |
1756 | } |
1757 | case 5:{ |
1758 | gco2h(o)->gclist=g->gray; |
1759 | g->gray=o; |
1760 | break; |
1761 | } |
1762 | case 8:{ |
1763 | gco2th(o)->gclist=g->gray; |
1764 | g->gray=o; |
1765 | break; |
1766 | } |
1767 | case(8+1):{ |
1768 | gco2p(o)->gclist=g->gray; |
1769 | g->gray=o; |
1770 | break; |
1771 | } |
1772 | default:; |
1773 | } |
1774 | } |
1775 | static void marktmu(global_State*g){ |
1776 | GCObject*u=g->tmudata; |
1777 | if(u){ |
1778 | do{ |
1779 | u=u->gch.next; |
1780 | makewhite(g,u); |
1781 | reallymarkobject(g,u); |
1782 | }while(u!=g->tmudata); |
1783 | } |
1784 | } |
1785 | static size_t luaC_separateudata(lua_State*L,int all){ |
1786 | global_State*g=G(L); |
1787 | size_t deadmem=0; |
1788 | GCObject**p=&g->mainthread->next; |
1789 | GCObject*curr; |
1790 | while((curr=*p)!=NULL){ |
1791 | if(!(iswhite(curr)||all)||isfinalized(gco2u(curr))) |
1792 | p=&curr->gch.next; |
1793 | else if(fasttm(L,gco2u(curr)->metatable,TM_GC)==NULL){ |
1794 | markfinalized(gco2u(curr)); |
1795 | p=&curr->gch.next; |
1796 | } |
1797 | else{ |
1798 | deadmem+=sizeudata(gco2u(curr)); |
1799 | markfinalized(gco2u(curr)); |
1800 | *p=curr->gch.next; |
1801 | if(g->tmudata==NULL) |
1802 | g->tmudata=curr->gch.next=curr; |
1803 | else{ |
1804 | curr->gch.next=g->tmudata->gch.next; |
1805 | g->tmudata->gch.next=curr; |
1806 | g->tmudata=curr; |
1807 | } |
1808 | } |
1809 | } |
1810 | return deadmem; |
1811 | } |
1812 | static int traversetable(global_State*g,Table*h){ |
1813 | int i; |
1814 | int weakkey=0; |
1815 | int weakvalue=0; |
1816 | const TValue*mode; |
1817 | if(h->metatable) |
1818 | markobject(g,h->metatable); |
1819 | mode=gfasttm(g,h->metatable,TM_MODE); |
1820 | if(mode&&ttisstring(mode)){ |
1821 | weakkey=(strchr(svalue(mode),'k')!=NULL); |
1822 | weakvalue=(strchr(svalue(mode),'v')!=NULL); |
1823 | if(weakkey||weakvalue){ |
1824 | h->marked&=~(bitmask(3)|bitmask(4)); |
1825 | h->marked|=cast_byte((weakkey<<3)| |
1826 | (weakvalue<<4)); |
1827 | h->gclist=g->weak; |
1828 | g->weak=obj2gco(h); |
1829 | } |
1830 | } |
1831 | if(weakkey&&weakvalue)return 1; |
1832 | if(!weakvalue){ |
1833 | i=h->sizearray; |
1834 | while(i--) |
1835 | markvalue(g,&h->array[i]); |
1836 | } |
1837 | i=sizenode(h); |
1838 | while(i--){ |
1839 | Node*n=gnode(h,i); |
1840 | if(ttisnil(gval(n))) |
1841 | removeentry(n); |
1842 | else{ |
1843 | if(!weakkey)markvalue(g,gkey(n)); |
1844 | if(!weakvalue)markvalue(g,gval(n)); |
1845 | } |
1846 | } |
1847 | return weakkey||weakvalue; |
1848 | } |
1849 | static void traverseproto(global_State*g,Proto*f){ |
1850 | int i; |
1851 | if(f->source)stringmark(f->source); |
1852 | for(i=0;i<f->sizek;i++) |
1853 | markvalue(g,&f->k[i]); |
1854 | for(i=0;i<f->sizeupvalues;i++){ |
1855 | if(f->upvalues[i]) |
1856 | stringmark(f->upvalues[i]); |
1857 | } |
1858 | for(i=0;i<f->sizep;i++){ |
1859 | if(f->p[i]) |
1860 | markobject(g,f->p[i]); |
1861 | } |
1862 | for(i=0;i<f->sizelocvars;i++){ |
1863 | if(f->locvars[i].varname) |
1864 | stringmark(f->locvars[i].varname); |
1865 | } |
1866 | } |
1867 | static void traverseclosure(global_State*g,Closure*cl){ |
1868 | markobject(g,cl->c.env); |
1869 | if(cl->c.isC){ |
1870 | int i; |
1871 | for(i=0;i<cl->c.nupvalues;i++) |
1872 | markvalue(g,&cl->c.upvalue[i]); |
1873 | } |
1874 | else{ |
1875 | int i; |
1876 | markobject(g,cl->l.p); |
1877 | for(i=0;i<cl->l.nupvalues;i++) |
1878 | markobject(g,cl->l.upvals[i]); |
1879 | } |
1880 | } |
1881 | static void checkstacksizes(lua_State*L,StkId max){ |
1882 | int ci_used=cast_int(L->ci-L->base_ci); |
1883 | int s_used=cast_int(max-L->stack); |
1884 | if(L->size_ci>20000) |
1885 | return; |
1886 | if(4*ci_used<L->size_ci&&2*8<L->size_ci) |
1887 | luaD_reallocCI(L,L->size_ci/2); |
1888 | condhardstacktests(luaD_reallocCI(L,ci_used+1)); |
1889 | if(4*s_used<L->stacksize&& |
1890 | 2*((2*20)+5)<L->stacksize) |
1891 | luaD_reallocstack(L,L->stacksize/2); |
1892 | condhardstacktests(luaD_reallocstack(L,s_used)); |
1893 | } |
1894 | static void traversestack(global_State*g,lua_State*l){ |
1895 | StkId o,lim; |
1896 | CallInfo*ci; |
1897 | markvalue(g,gt(l)); |
1898 | lim=l->top; |
1899 | for(ci=l->base_ci;ci<=l->ci;ci++){ |
1900 | if(lim<ci->top)lim=ci->top; |
1901 | } |
1902 | for(o=l->stack;o<l->top;o++) |
1903 | markvalue(g,o); |
1904 | for(;o<=lim;o++) |
1905 | setnilvalue(o); |
1906 | checkstacksizes(l,lim); |
1907 | } |
1908 | static l_mem propagatemark(global_State*g){ |
1909 | GCObject*o=g->gray; |
1910 | gray2black(o); |
1911 | switch(o->gch.tt){ |
1912 | case 5:{ |
1913 | Table*h=gco2h(o); |
1914 | g->gray=h->gclist; |
1915 | if(traversetable(g,h)) |
1916 | black2gray(o); |
1917 | return sizeof(Table)+sizeof(TValue)*h->sizearray+ |
1918 | sizeof(Node)*sizenode(h); |
1919 | } |
1920 | case 6:{ |
1921 | Closure*cl=gco2cl(o); |
1922 | g->gray=cl->c.gclist; |
1923 | traverseclosure(g,cl); |
1924 | return(cl->c.isC)?sizeCclosure(cl->c.nupvalues): |
1925 | sizeLclosure(cl->l.nupvalues); |
1926 | } |
1927 | case 8:{ |
1928 | lua_State*th=gco2th(o); |
1929 | g->gray=th->gclist; |
1930 | th->gclist=g->grayagain; |
1931 | g->grayagain=o; |
1932 | black2gray(o); |
1933 | traversestack(g,th); |
1934 | return sizeof(lua_State)+sizeof(TValue)*th->stacksize+ |
1935 | sizeof(CallInfo)*th->size_ci; |
1936 | } |
1937 | case(8+1):{ |
1938 | Proto*p=gco2p(o); |
1939 | g->gray=p->gclist; |
1940 | traverseproto(g,p); |
1941 | return sizeof(Proto)+sizeof(Instruction)*p->sizecode+ |
1942 | sizeof(Proto*)*p->sizep+ |
1943 | sizeof(TValue)*p->sizek+ |
1944 | sizeof(int)*p->sizelineinfo+ |
1945 | sizeof(LocVar)*p->sizelocvars+ |
1946 | sizeof(TString*)*p->sizeupvalues; |
1947 | } |
1948 | default:return 0; |
1949 | } |
1950 | } |
1951 | static size_t propagateall(global_State*g){ |
1952 | size_t m=0; |
1953 | while(g->gray)m+=propagatemark(g); |
1954 | return m; |
1955 | } |
1956 | static int iscleared(const TValue*o,int iskey){ |
1957 | if(!iscollectable(o))return 0; |
1958 | if(ttisstring(o)){ |
1959 | stringmark(rawtsvalue(o)); |
1960 | return 0; |
1961 | } |
1962 | return iswhite(gcvalue(o))|| |
1963 | (ttisuserdata(o)&&(!iskey&&isfinalized(uvalue(o)))); |
1964 | } |
1965 | static void cleartable(GCObject*l){ |
1966 | while(l){ |
1967 | Table*h=gco2h(l); |
1968 | int i=h->sizearray; |
1969 | if(testbit(h->marked,4)){ |
1970 | while(i--){ |
1971 | TValue*o=&h->array[i]; |
1972 | if(iscleared(o,0)) |
1973 | setnilvalue(o); |
1974 | } |
1975 | } |
1976 | i=sizenode(h); |
1977 | while(i--){ |
1978 | Node*n=gnode(h,i); |
1979 | if(!ttisnil(gval(n))&& |
1980 | (iscleared(key2tval(n),1)||iscleared(gval(n),0))){ |
1981 | setnilvalue(gval(n)); |
1982 | removeentry(n); |
1983 | } |
1984 | } |
1985 | l=h->gclist; |
1986 | } |
1987 | } |
1988 | static void freeobj(lua_State*L,GCObject*o){ |
1989 | switch(o->gch.tt){ |
1990 | case(8+1):luaF_freeproto(L,gco2p(o));break; |
1991 | case 6:luaF_freeclosure(L,gco2cl(o));break; |
1992 | case(8+2):luaF_freeupval(L,gco2uv(o));break; |
1993 | case 5:luaH_free(L,gco2h(o));break; |
1994 | case 8:{ |
1995 | luaE_freethread(L,gco2th(o)); |
1996 | break; |
1997 | } |
1998 | case 4:{ |
1999 | G(L)->strt.nuse--; |
2000 | luaM_freemem(L,o,sizestring(gco2ts(o))); |
2001 | break; |
2002 | } |
2003 | case 7:{ |
2004 | luaM_freemem(L,o,sizeudata(gco2u(o))); |
2005 | break; |
2006 | } |
2007 | default:; |
2008 | } |
2009 | } |
2010 | #define sweepwholelist(L,p)sweeplist(L,p,((lu_mem)(~(lu_mem)0)-2)) |
2011 | static GCObject**sweeplist(lua_State*L,GCObject**p,lu_mem count){ |
2012 | GCObject*curr; |
2013 | global_State*g=G(L); |
2014 | int deadmask=otherwhite(g); |
2015 | while((curr=*p)!=NULL&&count-->0){ |
2016 | if(curr->gch.tt==8) |
2017 | sweepwholelist(L,&gco2th(curr)->openupval); |
2018 | if((curr->gch.marked^bit2mask(0,1))&deadmask){ |
2019 | makewhite(g,curr); |
2020 | p=&curr->gch.next; |
2021 | } |
2022 | else{ |
2023 | *p=curr->gch.next; |
2024 | if(curr==g->rootgc) |
2025 | g->rootgc=curr->gch.next; |
2026 | freeobj(L,curr); |
2027 | } |
2028 | } |
2029 | return p; |
2030 | } |
2031 | static void checkSizes(lua_State*L){ |
2032 | global_State*g=G(L); |
2033 | if(g->strt.nuse<cast(lu_int32,g->strt.size/4)&& |
2034 | g->strt.size>32*2) |
2035 | luaS_resize(L,g->strt.size/2); |
2036 | if(luaZ_sizebuffer(&g->buff)>32*2){ |
2037 | size_t newsize=luaZ_sizebuffer(&g->buff)/2; |
2038 | luaZ_resizebuffer(L,&g->buff,newsize); |
2039 | } |
2040 | } |
2041 | static void GCTM(lua_State*L){ |
2042 | global_State*g=G(L); |
2043 | GCObject*o=g->tmudata->gch.next; |
2044 | Udata*udata=rawgco2u(o); |
2045 | const TValue*tm; |
2046 | if(o==g->tmudata) |
2047 | g->tmudata=NULL; |
2048 | else |
2049 | g->tmudata->gch.next=udata->uv.next; |
2050 | udata->uv.next=g->mainthread->next; |
2051 | g->mainthread->next=o; |
2052 | makewhite(g,o); |
2053 | tm=fasttm(L,udata->uv.metatable,TM_GC); |
2054 | if(tm!=NULL){ |
2055 | lu_byte oldah=L->allowhook; |
2056 | lu_mem oldt=g->GCthreshold; |
2057 | L->allowhook=0; |
2058 | g->GCthreshold=2*g->totalbytes; |
2059 | setobj(L,L->top,tm); |
2060 | setuvalue(L,L->top+1,udata); |
2061 | L->top+=2; |
2062 | luaD_call(L,L->top-2,0); |
2063 | L->allowhook=oldah; |
2064 | g->GCthreshold=oldt; |
2065 | } |
2066 | } |
2067 | static void luaC_callGCTM(lua_State*L){ |
2068 | while(G(L)->tmudata) |
2069 | GCTM(L); |
2070 | } |
2071 | static void luaC_freeall(lua_State*L){ |
2072 | global_State*g=G(L); |
2073 | int i; |
2074 | g->currentwhite=bit2mask(0,1)|bitmask(6); |
2075 | sweepwholelist(L,&g->rootgc); |
2076 | for(i=0;i<g->strt.size;i++) |
2077 | sweepwholelist(L,&g->strt.hash[i]); |
2078 | } |
2079 | static void markmt(global_State*g){ |
2080 | int i; |
2081 | for(i=0;i<(8+1);i++) |
2082 | if(g->mt[i])markobject(g,g->mt[i]); |
2083 | } |
2084 | static void markroot(lua_State*L){ |
2085 | global_State*g=G(L); |
2086 | g->gray=NULL; |
2087 | g->grayagain=NULL; |
2088 | g->weak=NULL; |
2089 | markobject(g,g->mainthread); |
2090 | markvalue(g,gt(g->mainthread)); |
2091 | markvalue(g,registry(L)); |
2092 | markmt(g); |
2093 | g->gcstate=1; |
2094 | } |
2095 | static void (global_State*g){ |
2096 | UpVal*uv; |
2097 | for(uv=g->uvhead.u.l.next;uv!=&g->uvhead;uv=uv->u.l.next){ |
2098 | if(isgray(obj2gco(uv))) |
2099 | markvalue(g,uv->v); |
2100 | } |
2101 | } |
2102 | static void atomic(lua_State*L){ |
2103 | global_State*g=G(L); |
2104 | size_t udsize; |
2105 | remarkupvals(g); |
2106 | propagateall(g); |
2107 | g->gray=g->weak; |
2108 | g->weak=NULL; |
2109 | markobject(g,L); |
2110 | markmt(g); |
2111 | propagateall(g); |
2112 | g->gray=g->grayagain; |
2113 | g->grayagain=NULL; |
2114 | propagateall(g); |
2115 | udsize=luaC_separateudata(L,0); |
2116 | marktmu(g); |
2117 | udsize+=propagateall(g); |
2118 | cleartable(g->weak); |
2119 | g->currentwhite=cast_byte(otherwhite(g)); |
2120 | g->sweepstrgc=0; |
2121 | g->sweepgc=&g->rootgc; |
2122 | g->gcstate=2; |
2123 | g->estimate=g->totalbytes-udsize; |
2124 | } |
2125 | static l_mem singlestep(lua_State*L){ |
2126 | global_State*g=G(L); |
2127 | switch(g->gcstate){ |
2128 | case 0:{ |
2129 | markroot(L); |
2130 | return 0; |
2131 | } |
2132 | case 1:{ |
2133 | if(g->gray) |
2134 | return propagatemark(g); |
2135 | else{ |
2136 | atomic(L); |
2137 | return 0; |
2138 | } |
2139 | } |
2140 | case 2:{ |
2141 | lu_mem old=g->totalbytes; |
2142 | sweepwholelist(L,&g->strt.hash[g->sweepstrgc++]); |
2143 | if(g->sweepstrgc>=g->strt.size) |
2144 | g->gcstate=3; |
2145 | g->estimate-=old-g->totalbytes; |
2146 | return 10; |
2147 | } |
2148 | case 3:{ |
2149 | lu_mem old=g->totalbytes; |
2150 | g->sweepgc=sweeplist(L,g->sweepgc,40); |
2151 | if(*g->sweepgc==NULL){ |
2152 | checkSizes(L); |
2153 | g->gcstate=4; |
2154 | } |
2155 | g->estimate-=old-g->totalbytes; |
2156 | return 40*10; |
2157 | } |
2158 | case 4:{ |
2159 | if(g->tmudata){ |
2160 | GCTM(L); |
2161 | if(g->estimate>100) |
2162 | g->estimate-=100; |
2163 | return 100; |
2164 | } |
2165 | else{ |
2166 | g->gcstate=0; |
2167 | g->gcdept=0; |
2168 | return 0; |
2169 | } |
2170 | } |
2171 | default:return 0; |
2172 | } |
2173 | } |
2174 | static void luaC_step(lua_State*L){ |
2175 | global_State*g=G(L); |
2176 | l_mem lim=(1024u/100)*g->gcstepmul; |
2177 | if(lim==0) |
2178 | lim=(((lu_mem)(~(lu_mem)0)-2)-1)/2; |
2179 | g->gcdept+=g->totalbytes-g->GCthreshold; |
2180 | do{ |
2181 | lim-=singlestep(L); |
2182 | if(g->gcstate==0) |
2183 | break; |
2184 | }while(lim>0); |
2185 | if(g->gcstate!=0){ |
2186 | if(g->gcdept<1024u) |
2187 | g->GCthreshold=g->totalbytes+1024u; |
2188 | else{ |
2189 | g->gcdept-=1024u; |
2190 | g->GCthreshold=g->totalbytes; |
2191 | } |
2192 | } |
2193 | else{ |
2194 | setthreshold(g); |
2195 | } |
2196 | } |
2197 | static void luaC_barrierf(lua_State*L,GCObject*o,GCObject*v){ |
2198 | global_State*g=G(L); |
2199 | if(g->gcstate==1) |
2200 | reallymarkobject(g,v); |
2201 | else |
2202 | makewhite(g,o); |
2203 | } |
2204 | static void luaC_barrierback(lua_State*L,Table*t){ |
2205 | global_State*g=G(L); |
2206 | GCObject*o=obj2gco(t); |
2207 | black2gray(o); |
2208 | t->gclist=g->grayagain; |
2209 | g->grayagain=o; |
2210 | } |
2211 | static void luaC_link(lua_State*L,GCObject*o,lu_byte tt){ |
2212 | global_State*g=G(L); |
2213 | o->gch.next=g->rootgc; |
2214 | g->rootgc=o; |
2215 | o->gch.marked=luaC_white(g); |
2216 | o->gch.tt=tt; |
2217 | } |
2218 | static void luaC_linkupval(lua_State*L,UpVal*uv){ |
2219 | global_State*g=G(L); |
2220 | GCObject*o=obj2gco(uv); |
2221 | o->gch.next=g->rootgc; |
2222 | g->rootgc=o; |
2223 | if(isgray(o)){ |
2224 | if(g->gcstate==1){ |
2225 | gray2black(o); |
2226 | luaC_barrier(L,uv,uv->v); |
2227 | } |
2228 | else{ |
2229 | makewhite(g,o); |
2230 | } |
2231 | } |
2232 | } |
2233 | typedef union{ |
2234 | lua_Number r; |
2235 | TString*ts; |
2236 | }SemInfo; |
2237 | typedef struct Token{ |
2238 | int token; |
2239 | SemInfo seminfo; |
2240 | }Token; |
2241 | typedef struct LexState{ |
2242 | int current; |
2243 | int linenumber; |
2244 | int lastline; |
2245 | Token t; |
2246 | Token lookahead; |
2247 | struct FuncState*fs; |
2248 | struct lua_State*L; |
2249 | ZIO*z; |
2250 | Mbuffer*buff; |
2251 | TString*source; |
2252 | char decpoint; |
2253 | }LexState; |
2254 | static void luaX_init(lua_State*L); |
2255 | static void luaX_lexerror(LexState*ls,const char*msg,int token); |
2256 | #define state_size(x)(sizeof(x)+0) |
2257 | #define fromstate(l)(cast(lu_byte*,(l))-0) |
2258 | #define tostate(l)(cast(lua_State*,cast(lu_byte*,l)+0)) |
2259 | typedef struct LG{ |
2260 | lua_State l; |
2261 | global_State g; |
2262 | }LG; |
2263 | static void stack_init(lua_State*L1,lua_State*L){ |
2264 | L1->base_ci=luaM_newvector(L,8,CallInfo); |
2265 | L1->ci=L1->base_ci; |
2266 | L1->size_ci=8; |
2267 | L1->end_ci=L1->base_ci+L1->size_ci-1; |
2268 | L1->stack=luaM_newvector(L,(2*20)+5,TValue); |
2269 | L1->stacksize=(2*20)+5; |
2270 | L1->top=L1->stack; |
2271 | L1->stack_last=L1->stack+(L1->stacksize-5)-1; |
2272 | L1->ci->func=L1->top; |
2273 | setnilvalue(L1->top++); |
2274 | L1->base=L1->ci->base=L1->top; |
2275 | L1->ci->top=L1->top+20; |
2276 | } |
2277 | static void freestack(lua_State*L,lua_State*L1){ |
2278 | luaM_freearray(L,L1->base_ci,L1->size_ci,CallInfo); |
2279 | luaM_freearray(L,L1->stack,L1->stacksize,TValue); |
2280 | } |
2281 | static void f_luaopen(lua_State*L,void*ud){ |
2282 | global_State*g=G(L); |
2283 | UNUSED(ud); |
2284 | stack_init(L,L); |
2285 | sethvalue(L,gt(L),luaH_new(L,0,2)); |
2286 | sethvalue(L,registry(L),luaH_new(L,0,2)); |
2287 | luaS_resize(L,32); |
2288 | luaT_init(L); |
2289 | luaX_init(L); |
2290 | luaS_fix(luaS_newliteral(L,"not enough memory" )); |
2291 | g->GCthreshold=4*g->totalbytes; |
2292 | } |
2293 | static void preinit_state(lua_State*L,global_State*g){ |
2294 | G(L)=g; |
2295 | L->stack=NULL; |
2296 | L->stacksize=0; |
2297 | L->errorJmp=NULL; |
2298 | L->hook=NULL; |
2299 | L->hookmask=0; |
2300 | L->basehookcount=0; |
2301 | L->allowhook=1; |
2302 | resethookcount(L); |
2303 | L->openupval=NULL; |
2304 | L->size_ci=0; |
2305 | L->nCcalls=L->baseCcalls=0; |
2306 | L->status=0; |
2307 | L->base_ci=L->ci=NULL; |
2308 | L->savedpc=NULL; |
2309 | L->errfunc=0; |
2310 | setnilvalue(gt(L)); |
2311 | } |
2312 | static void close_state(lua_State*L){ |
2313 | global_State*g=G(L); |
2314 | luaF_close(L,L->stack); |
2315 | luaC_freeall(L); |
2316 | luaM_freearray(L,G(L)->strt.hash,G(L)->strt.size,TString*); |
2317 | luaZ_freebuffer(L,&g->buff); |
2318 | freestack(L,L); |
2319 | (*g->frealloc)(g->ud,fromstate(L),state_size(LG),0); |
2320 | } |
2321 | static void luaE_freethread(lua_State*L,lua_State*L1){ |
2322 | luaF_close(L1,L1->stack); |
2323 | freestack(L,L1); |
2324 | luaM_freemem(L,fromstate(L1),state_size(lua_State)); |
2325 | } |
2326 | static lua_State*lua_newstate(lua_Alloc f,void*ud){ |
2327 | int i; |
2328 | lua_State*L; |
2329 | global_State*g; |
2330 | void*l=(*f)(ud,NULL,0,state_size(LG)); |
2331 | if(l==NULL)return NULL; |
2332 | L=tostate(l); |
2333 | g=&((LG*)L)->g; |
2334 | L->next=NULL; |
2335 | L->tt=8; |
2336 | g->currentwhite=bit2mask(0,5); |
2337 | L->marked=luaC_white(g); |
2338 | set2bits(L->marked,5,6); |
2339 | preinit_state(L,g); |
2340 | g->frealloc=f; |
2341 | g->ud=ud; |
2342 | g->mainthread=L; |
2343 | g->uvhead.u.l.prev=&g->uvhead; |
2344 | g->uvhead.u.l.next=&g->uvhead; |
2345 | g->GCthreshold=0; |
2346 | g->strt.size=0; |
2347 | g->strt.nuse=0; |
2348 | g->strt.hash=NULL; |
2349 | setnilvalue(registry(L)); |
2350 | luaZ_initbuffer(L,&g->buff); |
2351 | g->panic=NULL; |
2352 | g->gcstate=0; |
2353 | g->rootgc=obj2gco(L); |
2354 | g->sweepstrgc=0; |
2355 | g->sweepgc=&g->rootgc; |
2356 | g->gray=NULL; |
2357 | g->grayagain=NULL; |
2358 | g->weak=NULL; |
2359 | g->tmudata=NULL; |
2360 | g->totalbytes=sizeof(LG); |
2361 | g->gcpause=200; |
2362 | g->gcstepmul=200; |
2363 | g->gcdept=0; |
2364 | for(i=0;i<(8+1);i++)g->mt[i]=NULL; |
2365 | if(luaD_rawrunprotected(L,f_luaopen,NULL)!=0){ |
2366 | close_state(L); |
2367 | L=NULL; |
2368 | } |
2369 | else |
2370 | {} |
2371 | return L; |
2372 | } |
2373 | static void callallgcTM(lua_State*L,void*ud){ |
2374 | UNUSED(ud); |
2375 | luaC_callGCTM(L); |
2376 | } |
2377 | static void lua_close(lua_State*L){ |
2378 | L=G(L)->mainthread; |
2379 | luaF_close(L,L->stack); |
2380 | luaC_separateudata(L,1); |
2381 | L->errfunc=0; |
2382 | do{ |
2383 | L->ci=L->base_ci; |
2384 | L->base=L->top=L->ci->base; |
2385 | L->nCcalls=L->baseCcalls=0; |
2386 | }while(luaD_rawrunprotected(L,callallgcTM,NULL)!=0); |
2387 | close_state(L); |
2388 | } |
2389 | #define getcode(fs,e)((fs)->f->code[(e)->u.s.info]) |
2390 | #define luaK_codeAsBx(fs,o,A,sBx)luaK_codeABx(fs,o,A,(sBx)+(((1<<(9+9))-1)>>1)) |
2391 | #define luaK_setmultret(fs,e)luaK_setreturns(fs,e,(-1)) |
2392 | static int luaK_codeABx(FuncState*fs,OpCode o,int A,unsigned int Bx); |
2393 | static int luaK_codeABC(FuncState*fs,OpCode o,int A,int B,int C); |
2394 | static void luaK_setreturns(FuncState*fs,expdesc*e,int nresults); |
2395 | static void luaK_patchtohere(FuncState*fs,int list); |
2396 | static void luaK_concat(FuncState*fs,int*l1,int l2); |
2397 | static int currentpc(lua_State*L,CallInfo*ci){ |
2398 | if(!isLua(ci))return-1; |
2399 | if(ci==L->ci) |
2400 | ci->savedpc=L->savedpc; |
2401 | return pcRel(ci->savedpc,ci_func(ci)->l.p); |
2402 | } |
2403 | static int currentline(lua_State*L,CallInfo*ci){ |
2404 | int pc=currentpc(L,ci); |
2405 | if(pc<0) |
2406 | return-1; |
2407 | else |
2408 | return getline_(ci_func(ci)->l.p,pc); |
2409 | } |
2410 | static int lua_getstack(lua_State*L,int level,lua_Debug*ar){ |
2411 | int status; |
2412 | CallInfo*ci; |
2413 | for(ci=L->ci;level>0&&ci>L->base_ci;ci--){ |
2414 | level--; |
2415 | if(f_isLua(ci)) |
2416 | level-=ci->tailcalls; |
2417 | } |
2418 | if(level==0&&ci>L->base_ci){ |
2419 | status=1; |
2420 | ar->i_ci=cast_int(ci-L->base_ci); |
2421 | } |
2422 | else if(level<0){ |
2423 | status=1; |
2424 | ar->i_ci=0; |
2425 | } |
2426 | else status=0; |
2427 | return status; |
2428 | } |
2429 | static Proto*getluaproto(CallInfo*ci){ |
2430 | return(isLua(ci)?ci_func(ci)->l.p:NULL); |
2431 | } |
2432 | static void funcinfo(lua_Debug*ar,Closure*cl){ |
2433 | if(cl->c.isC){ |
2434 | ar->source="=[C]" ; |
2435 | ar->linedefined=-1; |
2436 | ar->lastlinedefined=-1; |
2437 | ar->what="C" ; |
2438 | } |
2439 | else{ |
2440 | ar->source=getstr(cl->l.p->source); |
2441 | ar->linedefined=cl->l.p->linedefined; |
2442 | ar->lastlinedefined=cl->l.p->lastlinedefined; |
2443 | ar->what=(ar->linedefined==0)?"main" :"Lua" ; |
2444 | } |
2445 | luaO_chunkid(ar->short_src,ar->source,60); |
2446 | } |
2447 | static void info_tailcall(lua_Debug*ar){ |
2448 | ar->name=ar->namewhat="" ; |
2449 | ar->what="tail" ; |
2450 | ar->lastlinedefined=ar->linedefined=ar->currentline=-1; |
2451 | ar->source="=(tail call)" ; |
2452 | luaO_chunkid(ar->short_src,ar->source,60); |
2453 | ar->nups=0; |
2454 | } |
2455 | static void collectvalidlines(lua_State*L,Closure*f){ |
2456 | if(f==NULL||f->c.isC){ |
2457 | setnilvalue(L->top); |
2458 | } |
2459 | else{ |
2460 | Table*t=luaH_new(L,0,0); |
2461 | int*lineinfo=f->l.p->lineinfo; |
2462 | int i; |
2463 | for(i=0;i<f->l.p->sizelineinfo;i++) |
2464 | setbvalue(luaH_setnum(L,t,lineinfo[i]),1); |
2465 | sethvalue(L,L->top,t); |
2466 | } |
2467 | incr_top(L); |
2468 | } |
2469 | static int auxgetinfo(lua_State*L,const char*what,lua_Debug*ar, |
2470 | Closure*f,CallInfo*ci){ |
2471 | int status=1; |
2472 | if(f==NULL){ |
2473 | info_tailcall(ar); |
2474 | return status; |
2475 | } |
2476 | for(;*what;what++){ |
2477 | switch(*what){ |
2478 | case'S':{ |
2479 | funcinfo(ar,f); |
2480 | break; |
2481 | } |
2482 | case'l':{ |
2483 | ar->currentline=(ci)?currentline(L,ci):-1; |
2484 | break; |
2485 | } |
2486 | case'u':{ |
2487 | ar->nups=f->c.nupvalues; |
2488 | break; |
2489 | } |
2490 | case'n':{ |
2491 | ar->namewhat=(ci)?NULL:NULL; |
2492 | if(ar->namewhat==NULL){ |
2493 | ar->namewhat="" ; |
2494 | ar->name=NULL; |
2495 | } |
2496 | break; |
2497 | } |
2498 | case'L': |
2499 | case'f': |
2500 | break; |
2501 | default:status=0; |
2502 | } |
2503 | } |
2504 | return status; |
2505 | } |
2506 | static int lua_getinfo(lua_State*L,const char*what,lua_Debug*ar){ |
2507 | int status; |
2508 | Closure*f=NULL; |
2509 | CallInfo*ci=NULL; |
2510 | if(*what=='>'){ |
2511 | StkId func=L->top-1; |
2512 | luai_apicheck(L,ttisfunction(func)); |
2513 | what++; |
2514 | f=clvalue(func); |
2515 | L->top--; |
2516 | } |
2517 | else if(ar->i_ci!=0){ |
2518 | ci=L->base_ci+ar->i_ci; |
2519 | f=clvalue(ci->func); |
2520 | } |
2521 | status=auxgetinfo(L,what,ar,f,ci); |
2522 | if(strchr(what,'f')){ |
2523 | if(f==NULL)setnilvalue(L->top); |
2524 | else setclvalue(L,L->top,f); |
2525 | incr_top(L); |
2526 | } |
2527 | if(strchr(what,'L')) |
2528 | collectvalidlines(L,f); |
2529 | return status; |
2530 | } |
2531 | static int isinstack(CallInfo*ci,const TValue*o){ |
2532 | StkId p; |
2533 | for(p=ci->base;p<ci->top;p++) |
2534 | if(o==p)return 1; |
2535 | return 0; |
2536 | } |
2537 | static void luaG_typeerror(lua_State*L,const TValue*o,const char*op){ |
2538 | const char*name=NULL; |
2539 | const char*t=luaT_typenames[ttype(o)]; |
2540 | const char*kind=(isinstack(L->ci,o))? |
2541 | NULL: |
2542 | NULL; |
2543 | if(kind) |
2544 | luaG_runerror(L,"attempt to %s %s " LUA_QL("%s" )" (a %s value)" , |
2545 | op,kind,name,t); |
2546 | else |
2547 | luaG_runerror(L,"attempt to %s a %s value" ,op,t); |
2548 | } |
2549 | static void luaG_concaterror(lua_State*L,StkId p1,StkId p2){ |
2550 | if(ttisstring(p1)||ttisnumber(p1))p1=p2; |
2551 | luaG_typeerror(L,p1,"concatenate" ); |
2552 | } |
2553 | static void luaG_aritherror(lua_State*L,const TValue*p1,const TValue*p2){ |
2554 | TValue temp; |
2555 | if(luaV_tonumber(p1,&temp)==NULL) |
2556 | p2=p1; |
2557 | luaG_typeerror(L,p2,"perform arithmetic on" ); |
2558 | } |
2559 | static int luaG_ordererror(lua_State*L,const TValue*p1,const TValue*p2){ |
2560 | const char*t1=luaT_typenames[ttype(p1)]; |
2561 | const char*t2=luaT_typenames[ttype(p2)]; |
2562 | if(t1[2]==t2[2]) |
2563 | luaG_runerror(L,"attempt to compare two %s values" ,t1); |
2564 | else |
2565 | luaG_runerror(L,"attempt to compare %s with %s" ,t1,t2); |
2566 | return 0; |
2567 | } |
2568 | static void addinfo(lua_State*L,const char*msg){ |
2569 | CallInfo*ci=L->ci; |
2570 | if(isLua(ci)){ |
2571 | char buff[60]; |
2572 | int line=currentline(L,ci); |
2573 | luaO_chunkid(buff,getstr(getluaproto(ci)->source),60); |
2574 | luaO_pushfstring(L,"%s:%d: %s" ,buff,line,msg); |
2575 | } |
2576 | } |
2577 | static void luaG_errormsg(lua_State*L){ |
2578 | if(L->errfunc!=0){ |
2579 | StkId errfunc=restorestack(L,L->errfunc); |
2580 | if(!ttisfunction(errfunc))luaD_throw(L,5); |
2581 | setobj(L,L->top,L->top-1); |
2582 | setobj(L,L->top-1,errfunc); |
2583 | incr_top(L); |
2584 | luaD_call(L,L->top-2,1); |
2585 | } |
2586 | luaD_throw(L,2); |
2587 | } |
2588 | static void luaG_runerror(lua_State*L,const char*fmt,...){ |
2589 | va_list argp; |
2590 | va_start(argp,fmt); |
2591 | addinfo(L,luaO_pushvfstring(L,fmt,argp)); |
2592 | va_end(argp); |
2593 | luaG_errormsg(L); |
2594 | } |
2595 | static int luaZ_fill(ZIO*z){ |
2596 | size_t size; |
2597 | lua_State*L=z->L; |
2598 | const char*buff; |
2599 | buff=z->reader(L,z->data,&size); |
2600 | if(buff==NULL||size==0)return(-1); |
2601 | z->n=size-1; |
2602 | z->p=buff; |
2603 | return char2int(*(z->p++)); |
2604 | } |
2605 | static void luaZ_init(lua_State*L,ZIO*z,lua_Reader reader,void*data){ |
2606 | z->L=L; |
2607 | z->reader=reader; |
2608 | z->data=data; |
2609 | z->n=0; |
2610 | z->p=NULL; |
2611 | } |
2612 | static char*luaZ_openspace(lua_State*L,Mbuffer*buff,size_t n){ |
2613 | if(n>buff->buffsize){ |
2614 | if(n<32)n=32; |
2615 | luaZ_resizebuffer(L,buff,n); |
2616 | } |
2617 | return buff->buffer; |
2618 | } |
2619 | #define opmode(t,a,b,c,m)(((t)<<7)|((a)<<6)|((b)<<4)|((c)<<2)|(m)) |
2620 | static const lu_byte luaP_opmodes[(cast(int,OP_VARARG)+1)]={ |
2621 | opmode(0,1,OpArgR,OpArgN,iABC) |
2622 | ,opmode(0,1,OpArgK,OpArgN,iABx) |
2623 | ,opmode(0,1,OpArgU,OpArgU,iABC) |
2624 | ,opmode(0,1,OpArgR,OpArgN,iABC) |
2625 | ,opmode(0,1,OpArgU,OpArgN,iABC) |
2626 | ,opmode(0,1,OpArgK,OpArgN,iABx) |
2627 | ,opmode(0,1,OpArgR,OpArgK,iABC) |
2628 | ,opmode(0,0,OpArgK,OpArgN,iABx) |
2629 | ,opmode(0,0,OpArgU,OpArgN,iABC) |
2630 | ,opmode(0,0,OpArgK,OpArgK,iABC) |
2631 | ,opmode(0,1,OpArgU,OpArgU,iABC) |
2632 | ,opmode(0,1,OpArgR,OpArgK,iABC) |
2633 | ,opmode(0,1,OpArgK,OpArgK,iABC) |
2634 | ,opmode(0,1,OpArgK,OpArgK,iABC) |
2635 | ,opmode(0,1,OpArgK,OpArgK,iABC) |
2636 | ,opmode(0,1,OpArgK,OpArgK,iABC) |
2637 | ,opmode(0,1,OpArgK,OpArgK,iABC) |
2638 | ,opmode(0,1,OpArgK,OpArgK,iABC) |
2639 | ,opmode(0,1,OpArgR,OpArgN,iABC) |
2640 | ,opmode(0,1,OpArgR,OpArgN,iABC) |
2641 | ,opmode(0,1,OpArgR,OpArgN,iABC) |
2642 | ,opmode(0,1,OpArgR,OpArgR,iABC) |
2643 | ,opmode(0,0,OpArgR,OpArgN,iAsBx) |
2644 | ,opmode(1,0,OpArgK,OpArgK,iABC) |
2645 | ,opmode(1,0,OpArgK,OpArgK,iABC) |
2646 | ,opmode(1,0,OpArgK,OpArgK,iABC) |
2647 | ,opmode(1,1,OpArgR,OpArgU,iABC) |
2648 | ,opmode(1,1,OpArgR,OpArgU,iABC) |
2649 | ,opmode(0,1,OpArgU,OpArgU,iABC) |
2650 | ,opmode(0,1,OpArgU,OpArgU,iABC) |
2651 | ,opmode(0,0,OpArgU,OpArgN,iABC) |
2652 | ,opmode(0,1,OpArgR,OpArgN,iAsBx) |
2653 | ,opmode(0,1,OpArgR,OpArgN,iAsBx) |
2654 | ,opmode(1,0,OpArgN,OpArgU,iABC) |
2655 | ,opmode(0,0,OpArgU,OpArgU,iABC) |
2656 | ,opmode(0,0,OpArgN,OpArgN,iABC) |
2657 | ,opmode(0,1,OpArgU,OpArgN,iABx) |
2658 | ,opmode(0,1,OpArgU,OpArgN,iABC) |
2659 | }; |
2660 | #define next(ls)(ls->current=zgetc(ls->z)) |
2661 | #define currIsNewline(ls)(ls->current=='\n'||ls->current=='\r') |
2662 | static const char*const luaX_tokens[]={ |
2663 | "and" ,"break" ,"do" ,"else" ,"elseif" , |
2664 | "end" ,"false" ,"for" ,"function" ,"if" , |
2665 | "in" ,"local" ,"nil" ,"not" ,"or" ,"repeat" , |
2666 | "return" ,"then" ,"true" ,"until" ,"while" , |
2667 | ".." ,"..." ,"==" ,">=" ,"<=" ,"~=" , |
2668 | "<number>" ,"<name>" ,"<string>" ,"<eof>" , |
2669 | NULL |
2670 | }; |
2671 | #define save_and_next(ls)(save(ls,ls->current),next(ls)) |
2672 | static void save(LexState*ls,int c){ |
2673 | Mbuffer*b=ls->buff; |
2674 | if(b->n+1>b->buffsize){ |
2675 | size_t newsize; |
2676 | if(b->buffsize>=((size_t)(~(size_t)0)-2)/2) |
2677 | luaX_lexerror(ls,"lexical element too long" ,0); |
2678 | newsize=b->buffsize*2; |
2679 | luaZ_resizebuffer(ls->L,b,newsize); |
2680 | } |
2681 | b->buffer[b->n++]=cast(char,c); |
2682 | } |
2683 | static void luaX_init(lua_State*L){ |
2684 | int i; |
2685 | for(i=0;i<(cast(int,TK_WHILE-257+1));i++){ |
2686 | TString*ts=luaS_new(L,luaX_tokens[i]); |
2687 | luaS_fix(ts); |
2688 | ts->tsv.reserved=cast_byte(i+1); |
2689 | } |
2690 | } |
2691 | static const char*luaX_token2str(LexState*ls,int token){ |
2692 | if(token<257){ |
2693 | return(iscntrl(token))?luaO_pushfstring(ls->L,"char(%d)" ,token): |
2694 | luaO_pushfstring(ls->L,"%c" ,token); |
2695 | } |
2696 | else |
2697 | return luaX_tokens[token-257]; |
2698 | } |
2699 | static const char*txtToken(LexState*ls,int token){ |
2700 | switch(token){ |
2701 | case TK_NAME: |
2702 | case TK_STRING: |
2703 | case TK_NUMBER: |
2704 | save(ls,'\0'); |
2705 | return luaZ_buffer(ls->buff); |
2706 | default: |
2707 | return luaX_token2str(ls,token); |
2708 | } |
2709 | } |
2710 | static void luaX_lexerror(LexState*ls,const char*msg,int token){ |
2711 | char buff[80]; |
2712 | luaO_chunkid(buff,getstr(ls->source),80); |
2713 | msg=luaO_pushfstring(ls->L,"%s:%d: %s" ,buff,ls->linenumber,msg); |
2714 | if(token) |
2715 | luaO_pushfstring(ls->L,"%s near " LUA_QL("%s" ),msg,txtToken(ls,token)); |
2716 | luaD_throw(ls->L,3); |
2717 | } |
2718 | static void luaX_syntaxerror(LexState*ls,const char*msg){ |
2719 | luaX_lexerror(ls,msg,ls->t.token); |
2720 | } |
2721 | static TString*luaX_newstring(LexState*ls,const char*str,size_t l){ |
2722 | lua_State*L=ls->L; |
2723 | TString*ts=luaS_newlstr(L,str,l); |
2724 | TValue*o=luaH_setstr(L,ls->fs->h,ts); |
2725 | if(ttisnil(o)){ |
2726 | setbvalue(o,1); |
2727 | luaC_checkGC(L); |
2728 | } |
2729 | return ts; |
2730 | } |
2731 | static void inclinenumber(LexState*ls){ |
2732 | int old=ls->current; |
2733 | next(ls); |
2734 | if(currIsNewline(ls)&&ls->current!=old) |
2735 | next(ls); |
2736 | if(++ls->linenumber>=(INT_MAX-2)) |
2737 | luaX_syntaxerror(ls,"chunk has too many lines" ); |
2738 | } |
2739 | static void luaX_setinput(lua_State*L,LexState*ls,ZIO*z,TString*source){ |
2740 | ls->decpoint='.'; |
2741 | ls->L=L; |
2742 | ls->lookahead.token=TK_EOS; |
2743 | ls->z=z; |
2744 | ls->fs=NULL; |
2745 | ls->linenumber=1; |
2746 | ls->lastline=1; |
2747 | ls->source=source; |
2748 | luaZ_resizebuffer(ls->L,ls->buff,32); |
2749 | next(ls); |
2750 | } |
2751 | static int check_next(LexState*ls,const char*set){ |
2752 | if(!strchr(set,ls->current)) |
2753 | return 0; |
2754 | save_and_next(ls); |
2755 | return 1; |
2756 | } |
2757 | static void buffreplace(LexState*ls,char from,char to){ |
2758 | size_t n=luaZ_bufflen(ls->buff); |
2759 | char*p=luaZ_buffer(ls->buff); |
2760 | while(n--) |
2761 | if(p[n]==from)p[n]=to; |
2762 | } |
2763 | static void read_numeral(LexState*ls,SemInfo*seminfo){ |
2764 | do{ |
2765 | save_and_next(ls); |
2766 | }while(isdigit(ls->current)||ls->current=='.'); |
2767 | if(check_next(ls,"Ee" )) |
2768 | check_next(ls,"+-" ); |
2769 | while(isalnum(ls->current)||ls->current=='_') |
2770 | save_and_next(ls); |
2771 | save(ls,'\0'); |
2772 | buffreplace(ls,'.',ls->decpoint); |
2773 | if(!luaO_str2d(luaZ_buffer(ls->buff),&seminfo->r)) |
2774 | luaX_lexerror(ls,"malformed number" ,TK_NUMBER); |
2775 | } |
2776 | static int skip_sep(LexState*ls){ |
2777 | int count=0; |
2778 | int s=ls->current; |
2779 | save_and_next(ls); |
2780 | while(ls->current=='='){ |
2781 | save_and_next(ls); |
2782 | count++; |
2783 | } |
2784 | return(ls->current==s)?count:(-count)-1; |
2785 | } |
2786 | static void read_long_string(LexState*ls,SemInfo*seminfo,int sep){ |
2787 | int cont=0; |
2788 | (void)(cont); |
2789 | save_and_next(ls); |
2790 | if(currIsNewline(ls)) |
2791 | inclinenumber(ls); |
2792 | for(;;){ |
2793 | switch(ls->current){ |
2794 | case(-1): |
2795 | luaX_lexerror(ls,(seminfo)?"unfinished long string" : |
2796 | "unfinished long comment" ,TK_EOS); |
2797 | break; |
2798 | case']':{ |
2799 | if(skip_sep(ls)==sep){ |
2800 | save_and_next(ls); |
2801 | goto endloop; |
2802 | } |
2803 | break; |
2804 | } |
2805 | case'\n': |
2806 | case'\r':{ |
2807 | save(ls,'\n'); |
2808 | inclinenumber(ls); |
2809 | if(!seminfo)luaZ_resetbuffer(ls->buff); |
2810 | break; |
2811 | } |
2812 | default:{ |
2813 | if(seminfo)save_and_next(ls); |
2814 | else next(ls); |
2815 | } |
2816 | } |
2817 | }endloop: |
2818 | if(seminfo) |
2819 | seminfo->ts=luaX_newstring(ls,luaZ_buffer(ls->buff)+(2+sep), |
2820 | luaZ_bufflen(ls->buff)-2*(2+sep)); |
2821 | } |
2822 | static void read_string(LexState*ls,int del,SemInfo*seminfo){ |
2823 | save_and_next(ls); |
2824 | while(ls->current!=del){ |
2825 | switch(ls->current){ |
2826 | case(-1): |
2827 | luaX_lexerror(ls,"unfinished string" ,TK_EOS); |
2828 | continue; |
2829 | case'\n': |
2830 | case'\r': |
2831 | luaX_lexerror(ls,"unfinished string" ,TK_STRING); |
2832 | continue; |
2833 | case'\\':{ |
2834 | int c; |
2835 | next(ls); |
2836 | switch(ls->current){ |
2837 | case'a':c='\a';break; |
2838 | case'b':c='\b';break; |
2839 | case'f':c='\f';break; |
2840 | case'n':c='\n';break; |
2841 | case'r':c='\r';break; |
2842 | case't':c='\t';break; |
2843 | case'v':c='\v';break; |
2844 | case'\n': |
2845 | case'\r':save(ls,'\n');inclinenumber(ls);continue; |
2846 | case(-1):continue; |
2847 | default:{ |
2848 | if(!isdigit(ls->current)) |
2849 | save_and_next(ls); |
2850 | else{ |
2851 | int i=0; |
2852 | c=0; |
2853 | do{ |
2854 | c=10*c+(ls->current-'0'); |
2855 | next(ls); |
2856 | }while(++i<3&&isdigit(ls->current)); |
2857 | if(c>UCHAR_MAX) |
2858 | luaX_lexerror(ls,"escape sequence too large" ,TK_STRING); |
2859 | save(ls,c); |
2860 | } |
2861 | continue; |
2862 | } |
2863 | } |
2864 | save(ls,c); |
2865 | next(ls); |
2866 | continue; |
2867 | } |
2868 | default: |
2869 | save_and_next(ls); |
2870 | } |
2871 | } |
2872 | save_and_next(ls); |
2873 | seminfo->ts=luaX_newstring(ls,luaZ_buffer(ls->buff)+1, |
2874 | luaZ_bufflen(ls->buff)-2); |
2875 | } |
2876 | static int llex(LexState*ls,SemInfo*seminfo){ |
2877 | luaZ_resetbuffer(ls->buff); |
2878 | for(;;){ |
2879 | switch(ls->current){ |
2880 | case'\n': |
2881 | case'\r':{ |
2882 | inclinenumber(ls); |
2883 | continue; |
2884 | } |
2885 | case'-':{ |
2886 | next(ls); |
2887 | if(ls->current!='-')return'-'; |
2888 | next(ls); |
2889 | if(ls->current=='['){ |
2890 | int sep=skip_sep(ls); |
2891 | luaZ_resetbuffer(ls->buff); |
2892 | if(sep>=0){ |
2893 | read_long_string(ls,NULL,sep); |
2894 | luaZ_resetbuffer(ls->buff); |
2895 | continue; |
2896 | } |
2897 | } |
2898 | while(!currIsNewline(ls)&&ls->current!=(-1)) |
2899 | next(ls); |
2900 | continue; |
2901 | } |
2902 | case'[':{ |
2903 | int sep=skip_sep(ls); |
2904 | if(sep>=0){ |
2905 | read_long_string(ls,seminfo,sep); |
2906 | return TK_STRING; |
2907 | } |
2908 | else if(sep==-1)return'['; |
2909 | else luaX_lexerror(ls,"invalid long string delimiter" ,TK_STRING); |
2910 | } |
2911 | case'=':{ |
2912 | next(ls); |
2913 | if(ls->current!='=')return'='; |
2914 | else{next(ls);return TK_EQ;} |
2915 | } |
2916 | case'<':{ |
2917 | next(ls); |
2918 | if(ls->current!='=')return'<'; |
2919 | else{next(ls);return TK_LE;} |
2920 | } |
2921 | case'>':{ |
2922 | next(ls); |
2923 | if(ls->current!='=')return'>'; |
2924 | else{next(ls);return TK_GE;} |
2925 | } |
2926 | case'~':{ |
2927 | next(ls); |
2928 | if(ls->current!='=')return'~'; |
2929 | else{next(ls);return TK_NE;} |
2930 | } |
2931 | case'"': |
2932 | case'\'':{ |
2933 | read_string(ls,ls->current,seminfo); |
2934 | return TK_STRING; |
2935 | } |
2936 | case'.':{ |
2937 | save_and_next(ls); |
2938 | if(check_next(ls,"." )){ |
2939 | if(check_next(ls,"." )) |
2940 | return TK_DOTS; |
2941 | else return TK_CONCAT; |
2942 | } |
2943 | else if(!isdigit(ls->current))return'.'; |
2944 | else{ |
2945 | read_numeral(ls,seminfo); |
2946 | return TK_NUMBER; |
2947 | } |
2948 | } |
2949 | case(-1):{ |
2950 | return TK_EOS; |
2951 | } |
2952 | default:{ |
2953 | if(isspace(ls->current)){ |
2954 | next(ls); |
2955 | continue; |
2956 | } |
2957 | else if(isdigit(ls->current)){ |
2958 | read_numeral(ls,seminfo); |
2959 | return TK_NUMBER; |
2960 | } |
2961 | else if(isalpha(ls->current)||ls->current=='_'){ |
2962 | TString*ts; |
2963 | do{ |
2964 | save_and_next(ls); |
2965 | }while(isalnum(ls->current)||ls->current=='_'); |
2966 | ts=luaX_newstring(ls,luaZ_buffer(ls->buff), |
2967 | luaZ_bufflen(ls->buff)); |
2968 | if(ts->tsv.reserved>0) |
2969 | return ts->tsv.reserved-1+257; |
2970 | else{ |
2971 | seminfo->ts=ts; |
2972 | return TK_NAME; |
2973 | } |
2974 | } |
2975 | else{ |
2976 | int c=ls->current; |
2977 | next(ls); |
2978 | return c; |
2979 | } |
2980 | } |
2981 | } |
2982 | } |
2983 | } |
2984 | static void luaX_next(LexState*ls){ |
2985 | ls->lastline=ls->linenumber; |
2986 | if(ls->lookahead.token!=TK_EOS){ |
2987 | ls->t=ls->lookahead; |
2988 | ls->lookahead.token=TK_EOS; |
2989 | } |
2990 | else |
2991 | ls->t.token=llex(ls,&ls->t.seminfo); |
2992 | } |
2993 | static void luaX_lookahead(LexState*ls){ |
2994 | ls->lookahead.token=llex(ls,&ls->lookahead.seminfo); |
2995 | } |
2996 | #define hasjumps(e)((e)->t!=(e)->f) |
2997 | static int isnumeral(expdesc*e){ |
2998 | return(e->k==VKNUM&&e->t==(-1)&&e->f==(-1)); |
2999 | } |
3000 | static void luaK_nil(FuncState*fs,int from,int n){ |
3001 | Instruction*previous; |
3002 | if(fs->pc>fs->lasttarget){ |
3003 | if(fs->pc==0){ |
3004 | if(from>=fs->nactvar) |
3005 | return; |
3006 | } |
3007 | else{ |
3008 | previous=&fs->f->code[fs->pc-1]; |
3009 | if(GET_OPCODE(*previous)==OP_LOADNIL){ |
3010 | int pfrom=GETARG_A(*previous); |
3011 | int pto=GETARG_B(*previous); |
3012 | if(pfrom<=from&&from<=pto+1){ |
3013 | if(from+n-1>pto) |
3014 | SETARG_B(*previous,from+n-1); |
3015 | return; |
3016 | } |
3017 | } |
3018 | } |
3019 | } |
3020 | luaK_codeABC(fs,OP_LOADNIL,from,from+n-1,0); |
3021 | } |
3022 | static int luaK_jump(FuncState*fs){ |
3023 | int jpc=fs->jpc; |
3024 | int j; |
3025 | fs->jpc=(-1); |
3026 | j=luaK_codeAsBx(fs,OP_JMP,0,(-1)); |
3027 | luaK_concat(fs,&j,jpc); |
3028 | return j; |
3029 | } |
3030 | static void luaK_ret(FuncState*fs,int first,int nret){ |
3031 | luaK_codeABC(fs,OP_RETURN,first,nret+1,0); |
3032 | } |
3033 | static int condjump(FuncState*fs,OpCode op,int A,int B,int C){ |
3034 | luaK_codeABC(fs,op,A,B,C); |
3035 | return luaK_jump(fs); |
3036 | } |
3037 | static void fixjump(FuncState*fs,int pc,int dest){ |
3038 | Instruction*jmp=&fs->f->code[pc]; |
3039 | int offset=dest-(pc+1); |
3040 | if(abs(offset)>(((1<<(9+9))-1)>>1)) |
3041 | luaX_syntaxerror(fs->ls,"control structure too long" ); |
3042 | SETARG_sBx(*jmp,offset); |
3043 | } |
3044 | static int luaK_getlabel(FuncState*fs){ |
3045 | fs->lasttarget=fs->pc; |
3046 | return fs->pc; |
3047 | } |
3048 | static int getjump(FuncState*fs,int pc){ |
3049 | int offset=GETARG_sBx(fs->f->code[pc]); |
3050 | if(offset==(-1)) |
3051 | return(-1); |
3052 | else |
3053 | return(pc+1)+offset; |
3054 | } |
3055 | static Instruction*getjumpcontrol(FuncState*fs,int pc){ |
3056 | Instruction*pi=&fs->f->code[pc]; |
3057 | if(pc>=1&&testTMode(GET_OPCODE(*(pi-1)))) |
3058 | return pi-1; |
3059 | else |
3060 | return pi; |
3061 | } |
3062 | static int need_value(FuncState*fs,int list){ |
3063 | for(;list!=(-1);list=getjump(fs,list)){ |
3064 | Instruction i=*getjumpcontrol(fs,list); |
3065 | if(GET_OPCODE(i)!=OP_TESTSET)return 1; |
3066 | } |
3067 | return 0; |
3068 | } |
3069 | static int patchtestreg(FuncState*fs,int node,int reg){ |
3070 | Instruction*i=getjumpcontrol(fs,node); |
3071 | if(GET_OPCODE(*i)!=OP_TESTSET) |
3072 | return 0; |
3073 | if(reg!=((1<<8)-1)&®!=GETARG_B(*i)) |
3074 | SETARG_A(*i,reg); |
3075 | else |
3076 | *i=CREATE_ABC(OP_TEST,GETARG_B(*i),0,GETARG_C(*i)); |
3077 | return 1; |
3078 | } |
3079 | static void removevalues(FuncState*fs,int list){ |
3080 | for(;list!=(-1);list=getjump(fs,list)) |
3081 | patchtestreg(fs,list,((1<<8)-1)); |
3082 | } |
3083 | static void patchlistaux(FuncState*fs,int list,int vtarget,int reg, |
3084 | int dtarget){ |
3085 | while(list!=(-1)){ |
3086 | int next=getjump(fs,list); |
3087 | if(patchtestreg(fs,list,reg)) |
3088 | fixjump(fs,list,vtarget); |
3089 | else |
3090 | fixjump(fs,list,dtarget); |
3091 | list=next; |
3092 | } |
3093 | } |
3094 | static void dischargejpc(FuncState*fs){ |
3095 | patchlistaux(fs,fs->jpc,fs->pc,((1<<8)-1),fs->pc); |
3096 | fs->jpc=(-1); |
3097 | } |
3098 | static void luaK_patchlist(FuncState*fs,int list,int target){ |
3099 | if(target==fs->pc) |
3100 | luaK_patchtohere(fs,list); |
3101 | else{ |
3102 | patchlistaux(fs,list,target,((1<<8)-1),target); |
3103 | } |
3104 | } |
3105 | static void luaK_patchtohere(FuncState*fs,int list){ |
3106 | luaK_getlabel(fs); |
3107 | luaK_concat(fs,&fs->jpc,list); |
3108 | } |
3109 | static void luaK_concat(FuncState*fs,int*l1,int l2){ |
3110 | if(l2==(-1))return; |
3111 | else if(*l1==(-1)) |
3112 | *l1=l2; |
3113 | else{ |
3114 | int list=*l1; |
3115 | int next; |
3116 | while((next=getjump(fs,list))!=(-1)) |
3117 | list=next; |
3118 | fixjump(fs,list,l2); |
3119 | } |
3120 | } |
3121 | static void luaK_checkstack(FuncState*fs,int n){ |
3122 | int newstack=fs->freereg+n; |
3123 | if(newstack>fs->f->maxstacksize){ |
3124 | if(newstack>=250) |
3125 | luaX_syntaxerror(fs->ls,"function or expression too complex" ); |
3126 | fs->f->maxstacksize=cast_byte(newstack); |
3127 | } |
3128 | } |
3129 | static void luaK_reserveregs(FuncState*fs,int n){ |
3130 | luaK_checkstack(fs,n); |
3131 | fs->freereg+=n; |
3132 | } |
3133 | static void freereg(FuncState*fs,int reg){ |
3134 | if(!ISK(reg)&®>=fs->nactvar){ |
3135 | fs->freereg--; |
3136 | } |
3137 | } |
3138 | static void freeexp(FuncState*fs,expdesc*e){ |
3139 | if(e->k==VNONRELOC) |
3140 | freereg(fs,e->u.s.info); |
3141 | } |
3142 | static int addk(FuncState*fs,TValue*k,TValue*v){ |
3143 | lua_State*L=fs->L; |
3144 | TValue*idx=luaH_set(L,fs->h,k); |
3145 | Proto*f=fs->f; |
3146 | int oldsize=f->sizek; |
3147 | if(ttisnumber(idx)){ |
3148 | return cast_int(nvalue(idx)); |
3149 | } |
3150 | else{ |
3151 | setnvalue(idx,cast_num(fs->nk)); |
3152 | luaM_growvector(L,f->k,fs->nk,f->sizek,TValue, |
3153 | ((1<<(9+9))-1),"constant table overflow" ); |
3154 | while(oldsize<f->sizek)setnilvalue(&f->k[oldsize++]); |
3155 | setobj(L,&f->k[fs->nk],v); |
3156 | luaC_barrier(L,f,v); |
3157 | return fs->nk++; |
3158 | } |
3159 | } |
3160 | static int luaK_stringK(FuncState*fs,TString*s){ |
3161 | TValue o; |
3162 | setsvalue(fs->L,&o,s); |
3163 | return addk(fs,&o,&o); |
3164 | } |
3165 | static int luaK_numberK(FuncState*fs,lua_Number r){ |
3166 | TValue o; |
3167 | setnvalue(&o,r); |
3168 | return addk(fs,&o,&o); |
3169 | } |
3170 | static int boolK(FuncState*fs,int b){ |
3171 | TValue o; |
3172 | setbvalue(&o,b); |
3173 | return addk(fs,&o,&o); |
3174 | } |
3175 | static int nilK(FuncState*fs){ |
3176 | TValue k,v; |
3177 | setnilvalue(&v); |
3178 | sethvalue(fs->L,&k,fs->h); |
3179 | return addk(fs,&k,&v); |
3180 | } |
3181 | static void luaK_setreturns(FuncState*fs,expdesc*e,int nresults){ |
3182 | if(e->k==VCALL){ |
3183 | SETARG_C(getcode(fs,e),nresults+1); |
3184 | } |
3185 | else if(e->k==VVARARG){ |
3186 | SETARG_B(getcode(fs,e),nresults+1); |
3187 | SETARG_A(getcode(fs,e),fs->freereg); |
3188 | luaK_reserveregs(fs,1); |
3189 | } |
3190 | } |
3191 | static void luaK_setoneret(FuncState*fs,expdesc*e){ |
3192 | if(e->k==VCALL){ |
3193 | e->k=VNONRELOC; |
3194 | e->u.s.info=GETARG_A(getcode(fs,e)); |
3195 | } |
3196 | else if(e->k==VVARARG){ |
3197 | SETARG_B(getcode(fs,e),2); |
3198 | e->k=VRELOCABLE; |
3199 | } |
3200 | } |
3201 | static void luaK_dischargevars(FuncState*fs,expdesc*e){ |
3202 | switch(e->k){ |
3203 | case VLOCAL:{ |
3204 | e->k=VNONRELOC; |
3205 | break; |
3206 | } |
3207 | case VUPVAL:{ |
3208 | e->u.s.info=luaK_codeABC(fs,OP_GETUPVAL,0,e->u.s.info,0); |
3209 | e->k=VRELOCABLE; |
3210 | break; |
3211 | } |
3212 | case VGLOBAL:{ |
3213 | e->u.s.info=luaK_codeABx(fs,OP_GETGLOBAL,0,e->u.s.info); |
3214 | e->k=VRELOCABLE; |
3215 | break; |
3216 | } |
3217 | case VINDEXED:{ |
3218 | freereg(fs,e->u.s.aux); |
3219 | freereg(fs,e->u.s.info); |
3220 | e->u.s.info=luaK_codeABC(fs,OP_GETTABLE,0,e->u.s.info,e->u.s.aux); |
3221 | e->k=VRELOCABLE; |
3222 | break; |
3223 | } |
3224 | case VVARARG: |
3225 | case VCALL:{ |
3226 | luaK_setoneret(fs,e); |
3227 | break; |
3228 | } |
3229 | default:break; |
3230 | } |
3231 | } |
3232 | static int code_label(FuncState*fs,int A,int b,int jump){ |
3233 | luaK_getlabel(fs); |
3234 | return luaK_codeABC(fs,OP_LOADBOOL,A,b,jump); |
3235 | } |
3236 | static void discharge2reg(FuncState*fs,expdesc*e,int reg){ |
3237 | luaK_dischargevars(fs,e); |
3238 | switch(e->k){ |
3239 | case VNIL:{ |
3240 | luaK_nil(fs,reg,1); |
3241 | break; |
3242 | } |
3243 | case VFALSE:case VTRUE:{ |
3244 | luaK_codeABC(fs,OP_LOADBOOL,reg,e->k==VTRUE,0); |
3245 | break; |
3246 | } |
3247 | case VK:{ |
3248 | luaK_codeABx(fs,OP_LOADK,reg,e->u.s.info); |
3249 | break; |
3250 | } |
3251 | case VKNUM:{ |
3252 | luaK_codeABx(fs,OP_LOADK,reg,luaK_numberK(fs,e->u.nval)); |
3253 | break; |
3254 | } |
3255 | case VRELOCABLE:{ |
3256 | Instruction*pc=&getcode(fs,e); |
3257 | SETARG_A(*pc,reg); |
3258 | break; |
3259 | } |
3260 | case VNONRELOC:{ |
3261 | if(reg!=e->u.s.info) |
3262 | luaK_codeABC(fs,OP_MOVE,reg,e->u.s.info,0); |
3263 | break; |
3264 | } |
3265 | default:{ |
3266 | return; |
3267 | } |
3268 | } |
3269 | e->u.s.info=reg; |
3270 | e->k=VNONRELOC; |
3271 | } |
3272 | static void discharge2anyreg(FuncState*fs,expdesc*e){ |
3273 | if(e->k!=VNONRELOC){ |
3274 | luaK_reserveregs(fs,1); |
3275 | discharge2reg(fs,e,fs->freereg-1); |
3276 | } |
3277 | } |
3278 | static void exp2reg(FuncState*fs,expdesc*e,int reg){ |
3279 | discharge2reg(fs,e,reg); |
3280 | if(e->k==VJMP) |
3281 | luaK_concat(fs,&e->t,e->u.s.info); |
3282 | if(hasjumps(e)){ |
3283 | int final; |
3284 | int p_f=(-1); |
3285 | int p_t=(-1); |
3286 | if(need_value(fs,e->t)||need_value(fs,e->f)){ |
3287 | int fj=(e->k==VJMP)?(-1):luaK_jump(fs); |
3288 | p_f=code_label(fs,reg,0,1); |
3289 | p_t=code_label(fs,reg,1,0); |
3290 | luaK_patchtohere(fs,fj); |
3291 | } |
3292 | final=luaK_getlabel(fs); |
3293 | patchlistaux(fs,e->f,final,reg,p_f); |
3294 | patchlistaux(fs,e->t,final,reg,p_t); |
3295 | } |
3296 | e->f=e->t=(-1); |
3297 | e->u.s.info=reg; |
3298 | e->k=VNONRELOC; |
3299 | } |
3300 | static void luaK_exp2nextreg(FuncState*fs,expdesc*e){ |
3301 | luaK_dischargevars(fs,e); |
3302 | freeexp(fs,e); |
3303 | luaK_reserveregs(fs,1); |
3304 | exp2reg(fs,e,fs->freereg-1); |
3305 | } |
3306 | static int luaK_exp2anyreg(FuncState*fs,expdesc*e){ |
3307 | luaK_dischargevars(fs,e); |
3308 | if(e->k==VNONRELOC){ |
3309 | if(!hasjumps(e))return e->u.s.info; |
3310 | if(e->u.s.info>=fs->nactvar){ |
3311 | exp2reg(fs,e,e->u.s.info); |
3312 | return e->u.s.info; |
3313 | } |
3314 | } |
3315 | luaK_exp2nextreg(fs,e); |
3316 | return e->u.s.info; |
3317 | } |
3318 | static void luaK_exp2val(FuncState*fs,expdesc*e){ |
3319 | if(hasjumps(e)) |
3320 | luaK_exp2anyreg(fs,e); |
3321 | else |
3322 | luaK_dischargevars(fs,e); |
3323 | } |
3324 | static int luaK_exp2RK(FuncState*fs,expdesc*e){ |
3325 | luaK_exp2val(fs,e); |
3326 | switch(e->k){ |
3327 | case VKNUM: |
3328 | case VTRUE: |
3329 | case VFALSE: |
3330 | case VNIL:{ |
3331 | if(fs->nk<=((1<<(9-1))-1)){ |
3332 | e->u.s.info=(e->k==VNIL)?nilK(fs): |
3333 | (e->k==VKNUM)?luaK_numberK(fs,e->u.nval): |
3334 | boolK(fs,(e->k==VTRUE)); |
3335 | e->k=VK; |
3336 | return RKASK(e->u.s.info); |
3337 | } |
3338 | else break; |
3339 | } |
3340 | case VK:{ |
3341 | if(e->u.s.info<=((1<<(9-1))-1)) |
3342 | return RKASK(e->u.s.info); |
3343 | else break; |
3344 | } |
3345 | default:break; |
3346 | } |
3347 | return luaK_exp2anyreg(fs,e); |
3348 | } |
3349 | static void luaK_storevar(FuncState*fs,expdesc*var,expdesc*ex){ |
3350 | switch(var->k){ |
3351 | case VLOCAL:{ |
3352 | freeexp(fs,ex); |
3353 | exp2reg(fs,ex,var->u.s.info); |
3354 | return; |
3355 | } |
3356 | case VUPVAL:{ |
3357 | int e=luaK_exp2anyreg(fs,ex); |
3358 | luaK_codeABC(fs,OP_SETUPVAL,e,var->u.s.info,0); |
3359 | break; |
3360 | } |
3361 | case VGLOBAL:{ |
3362 | int e=luaK_exp2anyreg(fs,ex); |
3363 | luaK_codeABx(fs,OP_SETGLOBAL,e,var->u.s.info); |
3364 | break; |
3365 | } |
3366 | case VINDEXED:{ |
3367 | int e=luaK_exp2RK(fs,ex); |
3368 | luaK_codeABC(fs,OP_SETTABLE,var->u.s.info,var->u.s.aux,e); |
3369 | break; |
3370 | } |
3371 | default:{ |
3372 | break; |
3373 | } |
3374 | } |
3375 | freeexp(fs,ex); |
3376 | } |
3377 | static void luaK_self(FuncState*fs,expdesc*e,expdesc*key){ |
3378 | int func; |
3379 | luaK_exp2anyreg(fs,e); |
3380 | freeexp(fs,e); |
3381 | func=fs->freereg; |
3382 | luaK_reserveregs(fs,2); |
3383 | luaK_codeABC(fs,OP_SELF,func,e->u.s.info,luaK_exp2RK(fs,key)); |
3384 | freeexp(fs,key); |
3385 | e->u.s.info=func; |
3386 | e->k=VNONRELOC; |
3387 | } |
3388 | static void invertjump(FuncState*fs,expdesc*e){ |
3389 | Instruction*pc=getjumpcontrol(fs,e->u.s.info); |
3390 | SETARG_A(*pc,!(GETARG_A(*pc))); |
3391 | } |
3392 | static int jumponcond(FuncState*fs,expdesc*e,int cond){ |
3393 | if(e->k==VRELOCABLE){ |
3394 | Instruction ie=getcode(fs,e); |
3395 | if(GET_OPCODE(ie)==OP_NOT){ |
3396 | fs->pc--; |
3397 | return condjump(fs,OP_TEST,GETARG_B(ie),0,!cond); |
3398 | } |
3399 | } |
3400 | discharge2anyreg(fs,e); |
3401 | freeexp(fs,e); |
3402 | return condjump(fs,OP_TESTSET,((1<<8)-1),e->u.s.info,cond); |
3403 | } |
3404 | static void luaK_goiftrue(FuncState*fs,expdesc*e){ |
3405 | int pc; |
3406 | luaK_dischargevars(fs,e); |
3407 | switch(e->k){ |
3408 | case VK:case VKNUM:case VTRUE:{ |
3409 | pc=(-1); |
3410 | break; |
3411 | } |
3412 | case VJMP:{ |
3413 | invertjump(fs,e); |
3414 | pc=e->u.s.info; |
3415 | break; |
3416 | } |
3417 | default:{ |
3418 | pc=jumponcond(fs,e,0); |
3419 | break; |
3420 | } |
3421 | } |
3422 | luaK_concat(fs,&e->f,pc); |
3423 | luaK_patchtohere(fs,e->t); |
3424 | e->t=(-1); |
3425 | } |
3426 | static void luaK_goiffalse(FuncState*fs,expdesc*e){ |
3427 | int pc; |
3428 | luaK_dischargevars(fs,e); |
3429 | switch(e->k){ |
3430 | case VNIL:case VFALSE:{ |
3431 | pc=(-1); |
3432 | break; |
3433 | } |
3434 | case VJMP:{ |
3435 | pc=e->u.s.info; |
3436 | break; |
3437 | } |
3438 | default:{ |
3439 | pc=jumponcond(fs,e,1); |
3440 | break; |
3441 | } |
3442 | } |
3443 | luaK_concat(fs,&e->t,pc); |
3444 | luaK_patchtohere(fs,e->f); |
3445 | e->f=(-1); |
3446 | } |
3447 | static void codenot(FuncState*fs,expdesc*e){ |
3448 | luaK_dischargevars(fs,e); |
3449 | switch(e->k){ |
3450 | case VNIL:case VFALSE:{ |
3451 | e->k=VTRUE; |
3452 | break; |
3453 | } |
3454 | case VK:case VKNUM:case VTRUE:{ |
3455 | e->k=VFALSE; |
3456 | break; |
3457 | } |
3458 | case VJMP:{ |
3459 | invertjump(fs,e); |
3460 | break; |
3461 | } |
3462 | case VRELOCABLE: |
3463 | case VNONRELOC:{ |
3464 | discharge2anyreg(fs,e); |
3465 | freeexp(fs,e); |
3466 | e->u.s.info=luaK_codeABC(fs,OP_NOT,0,e->u.s.info,0); |
3467 | e->k=VRELOCABLE; |
3468 | break; |
3469 | } |
3470 | default:{ |
3471 | break; |
3472 | } |
3473 | } |
3474 | {int temp=e->f;e->f=e->t;e->t=temp;} |
3475 | removevalues(fs,e->f); |
3476 | removevalues(fs,e->t); |
3477 | } |
3478 | static void luaK_indexed(FuncState*fs,expdesc*t,expdesc*k){ |
3479 | t->u.s.aux=luaK_exp2RK(fs,k); |
3480 | t->k=VINDEXED; |
3481 | } |
3482 | static int constfolding(OpCode op,expdesc*e1,expdesc*e2){ |
3483 | lua_Number v1,v2,r; |
3484 | if(!isnumeral(e1)||!isnumeral(e2))return 0; |
3485 | v1=e1->u.nval; |
3486 | v2=e2->u.nval; |
3487 | switch(op){ |
3488 | case OP_ADD:r=luai_numadd(v1,v2);break; |
3489 | case OP_SUB:r=luai_numsub(v1,v2);break; |
3490 | case OP_MUL:r=luai_nummul(v1,v2);break; |
3491 | case OP_DIV: |
3492 | if(v2==0)return 0; |
3493 | r=luai_numdiv(v1,v2);break; |
3494 | case OP_MOD: |
3495 | if(v2==0)return 0; |
3496 | r=luai_nummod(v1,v2);break; |
3497 | case OP_POW:r=luai_numpow(v1,v2);break; |
3498 | case OP_UNM:r=luai_numunm(v1);break; |
3499 | case OP_LEN:return 0; |
3500 | default:r=0;break; |
3501 | } |
3502 | if(luai_numisnan(r))return 0; |
3503 | e1->u.nval=r; |
3504 | return 1; |
3505 | } |
3506 | static void codearith(FuncState*fs,OpCode op,expdesc*e1,expdesc*e2){ |
3507 | if(constfolding(op,e1,e2)) |
3508 | return; |
3509 | else{ |
3510 | int o2=(op!=OP_UNM&&op!=OP_LEN)?luaK_exp2RK(fs,e2):0; |
3511 | int o1=luaK_exp2RK(fs,e1); |
3512 | if(o1>o2){ |
3513 | freeexp(fs,e1); |
3514 | freeexp(fs,e2); |
3515 | } |
3516 | else{ |
3517 | freeexp(fs,e2); |
3518 | freeexp(fs,e1); |
3519 | } |
3520 | e1->u.s.info=luaK_codeABC(fs,op,0,o1,o2); |
3521 | e1->k=VRELOCABLE; |
3522 | } |
3523 | } |
3524 | static void codecomp(FuncState*fs,OpCode op,int cond,expdesc*e1, |
3525 | expdesc*e2){ |
3526 | int o1=luaK_exp2RK(fs,e1); |
3527 | int o2=luaK_exp2RK(fs,e2); |
3528 | freeexp(fs,e2); |
3529 | freeexp(fs,e1); |
3530 | if(cond==0&&op!=OP_EQ){ |
3531 | int temp; |
3532 | temp=o1;o1=o2;o2=temp; |
3533 | cond=1; |
3534 | } |
3535 | e1->u.s.info=condjump(fs,op,cond,o1,o2); |
3536 | e1->k=VJMP; |
3537 | } |
3538 | static void luaK_prefix(FuncState*fs,UnOpr op,expdesc*e){ |
3539 | expdesc e2; |
3540 | e2.t=e2.f=(-1);e2.k=VKNUM;e2.u.nval=0; |
3541 | switch(op){ |
3542 | case OPR_MINUS:{ |
3543 | if(!isnumeral(e)) |
3544 | luaK_exp2anyreg(fs,e); |
3545 | codearith(fs,OP_UNM,e,&e2); |
3546 | break; |
3547 | } |
3548 | case OPR_NOT:codenot(fs,e);break; |
3549 | case OPR_LEN:{ |
3550 | luaK_exp2anyreg(fs,e); |
3551 | codearith(fs,OP_LEN,e,&e2); |
3552 | break; |
3553 | } |
3554 | default:; |
3555 | } |
3556 | } |
3557 | static void luaK_infix(FuncState*fs,BinOpr op,expdesc*v){ |
3558 | switch(op){ |
3559 | case OPR_AND:{ |
3560 | luaK_goiftrue(fs,v); |
3561 | break; |
3562 | } |
3563 | case OPR_OR:{ |
3564 | luaK_goiffalse(fs,v); |
3565 | break; |
3566 | } |
3567 | case OPR_CONCAT:{ |
3568 | luaK_exp2nextreg(fs,v); |
3569 | break; |
3570 | } |
3571 | case OPR_ADD:case OPR_SUB:case OPR_MUL:case OPR_DIV: |
3572 | case OPR_MOD:case OPR_POW:{ |
3573 | if(!isnumeral(v))luaK_exp2RK(fs,v); |
3574 | break; |
3575 | } |
3576 | default:{ |
3577 | luaK_exp2RK(fs,v); |
3578 | break; |
3579 | } |
3580 | } |
3581 | } |
3582 | static void luaK_posfix(FuncState*fs,BinOpr op,expdesc*e1,expdesc*e2){ |
3583 | switch(op){ |
3584 | case OPR_AND:{ |
3585 | luaK_dischargevars(fs,e2); |
3586 | luaK_concat(fs,&e2->f,e1->f); |
3587 | *e1=*e2; |
3588 | break; |
3589 | } |
3590 | case OPR_OR:{ |
3591 | luaK_dischargevars(fs,e2); |
3592 | luaK_concat(fs,&e2->t,e1->t); |
3593 | *e1=*e2; |
3594 | break; |
3595 | } |
3596 | case OPR_CONCAT:{ |
3597 | luaK_exp2val(fs,e2); |
3598 | if(e2->k==VRELOCABLE&&GET_OPCODE(getcode(fs,e2))==OP_CONCAT){ |
3599 | freeexp(fs,e1); |
3600 | SETARG_B(getcode(fs,e2),e1->u.s.info); |
3601 | e1->k=VRELOCABLE;e1->u.s.info=e2->u.s.info; |
3602 | } |
3603 | else{ |
3604 | luaK_exp2nextreg(fs,e2); |
3605 | codearith(fs,OP_CONCAT,e1,e2); |
3606 | } |
3607 | break; |
3608 | } |
3609 | case OPR_ADD:codearith(fs,OP_ADD,e1,e2);break; |
3610 | case OPR_SUB:codearith(fs,OP_SUB,e1,e2);break; |
3611 | case OPR_MUL:codearith(fs,OP_MUL,e1,e2);break; |
3612 | case OPR_DIV:codearith(fs,OP_DIV,e1,e2);break; |
3613 | case OPR_MOD:codearith(fs,OP_MOD,e1,e2);break; |
3614 | case OPR_POW:codearith(fs,OP_POW,e1,e2);break; |
3615 | case OPR_EQ:codecomp(fs,OP_EQ,1,e1,e2);break; |
3616 | case OPR_NE:codecomp(fs,OP_EQ,0,e1,e2);break; |
3617 | case OPR_LT:codecomp(fs,OP_LT,1,e1,e2);break; |
3618 | case OPR_LE:codecomp(fs,OP_LE,1,e1,e2);break; |
3619 | case OPR_GT:codecomp(fs,OP_LT,0,e1,e2);break; |
3620 | case OPR_GE:codecomp(fs,OP_LE,0,e1,e2);break; |
3621 | default:; |
3622 | } |
3623 | } |
3624 | static void luaK_fixline(FuncState*fs,int line){ |
3625 | fs->f->lineinfo[fs->pc-1]=line; |
3626 | } |
3627 | static int luaK_code(FuncState*fs,Instruction i,int line){ |
3628 | Proto*f=fs->f; |
3629 | dischargejpc(fs); |
3630 | luaM_growvector(fs->L,f->code,fs->pc,f->sizecode,Instruction, |
3631 | (INT_MAX-2),"code size overflow" ); |
3632 | f->code[fs->pc]=i; |
3633 | luaM_growvector(fs->L,f->lineinfo,fs->pc,f->sizelineinfo,int, |
3634 | (INT_MAX-2),"code size overflow" ); |
3635 | f->lineinfo[fs->pc]=line; |
3636 | return fs->pc++; |
3637 | } |
3638 | static int luaK_codeABC(FuncState*fs,OpCode o,int a,int b,int c){ |
3639 | return luaK_code(fs,CREATE_ABC(o,a,b,c),fs->ls->lastline); |
3640 | } |
3641 | static int luaK_codeABx(FuncState*fs,OpCode o,int a,unsigned int bc){ |
3642 | return luaK_code(fs,CREATE_ABx(o,a,bc),fs->ls->lastline); |
3643 | } |
3644 | static void luaK_setlist(FuncState*fs,int base,int nelems,int tostore){ |
3645 | int c=(nelems-1)/50+1; |
3646 | int b=(tostore==(-1))?0:tostore; |
3647 | if(c<=((1<<9)-1)) |
3648 | luaK_codeABC(fs,OP_SETLIST,base,b,c); |
3649 | else{ |
3650 | luaK_codeABC(fs,OP_SETLIST,base,b,0); |
3651 | luaK_code(fs,cast(Instruction,c),fs->ls->lastline); |
3652 | } |
3653 | fs->freereg=base+1; |
3654 | } |
3655 | #define hasmultret(k)((k)==VCALL||(k)==VVARARG) |
3656 | #define getlocvar(fs,i)((fs)->f->locvars[(fs)->actvar[i]]) |
3657 | #define luaY_checklimit(fs,v,l,m)if((v)>(l))errorlimit(fs,l,m) |
3658 | typedef struct BlockCnt{ |
3659 | struct BlockCnt*previous; |
3660 | int breaklist; |
3661 | lu_byte nactvar; |
3662 | lu_byte upval; |
3663 | lu_byte isbreakable; |
3664 | }BlockCnt; |
3665 | static void chunk(LexState*ls); |
3666 | static void expr(LexState*ls,expdesc*v); |
3667 | static void anchor_token(LexState*ls){ |
3668 | if(ls->t.token==TK_NAME||ls->t.token==TK_STRING){ |
3669 | TString*ts=ls->t.seminfo.ts; |
3670 | luaX_newstring(ls,getstr(ts),ts->tsv.len); |
3671 | } |
3672 | } |
3673 | static void error_expected(LexState*ls,int token){ |
3674 | luaX_syntaxerror(ls, |
3675 | luaO_pushfstring(ls->L,LUA_QL("%s" )" expected" ,luaX_token2str(ls,token))); |
3676 | } |
3677 | static void errorlimit(FuncState*fs,int limit,const char*what){ |
3678 | const char*msg=(fs->f->linedefined==0)? |
3679 | luaO_pushfstring(fs->L,"main function has more than %d %s" ,limit,what): |
3680 | luaO_pushfstring(fs->L,"function at line %d has more than %d %s" , |
3681 | fs->f->linedefined,limit,what); |
3682 | luaX_lexerror(fs->ls,msg,0); |
3683 | } |
3684 | static int testnext(LexState*ls,int c){ |
3685 | if(ls->t.token==c){ |
3686 | luaX_next(ls); |
3687 | return 1; |
3688 | } |
3689 | else return 0; |
3690 | } |
3691 | static void check(LexState*ls,int c){ |
3692 | if(ls->t.token!=c) |
3693 | error_expected(ls,c); |
3694 | } |
3695 | static void checknext(LexState*ls,int c){ |
3696 | check(ls,c); |
3697 | luaX_next(ls); |
3698 | } |
3699 | #define check_condition(ls,c,msg){if(!(c))luaX_syntaxerror(ls,msg);} |
3700 | static void check_match(LexState*ls,int what,int who,int where){ |
3701 | if(!testnext(ls,what)){ |
3702 | if(where==ls->linenumber) |
3703 | error_expected(ls,what); |
3704 | else{ |
3705 | luaX_syntaxerror(ls,luaO_pushfstring(ls->L, |
3706 | LUA_QL("%s" )" expected (to close " LUA_QL("%s" )" at line %d)" , |
3707 | luaX_token2str(ls,what),luaX_token2str(ls,who),where)); |
3708 | } |
3709 | } |
3710 | } |
3711 | static TString*str_checkname(LexState*ls){ |
3712 | TString*ts; |
3713 | check(ls,TK_NAME); |
3714 | ts=ls->t.seminfo.ts; |
3715 | luaX_next(ls); |
3716 | return ts; |
3717 | } |
3718 | static void init_exp(expdesc*e,expkind k,int i){ |
3719 | e->f=e->t=(-1); |
3720 | e->k=k; |
3721 | e->u.s.info=i; |
3722 | } |
3723 | static void codestring(LexState*ls,expdesc*e,TString*s){ |
3724 | init_exp(e,VK,luaK_stringK(ls->fs,s)); |
3725 | } |
3726 | static void checkname(LexState*ls,expdesc*e){ |
3727 | codestring(ls,e,str_checkname(ls)); |
3728 | } |
3729 | static int registerlocalvar(LexState*ls,TString*varname){ |
3730 | FuncState*fs=ls->fs; |
3731 | Proto*f=fs->f; |
3732 | int oldsize=f->sizelocvars; |
3733 | luaM_growvector(ls->L,f->locvars,fs->nlocvars,f->sizelocvars, |
3734 | LocVar,SHRT_MAX,"too many local variables" ); |
3735 | while(oldsize<f->sizelocvars)f->locvars[oldsize++].varname=NULL; |
3736 | f->locvars[fs->nlocvars].varname=varname; |
3737 | luaC_objbarrier(ls->L,f,varname); |
3738 | return fs->nlocvars++; |
3739 | } |
3740 | #define new_localvarliteral(ls,v,n)new_localvar(ls,luaX_newstring(ls,""v,(sizeof(v)/sizeof(char))-1),n) |
3741 | static void new_localvar(LexState*ls,TString*name,int n){ |
3742 | FuncState*fs=ls->fs; |
3743 | luaY_checklimit(fs,fs->nactvar+n+1,200,"local variables" ); |
3744 | fs->actvar[fs->nactvar+n]=cast(unsigned short,registerlocalvar(ls,name)); |
3745 | } |
3746 | static void adjustlocalvars(LexState*ls,int nvars){ |
3747 | FuncState*fs=ls->fs; |
3748 | fs->nactvar=cast_byte(fs->nactvar+nvars); |
3749 | for(;nvars;nvars--){ |
3750 | getlocvar(fs,fs->nactvar-nvars).startpc=fs->pc; |
3751 | } |
3752 | } |
3753 | static void removevars(LexState*ls,int tolevel){ |
3754 | FuncState*fs=ls->fs; |
3755 | while(fs->nactvar>tolevel) |
3756 | getlocvar(fs,--fs->nactvar).endpc=fs->pc; |
3757 | } |
3758 | static int indexupvalue(FuncState*fs,TString*name,expdesc*v){ |
3759 | int i; |
3760 | Proto*f=fs->f; |
3761 | int oldsize=f->sizeupvalues; |
3762 | for(i=0;i<f->nups;i++){ |
3763 | if(fs->upvalues[i].k==v->k&&fs->upvalues[i].info==v->u.s.info){ |
3764 | return i; |
3765 | } |
3766 | } |
3767 | luaY_checklimit(fs,f->nups+1,60,"upvalues" ); |
3768 | luaM_growvector(fs->L,f->upvalues,f->nups,f->sizeupvalues, |
3769 | TString*,(INT_MAX-2),"" ); |
3770 | while(oldsize<f->sizeupvalues)f->upvalues[oldsize++]=NULL; |
3771 | f->upvalues[f->nups]=name; |
3772 | luaC_objbarrier(fs->L,f,name); |
3773 | fs->upvalues[f->nups].k=cast_byte(v->k); |
3774 | fs->upvalues[f->nups].info=cast_byte(v->u.s.info); |
3775 | return f->nups++; |
3776 | } |
3777 | static int searchvar(FuncState*fs,TString*n){ |
3778 | int i; |
3779 | for(i=fs->nactvar-1;i>=0;i--){ |
3780 | if(n==getlocvar(fs,i).varname) |
3781 | return i; |
3782 | } |
3783 | return-1; |
3784 | } |
3785 | static void markupval(FuncState*fs,int level){ |
3786 | BlockCnt*bl=fs->bl; |
3787 | while(bl&&bl->nactvar>level)bl=bl->previous; |
3788 | if(bl)bl->upval=1; |
3789 | } |
3790 | static int singlevaraux(FuncState*fs,TString*n,expdesc*var,int base){ |
3791 | if(fs==NULL){ |
3792 | init_exp(var,VGLOBAL,((1<<8)-1)); |
3793 | return VGLOBAL; |
3794 | } |
3795 | else{ |
3796 | int v=searchvar(fs,n); |
3797 | if(v>=0){ |
3798 | init_exp(var,VLOCAL,v); |
3799 | if(!base) |
3800 | markupval(fs,v); |
3801 | return VLOCAL; |
3802 | } |
3803 | else{ |
3804 | if(singlevaraux(fs->prev,n,var,0)==VGLOBAL) |
3805 | return VGLOBAL; |
3806 | var->u.s.info=indexupvalue(fs,n,var); |
3807 | var->k=VUPVAL; |
3808 | return VUPVAL; |
3809 | } |
3810 | } |
3811 | } |
3812 | static void singlevar(LexState*ls,expdesc*var){ |
3813 | TString*varname=str_checkname(ls); |
3814 | FuncState*fs=ls->fs; |
3815 | if(singlevaraux(fs,varname,var,1)==VGLOBAL) |
3816 | var->u.s.info=luaK_stringK(fs,varname); |
3817 | } |
3818 | static void adjust_assign(LexState*ls,int nvars,int nexps,expdesc*e){ |
3819 | FuncState*fs=ls->fs; |
3820 | int =nvars-nexps; |
3821 | if(hasmultret(e->k)){ |
3822 | extra++; |
3823 | if(extra<0)extra=0; |
3824 | luaK_setreturns(fs,e,extra); |
3825 | if(extra>1)luaK_reserveregs(fs,extra-1); |
3826 | } |
3827 | else{ |
3828 | if(e->k!=VVOID)luaK_exp2nextreg(fs,e); |
3829 | if(extra>0){ |
3830 | int reg=fs->freereg; |
3831 | luaK_reserveregs(fs,extra); |
3832 | luaK_nil(fs,reg,extra); |
3833 | } |
3834 | } |
3835 | } |
3836 | static void enterlevel(LexState*ls){ |
3837 | if(++ls->L->nCcalls>200) |
3838 | luaX_lexerror(ls,"chunk has too many syntax levels" ,0); |
3839 | } |
3840 | #define leavelevel(ls)((ls)->L->nCcalls--) |
3841 | static void enterblock(FuncState*fs,BlockCnt*bl,lu_byte isbreakable){ |
3842 | bl->breaklist=(-1); |
3843 | bl->isbreakable=isbreakable; |
3844 | bl->nactvar=fs->nactvar; |
3845 | bl->upval=0; |
3846 | bl->previous=fs->bl; |
3847 | fs->bl=bl; |
3848 | } |
3849 | static void leaveblock(FuncState*fs){ |
3850 | BlockCnt*bl=fs->bl; |
3851 | fs->bl=bl->previous; |
3852 | removevars(fs->ls,bl->nactvar); |
3853 | if(bl->upval) |
3854 | luaK_codeABC(fs,OP_CLOSE,bl->nactvar,0,0); |
3855 | fs->freereg=fs->nactvar; |
3856 | luaK_patchtohere(fs,bl->breaklist); |
3857 | } |
3858 | static void pushclosure(LexState*ls,FuncState*func,expdesc*v){ |
3859 | FuncState*fs=ls->fs; |
3860 | Proto*f=fs->f; |
3861 | int oldsize=f->sizep; |
3862 | int i; |
3863 | luaM_growvector(ls->L,f->p,fs->np,f->sizep,Proto*, |
3864 | ((1<<(9+9))-1),"constant table overflow" ); |
3865 | while(oldsize<f->sizep)f->p[oldsize++]=NULL; |
3866 | f->p[fs->np++]=func->f; |
3867 | luaC_objbarrier(ls->L,f,func->f); |
3868 | init_exp(v,VRELOCABLE,luaK_codeABx(fs,OP_CLOSURE,0,fs->np-1)); |
3869 | for(i=0;i<func->f->nups;i++){ |
3870 | OpCode o=(func->upvalues[i].k==VLOCAL)?OP_MOVE:OP_GETUPVAL; |
3871 | luaK_codeABC(fs,o,0,func->upvalues[i].info,0); |
3872 | } |
3873 | } |
3874 | static void open_func(LexState*ls,FuncState*fs){ |
3875 | lua_State*L=ls->L; |
3876 | Proto*f=luaF_newproto(L); |
3877 | fs->f=f; |
3878 | fs->prev=ls->fs; |
3879 | fs->ls=ls; |
3880 | fs->L=L; |
3881 | ls->fs=fs; |
3882 | fs->pc=0; |
3883 | fs->lasttarget=-1; |
3884 | fs->jpc=(-1); |
3885 | fs->freereg=0; |
3886 | fs->nk=0; |
3887 | fs->np=0; |
3888 | fs->nlocvars=0; |
3889 | fs->nactvar=0; |
3890 | fs->bl=NULL; |
3891 | f->source=ls->source; |
3892 | f->maxstacksize=2; |
3893 | fs->h=luaH_new(L,0,0); |
3894 | sethvalue(L,L->top,fs->h); |
3895 | incr_top(L); |
3896 | setptvalue(L,L->top,f); |
3897 | incr_top(L); |
3898 | } |
3899 | static void close_func(LexState*ls){ |
3900 | lua_State*L=ls->L; |
3901 | FuncState*fs=ls->fs; |
3902 | Proto*f=fs->f; |
3903 | removevars(ls,0); |
3904 | luaK_ret(fs,0,0); |
3905 | luaM_reallocvector(L,f->code,f->sizecode,fs->pc,Instruction); |
3906 | f->sizecode=fs->pc; |
3907 | luaM_reallocvector(L,f->lineinfo,f->sizelineinfo,fs->pc,int); |
3908 | f->sizelineinfo=fs->pc; |
3909 | luaM_reallocvector(L,f->k,f->sizek,fs->nk,TValue); |
3910 | f->sizek=fs->nk; |
3911 | luaM_reallocvector(L,f->p,f->sizep,fs->np,Proto*); |
3912 | f->sizep=fs->np; |
3913 | luaM_reallocvector(L,f->locvars,f->sizelocvars,fs->nlocvars,LocVar); |
3914 | f->sizelocvars=fs->nlocvars; |
3915 | luaM_reallocvector(L,f->upvalues,f->sizeupvalues,f->nups,TString*); |
3916 | f->sizeupvalues=f->nups; |
3917 | ls->fs=fs->prev; |
3918 | if(fs)anchor_token(ls); |
3919 | L->top-=2; |
3920 | } |
3921 | static Proto*luaY_parser(lua_State*L,ZIO*z,Mbuffer*buff,const char*name){ |
3922 | struct LexState lexstate; |
3923 | struct FuncState funcstate; |
3924 | lexstate.buff=buff; |
3925 | luaX_setinput(L,&lexstate,z,luaS_new(L,name)); |
3926 | open_func(&lexstate,&funcstate); |
3927 | funcstate.f->is_vararg=2; |
3928 | luaX_next(&lexstate); |
3929 | chunk(&lexstate); |
3930 | check(&lexstate,TK_EOS); |
3931 | close_func(&lexstate); |
3932 | return funcstate.f; |
3933 | } |
3934 | static void field(LexState*ls,expdesc*v){ |
3935 | FuncState*fs=ls->fs; |
3936 | expdesc key; |
3937 | luaK_exp2anyreg(fs,v); |
3938 | luaX_next(ls); |
3939 | checkname(ls,&key); |
3940 | luaK_indexed(fs,v,&key); |
3941 | } |
3942 | static void yindex(LexState*ls,expdesc*v){ |
3943 | luaX_next(ls); |
3944 | expr(ls,v); |
3945 | luaK_exp2val(ls->fs,v); |
3946 | checknext(ls,']'); |
3947 | } |
3948 | struct ConsControl{ |
3949 | expdesc v; |
3950 | expdesc*t; |
3951 | int nh; |
3952 | int na; |
3953 | int tostore; |
3954 | }; |
3955 | static void recfield(LexState*ls,struct ConsControl*cc){ |
3956 | FuncState*fs=ls->fs; |
3957 | int reg=ls->fs->freereg; |
3958 | expdesc key,val; |
3959 | int rkkey; |
3960 | if(ls->t.token==TK_NAME){ |
3961 | luaY_checklimit(fs,cc->nh,(INT_MAX-2),"items in a constructor" ); |
3962 | checkname(ls,&key); |
3963 | } |
3964 | else |
3965 | yindex(ls,&key); |
3966 | cc->nh++; |
3967 | checknext(ls,'='); |
3968 | rkkey=luaK_exp2RK(fs,&key); |
3969 | expr(ls,&val); |
3970 | luaK_codeABC(fs,OP_SETTABLE,cc->t->u.s.info,rkkey,luaK_exp2RK(fs,&val)); |
3971 | fs->freereg=reg; |
3972 | } |
3973 | static void closelistfield(FuncState*fs,struct ConsControl*cc){ |
3974 | if(cc->v.k==VVOID)return; |
3975 | luaK_exp2nextreg(fs,&cc->v); |
3976 | cc->v.k=VVOID; |
3977 | if(cc->tostore==50){ |
3978 | luaK_setlist(fs,cc->t->u.s.info,cc->na,cc->tostore); |
3979 | cc->tostore=0; |
3980 | } |
3981 | } |
3982 | static void lastlistfield(FuncState*fs,struct ConsControl*cc){ |
3983 | if(cc->tostore==0)return; |
3984 | if(hasmultret(cc->v.k)){ |
3985 | luaK_setmultret(fs,&cc->v); |
3986 | luaK_setlist(fs,cc->t->u.s.info,cc->na,(-1)); |
3987 | cc->na--; |
3988 | } |
3989 | else{ |
3990 | if(cc->v.k!=VVOID) |
3991 | luaK_exp2nextreg(fs,&cc->v); |
3992 | luaK_setlist(fs,cc->t->u.s.info,cc->na,cc->tostore); |
3993 | } |
3994 | } |
3995 | static void listfield(LexState*ls,struct ConsControl*cc){ |
3996 | expr(ls,&cc->v); |
3997 | luaY_checklimit(ls->fs,cc->na,(INT_MAX-2),"items in a constructor" ); |
3998 | cc->na++; |
3999 | cc->tostore++; |
4000 | } |
4001 | static void constructor(LexState*ls,expdesc*t){ |
4002 | FuncState*fs=ls->fs; |
4003 | int line=ls->linenumber; |
4004 | int pc=luaK_codeABC(fs,OP_NEWTABLE,0,0,0); |
4005 | struct ConsControl cc; |
4006 | cc.na=cc.nh=cc.tostore=0; |
4007 | cc.t=t; |
4008 | init_exp(t,VRELOCABLE,pc); |
4009 | init_exp(&cc.v,VVOID,0); |
4010 | luaK_exp2nextreg(ls->fs,t); |
4011 | checknext(ls,'{'); |
4012 | do{ |
4013 | if(ls->t.token=='}')break; |
4014 | closelistfield(fs,&cc); |
4015 | switch(ls->t.token){ |
4016 | case TK_NAME:{ |
4017 | luaX_lookahead(ls); |
4018 | if(ls->lookahead.token!='=') |
4019 | listfield(ls,&cc); |
4020 | else |
4021 | recfield(ls,&cc); |
4022 | break; |
4023 | } |
4024 | case'[':{ |
4025 | recfield(ls,&cc); |
4026 | break; |
4027 | } |
4028 | default:{ |
4029 | listfield(ls,&cc); |
4030 | break; |
4031 | } |
4032 | } |
4033 | }while(testnext(ls,',')||testnext(ls,';')); |
4034 | check_match(ls,'}','{',line); |
4035 | lastlistfield(fs,&cc); |
4036 | SETARG_B(fs->f->code[pc],luaO_int2fb(cc.na)); |
4037 | SETARG_C(fs->f->code[pc],luaO_int2fb(cc.nh)); |
4038 | } |
4039 | static void parlist(LexState*ls){ |
4040 | FuncState*fs=ls->fs; |
4041 | Proto*f=fs->f; |
4042 | int nparams=0; |
4043 | f->is_vararg=0; |
4044 | if(ls->t.token!=')'){ |
4045 | do{ |
4046 | switch(ls->t.token){ |
4047 | case TK_NAME:{ |
4048 | new_localvar(ls,str_checkname(ls),nparams++); |
4049 | break; |
4050 | } |
4051 | case TK_DOTS:{ |
4052 | luaX_next(ls); |
4053 | f->is_vararg|=2; |
4054 | break; |
4055 | } |
4056 | default:luaX_syntaxerror(ls,"<name> or " LUA_QL("..." )" expected" ); |
4057 | } |
4058 | }while(!f->is_vararg&&testnext(ls,',')); |
4059 | } |
4060 | adjustlocalvars(ls,nparams); |
4061 | f->numparams=cast_byte(fs->nactvar-(f->is_vararg&1)); |
4062 | luaK_reserveregs(fs,fs->nactvar); |
4063 | } |
4064 | static void body(LexState*ls,expdesc*e,int needself,int line){ |
4065 | FuncState new_fs; |
4066 | open_func(ls,&new_fs); |
4067 | new_fs.f->linedefined=line; |
4068 | checknext(ls,'('); |
4069 | if(needself){ |
4070 | new_localvarliteral(ls,"self" ,0); |
4071 | adjustlocalvars(ls,1); |
4072 | } |
4073 | parlist(ls); |
4074 | checknext(ls,')'); |
4075 | chunk(ls); |
4076 | new_fs.f->lastlinedefined=ls->linenumber; |
4077 | check_match(ls,TK_END,TK_FUNCTION,line); |
4078 | close_func(ls); |
4079 | pushclosure(ls,&new_fs,e); |
4080 | } |
4081 | static int explist1(LexState*ls,expdesc*v){ |
4082 | int n=1; |
4083 | expr(ls,v); |
4084 | while(testnext(ls,',')){ |
4085 | luaK_exp2nextreg(ls->fs,v); |
4086 | expr(ls,v); |
4087 | n++; |
4088 | } |
4089 | return n; |
4090 | } |
4091 | static void funcargs(LexState*ls,expdesc*f){ |
4092 | FuncState*fs=ls->fs; |
4093 | expdesc args; |
4094 | int base,nparams; |
4095 | int line=ls->linenumber; |
4096 | switch(ls->t.token){ |
4097 | case'(':{ |
4098 | if(line!=ls->lastline) |
4099 | luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)" ); |
4100 | luaX_next(ls); |
4101 | if(ls->t.token==')') |
4102 | args.k=VVOID; |
4103 | else{ |
4104 | explist1(ls,&args); |
4105 | luaK_setmultret(fs,&args); |
4106 | } |
4107 | check_match(ls,')','(',line); |
4108 | break; |
4109 | } |
4110 | case'{':{ |
4111 | constructor(ls,&args); |
4112 | break; |
4113 | } |
4114 | case TK_STRING:{ |
4115 | codestring(ls,&args,ls->t.seminfo.ts); |
4116 | luaX_next(ls); |
4117 | break; |
4118 | } |
4119 | default:{ |
4120 | luaX_syntaxerror(ls,"function arguments expected" ); |
4121 | return; |
4122 | } |
4123 | } |
4124 | base=f->u.s.info; |
4125 | if(hasmultret(args.k)) |
4126 | nparams=(-1); |
4127 | else{ |
4128 | if(args.k!=VVOID) |
4129 | luaK_exp2nextreg(fs,&args); |
4130 | nparams=fs->freereg-(base+1); |
4131 | } |
4132 | init_exp(f,VCALL,luaK_codeABC(fs,OP_CALL,base,nparams+1,2)); |
4133 | luaK_fixline(fs,line); |
4134 | fs->freereg=base+1; |
4135 | } |
4136 | static void prefixexp(LexState*ls,expdesc*v){ |
4137 | switch(ls->t.token){ |
4138 | case'(':{ |
4139 | int line=ls->linenumber; |
4140 | luaX_next(ls); |
4141 | expr(ls,v); |
4142 | check_match(ls,')','(',line); |
4143 | luaK_dischargevars(ls->fs,v); |
4144 | return; |
4145 | } |
4146 | case TK_NAME:{ |
4147 | singlevar(ls,v); |
4148 | return; |
4149 | } |
4150 | default:{ |
4151 | luaX_syntaxerror(ls,"unexpected symbol" ); |
4152 | return; |
4153 | } |
4154 | } |
4155 | } |
4156 | static void primaryexp(LexState*ls,expdesc*v){ |
4157 | FuncState*fs=ls->fs; |
4158 | prefixexp(ls,v); |
4159 | for(;;){ |
4160 | switch(ls->t.token){ |
4161 | case'.':{ |
4162 | field(ls,v); |
4163 | break; |
4164 | } |
4165 | case'[':{ |
4166 | expdesc key; |
4167 | luaK_exp2anyreg(fs,v); |
4168 | yindex(ls,&key); |
4169 | luaK_indexed(fs,v,&key); |
4170 | break; |
4171 | } |
4172 | case':':{ |
4173 | expdesc key; |
4174 | luaX_next(ls); |
4175 | checkname(ls,&key); |
4176 | luaK_self(fs,v,&key); |
4177 | funcargs(ls,v); |
4178 | break; |
4179 | } |
4180 | case'(':case TK_STRING:case'{':{ |
4181 | luaK_exp2nextreg(fs,v); |
4182 | funcargs(ls,v); |
4183 | break; |
4184 | } |
4185 | default:return; |
4186 | } |
4187 | } |
4188 | } |
4189 | static void simpleexp(LexState*ls,expdesc*v){ |
4190 | switch(ls->t.token){ |
4191 | case TK_NUMBER:{ |
4192 | init_exp(v,VKNUM,0); |
4193 | v->u.nval=ls->t.seminfo.r; |
4194 | break; |
4195 | } |
4196 | case TK_STRING:{ |
4197 | codestring(ls,v,ls->t.seminfo.ts); |
4198 | break; |
4199 | } |
4200 | case TK_NIL:{ |
4201 | init_exp(v,VNIL,0); |
4202 | break; |
4203 | } |
4204 | case TK_TRUE:{ |
4205 | init_exp(v,VTRUE,0); |
4206 | break; |
4207 | } |
4208 | case TK_FALSE:{ |
4209 | init_exp(v,VFALSE,0); |
4210 | break; |
4211 | } |
4212 | case TK_DOTS:{ |
4213 | FuncState*fs=ls->fs; |
4214 | check_condition(ls,fs->f->is_vararg, |
4215 | "cannot use " LUA_QL("..." )" outside a vararg function" ); |
4216 | fs->f->is_vararg&=~4; |
4217 | init_exp(v,VVARARG,luaK_codeABC(fs,OP_VARARG,0,1,0)); |
4218 | break; |
4219 | } |
4220 | case'{':{ |
4221 | constructor(ls,v); |
4222 | return; |
4223 | } |
4224 | case TK_FUNCTION:{ |
4225 | luaX_next(ls); |
4226 | body(ls,v,0,ls->linenumber); |
4227 | return; |
4228 | } |
4229 | default:{ |
4230 | primaryexp(ls,v); |
4231 | return; |
4232 | } |
4233 | } |
4234 | luaX_next(ls); |
4235 | } |
4236 | static UnOpr getunopr(int op){ |
4237 | switch(op){ |
4238 | case TK_NOT:return OPR_NOT; |
4239 | case'-':return OPR_MINUS; |
4240 | case'#':return OPR_LEN; |
4241 | default:return OPR_NOUNOPR; |
4242 | } |
4243 | } |
4244 | static BinOpr getbinopr(int op){ |
4245 | switch(op){ |
4246 | case'+':return OPR_ADD; |
4247 | case'-':return OPR_SUB; |
4248 | case'*':return OPR_MUL; |
4249 | case'/':return OPR_DIV; |
4250 | case'%':return OPR_MOD; |
4251 | case'^':return OPR_POW; |
4252 | case TK_CONCAT:return OPR_CONCAT; |
4253 | case TK_NE:return OPR_NE; |
4254 | case TK_EQ:return OPR_EQ; |
4255 | case'<':return OPR_LT; |
4256 | case TK_LE:return OPR_LE; |
4257 | case'>':return OPR_GT; |
4258 | case TK_GE:return OPR_GE; |
4259 | case TK_AND:return OPR_AND; |
4260 | case TK_OR:return OPR_OR; |
4261 | default:return OPR_NOBINOPR; |
4262 | } |
4263 | } |
4264 | static const struct{ |
4265 | lu_byte left; |
4266 | lu_byte right; |
4267 | }priority[]={ |
4268 | {6,6},{6,6},{7,7},{7,7},{7,7}, |
4269 | {10,9},{5,4}, |
4270 | {3,3},{3,3}, |
4271 | {3,3},{3,3},{3,3},{3,3}, |
4272 | {2,2},{1,1} |
4273 | }; |
4274 | static BinOpr subexpr(LexState*ls,expdesc*v,unsigned int limit){ |
4275 | BinOpr op; |
4276 | UnOpr uop; |
4277 | enterlevel(ls); |
4278 | uop=getunopr(ls->t.token); |
4279 | if(uop!=OPR_NOUNOPR){ |
4280 | luaX_next(ls); |
4281 | subexpr(ls,v,8); |
4282 | luaK_prefix(ls->fs,uop,v); |
4283 | } |
4284 | else simpleexp(ls,v); |
4285 | op=getbinopr(ls->t.token); |
4286 | while(op!=OPR_NOBINOPR&&priority[op].left>limit){ |
4287 | expdesc v2; |
4288 | BinOpr nextop; |
4289 | luaX_next(ls); |
4290 | luaK_infix(ls->fs,op,v); |
4291 | nextop=subexpr(ls,&v2,priority[op].right); |
4292 | luaK_posfix(ls->fs,op,v,&v2); |
4293 | op=nextop; |
4294 | } |
4295 | leavelevel(ls); |
4296 | return op; |
4297 | } |
4298 | static void expr(LexState*ls,expdesc*v){ |
4299 | subexpr(ls,v,0); |
4300 | } |
4301 | static int block_follow(int token){ |
4302 | switch(token){ |
4303 | case TK_ELSE:case TK_ELSEIF:case TK_END: |
4304 | case TK_UNTIL:case TK_EOS: |
4305 | return 1; |
4306 | default:return 0; |
4307 | } |
4308 | } |
4309 | static void block(LexState*ls){ |
4310 | FuncState*fs=ls->fs; |
4311 | BlockCnt bl; |
4312 | enterblock(fs,&bl,0); |
4313 | chunk(ls); |
4314 | leaveblock(fs); |
4315 | } |
4316 | struct LHS_assign{ |
4317 | struct LHS_assign*prev; |
4318 | expdesc v; |
4319 | }; |
4320 | static void check_conflict(LexState*ls,struct LHS_assign*lh,expdesc*v){ |
4321 | FuncState*fs=ls->fs; |
4322 | int =fs->freereg; |
4323 | int conflict=0; |
4324 | for(;lh;lh=lh->prev){ |
4325 | if(lh->v.k==VINDEXED){ |
4326 | if(lh->v.u.s.info==v->u.s.info){ |
4327 | conflict=1; |
4328 | lh->v.u.s.info=extra; |
4329 | } |
4330 | if(lh->v.u.s.aux==v->u.s.info){ |
4331 | conflict=1; |
4332 | lh->v.u.s.aux=extra; |
4333 | } |
4334 | } |
4335 | } |
4336 | if(conflict){ |
4337 | luaK_codeABC(fs,OP_MOVE,fs->freereg,v->u.s.info,0); |
4338 | luaK_reserveregs(fs,1); |
4339 | } |
4340 | } |
4341 | static void assignment(LexState*ls,struct LHS_assign*lh,int nvars){ |
4342 | expdesc e; |
4343 | check_condition(ls,VLOCAL<=lh->v.k&&lh->v.k<=VINDEXED, |
4344 | "syntax error" ); |
4345 | if(testnext(ls,',')){ |
4346 | struct LHS_assign nv; |
4347 | nv.prev=lh; |
4348 | primaryexp(ls,&nv.v); |
4349 | if(nv.v.k==VLOCAL) |
4350 | check_conflict(ls,lh,&nv.v); |
4351 | luaY_checklimit(ls->fs,nvars,200-ls->L->nCcalls, |
4352 | "variables in assignment" ); |
4353 | assignment(ls,&nv,nvars+1); |
4354 | } |
4355 | else{ |
4356 | int nexps; |
4357 | checknext(ls,'='); |
4358 | nexps=explist1(ls,&e); |
4359 | if(nexps!=nvars){ |
4360 | adjust_assign(ls,nvars,nexps,&e); |
4361 | if(nexps>nvars) |
4362 | ls->fs->freereg-=nexps-nvars; |
4363 | } |
4364 | else{ |
4365 | luaK_setoneret(ls->fs,&e); |
4366 | luaK_storevar(ls->fs,&lh->v,&e); |
4367 | return; |
4368 | } |
4369 | } |
4370 | init_exp(&e,VNONRELOC,ls->fs->freereg-1); |
4371 | luaK_storevar(ls->fs,&lh->v,&e); |
4372 | } |
4373 | static int cond(LexState*ls){ |
4374 | expdesc v; |
4375 | expr(ls,&v); |
4376 | if(v.k==VNIL)v.k=VFALSE; |
4377 | luaK_goiftrue(ls->fs,&v); |
4378 | return v.f; |
4379 | } |
4380 | static void breakstat(LexState*ls){ |
4381 | FuncState*fs=ls->fs; |
4382 | BlockCnt*bl=fs->bl; |
4383 | int upval=0; |
4384 | while(bl&&!bl->isbreakable){ |
4385 | upval|=bl->upval; |
4386 | bl=bl->previous; |
4387 | } |
4388 | if(!bl) |
4389 | luaX_syntaxerror(ls,"no loop to break" ); |
4390 | if(upval) |
4391 | luaK_codeABC(fs,OP_CLOSE,bl->nactvar,0,0); |
4392 | luaK_concat(fs,&bl->breaklist,luaK_jump(fs)); |
4393 | } |
4394 | static void whilestat(LexState*ls,int line){ |
4395 | FuncState*fs=ls->fs; |
4396 | int whileinit; |
4397 | int condexit; |
4398 | BlockCnt bl; |
4399 | luaX_next(ls); |
4400 | whileinit=luaK_getlabel(fs); |
4401 | condexit=cond(ls); |
4402 | enterblock(fs,&bl,1); |
4403 | checknext(ls,TK_DO); |
4404 | block(ls); |
4405 | luaK_patchlist(fs,luaK_jump(fs),whileinit); |
4406 | check_match(ls,TK_END,TK_WHILE,line); |
4407 | leaveblock(fs); |
4408 | luaK_patchtohere(fs,condexit); |
4409 | } |
4410 | static void repeatstat(LexState*ls,int line){ |
4411 | int condexit; |
4412 | FuncState*fs=ls->fs; |
4413 | int repeat_init=luaK_getlabel(fs); |
4414 | BlockCnt bl1,bl2; |
4415 | enterblock(fs,&bl1,1); |
4416 | enterblock(fs,&bl2,0); |
4417 | luaX_next(ls); |
4418 | chunk(ls); |
4419 | check_match(ls,TK_UNTIL,TK_REPEAT,line); |
4420 | condexit=cond(ls); |
4421 | if(!bl2.upval){ |
4422 | leaveblock(fs); |
4423 | luaK_patchlist(ls->fs,condexit,repeat_init); |
4424 | } |
4425 | else{ |
4426 | breakstat(ls); |
4427 | luaK_patchtohere(ls->fs,condexit); |
4428 | leaveblock(fs); |
4429 | luaK_patchlist(ls->fs,luaK_jump(fs),repeat_init); |
4430 | } |
4431 | leaveblock(fs); |
4432 | } |
4433 | static int exp1(LexState*ls){ |
4434 | expdesc e; |
4435 | int k; |
4436 | expr(ls,&e); |
4437 | k=e.k; |
4438 | luaK_exp2nextreg(ls->fs,&e); |
4439 | return k; |
4440 | } |
4441 | static void forbody(LexState*ls,int base,int line,int nvars,int isnum){ |
4442 | BlockCnt bl; |
4443 | FuncState*fs=ls->fs; |
4444 | int prep,endfor; |
4445 | adjustlocalvars(ls,3); |
4446 | checknext(ls,TK_DO); |
4447 | prep=isnum?luaK_codeAsBx(fs,OP_FORPREP,base,(-1)):luaK_jump(fs); |
4448 | enterblock(fs,&bl,0); |
4449 | adjustlocalvars(ls,nvars); |
4450 | luaK_reserveregs(fs,nvars); |
4451 | block(ls); |
4452 | leaveblock(fs); |
4453 | luaK_patchtohere(fs,prep); |
4454 | endfor=(isnum)?luaK_codeAsBx(fs,OP_FORLOOP,base,(-1)): |
4455 | luaK_codeABC(fs,OP_TFORLOOP,base,0,nvars); |
4456 | luaK_fixline(fs,line); |
4457 | luaK_patchlist(fs,(isnum?endfor:luaK_jump(fs)),prep+1); |
4458 | } |
4459 | static void fornum(LexState*ls,TString*varname,int line){ |
4460 | FuncState*fs=ls->fs; |
4461 | int base=fs->freereg; |
4462 | new_localvarliteral(ls,"(for index)" ,0); |
4463 | new_localvarliteral(ls,"(for limit)" ,1); |
4464 | new_localvarliteral(ls,"(for step)" ,2); |
4465 | new_localvar(ls,varname,3); |
4466 | checknext(ls,'='); |
4467 | exp1(ls); |
4468 | checknext(ls,','); |
4469 | exp1(ls); |
4470 | if(testnext(ls,',')) |
4471 | exp1(ls); |
4472 | else{ |
4473 | luaK_codeABx(fs,OP_LOADK,fs->freereg,luaK_numberK(fs,1)); |
4474 | luaK_reserveregs(fs,1); |
4475 | } |
4476 | forbody(ls,base,line,1,1); |
4477 | } |
4478 | static void forlist(LexState*ls,TString*indexname){ |
4479 | FuncState*fs=ls->fs; |
4480 | expdesc e; |
4481 | int nvars=0; |
4482 | int line; |
4483 | int base=fs->freereg; |
4484 | new_localvarliteral(ls,"(for generator)" ,nvars++); |
4485 | new_localvarliteral(ls,"(for state)" ,nvars++); |
4486 | new_localvarliteral(ls,"(for control)" ,nvars++); |
4487 | new_localvar(ls,indexname,nvars++); |
4488 | while(testnext(ls,',')) |
4489 | new_localvar(ls,str_checkname(ls),nvars++); |
4490 | checknext(ls,TK_IN); |
4491 | line=ls->linenumber; |
4492 | adjust_assign(ls,3,explist1(ls,&e),&e); |
4493 | luaK_checkstack(fs,3); |
4494 | forbody(ls,base,line,nvars-3,0); |
4495 | } |
4496 | static void forstat(LexState*ls,int line){ |
4497 | FuncState*fs=ls->fs; |
4498 | TString*varname; |
4499 | BlockCnt bl; |
4500 | enterblock(fs,&bl,1); |
4501 | luaX_next(ls); |
4502 | varname=str_checkname(ls); |
4503 | switch(ls->t.token){ |
4504 | case'=':fornum(ls,varname,line);break; |
4505 | case',':case TK_IN:forlist(ls,varname);break; |
4506 | default:luaX_syntaxerror(ls,LUA_QL("=" )" or " LUA_QL("in" )" expected" ); |
4507 | } |
4508 | check_match(ls,TK_END,TK_FOR,line); |
4509 | leaveblock(fs); |
4510 | } |
4511 | static int test_then_block(LexState*ls){ |
4512 | int condexit; |
4513 | luaX_next(ls); |
4514 | condexit=cond(ls); |
4515 | checknext(ls,TK_THEN); |
4516 | block(ls); |
4517 | return condexit; |
4518 | } |
4519 | static void ifstat(LexState*ls,int line){ |
4520 | FuncState*fs=ls->fs; |
4521 | int flist; |
4522 | int escapelist=(-1); |
4523 | flist=test_then_block(ls); |
4524 | while(ls->t.token==TK_ELSEIF){ |
4525 | luaK_concat(fs,&escapelist,luaK_jump(fs)); |
4526 | luaK_patchtohere(fs,flist); |
4527 | flist=test_then_block(ls); |
4528 | } |
4529 | if(ls->t.token==TK_ELSE){ |
4530 | luaK_concat(fs,&escapelist,luaK_jump(fs)); |
4531 | luaK_patchtohere(fs,flist); |
4532 | luaX_next(ls); |
4533 | block(ls); |
4534 | } |
4535 | else |
4536 | luaK_concat(fs,&escapelist,flist); |
4537 | luaK_patchtohere(fs,escapelist); |
4538 | check_match(ls,TK_END,TK_IF,line); |
4539 | } |
4540 | static void localfunc(LexState*ls){ |
4541 | expdesc v,b; |
4542 | FuncState*fs=ls->fs; |
4543 | new_localvar(ls,str_checkname(ls),0); |
4544 | init_exp(&v,VLOCAL,fs->freereg); |
4545 | luaK_reserveregs(fs,1); |
4546 | adjustlocalvars(ls,1); |
4547 | body(ls,&b,0,ls->linenumber); |
4548 | luaK_storevar(fs,&v,&b); |
4549 | getlocvar(fs,fs->nactvar-1).startpc=fs->pc; |
4550 | } |
4551 | static void localstat(LexState*ls){ |
4552 | int nvars=0; |
4553 | int nexps; |
4554 | expdesc e; |
4555 | do{ |
4556 | new_localvar(ls,str_checkname(ls),nvars++); |
4557 | }while(testnext(ls,',')); |
4558 | if(testnext(ls,'=')) |
4559 | nexps=explist1(ls,&e); |
4560 | else{ |
4561 | e.k=VVOID; |
4562 | nexps=0; |
4563 | } |
4564 | adjust_assign(ls,nvars,nexps,&e); |
4565 | adjustlocalvars(ls,nvars); |
4566 | } |
4567 | static int funcname(LexState*ls,expdesc*v){ |
4568 | int needself=0; |
4569 | singlevar(ls,v); |
4570 | while(ls->t.token=='.') |
4571 | field(ls,v); |
4572 | if(ls->t.token==':'){ |
4573 | needself=1; |
4574 | field(ls,v); |
4575 | } |
4576 | return needself; |
4577 | } |
4578 | static void funcstat(LexState*ls,int line){ |
4579 | int needself; |
4580 | expdesc v,b; |
4581 | luaX_next(ls); |
4582 | needself=funcname(ls,&v); |
4583 | body(ls,&b,needself,line); |
4584 | luaK_storevar(ls->fs,&v,&b); |
4585 | luaK_fixline(ls->fs,line); |
4586 | } |
4587 | static void exprstat(LexState*ls){ |
4588 | FuncState*fs=ls->fs; |
4589 | struct LHS_assign v; |
4590 | primaryexp(ls,&v.v); |
4591 | if(v.v.k==VCALL) |
4592 | SETARG_C(getcode(fs,&v.v),1); |
4593 | else{ |
4594 | v.prev=NULL; |
4595 | assignment(ls,&v,1); |
4596 | } |
4597 | } |
4598 | static void retstat(LexState*ls){ |
4599 | FuncState*fs=ls->fs; |
4600 | expdesc e; |
4601 | int first,nret; |
4602 | luaX_next(ls); |
4603 | if(block_follow(ls->t.token)||ls->t.token==';') |
4604 | first=nret=0; |
4605 | else{ |
4606 | nret=explist1(ls,&e); |
4607 | if(hasmultret(e.k)){ |
4608 | luaK_setmultret(fs,&e); |
4609 | if(e.k==VCALL&&nret==1){ |
4610 | SET_OPCODE(getcode(fs,&e),OP_TAILCALL); |
4611 | } |
4612 | first=fs->nactvar; |
4613 | nret=(-1); |
4614 | } |
4615 | else{ |
4616 | if(nret==1) |
4617 | first=luaK_exp2anyreg(fs,&e); |
4618 | else{ |
4619 | luaK_exp2nextreg(fs,&e); |
4620 | first=fs->nactvar; |
4621 | } |
4622 | } |
4623 | } |
4624 | luaK_ret(fs,first,nret); |
4625 | } |
4626 | static int statement(LexState*ls){ |
4627 | int line=ls->linenumber; |
4628 | switch(ls->t.token){ |
4629 | case TK_IF:{ |
4630 | ifstat(ls,line); |
4631 | return 0; |
4632 | } |
4633 | case TK_WHILE:{ |
4634 | whilestat(ls,line); |
4635 | return 0; |
4636 | } |
4637 | case TK_DO:{ |
4638 | luaX_next(ls); |
4639 | block(ls); |
4640 | check_match(ls,TK_END,TK_DO,line); |
4641 | return 0; |
4642 | } |
4643 | case TK_FOR:{ |
4644 | forstat(ls,line); |
4645 | return 0; |
4646 | } |
4647 | case TK_REPEAT:{ |
4648 | repeatstat(ls,line); |
4649 | return 0; |
4650 | } |
4651 | case TK_FUNCTION:{ |
4652 | funcstat(ls,line); |
4653 | return 0; |
4654 | } |
4655 | case TK_LOCAL:{ |
4656 | luaX_next(ls); |
4657 | if(testnext(ls,TK_FUNCTION)) |
4658 | localfunc(ls); |
4659 | else |
4660 | localstat(ls); |
4661 | return 0; |
4662 | } |
4663 | case TK_RETURN:{ |
4664 | retstat(ls); |
4665 | return 1; |
4666 | } |
4667 | case TK_BREAK:{ |
4668 | luaX_next(ls); |
4669 | breakstat(ls); |
4670 | return 1; |
4671 | } |
4672 | default:{ |
4673 | exprstat(ls); |
4674 | return 0; |
4675 | } |
4676 | } |
4677 | } |
4678 | static void chunk(LexState*ls){ |
4679 | int islast=0; |
4680 | enterlevel(ls); |
4681 | while(!islast&&!block_follow(ls->t.token)){ |
4682 | islast=statement(ls); |
4683 | testnext(ls,';'); |
4684 | ls->fs->freereg=ls->fs->nactvar; |
4685 | } |
4686 | leavelevel(ls); |
4687 | } |
4688 | static const TValue*luaV_tonumber(const TValue*obj,TValue*n){ |
4689 | lua_Number num; |
4690 | if(ttisnumber(obj))return obj; |
4691 | if(ttisstring(obj)&&luaO_str2d(svalue(obj),&num)){ |
4692 | setnvalue(n,num); |
4693 | return n; |
4694 | } |
4695 | else |
4696 | return NULL; |
4697 | } |
4698 | static int luaV_tostring(lua_State*L,StkId obj){ |
4699 | if(!ttisnumber(obj)) |
4700 | return 0; |
4701 | else{ |
4702 | char s[32]; |
4703 | lua_Number n=nvalue(obj); |
4704 | lua_number2str(s,n); |
4705 | setsvalue(L,obj,luaS_new(L,s)); |
4706 | return 1; |
4707 | } |
4708 | } |
4709 | static void callTMres(lua_State*L,StkId res,const TValue*f, |
4710 | const TValue*p1,const TValue*p2){ |
4711 | ptrdiff_t result=savestack(L,res); |
4712 | setobj(L,L->top,f); |
4713 | setobj(L,L->top+1,p1); |
4714 | setobj(L,L->top+2,p2); |
4715 | luaD_checkstack(L,3); |
4716 | L->top+=3; |
4717 | luaD_call(L,L->top-3,1); |
4718 | res=restorestack(L,result); |
4719 | L->top--; |
4720 | setobj(L,res,L->top); |
4721 | } |
4722 | static void callTM(lua_State*L,const TValue*f,const TValue*p1, |
4723 | const TValue*p2,const TValue*p3){ |
4724 | setobj(L,L->top,f); |
4725 | setobj(L,L->top+1,p1); |
4726 | setobj(L,L->top+2,p2); |
4727 | setobj(L,L->top+3,p3); |
4728 | luaD_checkstack(L,4); |
4729 | L->top+=4; |
4730 | luaD_call(L,L->top-4,0); |
4731 | } |
4732 | static void luaV_gettable(lua_State*L,const TValue*t,TValue*key,StkId val){ |
4733 | int loop; |
4734 | for(loop=0;loop<100;loop++){ |
4735 | const TValue*tm; |
4736 | if(ttistable(t)){ |
4737 | Table*h=hvalue(t); |
4738 | const TValue*res=luaH_get(h,key); |
4739 | if(!ttisnil(res)|| |
4740 | (tm=fasttm(L,h->metatable,TM_INDEX))==NULL){ |
4741 | setobj(L,val,res); |
4742 | return; |
4743 | } |
4744 | } |
4745 | else if(ttisnil(tm=luaT_gettmbyobj(L,t,TM_INDEX))) |
4746 | luaG_typeerror(L,t,"index" ); |
4747 | if(ttisfunction(tm)){ |
4748 | callTMres(L,val,tm,t,key); |
4749 | return; |
4750 | } |
4751 | t=tm; |
4752 | } |
4753 | luaG_runerror(L,"loop in gettable" ); |
4754 | } |
4755 | static void luaV_settable(lua_State*L,const TValue*t,TValue*key,StkId val){ |
4756 | int loop; |
4757 | TValue temp; |
4758 | for(loop=0;loop<100;loop++){ |
4759 | const TValue*tm; |
4760 | if(ttistable(t)){ |
4761 | Table*h=hvalue(t); |
4762 | TValue*oldval=luaH_set(L,h,key); |
4763 | if(!ttisnil(oldval)|| |
4764 | (tm=fasttm(L,h->metatable,TM_NEWINDEX))==NULL){ |
4765 | setobj(L,oldval,val); |
4766 | h->flags=0; |
4767 | luaC_barriert(L,h,val); |
4768 | return; |
4769 | } |
4770 | } |
4771 | else if(ttisnil(tm=luaT_gettmbyobj(L,t,TM_NEWINDEX))) |
4772 | luaG_typeerror(L,t,"index" ); |
4773 | if(ttisfunction(tm)){ |
4774 | callTM(L,tm,t,key,val); |
4775 | return; |
4776 | } |
4777 | setobj(L,&temp,tm); |
4778 | t=&temp; |
4779 | } |
4780 | luaG_runerror(L,"loop in settable" ); |
4781 | } |
4782 | static int call_binTM(lua_State*L,const TValue*p1,const TValue*p2, |
4783 | StkId res,TMS event){ |
4784 | const TValue*tm=luaT_gettmbyobj(L,p1,event); |
4785 | if(ttisnil(tm)) |
4786 | tm=luaT_gettmbyobj(L,p2,event); |
4787 | if(ttisnil(tm))return 0; |
4788 | callTMres(L,res,tm,p1,p2); |
4789 | return 1; |
4790 | } |
4791 | static const TValue*get_compTM(lua_State*L,Table*mt1,Table*mt2, |
4792 | TMS event){ |
4793 | const TValue*tm1=fasttm(L,mt1,event); |
4794 | const TValue*tm2; |
4795 | if(tm1==NULL)return NULL; |
4796 | if(mt1==mt2)return tm1; |
4797 | tm2=fasttm(L,mt2,event); |
4798 | if(tm2==NULL)return NULL; |
4799 | if(luaO_rawequalObj(tm1,tm2)) |
4800 | return tm1; |
4801 | return NULL; |
4802 | } |
4803 | static int call_orderTM(lua_State*L,const TValue*p1,const TValue*p2, |
4804 | TMS event){ |
4805 | const TValue*tm1=luaT_gettmbyobj(L,p1,event); |
4806 | const TValue*tm2; |
4807 | if(ttisnil(tm1))return-1; |
4808 | tm2=luaT_gettmbyobj(L,p2,event); |
4809 | if(!luaO_rawequalObj(tm1,tm2)) |
4810 | return-1; |
4811 | callTMres(L,L->top,tm1,p1,p2); |
4812 | return!l_isfalse(L->top); |
4813 | } |
4814 | static int l_strcmp(const TString*ls,const TString*rs){ |
4815 | const char*l=getstr(ls); |
4816 | size_t ll=ls->tsv.len; |
4817 | const char*r=getstr(rs); |
4818 | size_t lr=rs->tsv.len; |
4819 | for(;;){ |
4820 | int temp=strcoll(l,r); |
4821 | if(temp!=0)return temp; |
4822 | else{ |
4823 | size_t len=strlen(l); |
4824 | if(len==lr) |
4825 | return(len==ll)?0:1; |
4826 | else if(len==ll) |
4827 | return-1; |
4828 | len++; |
4829 | l+=len;ll-=len;r+=len;lr-=len; |
4830 | } |
4831 | } |
4832 | } |
4833 | static int luaV_lessthan(lua_State*L,const TValue*l,const TValue*r){ |
4834 | int res; |
4835 | if(ttype(l)!=ttype(r)) |
4836 | return luaG_ordererror(L,l,r); |
4837 | else if(ttisnumber(l)) |
4838 | return luai_numlt(nvalue(l),nvalue(r)); |
4839 | else if(ttisstring(l)) |
4840 | return l_strcmp(rawtsvalue(l),rawtsvalue(r))<0; |
4841 | else if((res=call_orderTM(L,l,r,TM_LT))!=-1) |
4842 | return res; |
4843 | return luaG_ordererror(L,l,r); |
4844 | } |
4845 | static int lessequal(lua_State*L,const TValue*l,const TValue*r){ |
4846 | int res; |
4847 | if(ttype(l)!=ttype(r)) |
4848 | return luaG_ordererror(L,l,r); |
4849 | else if(ttisnumber(l)) |
4850 | return luai_numle(nvalue(l),nvalue(r)); |
4851 | else if(ttisstring(l)) |
4852 | return l_strcmp(rawtsvalue(l),rawtsvalue(r))<=0; |
4853 | else if((res=call_orderTM(L,l,r,TM_LE))!=-1) |
4854 | return res; |
4855 | else if((res=call_orderTM(L,r,l,TM_LT))!=-1) |
4856 | return!res; |
4857 | return luaG_ordererror(L,l,r); |
4858 | } |
4859 | static int luaV_equalval(lua_State*L,const TValue*t1,const TValue*t2){ |
4860 | const TValue*tm; |
4861 | switch(ttype(t1)){ |
4862 | case 0:return 1; |
4863 | case 3:return luai_numeq(nvalue(t1),nvalue(t2)); |
4864 | case 1:return bvalue(t1)==bvalue(t2); |
4865 | case 2:return pvalue(t1)==pvalue(t2); |
4866 | case 7:{ |
4867 | if(uvalue(t1)==uvalue(t2))return 1; |
4868 | tm=get_compTM(L,uvalue(t1)->metatable,uvalue(t2)->metatable, |
4869 | TM_EQ); |
4870 | break; |
4871 | } |
4872 | case 5:{ |
4873 | if(hvalue(t1)==hvalue(t2))return 1; |
4874 | tm=get_compTM(L,hvalue(t1)->metatable,hvalue(t2)->metatable,TM_EQ); |
4875 | break; |
4876 | } |
4877 | default:return gcvalue(t1)==gcvalue(t2); |
4878 | } |
4879 | if(tm==NULL)return 0; |
4880 | callTMres(L,L->top,tm,t1,t2); |
4881 | return!l_isfalse(L->top); |
4882 | } |
4883 | static void luaV_concat(lua_State*L,int total,int last){ |
4884 | do{ |
4885 | StkId top=L->base+last+1; |
4886 | int n=2; |
4887 | if(!(ttisstring(top-2)||ttisnumber(top-2))||!tostring(L,top-1)){ |
4888 | if(!call_binTM(L,top-2,top-1,top-2,TM_CONCAT)) |
4889 | luaG_concaterror(L,top-2,top-1); |
4890 | }else if(tsvalue(top-1)->len==0) |
4891 | (void)tostring(L,top-2); |
4892 | else{ |
4893 | size_t tl=tsvalue(top-1)->len; |
4894 | char*buffer; |
4895 | int i; |
4896 | for(n=1;n<total&&tostring(L,top-n-1);n++){ |
4897 | size_t l=tsvalue(top-n-1)->len; |
4898 | if(l>=((size_t)(~(size_t)0)-2)-tl)luaG_runerror(L,"string length overflow" ); |
4899 | tl+=l; |
4900 | } |
4901 | buffer=luaZ_openspace(L,&G(L)->buff,tl); |
4902 | tl=0; |
4903 | for(i=n;i>0;i--){ |
4904 | size_t l=tsvalue(top-i)->len; |
4905 | memcpy(buffer+tl,svalue(top-i),l); |
4906 | tl+=l; |
4907 | } |
4908 | setsvalue(L,top-n,luaS_newlstr(L,buffer,tl)); |
4909 | } |
4910 | total-=n-1; |
4911 | last-=n-1; |
4912 | }while(total>1); |
4913 | } |
4914 | static void Arith(lua_State*L,StkId ra,const TValue*rb, |
4915 | const TValue*rc,TMS op){ |
4916 | TValue tempb,tempc; |
4917 | const TValue*b,*c; |
4918 | if((b=luaV_tonumber(rb,&tempb))!=NULL&& |
4919 | (c=luaV_tonumber(rc,&tempc))!=NULL){ |
4920 | lua_Number nb=nvalue(b),nc=nvalue(c); |
4921 | switch(op){ |
4922 | case TM_ADD:setnvalue(ra,luai_numadd(nb,nc));break; |
4923 | case TM_SUB:setnvalue(ra,luai_numsub(nb,nc));break; |
4924 | case TM_MUL:setnvalue(ra,luai_nummul(nb,nc));break; |
4925 | case TM_DIV:setnvalue(ra,luai_numdiv(nb,nc));break; |
4926 | case TM_MOD:setnvalue(ra,luai_nummod(nb,nc));break; |
4927 | case TM_POW:setnvalue(ra,luai_numpow(nb,nc));break; |
4928 | case TM_UNM:setnvalue(ra,luai_numunm(nb));break; |
4929 | default:break; |
4930 | } |
4931 | } |
4932 | else if(!call_binTM(L,rb,rc,ra,op)) |
4933 | luaG_aritherror(L,rb,rc); |
4934 | } |
4935 | #define runtime_check(L,c){if(!(c))break;} |
4936 | #define RA(i)(base+GETARG_A(i)) |
4937 | #define RB(i)check_exp(getBMode(GET_OPCODE(i))==OpArgR,base+GETARG_B(i)) |
4938 | #define RKB(i)check_exp(getBMode(GET_OPCODE(i))==OpArgK,ISK(GETARG_B(i))?k+INDEXK(GETARG_B(i)):base+GETARG_B(i)) |
4939 | #define RKC(i)check_exp(getCMode(GET_OPCODE(i))==OpArgK,ISK(GETARG_C(i))?k+INDEXK(GETARG_C(i)):base+GETARG_C(i)) |
4940 | #define KBx(i)check_exp(getBMode(GET_OPCODE(i))==OpArgK,k+GETARG_Bx(i)) |
4941 | #define dojump(L,pc,i){(pc)+=(i);} |
4942 | #define Protect(x){L->savedpc=pc;{x;};base=L->base;} |
4943 | #define arith_op(op,tm){TValue*rb=RKB(i);TValue*rc=RKC(i);if(ttisnumber(rb)&&ttisnumber(rc)){lua_Number nb=nvalue(rb),nc=nvalue(rc);setnvalue(ra,op(nb,nc));}else Protect(Arith(L,ra,rb,rc,tm));} |
4944 | static void luaV_execute(lua_State*L,int nexeccalls){ |
4945 | LClosure*cl; |
4946 | StkId base; |
4947 | TValue*k; |
4948 | const Instruction*pc; |
4949 | reentry: |
4950 | pc=L->savedpc; |
4951 | cl=&clvalue(L->ci->func)->l; |
4952 | base=L->base; |
4953 | k=cl->p->k; |
4954 | for(;;){ |
4955 | const Instruction i=*pc++; |
4956 | StkId ra; |
4957 | ra=RA(i); |
4958 | switch(GET_OPCODE(i)){ |
4959 | case OP_MOVE:{ |
4960 | setobj(L,ra,RB(i)); |
4961 | continue; |
4962 | } |
4963 | case OP_LOADK:{ |
4964 | setobj(L,ra,KBx(i)); |
4965 | continue; |
4966 | } |
4967 | case OP_LOADBOOL:{ |
4968 | setbvalue(ra,GETARG_B(i)); |
4969 | if(GETARG_C(i))pc++; |
4970 | continue; |
4971 | } |
4972 | case OP_LOADNIL:{ |
4973 | TValue*rb=RB(i); |
4974 | do{ |
4975 | setnilvalue(rb--); |
4976 | }while(rb>=ra); |
4977 | continue; |
4978 | } |
4979 | case OP_GETUPVAL:{ |
4980 | int b=GETARG_B(i); |
4981 | setobj(L,ra,cl->upvals[b]->v); |
4982 | continue; |
4983 | } |
4984 | case OP_GETGLOBAL:{ |
4985 | TValue g; |
4986 | TValue*rb=KBx(i); |
4987 | sethvalue(L,&g,cl->env); |
4988 | Protect(luaV_gettable(L,&g,rb,ra)); |
4989 | continue; |
4990 | } |
4991 | case OP_GETTABLE:{ |
4992 | Protect(luaV_gettable(L,RB(i),RKC(i),ra)); |
4993 | continue; |
4994 | } |
4995 | case OP_SETGLOBAL:{ |
4996 | TValue g; |
4997 | sethvalue(L,&g,cl->env); |
4998 | Protect(luaV_settable(L,&g,KBx(i),ra)); |
4999 | continue; |
5000 | } |
5001 | case OP_SETUPVAL:{ |
5002 | UpVal*uv=cl->upvals[GETARG_B(i)]; |
5003 | setobj(L,uv->v,ra); |
5004 | luaC_barrier(L,uv,ra); |
5005 | continue; |
5006 | } |
5007 | case OP_SETTABLE:{ |
5008 | Protect(luaV_settable(L,ra,RKB(i),RKC(i))); |
5009 | continue; |
5010 | } |
5011 | case OP_NEWTABLE:{ |
5012 | int b=GETARG_B(i); |
5013 | int c=GETARG_C(i); |
5014 | sethvalue(L,ra,luaH_new(L,luaO_fb2int(b),luaO_fb2int(c))); |
5015 | Protect(luaC_checkGC(L)); |
5016 | continue; |
5017 | } |
5018 | case OP_SELF:{ |
5019 | StkId rb=RB(i); |
5020 | setobj(L,ra+1,rb); |
5021 | Protect(luaV_gettable(L,rb,RKC(i),ra)); |
5022 | continue; |
5023 | } |
5024 | case OP_ADD:{ |
5025 | arith_op(luai_numadd,TM_ADD); |
5026 | continue; |
5027 | } |
5028 | case OP_SUB:{ |
5029 | arith_op(luai_numsub,TM_SUB); |
5030 | continue; |
5031 | } |
5032 | case OP_MUL:{ |
5033 | arith_op(luai_nummul,TM_MUL); |
5034 | continue; |
5035 | } |
5036 | case OP_DIV:{ |
5037 | arith_op(luai_numdiv,TM_DIV); |
5038 | continue; |
5039 | } |
5040 | case OP_MOD:{ |
5041 | arith_op(luai_nummod,TM_MOD); |
5042 | continue; |
5043 | } |
5044 | case OP_POW:{ |
5045 | arith_op(luai_numpow,TM_POW); |
5046 | continue; |
5047 | } |
5048 | case OP_UNM:{ |
5049 | TValue*rb=RB(i); |
5050 | if(ttisnumber(rb)){ |
5051 | lua_Number nb=nvalue(rb); |
5052 | setnvalue(ra,luai_numunm(nb)); |
5053 | } |
5054 | else{ |
5055 | Protect(Arith(L,ra,rb,rb,TM_UNM)); |
5056 | } |
5057 | continue; |
5058 | } |
5059 | case OP_NOT:{ |
5060 | int res=l_isfalse(RB(i)); |
5061 | setbvalue(ra,res); |
5062 | continue; |
5063 | } |
5064 | case OP_LEN:{ |
5065 | const TValue*rb=RB(i); |
5066 | switch(ttype(rb)){ |
5067 | case 5:{ |
5068 | setnvalue(ra,cast_num(luaH_getn(hvalue(rb)))); |
5069 | break; |
5070 | } |
5071 | case 4:{ |
5072 | setnvalue(ra,cast_num(tsvalue(rb)->len)); |
5073 | break; |
5074 | } |
5075 | default:{ |
5076 | Protect( |
5077 | if(!call_binTM(L,rb,(&luaO_nilobject_),ra,TM_LEN)) |
5078 | luaG_typeerror(L,rb,"get length of" ); |
5079 | ) |
5080 | } |
5081 | } |
5082 | continue; |
5083 | } |
5084 | case OP_CONCAT:{ |
5085 | int b=GETARG_B(i); |
5086 | int c=GETARG_C(i); |
5087 | Protect(luaV_concat(L,c-b+1,c);luaC_checkGC(L)); |
5088 | setobj(L,RA(i),base+b); |
5089 | continue; |
5090 | } |
5091 | case OP_JMP:{ |
5092 | dojump(L,pc,GETARG_sBx(i)); |
5093 | continue; |
5094 | } |
5095 | case OP_EQ:{ |
5096 | TValue*rb=RKB(i); |
5097 | TValue*rc=RKC(i); |
5098 | Protect( |
5099 | if(equalobj(L,rb,rc)==GETARG_A(i)) |
5100 | dojump(L,pc,GETARG_sBx(*pc)); |
5101 | ) |
5102 | pc++; |
5103 | continue; |
5104 | } |
5105 | case OP_LT:{ |
5106 | Protect( |
5107 | if(luaV_lessthan(L,RKB(i),RKC(i))==GETARG_A(i)) |
5108 | dojump(L,pc,GETARG_sBx(*pc)); |
5109 | ) |
5110 | pc++; |
5111 | continue; |
5112 | } |
5113 | case OP_LE:{ |
5114 | Protect( |
5115 | if(lessequal(L,RKB(i),RKC(i))==GETARG_A(i)) |
5116 | dojump(L,pc,GETARG_sBx(*pc)); |
5117 | ) |
5118 | pc++; |
5119 | continue; |
5120 | } |
5121 | case OP_TEST:{ |
5122 | if(l_isfalse(ra)!=GETARG_C(i)) |
5123 | dojump(L,pc,GETARG_sBx(*pc)); |
5124 | pc++; |
5125 | continue; |
5126 | } |
5127 | case OP_TESTSET:{ |
5128 | TValue*rb=RB(i); |
5129 | if(l_isfalse(rb)!=GETARG_C(i)){ |
5130 | setobj(L,ra,rb); |
5131 | dojump(L,pc,GETARG_sBx(*pc)); |
5132 | } |
5133 | pc++; |
5134 | continue; |
5135 | } |
5136 | case OP_CALL:{ |
5137 | int b=GETARG_B(i); |
5138 | int nresults=GETARG_C(i)-1; |
5139 | if(b!=0)L->top=ra+b; |
5140 | L->savedpc=pc; |
5141 | switch(luaD_precall(L,ra,nresults)){ |
5142 | case 0:{ |
5143 | nexeccalls++; |
5144 | goto reentry; |
5145 | } |
5146 | case 1:{ |
5147 | if(nresults>=0)L->top=L->ci->top; |
5148 | base=L->base; |
5149 | continue; |
5150 | } |
5151 | default:{ |
5152 | return; |
5153 | } |
5154 | } |
5155 | } |
5156 | case OP_TAILCALL:{ |
5157 | int b=GETARG_B(i); |
5158 | if(b!=0)L->top=ra+b; |
5159 | L->savedpc=pc; |
5160 | switch(luaD_precall(L,ra,(-1))){ |
5161 | case 0:{ |
5162 | CallInfo*ci=L->ci-1; |
5163 | int aux; |
5164 | StkId func=ci->func; |
5165 | StkId pfunc=(ci+1)->func; |
5166 | if(L->openupval)luaF_close(L,ci->base); |
5167 | L->base=ci->base=ci->func+((ci+1)->base-pfunc); |
5168 | for(aux=0;pfunc+aux<L->top;aux++) |
5169 | setobj(L,func+aux,pfunc+aux); |
5170 | ci->top=L->top=func+aux; |
5171 | ci->savedpc=L->savedpc; |
5172 | ci->tailcalls++; |
5173 | L->ci--; |
5174 | goto reentry; |
5175 | } |
5176 | case 1:{ |
5177 | base=L->base; |
5178 | continue; |
5179 | } |
5180 | default:{ |
5181 | return; |
5182 | } |
5183 | } |
5184 | } |
5185 | case OP_RETURN:{ |
5186 | int b=GETARG_B(i); |
5187 | if(b!=0)L->top=ra+b-1; |
5188 | if(L->openupval)luaF_close(L,base); |
5189 | L->savedpc=pc; |
5190 | b=luaD_poscall(L,ra); |
5191 | if(--nexeccalls==0) |
5192 | return; |
5193 | else{ |
5194 | if(b)L->top=L->ci->top; |
5195 | goto reentry; |
5196 | } |
5197 | } |
5198 | case OP_FORLOOP:{ |
5199 | lua_Number step=nvalue(ra+2); |
5200 | lua_Number idx=luai_numadd(nvalue(ra),step); |
5201 | lua_Number limit=nvalue(ra+1); |
5202 | if(luai_numlt(0,step)?luai_numle(idx,limit) |
5203 | :luai_numle(limit,idx)){ |
5204 | dojump(L,pc,GETARG_sBx(i)); |
5205 | setnvalue(ra,idx); |
5206 | setnvalue(ra+3,idx); |
5207 | } |
5208 | continue; |
5209 | } |
5210 | case OP_FORPREP:{ |
5211 | const TValue*init=ra; |
5212 | const TValue*plimit=ra+1; |
5213 | const TValue*pstep=ra+2; |
5214 | L->savedpc=pc; |
5215 | if(!tonumber(init,ra)) |
5216 | luaG_runerror(L,LUA_QL("for" )" initial value must be a number" ); |
5217 | else if(!tonumber(plimit,ra+1)) |
5218 | luaG_runerror(L,LUA_QL("for" )" limit must be a number" ); |
5219 | else if(!tonumber(pstep,ra+2)) |
5220 | luaG_runerror(L,LUA_QL("for" )" step must be a number" ); |
5221 | setnvalue(ra,luai_numsub(nvalue(ra),nvalue(pstep))); |
5222 | dojump(L,pc,GETARG_sBx(i)); |
5223 | continue; |
5224 | } |
5225 | case OP_TFORLOOP:{ |
5226 | StkId cb=ra+3; |
5227 | setobj(L,cb+2,ra+2); |
5228 | setobj(L,cb+1,ra+1); |
5229 | setobj(L,cb,ra); |
5230 | L->top=cb+3; |
5231 | Protect(luaD_call(L,cb,GETARG_C(i))); |
5232 | L->top=L->ci->top; |
5233 | cb=RA(i)+3; |
5234 | if(!ttisnil(cb)){ |
5235 | setobj(L,cb-1,cb); |
5236 | dojump(L,pc,GETARG_sBx(*pc)); |
5237 | } |
5238 | pc++; |
5239 | continue; |
5240 | } |
5241 | case OP_SETLIST:{ |
5242 | int n=GETARG_B(i); |
5243 | int c=GETARG_C(i); |
5244 | int last; |
5245 | Table*h; |
5246 | if(n==0){ |
5247 | n=cast_int(L->top-ra)-1; |
5248 | L->top=L->ci->top; |
5249 | } |
5250 | if(c==0)c=cast_int(*pc++); |
5251 | runtime_check(L,ttistable(ra)); |
5252 | h=hvalue(ra); |
5253 | last=((c-1)*50)+n; |
5254 | if(last>h->sizearray) |
5255 | luaH_resizearray(L,h,last); |
5256 | for(;n>0;n--){ |
5257 | TValue*val=ra+n; |
5258 | setobj(L,luaH_setnum(L,h,last--),val); |
5259 | luaC_barriert(L,h,val); |
5260 | } |
5261 | continue; |
5262 | } |
5263 | case OP_CLOSE:{ |
5264 | luaF_close(L,ra); |
5265 | continue; |
5266 | } |
5267 | case OP_CLOSURE:{ |
5268 | Proto*p; |
5269 | Closure*ncl; |
5270 | int nup,j; |
5271 | p=cl->p->p[GETARG_Bx(i)]; |
5272 | nup=p->nups; |
5273 | ncl=luaF_newLclosure(L,nup,cl->env); |
5274 | ncl->l.p=p; |
5275 | for(j=0;j<nup;j++,pc++){ |
5276 | if(GET_OPCODE(*pc)==OP_GETUPVAL) |
5277 | ncl->l.upvals[j]=cl->upvals[GETARG_B(*pc)]; |
5278 | else{ |
5279 | ncl->l.upvals[j]=luaF_findupval(L,base+GETARG_B(*pc)); |
5280 | } |
5281 | } |
5282 | setclvalue(L,ra,ncl); |
5283 | Protect(luaC_checkGC(L)); |
5284 | continue; |
5285 | } |
5286 | case OP_VARARG:{ |
5287 | int b=GETARG_B(i)-1; |
5288 | int j; |
5289 | CallInfo*ci=L->ci; |
5290 | int n=cast_int(ci->base-ci->func)-cl->p->numparams-1; |
5291 | if(b==(-1)){ |
5292 | Protect(luaD_checkstack(L,n)); |
5293 | ra=RA(i); |
5294 | b=n; |
5295 | L->top=ra+n; |
5296 | } |
5297 | for(j=0;j<b;j++){ |
5298 | if(j<n){ |
5299 | setobj(L,ra+j,ci->base-n+j); |
5300 | } |
5301 | else{ |
5302 | setnilvalue(ra+j); |
5303 | } |
5304 | } |
5305 | continue; |
5306 | } |
5307 | } |
5308 | } |
5309 | } |
5310 | #define api_checknelems(L,n)luai_apicheck(L,(n)<=(L->top-L->base)) |
5311 | #define api_checkvalidindex(L,i)luai_apicheck(L,(i)!=(&luaO_nilobject_)) |
5312 | #define api_incr_top(L){luai_apicheck(L,L->top<L->ci->top);L->top++;} |
5313 | static TValue*index2adr(lua_State*L,int idx){ |
5314 | if(idx>0){ |
5315 | TValue*o=L->base+(idx-1); |
5316 | luai_apicheck(L,idx<=L->ci->top-L->base); |
5317 | if(o>=L->top)return cast(TValue*,(&luaO_nilobject_)); |
5318 | else return o; |
5319 | } |
5320 | else if(idx>(-10000)){ |
5321 | luai_apicheck(L,idx!=0&&-idx<=L->top-L->base); |
5322 | return L->top+idx; |
5323 | } |
5324 | else switch(idx){ |
5325 | case(-10000):return registry(L); |
5326 | case(-10001):{ |
5327 | Closure*func=curr_func(L); |
5328 | sethvalue(L,&L->env,func->c.env); |
5329 | return&L->env; |
5330 | } |
5331 | case(-10002):return gt(L); |
5332 | default:{ |
5333 | Closure*func=curr_func(L); |
5334 | idx=(-10002)-idx; |
5335 | return(idx<=func->c.nupvalues) |
5336 | ?&func->c.upvalue[idx-1] |
5337 | :cast(TValue*,(&luaO_nilobject_)); |
5338 | } |
5339 | } |
5340 | } |
5341 | static Table*getcurrenv(lua_State*L){ |
5342 | if(L->ci==L->base_ci) |
5343 | return hvalue(gt(L)); |
5344 | else{ |
5345 | Closure*func=curr_func(L); |
5346 | return func->c.env; |
5347 | } |
5348 | } |
5349 | static int lua_checkstack(lua_State*L,int size){ |
5350 | int res=1; |
5351 | if(size>8000||(L->top-L->base+size)>8000) |
5352 | res=0; |
5353 | else if(size>0){ |
5354 | luaD_checkstack(L,size); |
5355 | if(L->ci->top<L->top+size) |
5356 | L->ci->top=L->top+size; |
5357 | } |
5358 | return res; |
5359 | } |
5360 | static lua_CFunction lua_atpanic(lua_State*L,lua_CFunction panicf){ |
5361 | lua_CFunction old; |
5362 | old=G(L)->panic; |
5363 | G(L)->panic=panicf; |
5364 | return old; |
5365 | } |
5366 | static int lua_gettop(lua_State*L){ |
5367 | return cast_int(L->top-L->base); |
5368 | } |
5369 | static void lua_settop(lua_State*L,int idx){ |
5370 | if(idx>=0){ |
5371 | luai_apicheck(L,idx<=L->stack_last-L->base); |
5372 | while(L->top<L->base+idx) |
5373 | setnilvalue(L->top++); |
5374 | L->top=L->base+idx; |
5375 | } |
5376 | else{ |
5377 | luai_apicheck(L,-(idx+1)<=(L->top-L->base)); |
5378 | L->top+=idx+1; |
5379 | } |
5380 | } |
5381 | static void lua_remove(lua_State*L,int idx){ |
5382 | StkId p; |
5383 | p=index2adr(L,idx); |
5384 | api_checkvalidindex(L,p); |
5385 | while(++p<L->top)setobj(L,p-1,p); |
5386 | L->top--; |
5387 | } |
5388 | static void lua_insert(lua_State*L,int idx){ |
5389 | StkId p; |
5390 | StkId q; |
5391 | p=index2adr(L,idx); |
5392 | api_checkvalidindex(L,p); |
5393 | for(q=L->top;q>p;q--)setobj(L,q,q-1); |
5394 | setobj(L,p,L->top); |
5395 | } |
5396 | static void lua_replace(lua_State*L,int idx){ |
5397 | StkId o; |
5398 | if(idx==(-10001)&&L->ci==L->base_ci) |
5399 | luaG_runerror(L,"no calling environment" ); |
5400 | api_checknelems(L,1); |
5401 | o=index2adr(L,idx); |
5402 | api_checkvalidindex(L,o); |
5403 | if(idx==(-10001)){ |
5404 | Closure*func=curr_func(L); |
5405 | luai_apicheck(L,ttistable(L->top-1)); |
5406 | func->c.env=hvalue(L->top-1); |
5407 | luaC_barrier(L,func,L->top-1); |
5408 | } |
5409 | else{ |
5410 | setobj(L,o,L->top-1); |
5411 | if(idx<(-10002)) |
5412 | luaC_barrier(L,curr_func(L),L->top-1); |
5413 | } |
5414 | L->top--; |
5415 | } |
5416 | static void lua_pushvalue(lua_State*L,int idx){ |
5417 | setobj(L,L->top,index2adr(L,idx)); |
5418 | api_incr_top(L); |
5419 | } |
5420 | static int lua_type(lua_State*L,int idx){ |
5421 | StkId o=index2adr(L,idx); |
5422 | return(o==(&luaO_nilobject_))?(-1):ttype(o); |
5423 | } |
5424 | static const char*lua_typename(lua_State*L,int t){ |
5425 | UNUSED(L); |
5426 | return(t==(-1))?"no value" :luaT_typenames[t]; |
5427 | } |
5428 | static int lua_iscfunction(lua_State*L,int idx){ |
5429 | StkId o=index2adr(L,idx); |
5430 | return iscfunction(o); |
5431 | } |
5432 | static int lua_isnumber(lua_State*L,int idx){ |
5433 | TValue n; |
5434 | const TValue*o=index2adr(L,idx); |
5435 | return tonumber(o,&n); |
5436 | } |
5437 | static int lua_isstring(lua_State*L,int idx){ |
5438 | int t=lua_type(L,idx); |
5439 | return(t==4||t==3); |
5440 | } |
5441 | static int lua_rawequal(lua_State*L,int index1,int index2){ |
5442 | StkId o1=index2adr(L,index1); |
5443 | StkId o2=index2adr(L,index2); |
5444 | return(o1==(&luaO_nilobject_)||o2==(&luaO_nilobject_))?0 |
5445 | :luaO_rawequalObj(o1,o2); |
5446 | } |
5447 | static int lua_lessthan(lua_State*L,int index1,int index2){ |
5448 | StkId o1,o2; |
5449 | int i; |
5450 | o1=index2adr(L,index1); |
5451 | o2=index2adr(L,index2); |
5452 | i=(o1==(&luaO_nilobject_)||o2==(&luaO_nilobject_))?0 |
5453 | :luaV_lessthan(L,o1,o2); |
5454 | return i; |
5455 | } |
5456 | static lua_Number lua_tonumber(lua_State*L,int idx){ |
5457 | TValue n; |
5458 | const TValue*o=index2adr(L,idx); |
5459 | if(tonumber(o,&n)) |
5460 | return nvalue(o); |
5461 | else |
5462 | return 0; |
5463 | } |
5464 | static lua_Integer lua_tointeger(lua_State*L,int idx){ |
5465 | TValue n; |
5466 | const TValue*o=index2adr(L,idx); |
5467 | if(tonumber(o,&n)){ |
5468 | lua_Integer res; |
5469 | lua_Number num=nvalue(o); |
5470 | lua_number2integer(res,num); |
5471 | return res; |
5472 | } |
5473 | else |
5474 | return 0; |
5475 | } |
5476 | static int lua_toboolean(lua_State*L,int idx){ |
5477 | const TValue*o=index2adr(L,idx); |
5478 | return!l_isfalse(o); |
5479 | } |
5480 | static const char*lua_tolstring(lua_State*L,int idx,size_t*len){ |
5481 | StkId o=index2adr(L,idx); |
5482 | if(!ttisstring(o)){ |
5483 | if(!luaV_tostring(L,o)){ |
5484 | if(len!=NULL)*len=0; |
5485 | return NULL; |
5486 | } |
5487 | luaC_checkGC(L); |
5488 | o=index2adr(L,idx); |
5489 | } |
5490 | if(len!=NULL)*len=tsvalue(o)->len; |
5491 | return svalue(o); |
5492 | } |
5493 | static size_t lua_objlen(lua_State*L,int idx){ |
5494 | StkId o=index2adr(L,idx); |
5495 | switch(ttype(o)){ |
5496 | case 4:return tsvalue(o)->len; |
5497 | case 7:return uvalue(o)->len; |
5498 | case 5:return luaH_getn(hvalue(o)); |
5499 | case 3:{ |
5500 | size_t l; |
5501 | l=(luaV_tostring(L,o)?tsvalue(o)->len:0); |
5502 | return l; |
5503 | } |
5504 | default:return 0; |
5505 | } |
5506 | } |
5507 | static lua_CFunction lua_tocfunction(lua_State*L,int idx){ |
5508 | StkId o=index2adr(L,idx); |
5509 | return(!iscfunction(o))?NULL:clvalue(o)->c.f; |
5510 | } |
5511 | static void*lua_touserdata(lua_State*L,int idx){ |
5512 | StkId o=index2adr(L,idx); |
5513 | switch(ttype(o)){ |
5514 | case 7:return(rawuvalue(o)+1); |
5515 | case 2:return pvalue(o); |
5516 | default:return NULL; |
5517 | } |
5518 | } |
5519 | static void lua_pushnil(lua_State*L){ |
5520 | setnilvalue(L->top); |
5521 | api_incr_top(L); |
5522 | } |
5523 | static void lua_pushnumber(lua_State*L,lua_Number n){ |
5524 | setnvalue(L->top,n); |
5525 | api_incr_top(L); |
5526 | } |
5527 | static void lua_pushinteger(lua_State*L,lua_Integer n){ |
5528 | setnvalue(L->top,cast_num(n)); |
5529 | api_incr_top(L); |
5530 | } |
5531 | static void lua_pushlstring(lua_State*L,const char*s,size_t len){ |
5532 | luaC_checkGC(L); |
5533 | setsvalue(L,L->top,luaS_newlstr(L,s,len)); |
5534 | api_incr_top(L); |
5535 | } |
5536 | static void lua_pushstring(lua_State*L,const char*s){ |
5537 | if(s==NULL) |
5538 | lua_pushnil(L); |
5539 | else |
5540 | lua_pushlstring(L,s,strlen(s)); |
5541 | } |
5542 | static const char*lua_pushvfstring(lua_State*L,const char*fmt, |
5543 | va_list argp){ |
5544 | const char*ret; |
5545 | luaC_checkGC(L); |
5546 | ret=luaO_pushvfstring(L,fmt,argp); |
5547 | return ret; |
5548 | } |
5549 | static const char*lua_pushfstring(lua_State*L,const char*fmt,...){ |
5550 | const char*ret; |
5551 | va_list argp; |
5552 | luaC_checkGC(L); |
5553 | va_start(argp,fmt); |
5554 | ret=luaO_pushvfstring(L,fmt,argp); |
5555 | va_end(argp); |
5556 | return ret; |
5557 | } |
5558 | static void lua_pushcclosure(lua_State*L,lua_CFunction fn,int n){ |
5559 | Closure*cl; |
5560 | luaC_checkGC(L); |
5561 | api_checknelems(L,n); |
5562 | cl=luaF_newCclosure(L,n,getcurrenv(L)); |
5563 | cl->c.f=fn; |
5564 | L->top-=n; |
5565 | while(n--) |
5566 | setobj(L,&cl->c.upvalue[n],L->top+n); |
5567 | setclvalue(L,L->top,cl); |
5568 | api_incr_top(L); |
5569 | } |
5570 | static void lua_pushboolean(lua_State*L,int b){ |
5571 | setbvalue(L->top,(b!=0)); |
5572 | api_incr_top(L); |
5573 | } |
5574 | static int lua_pushthread(lua_State*L){ |
5575 | setthvalue(L,L->top,L); |
5576 | api_incr_top(L); |
5577 | return(G(L)->mainthread==L); |
5578 | } |
5579 | static void lua_gettable(lua_State*L,int idx){ |
5580 | StkId t; |
5581 | t=index2adr(L,idx); |
5582 | api_checkvalidindex(L,t); |
5583 | luaV_gettable(L,t,L->top-1,L->top-1); |
5584 | } |
5585 | static void lua_getfield(lua_State*L,int idx,const char*k){ |
5586 | StkId t; |
5587 | TValue key; |
5588 | t=index2adr(L,idx); |
5589 | api_checkvalidindex(L,t); |
5590 | setsvalue(L,&key,luaS_new(L,k)); |
5591 | luaV_gettable(L,t,&key,L->top); |
5592 | api_incr_top(L); |
5593 | } |
5594 | static void lua_rawget(lua_State*L,int idx){ |
5595 | StkId t; |
5596 | t=index2adr(L,idx); |
5597 | luai_apicheck(L,ttistable(t)); |
5598 | setobj(L,L->top-1,luaH_get(hvalue(t),L->top-1)); |
5599 | } |
5600 | static void lua_rawgeti(lua_State*L,int idx,int n){ |
5601 | StkId o; |
5602 | o=index2adr(L,idx); |
5603 | luai_apicheck(L,ttistable(o)); |
5604 | setobj(L,L->top,luaH_getnum(hvalue(o),n)); |
5605 | api_incr_top(L); |
5606 | } |
5607 | static void lua_createtable(lua_State*L,int narray,int nrec){ |
5608 | luaC_checkGC(L); |
5609 | sethvalue(L,L->top,luaH_new(L,narray,nrec)); |
5610 | api_incr_top(L); |
5611 | } |
5612 | static int lua_getmetatable(lua_State*L,int objindex){ |
5613 | const TValue*obj; |
5614 | Table*mt=NULL; |
5615 | int res; |
5616 | obj=index2adr(L,objindex); |
5617 | switch(ttype(obj)){ |
5618 | case 5: |
5619 | mt=hvalue(obj)->metatable; |
5620 | break; |
5621 | case 7: |
5622 | mt=uvalue(obj)->metatable; |
5623 | break; |
5624 | default: |
5625 | mt=G(L)->mt[ttype(obj)]; |
5626 | break; |
5627 | } |
5628 | if(mt==NULL) |
5629 | res=0; |
5630 | else{ |
5631 | sethvalue(L,L->top,mt); |
5632 | api_incr_top(L); |
5633 | res=1; |
5634 | } |
5635 | return res; |
5636 | } |
5637 | static void lua_getfenv(lua_State*L,int idx){ |
5638 | StkId o; |
5639 | o=index2adr(L,idx); |
5640 | api_checkvalidindex(L,o); |
5641 | switch(ttype(o)){ |
5642 | case 6: |
5643 | sethvalue(L,L->top,clvalue(o)->c.env); |
5644 | break; |
5645 | case 7: |
5646 | sethvalue(L,L->top,uvalue(o)->env); |
5647 | break; |
5648 | case 8: |
5649 | setobj(L,L->top,gt(thvalue(o))); |
5650 | break; |
5651 | default: |
5652 | setnilvalue(L->top); |
5653 | break; |
5654 | } |
5655 | api_incr_top(L); |
5656 | } |
5657 | static void lua_settable(lua_State*L,int idx){ |
5658 | StkId t; |
5659 | api_checknelems(L,2); |
5660 | t=index2adr(L,idx); |
5661 | api_checkvalidindex(L,t); |
5662 | luaV_settable(L,t,L->top-2,L->top-1); |
5663 | L->top-=2; |
5664 | } |
5665 | static void lua_setfield(lua_State*L,int idx,const char*k){ |
5666 | StkId t; |
5667 | TValue key; |
5668 | api_checknelems(L,1); |
5669 | t=index2adr(L,idx); |
5670 | api_checkvalidindex(L,t); |
5671 | setsvalue(L,&key,luaS_new(L,k)); |
5672 | luaV_settable(L,t,&key,L->top-1); |
5673 | L->top--; |
5674 | } |
5675 | static void lua_rawset(lua_State*L,int idx){ |
5676 | StkId t; |
5677 | api_checknelems(L,2); |
5678 | t=index2adr(L,idx); |
5679 | luai_apicheck(L,ttistable(t)); |
5680 | setobj(L,luaH_set(L,hvalue(t),L->top-2),L->top-1); |
5681 | luaC_barriert(L,hvalue(t),L->top-1); |
5682 | L->top-=2; |
5683 | } |
5684 | static void lua_rawseti(lua_State*L,int idx,int n){ |
5685 | StkId o; |
5686 | api_checknelems(L,1); |
5687 | o=index2adr(L,idx); |
5688 | luai_apicheck(L,ttistable(o)); |
5689 | setobj(L,luaH_setnum(L,hvalue(o),n),L->top-1); |
5690 | luaC_barriert(L,hvalue(o),L->top-1); |
5691 | L->top--; |
5692 | } |
5693 | static int lua_setmetatable(lua_State*L,int objindex){ |
5694 | TValue*obj; |
5695 | Table*mt; |
5696 | api_checknelems(L,1); |
5697 | obj=index2adr(L,objindex); |
5698 | api_checkvalidindex(L,obj); |
5699 | if(ttisnil(L->top-1)) |
5700 | mt=NULL; |
5701 | else{ |
5702 | luai_apicheck(L,ttistable(L->top-1)); |
5703 | mt=hvalue(L->top-1); |
5704 | } |
5705 | switch(ttype(obj)){ |
5706 | case 5:{ |
5707 | hvalue(obj)->metatable=mt; |
5708 | if(mt) |
5709 | luaC_objbarriert(L,hvalue(obj),mt); |
5710 | break; |
5711 | } |
5712 | case 7:{ |
5713 | uvalue(obj)->metatable=mt; |
5714 | if(mt) |
5715 | luaC_objbarrier(L,rawuvalue(obj),mt); |
5716 | break; |
5717 | } |
5718 | default:{ |
5719 | G(L)->mt[ttype(obj)]=mt; |
5720 | break; |
5721 | } |
5722 | } |
5723 | L->top--; |
5724 | return 1; |
5725 | } |
5726 | static int lua_setfenv(lua_State*L,int idx){ |
5727 | StkId o; |
5728 | int res=1; |
5729 | api_checknelems(L,1); |
5730 | o=index2adr(L,idx); |
5731 | api_checkvalidindex(L,o); |
5732 | luai_apicheck(L,ttistable(L->top-1)); |
5733 | switch(ttype(o)){ |
5734 | case 6: |
5735 | clvalue(o)->c.env=hvalue(L->top-1); |
5736 | break; |
5737 | case 7: |
5738 | uvalue(o)->env=hvalue(L->top-1); |
5739 | break; |
5740 | case 8: |
5741 | sethvalue(L,gt(thvalue(o)),hvalue(L->top-1)); |
5742 | break; |
5743 | default: |
5744 | res=0; |
5745 | break; |
5746 | } |
5747 | if(res)luaC_objbarrier(L,gcvalue(o),hvalue(L->top-1)); |
5748 | L->top--; |
5749 | return res; |
5750 | } |
5751 | #define adjustresults(L,nres){if(nres==(-1)&&L->top>=L->ci->top)L->ci->top=L->top;} |
5752 | #define checkresults(L,na,nr)luai_apicheck(L,(nr)==(-1)||(L->ci->top-L->top>=(nr)-(na))) |
5753 | static void lua_call(lua_State*L,int nargs,int nresults){ |
5754 | StkId func; |
5755 | api_checknelems(L,nargs+1); |
5756 | checkresults(L,nargs,nresults); |
5757 | func=L->top-(nargs+1); |
5758 | luaD_call(L,func,nresults); |
5759 | adjustresults(L,nresults); |
5760 | } |
5761 | struct CallS{ |
5762 | StkId func; |
5763 | int nresults; |
5764 | }; |
5765 | static void f_call(lua_State*L,void*ud){ |
5766 | struct CallS*c=cast(struct CallS*,ud); |
5767 | luaD_call(L,c->func,c->nresults); |
5768 | } |
5769 | static int lua_pcall(lua_State*L,int nargs,int nresults,int errfunc){ |
5770 | struct CallS c; |
5771 | int status; |
5772 | ptrdiff_t func; |
5773 | api_checknelems(L,nargs+1); |
5774 | checkresults(L,nargs,nresults); |
5775 | if(errfunc==0) |
5776 | func=0; |
5777 | else{ |
5778 | StkId o=index2adr(L,errfunc); |
5779 | api_checkvalidindex(L,o); |
5780 | func=savestack(L,o); |
5781 | } |
5782 | c.func=L->top-(nargs+1); |
5783 | c.nresults=nresults; |
5784 | status=luaD_pcall(L,f_call,&c,savestack(L,c.func),func); |
5785 | adjustresults(L,nresults); |
5786 | return status; |
5787 | } |
5788 | static int lua_load(lua_State*L,lua_Reader reader,void*data, |
5789 | const char*chunkname){ |
5790 | ZIO z; |
5791 | int status; |
5792 | if(!chunkname)chunkname="?" ; |
5793 | luaZ_init(L,&z,reader,data); |
5794 | status=luaD_protectedparser(L,&z,chunkname); |
5795 | return status; |
5796 | } |
5797 | static int lua_error(lua_State*L){ |
5798 | api_checknelems(L,1); |
5799 | luaG_errormsg(L); |
5800 | return 0; |
5801 | } |
5802 | static int lua_next(lua_State*L,int idx){ |
5803 | StkId t; |
5804 | int more; |
5805 | t=index2adr(L,idx); |
5806 | luai_apicheck(L,ttistable(t)); |
5807 | more=luaH_next(L,hvalue(t),L->top-1); |
5808 | if(more){ |
5809 | api_incr_top(L); |
5810 | } |
5811 | else |
5812 | L->top-=1; |
5813 | return more; |
5814 | } |
5815 | static void lua_concat(lua_State*L,int n){ |
5816 | api_checknelems(L,n); |
5817 | if(n>=2){ |
5818 | luaC_checkGC(L); |
5819 | luaV_concat(L,n,cast_int(L->top-L->base)-1); |
5820 | L->top-=(n-1); |
5821 | } |
5822 | else if(n==0){ |
5823 | setsvalue(L,L->top,luaS_newlstr(L,"" ,0)); |
5824 | api_incr_top(L); |
5825 | } |
5826 | } |
5827 | static void*lua_newuserdata(lua_State*L,size_t size){ |
5828 | Udata*u; |
5829 | luaC_checkGC(L); |
5830 | u=luaS_newudata(L,size,getcurrenv(L)); |
5831 | setuvalue(L,L->top,u); |
5832 | api_incr_top(L); |
5833 | return u+1; |
5834 | } |
5835 | #define luaL_getn(L,i)((int)lua_objlen(L,i)) |
5836 | #define luaL_setn(L,i,j)((void)0) |
5837 | typedef struct luaL_Reg{ |
5838 | const char*name; |
5839 | lua_CFunction func; |
5840 | }luaL_Reg; |
5841 | static void luaI_openlib(lua_State*L,const char*libname, |
5842 | const luaL_Reg*l,int nup); |
5843 | static int luaL_argerror(lua_State*L,int numarg,const char*); |
5844 | static const char* luaL_checklstring(lua_State*L,int numArg, |
5845 | size_t*l); |
5846 | static const char* luaL_optlstring(lua_State*L,int numArg, |
5847 | const char*def,size_t*l); |
5848 | static lua_Integer luaL_checkinteger(lua_State*L,int numArg); |
5849 | static lua_Integer luaL_optinteger(lua_State*L,int nArg, |
5850 | lua_Integer def); |
5851 | static int luaL_error(lua_State*L,const char*fmt,...); |
5852 | static const char* luaL_findtable(lua_State*L,int idx, |
5853 | const char*fname,int szhint); |
5854 | #define luaL_argcheck(L,cond,numarg,extramsg)((void)((cond)||luaL_argerror(L,(numarg),(extramsg)))) |
5855 | #define luaL_checkstring(L,n)(luaL_checklstring(L,(n),NULL)) |
5856 | #define luaL_optstring(L,n,d)(luaL_optlstring(L,(n),(d),NULL)) |
5857 | #define luaL_checkint(L,n)((int)luaL_checkinteger(L,(n))) |
5858 | #define luaL_optint(L,n,d)((int)luaL_optinteger(L,(n),(d))) |
5859 | #define luaL_typename(L,i)lua_typename(L,lua_type(L,(i))) |
5860 | #define luaL_getmetatable(L,n)(lua_getfield(L,(-10000),(n))) |
5861 | #define luaL_opt(L,f,n,d)(lua_isnoneornil(L,(n))?(d):f(L,(n))) |
5862 | typedef struct luaL_Buffer{ |
5863 | char*p; |
5864 | int lvl; |
5865 | lua_State*L; |
5866 | char buffer[BUFSIZ]; |
5867 | }luaL_Buffer; |
5868 | #define luaL_addchar(B,c)((void)((B)->p<((B)->buffer+BUFSIZ)||luaL_prepbuffer(B)),(*(B)->p++=(char)(c))) |
5869 | #define luaL_addsize(B,n)((B)->p+=(n)) |
5870 | static char* luaL_prepbuffer(luaL_Buffer*B); |
5871 | static int luaL_argerror(lua_State*L,int narg,const char*){ |
5872 | lua_Debug ar; |
5873 | if(!lua_getstack(L,0,&ar)) |
5874 | return luaL_error(L,"bad argument #%d (%s)" ,narg,extramsg); |
5875 | lua_getinfo(L,"n" ,&ar); |
5876 | if(strcmp(ar.namewhat,"method" )==0){ |
5877 | narg--; |
5878 | if(narg==0) |
5879 | return luaL_error(L,"calling " LUA_QL("%s" )" on bad self (%s)" , |
5880 | ar.name,extramsg); |
5881 | } |
5882 | if(ar.name==NULL) |
5883 | ar.name="?" ; |
5884 | return luaL_error(L,"bad argument #%d to " LUA_QL("%s" )" (%s)" , |
5885 | narg,ar.name,extramsg); |
5886 | } |
5887 | static int luaL_typerror(lua_State*L,int narg,const char*tname){ |
5888 | const char*msg=lua_pushfstring(L,"%s expected, got %s" , |
5889 | tname,luaL_typename(L,narg)); |
5890 | return luaL_argerror(L,narg,msg); |
5891 | } |
5892 | static void tag_error(lua_State*L,int narg,int tag){ |
5893 | luaL_typerror(L,narg,lua_typename(L,tag)); |
5894 | } |
5895 | static void luaL_where(lua_State*L,int level){ |
5896 | lua_Debug ar; |
5897 | if(lua_getstack(L,level,&ar)){ |
5898 | lua_getinfo(L,"Sl" ,&ar); |
5899 | if(ar.currentline>0){ |
5900 | lua_pushfstring(L,"%s:%d: " ,ar.short_src,ar.currentline); |
5901 | return; |
5902 | } |
5903 | } |
5904 | lua_pushliteral(L,"" ); |
5905 | } |
5906 | static int luaL_error(lua_State*L,const char*fmt,...){ |
5907 | va_list argp; |
5908 | va_start(argp,fmt); |
5909 | luaL_where(L,1); |
5910 | lua_pushvfstring(L,fmt,argp); |
5911 | va_end(argp); |
5912 | lua_concat(L,2); |
5913 | return lua_error(L); |
5914 | } |
5915 | static int luaL_newmetatable(lua_State*L,const char*tname){ |
5916 | lua_getfield(L,(-10000),tname); |
5917 | if(!lua_isnil(L,-1)) |
5918 | return 0; |
5919 | lua_pop(L,1); |
5920 | lua_newtable(L); |
5921 | lua_pushvalue(L,-1); |
5922 | lua_setfield(L,(-10000),tname); |
5923 | return 1; |
5924 | } |
5925 | static void*luaL_checkudata(lua_State*L,int ud,const char*tname){ |
5926 | void*p=lua_touserdata(L,ud); |
5927 | if(p!=NULL){ |
5928 | if(lua_getmetatable(L,ud)){ |
5929 | lua_getfield(L,(-10000),tname); |
5930 | if(lua_rawequal(L,-1,-2)){ |
5931 | lua_pop(L,2); |
5932 | return p; |
5933 | } |
5934 | } |
5935 | } |
5936 | luaL_typerror(L,ud,tname); |
5937 | return NULL; |
5938 | } |
5939 | static void luaL_checkstack(lua_State*L,int space,const char*mes){ |
5940 | if(!lua_checkstack(L,space)) |
5941 | luaL_error(L,"stack overflow (%s)" ,mes); |
5942 | } |
5943 | static void luaL_checktype(lua_State*L,int narg,int t){ |
5944 | if(lua_type(L,narg)!=t) |
5945 | tag_error(L,narg,t); |
5946 | } |
5947 | static void luaL_checkany(lua_State*L,int narg){ |
5948 | if(lua_type(L,narg)==(-1)) |
5949 | luaL_argerror(L,narg,"value expected" ); |
5950 | } |
5951 | static const char*luaL_checklstring(lua_State*L,int narg,size_t*len){ |
5952 | const char*s=lua_tolstring(L,narg,len); |
5953 | if(!s)tag_error(L,narg,4); |
5954 | return s; |
5955 | } |
5956 | static const char*luaL_optlstring(lua_State*L,int narg, |
5957 | const char*def,size_t*len){ |
5958 | if(lua_isnoneornil(L,narg)){ |
5959 | if(len) |
5960 | *len=(def?strlen(def):0); |
5961 | return def; |
5962 | } |
5963 | else return luaL_checklstring(L,narg,len); |
5964 | } |
5965 | static lua_Number luaL_checknumber(lua_State*L,int narg){ |
5966 | lua_Number d=lua_tonumber(L,narg); |
5967 | if(d==0&&!lua_isnumber(L,narg)) |
5968 | tag_error(L,narg,3); |
5969 | return d; |
5970 | } |
5971 | static lua_Integer luaL_checkinteger(lua_State*L,int narg){ |
5972 | lua_Integer d=lua_tointeger(L,narg); |
5973 | if(d==0&&!lua_isnumber(L,narg)) |
5974 | tag_error(L,narg,3); |
5975 | return d; |
5976 | } |
5977 | static lua_Integer luaL_optinteger(lua_State*L,int narg, |
5978 | lua_Integer def){ |
5979 | return luaL_opt(L,luaL_checkinteger,narg,def); |
5980 | } |
5981 | static int luaL_getmetafield(lua_State*L,int obj,const char*event){ |
5982 | if(!lua_getmetatable(L,obj)) |
5983 | return 0; |
5984 | lua_pushstring(L,event); |
5985 | lua_rawget(L,-2); |
5986 | if(lua_isnil(L,-1)){ |
5987 | lua_pop(L,2); |
5988 | return 0; |
5989 | } |
5990 | else{ |
5991 | lua_remove(L,-2); |
5992 | return 1; |
5993 | } |
5994 | } |
5995 | static void luaL_register(lua_State*L,const char*libname, |
5996 | const luaL_Reg*l){ |
5997 | luaI_openlib(L,libname,l,0); |
5998 | } |
5999 | static int libsize(const luaL_Reg*l){ |
6000 | int size=0; |
6001 | for(;l->name;l++)size++; |
6002 | return size; |
6003 | } |
6004 | static void luaI_openlib(lua_State*L,const char*libname, |
6005 | const luaL_Reg*l,int nup){ |
6006 | if(libname){ |
6007 | int size=libsize(l); |
6008 | luaL_findtable(L,(-10000),"_LOADED" ,1); |
6009 | lua_getfield(L,-1,libname); |
6010 | if(!lua_istable(L,-1)){ |
6011 | lua_pop(L,1); |
6012 | if(luaL_findtable(L,(-10002),libname,size)!=NULL) |
6013 | luaL_error(L,"name conflict for module " LUA_QL("%s" ),libname); |
6014 | lua_pushvalue(L,-1); |
6015 | lua_setfield(L,-3,libname); |
6016 | } |
6017 | lua_remove(L,-2); |
6018 | lua_insert(L,-(nup+1)); |
6019 | } |
6020 | for(;l->name;l++){ |
6021 | int i; |
6022 | for(i=0;i<nup;i++) |
6023 | lua_pushvalue(L,-nup); |
6024 | lua_pushcclosure(L,l->func,nup); |
6025 | lua_setfield(L,-(nup+2),l->name); |
6026 | } |
6027 | lua_pop(L,nup); |
6028 | } |
6029 | static const char*luaL_findtable(lua_State*L,int idx, |
6030 | const char*fname,int szhint){ |
6031 | const char*e; |
6032 | lua_pushvalue(L,idx); |
6033 | do{ |
6034 | e=strchr(fname,'.'); |
6035 | if(e==NULL)e=fname+strlen(fname); |
6036 | lua_pushlstring(L,fname,e-fname); |
6037 | lua_rawget(L,-2); |
6038 | if(lua_isnil(L,-1)){ |
6039 | lua_pop(L,1); |
6040 | lua_createtable(L,0,(*e=='.'?1:szhint)); |
6041 | lua_pushlstring(L,fname,e-fname); |
6042 | lua_pushvalue(L,-2); |
6043 | lua_settable(L,-4); |
6044 | } |
6045 | else if(!lua_istable(L,-1)){ |
6046 | lua_pop(L,2); |
6047 | return fname; |
6048 | } |
6049 | lua_remove(L,-2); |
6050 | fname=e+1; |
6051 | }while(*e=='.'); |
6052 | return NULL; |
6053 | } |
6054 | #define bufflen(B)((B)->p-(B)->buffer) |
6055 | #define bufffree(B)((size_t)(BUFSIZ-bufflen(B))) |
6056 | static int emptybuffer(luaL_Buffer*B){ |
6057 | size_t l=bufflen(B); |
6058 | if(l==0)return 0; |
6059 | else{ |
6060 | lua_pushlstring(B->L,B->buffer,l); |
6061 | B->p=B->buffer; |
6062 | B->lvl++; |
6063 | return 1; |
6064 | } |
6065 | } |
6066 | static void adjuststack(luaL_Buffer*B){ |
6067 | if(B->lvl>1){ |
6068 | lua_State*L=B->L; |
6069 | int toget=1; |
6070 | size_t toplen=lua_strlen(L,-1); |
6071 | do{ |
6072 | size_t l=lua_strlen(L,-(toget+1)); |
6073 | if(B->lvl-toget+1>=(20/2)||toplen>l){ |
6074 | toplen+=l; |
6075 | toget++; |
6076 | } |
6077 | else break; |
6078 | }while(toget<B->lvl); |
6079 | lua_concat(L,toget); |
6080 | B->lvl=B->lvl-toget+1; |
6081 | } |
6082 | } |
6083 | static char*luaL_prepbuffer(luaL_Buffer*B){ |
6084 | if(emptybuffer(B)) |
6085 | adjuststack(B); |
6086 | return B->buffer; |
6087 | } |
6088 | static void luaL_addlstring(luaL_Buffer*B,const char*s,size_t l){ |
6089 | while(l--) |
6090 | luaL_addchar(B,*s++); |
6091 | } |
6092 | static void luaL_pushresult(luaL_Buffer*B){ |
6093 | emptybuffer(B); |
6094 | lua_concat(B->L,B->lvl); |
6095 | B->lvl=1; |
6096 | } |
6097 | static void luaL_addvalue(luaL_Buffer*B){ |
6098 | lua_State*L=B->L; |
6099 | size_t vl; |
6100 | const char*s=lua_tolstring(L,-1,&vl); |
6101 | if(vl<=bufffree(B)){ |
6102 | memcpy(B->p,s,vl); |
6103 | B->p+=vl; |
6104 | lua_pop(L,1); |
6105 | } |
6106 | else{ |
6107 | if(emptybuffer(B)) |
6108 | lua_insert(L,-2); |
6109 | B->lvl++; |
6110 | adjuststack(B); |
6111 | } |
6112 | } |
6113 | static void luaL_buffinit(lua_State*L,luaL_Buffer*B){ |
6114 | B->L=L; |
6115 | B->p=B->buffer; |
6116 | B->lvl=0; |
6117 | } |
6118 | typedef struct LoadF{ |
6119 | int ; |
6120 | FILE*f; |
6121 | char buff[BUFSIZ]; |
6122 | }LoadF; |
6123 | static const char*getF(lua_State*L,void*ud,size_t*size){ |
6124 | LoadF*lf=(LoadF*)ud; |
6125 | (void)L; |
6126 | if(lf->extraline){ |
6127 | lf->extraline=0; |
6128 | *size=1; |
6129 | return"\n" ; |
6130 | } |
6131 | if(feof(lf->f))return NULL; |
6132 | *size=fread(lf->buff,1,sizeof(lf->buff),lf->f); |
6133 | return(*size>0)?lf->buff:NULL; |
6134 | } |
6135 | static int errfile(lua_State*L,const char*what,int fnameindex){ |
6136 | const char*serr=strerror(errno); |
6137 | const char*filename=lua_tostring(L,fnameindex)+1; |
6138 | lua_pushfstring(L,"cannot %s %s: %s" ,what,filename,serr); |
6139 | lua_remove(L,fnameindex); |
6140 | return(5+1); |
6141 | } |
6142 | static int luaL_loadfile(lua_State*L,const char*filename){ |
6143 | LoadF lf; |
6144 | int status,readstatus; |
6145 | int c; |
6146 | int fnameindex=lua_gettop(L)+1; |
6147 | lf.extraline=0; |
6148 | if(filename==NULL){ |
6149 | lua_pushliteral(L,"=stdin" ); |
6150 | lf.f=stdin; |
6151 | } |
6152 | else{ |
6153 | lua_pushfstring(L,"@%s" ,filename); |
6154 | lf.f=fopen(filename,"r" ); |
6155 | if(lf.f==NULL)return errfile(L,"open" ,fnameindex); |
6156 | } |
6157 | c=getc(lf.f); |
6158 | if(c=='#'){ |
6159 | lf.extraline=1; |
6160 | while((c=getc(lf.f))!=EOF&&c!='\n'); |
6161 | if(c=='\n')c=getc(lf.f); |
6162 | } |
6163 | if(c=="\033Lua" [0]&&filename){ |
6164 | lf.f=freopen(filename,"rb" ,lf.f); |
6165 | if(lf.f==NULL)return errfile(L,"reopen" ,fnameindex); |
6166 | while((c=getc(lf.f))!=EOF&&c!="\033Lua" [0]); |
6167 | lf.extraline=0; |
6168 | } |
6169 | ungetc(c,lf.f); |
6170 | status=lua_load(L,getF,&lf,lua_tostring(L,-1)); |
6171 | readstatus=ferror(lf.f); |
6172 | if(filename)fclose(lf.f); |
6173 | if(readstatus){ |
6174 | lua_settop(L,fnameindex); |
6175 | return errfile(L,"read" ,fnameindex); |
6176 | } |
6177 | lua_remove(L,fnameindex); |
6178 | return status; |
6179 | } |
6180 | typedef struct LoadS{ |
6181 | const char*s; |
6182 | size_t size; |
6183 | }LoadS; |
6184 | static const char*getS(lua_State*L,void*ud,size_t*size){ |
6185 | LoadS*ls=(LoadS*)ud; |
6186 | (void)L; |
6187 | if(ls->size==0)return NULL; |
6188 | *size=ls->size; |
6189 | ls->size=0; |
6190 | return ls->s; |
6191 | } |
6192 | static int luaL_loadbuffer(lua_State*L,const char*buff,size_t size, |
6193 | const char*name){ |
6194 | LoadS ls; |
6195 | ls.s=buff; |
6196 | ls.size=size; |
6197 | return lua_load(L,getS,&ls,name); |
6198 | } |
6199 | static void*l_alloc(void*ud,void*ptr,size_t osize,size_t nsize){ |
6200 | (void)ud; |
6201 | (void)osize; |
6202 | if(nsize==0){ |
6203 | free(ptr); |
6204 | return NULL; |
6205 | } |
6206 | else |
6207 | return realloc(ptr,nsize); |
6208 | } |
6209 | static int panic(lua_State*L){ |
6210 | (void)L; |
6211 | fprintf(stderr,"PANIC: unprotected error in call to Lua API (%s)\n" , |
6212 | lua_tostring(L,-1)); |
6213 | return 0; |
6214 | } |
6215 | static lua_State*luaL_newstate(void){ |
6216 | lua_State*L=lua_newstate(l_alloc,NULL); |
6217 | if(L)lua_atpanic(L,&panic); |
6218 | return L; |
6219 | } |
6220 | static int luaB_tonumber(lua_State*L){ |
6221 | int base=luaL_optint(L,2,10); |
6222 | if(base==10){ |
6223 | luaL_checkany(L,1); |
6224 | if(lua_isnumber(L,1)){ |
6225 | lua_pushnumber(L,lua_tonumber(L,1)); |
6226 | return 1; |
6227 | } |
6228 | } |
6229 | else{ |
6230 | const char*s1=luaL_checkstring(L,1); |
6231 | char*s2; |
6232 | unsigned long n; |
6233 | luaL_argcheck(L,2<=base&&base<=36,2,"base out of range" ); |
6234 | n=strtoul(s1,&s2,base); |
6235 | if(s1!=s2){ |
6236 | while(isspace((unsigned char)(*s2)))s2++; |
6237 | if(*s2=='\0'){ |
6238 | lua_pushnumber(L,(lua_Number)n); |
6239 | return 1; |
6240 | } |
6241 | } |
6242 | } |
6243 | lua_pushnil(L); |
6244 | return 1; |
6245 | } |
6246 | static int luaB_error(lua_State*L){ |
6247 | int level=luaL_optint(L,2,1); |
6248 | lua_settop(L,1); |
6249 | if(lua_isstring(L,1)&&level>0){ |
6250 | luaL_where(L,level); |
6251 | lua_pushvalue(L,1); |
6252 | lua_concat(L,2); |
6253 | } |
6254 | return lua_error(L); |
6255 | } |
6256 | static int luaB_setmetatable(lua_State*L){ |
6257 | int t=lua_type(L,2); |
6258 | luaL_checktype(L,1,5); |
6259 | luaL_argcheck(L,t==0||t==5,2, |
6260 | "nil or table expected" ); |
6261 | if(luaL_getmetafield(L,1,"__metatable" )) |
6262 | luaL_error(L,"cannot change a protected metatable" ); |
6263 | lua_settop(L,2); |
6264 | lua_setmetatable(L,1); |
6265 | return 1; |
6266 | } |
6267 | static void getfunc(lua_State*L,int opt){ |
6268 | if(lua_isfunction(L,1))lua_pushvalue(L,1); |
6269 | else{ |
6270 | lua_Debug ar; |
6271 | int level=opt?luaL_optint(L,1,1):luaL_checkint(L,1); |
6272 | luaL_argcheck(L,level>=0,1,"level must be non-negative" ); |
6273 | if(lua_getstack(L,level,&ar)==0) |
6274 | luaL_argerror(L,1,"invalid level" ); |
6275 | lua_getinfo(L,"f" ,&ar); |
6276 | if(lua_isnil(L,-1)) |
6277 | luaL_error(L,"no function environment for tail call at level %d" , |
6278 | level); |
6279 | } |
6280 | } |
6281 | static int luaB_setfenv(lua_State*L){ |
6282 | luaL_checktype(L,2,5); |
6283 | getfunc(L,0); |
6284 | lua_pushvalue(L,2); |
6285 | if(lua_isnumber(L,1)&&lua_tonumber(L,1)==0){ |
6286 | lua_pushthread(L); |
6287 | lua_insert(L,-2); |
6288 | lua_setfenv(L,-2); |
6289 | return 0; |
6290 | } |
6291 | else if(lua_iscfunction(L,-2)||lua_setfenv(L,-2)==0) |
6292 | luaL_error(L, |
6293 | LUA_QL("setfenv" )" cannot change environment of given object" ); |
6294 | return 1; |
6295 | } |
6296 | static int luaB_rawget(lua_State*L){ |
6297 | luaL_checktype(L,1,5); |
6298 | luaL_checkany(L,2); |
6299 | lua_settop(L,2); |
6300 | lua_rawget(L,1); |
6301 | return 1; |
6302 | } |
6303 | static int luaB_type(lua_State*L){ |
6304 | luaL_checkany(L,1); |
6305 | lua_pushstring(L,luaL_typename(L,1)); |
6306 | return 1; |
6307 | } |
6308 | static int luaB_next(lua_State*L){ |
6309 | luaL_checktype(L,1,5); |
6310 | lua_settop(L,2); |
6311 | if(lua_next(L,1)) |
6312 | return 2; |
6313 | else{ |
6314 | lua_pushnil(L); |
6315 | return 1; |
6316 | } |
6317 | } |
6318 | static int luaB_pairs(lua_State*L){ |
6319 | luaL_checktype(L,1,5); |
6320 | lua_pushvalue(L,lua_upvalueindex(1)); |
6321 | lua_pushvalue(L,1); |
6322 | lua_pushnil(L); |
6323 | return 3; |
6324 | } |
6325 | static int ipairsaux(lua_State*L){ |
6326 | int i=luaL_checkint(L,2); |
6327 | luaL_checktype(L,1,5); |
6328 | i++; |
6329 | lua_pushinteger(L,i); |
6330 | lua_rawgeti(L,1,i); |
6331 | return(lua_isnil(L,-1))?0:2; |
6332 | } |
6333 | static int luaB_ipairs(lua_State*L){ |
6334 | luaL_checktype(L,1,5); |
6335 | lua_pushvalue(L,lua_upvalueindex(1)); |
6336 | lua_pushvalue(L,1); |
6337 | lua_pushinteger(L,0); |
6338 | return 3; |
6339 | } |
6340 | static int load_aux(lua_State*L,int status){ |
6341 | if(status==0) |
6342 | return 1; |
6343 | else{ |
6344 | lua_pushnil(L); |
6345 | lua_insert(L,-2); |
6346 | return 2; |
6347 | } |
6348 | } |
6349 | static int luaB_loadstring(lua_State*L){ |
6350 | size_t l; |
6351 | const char*s=luaL_checklstring(L,1,&l); |
6352 | const char*chunkname=luaL_optstring(L,2,s); |
6353 | return load_aux(L,luaL_loadbuffer(L,s,l,chunkname)); |
6354 | } |
6355 | static int luaB_loadfile(lua_State*L){ |
6356 | const char*fname=luaL_optstring(L,1,NULL); |
6357 | return load_aux(L,luaL_loadfile(L,fname)); |
6358 | } |
6359 | static int luaB_assert(lua_State*L){ |
6360 | luaL_checkany(L,1); |
6361 | if(!lua_toboolean(L,1)) |
6362 | return luaL_error(L,"%s" ,luaL_optstring(L,2,"assertion failed!" )); |
6363 | return lua_gettop(L); |
6364 | } |
6365 | static int luaB_unpack(lua_State*L){ |
6366 | int i,e,n; |
6367 | luaL_checktype(L,1,5); |
6368 | i=luaL_optint(L,2,1); |
6369 | e=luaL_opt(L,luaL_checkint,3,luaL_getn(L,1)); |
6370 | if(i>e)return 0; |
6371 | n=e-i+1; |
6372 | if(n<=0||!lua_checkstack(L,n)) |
6373 | return luaL_error(L,"too many results to unpack" ); |
6374 | lua_rawgeti(L,1,i); |
6375 | while(i++<e) |
6376 | lua_rawgeti(L,1,i); |
6377 | return n; |
6378 | } |
6379 | static int luaB_pcall(lua_State*L){ |
6380 | int status; |
6381 | luaL_checkany(L,1); |
6382 | status=lua_pcall(L,lua_gettop(L)-1,(-1),0); |
6383 | lua_pushboolean(L,(status==0)); |
6384 | lua_insert(L,1); |
6385 | return lua_gettop(L); |
6386 | } |
6387 | static int luaB_newproxy(lua_State*L){ |
6388 | lua_settop(L,1); |
6389 | lua_newuserdata(L,0); |
6390 | if(lua_toboolean(L,1)==0) |
6391 | return 1; |
6392 | else if(lua_isboolean(L,1)){ |
6393 | lua_newtable(L); |
6394 | lua_pushvalue(L,-1); |
6395 | lua_pushboolean(L,1); |
6396 | lua_rawset(L,lua_upvalueindex(1)); |
6397 | } |
6398 | else{ |
6399 | int validproxy=0; |
6400 | if(lua_getmetatable(L,1)){ |
6401 | lua_rawget(L,lua_upvalueindex(1)); |
6402 | validproxy=lua_toboolean(L,-1); |
6403 | lua_pop(L,1); |
6404 | } |
6405 | luaL_argcheck(L,validproxy,1,"boolean or proxy expected" ); |
6406 | lua_getmetatable(L,1); |
6407 | } |
6408 | lua_setmetatable(L,2); |
6409 | return 1; |
6410 | } |
6411 | static const luaL_Reg base_funcs[]={ |
6412 | {"assert" ,luaB_assert}, |
6413 | {"error" ,luaB_error}, |
6414 | {"loadfile" ,luaB_loadfile}, |
6415 | {"loadstring" ,luaB_loadstring}, |
6416 | {"next" ,luaB_next}, |
6417 | {"pcall" ,luaB_pcall}, |
6418 | {"rawget" ,luaB_rawget}, |
6419 | {"setfenv" ,luaB_setfenv}, |
6420 | {"setmetatable" ,luaB_setmetatable}, |
6421 | {"tonumber" ,luaB_tonumber}, |
6422 | {"type" ,luaB_type}, |
6423 | {"unpack" ,luaB_unpack}, |
6424 | {NULL,NULL} |
6425 | }; |
6426 | static void auxopen(lua_State*L,const char*name, |
6427 | lua_CFunction f,lua_CFunction u){ |
6428 | lua_pushcfunction(L,u); |
6429 | lua_pushcclosure(L,f,1); |
6430 | lua_setfield(L,-2,name); |
6431 | } |
6432 | static void base_open(lua_State*L){ |
6433 | lua_pushvalue(L,(-10002)); |
6434 | lua_setglobal(L,"_G" ); |
6435 | luaL_register(L,"_G" ,base_funcs); |
6436 | lua_pushliteral(L,"Lua 5.1" ); |
6437 | lua_setglobal(L,"_VERSION" ); |
6438 | auxopen(L,"ipairs" ,luaB_ipairs,ipairsaux); |
6439 | auxopen(L,"pairs" ,luaB_pairs,luaB_next); |
6440 | lua_createtable(L,0,1); |
6441 | lua_pushvalue(L,-1); |
6442 | lua_setmetatable(L,-2); |
6443 | lua_pushliteral(L,"kv" ); |
6444 | lua_setfield(L,-2,"__mode" ); |
6445 | lua_pushcclosure(L,luaB_newproxy,1); |
6446 | lua_setglobal(L,"newproxy" ); |
6447 | } |
6448 | static int luaopen_base(lua_State*L){ |
6449 | base_open(L); |
6450 | return 1; |
6451 | } |
6452 | #define aux_getn(L,n)(luaL_checktype(L,n,5),luaL_getn(L,n)) |
6453 | static int tinsert(lua_State*L){ |
6454 | int e=aux_getn(L,1)+1; |
6455 | int pos; |
6456 | switch(lua_gettop(L)){ |
6457 | case 2:{ |
6458 | pos=e; |
6459 | break; |
6460 | } |
6461 | case 3:{ |
6462 | int i; |
6463 | pos=luaL_checkint(L,2); |
6464 | if(pos>e)e=pos; |
6465 | for(i=e;i>pos;i--){ |
6466 | lua_rawgeti(L,1,i-1); |
6467 | lua_rawseti(L,1,i); |
6468 | } |
6469 | break; |
6470 | } |
6471 | default:{ |
6472 | return luaL_error(L,"wrong number of arguments to " LUA_QL("insert" )); |
6473 | } |
6474 | } |
6475 | luaL_setn(L,1,e); |
6476 | lua_rawseti(L,1,pos); |
6477 | return 0; |
6478 | } |
6479 | static int tremove(lua_State*L){ |
6480 | int e=aux_getn(L,1); |
6481 | int pos=luaL_optint(L,2,e); |
6482 | if(!(1<=pos&&pos<=e)) |
6483 | return 0; |
6484 | luaL_setn(L,1,e-1); |
6485 | lua_rawgeti(L,1,pos); |
6486 | for(;pos<e;pos++){ |
6487 | lua_rawgeti(L,1,pos+1); |
6488 | lua_rawseti(L,1,pos); |
6489 | } |
6490 | lua_pushnil(L); |
6491 | lua_rawseti(L,1,e); |
6492 | return 1; |
6493 | } |
6494 | static void addfield(lua_State*L,luaL_Buffer*b,int i){ |
6495 | lua_rawgeti(L,1,i); |
6496 | if(!lua_isstring(L,-1)) |
6497 | luaL_error(L,"invalid value (%s) at index %d in table for " |
6498 | LUA_QL("concat" ),luaL_typename(L,-1),i); |
6499 | luaL_addvalue(b); |
6500 | } |
6501 | static int tconcat(lua_State*L){ |
6502 | luaL_Buffer b; |
6503 | size_t lsep; |
6504 | int i,last; |
6505 | const char*sep=luaL_optlstring(L,2,"" ,&lsep); |
6506 | luaL_checktype(L,1,5); |
6507 | i=luaL_optint(L,3,1); |
6508 | last=luaL_opt(L,luaL_checkint,4,luaL_getn(L,1)); |
6509 | luaL_buffinit(L,&b); |
6510 | for(;i<last;i++){ |
6511 | addfield(L,&b,i); |
6512 | luaL_addlstring(&b,sep,lsep); |
6513 | } |
6514 | if(i==last) |
6515 | addfield(L,&b,i); |
6516 | luaL_pushresult(&b); |
6517 | return 1; |
6518 | } |
6519 | static void set2(lua_State*L,int i,int j){ |
6520 | lua_rawseti(L,1,i); |
6521 | lua_rawseti(L,1,j); |
6522 | } |
6523 | static int sort_comp(lua_State*L,int a,int b){ |
6524 | if(!lua_isnil(L,2)){ |
6525 | int res; |
6526 | lua_pushvalue(L,2); |
6527 | lua_pushvalue(L,a-1); |
6528 | lua_pushvalue(L,b-2); |
6529 | lua_call(L,2,1); |
6530 | res=lua_toboolean(L,-1); |
6531 | lua_pop(L,1); |
6532 | return res; |
6533 | } |
6534 | else |
6535 | return lua_lessthan(L,a,b); |
6536 | } |
6537 | static void auxsort(lua_State*L,int l,int u){ |
6538 | while(l<u){ |
6539 | int i,j; |
6540 | lua_rawgeti(L,1,l); |
6541 | lua_rawgeti(L,1,u); |
6542 | if(sort_comp(L,-1,-2)) |
6543 | set2(L,l,u); |
6544 | else |
6545 | lua_pop(L,2); |
6546 | if(u-l==1)break; |
6547 | i=(l+u)/2; |
6548 | lua_rawgeti(L,1,i); |
6549 | lua_rawgeti(L,1,l); |
6550 | if(sort_comp(L,-2,-1)) |
6551 | set2(L,i,l); |
6552 | else{ |
6553 | lua_pop(L,1); |
6554 | lua_rawgeti(L,1,u); |
6555 | if(sort_comp(L,-1,-2)) |
6556 | set2(L,i,u); |
6557 | else |
6558 | lua_pop(L,2); |
6559 | } |
6560 | if(u-l==2)break; |
6561 | lua_rawgeti(L,1,i); |
6562 | lua_pushvalue(L,-1); |
6563 | lua_rawgeti(L,1,u-1); |
6564 | set2(L,i,u-1); |
6565 | i=l;j=u-1; |
6566 | for(;;){ |
6567 | while(lua_rawgeti(L,1,++i),sort_comp(L,-1,-2)){ |
6568 | if(i>u)luaL_error(L,"invalid order function for sorting" ); |
6569 | lua_pop(L,1); |
6570 | } |
6571 | while(lua_rawgeti(L,1,--j),sort_comp(L,-3,-1)){ |
6572 | if(j<l)luaL_error(L,"invalid order function for sorting" ); |
6573 | lua_pop(L,1); |
6574 | } |
6575 | if(j<i){ |
6576 | lua_pop(L,3); |
6577 | break; |
6578 | } |
6579 | set2(L,i,j); |
6580 | } |
6581 | lua_rawgeti(L,1,u-1); |
6582 | lua_rawgeti(L,1,i); |
6583 | set2(L,u-1,i); |
6584 | if(i-l<u-i){ |
6585 | j=l;i=i-1;l=i+2; |
6586 | } |
6587 | else{ |
6588 | j=i+1;i=u;u=j-2; |
6589 | } |
6590 | auxsort(L,j,i); |
6591 | } |
6592 | } |
6593 | static int sort(lua_State*L){ |
6594 | int n=aux_getn(L,1); |
6595 | luaL_checkstack(L,40,"" ); |
6596 | if(!lua_isnoneornil(L,2)) |
6597 | luaL_checktype(L,2,6); |
6598 | lua_settop(L,2); |
6599 | auxsort(L,1,n); |
6600 | return 0; |
6601 | } |
6602 | static const luaL_Reg tab_funcs[]={ |
6603 | {"concat" ,tconcat}, |
6604 | {"insert" ,tinsert}, |
6605 | {"remove" ,tremove}, |
6606 | {"sort" ,sort}, |
6607 | {NULL,NULL} |
6608 | }; |
6609 | static int luaopen_table(lua_State*L){ |
6610 | luaL_register(L,"table" ,tab_funcs); |
6611 | return 1; |
6612 | } |
6613 | static const char*const fnames[]={"input" ,"output" }; |
6614 | static int pushresult(lua_State*L,int i,const char*filename){ |
6615 | int en=errno; |
6616 | if(i){ |
6617 | lua_pushboolean(L,1); |
6618 | return 1; |
6619 | } |
6620 | else{ |
6621 | lua_pushnil(L); |
6622 | if(filename) |
6623 | lua_pushfstring(L,"%s: %s" ,filename,strerror(en)); |
6624 | else |
6625 | lua_pushfstring(L,"%s" ,strerror(en)); |
6626 | lua_pushinteger(L,en); |
6627 | return 3; |
6628 | } |
6629 | } |
6630 | static void fileerror(lua_State*L,int arg,const char*filename){ |
6631 | lua_pushfstring(L,"%s: %s" ,filename,strerror(errno)); |
6632 | luaL_argerror(L,arg,lua_tostring(L,-1)); |
6633 | } |
6634 | #define tofilep(L)((FILE**)luaL_checkudata(L,1,"FILE*")) |
6635 | static int io_type(lua_State*L){ |
6636 | void*ud; |
6637 | luaL_checkany(L,1); |
6638 | ud=lua_touserdata(L,1); |
6639 | lua_getfield(L,(-10000),"FILE*" ); |
6640 | if(ud==NULL||!lua_getmetatable(L,1)||!lua_rawequal(L,-2,-1)) |
6641 | lua_pushnil(L); |
6642 | else if(*((FILE**)ud)==NULL) |
6643 | lua_pushliteral(L,"closed file" ); |
6644 | else |
6645 | lua_pushliteral(L,"file" ); |
6646 | return 1; |
6647 | } |
6648 | static FILE*tofile(lua_State*L){ |
6649 | FILE**f=tofilep(L); |
6650 | if(*f==NULL) |
6651 | luaL_error(L,"attempt to use a closed file" ); |
6652 | return*f; |
6653 | } |
6654 | static FILE**newfile(lua_State*L){ |
6655 | FILE**pf=(FILE**)lua_newuserdata(L,sizeof(FILE*)); |
6656 | *pf=NULL; |
6657 | luaL_getmetatable(L,"FILE*" ); |
6658 | lua_setmetatable(L,-2); |
6659 | return pf; |
6660 | } |
6661 | static int io_noclose(lua_State*L){ |
6662 | lua_pushnil(L); |
6663 | lua_pushliteral(L,"cannot close standard file" ); |
6664 | return 2; |
6665 | } |
6666 | static int io_pclose(lua_State*L){ |
6667 | FILE**p=tofilep(L); |
6668 | int ok=lua_pclose(L,*p); |
6669 | *p=NULL; |
6670 | return pushresult(L,ok,NULL); |
6671 | } |
6672 | static int io_fclose(lua_State*L){ |
6673 | FILE**p=tofilep(L); |
6674 | int ok=(fclose(*p)==0); |
6675 | *p=NULL; |
6676 | return pushresult(L,ok,NULL); |
6677 | } |
6678 | static int aux_close(lua_State*L){ |
6679 | lua_getfenv(L,1); |
6680 | lua_getfield(L,-1,"__close" ); |
6681 | return(lua_tocfunction(L,-1))(L); |
6682 | } |
6683 | static int io_close(lua_State*L){ |
6684 | if(lua_isnone(L,1)) |
6685 | lua_rawgeti(L,(-10001),2); |
6686 | tofile(L); |
6687 | return aux_close(L); |
6688 | } |
6689 | static int io_gc(lua_State*L){ |
6690 | FILE*f=*tofilep(L); |
6691 | if(f!=NULL) |
6692 | aux_close(L); |
6693 | return 0; |
6694 | } |
6695 | static int io_open(lua_State*L){ |
6696 | const char*filename=luaL_checkstring(L,1); |
6697 | const char*mode=luaL_optstring(L,2,"r" ); |
6698 | FILE**pf=newfile(L); |
6699 | *pf=fopen(filename,mode); |
6700 | return(*pf==NULL)?pushresult(L,0,filename):1; |
6701 | } |
6702 | static FILE*getiofile(lua_State*L,int findex){ |
6703 | FILE*f; |
6704 | lua_rawgeti(L,(-10001),findex); |
6705 | f=*(FILE**)lua_touserdata(L,-1); |
6706 | if(f==NULL) |
6707 | luaL_error(L,"standard %s file is closed" ,fnames[findex-1]); |
6708 | return f; |
6709 | } |
6710 | static int g_iofile(lua_State*L,int f,const char*mode){ |
6711 | if(!lua_isnoneornil(L,1)){ |
6712 | const char*filename=lua_tostring(L,1); |
6713 | if(filename){ |
6714 | FILE**pf=newfile(L); |
6715 | *pf=fopen(filename,mode); |
6716 | if(*pf==NULL) |
6717 | fileerror(L,1,filename); |
6718 | } |
6719 | else{ |
6720 | tofile(L); |
6721 | lua_pushvalue(L,1); |
6722 | } |
6723 | lua_rawseti(L,(-10001),f); |
6724 | } |
6725 | lua_rawgeti(L,(-10001),f); |
6726 | return 1; |
6727 | } |
6728 | static int io_input(lua_State*L){ |
6729 | return g_iofile(L,1,"r" ); |
6730 | } |
6731 | static int io_output(lua_State*L){ |
6732 | return g_iofile(L,2,"w" ); |
6733 | } |
6734 | static int io_readline(lua_State*L); |
6735 | static void aux_lines(lua_State*L,int idx,int toclose){ |
6736 | lua_pushvalue(L,idx); |
6737 | lua_pushboolean(L,toclose); |
6738 | lua_pushcclosure(L,io_readline,2); |
6739 | } |
6740 | static int f_lines(lua_State*L){ |
6741 | tofile(L); |
6742 | aux_lines(L,1,0); |
6743 | return 1; |
6744 | } |
6745 | static int io_lines(lua_State*L){ |
6746 | if(lua_isnoneornil(L,1)){ |
6747 | lua_rawgeti(L,(-10001),1); |
6748 | return f_lines(L); |
6749 | } |
6750 | else{ |
6751 | const char*filename=luaL_checkstring(L,1); |
6752 | FILE**pf=newfile(L); |
6753 | *pf=fopen(filename,"r" ); |
6754 | if(*pf==NULL) |
6755 | fileerror(L,1,filename); |
6756 | aux_lines(L,lua_gettop(L),1); |
6757 | return 1; |
6758 | } |
6759 | } |
6760 | static int read_number(lua_State*L,FILE*f){ |
6761 | lua_Number d; |
6762 | if(fscanf(f,"%lf" ,&d)==1){ |
6763 | lua_pushnumber(L,d); |
6764 | return 1; |
6765 | } |
6766 | else{ |
6767 | lua_pushnil(L); |
6768 | return 0; |
6769 | } |
6770 | } |
6771 | static int test_eof(lua_State*L,FILE*f){ |
6772 | int c=getc(f); |
6773 | ungetc(c,f); |
6774 | lua_pushlstring(L,NULL,0); |
6775 | return(c!=EOF); |
6776 | } |
6777 | static int read_line(lua_State*L,FILE*f){ |
6778 | luaL_Buffer b; |
6779 | luaL_buffinit(L,&b); |
6780 | for(;;){ |
6781 | size_t l; |
6782 | char*p=luaL_prepbuffer(&b); |
6783 | if(fgets(p,BUFSIZ,f)==NULL){ |
6784 | luaL_pushresult(&b); |
6785 | return(lua_objlen(L,-1)>0); |
6786 | } |
6787 | l=strlen(p); |
6788 | if(l==0||p[l-1]!='\n') |
6789 | luaL_addsize(&b,l); |
6790 | else{ |
6791 | luaL_addsize(&b,l-1); |
6792 | luaL_pushresult(&b); |
6793 | return 1; |
6794 | } |
6795 | } |
6796 | } |
6797 | static int read_chars(lua_State*L,FILE*f,size_t n){ |
6798 | size_t rlen; |
6799 | size_t nr; |
6800 | luaL_Buffer b; |
6801 | luaL_buffinit(L,&b); |
6802 | rlen=BUFSIZ; |
6803 | do{ |
6804 | char*p=luaL_prepbuffer(&b); |
6805 | if(rlen>n)rlen=n; |
6806 | nr=fread(p,sizeof(char),rlen,f); |
6807 | luaL_addsize(&b,nr); |
6808 | n-=nr; |
6809 | }while(n>0&&nr==rlen); |
6810 | luaL_pushresult(&b); |
6811 | return(n==0||lua_objlen(L,-1)>0); |
6812 | } |
6813 | static int g_read(lua_State*L,FILE*f,int first){ |
6814 | int nargs=lua_gettop(L)-1; |
6815 | int success; |
6816 | int n; |
6817 | clearerr(f); |
6818 | if(nargs==0){ |
6819 | success=read_line(L,f); |
6820 | n=first+1; |
6821 | } |
6822 | else{ |
6823 | luaL_checkstack(L,nargs+20,"too many arguments" ); |
6824 | success=1; |
6825 | for(n=first;nargs--&&success;n++){ |
6826 | if(lua_type(L,n)==3){ |
6827 | size_t l=(size_t)lua_tointeger(L,n); |
6828 | success=(l==0)?test_eof(L,f):read_chars(L,f,l); |
6829 | } |
6830 | else{ |
6831 | const char*p=lua_tostring(L,n); |
6832 | luaL_argcheck(L,p&&p[0]=='*',n,"invalid option" ); |
6833 | switch(p[1]){ |
6834 | case'n': |
6835 | success=read_number(L,f); |
6836 | break; |
6837 | case'l': |
6838 | success=read_line(L,f); |
6839 | break; |
6840 | case'a': |
6841 | read_chars(L,f,~((size_t)0)); |
6842 | success=1; |
6843 | break; |
6844 | default: |
6845 | return luaL_argerror(L,n,"invalid format" ); |
6846 | } |
6847 | } |
6848 | } |
6849 | } |
6850 | if(ferror(f)) |
6851 | return pushresult(L,0,NULL); |
6852 | if(!success){ |
6853 | lua_pop(L,1); |
6854 | lua_pushnil(L); |
6855 | } |
6856 | return n-first; |
6857 | } |
6858 | static int io_read(lua_State*L){ |
6859 | return g_read(L,getiofile(L,1),1); |
6860 | } |
6861 | static int f_read(lua_State*L){ |
6862 | return g_read(L,tofile(L),2); |
6863 | } |
6864 | static int io_readline(lua_State*L){ |
6865 | FILE*f=*(FILE**)lua_touserdata(L,lua_upvalueindex(1)); |
6866 | int sucess; |
6867 | if(f==NULL) |
6868 | luaL_error(L,"file is already closed" ); |
6869 | sucess=read_line(L,f); |
6870 | if(ferror(f)) |
6871 | return luaL_error(L,"%s" ,strerror(errno)); |
6872 | if(sucess)return 1; |
6873 | else{ |
6874 | if(lua_toboolean(L,lua_upvalueindex(2))){ |
6875 | lua_settop(L,0); |
6876 | lua_pushvalue(L,lua_upvalueindex(1)); |
6877 | aux_close(L); |
6878 | } |
6879 | return 0; |
6880 | } |
6881 | } |
6882 | static int g_write(lua_State*L,FILE*f,int arg){ |
6883 | int nargs=lua_gettop(L)-1; |
6884 | int status=1; |
6885 | for(;nargs--;arg++){ |
6886 | if(lua_type(L,arg)==3){ |
6887 | status=status&& |
6888 | fprintf(f,"%.14g" ,lua_tonumber(L,arg))>0; |
6889 | } |
6890 | else{ |
6891 | size_t l; |
6892 | const char*s=luaL_checklstring(L,arg,&l); |
6893 | status=status&&(fwrite(s,sizeof(char),l,f)==l); |
6894 | } |
6895 | } |
6896 | return pushresult(L,status,NULL); |
6897 | } |
6898 | static int io_write(lua_State*L){ |
6899 | return g_write(L,getiofile(L,2),1); |
6900 | } |
6901 | static int f_write(lua_State*L){ |
6902 | return g_write(L,tofile(L),2); |
6903 | } |
6904 | static int io_flush(lua_State*L){ |
6905 | return pushresult(L,fflush(getiofile(L,2))==0,NULL); |
6906 | } |
6907 | static int f_flush(lua_State*L){ |
6908 | return pushresult(L,fflush(tofile(L))==0,NULL); |
6909 | } |
6910 | static const luaL_Reg iolib[]={ |
6911 | {"close" ,io_close}, |
6912 | {"flush" ,io_flush}, |
6913 | {"input" ,io_input}, |
6914 | {"lines" ,io_lines}, |
6915 | {"open" ,io_open}, |
6916 | {"output" ,io_output}, |
6917 | {"read" ,io_read}, |
6918 | {"type" ,io_type}, |
6919 | {"write" ,io_write}, |
6920 | {NULL,NULL} |
6921 | }; |
6922 | static const luaL_Reg flib[]={ |
6923 | {"close" ,io_close}, |
6924 | {"flush" ,f_flush}, |
6925 | {"lines" ,f_lines}, |
6926 | {"read" ,f_read}, |
6927 | {"write" ,f_write}, |
6928 | {"__gc" ,io_gc}, |
6929 | {NULL,NULL} |
6930 | }; |
6931 | static void createmeta(lua_State*L){ |
6932 | luaL_newmetatable(L,"FILE*" ); |
6933 | lua_pushvalue(L,-1); |
6934 | lua_setfield(L,-2,"__index" ); |
6935 | luaL_register(L,NULL,flib); |
6936 | } |
6937 | static void createstdfile(lua_State*L,FILE*f,int k,const char*fname){ |
6938 | *newfile(L)=f; |
6939 | if(k>0){ |
6940 | lua_pushvalue(L,-1); |
6941 | lua_rawseti(L,(-10001),k); |
6942 | } |
6943 | lua_pushvalue(L,-2); |
6944 | lua_setfenv(L,-2); |
6945 | lua_setfield(L,-3,fname); |
6946 | } |
6947 | static void newfenv(lua_State*L,lua_CFunction cls){ |
6948 | lua_createtable(L,0,1); |
6949 | lua_pushcfunction(L,cls); |
6950 | lua_setfield(L,-2,"__close" ); |
6951 | } |
6952 | static int luaopen_io(lua_State*L){ |
6953 | createmeta(L); |
6954 | newfenv(L,io_fclose); |
6955 | lua_replace(L,(-10001)); |
6956 | luaL_register(L,"io" ,iolib); |
6957 | newfenv(L,io_noclose); |
6958 | createstdfile(L,stdin,1,"stdin" ); |
6959 | createstdfile(L,stdout,2,"stdout" ); |
6960 | createstdfile(L,stderr,0,"stderr" ); |
6961 | lua_pop(L,1); |
6962 | lua_getfield(L,-1,"popen" ); |
6963 | newfenv(L,io_pclose); |
6964 | lua_setfenv(L,-2); |
6965 | lua_pop(L,1); |
6966 | return 1; |
6967 | } |
6968 | static int os_pushresult(lua_State*L,int i,const char*filename){ |
6969 | int en=errno; |
6970 | if(i){ |
6971 | lua_pushboolean(L,1); |
6972 | return 1; |
6973 | } |
6974 | else{ |
6975 | lua_pushnil(L); |
6976 | lua_pushfstring(L,"%s: %s" ,filename,strerror(en)); |
6977 | lua_pushinteger(L,en); |
6978 | return 3; |
6979 | } |
6980 | } |
6981 | static int os_remove(lua_State*L){ |
6982 | const char*filename=luaL_checkstring(L,1); |
6983 | return os_pushresult(L,remove(filename)==0,filename); |
6984 | } |
6985 | static int os_exit(lua_State*L){ |
6986 | exit(luaL_optint(L,1,EXIT_SUCCESS)); |
6987 | } |
6988 | static const luaL_Reg syslib[]={ |
6989 | {"exit" ,os_exit}, |
6990 | {"remove" ,os_remove}, |
6991 | {NULL,NULL} |
6992 | }; |
6993 | static int luaopen_os(lua_State*L){ |
6994 | luaL_register(L,"os" ,syslib); |
6995 | return 1; |
6996 | } |
6997 | #define uchar(c)((unsigned char)(c)) |
6998 | static ptrdiff_t posrelat(ptrdiff_t pos,size_t len){ |
6999 | if(pos<0)pos+=(ptrdiff_t)len+1; |
7000 | return(pos>=0)?pos:0; |
7001 | } |
7002 | static int str_sub(lua_State*L){ |
7003 | size_t l; |
7004 | const char*s=luaL_checklstring(L,1,&l); |
7005 | ptrdiff_t start=posrelat(luaL_checkinteger(L,2),l); |
7006 | ptrdiff_t end=posrelat(luaL_optinteger(L,3,-1),l); |
7007 | if(start<1)start=1; |
7008 | if(end>(ptrdiff_t)l)end=(ptrdiff_t)l; |
7009 | if(start<=end) |
7010 | lua_pushlstring(L,s+start-1,end-start+1); |
7011 | else lua_pushliteral(L,"" ); |
7012 | return 1; |
7013 | } |
7014 | static int str_lower(lua_State*L){ |
7015 | size_t l; |
7016 | size_t i; |
7017 | luaL_Buffer b; |
7018 | const char*s=luaL_checklstring(L,1,&l); |
7019 | luaL_buffinit(L,&b); |
7020 | for(i=0;i<l;i++) |
7021 | luaL_addchar(&b,tolower(uchar(s[i]))); |
7022 | luaL_pushresult(&b); |
7023 | return 1; |
7024 | } |
7025 | static int str_upper(lua_State*L){ |
7026 | size_t l; |
7027 | size_t i; |
7028 | luaL_Buffer b; |
7029 | const char*s=luaL_checklstring(L,1,&l); |
7030 | luaL_buffinit(L,&b); |
7031 | for(i=0;i<l;i++) |
7032 | luaL_addchar(&b,toupper(uchar(s[i]))); |
7033 | luaL_pushresult(&b); |
7034 | return 1; |
7035 | } |
7036 | static int str_rep(lua_State*L){ |
7037 | size_t l; |
7038 | luaL_Buffer b; |
7039 | const char*s=luaL_checklstring(L,1,&l); |
7040 | int n=luaL_checkint(L,2); |
7041 | luaL_buffinit(L,&b); |
7042 | while(n-->0) |
7043 | luaL_addlstring(&b,s,l); |
7044 | luaL_pushresult(&b); |
7045 | return 1; |
7046 | } |
7047 | static int str_byte(lua_State*L){ |
7048 | size_t l; |
7049 | const char*s=luaL_checklstring(L,1,&l); |
7050 | ptrdiff_t posi=posrelat(luaL_optinteger(L,2,1),l); |
7051 | ptrdiff_t pose=posrelat(luaL_optinteger(L,3,posi),l); |
7052 | int n,i; |
7053 | if(posi<=0)posi=1; |
7054 | if((size_t)pose>l)pose=l; |
7055 | if(posi>pose)return 0; |
7056 | n=(int)(pose-posi+1); |
7057 | if(posi+n<=pose) |
7058 | luaL_error(L,"string slice too long" ); |
7059 | luaL_checkstack(L,n,"string slice too long" ); |
7060 | for(i=0;i<n;i++) |
7061 | lua_pushinteger(L,uchar(s[posi+i-1])); |
7062 | return n; |
7063 | } |
7064 | static int str_char(lua_State*L){ |
7065 | int n=lua_gettop(L); |
7066 | int i; |
7067 | luaL_Buffer b; |
7068 | luaL_buffinit(L,&b); |
7069 | for(i=1;i<=n;i++){ |
7070 | int c=luaL_checkint(L,i); |
7071 | luaL_argcheck(L,uchar(c)==c,i,"invalid value" ); |
7072 | luaL_addchar(&b,uchar(c)); |
7073 | } |
7074 | luaL_pushresult(&b); |
7075 | return 1; |
7076 | } |
7077 | typedef struct MatchState{ |
7078 | const char*src_init; |
7079 | const char*src_end; |
7080 | lua_State*L; |
7081 | int level; |
7082 | struct{ |
7083 | const char*init; |
7084 | ptrdiff_t len; |
7085 | }capture[32]; |
7086 | }MatchState; |
7087 | static int check_capture(MatchState*ms,int l){ |
7088 | l-='1'; |
7089 | if(l<0||l>=ms->level||ms->capture[l].len==(-1)) |
7090 | return luaL_error(ms->L,"invalid capture index" ); |
7091 | return l; |
7092 | } |
7093 | static int capture_to_close(MatchState*ms){ |
7094 | int level=ms->level; |
7095 | for(level--;level>=0;level--) |
7096 | if(ms->capture[level].len==(-1))return level; |
7097 | return luaL_error(ms->L,"invalid pattern capture" ); |
7098 | } |
7099 | static const char*classend(MatchState*ms,const char*p){ |
7100 | switch(*p++){ |
7101 | case'%':{ |
7102 | if(*p=='\0') |
7103 | luaL_error(ms->L,"malformed pattern (ends with " LUA_QL("%%" )")" ); |
7104 | return p+1; |
7105 | } |
7106 | case'[':{ |
7107 | if(*p=='^')p++; |
7108 | do{ |
7109 | if(*p=='\0') |
7110 | luaL_error(ms->L,"malformed pattern (missing " LUA_QL("]" )")" ); |
7111 | if(*(p++)=='%'&&*p!='\0') |
7112 | p++; |
7113 | }while(*p!=']'); |
7114 | return p+1; |
7115 | } |
7116 | default:{ |
7117 | return p; |
7118 | } |
7119 | } |
7120 | } |
7121 | static int match_class(int c,int cl){ |
7122 | int res; |
7123 | switch(tolower(cl)){ |
7124 | case'a':res=isalpha(c);break; |
7125 | case'c':res=iscntrl(c);break; |
7126 | case'd':res=isdigit(c);break; |
7127 | case'l':res=islower(c);break; |
7128 | case'p':res=ispunct(c);break; |
7129 | case's':res=isspace(c);break; |
7130 | case'u':res=isupper(c);break; |
7131 | case'w':res=isalnum(c);break; |
7132 | case'x':res=isxdigit(c);break; |
7133 | case'z':res=(c==0);break; |
7134 | default:return(cl==c); |
7135 | } |
7136 | return(islower(cl)?res:!res); |
7137 | } |
7138 | static int matchbracketclass(int c,const char*p,const char*ec){ |
7139 | int sig=1; |
7140 | if(*(p+1)=='^'){ |
7141 | sig=0; |
7142 | p++; |
7143 | } |
7144 | while(++p<ec){ |
7145 | if(*p=='%'){ |
7146 | p++; |
7147 | if(match_class(c,uchar(*p))) |
7148 | return sig; |
7149 | } |
7150 | else if((*(p+1)=='-')&&(p+2<ec)){ |
7151 | p+=2; |
7152 | if(uchar(*(p-2))<=c&&c<=uchar(*p)) |
7153 | return sig; |
7154 | } |
7155 | else if(uchar(*p)==c)return sig; |
7156 | } |
7157 | return!sig; |
7158 | } |
7159 | static int singlematch(int c,const char*p,const char*ep){ |
7160 | switch(*p){ |
7161 | case'.':return 1; |
7162 | case'%':return match_class(c,uchar(*(p+1))); |
7163 | case'[':return matchbracketclass(c,p,ep-1); |
7164 | default:return(uchar(*p)==c); |
7165 | } |
7166 | } |
7167 | static const char*match(MatchState*ms,const char*s,const char*p); |
7168 | static const char*matchbalance(MatchState*ms,const char*s, |
7169 | const char*p){ |
7170 | if(*p==0||*(p+1)==0) |
7171 | luaL_error(ms->L,"unbalanced pattern" ); |
7172 | if(*s!=*p)return NULL; |
7173 | else{ |
7174 | int b=*p; |
7175 | int e=*(p+1); |
7176 | int cont=1; |
7177 | while(++s<ms->src_end){ |
7178 | if(*s==e){ |
7179 | if(--cont==0)return s+1; |
7180 | } |
7181 | else if(*s==b)cont++; |
7182 | } |
7183 | } |
7184 | return NULL; |
7185 | } |
7186 | static const char*max_expand(MatchState*ms,const char*s, |
7187 | const char*p,const char*ep){ |
7188 | ptrdiff_t i=0; |
7189 | while((s+i)<ms->src_end&&singlematch(uchar(*(s+i)),p,ep)) |
7190 | i++; |
7191 | while(i>=0){ |
7192 | const char*res=match(ms,(s+i),ep+1); |
7193 | if(res)return res; |
7194 | i--; |
7195 | } |
7196 | return NULL; |
7197 | } |
7198 | static const char*min_expand(MatchState*ms,const char*s, |
7199 | const char*p,const char*ep){ |
7200 | for(;;){ |
7201 | const char*res=match(ms,s,ep+1); |
7202 | if(res!=NULL) |
7203 | return res; |
7204 | else if(s<ms->src_end&&singlematch(uchar(*s),p,ep)) |
7205 | s++; |
7206 | else return NULL; |
7207 | } |
7208 | } |
7209 | static const char*start_capture(MatchState*ms,const char*s, |
7210 | const char*p,int what){ |
7211 | const char*res; |
7212 | int level=ms->level; |
7213 | if(level>=32)luaL_error(ms->L,"too many captures" ); |
7214 | ms->capture[level].init=s; |
7215 | ms->capture[level].len=what; |
7216 | ms->level=level+1; |
7217 | if((res=match(ms,s,p))==NULL) |
7218 | ms->level--; |
7219 | return res; |
7220 | } |
7221 | static const char*end_capture(MatchState*ms,const char*s, |
7222 | const char*p){ |
7223 | int l=capture_to_close(ms); |
7224 | const char*res; |
7225 | ms->capture[l].len=s-ms->capture[l].init; |
7226 | if((res=match(ms,s,p))==NULL) |
7227 | ms->capture[l].len=(-1); |
7228 | return res; |
7229 | } |
7230 | static const char*match_capture(MatchState*ms,const char*s,int l){ |
7231 | size_t len; |
7232 | l=check_capture(ms,l); |
7233 | len=ms->capture[l].len; |
7234 | if((size_t)(ms->src_end-s)>=len&& |
7235 | memcmp(ms->capture[l].init,s,len)==0) |
7236 | return s+len; |
7237 | else return NULL; |
7238 | } |
7239 | static const char*match(MatchState*ms,const char*s,const char*p){ |
7240 | init: |
7241 | switch(*p){ |
7242 | case'(':{ |
7243 | if(*(p+1)==')') |
7244 | return start_capture(ms,s,p+2,(-2)); |
7245 | else |
7246 | return start_capture(ms,s,p+1,(-1)); |
7247 | } |
7248 | case')':{ |
7249 | return end_capture(ms,s,p+1); |
7250 | } |
7251 | case'%':{ |
7252 | switch(*(p+1)){ |
7253 | case'b':{ |
7254 | s=matchbalance(ms,s,p+2); |
7255 | if(s==NULL)return NULL; |
7256 | p+=4;goto init; |
7257 | } |
7258 | case'f':{ |
7259 | const char*ep;char previous; |
7260 | p+=2; |
7261 | if(*p!='[') |
7262 | luaL_error(ms->L,"missing " LUA_QL("[" )" after " |
7263 | LUA_QL("%%f" )" in pattern" ); |
7264 | ep=classend(ms,p); |
7265 | previous=(s==ms->src_init)?'\0':*(s-1); |
7266 | if(matchbracketclass(uchar(previous),p,ep-1)|| |
7267 | !matchbracketclass(uchar(*s),p,ep-1))return NULL; |
7268 | p=ep;goto init; |
7269 | } |
7270 | default:{ |
7271 | if(isdigit(uchar(*(p+1)))){ |
7272 | s=match_capture(ms,s,uchar(*(p+1))); |
7273 | if(s==NULL)return NULL; |
7274 | p+=2;goto init; |
7275 | } |
7276 | goto dflt; |
7277 | } |
7278 | } |
7279 | } |
7280 | case'\0':{ |
7281 | return s; |
7282 | } |
7283 | case'$':{ |
7284 | if(*(p+1)=='\0') |
7285 | return(s==ms->src_end)?s:NULL; |
7286 | else goto dflt; |
7287 | } |
7288 | default:dflt:{ |
7289 | const char*ep=classend(ms,p); |
7290 | int m=s<ms->src_end&&singlematch(uchar(*s),p,ep); |
7291 | switch(*ep){ |
7292 | case'?':{ |
7293 | const char*res; |
7294 | if(m&&((res=match(ms,s+1,ep+1))!=NULL)) |
7295 | return res; |
7296 | p=ep+1;goto init; |
7297 | } |
7298 | case'*':{ |
7299 | return max_expand(ms,s,p,ep); |
7300 | } |
7301 | case'+':{ |
7302 | return(m?max_expand(ms,s+1,p,ep):NULL); |
7303 | } |
7304 | case'-':{ |
7305 | return min_expand(ms,s,p,ep); |
7306 | } |
7307 | default:{ |
7308 | if(!m)return NULL; |
7309 | s++;p=ep;goto init; |
7310 | } |
7311 | } |
7312 | } |
7313 | } |
7314 | } |
7315 | static const char*lmemfind(const char*s1,size_t l1, |
7316 | const char*s2,size_t l2){ |
7317 | if(l2==0)return s1; |
7318 | else if(l2>l1)return NULL; |
7319 | else{ |
7320 | const char*init; |
7321 | l2--; |
7322 | l1=l1-l2; |
7323 | while(l1>0&&(init=(const char*)memchr(s1,*s2,l1))!=NULL){ |
7324 | init++; |
7325 | if(memcmp(init,s2+1,l2)==0) |
7326 | return init-1; |
7327 | else{ |
7328 | l1-=init-s1; |
7329 | s1=init; |
7330 | } |
7331 | } |
7332 | return NULL; |
7333 | } |
7334 | } |
7335 | static void push_onecapture(MatchState*ms,int i,const char*s, |
7336 | const char*e){ |
7337 | if(i>=ms->level){ |
7338 | if(i==0) |
7339 | lua_pushlstring(ms->L,s,e-s); |
7340 | else |
7341 | luaL_error(ms->L,"invalid capture index" ); |
7342 | } |
7343 | else{ |
7344 | ptrdiff_t l=ms->capture[i].len; |
7345 | if(l==(-1))luaL_error(ms->L,"unfinished capture" ); |
7346 | if(l==(-2)) |
7347 | lua_pushinteger(ms->L,ms->capture[i].init-ms->src_init+1); |
7348 | else |
7349 | lua_pushlstring(ms->L,ms->capture[i].init,l); |
7350 | } |
7351 | } |
7352 | static int push_captures(MatchState*ms,const char*s,const char*e){ |
7353 | int i; |
7354 | int nlevels=(ms->level==0&&s)?1:ms->level; |
7355 | luaL_checkstack(ms->L,nlevels,"too many captures" ); |
7356 | for(i=0;i<nlevels;i++) |
7357 | push_onecapture(ms,i,s,e); |
7358 | return nlevels; |
7359 | } |
7360 | static int str_find_aux(lua_State*L,int find){ |
7361 | size_t l1,l2; |
7362 | const char*s=luaL_checklstring(L,1,&l1); |
7363 | const char*p=luaL_checklstring(L,2,&l2); |
7364 | ptrdiff_t init=posrelat(luaL_optinteger(L,3,1),l1)-1; |
7365 | if(init<0)init=0; |
7366 | else if((size_t)(init)>l1)init=(ptrdiff_t)l1; |
7367 | if(find&&(lua_toboolean(L,4)|| |
7368 | strpbrk(p,"^$*+?.([%-" )==NULL)){ |
7369 | const char*s2=lmemfind(s+init,l1-init,p,l2); |
7370 | if(s2){ |
7371 | lua_pushinteger(L,s2-s+1); |
7372 | lua_pushinteger(L,s2-s+l2); |
7373 | return 2; |
7374 | } |
7375 | } |
7376 | else{ |
7377 | MatchState ms; |
7378 | int anchor=(*p=='^')?(p++,1):0; |
7379 | const char*s1=s+init; |
7380 | ms.L=L; |
7381 | ms.src_init=s; |
7382 | ms.src_end=s+l1; |
7383 | do{ |
7384 | const char*res; |
7385 | ms.level=0; |
7386 | if((res=match(&ms,s1,p))!=NULL){ |
7387 | if(find){ |
7388 | lua_pushinteger(L,s1-s+1); |
7389 | lua_pushinteger(L,res-s); |
7390 | return push_captures(&ms,NULL,0)+2; |
7391 | } |
7392 | else |
7393 | return push_captures(&ms,s1,res); |
7394 | } |
7395 | }while(s1++<ms.src_end&&!anchor); |
7396 | } |
7397 | lua_pushnil(L); |
7398 | return 1; |
7399 | } |
7400 | static int str_find(lua_State*L){ |
7401 | return str_find_aux(L,1); |
7402 | } |
7403 | static int str_match(lua_State*L){ |
7404 | return str_find_aux(L,0); |
7405 | } |
7406 | static int gmatch_aux(lua_State*L){ |
7407 | MatchState ms; |
7408 | size_t ls; |
7409 | const char*s=lua_tolstring(L,lua_upvalueindex(1),&ls); |
7410 | const char*p=lua_tostring(L,lua_upvalueindex(2)); |
7411 | const char*src; |
7412 | ms.L=L; |
7413 | ms.src_init=s; |
7414 | ms.src_end=s+ls; |
7415 | for(src=s+(size_t)lua_tointeger(L,lua_upvalueindex(3)); |
7416 | src<=ms.src_end; |
7417 | src++){ |
7418 | const char*e; |
7419 | ms.level=0; |
7420 | if((e=match(&ms,src,p))!=NULL){ |
7421 | lua_Integer newstart=e-s; |
7422 | if(e==src)newstart++; |
7423 | lua_pushinteger(L,newstart); |
7424 | lua_replace(L,lua_upvalueindex(3)); |
7425 | return push_captures(&ms,src,e); |
7426 | } |
7427 | } |
7428 | return 0; |
7429 | } |
7430 | static int gmatch(lua_State*L){ |
7431 | luaL_checkstring(L,1); |
7432 | luaL_checkstring(L,2); |
7433 | lua_settop(L,2); |
7434 | lua_pushinteger(L,0); |
7435 | lua_pushcclosure(L,gmatch_aux,3); |
7436 | return 1; |
7437 | } |
7438 | static void add_s(MatchState*ms,luaL_Buffer*b,const char*s, |
7439 | const char*e){ |
7440 | size_t l,i; |
7441 | const char*news=lua_tolstring(ms->L,3,&l); |
7442 | for(i=0;i<l;i++){ |
7443 | if(news[i]!='%') |
7444 | luaL_addchar(b,news[i]); |
7445 | else{ |
7446 | i++; |
7447 | if(!isdigit(uchar(news[i]))) |
7448 | luaL_addchar(b,news[i]); |
7449 | else if(news[i]=='0') |
7450 | luaL_addlstring(b,s,e-s); |
7451 | else{ |
7452 | push_onecapture(ms,news[i]-'1',s,e); |
7453 | luaL_addvalue(b); |
7454 | } |
7455 | } |
7456 | } |
7457 | } |
7458 | static void add_value(MatchState*ms,luaL_Buffer*b,const char*s, |
7459 | const char*e){ |
7460 | lua_State*L=ms->L; |
7461 | switch(lua_type(L,3)){ |
7462 | case 3: |
7463 | case 4:{ |
7464 | add_s(ms,b,s,e); |
7465 | return; |
7466 | } |
7467 | case 6:{ |
7468 | int n; |
7469 | lua_pushvalue(L,3); |
7470 | n=push_captures(ms,s,e); |
7471 | lua_call(L,n,1); |
7472 | break; |
7473 | } |
7474 | case 5:{ |
7475 | push_onecapture(ms,0,s,e); |
7476 | lua_gettable(L,3); |
7477 | break; |
7478 | } |
7479 | } |
7480 | if(!lua_toboolean(L,-1)){ |
7481 | lua_pop(L,1); |
7482 | lua_pushlstring(L,s,e-s); |
7483 | } |
7484 | else if(!lua_isstring(L,-1)) |
7485 | luaL_error(L,"invalid replacement value (a %s)" ,luaL_typename(L,-1)); |
7486 | luaL_addvalue(b); |
7487 | } |
7488 | static int str_gsub(lua_State*L){ |
7489 | size_t srcl; |
7490 | const char*src=luaL_checklstring(L,1,&srcl); |
7491 | const char*p=luaL_checkstring(L,2); |
7492 | int tr=lua_type(L,3); |
7493 | int max_s=luaL_optint(L,4,srcl+1); |
7494 | int anchor=(*p=='^')?(p++,1):0; |
7495 | int n=0; |
7496 | MatchState ms; |
7497 | luaL_Buffer b; |
7498 | luaL_argcheck(L,tr==3||tr==4|| |
7499 | tr==6||tr==5,3, |
7500 | "string/function/table expected" ); |
7501 | luaL_buffinit(L,&b); |
7502 | ms.L=L; |
7503 | ms.src_init=src; |
7504 | ms.src_end=src+srcl; |
7505 | while(n<max_s){ |
7506 | const char*e; |
7507 | ms.level=0; |
7508 | e=match(&ms,src,p); |
7509 | if(e){ |
7510 | n++; |
7511 | add_value(&ms,&b,src,e); |
7512 | } |
7513 | if(e&&e>src) |
7514 | src=e; |
7515 | else if(src<ms.src_end) |
7516 | luaL_addchar(&b,*src++); |
7517 | else break; |
7518 | if(anchor)break; |
7519 | } |
7520 | luaL_addlstring(&b,src,ms.src_end-src); |
7521 | luaL_pushresult(&b); |
7522 | lua_pushinteger(L,n); |
7523 | return 2; |
7524 | } |
7525 | static void addquoted(lua_State*L,luaL_Buffer*b,int arg){ |
7526 | size_t l; |
7527 | const char*s=luaL_checklstring(L,arg,&l); |
7528 | luaL_addchar(b,'"'); |
7529 | while(l--){ |
7530 | switch(*s){ |
7531 | case'"':case'\\':case'\n':{ |
7532 | luaL_addchar(b,'\\'); |
7533 | luaL_addchar(b,*s); |
7534 | break; |
7535 | } |
7536 | case'\r':{ |
7537 | luaL_addlstring(b,"\\r" ,2); |
7538 | break; |
7539 | } |
7540 | case'\0':{ |
7541 | luaL_addlstring(b,"\\000" ,4); |
7542 | break; |
7543 | } |
7544 | default:{ |
7545 | luaL_addchar(b,*s); |
7546 | break; |
7547 | } |
7548 | } |
7549 | s++; |
7550 | } |
7551 | luaL_addchar(b,'"'); |
7552 | } |
7553 | static const char*scanformat(lua_State*L,const char*strfrmt,char*form){ |
7554 | const char*p=strfrmt; |
7555 | while(*p!='\0'&&strchr("-+ #0" ,*p)!=NULL)p++; |
7556 | if((size_t)(p-strfrmt)>=sizeof("-+ #0" )) |
7557 | luaL_error(L,"invalid format (repeated flags)" ); |
7558 | if(isdigit(uchar(*p)))p++; |
7559 | if(isdigit(uchar(*p)))p++; |
7560 | if(*p=='.'){ |
7561 | p++; |
7562 | if(isdigit(uchar(*p)))p++; |
7563 | if(isdigit(uchar(*p)))p++; |
7564 | } |
7565 | if(isdigit(uchar(*p))) |
7566 | luaL_error(L,"invalid format (width or precision too long)" ); |
7567 | *(form++)='%'; |
7568 | strncpy(form,strfrmt,p-strfrmt+1); |
7569 | form+=p-strfrmt+1; |
7570 | *form='\0'; |
7571 | return p; |
7572 | } |
7573 | static void addintlen(char*form){ |
7574 | size_t l=strlen(form); |
7575 | char spec=form[l-1]; |
7576 | strcpy(form+l-1,"l" ); |
7577 | form[l+sizeof("l" )-2]=spec; |
7578 | form[l+sizeof("l" )-1]='\0'; |
7579 | } |
7580 | static int str_format(lua_State*L){ |
7581 | int top=lua_gettop(L); |
7582 | int arg=1; |
7583 | size_t sfl; |
7584 | const char*strfrmt=luaL_checklstring(L,arg,&sfl); |
7585 | const char*strfrmt_end=strfrmt+sfl; |
7586 | luaL_Buffer b; |
7587 | luaL_buffinit(L,&b); |
7588 | while(strfrmt<strfrmt_end){ |
7589 | if(*strfrmt!='%') |
7590 | luaL_addchar(&b,*strfrmt++); |
7591 | else if(*++strfrmt=='%') |
7592 | luaL_addchar(&b,*strfrmt++); |
7593 | else{ |
7594 | char form[(sizeof("-+ #0" )+sizeof("l" )+10)]; |
7595 | char buff[512]; |
7596 | if(++arg>top) |
7597 | luaL_argerror(L,arg,"no value" ); |
7598 | strfrmt=scanformat(L,strfrmt,form); |
7599 | switch(*strfrmt++){ |
7600 | case'c':{ |
7601 | sprintf(buff,form,(int)luaL_checknumber(L,arg)); |
7602 | break; |
7603 | } |
7604 | case'd':case'i':{ |
7605 | addintlen(form); |
7606 | sprintf(buff,form,(long)luaL_checknumber(L,arg)); |
7607 | break; |
7608 | } |
7609 | case'o':case'u':case'x':case'X':{ |
7610 | addintlen(form); |
7611 | sprintf(buff,form,(unsigned long)luaL_checknumber(L,arg)); |
7612 | break; |
7613 | } |
7614 | case'e':case'E':case'f': |
7615 | case'g':case'G':{ |
7616 | sprintf(buff,form,(double)luaL_checknumber(L,arg)); |
7617 | break; |
7618 | } |
7619 | case'q':{ |
7620 | addquoted(L,&b,arg); |
7621 | continue; |
7622 | } |
7623 | case's':{ |
7624 | size_t l; |
7625 | const char*s=luaL_checklstring(L,arg,&l); |
7626 | if(!strchr(form,'.')&&l>=100){ |
7627 | lua_pushvalue(L,arg); |
7628 | luaL_addvalue(&b); |
7629 | continue; |
7630 | } |
7631 | else{ |
7632 | sprintf(buff,form,s); |
7633 | break; |
7634 | } |
7635 | } |
7636 | default:{ |
7637 | return luaL_error(L,"invalid option " LUA_QL("%%%c" )" to " |
7638 | LUA_QL("format" ),*(strfrmt-1)); |
7639 | } |
7640 | } |
7641 | luaL_addlstring(&b,buff,strlen(buff)); |
7642 | } |
7643 | } |
7644 | luaL_pushresult(&b); |
7645 | return 1; |
7646 | } |
7647 | static const luaL_Reg strlib[]={ |
7648 | {"byte" ,str_byte}, |
7649 | {"char" ,str_char}, |
7650 | {"find" ,str_find}, |
7651 | {"format" ,str_format}, |
7652 | {"gmatch" ,gmatch}, |
7653 | {"gsub" ,str_gsub}, |
7654 | {"lower" ,str_lower}, |
7655 | {"match" ,str_match}, |
7656 | {"rep" ,str_rep}, |
7657 | {"sub" ,str_sub}, |
7658 | {"upper" ,str_upper}, |
7659 | {NULL,NULL} |
7660 | }; |
7661 | static void createmetatable(lua_State*L){ |
7662 | lua_createtable(L,0,1); |
7663 | lua_pushliteral(L,"" ); |
7664 | lua_pushvalue(L,-2); |
7665 | lua_setmetatable(L,-2); |
7666 | lua_pop(L,1); |
7667 | lua_pushvalue(L,-2); |
7668 | lua_setfield(L,-2,"__index" ); |
7669 | lua_pop(L,1); |
7670 | } |
7671 | static int luaopen_string(lua_State*L){ |
7672 | luaL_register(L,"string" ,strlib); |
7673 | createmetatable(L); |
7674 | return 1; |
7675 | } |
7676 | static const luaL_Reg lualibs[]={ |
7677 | {"" ,luaopen_base}, |
7678 | {"table" ,luaopen_table}, |
7679 | {"io" ,luaopen_io}, |
7680 | {"os" ,luaopen_os}, |
7681 | {"string" ,luaopen_string}, |
7682 | {NULL,NULL} |
7683 | }; |
7684 | static void luaL_openlibs(lua_State*L){ |
7685 | const luaL_Reg*lib=lualibs; |
7686 | for(;lib->func;lib++){ |
7687 | lua_pushcfunction(L,lib->func); |
7688 | lua_pushstring(L,lib->name); |
7689 | lua_call(L,1,0); |
7690 | } |
7691 | } |
7692 | typedef unsigned int UB; |
7693 | static UB barg(lua_State*L,int idx){ |
7694 | union{lua_Number n;U64 b;}bn; |
7695 | bn.n=lua_tonumber(L,idx)+6755399441055744.0; |
7696 | if(bn.n==0.0&&!lua_isnumber(L,idx))luaL_typerror(L,idx,"number" ); |
7697 | return(UB)bn.b; |
7698 | } |
7699 | #define BRET(b)lua_pushnumber(L,(lua_Number)(int)(b));return 1; |
7700 | static int tobit(lua_State*L){ |
7701 | BRET(barg(L,1))} |
7702 | static int bnot(lua_State*L){ |
7703 | BRET(~barg(L,1))} |
7704 | static int band(lua_State*L){ |
7705 | int i;UB b=barg(L,1);for(i=lua_gettop(L);i>1;i--)b&=barg(L,i);BRET(b)} |
7706 | static int bor(lua_State*L){ |
7707 | int i;UB b=barg(L,1);for(i=lua_gettop(L);i>1;i--)b|=barg(L,i);BRET(b)} |
7708 | static int bxor(lua_State*L){ |
7709 | int i;UB b=barg(L,1);for(i=lua_gettop(L);i>1;i--)b^=barg(L,i);BRET(b)} |
7710 | static int lshift(lua_State*L){ |
7711 | UB b=barg(L,1),n=barg(L,2)&31;BRET(b<<n)} |
7712 | static int rshift(lua_State*L){ |
7713 | UB b=barg(L,1),n=barg(L,2)&31;BRET(b>>n)} |
7714 | static int arshift(lua_State*L){ |
7715 | UB b=barg(L,1),n=barg(L,2)&31;BRET((int)b>>n)} |
7716 | static int rol(lua_State*L){ |
7717 | UB b=barg(L,1),n=barg(L,2)&31;BRET((b<<n)|(b>>(32-n)))} |
7718 | static int ror(lua_State*L){ |
7719 | UB b=barg(L,1),n=barg(L,2)&31;BRET((b>>n)|(b<<(32-n)))} |
7720 | static int bswap(lua_State*L){ |
7721 | UB b=barg(L,1);b=(b>>24)|((b>>8)&0xff00)|((b&0xff00)<<8)|(b<<24);BRET(b)} |
7722 | static int tohex(lua_State*L){ |
7723 | UB b=barg(L,1); |
7724 | int n=lua_isnone(L,2)?8:(int)barg(L,2); |
7725 | const char*hexdigits="0123456789abcdef" ; |
7726 | char buf[8]; |
7727 | int i; |
7728 | if(n<0){n=-n;hexdigits="0123456789ABCDEF" ;} |
7729 | if(n>8)n=8; |
7730 | for(i=(int)n;--i>=0;){buf[i]=hexdigits[b&15];b>>=4;} |
7731 | lua_pushlstring(L,buf,(size_t)n); |
7732 | return 1; |
7733 | } |
7734 | static const struct luaL_Reg bitlib[]={ |
7735 | {"tobit" ,tobit}, |
7736 | {"bnot" ,bnot}, |
7737 | {"band" ,band}, |
7738 | {"bor" ,bor}, |
7739 | {"bxor" ,bxor}, |
7740 | {"lshift" ,lshift}, |
7741 | {"rshift" ,rshift}, |
7742 | {"arshift" ,arshift}, |
7743 | {"rol" ,rol}, |
7744 | {"ror" ,ror}, |
7745 | {"bswap" ,bswap}, |
7746 | {"tohex" ,tohex}, |
7747 | {NULL,NULL} |
7748 | }; |
7749 | int main(int argc,char**argv){ |
7750 | lua_State*L=luaL_newstate(); |
7751 | int i; |
7752 | luaL_openlibs(L); |
7753 | luaL_register(L,"bit" ,bitlib); |
7754 | if(argc<2)return sizeof(void*); |
7755 | lua_createtable(L,0,1); |
7756 | lua_pushstring(L,argv[1]); |
7757 | lua_rawseti(L,-2,0); |
7758 | lua_setglobal(L,"arg" ); |
7759 | if(luaL_loadfile(L,argv[1])) |
7760 | goto err; |
7761 | for(i=2;i<argc;i++) |
7762 | lua_pushstring(L,argv[i]); |
7763 | if(lua_pcall(L,argc-2,0,0)){ |
7764 | err: |
7765 | fprintf(stderr,"Error: %s\n" ,lua_tostring(L,-1)); |
7766 | return 1; |
7767 | } |
7768 | lua_close(L); |
7769 | return 0; |
7770 | } |
7771 | |