immunio 0.15.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +234 -0
  3. data/README.md +147 -0
  4. data/bin/immunio +5 -0
  5. data/lib/immunio.rb +29 -0
  6. data/lib/immunio/agent.rb +260 -0
  7. data/lib/immunio/authentication.rb +96 -0
  8. data/lib/immunio/blocked_app.rb +38 -0
  9. data/lib/immunio/channel.rb +432 -0
  10. data/lib/immunio/cli.rb +39 -0
  11. data/lib/immunio/context.rb +114 -0
  12. data/lib/immunio/errors.rb +43 -0
  13. data/lib/immunio/immunio_ca.crt +45 -0
  14. data/lib/immunio/logger.rb +87 -0
  15. data/lib/immunio/plugins/action_dispatch.rb +45 -0
  16. data/lib/immunio/plugins/action_view.rb +431 -0
  17. data/lib/immunio/plugins/active_record.rb +707 -0
  18. data/lib/immunio/plugins/active_record_relation.rb +370 -0
  19. data/lib/immunio/plugins/authlogic.rb +80 -0
  20. data/lib/immunio/plugins/csrf.rb +24 -0
  21. data/lib/immunio/plugins/devise.rb +40 -0
  22. data/lib/immunio/plugins/environment_reporter.rb +69 -0
  23. data/lib/immunio/plugins/eval.rb +51 -0
  24. data/lib/immunio/plugins/exception_handler.rb +55 -0
  25. data/lib/immunio/plugins/gems_tracker.rb +5 -0
  26. data/lib/immunio/plugins/haml.rb +36 -0
  27. data/lib/immunio/plugins/http_finisher.rb +50 -0
  28. data/lib/immunio/plugins/http_tracker.rb +203 -0
  29. data/lib/immunio/plugins/io.rb +96 -0
  30. data/lib/immunio/plugins/redirect.rb +42 -0
  31. data/lib/immunio/plugins/warden.rb +66 -0
  32. data/lib/immunio/processor.rb +234 -0
  33. data/lib/immunio/rails.rb +26 -0
  34. data/lib/immunio/request.rb +139 -0
  35. data/lib/immunio/rufus_lua_ext/ref.rb +27 -0
  36. data/lib/immunio/rufus_lua_ext/state.rb +157 -0
  37. data/lib/immunio/rufus_lua_ext/table.rb +137 -0
  38. data/lib/immunio/rufus_lua_ext/utils.rb +13 -0
  39. data/lib/immunio/version.rb +5 -0
  40. data/lib/immunio/vm.rb +291 -0
  41. data/lua-hooks/ext/all.c +78 -0
  42. data/lua-hooks/ext/bitop/README +22 -0
  43. data/lua-hooks/ext/bitop/bit.c +189 -0
  44. data/lua-hooks/ext/extconf.rb +38 -0
  45. data/lua-hooks/ext/libinjection/COPYING +37 -0
  46. data/lua-hooks/ext/libinjection/libinjection.h +65 -0
  47. data/lua-hooks/ext/libinjection/libinjection_html5.c +847 -0
  48. data/lua-hooks/ext/libinjection/libinjection_html5.h +54 -0
  49. data/lua-hooks/ext/libinjection/libinjection_sqli.c +2301 -0
  50. data/lua-hooks/ext/libinjection/libinjection_sqli.h +295 -0
  51. data/lua-hooks/ext/libinjection/libinjection_sqli_data.h +9349 -0
  52. data/lua-hooks/ext/libinjection/libinjection_xss.c +531 -0
  53. data/lua-hooks/ext/libinjection/libinjection_xss.h +21 -0
  54. data/lua-hooks/ext/libinjection/lualib.c +109 -0
  55. data/lua-hooks/ext/lpeg/HISTORY +90 -0
  56. data/lua-hooks/ext/lpeg/lpcap.c +537 -0
  57. data/lua-hooks/ext/lpeg/lpcap.h +43 -0
  58. data/lua-hooks/ext/lpeg/lpcode.c +986 -0
  59. data/lua-hooks/ext/lpeg/lpcode.h +34 -0
  60. data/lua-hooks/ext/lpeg/lpeg-128.gif +0 -0
  61. data/lua-hooks/ext/lpeg/lpeg.html +1429 -0
  62. data/lua-hooks/ext/lpeg/lpprint.c +244 -0
  63. data/lua-hooks/ext/lpeg/lpprint.h +35 -0
  64. data/lua-hooks/ext/lpeg/lptree.c +1238 -0
  65. data/lua-hooks/ext/lpeg/lptree.h +77 -0
  66. data/lua-hooks/ext/lpeg/lptypes.h +149 -0
  67. data/lua-hooks/ext/lpeg/lpvm.c +355 -0
  68. data/lua-hooks/ext/lpeg/lpvm.h +58 -0
  69. data/lua-hooks/ext/lpeg/makefile +55 -0
  70. data/lua-hooks/ext/lpeg/re.html +498 -0
  71. data/lua-hooks/ext/lpeg/test.lua +1409 -0
  72. data/lua-hooks/ext/lua-cmsgpack/CMakeLists.txt +45 -0
  73. data/lua-hooks/ext/lua-cmsgpack/README.md +115 -0
  74. data/lua-hooks/ext/lua-cmsgpack/lua_cmsgpack.c +957 -0
  75. data/lua-hooks/ext/lua-cmsgpack/test.lua +570 -0
  76. data/lua-hooks/ext/lua-snapshot/LICENSE +7 -0
  77. data/lua-hooks/ext/lua-snapshot/Makefile +12 -0
  78. data/lua-hooks/ext/lua-snapshot/README.md +18 -0
  79. data/lua-hooks/ext/lua-snapshot/dump.lua +15 -0
  80. data/lua-hooks/ext/lua-snapshot/snapshot.c +455 -0
  81. data/lua-hooks/ext/lua/COPYRIGHT +34 -0
  82. data/lua-hooks/ext/lua/lapi.c +1087 -0
  83. data/lua-hooks/ext/lua/lapi.h +16 -0
  84. data/lua-hooks/ext/lua/lauxlib.c +652 -0
  85. data/lua-hooks/ext/lua/lauxlib.h +174 -0
  86. data/lua-hooks/ext/lua/lbaselib.c +659 -0
  87. data/lua-hooks/ext/lua/lcode.c +831 -0
  88. data/lua-hooks/ext/lua/lcode.h +76 -0
  89. data/lua-hooks/ext/lua/ldblib.c +398 -0
  90. data/lua-hooks/ext/lua/ldebug.c +638 -0
  91. data/lua-hooks/ext/lua/ldebug.h +33 -0
  92. data/lua-hooks/ext/lua/ldo.c +519 -0
  93. data/lua-hooks/ext/lua/ldo.h +57 -0
  94. data/lua-hooks/ext/lua/ldump.c +164 -0
  95. data/lua-hooks/ext/lua/lfunc.c +174 -0
  96. data/lua-hooks/ext/lua/lfunc.h +34 -0
  97. data/lua-hooks/ext/lua/lgc.c +710 -0
  98. data/lua-hooks/ext/lua/lgc.h +110 -0
  99. data/lua-hooks/ext/lua/linit.c +38 -0
  100. data/lua-hooks/ext/lua/liolib.c +556 -0
  101. data/lua-hooks/ext/lua/llex.c +463 -0
  102. data/lua-hooks/ext/lua/llex.h +81 -0
  103. data/lua-hooks/ext/lua/llimits.h +128 -0
  104. data/lua-hooks/ext/lua/lmathlib.c +263 -0
  105. data/lua-hooks/ext/lua/lmem.c +86 -0
  106. data/lua-hooks/ext/lua/lmem.h +49 -0
  107. data/lua-hooks/ext/lua/loadlib.c +705 -0
  108. data/lua-hooks/ext/lua/loadlib_rel.c +760 -0
  109. data/lua-hooks/ext/lua/lobject.c +214 -0
  110. data/lua-hooks/ext/lua/lobject.h +381 -0
  111. data/lua-hooks/ext/lua/lopcodes.c +102 -0
  112. data/lua-hooks/ext/lua/lopcodes.h +268 -0
  113. data/lua-hooks/ext/lua/loslib.c +243 -0
  114. data/lua-hooks/ext/lua/lparser.c +1339 -0
  115. data/lua-hooks/ext/lua/lparser.h +82 -0
  116. data/lua-hooks/ext/lua/lstate.c +214 -0
  117. data/lua-hooks/ext/lua/lstate.h +169 -0
  118. data/lua-hooks/ext/lua/lstring.c +111 -0
  119. data/lua-hooks/ext/lua/lstring.h +31 -0
  120. data/lua-hooks/ext/lua/lstrlib.c +871 -0
  121. data/lua-hooks/ext/lua/ltable.c +588 -0
  122. data/lua-hooks/ext/lua/ltable.h +40 -0
  123. data/lua-hooks/ext/lua/ltablib.c +287 -0
  124. data/lua-hooks/ext/lua/ltm.c +75 -0
  125. data/lua-hooks/ext/lua/ltm.h +54 -0
  126. data/lua-hooks/ext/lua/lua.c +392 -0
  127. data/lua-hooks/ext/lua/lua.def +131 -0
  128. data/lua-hooks/ext/lua/lua.h +388 -0
  129. data/lua-hooks/ext/lua/lua.rc +28 -0
  130. data/lua-hooks/ext/lua/lua_dll.rc +26 -0
  131. data/lua-hooks/ext/lua/luac.c +200 -0
  132. data/lua-hooks/ext/lua/luac.rc +1 -0
  133. data/lua-hooks/ext/lua/luaconf.h +763 -0
  134. data/lua-hooks/ext/lua/luaconf.h.in +724 -0
  135. data/lua-hooks/ext/lua/luaconf.h.orig +763 -0
  136. data/lua-hooks/ext/lua/lualib.h +53 -0
  137. data/lua-hooks/ext/lua/lundump.c +227 -0
  138. data/lua-hooks/ext/lua/lundump.h +36 -0
  139. data/lua-hooks/ext/lua/lvm.c +767 -0
  140. data/lua-hooks/ext/lua/lvm.h +36 -0
  141. data/lua-hooks/ext/lua/lzio.c +82 -0
  142. data/lua-hooks/ext/lua/lzio.h +67 -0
  143. data/lua-hooks/ext/lua/print.c +227 -0
  144. data/lua-hooks/ext/luautf8/README.md +152 -0
  145. data/lua-hooks/ext/luautf8/lutf8lib.c +1274 -0
  146. data/lua-hooks/ext/luautf8/unidata.h +3064 -0
  147. data/lua-hooks/lib/boot.lua +254 -0
  148. data/lua-hooks/lib/encode.lua +4 -0
  149. data/lua-hooks/lib/lexers/LICENSE +21 -0
  150. data/lua-hooks/lib/lexers/bash.lua +134 -0
  151. data/lua-hooks/lib/lexers/bash_dqstr.lua +62 -0
  152. data/lua-hooks/lib/lexers/css.lua +216 -0
  153. data/lua-hooks/lib/lexers/html.lua +106 -0
  154. data/lua-hooks/lib/lexers/javascript.lua +68 -0
  155. data/lua-hooks/lib/lexers/lexer.lua +1575 -0
  156. data/lua-hooks/lib/lexers/markers.lua +33 -0
  157. metadata +308 -0
@@ -0,0 +1,1339 @@
1
+ /*
2
+ ** $Id: lparser.c,v 2.42.1.4 2011/10/21 19:31:42 roberto Exp $
3
+ ** Lua Parser
4
+ ** See Copyright Notice in lua.h
5
+ */
6
+
7
+
8
+ #include <string.h>
9
+
10
+ #define lparser_c
11
+ #define LUA_CORE
12
+
13
+ #include "lua.h"
14
+
15
+ #include "lcode.h"
16
+ #include "ldebug.h"
17
+ #include "ldo.h"
18
+ #include "lfunc.h"
19
+ #include "llex.h"
20
+ #include "lmem.h"
21
+ #include "lobject.h"
22
+ #include "lopcodes.h"
23
+ #include "lparser.h"
24
+ #include "lstate.h"
25
+ #include "lstring.h"
26
+ #include "ltable.h"
27
+
28
+
29
+
30
+ #define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
31
+
32
+ #define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])
33
+
34
+ #define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m)
35
+
36
+
37
+ /*
38
+ ** nodes for block list (list of active blocks)
39
+ */
40
+ typedef struct BlockCnt {
41
+ struct BlockCnt *previous; /* chain */
42
+ int breaklist; /* list of jumps out of this loop */
43
+ lu_byte nactvar; /* # active locals outside the breakable structure */
44
+ lu_byte upval; /* true if some variable in the block is an upvalue */
45
+ lu_byte isbreakable; /* true if `block' is a loop */
46
+ } BlockCnt;
47
+
48
+
49
+
50
+ /*
51
+ ** prototypes for recursive non-terminal functions
52
+ */
53
+ static void chunk (LexState *ls);
54
+ static void expr (LexState *ls, expdesc *v);
55
+
56
+
57
+ static void anchor_token (LexState *ls) {
58
+ if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
59
+ TString *ts = ls->t.seminfo.ts;
60
+ luaX_newstring(ls, getstr(ts), ts->tsv.len);
61
+ }
62
+ }
63
+
64
+
65
+ static void error_expected (LexState *ls, int token) {
66
+ luaX_syntaxerror(ls,
67
+ luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token)));
68
+ }
69
+
70
+
71
+ static void errorlimit (FuncState *fs, int limit, const char *what) {
72
+ const char *msg = (fs->f->linedefined == 0) ?
73
+ luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) :
74
+ luaO_pushfstring(fs->L, "function at line %d has more than %d %s",
75
+ fs->f->linedefined, limit, what);
76
+ luaX_lexerror(fs->ls, msg, 0);
77
+ }
78
+
79
+
80
+ static int testnext (LexState *ls, int c) {
81
+ if (ls->t.token == c) {
82
+ luaX_next(ls);
83
+ return 1;
84
+ }
85
+ else return 0;
86
+ }
87
+
88
+
89
+ static void check (LexState *ls, int c) {
90
+ if (ls->t.token != c)
91
+ error_expected(ls, c);
92
+ }
93
+
94
+ static void checknext (LexState *ls, int c) {
95
+ check(ls, c);
96
+ luaX_next(ls);
97
+ }
98
+
99
+
100
+ #define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
101
+
102
+
103
+
104
+ static void check_match (LexState *ls, int what, int who, int where) {
105
+ if (!testnext(ls, what)) {
106
+ if (where == ls->linenumber)
107
+ error_expected(ls, what);
108
+ else {
109
+ luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
110
+ LUA_QS " expected (to close " LUA_QS " at line %d)",
111
+ luaX_token2str(ls, what), luaX_token2str(ls, who), where));
112
+ }
113
+ }
114
+ }
115
+
116
+
117
+ static TString *str_checkname (LexState *ls) {
118
+ TString *ts;
119
+ check(ls, TK_NAME);
120
+ ts = ls->t.seminfo.ts;
121
+ luaX_next(ls);
122
+ return ts;
123
+ }
124
+
125
+
126
+ static void init_exp (expdesc *e, expkind k, int i) {
127
+ e->f = e->t = NO_JUMP;
128
+ e->k = k;
129
+ e->u.s.info = i;
130
+ }
131
+
132
+
133
+ static void codestring (LexState *ls, expdesc *e, TString *s) {
134
+ init_exp(e, VK, luaK_stringK(ls->fs, s));
135
+ }
136
+
137
+
138
+ static void checkname(LexState *ls, expdesc *e) {
139
+ codestring(ls, e, str_checkname(ls));
140
+ }
141
+
142
+
143
+ static int registerlocalvar (LexState *ls, TString *varname) {
144
+ FuncState *fs = ls->fs;
145
+ Proto *f = fs->f;
146
+ int oldsize = f->sizelocvars;
147
+ luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
148
+ LocVar, SHRT_MAX, "too many local variables");
149
+ while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
150
+ f->locvars[fs->nlocvars].varname = varname;
151
+ luaC_objbarrier(ls->L, f, varname);
152
+ return fs->nlocvars++;
153
+ }
154
+
155
+
156
+ #define new_localvarliteral(ls,v,n) \
157
+ new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n)
158
+
159
+
160
+ static void new_localvar (LexState *ls, TString *name, int n) {
161
+ FuncState *fs = ls->fs;
162
+ luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables");
163
+ fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name));
164
+ }
165
+
166
+
167
+ static void adjustlocalvars (LexState *ls, int nvars) {
168
+ FuncState *fs = ls->fs;
169
+ fs->nactvar = cast_byte(fs->nactvar + nvars);
170
+ for (; nvars; nvars--) {
171
+ getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc;
172
+ }
173
+ }
174
+
175
+
176
+ static void removevars (LexState *ls, int tolevel) {
177
+ FuncState *fs = ls->fs;
178
+ while (fs->nactvar > tolevel)
179
+ getlocvar(fs, --fs->nactvar).endpc = fs->pc;
180
+ }
181
+
182
+
183
+ static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
184
+ int i;
185
+ Proto *f = fs->f;
186
+ int oldsize = f->sizeupvalues;
187
+ for (i=0; i<f->nups; i++) {
188
+ if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) {
189
+ lua_assert(f->upvalues[i] == name);
190
+ return i;
191
+ }
192
+ }
193
+ /* new one */
194
+ luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues");
195
+ luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues,
196
+ TString *, MAX_INT, "");
197
+ while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL;
198
+ f->upvalues[f->nups] = name;
199
+ luaC_objbarrier(fs->L, f, name);
200
+ lua_assert(v->k == VLOCAL || v->k == VUPVAL);
201
+ fs->upvalues[f->nups].k = cast_byte(v->k);
202
+ fs->upvalues[f->nups].info = cast_byte(v->u.s.info);
203
+ return f->nups++;
204
+ }
205
+
206
+
207
+ static int searchvar (FuncState *fs, TString *n) {
208
+ int i;
209
+ for (i=fs->nactvar-1; i >= 0; i--) {
210
+ if (n == getlocvar(fs, i).varname)
211
+ return i;
212
+ }
213
+ return -1; /* not found */
214
+ }
215
+
216
+
217
+ static void markupval (FuncState *fs, int level) {
218
+ BlockCnt *bl = fs->bl;
219
+ while (bl && bl->nactvar > level) bl = bl->previous;
220
+ if (bl) bl->upval = 1;
221
+ }
222
+
223
+
224
+ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
225
+ if (fs == NULL) { /* no more levels? */
226
+ init_exp(var, VGLOBAL, NO_REG); /* default is global variable */
227
+ return VGLOBAL;
228
+ }
229
+ else {
230
+ int v = searchvar(fs, n); /* look up at current level */
231
+ if (v >= 0) {
232
+ init_exp(var, VLOCAL, v);
233
+ if (!base)
234
+ markupval(fs, v); /* local will be used as an upval */
235
+ return VLOCAL;
236
+ }
237
+ else { /* not found at current level; try upper one */
238
+ if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL)
239
+ return VGLOBAL;
240
+ var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */
241
+ var->k = VUPVAL; /* upvalue in this level */
242
+ return VUPVAL;
243
+ }
244
+ }
245
+ }
246
+
247
+
248
+ static void singlevar (LexState *ls, expdesc *var) {
249
+ TString *varname = str_checkname(ls);
250
+ FuncState *fs = ls->fs;
251
+ if (singlevaraux(fs, varname, var, 1) == VGLOBAL)
252
+ var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */
253
+ }
254
+
255
+
256
+ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
257
+ FuncState *fs = ls->fs;
258
+ int extra = nvars - nexps;
259
+ if (hasmultret(e->k)) {
260
+ extra++; /* includes call itself */
261
+ if (extra < 0) extra = 0;
262
+ luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
263
+ if (extra > 1) luaK_reserveregs(fs, extra-1);
264
+ }
265
+ else {
266
+ if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
267
+ if (extra > 0) {
268
+ int reg = fs->freereg;
269
+ luaK_reserveregs(fs, extra);
270
+ luaK_nil(fs, reg, extra);
271
+ }
272
+ }
273
+ }
274
+
275
+
276
+ static void enterlevel (LexState *ls) {
277
+ if (++ls->L->nCcalls > LUAI_MAXCCALLS)
278
+ luaX_lexerror(ls, "chunk has too many syntax levels", 0);
279
+ }
280
+
281
+
282
+ #define leavelevel(ls) ((ls)->L->nCcalls--)
283
+
284
+
285
+ static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) {
286
+ bl->breaklist = NO_JUMP;
287
+ bl->isbreakable = isbreakable;
288
+ bl->nactvar = fs->nactvar;
289
+ bl->upval = 0;
290
+ bl->previous = fs->bl;
291
+ fs->bl = bl;
292
+ lua_assert(fs->freereg == fs->nactvar);
293
+ }
294
+
295
+
296
+ static void leaveblock (FuncState *fs) {
297
+ BlockCnt *bl = fs->bl;
298
+ fs->bl = bl->previous;
299
+ removevars(fs->ls, bl->nactvar);
300
+ if (bl->upval)
301
+ luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
302
+ /* a block either controls scope or breaks (never both) */
303
+ lua_assert(!bl->isbreakable || !bl->upval);
304
+ lua_assert(bl->nactvar == fs->nactvar);
305
+ fs->freereg = fs->nactvar; /* free registers */
306
+ luaK_patchtohere(fs, bl->breaklist);
307
+ }
308
+
309
+
310
+ static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
311
+ FuncState *fs = ls->fs;
312
+ Proto *f = fs->f;
313
+ int oldsize = f->sizep;
314
+ int i;
315
+ luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
316
+ MAXARG_Bx, "constant table overflow");
317
+ while (oldsize < f->sizep) f->p[oldsize++] = NULL;
318
+ f->p[fs->np++] = func->f;
319
+ luaC_objbarrier(ls->L, f, func->f);
320
+ init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
321
+ for (i=0; i<func->f->nups; i++) {
322
+ OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
323
+ luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
324
+ }
325
+ }
326
+
327
+
328
+ static void open_func (LexState *ls, FuncState *fs) {
329
+ lua_State *L = ls->L;
330
+ Proto *f = luaF_newproto(L);
331
+ fs->f = f;
332
+ fs->prev = ls->fs; /* linked list of funcstates */
333
+ fs->ls = ls;
334
+ fs->L = L;
335
+ ls->fs = fs;
336
+ fs->pc = 0;
337
+ fs->lasttarget = -1;
338
+ fs->jpc = NO_JUMP;
339
+ fs->freereg = 0;
340
+ fs->nk = 0;
341
+ fs->np = 0;
342
+ fs->nlocvars = 0;
343
+ fs->nactvar = 0;
344
+ fs->bl = NULL;
345
+ f->source = ls->source;
346
+ f->maxstacksize = 2; /* registers 0/1 are always valid */
347
+ fs->h = luaH_new(L, 0, 0);
348
+ /* anchor table of constants and prototype (to avoid being collected) */
349
+ sethvalue2s(L, L->top, fs->h);
350
+ incr_top(L);
351
+ setptvalue2s(L, L->top, f);
352
+ incr_top(L);
353
+ }
354
+
355
+
356
+ static void close_func (LexState *ls) {
357
+ lua_State *L = ls->L;
358
+ FuncState *fs = ls->fs;
359
+ Proto *f = fs->f;
360
+ removevars(ls, 0);
361
+ luaK_ret(fs, 0, 0); /* final return */
362
+ luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
363
+ f->sizecode = fs->pc;
364
+ luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
365
+ f->sizelineinfo = fs->pc;
366
+ luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
367
+ f->sizek = fs->nk;
368
+ luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
369
+ f->sizep = fs->np;
370
+ luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
371
+ f->sizelocvars = fs->nlocvars;
372
+ luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
373
+ f->sizeupvalues = f->nups;
374
+ lua_assert(luaG_checkcode(f));
375
+ lua_assert(fs->bl == NULL);
376
+ ls->fs = fs->prev;
377
+ /* last token read was anchored in defunct function; must reanchor it */
378
+ if (fs) anchor_token(ls);
379
+ L->top -= 2; /* remove table and prototype from the stack */
380
+ }
381
+
382
+
383
+ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
384
+ struct LexState lexstate;
385
+ struct FuncState funcstate;
386
+ lexstate.buff = buff;
387
+ luaX_setinput(L, &lexstate, z, luaS_new(L, name));
388
+ open_func(&lexstate, &funcstate);
389
+ funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */
390
+ luaX_next(&lexstate); /* read first token */
391
+ chunk(&lexstate);
392
+ check(&lexstate, TK_EOS);
393
+ close_func(&lexstate);
394
+ lua_assert(funcstate.prev == NULL);
395
+ lua_assert(funcstate.f->nups == 0);
396
+ lua_assert(lexstate.fs == NULL);
397
+ return funcstate.f;
398
+ }
399
+
400
+
401
+
402
+ /*============================================================*/
403
+ /* GRAMMAR RULES */
404
+ /*============================================================*/
405
+
406
+
407
+ static void field (LexState *ls, expdesc *v) {
408
+ /* field -> ['.' | ':'] NAME */
409
+ FuncState *fs = ls->fs;
410
+ expdesc key;
411
+ luaK_exp2anyreg(fs, v);
412
+ luaX_next(ls); /* skip the dot or colon */
413
+ checkname(ls, &key);
414
+ luaK_indexed(fs, v, &key);
415
+ }
416
+
417
+
418
+ static void yindex (LexState *ls, expdesc *v) {
419
+ /* index -> '[' expr ']' */
420
+ luaX_next(ls); /* skip the '[' */
421
+ expr(ls, v);
422
+ luaK_exp2val(ls->fs, v);
423
+ checknext(ls, ']');
424
+ }
425
+
426
+
427
+ /*
428
+ ** {======================================================================
429
+ ** Rules for Constructors
430
+ ** =======================================================================
431
+ */
432
+
433
+
434
+ struct ConsControl {
435
+ expdesc v; /* last list item read */
436
+ expdesc *t; /* table descriptor */
437
+ int nh; /* total number of `record' elements */
438
+ int na; /* total number of array elements */
439
+ int tostore; /* number of array elements pending to be stored */
440
+ };
441
+
442
+
443
+ static void recfield (LexState *ls, struct ConsControl *cc) {
444
+ /* recfield -> (NAME | `['exp1`]') = exp1 */
445
+ FuncState *fs = ls->fs;
446
+ int reg = ls->fs->freereg;
447
+ expdesc key, val;
448
+ int rkkey;
449
+ if (ls->t.token == TK_NAME) {
450
+ luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
451
+ checkname(ls, &key);
452
+ }
453
+ else /* ls->t.token == '[' */
454
+ yindex(ls, &key);
455
+ cc->nh++;
456
+ checknext(ls, '=');
457
+ rkkey = luaK_exp2RK(fs, &key);
458
+ expr(ls, &val);
459
+ luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val));
460
+ fs->freereg = reg; /* free registers */
461
+ }
462
+
463
+
464
+ static void closelistfield (FuncState *fs, struct ConsControl *cc) {
465
+ if (cc->v.k == VVOID) return; /* there is no list item */
466
+ luaK_exp2nextreg(fs, &cc->v);
467
+ cc->v.k = VVOID;
468
+ if (cc->tostore == LFIELDS_PER_FLUSH) {
469
+ luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */
470
+ cc->tostore = 0; /* no more items pending */
471
+ }
472
+ }
473
+
474
+
475
+ static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
476
+ if (cc->tostore == 0) return;
477
+ if (hasmultret(cc->v.k)) {
478
+ luaK_setmultret(fs, &cc->v);
479
+ luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET);
480
+ cc->na--; /* do not count last expression (unknown number of elements) */
481
+ }
482
+ else {
483
+ if (cc->v.k != VVOID)
484
+ luaK_exp2nextreg(fs, &cc->v);
485
+ luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore);
486
+ }
487
+ }
488
+
489
+
490
+ static void listfield (LexState *ls, struct ConsControl *cc) {
491
+ expr(ls, &cc->v);
492
+ luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
493
+ cc->na++;
494
+ cc->tostore++;
495
+ }
496
+
497
+
498
+ static void constructor (LexState *ls, expdesc *t) {
499
+ /* constructor -> ?? */
500
+ FuncState *fs = ls->fs;
501
+ int line = ls->linenumber;
502
+ int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
503
+ struct ConsControl cc;
504
+ cc.na = cc.nh = cc.tostore = 0;
505
+ cc.t = t;
506
+ init_exp(t, VRELOCABLE, pc);
507
+ init_exp(&cc.v, VVOID, 0); /* no value (yet) */
508
+ luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */
509
+ checknext(ls, '{');
510
+ do {
511
+ lua_assert(cc.v.k == VVOID || cc.tostore > 0);
512
+ if (ls->t.token == '}') break;
513
+ closelistfield(fs, &cc);
514
+ switch(ls->t.token) {
515
+ case TK_NAME: { /* may be listfields or recfields */
516
+ luaX_lookahead(ls);
517
+ if (ls->lookahead.token != '=') /* expression? */
518
+ listfield(ls, &cc);
519
+ else
520
+ recfield(ls, &cc);
521
+ break;
522
+ }
523
+ case '[': { /* constructor_item -> recfield */
524
+ recfield(ls, &cc);
525
+ break;
526
+ }
527
+ default: { /* constructor_part -> listfield */
528
+ listfield(ls, &cc);
529
+ break;
530
+ }
531
+ }
532
+ } while (testnext(ls, ',') || testnext(ls, ';'));
533
+ check_match(ls, '}', '{', line);
534
+ lastlistfield(fs, &cc);
535
+ SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
536
+ SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */
537
+ }
538
+
539
+ /* }====================================================================== */
540
+
541
+
542
+
543
+ static void parlist (LexState *ls) {
544
+ /* parlist -> [ param { `,' param } ] */
545
+ FuncState *fs = ls->fs;
546
+ Proto *f = fs->f;
547
+ int nparams = 0;
548
+ f->is_vararg = 0;
549
+ if (ls->t.token != ')') { /* is `parlist' not empty? */
550
+ do {
551
+ switch (ls->t.token) {
552
+ case TK_NAME: { /* param -> NAME */
553
+ new_localvar(ls, str_checkname(ls), nparams++);
554
+ break;
555
+ }
556
+ case TK_DOTS: { /* param -> `...' */
557
+ luaX_next(ls);
558
+ #if defined(LUA_COMPAT_VARARG)
559
+ /* use `arg' as default name */
560
+ new_localvarliteral(ls, "arg", nparams++);
561
+ f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG;
562
+ #endif
563
+ f->is_vararg |= VARARG_ISVARARG;
564
+ break;
565
+ }
566
+ default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
567
+ }
568
+ } while (!f->is_vararg && testnext(ls, ','));
569
+ }
570
+ adjustlocalvars(ls, nparams);
571
+ f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG));
572
+ luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
573
+ }
574
+
575
+
576
+ static void body (LexState *ls, expdesc *e, int needself, int line) {
577
+ /* body -> `(' parlist `)' chunk END */
578
+ FuncState new_fs;
579
+ open_func(ls, &new_fs);
580
+ new_fs.f->linedefined = line;
581
+ checknext(ls, '(');
582
+ if (needself) {
583
+ new_localvarliteral(ls, "self", 0);
584
+ adjustlocalvars(ls, 1);
585
+ }
586
+ parlist(ls);
587
+ checknext(ls, ')');
588
+ chunk(ls);
589
+ new_fs.f->lastlinedefined = ls->linenumber;
590
+ check_match(ls, TK_END, TK_FUNCTION, line);
591
+ close_func(ls);
592
+ pushclosure(ls, &new_fs, e);
593
+ }
594
+
595
+
596
+ static int explist1 (LexState *ls, expdesc *v) {
597
+ /* explist1 -> expr { `,' expr } */
598
+ int n = 1; /* at least one expression */
599
+ expr(ls, v);
600
+ while (testnext(ls, ',')) {
601
+ luaK_exp2nextreg(ls->fs, v);
602
+ expr(ls, v);
603
+ n++;
604
+ }
605
+ return n;
606
+ }
607
+
608
+
609
+ static void funcargs (LexState *ls, expdesc *f) {
610
+ FuncState *fs = ls->fs;
611
+ expdesc args;
612
+ int base, nparams;
613
+ int line = ls->linenumber;
614
+ switch (ls->t.token) {
615
+ case '(': { /* funcargs -> `(' [ explist1 ] `)' */
616
+ if (line != ls->lastline)
617
+ luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
618
+ luaX_next(ls);
619
+ if (ls->t.token == ')') /* arg list is empty? */
620
+ args.k = VVOID;
621
+ else {
622
+ explist1(ls, &args);
623
+ luaK_setmultret(fs, &args);
624
+ }
625
+ check_match(ls, ')', '(', line);
626
+ break;
627
+ }
628
+ case '{': { /* funcargs -> constructor */
629
+ constructor(ls, &args);
630
+ break;
631
+ }
632
+ case TK_STRING: { /* funcargs -> STRING */
633
+ codestring(ls, &args, ls->t.seminfo.ts);
634
+ luaX_next(ls); /* must use `seminfo' before `next' */
635
+ break;
636
+ }
637
+ default: {
638
+ luaX_syntaxerror(ls, "function arguments expected");
639
+ return;
640
+ }
641
+ }
642
+ lua_assert(f->k == VNONRELOC);
643
+ base = f->u.s.info; /* base register for call */
644
+ if (hasmultret(args.k))
645
+ nparams = LUA_MULTRET; /* open call */
646
+ else {
647
+ if (args.k != VVOID)
648
+ luaK_exp2nextreg(fs, &args); /* close last argument */
649
+ nparams = fs->freereg - (base+1);
650
+ }
651
+ init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
652
+ luaK_fixline(fs, line);
653
+ fs->freereg = base+1; /* call remove function and arguments and leaves
654
+ (unless changed) one result */
655
+ }
656
+
657
+
658
+
659
+
660
+ /*
661
+ ** {======================================================================
662
+ ** Expression parsing
663
+ ** =======================================================================
664
+ */
665
+
666
+
667
+ static void prefixexp (LexState *ls, expdesc *v) {
668
+ /* prefixexp -> NAME | '(' expr ')' */
669
+ switch (ls->t.token) {
670
+ case '(': {
671
+ int line = ls->linenumber;
672
+ luaX_next(ls);
673
+ expr(ls, v);
674
+ check_match(ls, ')', '(', line);
675
+ luaK_dischargevars(ls->fs, v);
676
+ return;
677
+ }
678
+ case TK_NAME: {
679
+ singlevar(ls, v);
680
+ return;
681
+ }
682
+ default: {
683
+ luaX_syntaxerror(ls, "unexpected symbol");
684
+ return;
685
+ }
686
+ }
687
+ }
688
+
689
+
690
+ static void primaryexp (LexState *ls, expdesc *v) {
691
+ /* primaryexp ->
692
+ prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
693
+ FuncState *fs = ls->fs;
694
+ prefixexp(ls, v);
695
+ for (;;) {
696
+ switch (ls->t.token) {
697
+ case '.': { /* field */
698
+ field(ls, v);
699
+ break;
700
+ }
701
+ case '[': { /* `[' exp1 `]' */
702
+ expdesc key;
703
+ luaK_exp2anyreg(fs, v);
704
+ yindex(ls, &key);
705
+ luaK_indexed(fs, v, &key);
706
+ break;
707
+ }
708
+ case ':': { /* `:' NAME funcargs */
709
+ expdesc key;
710
+ luaX_next(ls);
711
+ checkname(ls, &key);
712
+ luaK_self(fs, v, &key);
713
+ funcargs(ls, v);
714
+ break;
715
+ }
716
+ case '(': case TK_STRING: case '{': { /* funcargs */
717
+ luaK_exp2nextreg(fs, v);
718
+ funcargs(ls, v);
719
+ break;
720
+ }
721
+ default: return;
722
+ }
723
+ }
724
+ }
725
+
726
+
727
+ static void simpleexp (LexState *ls, expdesc *v) {
728
+ /* simpleexp -> NUMBER | STRING | NIL | true | false | ... |
729
+ constructor | FUNCTION body | primaryexp */
730
+ switch (ls->t.token) {
731
+ case TK_NUMBER: {
732
+ init_exp(v, VKNUM, 0);
733
+ v->u.nval = ls->t.seminfo.r;
734
+ break;
735
+ }
736
+ case TK_STRING: {
737
+ codestring(ls, v, ls->t.seminfo.ts);
738
+ break;
739
+ }
740
+ case TK_NIL: {
741
+ init_exp(v, VNIL, 0);
742
+ break;
743
+ }
744
+ case TK_TRUE: {
745
+ init_exp(v, VTRUE, 0);
746
+ break;
747
+ }
748
+ case TK_FALSE: {
749
+ init_exp(v, VFALSE, 0);
750
+ break;
751
+ }
752
+ case TK_DOTS: { /* vararg */
753
+ FuncState *fs = ls->fs;
754
+ check_condition(ls, fs->f->is_vararg,
755
+ "cannot use " LUA_QL("...") " outside a vararg function");
756
+ fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */
757
+ init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
758
+ break;
759
+ }
760
+ case '{': { /* constructor */
761
+ constructor(ls, v);
762
+ return;
763
+ }
764
+ case TK_FUNCTION: {
765
+ luaX_next(ls);
766
+ body(ls, v, 0, ls->linenumber);
767
+ return;
768
+ }
769
+ default: {
770
+ primaryexp(ls, v);
771
+ return;
772
+ }
773
+ }
774
+ luaX_next(ls);
775
+ }
776
+
777
+
778
+ static UnOpr getunopr (int op) {
779
+ switch (op) {
780
+ case TK_NOT: return OPR_NOT;
781
+ case '-': return OPR_MINUS;
782
+ case '#': return OPR_LEN;
783
+ default: return OPR_NOUNOPR;
784
+ }
785
+ }
786
+
787
+
788
+ static BinOpr getbinopr (int op) {
789
+ switch (op) {
790
+ case '+': return OPR_ADD;
791
+ case '-': return OPR_SUB;
792
+ case '*': return OPR_MUL;
793
+ case '/': return OPR_DIV;
794
+ case '%': return OPR_MOD;
795
+ case '^': return OPR_POW;
796
+ case TK_CONCAT: return OPR_CONCAT;
797
+ case TK_NE: return OPR_NE;
798
+ case TK_EQ: return OPR_EQ;
799
+ case '<': return OPR_LT;
800
+ case TK_LE: return OPR_LE;
801
+ case '>': return OPR_GT;
802
+ case TK_GE: return OPR_GE;
803
+ case TK_AND: return OPR_AND;
804
+ case TK_OR: return OPR_OR;
805
+ default: return OPR_NOBINOPR;
806
+ }
807
+ }
808
+
809
+
810
+ static const struct {
811
+ lu_byte left; /* left priority for each binary operator */
812
+ lu_byte right; /* right priority */
813
+ } priority[] = { /* ORDER OPR */
814
+ {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */
815
+ {10, 9}, {5, 4}, /* power and concat (right associative) */
816
+ {3, 3}, {3, 3}, /* equality and inequality */
817
+ {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */
818
+ {2, 2}, {1, 1} /* logical (and/or) */
819
+ };
820
+
821
+ #define UNARY_PRIORITY 8 /* priority for unary operators */
822
+
823
+
824
+ /*
825
+ ** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
826
+ ** where `binop' is any binary operator with a priority higher than `limit'
827
+ */
828
+ static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) {
829
+ BinOpr op;
830
+ UnOpr uop;
831
+ enterlevel(ls);
832
+ uop = getunopr(ls->t.token);
833
+ if (uop != OPR_NOUNOPR) {
834
+ luaX_next(ls);
835
+ subexpr(ls, v, UNARY_PRIORITY);
836
+ luaK_prefix(ls->fs, uop, v);
837
+ }
838
+ else simpleexp(ls, v);
839
+ /* expand while operators have priorities higher than `limit' */
840
+ op = getbinopr(ls->t.token);
841
+ while (op != OPR_NOBINOPR && priority[op].left > limit) {
842
+ expdesc v2;
843
+ BinOpr nextop;
844
+ luaX_next(ls);
845
+ luaK_infix(ls->fs, op, v);
846
+ /* read sub-expression with higher priority */
847
+ nextop = subexpr(ls, &v2, priority[op].right);
848
+ luaK_posfix(ls->fs, op, v, &v2);
849
+ op = nextop;
850
+ }
851
+ leavelevel(ls);
852
+ return op; /* return first untreated operator */
853
+ }
854
+
855
+
856
+ static void expr (LexState *ls, expdesc *v) {
857
+ subexpr(ls, v, 0);
858
+ }
859
+
860
+ /* }==================================================================== */
861
+
862
+
863
+
864
+ /*
865
+ ** {======================================================================
866
+ ** Rules for Statements
867
+ ** =======================================================================
868
+ */
869
+
870
+
871
+ static int block_follow (int token) {
872
+ switch (token) {
873
+ case TK_ELSE: case TK_ELSEIF: case TK_END:
874
+ case TK_UNTIL: case TK_EOS:
875
+ return 1;
876
+ default: return 0;
877
+ }
878
+ }
879
+
880
+
881
+ static void block (LexState *ls) {
882
+ /* block -> chunk */
883
+ FuncState *fs = ls->fs;
884
+ BlockCnt bl;
885
+ enterblock(fs, &bl, 0);
886
+ chunk(ls);
887
+ lua_assert(bl.breaklist == NO_JUMP);
888
+ leaveblock(fs);
889
+ }
890
+
891
+
892
+ /*
893
+ ** structure to chain all variables in the left-hand side of an
894
+ ** assignment
895
+ */
896
+ struct LHS_assign {
897
+ struct LHS_assign *prev;
898
+ expdesc v; /* variable (global, local, upvalue, or indexed) */
899
+ };
900
+
901
+
902
+ /*
903
+ ** check whether, in an assignment to a local variable, the local variable
904
+ ** is needed in a previous assignment (to a table). If so, save original
905
+ ** local value in a safe place and use this safe copy in the previous
906
+ ** assignment.
907
+ */
908
+ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
909
+ FuncState *fs = ls->fs;
910
+ int extra = fs->freereg; /* eventual position to save local variable */
911
+ int conflict = 0;
912
+ for (; lh; lh = lh->prev) {
913
+ if (lh->v.k == VINDEXED) {
914
+ if (lh->v.u.s.info == v->u.s.info) { /* conflict? */
915
+ conflict = 1;
916
+ lh->v.u.s.info = extra; /* previous assignment will use safe copy */
917
+ }
918
+ if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */
919
+ conflict = 1;
920
+ lh->v.u.s.aux = extra; /* previous assignment will use safe copy */
921
+ }
922
+ }
923
+ }
924
+ if (conflict) {
925
+ luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */
926
+ luaK_reserveregs(fs, 1);
927
+ }
928
+ }
929
+
930
+
931
+ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
932
+ expdesc e;
933
+ check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
934
+ "syntax error");
935
+ if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */
936
+ struct LHS_assign nv;
937
+ nv.prev = lh;
938
+ primaryexp(ls, &nv.v);
939
+ if (nv.v.k == VLOCAL)
940
+ check_conflict(ls, lh, &nv.v);
941
+ luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls,
942
+ "variables in assignment");
943
+ assignment(ls, &nv, nvars+1);
944
+ }
945
+ else { /* assignment -> `=' explist1 */
946
+ int nexps;
947
+ checknext(ls, '=');
948
+ nexps = explist1(ls, &e);
949
+ if (nexps != nvars) {
950
+ adjust_assign(ls, nvars, nexps, &e);
951
+ if (nexps > nvars)
952
+ ls->fs->freereg -= nexps - nvars; /* remove extra values */
953
+ }
954
+ else {
955
+ luaK_setoneret(ls->fs, &e); /* close last expression */
956
+ luaK_storevar(ls->fs, &lh->v, &e);
957
+ return; /* avoid default */
958
+ }
959
+ }
960
+ init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */
961
+ luaK_storevar(ls->fs, &lh->v, &e);
962
+ }
963
+
964
+
965
+ static int cond (LexState *ls) {
966
+ /* cond -> exp */
967
+ expdesc v;
968
+ expr(ls, &v); /* read condition */
969
+ if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */
970
+ luaK_goiftrue(ls->fs, &v);
971
+ return v.f;
972
+ }
973
+
974
+
975
+ static void breakstat (LexState *ls) {
976
+ FuncState *fs = ls->fs;
977
+ BlockCnt *bl = fs->bl;
978
+ int upval = 0;
979
+ while (bl && !bl->isbreakable) {
980
+ upval |= bl->upval;
981
+ bl = bl->previous;
982
+ }
983
+ if (!bl)
984
+ luaX_syntaxerror(ls, "no loop to break");
985
+ if (upval)
986
+ luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
987
+ luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
988
+ }
989
+
990
+
991
+ static void whilestat (LexState *ls, int line) {
992
+ /* whilestat -> WHILE cond DO block END */
993
+ FuncState *fs = ls->fs;
994
+ int whileinit;
995
+ int condexit;
996
+ BlockCnt bl;
997
+ luaX_next(ls); /* skip WHILE */
998
+ whileinit = luaK_getlabel(fs);
999
+ condexit = cond(ls);
1000
+ enterblock(fs, &bl, 1);
1001
+ checknext(ls, TK_DO);
1002
+ block(ls);
1003
+ luaK_patchlist(fs, luaK_jump(fs), whileinit);
1004
+ check_match(ls, TK_END, TK_WHILE, line);
1005
+ leaveblock(fs);
1006
+ luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
1007
+ }
1008
+
1009
+
1010
+ static void repeatstat (LexState *ls, int line) {
1011
+ /* repeatstat -> REPEAT block UNTIL cond */
1012
+ int condexit;
1013
+ FuncState *fs = ls->fs;
1014
+ int repeat_init = luaK_getlabel(fs);
1015
+ BlockCnt bl1, bl2;
1016
+ enterblock(fs, &bl1, 1); /* loop block */
1017
+ enterblock(fs, &bl2, 0); /* scope block */
1018
+ luaX_next(ls); /* skip REPEAT */
1019
+ chunk(ls);
1020
+ check_match(ls, TK_UNTIL, TK_REPEAT, line);
1021
+ condexit = cond(ls); /* read condition (inside scope block) */
1022
+ if (!bl2.upval) { /* no upvalues? */
1023
+ leaveblock(fs); /* finish scope */
1024
+ luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */
1025
+ }
1026
+ else { /* complete semantics when there are upvalues */
1027
+ breakstat(ls); /* if condition then break */
1028
+ luaK_patchtohere(ls->fs, condexit); /* else... */
1029
+ leaveblock(fs); /* finish scope... */
1030
+ luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */
1031
+ }
1032
+ leaveblock(fs); /* finish loop */
1033
+ }
1034
+
1035
+
1036
+ static int exp1 (LexState *ls) {
1037
+ expdesc e;
1038
+ int k;
1039
+ expr(ls, &e);
1040
+ k = e.k;
1041
+ luaK_exp2nextreg(ls->fs, &e);
1042
+ return k;
1043
+ }
1044
+
1045
+
1046
+ static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
1047
+ /* forbody -> DO block */
1048
+ BlockCnt bl;
1049
+ FuncState *fs = ls->fs;
1050
+ int prep, endfor;
1051
+ adjustlocalvars(ls, 3); /* control variables */
1052
+ checknext(ls, TK_DO);
1053
+ prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);
1054
+ enterblock(fs, &bl, 0); /* scope for declared variables */
1055
+ adjustlocalvars(ls, nvars);
1056
+ luaK_reserveregs(fs, nvars);
1057
+ block(ls);
1058
+ leaveblock(fs); /* end of scope for declared variables */
1059
+ luaK_patchtohere(fs, prep);
1060
+ endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
1061
+ luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
1062
+ luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
1063
+ luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
1064
+ }
1065
+
1066
+
1067
+ static void fornum (LexState *ls, TString *varname, int line) {
1068
+ /* fornum -> NAME = exp1,exp1[,exp1] forbody */
1069
+ FuncState *fs = ls->fs;
1070
+ int base = fs->freereg;
1071
+ new_localvarliteral(ls, "(for index)", 0);
1072
+ new_localvarliteral(ls, "(for limit)", 1);
1073
+ new_localvarliteral(ls, "(for step)", 2);
1074
+ new_localvar(ls, varname, 3);
1075
+ checknext(ls, '=');
1076
+ exp1(ls); /* initial value */
1077
+ checknext(ls, ',');
1078
+ exp1(ls); /* limit */
1079
+ if (testnext(ls, ','))
1080
+ exp1(ls); /* optional step */
1081
+ else { /* default step = 1 */
1082
+ luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
1083
+ luaK_reserveregs(fs, 1);
1084
+ }
1085
+ forbody(ls, base, line, 1, 1);
1086
+ }
1087
+
1088
+
1089
+ static void forlist (LexState *ls, TString *indexname) {
1090
+ /* forlist -> NAME {,NAME} IN explist1 forbody */
1091
+ FuncState *fs = ls->fs;
1092
+ expdesc e;
1093
+ int nvars = 0;
1094
+ int line;
1095
+ int base = fs->freereg;
1096
+ /* create control variables */
1097
+ new_localvarliteral(ls, "(for generator)", nvars++);
1098
+ new_localvarliteral(ls, "(for state)", nvars++);
1099
+ new_localvarliteral(ls, "(for control)", nvars++);
1100
+ /* create declared variables */
1101
+ new_localvar(ls, indexname, nvars++);
1102
+ while (testnext(ls, ','))
1103
+ new_localvar(ls, str_checkname(ls), nvars++);
1104
+ checknext(ls, TK_IN);
1105
+ line = ls->linenumber;
1106
+ adjust_assign(ls, 3, explist1(ls, &e), &e);
1107
+ luaK_checkstack(fs, 3); /* extra space to call generator */
1108
+ forbody(ls, base, line, nvars - 3, 0);
1109
+ }
1110
+
1111
+
1112
+ static void forstat (LexState *ls, int line) {
1113
+ /* forstat -> FOR (fornum | forlist) END */
1114
+ FuncState *fs = ls->fs;
1115
+ TString *varname;
1116
+ BlockCnt bl;
1117
+ enterblock(fs, &bl, 1); /* scope for loop and control variables */
1118
+ luaX_next(ls); /* skip `for' */
1119
+ varname = str_checkname(ls); /* first variable name */
1120
+ switch (ls->t.token) {
1121
+ case '=': fornum(ls, varname, line); break;
1122
+ case ',': case TK_IN: forlist(ls, varname); break;
1123
+ default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected");
1124
+ }
1125
+ check_match(ls, TK_END, TK_FOR, line);
1126
+ leaveblock(fs); /* loop scope (`break' jumps to this point) */
1127
+ }
1128
+
1129
+
1130
+ static int test_then_block (LexState *ls) {
1131
+ /* test_then_block -> [IF | ELSEIF] cond THEN block */
1132
+ int condexit;
1133
+ luaX_next(ls); /* skip IF or ELSEIF */
1134
+ condexit = cond(ls);
1135
+ checknext(ls, TK_THEN);
1136
+ block(ls); /* `then' part */
1137
+ return condexit;
1138
+ }
1139
+
1140
+
1141
+ static void ifstat (LexState *ls, int line) {
1142
+ /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
1143
+ FuncState *fs = ls->fs;
1144
+ int flist;
1145
+ int escapelist = NO_JUMP;
1146
+ flist = test_then_block(ls); /* IF cond THEN block */
1147
+ while (ls->t.token == TK_ELSEIF) {
1148
+ luaK_concat(fs, &escapelist, luaK_jump(fs));
1149
+ luaK_patchtohere(fs, flist);
1150
+ flist = test_then_block(ls); /* ELSEIF cond THEN block */
1151
+ }
1152
+ if (ls->t.token == TK_ELSE) {
1153
+ luaK_concat(fs, &escapelist, luaK_jump(fs));
1154
+ luaK_patchtohere(fs, flist);
1155
+ luaX_next(ls); /* skip ELSE (after patch, for correct line info) */
1156
+ block(ls); /* `else' part */
1157
+ }
1158
+ else
1159
+ luaK_concat(fs, &escapelist, flist);
1160
+ luaK_patchtohere(fs, escapelist);
1161
+ check_match(ls, TK_END, TK_IF, line);
1162
+ }
1163
+
1164
+
1165
+ static void localfunc (LexState *ls) {
1166
+ expdesc v, b;
1167
+ FuncState *fs = ls->fs;
1168
+ new_localvar(ls, str_checkname(ls), 0);
1169
+ init_exp(&v, VLOCAL, fs->freereg);
1170
+ luaK_reserveregs(fs, 1);
1171
+ adjustlocalvars(ls, 1);
1172
+ body(ls, &b, 0, ls->linenumber);
1173
+ luaK_storevar(fs, &v, &b);
1174
+ /* debug information will only see the variable after this point! */
1175
+ getlocvar(fs, fs->nactvar - 1).startpc = fs->pc;
1176
+ }
1177
+
1178
+
1179
+ static void localstat (LexState *ls) {
1180
+ /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */
1181
+ int nvars = 0;
1182
+ int nexps;
1183
+ expdesc e;
1184
+ do {
1185
+ new_localvar(ls, str_checkname(ls), nvars++);
1186
+ } while (testnext(ls, ','));
1187
+ if (testnext(ls, '='))
1188
+ nexps = explist1(ls, &e);
1189
+ else {
1190
+ e.k = VVOID;
1191
+ nexps = 0;
1192
+ }
1193
+ adjust_assign(ls, nvars, nexps, &e);
1194
+ adjustlocalvars(ls, nvars);
1195
+ }
1196
+
1197
+
1198
+ static int funcname (LexState *ls, expdesc *v) {
1199
+ /* funcname -> NAME {field} [`:' NAME] */
1200
+ int needself = 0;
1201
+ singlevar(ls, v);
1202
+ while (ls->t.token == '.')
1203
+ field(ls, v);
1204
+ if (ls->t.token == ':') {
1205
+ needself = 1;
1206
+ field(ls, v);
1207
+ }
1208
+ return needself;
1209
+ }
1210
+
1211
+
1212
+ static void funcstat (LexState *ls, int line) {
1213
+ /* funcstat -> FUNCTION funcname body */
1214
+ int needself;
1215
+ expdesc v, b;
1216
+ luaX_next(ls); /* skip FUNCTION */
1217
+ needself = funcname(ls, &v);
1218
+ body(ls, &b, needself, line);
1219
+ luaK_storevar(ls->fs, &v, &b);
1220
+ luaK_fixline(ls->fs, line); /* definition `happens' in the first line */
1221
+ }
1222
+
1223
+
1224
+ static void exprstat (LexState *ls) {
1225
+ /* stat -> func | assignment */
1226
+ FuncState *fs = ls->fs;
1227
+ struct LHS_assign v;
1228
+ primaryexp(ls, &v.v);
1229
+ if (v.v.k == VCALL) /* stat -> func */
1230
+ SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */
1231
+ else { /* stat -> assignment */
1232
+ v.prev = NULL;
1233
+ assignment(ls, &v, 1);
1234
+ }
1235
+ }
1236
+
1237
+
1238
+ static void retstat (LexState *ls) {
1239
+ /* stat -> RETURN explist */
1240
+ FuncState *fs = ls->fs;
1241
+ expdesc e;
1242
+ int first, nret; /* registers with returned values */
1243
+ luaX_next(ls); /* skip RETURN */
1244
+ if (block_follow(ls->t.token) || ls->t.token == ';')
1245
+ first = nret = 0; /* return no values */
1246
+ else {
1247
+ nret = explist1(ls, &e); /* optional return values */
1248
+ if (hasmultret(e.k)) {
1249
+ luaK_setmultret(fs, &e);
1250
+ if (e.k == VCALL && nret == 1) { /* tail call? */
1251
+ SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
1252
+ lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
1253
+ }
1254
+ first = fs->nactvar;
1255
+ nret = LUA_MULTRET; /* return all values */
1256
+ }
1257
+ else {
1258
+ if (nret == 1) /* only one single value? */
1259
+ first = luaK_exp2anyreg(fs, &e);
1260
+ else {
1261
+ luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
1262
+ first = fs->nactvar; /* return all `active' values */
1263
+ lua_assert(nret == fs->freereg - first);
1264
+ }
1265
+ }
1266
+ }
1267
+ luaK_ret(fs, first, nret);
1268
+ }
1269
+
1270
+
1271
+ static int statement (LexState *ls) {
1272
+ int line = ls->linenumber; /* may be needed for error messages */
1273
+ switch (ls->t.token) {
1274
+ case TK_IF: { /* stat -> ifstat */
1275
+ ifstat(ls, line);
1276
+ return 0;
1277
+ }
1278
+ case TK_WHILE: { /* stat -> whilestat */
1279
+ whilestat(ls, line);
1280
+ return 0;
1281
+ }
1282
+ case TK_DO: { /* stat -> DO block END */
1283
+ luaX_next(ls); /* skip DO */
1284
+ block(ls);
1285
+ check_match(ls, TK_END, TK_DO, line);
1286
+ return 0;
1287
+ }
1288
+ case TK_FOR: { /* stat -> forstat */
1289
+ forstat(ls, line);
1290
+ return 0;
1291
+ }
1292
+ case TK_REPEAT: { /* stat -> repeatstat */
1293
+ repeatstat(ls, line);
1294
+ return 0;
1295
+ }
1296
+ case TK_FUNCTION: {
1297
+ funcstat(ls, line); /* stat -> funcstat */
1298
+ return 0;
1299
+ }
1300
+ case TK_LOCAL: { /* stat -> localstat */
1301
+ luaX_next(ls); /* skip LOCAL */
1302
+ if (testnext(ls, TK_FUNCTION)) /* local function? */
1303
+ localfunc(ls);
1304
+ else
1305
+ localstat(ls);
1306
+ return 0;
1307
+ }
1308
+ case TK_RETURN: { /* stat -> retstat */
1309
+ retstat(ls);
1310
+ return 1; /* must be last statement */
1311
+ }
1312
+ case TK_BREAK: { /* stat -> breakstat */
1313
+ luaX_next(ls); /* skip BREAK */
1314
+ breakstat(ls);
1315
+ return 1; /* must be last statement */
1316
+ }
1317
+ default: {
1318
+ exprstat(ls);
1319
+ return 0; /* to avoid warnings */
1320
+ }
1321
+ }
1322
+ }
1323
+
1324
+
1325
+ static void chunk (LexState *ls) {
1326
+ /* chunk -> { stat [`;'] } */
1327
+ int islast = 0;
1328
+ enterlevel(ls);
1329
+ while (!islast && !block_follow(ls->t.token)) {
1330
+ islast = statement(ls);
1331
+ testnext(ls, ';');
1332
+ lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
1333
+ ls->fs->freereg >= ls->fs->nactvar);
1334
+ ls->fs->freereg = ls->fs->nactvar; /* free registers */
1335
+ }
1336
+ leavelevel(ls);
1337
+ }
1338
+
1339
+ /* }====================================================================== */