diff options
author | Mike Pall <mike> | 2010-02-06 08:18:32 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2010-02-06 08:18:32 +0100 |
commit | 1307f49137f328b0880c736644755428d84be0ba (patch) | |
tree | f530c2fd66f346b0942a9af7a155bf7b91ef958d /src | |
parent | 1f39cc5c21d9e78e955f3e98a7595151cc763ef7 (diff) | |
download | luajit-1307f49137f328b0880c736644755428d84be0ba.tar.gz luajit-1307f49137f328b0880c736644755428d84be0ba.tar.bz2 luajit-1307f49137f328b0880c736644755428d84be0ba.zip |
Major cleanup of bytecode parser.
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_parse.c | 2661 |
1 files changed, 1327 insertions, 1334 deletions
diff --git a/src/lj_parse.c b/src/lj_parse.c index 30a423bd..96136280 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c | |||
@@ -31,7 +31,7 @@ typedef enum { | |||
31 | VKFALSE, | 31 | VKFALSE, |
32 | VKTRUE, | 32 | VKTRUE, |
33 | VKSTR, /* sval = string value */ | 33 | VKSTR, /* sval = string value */ |
34 | VKNUM, /* nval = numerical value */ | 34 | VKNUM, /* nval = number value */ |
35 | VKLAST = VKNUM, | 35 | VKLAST = VKNUM, |
36 | /* Non-constant expressions follow: */ | 36 | /* Non-constant expressions follow: */ |
37 | VLOCAL, /* info = local register */ | 37 | VLOCAL, /* info = local register */ |
@@ -48,60 +48,73 @@ typedef enum { | |||
48 | /* Expression descriptor. */ | 48 | /* Expression descriptor. */ |
49 | typedef struct ExpDesc { | 49 | typedef struct ExpDesc { |
50 | union { | 50 | union { |
51 | struct { uint32_t info, aux; } s; | 51 | struct { |
52 | TValue nval; | 52 | uint32_t info; /* Primary info. */ |
53 | GCstr *sval; | 53 | uint32_t aux; /* Secondary info. */ |
54 | } s; | ||
55 | TValue nval; /* Number value. */ | ||
56 | GCstr *sval; /* String value. */ | ||
54 | } u; | 57 | } u; |
55 | ExpKind k; | 58 | ExpKind k; |
56 | BCPos t; /* true condition exit list */ | 59 | BCPos t; /* True condition jump list. */ |
57 | BCPos f; /* false condition exit list */ | 60 | BCPos f; /* False condition jump list. */ |
58 | } ExpDesc; | 61 | } ExpDesc; |
59 | 62 | ||
60 | /* Tests for expression types */ | 63 | /* Macros for expressions. */ |
61 | #define isK(e) ((uint32_t)((e)->k) <= VKLAST) | 64 | #define expr_hasnojump(e) ((e)->t != (e)->f) |
62 | #define isnumK(e) ((e)->k == VKNUM) | 65 | |
63 | #define isstrK(e) ((e)->k == VKSTR) | 66 | #define expr_isk(e) ((e)->k <= VKLAST) |
64 | #define expnumV(e) check_exp(isnumK((e)), numV(&(e)->u.nval)) | 67 | #define expr_isk_nojump(e) (expr_isk(e) && !expr_hasnojump(e)) |
65 | 68 | #define expr_isnumk(e) ((e)->k == VKNUM) | |
66 | #define hasjumps(e) ((e)->t != (e)->f) | 69 | #define expr_isnumk_nojump(e) (expr_isnumk(e) && !expr_hasnojump(e)) |
67 | #define isKexp(e) (isK(e) && !hasjumps(e)) | 70 | #define expr_isstrk(e) ((e)->k == VKSTR) |
68 | #define isnumKexp(e) (isnumK(e) && !hasjumps(e)) | 71 | |
69 | 72 | #define expr_numV(e) check_exp(expr_isnumk((e)), numV(&(e)->u.nval)) | |
70 | #define priKk(k) check_exp((k) <= VKTRUE, (k) - VKNIL) | 73 | |
71 | #define priK(e) priKk((e)->k) | 74 | /* Initialize expression. */ |
72 | 75 | static LJ_AINLINE void expr_init(ExpDesc *e, ExpKind k, uint32_t info) | |
73 | /* Per-function linked list of blocks. */ | 76 | { |
74 | typedef struct FuncBlock { | 77 | e->k = k; |
75 | struct FuncBlock *previous; /* chain */ | 78 | e->u.s.info = info; |
76 | BCPos breaklist; /* list of jumps out of this loop */ | 79 | e->f = e->t = NO_JMP; |
77 | uint8_t nactvar; /* # active locals outside the breakable structure */ | 80 | } |
78 | uint8_t upval; /* true if some variable in the block is an upvalue */ | 81 | |
79 | uint8_t isbreakable; /* true if `block' is a loop */ | 82 | /* Per-function linked list of scope blocks. */ |
80 | } FuncBlock; | 83 | typedef struct FuncScope { |
81 | 84 | struct FuncScope *prev; /* Link to outer scope. */ | |
82 | typedef struct UpValDesc { | 85 | BCPos breaklist; /* Jump list for loop breaks. */ |
83 | uint8_t k; | 86 | uint8_t nactvar; /* Number of active vars outside the scope. */ |
84 | uint8_t info; | 87 | uint8_t upval; /* Some variable in the scope is an upvalue. */ |
85 | } UpValDesc; | 88 | uint8_t isbreakable; /* Scope is a loop and allows a break. */ |
89 | } FuncScope; | ||
90 | |||
91 | /* Upvalue type and location. */ | ||
92 | typedef struct UVLoc { | ||
93 | uint8_t k; /* Upvalue type (ExpKind). */ | ||
94 | uint8_t info; /* Upvalue location (BCReg or uvidx). */ | ||
95 | } UVLoc; | ||
86 | 96 | ||
87 | /* Per-function state. */ | 97 | /* Per-function state. */ |
88 | typedef struct FuncState { | 98 | typedef struct FuncState { |
89 | GCproto *pt; /* current function header */ | 99 | GCproto *pt; /* Prototype object to be built. */ |
90 | GCtab *kt; /* table to find (and reuse) elements in `k' */ | 100 | GCtab *kt; /* Hash table for constants. */ |
91 | struct FuncState *prev; /* enclosing function */ | 101 | LexState *ls; /* Lexer state. */ |
92 | struct LexState *ls; /* lexical state */ | 102 | lua_State *L; /* Lua state. */ |
93 | struct lua_State *L; /* copy of the Lua state */ | 103 | FuncScope *bl; /* Current scope. */ |
94 | struct FuncBlock *bl; /* chain of current blocks */ | 104 | struct FuncState *prev; /* Enclosing function. */ |
95 | BCPos pc; /* next bytecode position */ | 105 | BCPos pc; /* Next bytecode position. */ |
96 | BCPos lasttarget; /* PC of last jump target */ | 106 | BCPos lasttarget; /* Bytecode position of last jump target. */ |
97 | BCPos jpc; /* list of pending jumps to PC */ | 107 | BCPos jpc; /* Pending jump list to next bytecode. */ |
98 | BCReg freereg; /* first free register */ | 108 | BCReg freereg; /* First free register. */ |
99 | BCReg nkn, nkgc; /* number of lua_Number/GCobj constants */ | 109 | BCReg nkn, nkgc; /* Number of lua_Number/GCobj constants */ |
100 | uint16_t nlocvars; /* number of elements in `locvars' */ | 110 | BCLine linedefined; /* First line of the function definition. */ |
101 | uint8_t nactvar; /* number of active local variables */ | 111 | MSize nvarinfo; /* Number of entries in varinfo. */ |
102 | uint8_t nuv; /* number of upvalues */ | 112 | uint8_t nactvar; /* Number of active local variables. */ |
103 | UpValDesc upvalues[LJ_MAX_UPVAL]; /* upvalues */ | 113 | uint8_t flags; /* Prototype flags. */ |
104 | uint16_t actvar[LJ_MAX_LOCVAR]; /* declared-variable stack */ | 114 | uint8_t framesize; /* Fixed frame size. */ |
115 | uint8_t nuv; /* Number of upvalues */ | ||
116 | uint16_t varmap[LJ_MAX_LOCVAR]; /* Map from register to varinfo index. */ | ||
117 | UVLoc uvloc[LJ_MAX_UPVAL]; /* Upvalue type and location. */ | ||
105 | } FuncState; | 118 | } FuncState; |
106 | 119 | ||
107 | /* Binary and unary operators. ORDER OPR */ | 120 | /* Binary and unary operators. ORDER OPR */ |
@@ -122,8 +135,6 @@ LJ_STATIC_ASSERT((int)BC_MULVV-(int)BC_ADDVV == (int)OPR_MUL-(int)OPR_ADD); | |||
122 | LJ_STATIC_ASSERT((int)BC_DIVVV-(int)BC_ADDVV == (int)OPR_DIV-(int)OPR_ADD); | 135 | LJ_STATIC_ASSERT((int)BC_DIVVV-(int)BC_ADDVV == (int)OPR_DIV-(int)OPR_ADD); |
123 | LJ_STATIC_ASSERT((int)BC_MODVV-(int)BC_ADDVV == (int)OPR_MOD-(int)OPR_ADD); | 136 | LJ_STATIC_ASSERT((int)BC_MODVV-(int)BC_ADDVV == (int)OPR_MOD-(int)OPR_ADD); |
124 | 137 | ||
125 | typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; | ||
126 | |||
127 | /* -- Error handling ------------------------------------------------------ */ | 138 | /* -- Error handling ------------------------------------------------------ */ |
128 | 139 | ||
129 | LJ_NORET LJ_NOINLINE static void err_syntax(LexState *ls, ErrMsg em) | 140 | LJ_NORET LJ_NOINLINE static void err_syntax(LexState *ls, ErrMsg em) |
@@ -138,19 +149,69 @@ LJ_NORET LJ_NOINLINE static void err_token(LexState *ls, LexToken token) | |||
138 | 149 | ||
139 | LJ_NORET static void err_limit(FuncState *fs, uint32_t limit, const char *what) | 150 | LJ_NORET static void err_limit(FuncState *fs, uint32_t limit, const char *what) |
140 | { | 151 | { |
141 | if (fs->pt->linedefined == 0) | 152 | if (fs->linedefined == 0) |
142 | lj_lex_error(fs->ls, 0, LJ_ERR_XLIMM, limit, what); | 153 | lj_lex_error(fs->ls, 0, LJ_ERR_XLIMM, limit, what); |
143 | else | 154 | else |
144 | lj_lex_error(fs->ls, 0, LJ_ERR_XLIMF, fs->pt->linedefined, limit, what); | 155 | lj_lex_error(fs->ls, 0, LJ_ERR_XLIMF, fs->linedefined, limit, what); |
145 | } | 156 | } |
146 | 157 | ||
147 | #define checklimit(fs, v, l, m) if ((v) >= (l)) err_limit(fs, l, m) | 158 | #define checklimit(fs, v, l, m) if ((v) >= (l)) err_limit(fs, l, m) |
148 | #define checklimitgt(fs, v, l, m) if ((v) > (l)) err_limit(fs, l, m) | 159 | #define checklimitgt(fs, v, l, m) if ((v) > (l)) err_limit(fs, l, m) |
149 | #define checkcond(ls, c, em) { if (!(c)) err_syntax(ls, em); } | 160 | #define checkcond(ls, c, em) { if (!(c)) err_syntax(ls, em); } |
150 | 161 | ||
151 | /* -- Code emitter: branches ---------------------------------------------- */ | 162 | /* -- Management of constants --------------------------------------------- */ |
163 | |||
164 | /* Return bytecode encoding for primitive constant. */ | ||
165 | #define const_pri(e) check_exp((e)->k <= VKTRUE, (e)->k) | ||
152 | 166 | ||
153 | static BCPos getjump(FuncState *fs, BCPos pc) | 167 | /* Add a number constant. */ |
168 | static BCReg const_num(FuncState *fs, ExpDesc *e) | ||
169 | { | ||
170 | lua_State *L = fs->L; | ||
171 | TValue *val; | ||
172 | lua_assert(expr_isnumk(e)); | ||
173 | val = lj_tab_set(L, fs->kt, &e->u.nval); | ||
174 | if (tvisnum(val)) | ||
175 | return val->u32.lo; | ||
176 | val->u64 = fs->nkn; | ||
177 | return fs->nkn++; | ||
178 | } | ||
179 | |||
180 | /* Add a GC object constant. */ | ||
181 | static BCReg const_gc(FuncState *fs, GCobj *gc, int itype) | ||
182 | { | ||
183 | lua_State *L = fs->L; | ||
184 | TValue o, *val; | ||
185 | setgcV(L, &o, &gc->gch, itype); | ||
186 | val = lj_tab_set(L, fs->kt, &o); | ||
187 | if (tvisnum(val)) | ||
188 | return val->u32.lo; | ||
189 | val->u64 = fs->nkgc; | ||
190 | return fs->nkgc++; | ||
191 | } | ||
192 | |||
193 | /* Add a string constant. */ | ||
194 | static BCReg const_str(FuncState *fs, ExpDesc *e) | ||
195 | { | ||
196 | lua_assert(expr_isstrk(e) || e->k == VGLOBAL); | ||
197 | return const_gc(fs, obj2gco(e->u.sval), LJ_TSTR); | ||
198 | } | ||
199 | |||
200 | /* Anchor string constant to avoid GC. */ | ||
201 | GCstr *lj_parse_keepstr(LexState *ls, const char *str, size_t len) | ||
202 | { | ||
203 | lua_State *L = ls->L; | ||
204 | GCstr *s = lj_str_new(L, str, len); | ||
205 | TValue *tv = lj_tab_setstr(L, ls->fs->kt, s); | ||
206 | if (tvisnil(tv)) setboolV(tv, 1); | ||
207 | lj_gc_check(L); | ||
208 | return s; | ||
209 | } | ||
210 | |||
211 | /* -- Jump list handling -------------------------------------------------- */ | ||
212 | |||
213 | /* Get next element in jump list. */ | ||
214 | static BCPos jmp_next(FuncState *fs, BCPos pc) | ||
154 | { | 215 | { |
155 | ptrdiff_t delta = bc_j(proto_ins(fs->pt, pc)); | 216 | ptrdiff_t delta = bc_j(proto_ins(fs->pt, pc)); |
156 | if ((BCPos)delta == NO_JMP) | 217 | if ((BCPos)delta == NO_JMP) |
@@ -159,37 +220,41 @@ static BCPos getjump(FuncState *fs, BCPos pc) | |||
159 | return (BCPos)(((ptrdiff_t)pc+1)+delta); | 220 | return (BCPos)(((ptrdiff_t)pc+1)+delta); |
160 | } | 221 | } |
161 | 222 | ||
162 | static int need_value(FuncState *fs, BCPos list) | 223 | /* Check if any of the instructions on the jump list produce no value. */ |
224 | static int jmp_novalue(FuncState *fs, BCPos list) | ||
163 | { | 225 | { |
164 | for (; list != NO_JMP; list = getjump(fs, list)) { | 226 | for (; list != NO_JMP; list = jmp_next(fs, list)) { |
165 | BCOp op = bc_op(proto_ins(fs->pt, list >= 1 ? list-1 : list)); | 227 | BCOp op = bc_op(proto_ins(fs->pt, list >= 1 ? list-1 : list)); |
166 | if (!(op == BC_ISTC || op == BC_ISFC)) return 1; | 228 | if (!(op == BC_ISTC || op == BC_ISFC)) return 1; |
167 | } | 229 | } |
168 | return 0; /* Not found. */ | 230 | return 0; |
169 | } | 231 | } |
170 | 232 | ||
171 | static int patchtestreg(FuncState *fs, BCPos pc, BCReg reg) | 233 | /* Patch register of test instructions. */ |
234 | static int jmp_patchtestreg(FuncState *fs, BCPos pc, BCReg reg) | ||
172 | { | 235 | { |
173 | BCIns *i = proto_insptr(fs->pt, pc >= 1 ? pc-1 : pc); | 236 | BCIns *i = proto_insptr(fs->pt, pc >= 1 ? pc-1 : pc); |
174 | BCOp op = bc_op(*i); | 237 | BCOp op = bc_op(*i); |
175 | if (!(op == BC_ISTC || op == BC_ISFC)) | 238 | if (!(op == BC_ISTC || op == BC_ISFC)) |
176 | return 0; /* cannot patch other instructions */ | 239 | return 0; /* Cannot patch other instructions. */ |
177 | if (reg != NO_REG && reg != bc_d(*i)) { | 240 | if (reg != NO_REG && reg != bc_d(*i)) { |
178 | setbc_a(i, reg); | 241 | setbc_a(i, reg); |
179 | } else { /* no register to put value or register already has the value */ | 242 | } else { /* Nothing to store or already in the right register. */ |
180 | setbc_op(i, op+(BC_IST-BC_ISTC)); | 243 | setbc_op(i, op+(BC_IST-BC_ISTC)); |
181 | setbc_a(i, 0); | 244 | setbc_a(i, 0); |
182 | } | 245 | } |
183 | return 1; | 246 | return 1; |
184 | } | 247 | } |
185 | 248 | ||
186 | static void removevalues(FuncState *fs, BCPos list) | 249 | /* Drop values for all instructions on jump list. */ |
250 | static void jmp_dropval(FuncState *fs, BCPos list) | ||
187 | { | 251 | { |
188 | for (; list != NO_JMP; list = getjump(fs, list)) | 252 | for (; list != NO_JMP; list = jmp_next(fs, list)) |
189 | patchtestreg(fs, list, NO_REG); | 253 | jmp_patchtestreg(fs, list, NO_REG); |
190 | } | 254 | } |
191 | 255 | ||
192 | static void fixjump(FuncState *fs, BCPos pc, BCPos dest) | 256 | /* Patch jump instruction to target. */ |
257 | static void jmp_patchins(FuncState *fs, BCPos pc, BCPos dest) | ||
193 | { | 258 | { |
194 | BCIns *jmp = proto_insptr(fs->pt, pc); | 259 | BCIns *jmp = proto_insptr(fs->pt, pc); |
195 | BCPos offset = dest-(pc+1)+BCBIAS_J; | 260 | BCPos offset = dest-(pc+1)+BCBIAS_J; |
@@ -199,198 +264,76 @@ static void fixjump(FuncState *fs, BCPos pc, BCPos dest) | |||
199 | setbc_d(jmp, offset); | 264 | setbc_d(jmp, offset); |
200 | } | 265 | } |
201 | 266 | ||
202 | static void concatjumps(FuncState *fs, BCPos *l1, BCPos l2) | 267 | /* Append to jump list. */ |
268 | static void jmp_append(FuncState *fs, BCPos *l1, BCPos l2) | ||
203 | { | 269 | { |
204 | if (l2 == NO_JMP) return; | 270 | if (l2 == NO_JMP) { |
205 | else if (*l1 == NO_JMP) { | 271 | return; |
272 | } else if (*l1 == NO_JMP) { | ||
206 | *l1 = l2; | 273 | *l1 = l2; |
207 | } else { | 274 | } else { |
208 | BCPos list = *l1; | 275 | BCPos list = *l1; |
209 | BCPos next; | 276 | BCPos next; |
210 | while ((next = getjump(fs, list)) != NO_JMP) /* find last element */ | 277 | while ((next = jmp_next(fs, list)) != NO_JMP) /* Find last element. */ |
211 | list = next; | 278 | list = next; |
212 | fixjump(fs, list, l2); | 279 | jmp_patchins(fs, list, l2); |
213 | } | 280 | } |
214 | } | 281 | } |
215 | 282 | ||
216 | static void patchlistaux(FuncState *fs, BCPos list, BCPos vtarget, | 283 | /* Patch jump list and preserve produced values. */ |
217 | BCReg reg, BCPos dtarget) | 284 | static void jmp_patchval(FuncState *fs, BCPos list, BCPos vtarget, |
285 | BCReg reg, BCPos dtarget) | ||
218 | { | 286 | { |
219 | while (list != NO_JMP) { | 287 | while (list != NO_JMP) { |
220 | BCPos next = getjump(fs, list); | 288 | BCPos next = jmp_next(fs, list); |
221 | if (patchtestreg(fs, list, reg)) | 289 | if (jmp_patchtestreg(fs, list, reg)) |
222 | fixjump(fs, list, vtarget); | 290 | jmp_patchins(fs, list, vtarget); /* Jump to target with value. */ |
223 | else | 291 | else |
224 | fixjump(fs, list, dtarget); /* jump to default target */ | 292 | jmp_patchins(fs, list, dtarget); /* Jump to default target. */ |
225 | list = next; | 293 | list = next; |
226 | } | 294 | } |
227 | } | 295 | } |
228 | 296 | ||
229 | static void patchtohere(FuncState *fs, BCPos list) | 297 | /* Jump to following instruction. Append to list of pending jumps. */ |
298 | static void jmp_tohere(FuncState *fs, BCPos list) | ||
230 | { | 299 | { |
231 | fs->lasttarget = fs->pc; | 300 | fs->lasttarget = fs->pc; |
232 | concatjumps(fs, &fs->jpc, list); | 301 | jmp_append(fs, &fs->jpc, list); |
233 | } | 302 | } |
234 | 303 | ||
235 | static void patchlist(FuncState *fs, BCPos list, BCPos target) | 304 | /* Patch jump list to target. */ |
305 | static void jmp_patch(FuncState *fs, BCPos list, BCPos target) | ||
236 | { | 306 | { |
237 | if (target == fs->pc) { | 307 | if (target == fs->pc) { |
238 | patchtohere(fs, list); | 308 | jmp_tohere(fs, list); |
239 | } else { | 309 | } else { |
240 | lua_assert(target < fs->pc); | 310 | lua_assert(target < fs->pc); |
241 | patchlistaux(fs, list, target, NO_REG, target); | 311 | jmp_patchval(fs, list, target, NO_REG, target); |
242 | } | 312 | } |
243 | } | 313 | } |
244 | 314 | ||
245 | /* -- Code emitter: instructions ------------------------------------------ */ | 315 | /* -- Bytecode register allocator ----------------------------------------- */ |
246 | |||
247 | static BCPos emitINS(FuncState *fs, BCIns i) | ||
248 | { | ||
249 | GCproto *pt; | ||
250 | BCIns *bc; | ||
251 | BCLine *lineinfo; | ||
252 | patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); | ||
253 | fs->jpc = NO_JMP; | ||
254 | pt = fs->pt; | ||
255 | bc = proto_bc(pt); | ||
256 | lineinfo = proto_lineinfo(pt); | ||
257 | if (LJ_UNLIKELY(fs->pc >= pt->sizebc)) { | ||
258 | checklimit(fs, fs->pc, LJ_MAX_BCINS, "bytecode instructions"); | ||
259 | lj_mem_growvec(fs->L, bc, pt->sizebc, LJ_MAX_BCINS, BCIns); | ||
260 | setmref(pt->bc, bc); | ||
261 | lj_mem_growvec(fs->L, lineinfo, pt->sizelineinfo, LJ_MAX_BCINS, BCLine); | ||
262 | setmref(pt->lineinfo, lineinfo); | ||
263 | } | ||
264 | bc[fs->pc] = i; | ||
265 | lineinfo[fs->pc] = fs->ls->lastline; | ||
266 | return fs->pc++; | ||
267 | } | ||
268 | |||
269 | #define emitABC(fs, o, a, b, c) emitINS(fs, BCINS_ABC(o, a, b, c)) | ||
270 | #define emitAD(fs, o, a, d) emitINS(fs, BCINS_AD(o, a, d)) | ||
271 | #define emitAJ(fs, o, a, j) emitINS(fs, BCINS_AJ(o, a, j)) | ||
272 | |||
273 | #define bcptr(fs, e) (proto_insptr((fs)->pt, (e)->u.s.info)) | ||
274 | |||
275 | static BCPos emit_jump(FuncState *fs) | ||
276 | { | ||
277 | BCPos jpc = fs->jpc; /* save list of jumps to here */ | ||
278 | BCPos j = fs->pc - 1; | ||
279 | fs->jpc = NO_JMP; | ||
280 | if ((int32_t)j >= (int32_t)fs->lasttarget && | ||
281 | bc_op(proto_ins(fs->pt, j)) == BC_UCLO) | ||
282 | setbc_j(proto_insptr(fs->pt, j), NO_JMP); | ||
283 | else | ||
284 | j = emitAJ(fs, BC_JMP, fs->freereg, NO_JMP); | ||
285 | concatjumps(fs, &j, jpc); /* keep them on hold */ | ||
286 | return j; | ||
287 | } | ||
288 | |||
289 | /* -- Code emitter: constants --------------------------------------------- */ | ||
290 | 316 | ||
291 | static BCReg numK(FuncState *fs, ExpDesc *e) | 317 | /* Bump frame size. */ |
292 | { | 318 | static void bcreg_bump(FuncState *fs, BCReg n) |
293 | lua_State *L = fs->L; | ||
294 | TValue *val; | ||
295 | lua_assert(isnumK(e)); | ||
296 | val = lj_tab_set(L, fs->kt, &e->u.nval); | ||
297 | if (tvisnum(val)) | ||
298 | return val->u32.lo; | ||
299 | val->u64 = fs->nkn; | ||
300 | return fs->nkn++; | ||
301 | } | ||
302 | |||
303 | static BCReg gcK(FuncState *fs, GCobj *gc, int itype) | ||
304 | { | ||
305 | lua_State *L = fs->L; | ||
306 | TValue o, *val; | ||
307 | setgcV(L, &o, &gc->gch, itype); | ||
308 | val = lj_tab_set(L, fs->kt, &o); | ||
309 | if (tvisnum(val)) | ||
310 | return val->u32.lo; | ||
311 | val->u64 = fs->nkgc; | ||
312 | return fs->nkgc++; | ||
313 | } | ||
314 | |||
315 | static BCReg strK(FuncState *fs, ExpDesc *e) | ||
316 | { | ||
317 | lua_assert(isstrK(e) || e->k == VGLOBAL); | ||
318 | return gcK(fs, obj2gco(e->u.sval), LJ_TSTR); | ||
319 | } | ||
320 | |||
321 | GCstr *lj_parse_keepstr(LexState *ls, const char *str, size_t len) | ||
322 | { | ||
323 | lua_State *L = ls->L; | ||
324 | GCstr *s = lj_str_new(L, str, len); | ||
325 | TValue *tv = lj_tab_setstr(L, ls->fs->kt, s); | ||
326 | if (tvisnil(tv)) setboolV(tv, 1); /* Anchor string to avoid GC. */ | ||
327 | lj_gc_check(L); | ||
328 | return s; | ||
329 | } | ||
330 | |||
331 | static void keep_token(LexState *ls) | ||
332 | { | ||
333 | if (ls->token == TK_name || ls->token == TK_string) { | ||
334 | TValue *tv = lj_tab_setstr(ls->L, ls->fs->kt, strV(&ls->tokenval)); | ||
335 | if (tvisnil(tv)) setboolV(tv, 1); /* Anchor string to avoid GC. */ | ||
336 | } | ||
337 | } | ||
338 | |||
339 | static void nilK(FuncState *fs, BCReg from, BCReg n) | ||
340 | { | ||
341 | BCIns *pr; | ||
342 | if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ | ||
343 | BCReg pfrom, pto; | ||
344 | pr = proto_insptr(fs->pt, fs->pc-1); | ||
345 | pfrom = bc_a(*pr); | ||
346 | switch (bc_op(*pr)) { | ||
347 | case BC_KPRI: | ||
348 | if (bc_d(*pr) != ~LJ_TNIL) break; | ||
349 | if (from == pfrom) { | ||
350 | if (n == 1) return; | ||
351 | } else if (from == pfrom+1) { | ||
352 | from = pfrom; | ||
353 | n++; | ||
354 | } else { | ||
355 | break; | ||
356 | } | ||
357 | fs->pc--; | ||
358 | break; | ||
359 | case BC_KNIL: | ||
360 | pto = bc_d(*pr); | ||
361 | if (pfrom <= from && from <= pto+1) { /* can connect both? */ | ||
362 | if (from+n-1 > pto) | ||
363 | setbc_d(pr, from+n-1); | ||
364 | return; | ||
365 | } | ||
366 | break; | ||
367 | default: | ||
368 | break; | ||
369 | } | ||
370 | } | ||
371 | emitINS(fs, n == 1 ? BCINS_AD(BC_KPRI, from, priKk(VKNIL)) | ||
372 | : BCINS_AD(BC_KNIL, from, from+n-1)); | ||
373 | } | ||
374 | |||
375 | /* -- Code emitter: registers --------------------------------------------- */ | ||
376 | |||
377 | static void checkframe(FuncState *fs, BCReg n) | ||
378 | { | 319 | { |
379 | BCReg sz = fs->freereg + n; | 320 | BCReg sz = fs->freereg + n; |
380 | if (sz > fs->pt->framesize) { | 321 | if (sz > fs->framesize) { |
381 | if (sz >= LJ_MAX_SLOTS) | 322 | if (sz >= LJ_MAX_SLOTS) |
382 | err_syntax(fs->ls, LJ_ERR_XSLOTS); | 323 | err_syntax(fs->ls, LJ_ERR_XSLOTS); |
383 | fs->pt->framesize = cast_byte(sz); | 324 | fs->framesize = cast_byte(sz); |
384 | } | 325 | } |
385 | } | 326 | } |
386 | 327 | ||
387 | static void reserveregs(FuncState *fs, BCReg n) | 328 | /* Reserve registers. */ |
329 | static void bcreg_reserve(FuncState *fs, BCReg n) | ||
388 | { | 330 | { |
389 | checkframe(fs, n); | 331 | bcreg_bump(fs, n); |
390 | fs->freereg += n; | 332 | fs->freereg += n; |
391 | } | 333 | } |
392 | 334 | ||
393 | static void freereg(FuncState *fs, BCReg reg) | 335 | /* Free register. */ |
336 | static void bcreg_free(FuncState *fs, BCReg reg) | ||
394 | { | 337 | { |
395 | if (reg >= fs->nactvar) { | 338 | if (reg >= fs->nactvar) { |
396 | fs->freereg--; | 339 | fs->freereg--; |
@@ -398,337 +341,371 @@ static void freereg(FuncState *fs, BCReg reg) | |||
398 | } | 341 | } |
399 | } | 342 | } |
400 | 343 | ||
401 | static void freeexp(FuncState *fs, ExpDesc *e) | 344 | /* Free register for expression. */ |
345 | static void expr_free(FuncState *fs, ExpDesc *e) | ||
402 | { | 346 | { |
403 | if (e->k == VNONRELOC) | 347 | if (e->k == VNONRELOC) |
404 | freereg(fs, e->u.s.info); | 348 | bcreg_free(fs, e->u.s.info); |
349 | } | ||
350 | |||
351 | /* -- Bytecode emitter ---------------------------------------------------- */ | ||
352 | |||
353 | /* Emit bytecode instruction. */ | ||
354 | static BCPos bcemit_INS(FuncState *fs, BCIns i) | ||
355 | { | ||
356 | GCproto *pt; | ||
357 | BCIns *bc; | ||
358 | BCLine *lineinfo; | ||
359 | jmp_patchval(fs, fs->jpc, fs->pc, NO_REG, fs->pc); | ||
360 | fs->jpc = NO_JMP; | ||
361 | pt = fs->pt; | ||
362 | bc = proto_bc(pt); | ||
363 | lineinfo = proto_lineinfo(pt); | ||
364 | if (LJ_UNLIKELY(fs->pc >= pt->sizebc)) { | ||
365 | checklimit(fs, fs->pc, LJ_MAX_BCINS, "bytecode instructions"); | ||
366 | lj_mem_growvec(fs->L, bc, pt->sizebc, LJ_MAX_BCINS, BCIns); | ||
367 | setmref(pt->bc, bc); | ||
368 | lj_mem_growvec(fs->L, lineinfo, pt->sizelineinfo, LJ_MAX_BCINS, BCLine); | ||
369 | setmref(pt->lineinfo, lineinfo); | ||
370 | } | ||
371 | bc[fs->pc] = i; | ||
372 | lineinfo[fs->pc] = fs->ls->lastline; | ||
373 | return fs->pc++; | ||
405 | } | 374 | } |
406 | 375 | ||
407 | /* -- Code emitter: expressions ------------------------------------------- */ | 376 | #define bcemit_ABC(fs, o, a, b, c) bcemit_INS(fs, BCINS_ABC(o, a, b, c)) |
377 | #define bcemit_AD(fs, o, a, d) bcemit_INS(fs, BCINS_AD(o, a, d)) | ||
378 | #define bcemit_AJ(fs, o, a, j) bcemit_INS(fs, BCINS_AJ(o, a, j)) | ||
379 | |||
380 | #define bcptr(fs, e) (proto_insptr((fs)->pt, (e)->u.s.info)) | ||
408 | 381 | ||
409 | static void dischargevars(FuncState *fs, ExpDesc *e) | 382 | /* -- Bytecode emitter for expressions ------------------------------------ */ |
383 | |||
384 | /* Discharge non-constant expression to any register. */ | ||
385 | static void expr_discharge(FuncState *fs, ExpDesc *e) | ||
410 | { | 386 | { |
411 | BCIns ins; | 387 | BCIns ins; |
412 | switch (e->k) { | 388 | if (e->k == VUPVAL) { |
413 | case VUPVAL: | ||
414 | ins = BCINS_AD(BC_UGET, 0, e->u.s.info); | 389 | ins = BCINS_AD(BC_UGET, 0, e->u.s.info); |
415 | break; | 390 | } else if (e->k == VGLOBAL) { |
416 | case VGLOBAL: | 391 | ins = BCINS_AD(BC_GGET, 0, const_str(fs, e)); |
417 | ins = BCINS_AD(BC_GGET, 0, strK(fs, e)); | 392 | } else if (e->k == VINDEXED) { |
418 | break; | ||
419 | case VINDEXED: { | ||
420 | /* TGET[VSB] key = reg, string const or byte const */ | ||
421 | BCReg rc = e->u.s.aux; | 393 | BCReg rc = e->u.s.aux; |
422 | if ((int32_t)rc < 0) { | 394 | if ((int32_t)rc < 0) { |
423 | ins = BCINS_ABC(BC_TGETS, 0, e->u.s.info, ~rc); | 395 | ins = BCINS_ABC(BC_TGETS, 0, e->u.s.info, ~rc); |
424 | } else if (rc > BCMAX_C) { | 396 | } else if (rc > BCMAX_C) { |
425 | ins = BCINS_ABC(BC_TGETB, 0, e->u.s.info, rc-(BCMAX_C+1)); | 397 | ins = BCINS_ABC(BC_TGETB, 0, e->u.s.info, rc-(BCMAX_C+1)); |
426 | } else { | 398 | } else { |
427 | freereg(fs, rc); | 399 | bcreg_free(fs, rc); |
428 | ins = BCINS_ABC(BC_TGETV, 0, e->u.s.info, rc); | 400 | ins = BCINS_ABC(BC_TGETV, 0, e->u.s.info, rc); |
429 | } | 401 | } |
430 | freereg(fs, e->u.s.info); | 402 | bcreg_free(fs, e->u.s.info); |
431 | break; | 403 | } else if (e->k == VCALL) { |
432 | } | ||
433 | case VCALL: | ||
434 | e->u.s.info = e->u.s.aux; | 404 | e->u.s.info = e->u.s.aux; |
435 | /* fallthrough */ | ||
436 | case VLOCAL: | ||
437 | e->k = VNONRELOC; | 405 | e->k = VNONRELOC; |
438 | /* fallthrough */ | 406 | return; |
439 | default: | 407 | } else if (e->k == VLOCAL) { |
408 | e->k = VNONRELOC; | ||
409 | return; | ||
410 | } else { | ||
440 | return; | 411 | return; |
441 | } | 412 | } |
442 | e->u.s.info = emitINS(fs, ins); | 413 | e->u.s.info = bcemit_INS(fs, ins); |
443 | e->k = VRELOCABLE; | 414 | e->k = VRELOCABLE; |
444 | } | 415 | } |
445 | 416 | ||
446 | static void discharge2reg(FuncState *fs, ExpDesc *e, BCReg reg) | 417 | /* Discharge an expression to a specific register. Ignore branches. */ |
418 | static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg) | ||
447 | { | 419 | { |
448 | BCIns ins; | 420 | BCIns ins; |
449 | dischargevars(fs, e); | 421 | expr_discharge(fs, e); |
450 | switch (e->k) { | 422 | if (e->k <= VKTRUE) { |
451 | case VKNIL: case VKFALSE: case VKTRUE: | 423 | ins = BCINS_AD(BC_KPRI, reg, const_pri(e)); |
452 | ins = BCINS_AD(BC_KPRI, reg, priK(e)); | 424 | } else if (e->k == VKSTR) { |
453 | break; | 425 | ins = BCINS_AD(BC_KSTR, reg, const_str(fs, e)); |
454 | case VKSTR: | 426 | } else if (e->k == VKNUM) { |
455 | ins = BCINS_AD(BC_KSTR, reg, strK(fs, e)); | 427 | lua_Number n = expr_numV(e); |
456 | break; | ||
457 | case VKNUM: { | ||
458 | lua_Number n = expnumV(e); | ||
459 | int32_t k = lj_num2int(n); | 428 | int32_t k = lj_num2int(n); |
460 | if (checki16(k) && n == cast_num(k)) | 429 | if (checki16(k) && n == cast_num(k)) |
461 | ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k); | 430 | ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k); |
462 | else | 431 | else |
463 | ins = BCINS_AD(BC_KNUM, reg, numK(fs, e)); | 432 | ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e)); |
464 | break; | 433 | } else if (e->k == VRELOCABLE) { |
465 | } | ||
466 | case VRELOCABLE: | ||
467 | setbc_a(bcptr(fs, e), reg); | 434 | setbc_a(bcptr(fs, e), reg); |
468 | goto noins; | 435 | goto noins; |
469 | case VNONRELOC: | 436 | } else if (e->k == VNONRELOC) { |
470 | if (reg == e->u.s.info) | 437 | if (reg == e->u.s.info) |
471 | goto noins; | 438 | goto noins; |
472 | ins = BCINS_AD(BC_MOV, reg, e->u.s.info); | 439 | ins = BCINS_AD(BC_MOV, reg, e->u.s.info); |
473 | break; | 440 | } else { |
474 | default: | ||
475 | lua_assert(e->k == VVOID || e->k == VJMP); | 441 | lua_assert(e->k == VVOID || e->k == VJMP); |
476 | return; /* nothing to do... */ | 442 | return; |
477 | } | 443 | } |
478 | emitINS(fs, ins); | 444 | bcemit_INS(fs, ins); |
479 | noins: | 445 | noins: |
480 | e->u.s.info = reg; | 446 | e->u.s.info = reg; |
481 | e->k = VNONRELOC; | 447 | e->k = VNONRELOC; |
482 | } | 448 | } |
483 | 449 | ||
484 | static void exp2reg(FuncState *fs, ExpDesc *e, BCReg reg) | 450 | /* Forward declaration. */ |
451 | static BCPos bcemit_jmp(FuncState *fs); | ||
452 | |||
453 | /* Discharge an expression to a specific register. */ | ||
454 | static void expr_toreg(FuncState *fs, ExpDesc *e, BCReg reg) | ||
485 | { | 455 | { |
486 | discharge2reg(fs, e, reg); | 456 | expr_toreg_nobranch(fs, e, reg); |
487 | if (e->k == VJMP) | 457 | if (e->k == VJMP) |
488 | concatjumps(fs, &e->t, e->u.s.info); /* put this jump in `t' list */ | 458 | jmp_append(fs, &e->t, e->u.s.info); /* Add it to the true jump list. */ |
489 | if (hasjumps(e)) { | 459 | if (expr_hasnojump(e)) { /* Discharge expression with branches. */ |
490 | BCPos final; /* position after whole expression */ | 460 | BCPos jend, jfalse = NO_JMP, jtrue = NO_JMP; |
491 | BCPos p_f = NO_JMP; /* position of an eventual LOAD false */ | 461 | if (jmp_novalue(fs, e->t) || jmp_novalue(fs, e->f)) { |
492 | BCPos p_t = NO_JMP; /* position of an eventual LOAD true */ | 462 | BCPos jval = (e->k == VJMP) ? NO_JMP : bcemit_jmp(fs); |
493 | if (need_value(fs, e->t) || need_value(fs, e->f)) { | 463 | jfalse = bcemit_AD(fs, BC_KPRI, reg, VKFALSE); |
494 | BCPos fj = (e->k == VJMP) ? NO_JMP : emit_jump(fs); | 464 | bcemit_AJ(fs, BC_JMP, fs->freereg, 1); |
495 | p_f = emitAD(fs, BC_KPRI, reg, priKk(VKFALSE)); | 465 | jtrue = bcemit_AD(fs, BC_KPRI, reg, VKTRUE); |
496 | emitAJ(fs, BC_JMP, fs->freereg, 1); | 466 | jmp_tohere(fs, jval); |
497 | p_t = emitAD(fs, BC_KPRI, reg, priKk(VKTRUE)); | ||
498 | patchtohere(fs, fj); | ||
499 | } | 467 | } |
500 | final = fs->pc; | 468 | jend = fs->pc; |
501 | fs->lasttarget = final; | 469 | fs->lasttarget = jend; |
502 | patchlistaux(fs, e->f, final, reg, p_f); | 470 | jmp_patchval(fs, e->f, jend, reg, jfalse); |
503 | patchlistaux(fs, e->t, final, reg, p_t); | 471 | jmp_patchval(fs, e->t, jend, reg, jtrue); |
504 | } | 472 | } |
505 | e->f = e->t = NO_JMP; | 473 | e->f = e->t = NO_JMP; |
506 | e->u.s.info = reg; | 474 | e->u.s.info = reg; |
507 | e->k = VNONRELOC; | 475 | e->k = VNONRELOC; |
508 | } | 476 | } |
509 | 477 | ||
510 | static void exp2nextreg(FuncState *fs, ExpDesc *e) | 478 | /* Discharge an expression to the next free register. */ |
479 | static void expr_tonextreg(FuncState *fs, ExpDesc *e) | ||
511 | { | 480 | { |
512 | dischargevars(fs, e); | 481 | expr_discharge(fs, e); |
513 | freeexp(fs, e); | 482 | expr_free(fs, e); |
514 | reserveregs(fs, 1); | 483 | bcreg_reserve(fs, 1); |
515 | exp2reg(fs, e, fs->freereg - 1); | 484 | expr_toreg(fs, e, fs->freereg - 1); |
516 | } | 485 | } |
517 | 486 | ||
518 | static BCReg exp2anyreg(FuncState *fs, ExpDesc *e) | 487 | /* Discharge an expression to any register. */ |
488 | static BCReg expr_toanyreg(FuncState *fs, ExpDesc *e) | ||
519 | { | 489 | { |
520 | dischargevars(fs, e); | 490 | expr_discharge(fs, e); |
521 | if (e->k == VNONRELOC) { | 491 | if (e->k == VNONRELOC) { |
522 | if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */ | 492 | if (!expr_hasnojump(e)) return e->u.s.info; /* Already in a register. */ |
523 | if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */ | 493 | if (e->u.s.info >= fs->nactvar) { |
524 | exp2reg(fs, e, e->u.s.info); /* put value on it */ | 494 | expr_toreg(fs, e, e->u.s.info); /* Discharge to temp. register. */ |
525 | return e->u.s.info; | 495 | return e->u.s.info; |
526 | } | 496 | } |
527 | } | 497 | } |
528 | exp2nextreg(fs, e); /* default */ | 498 | expr_tonextreg(fs, e); /* Discharge to next register. */ |
529 | return e->u.s.info; | 499 | return e->u.s.info; |
530 | } | 500 | } |
531 | 501 | ||
532 | static void exp2val(FuncState *fs, ExpDesc *e) | 502 | /* Partially discharge expression to a value. */ |
503 | static void expr_toval(FuncState *fs, ExpDesc *e) | ||
533 | { | 504 | { |
534 | if (hasjumps(e)) | 505 | if (expr_hasnojump(e)) |
535 | exp2anyreg(fs, e); | 506 | expr_toanyreg(fs, e); |
536 | else | 507 | else |
537 | dischargevars(fs, e); | 508 | expr_discharge(fs, e); |
538 | } | 509 | } |
539 | 510 | ||
540 | static void storevar(FuncState *fs, ExpDesc *var, ExpDesc *e) | 511 | /* Emit store for LHS expression. */ |
512 | static void bcemit_store(FuncState *fs, ExpDesc *var, ExpDesc *e) | ||
541 | { | 513 | { |
542 | BCIns ins; | 514 | BCIns ins; |
543 | switch (var->k) { | 515 | if (var->k == VLOCAL) { |
544 | case VLOCAL: | 516 | expr_free(fs, e); |
545 | freeexp(fs, e); | 517 | expr_toreg(fs, e, var->u.s.info); |
546 | exp2reg(fs, e, var->u.s.info); | ||
547 | return; | 518 | return; |
548 | case VUPVAL: | 519 | } else if (var->k == VUPVAL) { |
549 | exp2val(fs, e); | 520 | expr_toval(fs, e); |
550 | switch (e->k) { | 521 | if (e->k <= VKTRUE) |
551 | case VKNIL: case VKFALSE: case VKTRUE: | 522 | ins = BCINS_AD(BC_USETP, var->u.s.info, const_pri(e)); |
552 | ins = BCINS_AD(BC_USETP, var->u.s.info, priK(e)); | 523 | else if (e->k == VKSTR) |
553 | break; | 524 | ins = BCINS_AD(BC_USETS, var->u.s.info, const_str(fs, e)); |
554 | case VKSTR: | 525 | else if (e->k == VKNUM) |
555 | ins = BCINS_AD(BC_USETS, var->u.s.info, strK(fs, e)); | 526 | ins = BCINS_AD(BC_USETN, var->u.s.info, const_num(fs, e)); |
556 | break; | 527 | else |
557 | case VKNUM: | 528 | ins = BCINS_AD(BC_USETV, var->u.s.info, expr_toanyreg(fs, e)); |
558 | ins = BCINS_AD(BC_USETN, var->u.s.info, numK(fs, e)); | 529 | } else if (var->k == VGLOBAL) { |
559 | break; | 530 | BCReg ra = expr_toanyreg(fs, e); |
560 | default: | 531 | ins = BCINS_AD(BC_GSET, ra, const_str(fs, var)); |
561 | ins = BCINS_AD(BC_USETV, var->u.s.info, exp2anyreg(fs, e)); | 532 | } else { |
562 | break; | 533 | BCReg ra, rc; |
563 | } | 534 | lua_assert(var->k == VINDEXED); |
564 | break; | 535 | ra = expr_toanyreg(fs, e); |
565 | case VGLOBAL: { | 536 | rc = var->u.s.aux; |
566 | BCReg ra = exp2anyreg(fs, e); | ||
567 | ins = BCINS_AD(BC_GSET, ra, strK(fs, var)); | ||
568 | break; | ||
569 | } | ||
570 | case VINDEXED: { | ||
571 | /* TSET[VSB] key = reg, string const or byte const */ | ||
572 | BCReg ra = exp2anyreg(fs, e); | ||
573 | BCReg rc = var->u.s.aux; | ||
574 | if ((int32_t)rc < 0) { | 537 | if ((int32_t)rc < 0) { |
575 | ins = BCINS_ABC(BC_TSETS, ra, var->u.s.info, ~rc); | 538 | ins = BCINS_ABC(BC_TSETS, ra, var->u.s.info, ~rc); |
576 | } else if (rc > BCMAX_C) { | 539 | } else if (rc > BCMAX_C) { |
577 | ins = BCINS_ABC(BC_TSETB, ra, var->u.s.info, rc-(BCMAX_C+1)); | 540 | ins = BCINS_ABC(BC_TSETB, ra, var->u.s.info, rc-(BCMAX_C+1)); |
578 | } else { | 541 | } else { |
579 | /* Free late alloced key reg to avoid assert on free of value reg. */ | 542 | /* Free late alloced key reg to avoid assert on free of value reg. */ |
580 | /* This can only happen when called from constructor(). */ | 543 | /* This can only happen when called from expr_table(). */ |
581 | lua_assert(e->k != VNONRELOC || ra < fs->nactvar || | 544 | lua_assert(e->k != VNONRELOC || ra < fs->nactvar || |
582 | rc < ra || (freereg(fs, rc),1)); | 545 | rc < ra || (bcreg_free(fs, rc),1)); |
583 | ins = BCINS_ABC(BC_TSETV, ra, var->u.s.info, rc); | 546 | ins = BCINS_ABC(BC_TSETV, ra, var->u.s.info, rc); |
584 | } | 547 | } |
585 | break; | ||
586 | } | ||
587 | default: | ||
588 | lua_assert(0); /* invalid var kind to store */ | ||
589 | return; | ||
590 | } | ||
591 | emitINS(fs, ins); | ||
592 | freeexp(fs, e); | ||
593 | } | ||
594 | |||
595 | static void indexexp(FuncState *fs, ExpDesc *t, ExpDesc *e) | ||
596 | { | ||
597 | /* already called: exp2val(fs, e) */ | ||
598 | t->k = VINDEXED; | ||
599 | if (isnumK(e)) { | ||
600 | lua_Number n = expnumV(e); | ||
601 | int32_t k = lj_num2int(n); | ||
602 | if (checku8(k) && n == cast_num(k)) { | ||
603 | t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */ | ||
604 | return; | ||
605 | } | ||
606 | } else if (isstrK(e)) { | ||
607 | BCReg idx = strK(fs, e); | ||
608 | if (idx <= BCMAX_C) { | ||
609 | t->u.s.aux = ~idx; /* -256..-1: const string key */ | ||
610 | return; | ||
611 | } | ||
612 | } | 548 | } |
613 | t->u.s.aux = exp2anyreg(fs, e); /* 0..255: register */ | 549 | bcemit_INS(fs, ins); |
550 | expr_free(fs, e); | ||
614 | } | 551 | } |
615 | 552 | ||
616 | static void methodexp(FuncState *fs, ExpDesc *e, ExpDesc *key) | 553 | /* Emit method lookup expression. */ |
554 | static void bcemit_method(FuncState *fs, ExpDesc *e, ExpDesc *key) | ||
617 | { | 555 | { |
618 | BCReg idx, func, tab = exp2anyreg(fs, e); | 556 | BCReg idx, func, obj = expr_toanyreg(fs, e); |
619 | freeexp(fs, e); | 557 | expr_free(fs, e); |
620 | func = fs->freereg; | 558 | func = fs->freereg; |
621 | emitAD(fs, BC_MOV, func+1, tab); | 559 | bcemit_AD(fs, BC_MOV, func+1, obj); /* Copy object to first argument. */ |
622 | lua_assert(isstrK(key)); | 560 | lua_assert(expr_isstrk(key)); |
623 | idx = strK(fs, key); | 561 | idx = const_str(fs, key); |
624 | if (idx <= BCMAX_C) { | 562 | if (idx <= BCMAX_C) { |
625 | reserveregs(fs, 2); | 563 | bcreg_reserve(fs, 2); |
626 | emitABC(fs, BC_TGETS, func, tab, idx); | 564 | bcemit_ABC(fs, BC_TGETS, func, obj, idx); |
627 | } else { | 565 | } else { |
628 | reserveregs(fs, 3); | 566 | bcreg_reserve(fs, 3); |
629 | emitAD(fs, BC_KSTR, func+2, idx); | 567 | bcemit_AD(fs, BC_KSTR, func+2, idx); |
630 | emitABC(fs, BC_TGETV, func, tab, func+2); | 568 | bcemit_ABC(fs, BC_TGETV, func, obj, func+2); |
631 | fs->freereg--; | 569 | fs->freereg--; |
632 | } | 570 | } |
633 | e->u.s.info = func; | 571 | e->u.s.info = func; |
634 | e->k = VNONRELOC; | 572 | e->k = VNONRELOC; |
635 | } | 573 | } |
636 | 574 | ||
637 | /* -- Code emitter: conditionals ------------------------------------------ */ | 575 | /* Emit bytecode to set a range of registers to nil. */ |
576 | static void bcemit_nil(FuncState *fs, BCReg from, BCReg n) | ||
577 | { | ||
578 | BCIns *pr; | ||
579 | if (fs->pc > fs->lasttarget) { /* No jumps to current position? */ | ||
580 | BCReg pfrom, pto; | ||
581 | pr = proto_insptr(fs->pt, fs->pc-1); | ||
582 | pfrom = bc_a(*pr); | ||
583 | switch (bc_op(*pr)) { /* Try to merge with the previous instruction. */ | ||
584 | case BC_KPRI: | ||
585 | if (bc_d(*pr) != ~LJ_TNIL) break; | ||
586 | if (from == pfrom) { | ||
587 | if (n == 1) return; | ||
588 | } else if (from == pfrom+1) { | ||
589 | from = pfrom; | ||
590 | n++; | ||
591 | } else { | ||
592 | break; | ||
593 | } | ||
594 | fs->pc--; /* Drop KPRI. */ | ||
595 | break; | ||
596 | case BC_KNIL: | ||
597 | pto = bc_d(*pr); | ||
598 | if (pfrom <= from && from <= pto+1) { /* Can we connect both ranges? */ | ||
599 | if (from+n-1 > pto) | ||
600 | setbc_d(pr, from+n-1); /* Patch previous instruction range. */ | ||
601 | return; | ||
602 | } | ||
603 | break; | ||
604 | default: | ||
605 | break; | ||
606 | } | ||
607 | } | ||
608 | /* Emit new instruction or replace old instruction. */ | ||
609 | bcemit_INS(fs, n == 1 ? BCINS_AD(BC_KPRI, from, VKNIL) : | ||
610 | BCINS_AD(BC_KNIL, from, from+n-1)); | ||
611 | } | ||
612 | |||
613 | /* -- Bytecode emitter for branches --------------------------------------- */ | ||
614 | |||
615 | /* Emit unconditional branch. */ | ||
616 | static BCPos bcemit_jmp(FuncState *fs) | ||
617 | { | ||
618 | BCPos jpc = fs->jpc; | ||
619 | BCPos j = fs->pc - 1; | ||
620 | fs->jpc = NO_JMP; | ||
621 | if ((int32_t)j >= (int32_t)fs->lasttarget && | ||
622 | bc_op(proto_ins(fs->pt, j)) == BC_UCLO) | ||
623 | setbc_j(proto_insptr(fs->pt, j), NO_JMP); | ||
624 | else | ||
625 | j = bcemit_AJ(fs, BC_JMP, fs->freereg, NO_JMP); | ||
626 | jmp_append(fs, &j, jpc); | ||
627 | return j; | ||
628 | } | ||
638 | 629 | ||
639 | static void invertjump(FuncState *fs, ExpDesc *e) | 630 | /* Invert branch condition of bytecode instruction. */ |
631 | static void invertcond(FuncState *fs, ExpDesc *e) | ||
640 | { | 632 | { |
641 | BCIns *i = bcptr(fs, e) - 1; | 633 | BCIns *i = bcptr(fs, e) - 1; |
642 | setbc_op(i, bc_op(*i)^1); | 634 | setbc_op(i, bc_op(*i)^1); |
643 | } | 635 | } |
644 | 636 | ||
645 | static BCPos jumponcond(FuncState *fs, ExpDesc *e, int cond) | 637 | /* Emit conditional branch. */ |
638 | static BCPos bcemit_branch(FuncState *fs, ExpDesc *e, int cond) | ||
646 | { | 639 | { |
647 | BCPos pc; | 640 | BCPos pc; |
648 | if (e->k == VRELOCABLE) { | 641 | if (e->k == VRELOCABLE) { |
649 | BCIns *i = bcptr(fs, e); | 642 | BCIns *i = bcptr(fs, e); |
650 | if (bc_op(*i) == BC_NOT) { | 643 | if (bc_op(*i) == BC_NOT) { |
651 | *i = BCINS_AD(cond ? BC_ISF : BC_IST, 0, bc_d(*i)); | 644 | *i = BCINS_AD(cond ? BC_ISF : BC_IST, 0, bc_d(*i)); |
652 | return emit_jump(fs); | 645 | return bcemit_jmp(fs); |
653 | } | 646 | } |
654 | /* else go through */ | ||
655 | } | 647 | } |
656 | if (e->k != VNONRELOC) { | 648 | if (e->k != VNONRELOC) { |
657 | reserveregs(fs, 1); | 649 | bcreg_reserve(fs, 1); |
658 | discharge2reg(fs, e, fs->freereg-1); | 650 | expr_toreg_nobranch(fs, e, fs->freereg-1); |
659 | } | 651 | } |
660 | emitAD(fs, cond ? BC_ISTC : BC_ISFC, NO_REG, e->u.s.info); | 652 | bcemit_AD(fs, cond ? BC_ISTC : BC_ISFC, NO_REG, e->u.s.info); |
661 | pc = emit_jump(fs); | 653 | pc = bcemit_jmp(fs); |
662 | freeexp(fs, e); | 654 | expr_free(fs, e); |
663 | return pc; | 655 | return pc; |
664 | } | 656 | } |
665 | 657 | ||
666 | static void goiftrue(FuncState *fs, ExpDesc *e) | 658 | /* Emit branch on true condition. */ |
659 | static void bcemit_branch_t(FuncState *fs, ExpDesc *e) | ||
667 | { | 660 | { |
668 | BCPos pc; /* PC of last jump. */ | 661 | BCPos pc; |
669 | dischargevars(fs, e); | 662 | expr_discharge(fs, e); |
670 | switch (e->k) { | 663 | if (e->k == VKSTR || e->k == VKNUM || e->k == VKTRUE) |
671 | case VKSTR: case VKNUM: case VKTRUE: | 664 | pc = NO_JMP; /* Never jump. */ |
672 | pc = NO_JMP; /* always true; do nothing */ | 665 | else if (e->k == VJMP) |
673 | break; | 666 | invertcond(fs, e), pc = e->u.s.info; |
674 | case VJMP: | 667 | else if (e->k == VKFALSE && !expr_hasnojump(e)) |
675 | invertjump(fs, e); | 668 | pc = bcemit_jmp(fs); /* Always jump. */ |
676 | pc = e->u.s.info; | 669 | else |
677 | break; | 670 | pc = bcemit_branch(fs, e, 0); |
678 | case VKFALSE: | 671 | jmp_append(fs, &e->f, pc); |
679 | if (!hasjumps(e)) { | 672 | jmp_tohere(fs, e->t); |
680 | pc = emit_jump(fs); /* always jump */ | ||
681 | break; | ||
682 | } | ||
683 | /* fallthrough */ | ||
684 | default: | ||
685 | pc = jumponcond(fs, e, 0); | ||
686 | break; | ||
687 | } | ||
688 | concatjumps(fs, &e->f, pc); /* insert last jump in `f' list */ | ||
689 | patchtohere(fs, e->t); | ||
690 | e->t = NO_JMP; | 673 | e->t = NO_JMP; |
691 | } | 674 | } |
692 | 675 | ||
693 | static void goiffalse(FuncState *fs, ExpDesc *e) | 676 | /* Emit branch on false condition. */ |
677 | static void bcemit_branch_f(FuncState *fs, ExpDesc *e) | ||
694 | { | 678 | { |
695 | BCPos pc; /* PC of last jump. */ | 679 | BCPos pc; |
696 | dischargevars(fs, e); | 680 | expr_discharge(fs, e); |
697 | switch (e->k) { | 681 | if (e->k == VKNIL || e->k == VKFALSE) |
698 | case VKNIL: case VKFALSE: | 682 | pc = NO_JMP; /* Never jump. */ |
699 | pc = NO_JMP; /* always false; do nothing */ | 683 | else if (e->k == VJMP) |
700 | break; | ||
701 | case VJMP: | ||
702 | pc = e->u.s.info; | 684 | pc = e->u.s.info; |
703 | break; | 685 | else if (e->k == VKTRUE && !expr_hasnojump(e)) |
704 | case VKTRUE: | 686 | pc = bcemit_jmp(fs); /* Always jump. */ |
705 | if (!hasjumps(e)) { | 687 | else |
706 | pc = emit_jump(fs); /* always jump */ | 688 | pc = bcemit_branch(fs, e, 1); |
707 | break; | 689 | jmp_append(fs, &e->t, pc); |
708 | } | 690 | jmp_tohere(fs, e->f); |
709 | /* fallthrough */ | ||
710 | default: | ||
711 | pc = jumponcond(fs, e, 1); | ||
712 | break; | ||
713 | } | ||
714 | concatjumps(fs, &e->t, pc); /* insert last jump in `t' list */ | ||
715 | patchtohere(fs, e->f); | ||
716 | e->f = NO_JMP; | 691 | e->f = NO_JMP; |
717 | } | 692 | } |
718 | 693 | ||
719 | /* -- Code emitter: operators --------------------------------------------- */ | 694 | /* -- Bytecode emitter for operators -------------------------------------- */ |
720 | 695 | ||
696 | /* Try constant-folding of arithmetic operators. */ | ||
721 | static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2) | 697 | static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2) |
722 | { | 698 | { |
723 | TValue o; | 699 | TValue o; |
724 | if (!isnumKexp(e1) || !isnumKexp(e2)) return 0; | 700 | if (!expr_isnumk_nojump(e1) || !expr_isnumk_nojump(e2)) return 0; |
725 | setnumV(&o, lj_vm_foldarith(expnumV(e1), expnumV(e2), (int)opr-OPR_ADD)); | 701 | setnumV(&o, lj_vm_foldarith(expr_numV(e1), expr_numV(e2), (int)opr-OPR_ADD)); |
726 | if (tvisnan(&o) || tvismzero(&o)) return 0; /* Avoid NaN and -0 as consts. */ | 702 | if (tvisnan(&o) || tvismzero(&o)) return 0; /* Avoid NaN and -0 as consts. */ |
727 | setnumV(&e1->u.nval, numV(&o)); | 703 | setnumV(&e1->u.nval, numV(&o)); |
728 | return 1; | 704 | return 1; |
729 | } | 705 | } |
730 | 706 | ||
731 | static void codearith(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2) | 707 | /* Emit arithmetic operator. */ |
708 | static void bcemit_arith(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2) | ||
732 | { | 709 | { |
733 | BCReg rb, rc, t; | 710 | BCReg rb, rc, t; |
734 | uint32_t op; | 711 | uint32_t op; |
@@ -736,191 +713,174 @@ static void codearith(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2) | |||
736 | return; | 713 | return; |
737 | if (opr == OPR_POW) { | 714 | if (opr == OPR_POW) { |
738 | op = BC_POW; | 715 | op = BC_POW; |
739 | rc = exp2anyreg(fs, e2); | 716 | rc = expr_toanyreg(fs, e2); |
740 | rb = exp2anyreg(fs, e1); | 717 | rb = expr_toanyreg(fs, e1); |
741 | } else { | 718 | } else { |
742 | op = opr-OPR_ADD+BC_ADDVV; | 719 | op = opr-OPR_ADD+BC_ADDVV; |
743 | /* must discharge 2nd operand first since VINDEXED might free regs */ | 720 | /* Must discharge 2nd operand first since VINDEXED might free regs. */ |
744 | exp2val(fs, e2); | 721 | expr_toval(fs, e2); |
745 | if (isnumK(e2) && (rc = numK(fs, e2)) <= BCMAX_C) | 722 | if (expr_isnumk(e2) && (rc = const_num(fs, e2)) <= BCMAX_C) |
746 | op -= BC_ADDVV-BC_ADDVN; | 723 | op -= BC_ADDVV-BC_ADDVN; |
747 | else | 724 | else |
748 | rc = exp2anyreg(fs, e2); | 725 | rc = expr_toanyreg(fs, e2); |
749 | /* emit_prebinop discharges 1st operand, but may need to use KNUM/KSHORT */ | 726 | /* 1st operand discharged by bcemit_binop_left, but need KNUM/KSHORT. */ |
750 | lua_assert(isnumK(e1) || e1->k == VNONRELOC); | 727 | lua_assert(expr_isnumk(e1) || e1->k == VNONRELOC); |
751 | exp2val(fs, e1); | 728 | expr_toval(fs, e1); |
752 | /* avoid two consts to satisfy bytecode constraints */ | 729 | /* Avoid two consts to satisfy bytecode constraints. */ |
753 | if (isnumK(e1) && !isnumK(e2) && (t = numK(fs, e1)) <= BCMAX_B) { | 730 | if (expr_isnumk(e1) && !expr_isnumk(e2) && |
731 | (t = const_num(fs, e1)) <= BCMAX_B) { | ||
754 | rb = rc; rc = t; op -= BC_ADDVV-BC_ADDNV; | 732 | rb = rc; rc = t; op -= BC_ADDVV-BC_ADDNV; |
755 | } else { | 733 | } else { |
756 | rb = exp2anyreg(fs, e1); | 734 | rb = expr_toanyreg(fs, e1); |
757 | } | 735 | } |
758 | } | 736 | } |
759 | /* using freeexp might cause asserts if the order is wrong */ | 737 | /* Using expr_free might cause asserts if the order is wrong. */ |
760 | if (e1->k == VNONRELOC && e1->u.s.info >= fs->nactvar) fs->freereg--; | 738 | if (e1->k == VNONRELOC && e1->u.s.info >= fs->nactvar) fs->freereg--; |
761 | if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--; | 739 | if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--; |
762 | e1->u.s.info = emitABC(fs, op, 0, rb, rc); | 740 | e1->u.s.info = bcemit_ABC(fs, op, 0, rb, rc); |
763 | e1->k = VRELOCABLE; | 741 | e1->k = VRELOCABLE; |
764 | } | 742 | } |
765 | 743 | ||
766 | static void codecomp(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2) | 744 | /* Emit comparison operator. */ |
745 | static void bcemit_comp(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2) | ||
767 | { | 746 | { |
768 | ExpDesc *eret = e1; | 747 | ExpDesc *eret = e1; |
769 | BCIns ins; | 748 | BCIns ins; |
770 | exp2val(fs, e1); | 749 | expr_toval(fs, e1); |
771 | if (opr == OPR_EQ || opr == OPR_NE) { | 750 | if (opr == OPR_EQ || opr == OPR_NE) { |
772 | BCOp op = opr == OPR_EQ ? BC_ISEQV : BC_ISNEV; | 751 | BCOp op = opr == OPR_EQ ? BC_ISEQV : BC_ISNEV; |
773 | BCReg ra; | 752 | BCReg ra; |
774 | if (isK(e1)) { e1 = e2; e2 = eret; } /* need constant in 2nd arg */ | 753 | if (expr_isk(e1)) { e1 = e2; e2 = eret; } /* Need constant in 2nd arg. */ |
775 | ra = exp2anyreg(fs, e1); /* first arg must be in a reg */ | 754 | ra = expr_toanyreg(fs, e1); /* First arg must be in a reg. */ |
776 | exp2val(fs, e2); | 755 | expr_toval(fs, e2); |
777 | switch (e2->k) { | 756 | switch (e2->k) { |
778 | case VKNIL: case VKFALSE: case VKTRUE: | 757 | case VKNIL: case VKFALSE: case VKTRUE: |
779 | ins = BCINS_AD(op+(BC_ISEQP-BC_ISEQV), ra, priK(e2)); | 758 | ins = BCINS_AD(op+(BC_ISEQP-BC_ISEQV), ra, const_pri(e2)); |
780 | break; | 759 | break; |
781 | case VKSTR: | 760 | case VKSTR: |
782 | ins = BCINS_AD(op+(BC_ISEQS-BC_ISEQV), ra, strK(fs, e2)); | 761 | ins = BCINS_AD(op+(BC_ISEQS-BC_ISEQV), ra, const_str(fs, e2)); |
783 | break; | 762 | break; |
784 | case VKNUM: | 763 | case VKNUM: |
785 | ins = BCINS_AD(op+(BC_ISEQN-BC_ISEQV), ra, numK(fs, e2)); | 764 | ins = BCINS_AD(op+(BC_ISEQN-BC_ISEQV), ra, const_num(fs, e2)); |
786 | break; | 765 | break; |
787 | default: | 766 | default: |
788 | ins = BCINS_AD(op, ra, exp2anyreg(fs, e2)); | 767 | ins = BCINS_AD(op, ra, expr_toanyreg(fs, e2)); |
789 | break; | 768 | break; |
790 | } | 769 | } |
791 | } else { | 770 | } else { |
792 | uint32_t op = opr-OPR_LT+BC_ISLT; | 771 | uint32_t op = opr-OPR_LT+BC_ISLT; |
793 | BCReg ra; | 772 | BCReg ra; |
794 | if ((op-BC_ISLT) & 1) { /* GT -> LT, GE -> LE */ | 773 | if ((op-BC_ISLT) & 1) { /* GT -> LT, GE -> LE */ |
795 | e1 = e2; e2 = eret; /* swap operands */ | 774 | e1 = e2; e2 = eret; /* Swap operands. */ |
796 | op = ((op-BC_ISLT)^3)+BC_ISLT; | 775 | op = ((op-BC_ISLT)^3)+BC_ISLT; |
797 | } | 776 | } |
798 | ra = exp2anyreg(fs, e1); | 777 | ra = expr_toanyreg(fs, e1); |
799 | ins = BCINS_AD(op, ra, exp2anyreg(fs, e2)); | 778 | ins = BCINS_AD(op, ra, expr_toanyreg(fs, e2)); |
800 | } | 779 | } |
801 | /* using freeexp might cause asserts if the order is wrong */ | 780 | /* Using expr_free might cause asserts if the order is wrong. */ |
802 | if (e1->k == VNONRELOC && e1->u.s.info >= fs->nactvar) fs->freereg--; | 781 | if (e1->k == VNONRELOC && e1->u.s.info >= fs->nactvar) fs->freereg--; |
803 | if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--; | 782 | if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--; |
804 | emitINS(fs, ins); | 783 | bcemit_INS(fs, ins); |
805 | eret->u.s.info = emit_jump(fs); | 784 | eret->u.s.info = bcemit_jmp(fs); |
806 | eret->k = VJMP; | 785 | eret->k = VJMP; |
807 | } | 786 | } |
808 | 787 | ||
809 | static void emit_unop(FuncState *fs, UnOpr uop, ExpDesc *e) | 788 | /* Fixup left side of binary operator. */ |
810 | { | 789 | static void bcemit_binop_left(FuncState *fs, BinOpr op, ExpDesc *e) |
811 | BCOp op = BC_LEN; | ||
812 | switch (uop) { | ||
813 | case OPR_MINUS: | ||
814 | if (isnumKexp(e) && expnumV(e) != 0) { /* Avoid const-folding to -0. */ | ||
815 | setnumV(&e->u.nval, -expnumV(e)); | ||
816 | return; | ||
817 | } | ||
818 | op = BC_UNM; | ||
819 | /* fallthrough */ | ||
820 | case OPR_LEN: | ||
821 | exp2anyreg(fs, e); | ||
822 | break; | ||
823 | case OPR_NOT: | ||
824 | /* interchange true and false lists */ | ||
825 | { BCPos temp = e->f; e->f = e->t; e->t = temp; } | ||
826 | removevalues(fs, e->f); | ||
827 | removevalues(fs, e->t); | ||
828 | dischargevars(fs, e); | ||
829 | switch (e->k) { | ||
830 | case VKNIL: case VKFALSE: | ||
831 | e->k = VKTRUE; | ||
832 | return; | ||
833 | case VKSTR: case VKNUM: case VKTRUE: | ||
834 | e->k = VKFALSE; | ||
835 | return; | ||
836 | case VJMP: | ||
837 | invertjump(fs, e); | ||
838 | return; | ||
839 | case VRELOCABLE: | ||
840 | reserveregs(fs, 1); | ||
841 | setbc_a(bcptr(fs, e), fs->freereg-1); | ||
842 | e->u.s.info = fs->freereg-1; | ||
843 | e->k = VNONRELOC; | ||
844 | break; | ||
845 | case VNONRELOC: | ||
846 | break; | ||
847 | default: lua_assert(0); return; | ||
848 | } | ||
849 | op = BC_NOT; | ||
850 | break; | ||
851 | default: lua_assert(0); return; | ||
852 | } | ||
853 | freeexp(fs, e); | ||
854 | e->u.s.info = emitAD(fs, op, 0, e->u.s.info); | ||
855 | e->k = VRELOCABLE; | ||
856 | } | ||
857 | |||
858 | static void prepare_binop(FuncState *fs, BinOpr op, ExpDesc *e) | ||
859 | { | 790 | { |
860 | switch (op) { | 791 | if (op == OPR_AND) { |
861 | case OPR_AND: | 792 | bcemit_branch_t(fs, e); |
862 | goiftrue(fs, e); | 793 | } else if (op == OPR_OR) { |
863 | break; | 794 | bcemit_branch_f(fs, e); |
864 | case OPR_OR: | 795 | } else if (op == OPR_CONCAT) { |
865 | goiffalse(fs, e); | 796 | expr_tonextreg(fs, e); |
866 | break; | 797 | } else if (op == OPR_EQ || op == OPR_NE) { |
867 | case OPR_CONCAT: | 798 | if (!expr_isk_nojump(e)) expr_toanyreg(fs, e); |
868 | exp2nextreg(fs, e); /* operand must be on the `stack' */ | 799 | } else { |
869 | break; | 800 | if (!expr_isnumk_nojump(e)) expr_toanyreg(fs, e); |
870 | case OPR_EQ: case OPR_NE: | ||
871 | if (!isKexp(e)) exp2anyreg(fs, e); | ||
872 | break; | ||
873 | default: | ||
874 | if (!isnumKexp(e)) exp2anyreg(fs, e); | ||
875 | break; | ||
876 | } | 801 | } |
877 | } | 802 | } |
878 | 803 | ||
879 | static void emit_binop(FuncState *fs, BinOpr op, ExpDesc *e1, ExpDesc *e2) | 804 | /* Emit binary operator. */ |
805 | static void bcemit_binop(FuncState *fs, BinOpr op, ExpDesc *e1, ExpDesc *e2) | ||
880 | { | 806 | { |
881 | switch (op) { | 807 | if (op <= OPR_POW) { |
882 | case OPR_AND: | 808 | bcemit_arith(fs, op, e1, e2); |
883 | lua_assert(e1->t == NO_JMP); /* list must be closed */ | 809 | } else if (op == OPR_AND) { |
884 | dischargevars(fs, e2); | 810 | lua_assert(e1->t == NO_JMP); /* List must be closed. */ |
885 | concatjumps(fs, &e2->f, e1->f); | 811 | expr_discharge(fs, e2); |
812 | jmp_append(fs, &e2->f, e1->f); | ||
886 | *e1 = *e2; | 813 | *e1 = *e2; |
887 | break; | 814 | } else if (op == OPR_OR) { |
888 | case OPR_OR: | 815 | lua_assert(e1->f == NO_JMP); /* List must be closed. */ |
889 | lua_assert(e1->f == NO_JMP); /* list must be closed */ | 816 | expr_discharge(fs, e2); |
890 | dischargevars(fs, e2); | 817 | jmp_append(fs, &e2->t, e1->t); |
891 | concatjumps(fs, &e2->t, e1->t); | ||
892 | *e1 = *e2; | 818 | *e1 = *e2; |
893 | break; | 819 | } else if (op == OPR_CONCAT) { |
894 | case OPR_CONCAT: | 820 | expr_toval(fs, e2); |
895 | exp2val(fs, e2); | ||
896 | if (e2->k == VRELOCABLE && bc_op(*bcptr(fs, e2)) == BC_CAT) { | 821 | if (e2->k == VRELOCABLE && bc_op(*bcptr(fs, e2)) == BC_CAT) { |
897 | lua_assert(e1->u.s.info == bc_b(*bcptr(fs, e2))-1); | 822 | lua_assert(e1->u.s.info == bc_b(*bcptr(fs, e2))-1); |
898 | freeexp(fs, e1); | 823 | expr_free(fs, e1); |
899 | setbc_b(bcptr(fs, e2), e1->u.s.info); | 824 | setbc_b(bcptr(fs, e2), e1->u.s.info); |
900 | e1->u.s.info = e2->u.s.info; | 825 | e1->u.s.info = e2->u.s.info; |
901 | } else { | 826 | } else { |
902 | exp2nextreg(fs, e2); | 827 | expr_tonextreg(fs, e2); |
903 | freeexp(fs, e2); | 828 | expr_free(fs, e2); |
904 | freeexp(fs, e1); | 829 | expr_free(fs, e1); |
905 | e1->u.s.info = emitABC(fs, BC_CAT, 0, e1->u.s.info, e2->u.s.info); | 830 | e1->u.s.info = bcemit_ABC(fs, BC_CAT, 0, e1->u.s.info, e2->u.s.info); |
906 | } | 831 | } |
907 | e1->k = VRELOCABLE; | 832 | e1->k = VRELOCABLE; |
908 | break; | 833 | } else { |
909 | case OPR_ADD: case OPR_SUB: case OPR_MUL: | 834 | lua_assert(op == OPR_NE || op == OPR_EQ || |
910 | case OPR_DIV: case OPR_MOD: case OPR_POW: | 835 | op == OPR_LT || op == OPR_GE || op == OPR_LE || op == OPR_GT); |
911 | codearith(fs, op, e1, e2); | 836 | bcemit_comp(fs, op, e1, e2); |
912 | break; | 837 | } |
913 | case OPR_EQ: case OPR_NE: | 838 | } |
914 | case OPR_LT: case OPR_LE: case OPR_GT: case OPR_GE: | 839 | |
915 | codecomp(fs, op, e1, e2); | 840 | /* Emit unary operator. */ |
916 | break; | 841 | static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e) |
917 | default: lua_assert(0); break; | 842 | { |
843 | if (op == BC_NOT) { | ||
844 | /* Swap true and false lists. */ | ||
845 | { BCPos temp = e->f; e->f = e->t; e->t = temp; } | ||
846 | jmp_dropval(fs, e->f); | ||
847 | jmp_dropval(fs, e->t); | ||
848 | expr_discharge(fs, e); | ||
849 | if (e->k == VKNIL || e->k == VKFALSE) { | ||
850 | e->k = VKTRUE; | ||
851 | return; | ||
852 | } else if (expr_isk(e)) { | ||
853 | e->k = VKFALSE; | ||
854 | return; | ||
855 | } else if (e->k == VJMP) { | ||
856 | invertcond(fs, e); | ||
857 | return; | ||
858 | } else if (e->k == VRELOCABLE) { | ||
859 | bcreg_reserve(fs, 1); | ||
860 | setbc_a(bcptr(fs, e), fs->freereg-1); | ||
861 | e->u.s.info = fs->freereg-1; | ||
862 | e->k = VNONRELOC; | ||
863 | } else { | ||
864 | lua_assert(e->k == VNONRELOC); | ||
865 | } | ||
866 | } else { | ||
867 | lua_assert(op == BC_UNM || op == BC_LEN); | ||
868 | /* Constant-fold negations. But avoid folding to -0. */ | ||
869 | if (op == BC_UNM && expr_isnumk_nojump(e) && expr_numV(e) != 0) { | ||
870 | setnumV(&e->u.nval, -expr_numV(e)); | ||
871 | return; | ||
872 | } | ||
873 | expr_toanyreg(fs, e); | ||
918 | } | 874 | } |
875 | expr_free(fs, e); | ||
876 | e->u.s.info = bcemit_AD(fs, op, 0, e->u.s.info); | ||
877 | e->k = VRELOCABLE; | ||
919 | } | 878 | } |
920 | 879 | ||
921 | /* -- Lexer support ------------------------------------------------------- */ | 880 | /* -- Lexer support ------------------------------------------------------- */ |
922 | 881 | ||
923 | static int testnext(LexState *ls, LexToken tok) | 882 | /* Check and consume optional token. */ |
883 | static int lex_opt(LexState *ls, LexToken tok) | ||
924 | { | 884 | { |
925 | if (ls->token == tok) { | 885 | if (ls->token == tok) { |
926 | lj_lex_next(ls); | 886 | lj_lex_next(ls); |
@@ -929,16 +889,18 @@ static int testnext(LexState *ls, LexToken tok) | |||
929 | return 0; | 889 | return 0; |
930 | } | 890 | } |
931 | 891 | ||
932 | static void checknext(LexState *ls, LexToken tok) | 892 | /* Check and consume token. */ |
893 | static void lex_check(LexState *ls, LexToken tok) | ||
933 | { | 894 | { |
934 | if (ls->token != tok) | 895 | if (ls->token != tok) |
935 | err_token(ls, tok); | 896 | err_token(ls, tok); |
936 | lj_lex_next(ls); | 897 | lj_lex_next(ls); |
937 | } | 898 | } |
938 | 899 | ||
939 | static void checkmatch(LexState *ls, LexToken what, LexToken who, BCLine line) | 900 | /* Check for matching token. */ |
901 | static void lex_match(LexState *ls, LexToken what, LexToken who, BCLine line) | ||
940 | { | 902 | { |
941 | if (!testnext(ls, what)) { | 903 | if (!lex_opt(ls, what)) { |
942 | if (line == ls->linenumber) { | 904 | if (line == ls->linenumber) { |
943 | err_token(ls, what); | 905 | err_token(ls, what); |
944 | } else { | 906 | } else { |
@@ -949,7 +911,8 @@ static void checkmatch(LexState *ls, LexToken what, LexToken who, BCLine line) | |||
949 | } | 911 | } |
950 | } | 912 | } |
951 | 913 | ||
952 | static GCstr *str_checkname(LexState *ls) | 914 | /* Check for string token. */ |
915 | static GCstr *lex_str(LexState *ls) | ||
953 | { | 916 | { |
954 | GCstr *s; | 917 | GCstr *s; |
955 | if (ls->token != TK_name) | 918 | if (ls->token != TK_name) |
@@ -959,72 +922,68 @@ static GCstr *str_checkname(LexState *ls) | |||
959 | return s; | 922 | return s; |
960 | } | 923 | } |
961 | 924 | ||
962 | static void init_exp(ExpDesc *e, ExpKind k, uint32_t info) | ||
963 | { | ||
964 | e->k = k; | ||
965 | e->u.s.info = info; | ||
966 | e->f = e->t = NO_JMP; | ||
967 | } | ||
968 | |||
969 | static void checkname(LexState *ls, ExpDesc *e) | ||
970 | { | ||
971 | init_exp(e, VKSTR, 0); | ||
972 | e->u.sval = str_checkname(ls); | ||
973 | } | ||
974 | |||
975 | /* -- Variable handling --------------------------------------------------- */ | 925 | /* -- Variable handling --------------------------------------------------- */ |
976 | 926 | ||
977 | #define getlocvar(fs, i) (proto_varinfo((fs)->pt)[(fs)->actvar[(i)]]) | 927 | #define var_get(fs, i) (proto_varinfo((fs)->pt)[(fs)->varmap[(i)]]) |
978 | 928 | ||
979 | static BCReg registerlocalvar(LexState *ls, GCstr *name) | 929 | /* Define a new local variable. */ |
930 | static void var_new(LexState *ls, BCReg n, GCstr *name) | ||
980 | { | 931 | { |
981 | FuncState *fs = ls->fs; | 932 | FuncState *fs = ls->fs; |
982 | GCproto *pt = fs->pt; | 933 | GCproto *pt = fs->pt; |
983 | VarInfo *varinfo = proto_varinfo(pt); | 934 | VarInfo *varinfo = proto_varinfo(pt); |
984 | if (LJ_UNLIKELY(fs->nlocvars >= pt->sizevarinfo)) { | 935 | checklimit(fs, fs->nactvar+n, LJ_MAX_LOCVAR, "local variables"); |
936 | if (LJ_UNLIKELY(fs->nvarinfo >= pt->sizevarinfo)) { | ||
985 | MSize oldsize = pt->sizevarinfo; | 937 | MSize oldsize = pt->sizevarinfo; |
986 | checklimit(fs, fs->nlocvars, 32767, "local variables"); | 938 | checklimit(fs, fs->nvarinfo, 32767, "local variables"); |
987 | lj_mem_growvec(fs->L, varinfo, pt->sizevarinfo, 32767, VarInfo); | 939 | lj_mem_growvec(fs->L, varinfo, pt->sizevarinfo, 32767, VarInfo); |
988 | setmref(pt->varinfo, varinfo); | 940 | setmref(pt->varinfo, varinfo); |
989 | while (oldsize < pt->sizevarinfo) setgcrefnull(varinfo[oldsize++].name); | 941 | while (oldsize < pt->sizevarinfo) setgcrefnull(varinfo[oldsize++].name); |
990 | } | 942 | } |
991 | setgcref(varinfo[fs->nlocvars].name, obj2gco(name)); | 943 | setgcref(varinfo[fs->nvarinfo].name, obj2gco(name)); |
992 | lj_gc_objbarrier(ls->L, pt, name); | 944 | lj_gc_objbarrier(ls->L, pt, name); |
993 | return fs->nlocvars++; | 945 | fs->varmap[fs->nactvar+n] = (uint16_t)(fs->nvarinfo++); |
994 | } | ||
995 | |||
996 | static void new_localvar(LexState *ls, GCstr *name, BCReg n) | ||
997 | { | ||
998 | FuncState *fs = ls->fs; | ||
999 | checklimit(fs, fs->nactvar+n, LJ_MAX_LOCVAR, "local variables"); | ||
1000 | fs->actvar[fs->nactvar+n] = cast(uint16_t, registerlocalvar(ls, name)); | ||
1001 | } | 946 | } |
1002 | 947 | ||
1003 | #define new_localvarliteral(ls,v,n) \ | 948 | #define var_new_lit(ls, v, n) \ |
1004 | new_localvar(ls, lj_parse_keepstr(ls, "" v, sizeof(v)-1), n) | 949 | var_new(ls, (n), lj_parse_keepstr(ls, "" v, sizeof(v)-1)) |
1005 | 950 | ||
1006 | static void adjustlocalvars(LexState *ls, BCReg nvars) | 951 | /* Add local variables. */ |
952 | static void var_add(LexState *ls, BCReg nvars) | ||
1007 | { | 953 | { |
1008 | FuncState *fs = ls->fs; | 954 | FuncState *fs = ls->fs; |
1009 | fs->nactvar = cast_byte(fs->nactvar + nvars); | 955 | fs->nactvar = cast_byte(fs->nactvar + nvars); |
1010 | for (; nvars; nvars--) | 956 | for (; nvars; nvars--) |
1011 | getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; | 957 | var_get(fs, fs->nactvar - nvars).startpc = fs->pc; |
1012 | } | 958 | } |
1013 | 959 | ||
1014 | static void removevars(LexState *ls, BCReg tolevel) | 960 | /* Remove local variables. */ |
961 | static void var_remove(LexState *ls, BCReg tolevel) | ||
1015 | { | 962 | { |
1016 | FuncState *fs = ls->fs; | 963 | FuncState *fs = ls->fs; |
1017 | while (fs->nactvar > tolevel) | 964 | while (fs->nactvar > tolevel) |
1018 | getlocvar(fs, --fs->nactvar).endpc = fs->pc; | 965 | var_get(fs, --fs->nactvar).endpc = fs->pc; |
1019 | } | 966 | } |
1020 | 967 | ||
1021 | static uint32_t indexupvalue(FuncState *fs, GCstr *name, ExpDesc *v) | 968 | /* Lookup local variable name. */ |
969 | static BCReg var_lookup_local(FuncState *fs, GCstr *n) | ||
970 | { | ||
971 | int i; | ||
972 | for (i = fs->nactvar-1; i >= 0; i--) { | ||
973 | if (n == gco2str(gcref(var_get(fs, i).name))) | ||
974 | return (BCReg)i; | ||
975 | } | ||
976 | return (BCReg)-1; /* Not found. */ | ||
977 | } | ||
978 | |||
979 | /* Lookup upvalue name. */ | ||
980 | static uint32_t var_lookup_uv(FuncState *fs, GCstr *name, ExpDesc *v) | ||
1022 | { | 981 | { |
1023 | uint32_t i; | 982 | uint32_t i; |
1024 | GCproto *pt = fs->pt; | 983 | GCproto *pt = fs->pt; |
1025 | GCRef *uvname; | 984 | GCRef *uvname; |
1026 | for (i = 0; i < fs->nuv; i++) { | 985 | for (i = 0; i < fs->nuv; i++) { |
1027 | if (fs->upvalues[i].info == v->u.s.info && fs->upvalues[i].k == v->k) { | 986 | if (fs->uvloc[i].info == v->u.s.info && fs->uvloc[i].k == v->k) { |
1028 | lua_assert(gco2str(proto_uvname(pt, i)) == name); | 987 | lua_assert(gco2str(proto_uvname(pt, i)) == name); |
1029 | return i; | 988 | return i; |
1030 | } | 989 | } |
@@ -1041,107 +1000,44 @@ static uint32_t indexupvalue(FuncState *fs, GCstr *name, ExpDesc *v) | |||
1041 | setgcref(uvname[fs->nuv], obj2gco(name)); | 1000 | setgcref(uvname[fs->nuv], obj2gco(name)); |
1042 | lj_gc_objbarrier(fs->L, pt, name); | 1001 | lj_gc_objbarrier(fs->L, pt, name); |
1043 | lua_assert(v->k == VLOCAL || v->k == VUPVAL); | 1002 | lua_assert(v->k == VLOCAL || v->k == VUPVAL); |
1044 | fs->upvalues[fs->nuv].k = cast_byte(v->k); | 1003 | fs->uvloc[fs->nuv].k = cast_byte(v->k); |
1045 | fs->upvalues[fs->nuv].info = cast_byte(v->u.s.info); | 1004 | fs->uvloc[fs->nuv].info = cast_byte(v->u.s.info); |
1046 | return fs->nuv++; | 1005 | return fs->nuv++; |
1047 | } | 1006 | } |
1048 | 1007 | ||
1049 | static BCReg searchvar(FuncState *fs, GCstr *n) | 1008 | /* Forward declaration. */ |
1050 | { | 1009 | static void scope_uvmark(FuncState *fs, BCReg level); |
1051 | int i; | ||
1052 | for (i = fs->nactvar-1; i >= 0; i--) { | ||
1053 | if (n == gco2str(gcref(getlocvar(fs, i).name))) | ||
1054 | return (BCReg)i; | ||
1055 | } | ||
1056 | return (BCReg)-1; /* Not found. */ | ||
1057 | } | ||
1058 | |||
1059 | static void markupval(FuncState *fs, BCReg level) | ||
1060 | { | ||
1061 | FuncBlock *bl = fs->bl; | ||
1062 | while (bl && bl->nactvar > level) bl = bl->previous; | ||
1063 | if (bl) bl->upval = 1; | ||
1064 | } | ||
1065 | 1010 | ||
1066 | static int singlevaraux(FuncState *fs, GCstr *name, ExpDesc *e, int first) | 1011 | /* Recursively lookup variables in enclosing functions. */ |
1012 | static int var_lookup_(FuncState *fs, GCstr *name, ExpDesc *e, int first) | ||
1067 | { | 1013 | { |
1068 | if (fs == NULL) { /* no more levels? */ | 1014 | if (fs) { |
1069 | init_exp(e, VGLOBAL, 0); /* default is global variable */ | 1015 | BCReg reg = var_lookup_local(fs, name); |
1070 | e->u.sval = name; | 1016 | if ((int32_t)reg >= 0) { /* Local in this function? */ |
1071 | return 1; | 1017 | expr_init(e, VLOCAL, reg); |
1072 | } else { | ||
1073 | BCReg reg = searchvar(fs, name); /* look up at current level */ | ||
1074 | if ((int32_t)reg >= 0) { | ||
1075 | init_exp(e, VLOCAL, reg); | ||
1076 | if (!first) | 1018 | if (!first) |
1077 | markupval(fs, reg); /* local will be used as an upval */ | 1019 | scope_uvmark(fs, reg); /* Scope now has an upvalue. */ |
1078 | return 0; | 1020 | return 1; |
1079 | } else { /* not found at current level; try upper one */ | 1021 | } else if (var_lookup_(fs->prev, name, e, 0)) { /* In outer function? */ |
1080 | if (singlevaraux(fs->prev, name, e, 0)) /* global? */ | 1022 | e->u.s.info = var_lookup_uv(fs, name, e); /* Make it an upvalue here. */ |
1081 | return 1; | 1023 | e->k = VUPVAL; |
1082 | e->u.s.info = indexupvalue(fs, name, e); /* else was local or upvalue */ | 1024 | return 1; |
1083 | e->k = VUPVAL; /* upvalue in this level */ | ||
1084 | return 0; | ||
1085 | } | ||
1086 | } | ||
1087 | } | ||
1088 | |||
1089 | #define singlevar(ls, e) singlevaraux((ls)->fs, str_checkname(ls), (e), 1) | ||
1090 | |||
1091 | static void adjust_assign(LexState *ls, BCReg nvars, BCReg nexps, ExpDesc *e) | ||
1092 | { | ||
1093 | FuncState *fs = ls->fs; | ||
1094 | int32_t extra = (int32_t)nvars - (int32_t)nexps; | ||
1095 | if (e->k == VCALL) { | ||
1096 | extra++; /* includes call itself */ | ||
1097 | if (extra < 0) extra = 0; | ||
1098 | setbc_b(bcptr(fs, e), extra+1); | ||
1099 | if (extra > 1) reserveregs(fs, (BCReg)extra-1); | ||
1100 | } else { | ||
1101 | if (e->k != VVOID) exp2nextreg(fs, e); /* close last expression */ | ||
1102 | if (extra > 0) { | ||
1103 | BCReg reg = fs->freereg; | ||
1104 | reserveregs(fs, (BCReg)extra); | ||
1105 | nilK(fs, reg, (BCReg)extra); | ||
1106 | } | 1025 | } |
1026 | } else { /* Not found in any function, must be a global. */ | ||
1027 | expr_init(e, VGLOBAL, 0); | ||
1028 | e->u.sval = name; | ||
1107 | } | 1029 | } |
1030 | return 0; /* Global. */ | ||
1108 | } | 1031 | } |
1109 | 1032 | ||
1110 | /* -- Function handling --------------------------------------------------- */ | 1033 | /* Lookup variable name. */ |
1034 | #define var_lookup(ls, e) \ | ||
1035 | var_lookup_((ls)->fs, lex_str(ls), (e), 1) | ||
1111 | 1036 | ||
1112 | /* Forward declaration. */ | 1037 | /* -- Function state management ------------------------------------------- */ |
1113 | static void chunk(LexState *ls); | ||
1114 | |||
1115 | static void open_func(LexState *ls, FuncState *fs) | ||
1116 | { | ||
1117 | lua_State *L = ls->L; | ||
1118 | GCproto *pt = lj_func_newproto(L); | ||
1119 | fs->pt = pt; | ||
1120 | fs->prev = ls->fs; /* linked list of funcstates */ | ||
1121 | fs->ls = ls; | ||
1122 | fs->L = L; | ||
1123 | ls->fs = fs; | ||
1124 | fs->pc = 0; | ||
1125 | fs->lasttarget = 0; | ||
1126 | fs->jpc = NO_JMP; | ||
1127 | fs->freereg = 0; | ||
1128 | fs->nkgc = 0; | ||
1129 | fs->nkn = 0; | ||
1130 | fs->nlocvars = 0; | ||
1131 | fs->nactvar = 0; | ||
1132 | fs->nuv = 0; | ||
1133 | fs->bl = NULL; | ||
1134 | setgcref(pt->chunkname, obj2gco(ls->chunkname)); | ||
1135 | pt->framesize = 2; /* registers 0/1 are always valid */ | ||
1136 | fs->kt = lj_tab_new(L, 0, 0); | ||
1137 | /* anchor table of constants and prototype (to avoid being collected) */ | ||
1138 | settabV(L, L->top, fs->kt); | ||
1139 | incr_top(L); | ||
1140 | setprotoV(L, L->top, pt); | ||
1141 | incr_top(L); | ||
1142 | } | ||
1143 | 1038 | ||
1144 | static void collectk(FuncState *fs, GCproto *pt) | 1039 | /* Fixup constants for prototype. */ |
1040 | static void fs_fixup_k(FuncState *fs, GCproto *pt) | ||
1145 | { | 1041 | { |
1146 | GCtab *kt; | 1042 | GCtab *kt; |
1147 | TValue *array; | 1043 | TValue *array; |
@@ -1181,36 +1077,43 @@ static void collectk(FuncState *fs, GCproto *pt) | |||
1181 | } | 1077 | } |
1182 | } | 1078 | } |
1183 | 1079 | ||
1184 | static void collectuv(FuncState *fs, GCproto *pt) | 1080 | /* Fixup upvalues for prototype. */ |
1081 | static void fs_fixup_uv(FuncState *fs, GCproto *pt) | ||
1185 | { | 1082 | { |
1186 | uint32_t i; | 1083 | uint32_t i; |
1187 | uint16_t *uv = lj_mem_newvec(fs->L, fs->nuv, uint16_t); | 1084 | uint16_t *uv = lj_mem_newvec(fs->L, fs->nuv, uint16_t); |
1188 | setmref(pt->uv, uv); | 1085 | setmref(pt->uv, uv); |
1189 | pt->sizeuv = fs->nuv; | 1086 | pt->sizeuv = fs->nuv; |
1190 | for (i = 0; i < pt->sizeuv; i++) { | 1087 | for (i = 0; i < pt->sizeuv; i++) { |
1191 | uint32_t v = fs->upvalues[i].info; | 1088 | uint32_t v = fs->uvloc[i].info; |
1192 | if (fs->upvalues[i].k == VLOCAL) v |= 0x8000; | 1089 | if (fs->uvloc[i].k == VLOCAL) v |= 0x8000; |
1193 | uv[i] = (uint16_t)v; | 1090 | uv[i] = (uint16_t)v; |
1194 | } | 1091 | } |
1195 | } | 1092 | } |
1196 | 1093 | ||
1197 | static void finalret(FuncState *fs, GCproto *pt) | 1094 | /* Check if bytecode op returns. */ |
1095 | static int bcopisret(BCOp op) | ||
1096 | { | ||
1097 | switch (op) { | ||
1098 | case BC_CALLMT: case BC_CALLT: | ||
1099 | case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1: | ||
1100 | return 1; | ||
1101 | default: | ||
1102 | return 0; | ||
1103 | } | ||
1104 | } | ||
1105 | |||
1106 | /* Fixup return instruction for prototype. */ | ||
1107 | static void fs_fixup_ret(FuncState *fs, GCproto *pt) | ||
1198 | { | 1108 | { |
1199 | BCPos lastpc = fs->pc; | 1109 | BCPos lastpc = fs->pc; |
1200 | if (lastpc > fs->lasttarget) { | 1110 | if (lastpc <= fs->lasttarget || !bcopisret(bc_op(proto_ins(pt, lastpc-1)))) { |
1201 | switch (bc_op(proto_ins(pt, lastpc-1))) { | 1111 | if (fs->flags & PROTO_HAS_FNEW) |
1202 | case BC_CALLMT: case BC_CALLT: | 1112 | bcemit_AJ(fs, BC_UCLO, 0, 0); |
1203 | case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1: | 1113 | bcemit_AD(fs, BC_RET0, 0, 1); /* Need final return. */ |
1204 | goto suppress_return; /* already got a return */ | ||
1205 | default: break; | ||
1206 | } | ||
1207 | } | 1114 | } |
1208 | if (fs->pt->flags & PROTO_HAS_FNEW) | ||
1209 | emitAJ(fs, BC_UCLO, 0, 0); | ||
1210 | emitAD(fs, BC_RET0, 0, 1); /* final return */ | ||
1211 | suppress_return: | ||
1212 | /* May need to fixup returns encoded before first function was created. */ | 1115 | /* May need to fixup returns encoded before first function was created. */ |
1213 | if (fs->pt->flags & PROTO_FIXUP_RETURN) { | 1116 | if (fs->flags & PROTO_FIXUP_RETURN) { |
1214 | BCPos pc; | 1117 | BCPos pc; |
1215 | for (pc = 0; pc < lastpc; pc++) { | 1118 | for (pc = 0; pc < lastpc; pc++) { |
1216 | BCIns i = proto_ins(pt, pc); | 1119 | BCIns i = proto_ins(pt, pc); |
@@ -1218,20 +1121,23 @@ suppress_return: | |||
1218 | switch (bc_op(i)) { | 1121 | switch (bc_op(i)) { |
1219 | case BC_CALLMT: case BC_CALLT: | 1122 | case BC_CALLMT: case BC_CALLT: |
1220 | case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1: | 1123 | case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1: |
1221 | offset = emitINS(fs, i)-(pc+1)+BCBIAS_J; /* Copy return ins. */ | 1124 | offset = bcemit_INS(fs, i)-(pc+1)+BCBIAS_J; /* Copy return ins. */ |
1222 | if (offset > BCMAX_D) | 1125 | if (offset > BCMAX_D) |
1223 | err_syntax(fs->ls, LJ_ERR_XFIXUP); | 1126 | err_syntax(fs->ls, LJ_ERR_XFIXUP); |
1224 | /* Replace with UCLO plus branch. */ | 1127 | /* Replace with UCLO plus branch. */ |
1225 | *proto_insptr(pt, pc) = BCINS_AD(BC_UCLO, 0, offset); | 1128 | *proto_insptr(pt, pc) = BCINS_AD(BC_UCLO, 0, offset); |
1226 | break; | 1129 | break; |
1227 | case BC_UCLO: return; /* We're done. */ | 1130 | case BC_UCLO: |
1228 | default: break; | 1131 | return; /* We're done. */ |
1132 | default: | ||
1133 | break; | ||
1229 | } | 1134 | } |
1230 | } | 1135 | } |
1231 | } | 1136 | } |
1232 | } | 1137 | } |
1233 | 1138 | ||
1234 | static void close_func(LexState *ls) | 1139 | /* Finish a FuncState and return the new prototype. */ |
1140 | static GCproto *fs_finish(LexState *ls, BCLine line) | ||
1235 | { | 1141 | { |
1236 | lua_State *L = ls->L; | 1142 | lua_State *L = ls->L; |
1237 | FuncState *fs = ls->fs; | 1143 | FuncState *fs = ls->fs; |
@@ -1240,161 +1146,225 @@ static void close_func(LexState *ls) | |||
1240 | GCRef *uvname; | 1146 | GCRef *uvname; |
1241 | BCLine *lineinfo; | 1147 | BCLine *lineinfo; |
1242 | VarInfo *varinfo; | 1148 | VarInfo *varinfo; |
1243 | removevars(ls, 0); | 1149 | |
1244 | finalret(fs, pt); | 1150 | /* Apply final fixups. */ |
1151 | var_remove(ls, 0); | ||
1152 | fs_fixup_ret(fs, pt); | ||
1153 | |||
1154 | /* Reallocate arrays. */ | ||
1245 | bc = proto_bc(pt); | 1155 | bc = proto_bc(pt); |
1246 | lj_mem_reallocvec(L, bc, pt->sizebc, fs->pc, BCIns); | 1156 | lj_mem_reallocvec(L, bc, pt->sizebc, fs->pc, BCIns); |
1247 | setmref(pt->bc, bc); | 1157 | setmref(pt->bc, bc); |
1248 | pt->sizebc = fs->pc; | 1158 | pt->sizebc = fs->pc; |
1249 | collectk(fs, pt); | 1159 | fs_fixup_k(fs, pt); |
1250 | collectuv(fs, pt); | 1160 | fs_fixup_uv(fs, pt); |
1251 | lineinfo = proto_lineinfo(pt); | 1161 | lineinfo = proto_lineinfo(pt); |
1252 | lj_mem_reallocvec(L, lineinfo, pt->sizelineinfo, fs->pc, BCLine); | 1162 | lj_mem_reallocvec(L, lineinfo, pt->sizelineinfo, fs->pc, BCLine); |
1253 | setmref(pt->lineinfo, lineinfo); | 1163 | setmref(pt->lineinfo, lineinfo); |
1254 | pt->sizelineinfo = fs->pc; | 1164 | pt->sizelineinfo = fs->pc; |
1255 | varinfo = proto_varinfo(pt); | 1165 | varinfo = proto_varinfo(pt); |
1256 | lj_mem_reallocvec(L, varinfo, pt->sizevarinfo, fs->nlocvars, VarInfo); | 1166 | lj_mem_reallocvec(L, varinfo, pt->sizevarinfo, fs->nvarinfo, VarInfo); |
1257 | setmref(pt->varinfo, varinfo); | 1167 | setmref(pt->varinfo, varinfo); |
1258 | pt->sizevarinfo = fs->nlocvars; | 1168 | pt->sizevarinfo = fs->nvarinfo; |
1259 | uvname = mref(pt->uvname, GCRef); | 1169 | uvname = mref(pt->uvname, GCRef); |
1260 | lj_mem_reallocvec(L, uvname, pt->sizeuvname, fs->nuv, GCRef); | 1170 | lj_mem_reallocvec(L, uvname, pt->sizeuvname, fs->nuv, GCRef); |
1261 | setmref(pt->uvname, uvname); | 1171 | setmref(pt->uvname, uvname); |
1262 | pt->sizeuvname = fs->nuv; | 1172 | pt->sizeuvname = fs->nuv; |
1263 | lua_assert(fs->bl == NULL); | 1173 | lua_assert(fs->bl == NULL); |
1174 | |||
1175 | /* Initialize prototype fields. */ | ||
1176 | pt->flags = fs->flags; | ||
1177 | pt->framesize = fs->framesize; | ||
1178 | pt->linedefined = fs->linedefined; | ||
1179 | pt->lastlinedefined = line; | ||
1180 | |||
1264 | lj_vmevent_send(L, BC, | 1181 | lj_vmevent_send(L, BC, |
1265 | setprotoV(L, L->top++, pt); | 1182 | setprotoV(L, L->top++, pt); |
1266 | ); | 1183 | ); |
1184 | |||
1185 | /* Remove FuncState from list. Pop const table and prototype. */ | ||
1267 | ls->fs = fs->prev; | 1186 | ls->fs = fs->prev; |
1268 | L->top -= 2; /* Remove table and prototype from the stack. */ | 1187 | L->top -= 2; |
1269 | lua_assert(ls->fs != NULL || ls->token == TK_eof); | 1188 | lua_assert(ls->fs != NULL || ls->token == TK_eof); |
1270 | keep_token(ls); /* Re-anchor last token. */ | 1189 | /* Re-anchor last string token to avoid GC. */ |
1190 | if (ls->token == TK_name || ls->token == TK_string) { | ||
1191 | TValue *tv = lj_tab_setstr(ls->L, ls->fs->kt, strV(&ls->tokenval)); | ||
1192 | if (tvisnil(tv)) setboolV(tv, 1); | ||
1193 | } | ||
1194 | return pt; | ||
1271 | } | 1195 | } |
1272 | 1196 | ||
1273 | GCproto *lj_parse(LexState *ls) | 1197 | /* Initialize a new FuncState. */ |
1198 | static void fs_init(LexState *ls, FuncState *fs, BCLine line) | ||
1274 | { | 1199 | { |
1275 | struct FuncState fs; | 1200 | lua_State *L = ls->L; |
1276 | ls->level = 0; | 1201 | GCproto *pt = lj_func_newproto(L); |
1277 | open_func(ls, &fs); | 1202 | fs->pt = pt; |
1278 | fs.pt->flags |= PROTO_IS_VARARG; /* Main chunk is always a vararg func. */ | 1203 | fs->prev = ls->fs; ls->fs = fs; /* Append to list. */ |
1279 | lj_lex_next(ls); /* Read-ahead first token. */ | 1204 | fs->ls = ls; |
1280 | chunk(ls); | 1205 | fs->L = L; |
1281 | if (ls->token != TK_eof) | 1206 | fs->pc = 0; |
1282 | err_token(ls, TK_eof); | 1207 | fs->lasttarget = 0; |
1283 | fs.pt->lastlinedefined = ls->linenumber; | 1208 | fs->jpc = NO_JMP; |
1284 | close_func(ls); | 1209 | fs->freereg = 0; |
1285 | lua_assert(fs.prev == NULL); | 1210 | fs->nkgc = 0; |
1286 | lua_assert(fs.pt->sizeuv == 0); | 1211 | fs->nkn = 0; |
1287 | lua_assert(ls->fs == NULL); | 1212 | fs->nvarinfo = 0; |
1288 | return fs.pt; | 1213 | fs->nactvar = 0; |
1214 | fs->nuv = 0; | ||
1215 | fs->bl = NULL; | ||
1216 | setgcref(pt->chunkname, obj2gco(ls->chunkname)); | ||
1217 | fs->flags = 0; | ||
1218 | fs->framesize = 2; /* Minimum frame size. */ | ||
1219 | fs->linedefined = line; | ||
1220 | fs->kt = lj_tab_new(L, 0, 0); | ||
1221 | /* Anchor table of constants and prototype (to avoid being collected). */ | ||
1222 | settabV(L, L->top, fs->kt); | ||
1223 | incr_top(L); | ||
1224 | setprotoV(L, L->top, pt); | ||
1225 | incr_top(L); | ||
1289 | } | 1226 | } |
1290 | 1227 | ||
1291 | /* -- Expressions --------------------------------------------------------- */ | 1228 | /* -- Expressions --------------------------------------------------------- */ |
1292 | 1229 | ||
1293 | /* forward declaration */ | 1230 | /* Forward declaration. */ |
1294 | static void expr(LexState *ls, ExpDesc *v); | 1231 | static void expr(LexState *ls, ExpDesc *v); |
1295 | 1232 | ||
1296 | static void field(LexState *ls, ExpDesc *v) | 1233 | /* Return string expression. */ |
1234 | static void expr_str(LexState *ls, ExpDesc *e) | ||
1235 | { | ||
1236 | expr_init(e, VKSTR, 0); | ||
1237 | e->u.sval = lex_str(ls); | ||
1238 | } | ||
1239 | |||
1240 | /* Return index expression. */ | ||
1241 | static void expr_index(FuncState *fs, ExpDesc *t, ExpDesc *e) | ||
1242 | { | ||
1243 | /* Already called: expr_toval(fs, e). */ | ||
1244 | t->k = VINDEXED; | ||
1245 | if (expr_isnumk(e)) { | ||
1246 | lua_Number n = expr_numV(e); | ||
1247 | int32_t k = lj_num2int(n); | ||
1248 | if (checku8(k) && n == cast_num(k)) { | ||
1249 | t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */ | ||
1250 | return; | ||
1251 | } | ||
1252 | } else if (expr_isstrk(e)) { | ||
1253 | BCReg idx = const_str(fs, e); | ||
1254 | if (idx <= BCMAX_C) { | ||
1255 | t->u.s.aux = ~idx; /* -256..-1: const string key */ | ||
1256 | return; | ||
1257 | } | ||
1258 | } | ||
1259 | t->u.s.aux = expr_toanyreg(fs, e); /* 0..255: register */ | ||
1260 | } | ||
1261 | |||
1262 | /* Parse index expression with named field. */ | ||
1263 | static void expr_field(LexState *ls, ExpDesc *v) | ||
1297 | { | 1264 | { |
1298 | /* field -> ['.' | ':'] NAME */ | ||
1299 | FuncState *fs = ls->fs; | 1265 | FuncState *fs = ls->fs; |
1300 | ExpDesc key; | 1266 | ExpDesc key; |
1301 | exp2anyreg(fs, v); | 1267 | expr_toanyreg(fs, v); |
1302 | lj_lex_next(ls); /* skip the dot or colon */ | 1268 | lj_lex_next(ls); /* Skip dot or colon. */ |
1303 | checkname(ls, &key); | 1269 | expr_str(ls, &key); |
1304 | indexexp(fs, v, &key); | 1270 | expr_index(fs, v, &key); |
1305 | } | 1271 | } |
1306 | 1272 | ||
1307 | static void yindex(LexState *ls, ExpDesc *v) | 1273 | /* Parse index expression with brackets. */ |
1274 | static void expr_bracket(LexState *ls, ExpDesc *v) | ||
1308 | { | 1275 | { |
1309 | /* index -> '[' expr ']' */ | 1276 | lj_lex_next(ls); /* Skip '['. */ |
1310 | lj_lex_next(ls); /* skip the '[' */ | ||
1311 | expr(ls, v); | 1277 | expr(ls, v); |
1312 | exp2val(ls->fs, v); | 1278 | expr_toval(ls->fs, v); |
1313 | checknext(ls, ']'); | 1279 | lex_check(ls, ']'); |
1314 | } | 1280 | } |
1315 | 1281 | ||
1316 | static void kexp2tv(TValue *v, ExpDesc *e) | 1282 | /* Get value of constant expression. */ |
1283 | static void expr_kvalue(TValue *v, ExpDesc *e) | ||
1317 | { | 1284 | { |
1318 | switch (e->k) { | 1285 | if (e->k <= VKTRUE) { |
1319 | case VKNIL: case VKFALSE: case VKTRUE: v->it = ~(int32_t)e->k; break; | 1286 | v->it = ~(int32_t)e->k; |
1320 | case VKSTR: | 1287 | } else if (e->k == VKSTR) { |
1321 | setgcref(v->gcr, obj2gco(e->u.sval)); v->it = LJ_TSTR; break; | 1288 | setgcref(v->gcr, obj2gco(e->u.sval)); |
1322 | case VKNUM: setnumV(v, expnumV(e)); break; | 1289 | v->it = LJ_TSTR; |
1323 | default: lua_assert(0); break; | 1290 | } else { |
1291 | lua_assert(e->k == VKNUM); | ||
1292 | setnumV(v, expr_numV(e)); | ||
1324 | } | 1293 | } |
1325 | } | 1294 | } |
1326 | 1295 | ||
1327 | static void constructor(LexState *ls, ExpDesc *e) | 1296 | /* Parse table constructor expression. */ |
1297 | static void expr_table(LexState *ls, ExpDesc *e) | ||
1328 | { | 1298 | { |
1329 | FuncState *fs = ls->fs; | 1299 | FuncState *fs = ls->fs; |
1330 | BCLine line = ls->linenumber; | 1300 | BCLine line = ls->linenumber; |
1331 | GCtab *t = NULL; | 1301 | GCtab *t = NULL; |
1332 | int vcall = 0, needarr = 0; | 1302 | int vcall = 0, needarr = 0; |
1333 | int32_t narr = 1; /* first array index */ | 1303 | int32_t narr = 1; /* First array index. */ |
1334 | uint32_t nhash = 0; /* number of hash entries */ | 1304 | uint32_t nhash = 0; /* Number of hash entries. */ |
1335 | BCReg freg = fs->freereg; | 1305 | BCReg freg = fs->freereg; |
1336 | BCPos pc = emitAD(fs, BC_TNEW, freg, 0); | 1306 | BCPos pc = bcemit_AD(fs, BC_TNEW, freg, 0); |
1337 | init_exp(e, VNONRELOC, freg); | 1307 | expr_init(e, VNONRELOC, freg); |
1338 | reserveregs(fs, 1); | 1308 | bcreg_reserve(fs, 1); |
1339 | freg++; | 1309 | freg++; |
1340 | checknext(ls, '{'); | 1310 | lex_check(ls, '{'); |
1341 | while (ls->token != '}') { | 1311 | while (ls->token != '}') { |
1342 | ExpDesc key, val; | 1312 | ExpDesc key, val; |
1343 | vcall = 0; | 1313 | vcall = 0; |
1344 | if (ls->token == '[') { | 1314 | if (ls->token == '[') { |
1345 | yindex(ls, &key); /* already calls exp2val */ | 1315 | expr_bracket(ls, &key); /* Already calls expr_toval. */ |
1346 | if (!isK(&key)) indexexp(fs, e, &key); | 1316 | if (!expr_isk(&key)) expr_index(fs, e, &key); |
1347 | if (isnumK(&key) && expnumV(&key) == 0) needarr = 1; else nhash++; | 1317 | if (expr_isnumk(&key) && expr_numV(&key) == 0) needarr = 1; else nhash++; |
1348 | checknext(ls, '='); | 1318 | lex_check(ls, '='); |
1349 | } else if (ls->token == TK_name && lj_lex_lookahead(ls) == '=') { | 1319 | } else if (ls->token == TK_name && lj_lex_lookahead(ls) == '=') { |
1350 | checkname(ls, &key); | 1320 | expr_str(ls, &key); |
1351 | checknext(ls, '='); | 1321 | lex_check(ls, '='); |
1352 | nhash++; | 1322 | nhash++; |
1353 | } else { | 1323 | } else { |
1354 | init_exp(&key, VKNUM, 0); | 1324 | expr_init(&key, VKNUM, 0); |
1355 | setintV(&key.u.nval, narr); | 1325 | setintV(&key.u.nval, narr); |
1356 | narr++; | 1326 | narr++; |
1357 | needarr = vcall = 1; | 1327 | needarr = vcall = 1; |
1358 | } | 1328 | } |
1359 | expr(ls, &val); | 1329 | expr(ls, &val); |
1360 | if (isKexp(&val) && isK(&key) && key.k != VKNIL) { | 1330 | if (expr_isk_nojump(&val) && expr_isk(&key) && key.k != VKNIL) { |
1361 | TValue k; | 1331 | TValue k; |
1362 | if (!t) { /* create template table on demand */ | 1332 | if (!t) { /* Create template table on demand. */ |
1363 | BCReg kidx; | 1333 | BCReg kidx; |
1364 | t = lj_tab_new(fs->L, 0, 0); | 1334 | t = lj_tab_new(fs->L, 0, 0); |
1365 | kidx = gcK(fs, obj2gco(t), LJ_TTAB); | 1335 | kidx = const_gc(fs, obj2gco(t), LJ_TTAB); |
1366 | *proto_insptr(fs->pt, pc) = BCINS_AD(BC_TDUP, freg-1, kidx); | 1336 | *proto_insptr(fs->pt, pc) = BCINS_AD(BC_TDUP, freg-1, kidx); |
1367 | } | 1337 | } |
1368 | vcall = 0; | 1338 | vcall = 0; |
1369 | kexp2tv(&k, &key); | 1339 | expr_kvalue(&k, &key); |
1370 | kexp2tv(lj_tab_set(fs->L, t, &k), &val); | 1340 | expr_kvalue(lj_tab_set(fs->L, t, &k), &val); |
1371 | if (val.k == VKSTR) | 1341 | if (val.k == VKSTR) |
1372 | lj_gc_objbarriert(fs->L, t, val.u.sval); | 1342 | lj_gc_objbarriert(fs->L, t, val.u.sval); |
1373 | } else { | 1343 | } else { |
1374 | if (isK(&key)) indexexp(fs, e, &key); | 1344 | if (expr_isk(&key)) expr_index(fs, e, &key); |
1375 | if (val.k != VCALL) vcall = 0; | 1345 | if (val.k != VCALL) vcall = 0; |
1376 | storevar(fs, e, &val); | 1346 | bcemit_store(fs, e, &val); |
1377 | } | 1347 | } |
1378 | fs->freereg = freg; | 1348 | fs->freereg = freg; |
1379 | if (!testnext(ls, ',') && !testnext(ls, ';')) break; | 1349 | if (!lex_opt(ls, ',') && !lex_opt(ls, ';')) break; |
1380 | } | 1350 | } |
1381 | checkmatch(ls, '}', '{', line); | 1351 | lex_match(ls, '}', '{', line); |
1382 | if (vcall) { | 1352 | if (vcall) { |
1383 | BCIns *i = proto_insptr(fs->pt, fs->pc-1); | 1353 | BCIns *i = proto_insptr(fs->pt, fs->pc-1); |
1384 | ExpDesc en; | 1354 | ExpDesc en; |
1385 | lua_assert(bc_a(*i)==freg && bc_op(*i) == (narr>256?BC_TSETV:BC_TSETB)); | 1355 | lua_assert(bc_a(*i)==freg && bc_op(*i) == (narr>256?BC_TSETV:BC_TSETB)); |
1386 | init_exp(&en, VKNUM, 0); | 1356 | expr_init(&en, VKNUM, 0); |
1387 | setintV(&en.u.nval, narr-1); | 1357 | setintV(&en.u.nval, narr-1); |
1388 | if (narr > 256) { fs->pc--; i--; } | 1358 | if (narr > 256) { fs->pc--; i--; } |
1389 | *i = BCINS_AD(BC_TSETM, freg, numK(fs, &en)); | 1359 | *i = BCINS_AD(BC_TSETM, freg, const_num(fs, &en)); |
1390 | setbc_b(i-1, 0); | 1360 | setbc_b(i-1, 0); |
1391 | } | 1361 | } |
1392 | if (pc == fs->pc-1) { /* make expr relocable if possible */ | 1362 | if (pc == fs->pc-1) { /* Make expr relocable if possible. */ |
1393 | e->u.s.info = pc; | 1363 | e->u.s.info = pc; |
1394 | fs->freereg--; | 1364 | fs->freereg--; |
1395 | e->k = VRELOCABLE; | 1365 | e->k = VRELOCABLE; |
1396 | } else { | 1366 | } else { |
1397 | e->k = VNONRELOC; /* indexexp may have changed it */ | 1367 | e->k = VNONRELOC; /* May have been changed by expr_index. */ |
1398 | } | 1368 | } |
1399 | if (!t) { /* Construct TNEW RD: hhhhhaaaaaaaaaaa. */ | 1369 | if (!t) { /* Construct TNEW RD: hhhhhaaaaaaaaaaa. */ |
1400 | if (!needarr) narr = 0; | 1370 | if (!needarr) narr = 0; |
@@ -1404,275 +1374,242 @@ static void constructor(LexState *ls, ExpDesc *e) | |||
1404 | } | 1374 | } |
1405 | } | 1375 | } |
1406 | 1376 | ||
1407 | static void parlist(LexState *ls) | 1377 | /* Parse function parameters. */ |
1378 | static void parse_params(LexState *ls, int needself) | ||
1408 | { | 1379 | { |
1409 | /* parlist -> [ param { `,' param } ] */ | ||
1410 | FuncState *fs = ls->fs; | 1380 | FuncState *fs = ls->fs; |
1411 | GCproto *pt = fs->pt; | 1381 | GCproto *pt = fs->pt; |
1412 | BCReg nparams = 0; | 1382 | BCReg nparams = 0; |
1413 | if (ls->token != ')') { /* is `parlist' not empty? */ | 1383 | lex_check(ls, '('); |
1384 | if (needself) { | ||
1385 | var_new_lit(ls, "self", 0); | ||
1386 | var_add(ls, 1); | ||
1387 | } | ||
1388 | if (ls->token != ')') { | ||
1414 | do { | 1389 | do { |
1415 | switch (ls->token) { | 1390 | if (ls->token == TK_name) { |
1416 | case TK_name: /* param -> NAME */ | 1391 | var_new(ls, nparams++, lex_str(ls)); |
1417 | new_localvar(ls, str_checkname(ls), nparams++); | 1392 | } else if (ls->token == TK_dots) { |
1418 | break; | ||
1419 | case TK_dots: /* param -> `...' */ | ||
1420 | lj_lex_next(ls); | 1393 | lj_lex_next(ls); |
1421 | pt->flags |= PROTO_IS_VARARG; | 1394 | fs->flags |= PROTO_IS_VARARG; |
1422 | break; | 1395 | break; |
1423 | default: | 1396 | } else { |
1424 | err_syntax(ls, LJ_ERR_XPARAM); | 1397 | err_syntax(ls, LJ_ERR_XPARAM); |
1425 | break; | ||
1426 | } | 1398 | } |
1427 | } while (!(pt->flags & PROTO_IS_VARARG) && testnext(ls, ',')); | 1399 | } while (lex_opt(ls, ',')); |
1428 | } | 1400 | } |
1429 | adjustlocalvars(ls, nparams); | 1401 | var_add(ls, nparams); |
1430 | pt->numparams = cast_byte(fs->nactvar); | 1402 | pt->numparams = cast_byte(fs->nactvar); |
1431 | reserveregs(fs, fs->nactvar); /* reserve register for parameters */ | 1403 | bcreg_reserve(fs, fs->nactvar); |
1404 | lex_check(ls, ')'); | ||
1432 | } | 1405 | } |
1433 | 1406 | ||
1434 | static void body(LexState *ls, ExpDesc *e, int needself, BCLine line) | 1407 | /* Forward declaration. */ |
1408 | static void parse_chunk(LexState *ls); | ||
1409 | |||
1410 | /* Parse body of a function. */ | ||
1411 | static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line) | ||
1435 | { | 1412 | { |
1436 | /* body -> `(' parlist `)' chunk END */ | 1413 | FuncState *fs, cfs; |
1437 | FuncState *fs, new_fs; | ||
1438 | BCReg kidx; | 1414 | BCReg kidx; |
1439 | open_func(ls, &new_fs); | 1415 | BCLine lastline; |
1440 | new_fs.pt->linedefined = line; | 1416 | GCproto *pt; |
1441 | checknext(ls, '('); | 1417 | fs_init(ls, &cfs, line); |
1442 | if (needself) { | 1418 | parse_params(ls, needself); |
1443 | new_localvarliteral(ls, "self", 0); | 1419 | parse_chunk(ls); |
1444 | adjustlocalvars(ls, 1); | 1420 | lastline = ls->linenumber; |
1445 | } | 1421 | lex_match(ls, TK_end, TK_function, line); |
1446 | parlist(ls); | 1422 | pt = fs_finish(ls, lastline); |
1447 | checknext(ls, ')'); | 1423 | /* Store new prototype in the constant array of the parent. */ |
1448 | chunk(ls); | ||
1449 | new_fs.pt->lastlinedefined = ls->linenumber; | ||
1450 | checkmatch(ls, TK_end, TK_function, line); | ||
1451 | close_func(ls); | ||
1452 | fs = ls->fs; | 1424 | fs = ls->fs; |
1453 | kidx = gcK(fs, obj2gco(new_fs.pt), LJ_TPROTO); | 1425 | kidx = const_gc(fs, obj2gco(pt), LJ_TPROTO); |
1454 | init_exp(e, VRELOCABLE, emitAD(fs, BC_FNEW, 0, kidx)); | 1426 | expr_init(e, VRELOCABLE, bcemit_AD(fs, BC_FNEW, 0, kidx)); |
1455 | if (!(fs->pt->flags & PROTO_HAS_FNEW)) { | 1427 | if (!(fs->flags & PROTO_HAS_FNEW)) { |
1456 | if (fs->pt->flags & PROTO_HAS_RETURN) | 1428 | if (fs->flags & PROTO_HAS_RETURN) |
1457 | fs->pt->flags |= PROTO_FIXUP_RETURN; | 1429 | fs->flags |= PROTO_FIXUP_RETURN; |
1458 | fs->pt->flags |= PROTO_HAS_FNEW; | 1430 | fs->flags |= PROTO_HAS_FNEW; |
1459 | } | 1431 | } |
1460 | } | 1432 | } |
1461 | 1433 | ||
1462 | static BCReg explist1(LexState *ls, ExpDesc *v) | 1434 | /* Parse expression list. Last expression is left open. */ |
1435 | static BCReg expr_list(LexState *ls, ExpDesc *v) | ||
1463 | { | 1436 | { |
1464 | /* explist1 -> expr { `,' expr } */ | 1437 | BCReg n = 1; |
1465 | BCReg n = 1; /* at least one expression */ | ||
1466 | expr(ls, v); | 1438 | expr(ls, v); |
1467 | while (testnext(ls, ',')) { | 1439 | while (lex_opt(ls, ',')) { |
1468 | exp2nextreg(ls->fs, v); | 1440 | expr_tonextreg(ls->fs, v); |
1469 | expr(ls, v); | 1441 | expr(ls, v); |
1470 | n++; | 1442 | n++; |
1471 | } | 1443 | } |
1472 | return n; | 1444 | return n; |
1473 | } | 1445 | } |
1474 | 1446 | ||
1475 | static void funcargs(LexState *ls, ExpDesc *e) | 1447 | /* Parse function argument list. */ |
1448 | static void parse_args(LexState *ls, ExpDesc *e) | ||
1476 | { | 1449 | { |
1477 | FuncState *fs = ls->fs; | 1450 | FuncState *fs = ls->fs; |
1478 | ExpDesc args; | 1451 | ExpDesc args; |
1479 | BCIns ins; | 1452 | BCIns ins; |
1480 | BCReg base; | 1453 | BCReg base; |
1481 | BCLine line = ls->linenumber; | 1454 | BCLine line = ls->linenumber; |
1482 | switch (ls->token) { | 1455 | if (ls->token == '(') { |
1483 | case '(': { /* funcargs -> `(' [ explist1 ] `)' */ | 1456 | if (line != ls->lastline) |
1484 | if (line != ls->lastline) | 1457 | err_syntax(ls, LJ_ERR_XAMBIG); |
1485 | err_syntax(ls, LJ_ERR_XAMBIG); | 1458 | lj_lex_next(ls); |
1486 | lj_lex_next(ls); | 1459 | if (ls->token == ')') { /* f(). */ |
1487 | if (ls->token == ')') { /* arg list is empty? */ | 1460 | args.k = VVOID; |
1488 | args.k = VVOID; | 1461 | } else { |
1489 | } else { | 1462 | expr_list(ls, &args); |
1490 | explist1(ls, &args); | 1463 | if (args.k == VCALL) /* f(a, b, g()) or f(a, b, ...). */ |
1491 | if (args.k == VCALL) | 1464 | setbc_b(bcptr(fs, &args), 0); /* Pass on multiple results. */ |
1492 | setbc_b(bcptr(fs, &args), 0); | ||
1493 | } | ||
1494 | checkmatch(ls, ')', '(', line); | ||
1495 | break; | ||
1496 | } | ||
1497 | case '{': { /* funcargs -> constructor */ | ||
1498 | constructor(ls, &args); | ||
1499 | break; | ||
1500 | } | ||
1501 | case TK_string: { /* funcargs -> STRING */ | ||
1502 | init_exp(&args, VKSTR, 0); | ||
1503 | args.u.sval = strV(&ls->tokenval); | ||
1504 | lj_lex_next(ls); /* must use `seminfo' before `next' */ | ||
1505 | break; | ||
1506 | } | ||
1507 | default: { | ||
1508 | err_syntax(ls, LJ_ERR_XFUNARG); | ||
1509 | return; | ||
1510 | } | 1465 | } |
1466 | lex_match(ls, ')', '(', line); | ||
1467 | } else if (ls->token == '{') { | ||
1468 | expr_table(ls, &args); | ||
1469 | } else if (ls->token == TK_string) { | ||
1470 | expr_init(&args, VKSTR, 0); | ||
1471 | args.u.sval = strV(&ls->tokenval); | ||
1472 | lj_lex_next(ls); | ||
1473 | } else { | ||
1474 | err_syntax(ls, LJ_ERR_XFUNARG); | ||
1475 | return; /* Silence compiler. */ | ||
1511 | } | 1476 | } |
1512 | lua_assert(e->k == VNONRELOC); | 1477 | lua_assert(e->k == VNONRELOC); |
1513 | base = e->u.s.info; /* base register for call */ | 1478 | base = e->u.s.info; /* Base register for call. */ |
1514 | if (args.k == VCALL) { | 1479 | if (args.k == VCALL) { |
1515 | ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1); | 1480 | ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1); |
1516 | } else { | 1481 | } else { |
1517 | if (args.k != VVOID) | 1482 | if (args.k != VVOID) |
1518 | exp2nextreg(fs, &args); /* close last argument */ | 1483 | expr_tonextreg(fs, &args); |
1519 | ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base); | 1484 | ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base); |
1520 | } | 1485 | } |
1521 | init_exp(e, VCALL, emitINS(fs, ins)); | 1486 | expr_init(e, VCALL, bcemit_INS(fs, ins)); |
1522 | e->u.s.aux = base; | 1487 | e->u.s.aux = base; |
1523 | proto_lineinfo(fs->pt)[fs->pc - 1] = line; | 1488 | proto_lineinfo(fs->pt)[fs->pc - 1] = line; |
1524 | fs->freereg = base+1; /* call removes function and arguments and leaves | 1489 | fs->freereg = base+1; /* Leave one result by default. */ |
1525 | (unless changed) one result */ | ||
1526 | } | ||
1527 | |||
1528 | static void prefixexp(LexState *ls, ExpDesc *v) | ||
1529 | { | ||
1530 | /* prefixexp -> NAME | '(' expr ')' */ | ||
1531 | switch (ls->token) { | ||
1532 | case '(': { | ||
1533 | BCLine line = ls->linenumber; | ||
1534 | lj_lex_next(ls); | ||
1535 | expr(ls, v); | ||
1536 | checkmatch(ls, ')', '(', line); | ||
1537 | dischargevars(ls->fs, v); | ||
1538 | return; | ||
1539 | } | ||
1540 | case TK_name: { | ||
1541 | singlevar(ls, v); | ||
1542 | return; | ||
1543 | } | ||
1544 | default: { | ||
1545 | err_syntax(ls, LJ_ERR_XSYMBOL); | ||
1546 | return; | ||
1547 | } | ||
1548 | } | ||
1549 | } | 1490 | } |
1550 | 1491 | ||
1551 | static void primaryexp(LexState *ls, ExpDesc *v) | 1492 | /* Parse primary expression. */ |
1493 | static void expr_primary(LexState *ls, ExpDesc *v) | ||
1552 | { | 1494 | { |
1553 | /* primaryexp -> | ||
1554 | prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ | ||
1555 | FuncState *fs = ls->fs; | 1495 | FuncState *fs = ls->fs; |
1556 | prefixexp(ls, v); | 1496 | /* Parse prefix expression. */ |
1557 | for (;;) { | 1497 | if (ls->token == '(') { |
1558 | switch (ls->token) { | 1498 | BCLine line = ls->linenumber; |
1559 | case '.': /* field */ | 1499 | lj_lex_next(ls); |
1560 | field(ls, v); | 1500 | expr(ls, v); |
1561 | break; | 1501 | lex_match(ls, ')', '(', line); |
1562 | case '[': { /* `[' exp1 `]' */ | 1502 | expr_discharge(ls->fs, v); |
1563 | ExpDesc key; | 1503 | } else if (ls->token == TK_name) { |
1564 | exp2anyreg(fs, v); | 1504 | var_lookup(ls, v); |
1565 | yindex(ls, &key); | 1505 | } else { |
1566 | indexexp(fs, v, &key); | 1506 | err_syntax(ls, LJ_ERR_XSYMBOL); |
1567 | break; | 1507 | } |
1568 | } | 1508 | for (;;) { /* Parse multiple expression suffixes. */ |
1569 | case ':': { /* `:' NAME funcargs */ | 1509 | if (ls->token == '.') { |
1570 | ExpDesc key; | 1510 | expr_field(ls, v); |
1571 | lj_lex_next(ls); | 1511 | } else if (ls->token == '[') { |
1572 | checkname(ls, &key); | 1512 | ExpDesc key; |
1573 | methodexp(fs, v, &key); | 1513 | expr_toanyreg(fs, v); |
1574 | funcargs(ls, v); | 1514 | expr_bracket(ls, &key); |
1575 | break; | 1515 | expr_index(fs, v, &key); |
1576 | } | 1516 | } else if (ls->token == ':') { |
1577 | case '(': case TK_string: case '{': /* funcargs */ | 1517 | ExpDesc key; |
1578 | exp2nextreg(fs, v); | 1518 | lj_lex_next(ls); |
1579 | funcargs(ls, v); | 1519 | expr_str(ls, &key); |
1580 | break; | 1520 | bcemit_method(fs, v, &key); |
1581 | default: return; | 1521 | parse_args(ls, v); |
1522 | } else if (ls->token == '(' || ls->token == TK_string || ls->token == '{') { | ||
1523 | expr_tonextreg(fs, v); | ||
1524 | parse_args(ls, v); | ||
1525 | } else { | ||
1526 | break; | ||
1582 | } | 1527 | } |
1583 | } | 1528 | } |
1584 | } | 1529 | } |
1585 | 1530 | ||
1586 | static void simpleexp(LexState *ls, ExpDesc *v) | 1531 | /* Parse simple expression. */ |
1532 | static void expr_simple(LexState *ls, ExpDesc *v) | ||
1587 | { | 1533 | { |
1588 | /* simpleexp -> NUMBER | STRING | NIL | true | false | ... | | ||
1589 | constructor | FUNCTION body | primaryexp */ | ||
1590 | switch (ls->token) { | 1534 | switch (ls->token) { |
1591 | case TK_number: | 1535 | case TK_number: |
1592 | init_exp(v, VKNUM, 0); | 1536 | expr_init(v, VKNUM, 0); |
1593 | setnumV(&v->u.nval, numV(&ls->tokenval)); | 1537 | setnumV(&v->u.nval, numV(&ls->tokenval)); |
1594 | break; | 1538 | break; |
1595 | case TK_string: | 1539 | case TK_string: |
1596 | init_exp(v, VKSTR, 0); | 1540 | expr_init(v, VKSTR, 0); |
1597 | v->u.sval = strV(&ls->tokenval); | 1541 | v->u.sval = strV(&ls->tokenval); |
1598 | break; | 1542 | break; |
1599 | case TK_nil: | 1543 | case TK_nil: |
1600 | init_exp(v, VKNIL, 0); | 1544 | expr_init(v, VKNIL, 0); |
1601 | break; | 1545 | break; |
1602 | case TK_true: | 1546 | case TK_true: |
1603 | init_exp(v, VKTRUE, 0); | 1547 | expr_init(v, VKTRUE, 0); |
1604 | break; | 1548 | break; |
1605 | case TK_false: | 1549 | case TK_false: |
1606 | init_exp(v, VKFALSE, 0); | 1550 | expr_init(v, VKFALSE, 0); |
1607 | break; | 1551 | break; |
1608 | case TK_dots: { /* vararg */ | 1552 | case TK_dots: { /* Vararg. */ |
1609 | FuncState *fs = ls->fs; | 1553 | FuncState *fs = ls->fs; |
1610 | BCReg base; | 1554 | BCReg base; |
1611 | checkcond(ls, fs->pt->flags & PROTO_IS_VARARG, LJ_ERR_XDOTS); | 1555 | checkcond(ls, fs->flags & PROTO_IS_VARARG, LJ_ERR_XDOTS); |
1612 | reserveregs(fs, 1); | 1556 | bcreg_reserve(fs, 1); |
1613 | base = fs->freereg-1; | 1557 | base = fs->freereg-1; |
1614 | init_exp(v, VCALL, emitABC(fs, BC_VARG, base, 2, 1)); | 1558 | expr_init(v, VCALL, bcemit_ABC(fs, BC_VARG, base, 2, 1)); |
1615 | v->u.s.aux = base; | 1559 | v->u.s.aux = base; |
1616 | break; | 1560 | break; |
1617 | } | 1561 | } |
1618 | case '{': /* constructor */ | 1562 | case '{': /* Table constructor. */ |
1619 | constructor(ls, v); | 1563 | expr_table(ls, v); |
1620 | return; | 1564 | return; |
1621 | case TK_function: | 1565 | case TK_function: |
1622 | lj_lex_next(ls); | 1566 | lj_lex_next(ls); |
1623 | body(ls, v, 0, ls->linenumber); | 1567 | parse_body(ls, v, 0, ls->linenumber); |
1624 | return; | 1568 | return; |
1625 | default: | 1569 | default: |
1626 | primaryexp(ls, v); | 1570 | expr_primary(ls, v); |
1627 | return; | 1571 | return; |
1628 | } | 1572 | } |
1629 | lj_lex_next(ls); | 1573 | lj_lex_next(ls); |
1630 | } | 1574 | } |
1631 | 1575 | ||
1632 | static void enterlevel(LexState *ls) | 1576 | /* Manage syntactic levels to avoid blowing up the stack. */ |
1577 | static void synlevel_begin(LexState *ls) | ||
1633 | { | 1578 | { |
1634 | if (++ls->level >= LJ_MAX_XLEVEL) | 1579 | if (++ls->level >= LJ_MAX_XLEVEL) |
1635 | lj_lex_error(ls, 0, LJ_ERR_XLEVELS); | 1580 | lj_lex_error(ls, 0, LJ_ERR_XLEVELS); |
1636 | } | 1581 | } |
1637 | 1582 | ||
1638 | #define leavelevel(ls) ((ls)->level--) | 1583 | #define synlevel_end(ls) ((ls)->level--) |
1639 | |||
1640 | static UnOpr getunopr(LexToken tok) | ||
1641 | { | ||
1642 | switch (tok) { | ||
1643 | case TK_not: return OPR_NOT; | ||
1644 | case '-': return OPR_MINUS; | ||
1645 | case '#': return OPR_LEN; | ||
1646 | default: return OPR_NOUNOPR; | ||
1647 | } | ||
1648 | } | ||
1649 | 1584 | ||
1650 | static BinOpr getbinopr(LexToken tok) | 1585 | /* Convert token to binary operator. */ |
1586 | static BinOpr token2binop(LexToken tok) | ||
1651 | { | 1587 | { |
1652 | switch (tok) { | 1588 | switch (tok) { |
1653 | case '+': return OPR_ADD; | 1589 | case '+': return OPR_ADD; |
1654 | case '-': return OPR_SUB; | 1590 | case '-': return OPR_SUB; |
1655 | case '*': return OPR_MUL; | 1591 | case '*': return OPR_MUL; |
1656 | case '/': return OPR_DIV; | 1592 | case '/': return OPR_DIV; |
1657 | case '%': return OPR_MOD; | 1593 | case '%': return OPR_MOD; |
1658 | case '^': return OPR_POW; | 1594 | case '^': return OPR_POW; |
1659 | case TK_concat: return OPR_CONCAT; | 1595 | case TK_concat: return OPR_CONCAT; |
1660 | case TK_ne: return OPR_NE; | 1596 | case TK_ne: return OPR_NE; |
1661 | case TK_eq: return OPR_EQ; | 1597 | case TK_eq: return OPR_EQ; |
1662 | case '<': return OPR_LT; | 1598 | case '<': return OPR_LT; |
1663 | case TK_le: return OPR_LE; | 1599 | case TK_le: return OPR_LE; |
1664 | case '>': return OPR_GT; | 1600 | case '>': return OPR_GT; |
1665 | case TK_ge: return OPR_GE; | 1601 | case TK_ge: return OPR_GE; |
1666 | case TK_and: return OPR_AND; | 1602 | case TK_and: return OPR_AND; |
1667 | case TK_or: return OPR_OR; | 1603 | case TK_or: return OPR_OR; |
1668 | default: return OPR_NOBINOPR; | 1604 | default: return OPR_NOBINOPR; |
1669 | } | 1605 | } |
1670 | } | 1606 | } |
1671 | 1607 | ||
1608 | /* Priorities for each binary operator. ORDER OPR. */ | ||
1672 | static const struct { | 1609 | static const struct { |
1673 | uint8_t left; /* left priority for each binary operator */ | 1610 | uint8_t left; /* Left priority. */ |
1674 | uint8_t right; /* right priority */ | 1611 | uint8_t right; /* Right priority. */ |
1675 | } priority[] = { /* ORDER OPR */ | 1612 | } priority[] = { |
1676 | {6,6}, {6,6}, {7,7}, {7,7}, {7,7}, /* ADD SUB MUL DIV MOD */ | 1613 | {6,6}, {6,6}, {7,7}, {7,7}, {7,7}, /* ADD SUB MUL DIV MOD */ |
1677 | {10,9}, {5,4}, /* POW CONCAT (right associative) */ | 1614 | {10,9}, {5,4}, /* POW CONCAT (right associative) */ |
1678 | {3,3}, {3,3}, /* EQ NE */ | 1615 | {3,3}, {3,3}, /* EQ NE */ |
@@ -1680,549 +1617,605 @@ static const struct { | |||
1680 | {2,2}, {1,1} /* AND OR */ | 1617 | {2,2}, {1,1} /* AND OR */ |
1681 | }; | 1618 | }; |
1682 | 1619 | ||
1683 | #define UNARY_PRIORITY 8 /* priority for unary operators */ | 1620 | #define UNARY_PRIORITY 8 /* Priority for unary operators. */ |
1684 | 1621 | ||
1685 | /* | 1622 | /* Forward declaration. */ |
1686 | ** subexpr -> (simpleexp | unop subexpr) { binop subexpr } | 1623 | static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit); |
1687 | ** where `binop' is any binary operator with a priority higher than `limit' | 1624 | |
1688 | */ | 1625 | /* Parse unary expression. */ |
1689 | static BinOpr subexpr(LexState *ls, ExpDesc *v, uint32_t limit) | 1626 | static void expr_unop(LexState *ls, ExpDesc *v) |
1690 | { | 1627 | { |
1691 | BinOpr op; | 1628 | BCOp op; |
1692 | UnOpr uop; | 1629 | if (ls->token == TK_not) { |
1693 | enterlevel(ls); | 1630 | op = BC_NOT; |
1694 | uop = getunopr(ls->token); | 1631 | } else if (ls->token == '-') { |
1695 | if (uop != OPR_NOUNOPR) { | 1632 | op = BC_UNM; |
1696 | lj_lex_next(ls); | 1633 | } else if (ls->token == '#') { |
1697 | subexpr(ls, v, UNARY_PRIORITY); | 1634 | op = BC_LEN; |
1698 | emit_unop(ls->fs, uop, v); | ||
1699 | } else { | 1635 | } else { |
1700 | simpleexp(ls, v); | 1636 | expr_simple(ls, v); |
1637 | return; | ||
1701 | } | 1638 | } |
1702 | /* expand while operators have priorities higher than `limit' */ | 1639 | lj_lex_next(ls); |
1703 | op = getbinopr(ls->token); | 1640 | expr_binop(ls, v, UNARY_PRIORITY); |
1641 | bcemit_unop(ls->fs, op, v); | ||
1642 | } | ||
1643 | |||
1644 | /* Parse binary expressions with priority higher than the limit. */ | ||
1645 | static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit) | ||
1646 | { | ||
1647 | BinOpr op; | ||
1648 | synlevel_begin(ls); | ||
1649 | expr_unop(ls, v); | ||
1650 | op = token2binop(ls->token); | ||
1704 | while (op != OPR_NOBINOPR && priority[op].left > limit) { | 1651 | while (op != OPR_NOBINOPR && priority[op].left > limit) { |
1705 | ExpDesc v2; | 1652 | ExpDesc v2; |
1706 | BinOpr nextop; | 1653 | BinOpr nextop; |
1707 | lj_lex_next(ls); | 1654 | lj_lex_next(ls); |
1708 | prepare_binop(ls->fs, op, v); | 1655 | bcemit_binop_left(ls->fs, op, v); |
1709 | /* read sub-expression with higher priority */ | 1656 | /* Parse binary expression with higher priority. */ |
1710 | nextop = subexpr(ls, &v2, priority[op].right); | 1657 | nextop = expr_binop(ls, &v2, priority[op].right); |
1711 | emit_binop(ls->fs, op, v, &v2); | 1658 | bcemit_binop(ls->fs, op, v, &v2); |
1712 | op = nextop; | 1659 | op = nextop; |
1713 | } | 1660 | } |
1714 | leavelevel(ls); | 1661 | synlevel_end(ls); |
1715 | return op; /* return first untreated operator */ | 1662 | return op; /* Return unconsumed binary operator (if any). */ |
1716 | } | 1663 | } |
1717 | 1664 | ||
1665 | /* Parse expression. */ | ||
1718 | static void expr(LexState *ls, ExpDesc *v) | 1666 | static void expr(LexState *ls, ExpDesc *v) |
1719 | { | 1667 | { |
1720 | subexpr(ls, v, 0); | 1668 | expr_binop(ls, v, 0); /* Priority 0: parse whole expression. */ |
1721 | } | 1669 | } |
1722 | 1670 | ||
1723 | static BCPos condexpr(LexState *ls) | 1671 | /* Assign expression to the next register. */ |
1672 | static void expr_next(LexState *ls) | ||
1673 | { | ||
1674 | ExpDesc e; | ||
1675 | expr(ls, &e); | ||
1676 | expr_tonextreg(ls->fs, &e); | ||
1677 | } | ||
1678 | |||
1679 | /* Parse conditional expression. */ | ||
1680 | static BCPos expr_cond(LexState *ls) | ||
1724 | { | 1681 | { |
1725 | /* cond -> exp */ | ||
1726 | ExpDesc v; | 1682 | ExpDesc v; |
1727 | expr(ls, &v); /* read condition */ | 1683 | expr(ls, &v); |
1728 | if (v.k == VKNIL) v.k = VKFALSE; /* `falses' are all equal here */ | 1684 | if (v.k == VKNIL) v.k = VKFALSE; |
1729 | goiftrue(ls->fs, &v); | 1685 | bcemit_branch_t(ls->fs, &v); |
1730 | return v.f; | 1686 | return v.f; |
1731 | } | 1687 | } |
1732 | 1688 | ||
1733 | /* -- Scope handling ------------------------------------------------------ */ | 1689 | /* -- Scope handling ------------------------------------------------------ */ |
1734 | 1690 | ||
1735 | static void enterblock(FuncState *fs, FuncBlock *bl, int isbreakable) | 1691 | /* Begin a scope. */ |
1692 | static void scope_begin(FuncState *fs, FuncScope *bl, int isbreakable) | ||
1736 | { | 1693 | { |
1737 | bl->breaklist = NO_JMP; | 1694 | bl->breaklist = NO_JMP; |
1738 | bl->isbreakable = (uint8_t)isbreakable; | 1695 | bl->isbreakable = (uint8_t)isbreakable; |
1739 | bl->nactvar = fs->nactvar; | 1696 | bl->nactvar = fs->nactvar; |
1740 | bl->upval = 0; | 1697 | bl->upval = 0; |
1741 | bl->previous = fs->bl; | 1698 | bl->prev = fs->bl; |
1742 | fs->bl = bl; | 1699 | fs->bl = bl; |
1743 | lua_assert(fs->freereg == fs->nactvar); | 1700 | lua_assert(fs->freereg == fs->nactvar); |
1744 | } | 1701 | } |
1745 | 1702 | ||
1746 | static void leaveblock(FuncState *fs) | 1703 | /* End a scope. */ |
1704 | static void scope_end(FuncState *fs) | ||
1747 | { | 1705 | { |
1748 | FuncBlock *bl = fs->bl; | 1706 | FuncScope *bl = fs->bl; |
1749 | fs->bl = bl->previous; | 1707 | fs->bl = bl->prev; |
1750 | removevars(fs->ls, bl->nactvar); | 1708 | var_remove(fs->ls, bl->nactvar); |
1751 | fs->freereg = fs->nactvar; /* free registers */ | 1709 | fs->freereg = fs->nactvar; |
1752 | lua_assert(bl->nactvar == fs->nactvar); | 1710 | lua_assert(bl->nactvar == fs->nactvar); |
1753 | /* a block either controls scope or breaks (never both) */ | 1711 | /* A scope is either breakable or has upvalues. */ |
1754 | lua_assert(!bl->isbreakable || !bl->upval); | 1712 | lua_assert(!bl->isbreakable || !bl->upval); |
1755 | if (bl->upval) | 1713 | if (bl->upval) |
1756 | emitAJ(fs, BC_UCLO, bl->nactvar, 0); | 1714 | bcemit_AJ(fs, BC_UCLO, bl->nactvar, 0); |
1757 | else /* avoid in upval case, it clears lasttarget and kills UCLO+JMP join */ | 1715 | else /* Avoid in upval case, it clears lasttarget and kills UCLO+JMP join. */ |
1758 | patchtohere(fs, bl->breaklist); | 1716 | jmp_tohere(fs, bl->breaklist); |
1717 | } | ||
1718 | |||
1719 | /* Mark scope as having an upvalue. */ | ||
1720 | static void scope_uvmark(FuncState *fs, BCReg level) | ||
1721 | { | ||
1722 | FuncScope *bl; | ||
1723 | for (bl = fs->bl; bl && bl->nactvar > level; bl = bl->prev) | ||
1724 | ; | ||
1725 | if (bl) | ||
1726 | bl->upval = 1; | ||
1727 | } | ||
1728 | |||
1729 | /* Parse 'break' statement. */ | ||
1730 | static void parse_break(LexState *ls) | ||
1731 | { | ||
1732 | FuncState *fs = ls->fs; | ||
1733 | FuncScope *bl; | ||
1734 | int upval = 0; | ||
1735 | for (bl = fs->bl; bl && !bl->isbreakable; bl = bl->prev) | ||
1736 | upval |= bl->upval; /* Collect upvalues in intervening scopes. */ | ||
1737 | if (!bl) /* Error if no breakable scope found. */ | ||
1738 | err_syntax(ls, LJ_ERR_XBREAK); | ||
1739 | if (upval) | ||
1740 | bcemit_AJ(fs, BC_UCLO, bl->nactvar, 0); /* Close upvalues. */ | ||
1741 | jmp_append(fs, &bl->breaklist, bcemit_jmp(fs)); | ||
1742 | } | ||
1743 | |||
1744 | /* Check for end of block. */ | ||
1745 | static int endofblock(LexToken token) | ||
1746 | { | ||
1747 | switch (token) { | ||
1748 | case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof: | ||
1749 | return 1; | ||
1750 | default: | ||
1751 | return 0; | ||
1752 | } | ||
1753 | } | ||
1754 | |||
1755 | /* Parse 'return' statement. */ | ||
1756 | static void parse_return(LexState *ls) | ||
1757 | { | ||
1758 | BCIns ins; | ||
1759 | FuncState *fs = ls->fs; | ||
1760 | lj_lex_next(ls); /* Skip 'return'. */ | ||
1761 | fs->flags |= PROTO_HAS_RETURN; | ||
1762 | if (endofblock(ls->token) || ls->token == ';') { /* Bare return. */ | ||
1763 | ins = BCINS_AD(BC_RET0, 0, 1); | ||
1764 | } else { /* Return with one or more values. */ | ||
1765 | ExpDesc e; /* Receives the _last_ expression in the list. */ | ||
1766 | BCReg nret = expr_list(ls, &e); | ||
1767 | if (nret == 1) { /* Return one result. */ | ||
1768 | if (e.k == VCALL) { /* Check for tail call. */ | ||
1769 | BCIns *i = bcptr(fs, &e); | ||
1770 | /* It doesn't pay off to add BC_VARGT just for 'return ...'. */ | ||
1771 | if (bc_op(*i) == BC_VARG) goto notailcall; | ||
1772 | fs->pc--; | ||
1773 | ins = BCINS_AD(bc_op(*i)-BC_CALL+BC_CALLT, bc_a(*i), bc_c(*i)); | ||
1774 | } else { /* Can return the result from any register. */ | ||
1775 | ins = BCINS_AD(BC_RET1, expr_toanyreg(fs, &e), 2); | ||
1776 | } | ||
1777 | } else { | ||
1778 | if (e.k == VCALL) { /* Append all results from a call. */ | ||
1779 | notailcall: | ||
1780 | setbc_b(bcptr(fs, &e), 0); | ||
1781 | ins = BCINS_AD(BC_RETM, fs->nactvar, e.u.s.aux - fs->nactvar); | ||
1782 | } else { | ||
1783 | expr_tonextreg(fs, &e); /* Force contiguous registers. */ | ||
1784 | ins = BCINS_AD(BC_RET, fs->nactvar, nret+1); | ||
1785 | } | ||
1786 | } | ||
1787 | } | ||
1788 | if (fs->flags & PROTO_HAS_FNEW) | ||
1789 | bcemit_AJ(fs, BC_UCLO, 0, 0); /* May need to close upvalues first. */ | ||
1790 | bcemit_INS(fs, ins); | ||
1759 | } | 1791 | } |
1760 | 1792 | ||
1761 | static void block(LexState *ls) | 1793 | /* Parse a block. */ |
1794 | static void parse_block(LexState *ls) | ||
1762 | { | 1795 | { |
1763 | /* block -> chunk */ | ||
1764 | FuncState *fs = ls->fs; | 1796 | FuncState *fs = ls->fs; |
1765 | FuncBlock bl; | 1797 | FuncScope bl; |
1766 | enterblock(fs, &bl, 0); | 1798 | scope_begin(fs, &bl, 0); |
1767 | chunk(ls); | 1799 | parse_chunk(ls); |
1768 | lua_assert(bl.breaklist == NO_JMP); | 1800 | lua_assert(bl.breaklist == NO_JMP); |
1769 | leaveblock(fs); | 1801 | scope_end(fs); |
1770 | } | 1802 | } |
1771 | 1803 | ||
1772 | /* -- Statements ---------------------------------------------------------- */ | 1804 | /* -- Assignments --------------------------------------------------------- */ |
1773 | 1805 | ||
1774 | /* | 1806 | /* List of LHS variables. */ |
1775 | ** structure to chain all variables in the left-hand side of an | 1807 | typedef struct LHSVarList { |
1776 | ** assignment | 1808 | ExpDesc v; /* LHS variable. */ |
1777 | */ | 1809 | struct LHSVarList *prev; /* Link to previous LHS variable. */ |
1778 | struct LHS_assign { | 1810 | } LHSVarList; |
1779 | ExpDesc v; /* variable (global, local, upvalue, or indexed) */ | ||
1780 | struct LHS_assign *prev; | ||
1781 | }; | ||
1782 | 1811 | ||
1783 | /* | 1812 | /* Eliminate write-after-read hazards for local variable assignment. */ |
1784 | ** check whether, in an assignment to a local variable, the local variable | 1813 | static void assign_hazard(LexState *ls, LHSVarList *lh, const ExpDesc *v) |
1785 | ** is needed in a previous assignment (to a table). If so, save original | ||
1786 | ** local value in a safe place and use this safe copy in the previous | ||
1787 | ** assignment. | ||
1788 | */ | ||
1789 | static void check_conflict(LexState *ls, struct LHS_assign *lh, | ||
1790 | const ExpDesc *v) | ||
1791 | { | 1814 | { |
1792 | FuncState *fs = ls->fs; | 1815 | FuncState *fs = ls->fs; |
1793 | BCReg reg = fs->freereg; /* eventual position to save local variable */ | 1816 | BCReg reg = v->u.s.info; /* Check against this variable. */ |
1794 | int conflict = 0; | 1817 | BCReg tmp = fs->freereg; /* Rename to this temp. register (if needed). */ |
1818 | int hazard = 0; | ||
1795 | for (; lh; lh = lh->prev) { | 1819 | for (; lh; lh = lh->prev) { |
1796 | if (lh->v.k == VINDEXED) { | 1820 | if (lh->v.k == VINDEXED) { |
1797 | if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ | 1821 | if (lh->v.u.s.info == reg) { /* t[i], t = 1, 2 */ |
1798 | conflict = 1; | 1822 | hazard = 1; |
1799 | lh->v.u.s.info = reg; /* previous assignment will use safe copy */ | 1823 | lh->v.u.s.info = tmp; |
1800 | } | 1824 | } |
1801 | if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */ | 1825 | if (lh->v.u.s.aux == reg) { /* t[i], i = 1, 2 */ |
1802 | conflict = 1; | 1826 | hazard = 1; |
1803 | lh->v.u.s.aux = reg; /* previous assignment will use safe copy */ | 1827 | lh->v.u.s.aux = tmp; |
1804 | } | 1828 | } |
1805 | } | 1829 | } |
1806 | } | 1830 | } |
1807 | if (conflict) { | 1831 | if (hazard) { |
1808 | emitAD(fs, BC_MOV, reg, v->u.s.info); /* make copy */ | 1832 | bcemit_AD(fs, BC_MOV, tmp, reg); /* Rename conflicting variable. */ |
1809 | reserveregs(fs, 1); | 1833 | bcreg_reserve(fs, 1); |
1834 | } | ||
1835 | } | ||
1836 | |||
1837 | /* Adjust LHS/RHS of an assignment. */ | ||
1838 | static void assign_adjust(LexState *ls, BCReg nvars, BCReg nexps, ExpDesc *e) | ||
1839 | { | ||
1840 | FuncState *fs = ls->fs; | ||
1841 | int32_t extra = (int32_t)nvars - (int32_t)nexps; | ||
1842 | if (e->k == VCALL) { | ||
1843 | extra++; /* Compensate for the VCALL itself. */ | ||
1844 | if (extra < 0) extra = 0; | ||
1845 | setbc_b(bcptr(fs, e), extra+1); /* Fixup call results. */ | ||
1846 | if (extra > 1) bcreg_reserve(fs, (BCReg)extra-1); | ||
1847 | } else { | ||
1848 | if (e->k != VVOID) | ||
1849 | expr_tonextreg(fs, e); /* Close last expression. */ | ||
1850 | if (extra > 0) { /* Leftover LHS are set to nil. */ | ||
1851 | BCReg reg = fs->freereg; | ||
1852 | bcreg_reserve(fs, (BCReg)extra); | ||
1853 | bcemit_nil(fs, reg, (BCReg)extra); | ||
1854 | } | ||
1810 | } | 1855 | } |
1811 | } | 1856 | } |
1812 | 1857 | ||
1813 | static void assignment(LexState *ls, struct LHS_assign *lh, BCReg nvars) | 1858 | /* Recursively parse assignment statement. */ |
1859 | static void parse_assignment(LexState *ls, LHSVarList *lh, BCReg nvars) | ||
1814 | { | 1860 | { |
1815 | ExpDesc e; | 1861 | ExpDesc e; |
1816 | checkcond(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, LJ_ERR_XSYNTAX); | 1862 | checkcond(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, LJ_ERR_XSYNTAX); |
1817 | if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ | 1863 | if (lex_opt(ls, ',')) { /* Collect LHS list and recurse upwards. */ |
1818 | struct LHS_assign nv; | 1864 | LHSVarList vl; |
1819 | nv.prev = lh; | 1865 | vl.prev = lh; |
1820 | primaryexp(ls, &nv.v); | 1866 | expr_primary(ls, &vl.v); |
1821 | if (nv.v.k == VLOCAL) | 1867 | if (vl.v.k == VLOCAL) |
1822 | check_conflict(ls, lh, &nv.v); | 1868 | assign_hazard(ls, lh, &vl.v); |
1823 | checklimit(ls->fs, ls->level + nvars, LJ_MAX_XLEVEL, "variable names"); | 1869 | checklimit(ls->fs, ls->level + nvars, LJ_MAX_XLEVEL, "variable names"); |
1824 | assignment(ls, &nv, nvars+1); | 1870 | parse_assignment(ls, &vl, nvars+1); |
1825 | } else { /* assignment -> `=' explist1 */ | 1871 | } else { /* Parse RHS. */ |
1826 | BCReg nexps; | 1872 | BCReg nexps; |
1827 | checknext(ls, '='); | 1873 | lex_check(ls, '='); |
1828 | nexps = explist1(ls, &e); | 1874 | nexps = expr_list(ls, &e); |
1829 | if (nexps == nvars) { | 1875 | if (nexps == nvars) { |
1830 | if (e.k == VCALL) { | 1876 | if (e.k == VCALL) { |
1831 | if (bc_op(*bcptr(ls->fs, &e)) == BC_VARG) { | 1877 | if (bc_op(*bcptr(ls->fs, &e)) == BC_VARG) { /* Vararg assignment. */ |
1832 | ls->fs->freereg--; | 1878 | ls->fs->freereg--; |
1833 | e.k = VRELOCABLE; | 1879 | e.k = VRELOCABLE; |
1834 | } else { | 1880 | } else { /* Multiple call results. */ |
1835 | e.u.s.info = e.u.s.aux; | 1881 | e.u.s.info = e.u.s.aux; /* Base of call is not relocatable. */ |
1836 | e.k = VNONRELOC; | 1882 | e.k = VNONRELOC; |
1837 | } | 1883 | } |
1838 | } | 1884 | } |
1839 | storevar(ls->fs, &lh->v, &e); | 1885 | bcemit_store(ls->fs, &lh->v, &e); |
1840 | return; | 1886 | return; |
1841 | } | 1887 | } |
1842 | adjust_assign(ls, nvars, nexps, &e); | 1888 | assign_adjust(ls, nvars, nexps, &e); |
1843 | if (nexps > nvars) | 1889 | if (nexps > nvars) |
1844 | ls->fs->freereg -= nexps - nvars; /* remove extra values */ | 1890 | ls->fs->freereg -= nexps - nvars; /* Drop leftover regs. */ |
1845 | } | 1891 | } |
1846 | init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ | 1892 | /* Assign RHS to LHS and recurse downwards. */ |
1847 | storevar(ls->fs, &lh->v, &e); | 1893 | expr_init(&e, VNONRELOC, ls->fs->freereg-1); |
1894 | bcemit_store(ls->fs, &lh->v, &e); | ||
1848 | } | 1895 | } |
1849 | 1896 | ||
1850 | static void breakstat(LexState *ls) | 1897 | /* Parse call statement or assignment. */ |
1898 | static void parse_call_assign(LexState *ls) | ||
1851 | { | 1899 | { |
1852 | FuncState *fs = ls->fs; | 1900 | FuncState *fs = ls->fs; |
1853 | FuncBlock *bl = fs->bl; | 1901 | LHSVarList vl; |
1854 | int upval = 0; | 1902 | expr_primary(ls, &vl.v); |
1855 | while (bl && !bl->isbreakable) { | 1903 | if (vl.v.k == VCALL) { /* Function call statement. */ |
1856 | upval |= bl->upval; | 1904 | setbc_b(bcptr(fs, &vl.v), 1); /* No results. */ |
1857 | bl = bl->previous; | 1905 | } else { /* Start of an assignment. */ |
1906 | vl.prev = NULL; | ||
1907 | parse_assignment(ls, &vl, 1); | ||
1858 | } | 1908 | } |
1859 | if (!bl) | ||
1860 | err_syntax(ls, LJ_ERR_XBREAK); | ||
1861 | if (upval) | ||
1862 | emitAJ(fs, BC_UCLO, bl->nactvar, 0); | ||
1863 | concatjumps(fs, &bl->breaklist, emit_jump(fs)); | ||
1864 | } | 1909 | } |
1865 | 1910 | ||
1866 | static void whilestat(LexState *ls, BCLine line) | 1911 | /* Parse 'local' statement. */ |
1912 | static void parse_local(LexState *ls) | ||
1913 | { | ||
1914 | if (lex_opt(ls, TK_function)) { /* Local function declaration. */ | ||
1915 | ExpDesc v, b; | ||
1916 | FuncState *fs = ls->fs; | ||
1917 | var_new(ls, 0, lex_str(ls)); | ||
1918 | expr_init(&v, VLOCAL, fs->freereg); | ||
1919 | bcreg_reserve(fs, 1); | ||
1920 | var_add(ls, 1); | ||
1921 | parse_body(ls, &b, 0, ls->linenumber); | ||
1922 | bcemit_store(fs, &v, &b); | ||
1923 | /* The upvalue is in scope, but the local is only valid after the store. */ | ||
1924 | var_get(fs, fs->nactvar - 1).startpc = fs->pc; | ||
1925 | } else { /* Local variable declaration. */ | ||
1926 | ExpDesc e; | ||
1927 | BCReg nexps, nvars = 0; | ||
1928 | do { /* Collect LHS. */ | ||
1929 | var_new(ls, nvars++, lex_str(ls)); | ||
1930 | } while (lex_opt(ls, ',')); | ||
1931 | if (lex_opt(ls, '=')) { /* Optional RHS. */ | ||
1932 | nexps = expr_list(ls, &e); | ||
1933 | } else { /* Or implicitly set to nil. */ | ||
1934 | e.k = VVOID; | ||
1935 | nexps = 0; | ||
1936 | } | ||
1937 | assign_adjust(ls, nvars, nexps, &e); | ||
1938 | var_add(ls, nvars); | ||
1939 | } | ||
1940 | } | ||
1941 | |||
1942 | /* Parse 'function' statement. */ | ||
1943 | static void parse_func(LexState *ls, BCLine line) | ||
1944 | { | ||
1945 | FuncState *fs; | ||
1946 | ExpDesc v, b; | ||
1947 | int needself = 0; | ||
1948 | lj_lex_next(ls); /* Skip 'function'. */ | ||
1949 | /* Parse function name. */ | ||
1950 | var_lookup(ls, &v); | ||
1951 | while (ls->token == '.') /* Multiple dot-separated fields. */ | ||
1952 | expr_field(ls, &v); | ||
1953 | if (ls->token == ':') { /* Optional colon to signify method call. */ | ||
1954 | needself = 1; | ||
1955 | expr_field(ls, &v); | ||
1956 | } | ||
1957 | parse_body(ls, &b, needself, line); | ||
1958 | fs = ls->fs; | ||
1959 | bcemit_store(fs, &v, &b); | ||
1960 | proto_lineinfo(fs->pt)[fs->pc - 1] = line; /* Set line for the store. */ | ||
1961 | } | ||
1962 | |||
1963 | /* -- Loop and conditional statements ------------------------------------- */ | ||
1964 | |||
1965 | /* Parse 'while' statement. */ | ||
1966 | static void parse_while(LexState *ls, BCLine line) | ||
1867 | { | 1967 | { |
1868 | /* whilestat -> WHILE cond DO block END */ | ||
1869 | FuncState *fs = ls->fs; | 1968 | FuncState *fs = ls->fs; |
1870 | BCPos start, loop, condexit; | 1969 | BCPos start, loop, condexit; |
1871 | FuncBlock bl; | 1970 | FuncScope bl; |
1872 | lj_lex_next(ls); /* skip WHILE */ | 1971 | lj_lex_next(ls); /* Skip 'while'. */ |
1873 | start = fs->lasttarget = fs->pc; | 1972 | start = fs->lasttarget = fs->pc; |
1874 | condexit = condexpr(ls); | 1973 | condexit = expr_cond(ls); |
1875 | enterblock(fs, &bl, 1); | 1974 | scope_begin(fs, &bl, 1); |
1876 | checknext(ls, TK_do); | 1975 | lex_check(ls, TK_do); |
1877 | loop = emitAD(fs, BC_LOOP, fs->nactvar, 0); | 1976 | loop = bcemit_AD(fs, BC_LOOP, fs->nactvar, 0); |
1878 | block(ls); | 1977 | parse_block(ls); |
1879 | patchlist(fs, emit_jump(fs), start); | 1978 | jmp_patch(fs, bcemit_jmp(fs), start); |
1880 | checkmatch(ls, TK_end, TK_while, line); | 1979 | lex_match(ls, TK_end, TK_while, line); |
1881 | leaveblock(fs); | 1980 | scope_end(fs); |
1882 | patchtohere(fs, condexit); /* false conditions finish the loop */ | 1981 | jmp_tohere(fs, condexit); |
1883 | fixjump(fs, loop, fs->pc); | 1982 | jmp_patchins(fs, loop, fs->pc); |
1884 | } | 1983 | } |
1885 | 1984 | ||
1886 | static void repeatstat(LexState *ls, BCLine line) | 1985 | /* Parse 'repeat' statement. */ |
1986 | static void parse_repeat(LexState *ls, BCLine line) | ||
1887 | { | 1987 | { |
1888 | /* repeatstat -> REPEAT block UNTIL cond */ | ||
1889 | FuncState *fs = ls->fs; | 1988 | FuncState *fs = ls->fs; |
1890 | BCPos loop = fs->lasttarget = fs->pc; | 1989 | BCPos loop = fs->lasttarget = fs->pc; |
1891 | BCPos condexit; | 1990 | BCPos condexit; |
1892 | FuncBlock bl1, bl2; | 1991 | FuncScope bl1, bl2; |
1893 | enterblock(fs, &bl1, 1); /* loop block */ | 1992 | scope_begin(fs, &bl1, 1); /* Breakable loop scope. */ |
1894 | enterblock(fs, &bl2, 0); /* scope block */ | 1993 | scope_begin(fs, &bl2, 0); /* Inner scope. */ |
1895 | lj_lex_next(ls); /* skip REPEAT */ | 1994 | lj_lex_next(ls); /* Skip 'repeat'. */ |
1896 | emitAD(fs, BC_LOOP, fs->nactvar, 0); | 1995 | bcemit_AD(fs, BC_LOOP, fs->nactvar, 0); |
1897 | chunk(ls); | 1996 | parse_chunk(ls); |
1898 | checkmatch(ls, TK_until, TK_repeat, line); | 1997 | lex_match(ls, TK_until, TK_repeat, line); |
1899 | condexit = condexpr(ls); /* read condition (inside scope block) */ | 1998 | condexit = expr_cond(ls); /* Parse condition (still inside inner scope). */ |
1900 | if (!bl2.upval) { /* no upvalues? */ | 1999 | if (!bl2.upval) { /* No upvalues? Just end inner scope. */ |
1901 | leaveblock(fs); /* finish scope */ | 2000 | scope_end(fs); |
1902 | } else { /* complete semantics when there are upvalues */ | 2001 | } else { /* Otherwise generate: cond: UCLO+JMP out, !cond: UCLO+JMP loop. */ |
1903 | breakstat(ls); /* if condition then break */ | 2002 | parse_break(ls); /* Break from loop and close upvalues. */ |
1904 | patchtohere(fs, condexit); /* else... */ | 2003 | jmp_tohere(fs, condexit); |
1905 | leaveblock(fs); /* finish scope... */ | 2004 | scope_end(fs); /* End inner scope and close upvalues. */ |
1906 | condexit = emit_jump(fs); /* and repeat */ | 2005 | condexit = bcemit_jmp(fs); |
1907 | } | 2006 | } |
1908 | patchlist(fs, condexit, loop); /* close the loop */ | 2007 | jmp_patch(fs, condexit, loop); /* Jump backwards if !cond. */ |
1909 | fixjump(fs, loop, fs->pc); | 2008 | jmp_patchins(fs, loop, fs->pc); |
1910 | leaveblock(fs); /* finish loop */ | 2009 | scope_end(fs); /* End loop scope. */ |
1911 | } | 2010 | } |
1912 | 2011 | ||
1913 | static void exp1(LexState *ls) | 2012 | /* Parse body of a 'for' statement. */ |
1914 | { | 2013 | static void parse_for_body(LexState *ls, BCReg base, BCLine line, |
1915 | ExpDesc e; | 2014 | BCReg nvars, int isnum) |
1916 | expr(ls, &e); | 2015 | { |
1917 | exp2nextreg(ls->fs, &e); | 2016 | FuncScope bl; |
1918 | } | ||
1919 | |||
1920 | static void forbody(LexState *ls, BCReg base, BCLine line, BCReg nvars, | ||
1921 | int isnum) | ||
1922 | { | ||
1923 | /* forbody -> DO block */ | ||
1924 | FuncBlock bl; | ||
1925 | FuncState *fs = ls->fs; | 2017 | FuncState *fs = ls->fs; |
1926 | BCPos loop, loopend; | 2018 | BCPos loop, loopend; |
1927 | adjustlocalvars(ls, 3); /* control variables */ | 2019 | var_add(ls, 3); /* Hidden control variables. */ |
1928 | checknext(ls, TK_do); | 2020 | lex_check(ls, TK_do); |
1929 | loop = isnum ? emitAJ(fs, BC_FORI, base, NO_JMP) : | 2021 | loop = isnum ? bcemit_AJ(fs, BC_FORI, base, NO_JMP) : |
1930 | emitAJ(fs, BC_JMP, fs->freereg, NO_JMP); | 2022 | bcemit_AJ(fs, BC_JMP, fs->freereg, NO_JMP); |
1931 | enterblock(fs, &bl, 0); /* scope for declared variables */ | 2023 | scope_begin(fs, &bl, 0); /* Scope for visible variables. */ |
1932 | adjustlocalvars(ls, nvars); | 2024 | var_add(ls, nvars); |
1933 | reserveregs(fs, nvars); | 2025 | bcreg_reserve(fs, nvars); |
1934 | block(ls); | 2026 | parse_block(ls); |
1935 | leaveblock(fs); /* end of scope for declared variables */ | 2027 | scope_end(fs); |
2028 | /* Perform loop inversion. Loop control instructions are at the end. */ | ||
1936 | if (isnum) { | 2029 | if (isnum) { |
1937 | loopend = emitAJ(fs, BC_FORL, base, NO_JMP); | 2030 | loopend = bcemit_AJ(fs, BC_FORL, base, NO_JMP); |
1938 | fixjump(fs, loop, fs->pc); | 2031 | jmp_patchins(fs, loop, fs->pc); |
1939 | } else { | 2032 | } else { |
1940 | fixjump(fs, loop, fs->pc); | 2033 | jmp_patchins(fs, loop, fs->pc); |
1941 | emitABC(fs, BC_ITERC, base+3, nvars+1, 2+1); | 2034 | bcemit_ABC(fs, BC_ITERC, base+3, nvars+1, 2+1); |
1942 | loopend = emitAJ(fs, BC_ITERL, base+3, NO_JMP); | 2035 | loopend = bcemit_AJ(fs, BC_ITERL, base+3, NO_JMP); |
1943 | proto_lineinfo(fs->pt)[loopend-1] = line; | 2036 | proto_lineinfo(fs->pt)[loopend-1] = line; |
1944 | } | 2037 | } |
1945 | proto_lineinfo(fs->pt)[loopend] = line; /* pretend last op starts the loop */ | 2038 | proto_lineinfo(fs->pt)[loopend] = line; /* Fix line for control ins. */ |
1946 | fixjump(fs, loopend, loop+1); | 2039 | jmp_patchins(fs, loopend, loop+1); |
1947 | } | 2040 | } |
1948 | 2041 | ||
1949 | static void fornum(LexState *ls, GCstr *varname, BCLine line) | 2042 | /* Parse numeric 'for'. */ |
2043 | static void parse_for_num(LexState *ls, GCstr *varname, BCLine line) | ||
1950 | { | 2044 | { |
1951 | /* fornum -> NAME = exp1,exp1[,exp1] forbody */ | ||
1952 | FuncState *fs = ls->fs; | 2045 | FuncState *fs = ls->fs; |
1953 | BCReg base = fs->freereg; | 2046 | BCReg base = fs->freereg; |
1954 | new_localvarliteral(ls, "(for index)", FORL_IDX); | 2047 | /* Hidden control variables. */ |
1955 | new_localvarliteral(ls, "(for limit)", FORL_STOP); | 2048 | var_new_lit(ls, "(for index)", FORL_IDX); |
1956 | new_localvarliteral(ls, "(for step)", FORL_STEP); | 2049 | var_new_lit(ls, "(for limit)", FORL_STOP); |
1957 | new_localvar(ls, varname, FORL_EXT); | 2050 | var_new_lit(ls, "(for step)", FORL_STEP); |
1958 | checknext(ls, '='); | 2051 | /* Visible copy of index variable. */ |
1959 | exp1(ls); /* initial value */ | 2052 | var_new(ls, FORL_EXT, varname); |
1960 | checknext(ls, ','); | 2053 | lex_check(ls, '='); |
1961 | exp1(ls); /* limit */ | 2054 | expr_next(ls); |
1962 | if (testnext(ls, ',')) { | 2055 | lex_check(ls, ','); |
1963 | exp1(ls); /* optional step */ | 2056 | expr_next(ls); |
1964 | } else { /* default step = 1 */ | 2057 | if (lex_opt(ls, ',')) { |
1965 | emitAD(fs, BC_KSHORT, fs->freereg, 1); | 2058 | expr_next(ls); |
1966 | reserveregs(fs, 1); | 2059 | } else { |
1967 | } | 2060 | bcemit_AD(fs, BC_KSHORT, fs->freereg, 1); /* Default step is 1. */ |
1968 | forbody(ls, base, line, 1, 1); | 2061 | bcreg_reserve(fs, 1); |
1969 | } | 2062 | } |
1970 | 2063 | parse_for_body(ls, base, line, 1, 1); | |
1971 | static void forlist(LexState *ls, GCstr *indexname) | 2064 | } |
1972 | { | 2065 | |
1973 | /* forlist -> NAME {,NAME} IN explist1 forbody */ | 2066 | /* Parse 'for' iterator. */ |
2067 | static void parse_for_iter(LexState *ls, GCstr *indexname) | ||
2068 | { | ||
1974 | FuncState *fs = ls->fs; | 2069 | FuncState *fs = ls->fs; |
1975 | ExpDesc e; | 2070 | ExpDesc e; |
1976 | BCReg nvars = 0; | 2071 | BCReg nvars = 0; |
1977 | BCLine line; | 2072 | BCLine line; |
1978 | BCReg base = fs->freereg; | 2073 | BCReg base = fs->freereg; |
1979 | /* create control variables */ | 2074 | /* Hidden control variables. */ |
1980 | new_localvarliteral(ls, "(for generator)", nvars++); | 2075 | var_new_lit(ls, "(for generator)", nvars++); |
1981 | new_localvarliteral(ls, "(for state)", nvars++); | 2076 | var_new_lit(ls, "(for state)", nvars++); |
1982 | new_localvarliteral(ls, "(for control)", nvars++); | 2077 | var_new_lit(ls, "(for control)", nvars++); |
1983 | /* create declared variables */ | 2078 | /* Visible variables returned from iterator. */ |
1984 | new_localvar(ls, indexname, nvars++); | 2079 | var_new(ls, nvars++, indexname); |
1985 | while (testnext(ls, ',')) | 2080 | while (lex_opt(ls, ',')) |
1986 | new_localvar(ls, str_checkname(ls), nvars++); | 2081 | var_new(ls, nvars++, lex_str(ls)); |
1987 | checknext(ls, TK_in); | 2082 | lex_check(ls, TK_in); |
1988 | line = ls->linenumber; | 2083 | line = ls->linenumber; |
1989 | adjust_assign(ls, 3, explist1(ls, &e), &e); | 2084 | assign_adjust(ls, 3, expr_list(ls, &e), &e); |
1990 | checkframe(fs, 3); /* extra space to call generator */ | 2085 | bcreg_bump(fs, 3); /* The iterator needs another 3 slots (func + 2 args). */ |
1991 | forbody(ls, base, line, nvars - 3, 0); | 2086 | parse_for_body(ls, base, line, nvars - 3, 0); |
1992 | } | 2087 | } |
1993 | 2088 | ||
1994 | static void forstat(LexState *ls, BCLine line) | 2089 | /* Parse 'for' statement. */ |
2090 | static void parse_for(LexState *ls, BCLine line) | ||
1995 | { | 2091 | { |
1996 | /* forstat -> FOR (fornum | forlist) END */ | ||
1997 | FuncState *fs = ls->fs; | 2092 | FuncState *fs = ls->fs; |
1998 | GCstr *varname; | 2093 | GCstr *varname; |
1999 | FuncBlock bl; | 2094 | FuncScope bl; |
2000 | enterblock(fs, &bl, 1); /* scope for loop and control variables */ | 2095 | scope_begin(fs, &bl, 1); /* Breakable loop scope. */ |
2001 | lj_lex_next(ls); /* skip `for' */ | 2096 | lj_lex_next(ls); /* Skip 'for'. */ |
2002 | varname = str_checkname(ls); /* first variable name */ | 2097 | varname = lex_str(ls); /* Get first variable name. */ |
2003 | switch (ls->token) { | 2098 | if (ls->token == '=') |
2004 | case '=': fornum(ls, varname, line); break; | 2099 | parse_for_num(ls, varname, line); |
2005 | case ',': case TK_in: forlist(ls, varname); break; | 2100 | else if (ls->token == ',' || ls->token == TK_in) |
2006 | default: err_syntax(ls, LJ_ERR_XFOR); | 2101 | parse_for_iter(ls, varname); |
2007 | } | 2102 | else |
2008 | checkmatch(ls, TK_end, TK_for, line); | 2103 | err_syntax(ls, LJ_ERR_XFOR); |
2009 | leaveblock(fs); /* loop scope (`break' jumps to this point) */ | 2104 | lex_match(ls, TK_end, TK_for, line); |
2105 | scope_end(fs); /* Resolve break list. */ | ||
2010 | } | 2106 | } |
2011 | 2107 | ||
2012 | static BCPos test_then_block(LexState *ls) | 2108 | /* Parse condition and 'then' block. */ |
2109 | static BCPos parse_then(LexState *ls) | ||
2013 | { | 2110 | { |
2014 | /* test_then_block -> [IF | ELSEIF] cond THEN block */ | ||
2015 | BCPos condexit; | 2111 | BCPos condexit; |
2016 | lj_lex_next(ls); /* skip IF or ELSEIF */ | 2112 | lj_lex_next(ls); /* Skip 'if' or 'elseif'. */ |
2017 | condexit = condexpr(ls); | 2113 | condexit = expr_cond(ls); |
2018 | checknext(ls, TK_then); | 2114 | lex_check(ls, TK_then); |
2019 | block(ls); /* `then' part */ | 2115 | parse_block(ls); |
2020 | return condexit; | 2116 | return condexit; |
2021 | } | 2117 | } |
2022 | 2118 | ||
2023 | static void ifstat(LexState *ls, BCLine line) | 2119 | /* Parse 'if' statement. */ |
2120 | static void parse_if(LexState *ls, BCLine line) | ||
2024 | { | 2121 | { |
2025 | /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ | ||
2026 | FuncState *fs = ls->fs; | 2122 | FuncState *fs = ls->fs; |
2027 | BCPos flist; | 2123 | BCPos flist; |
2028 | BCPos escapelist = NO_JMP; | 2124 | BCPos escapelist = NO_JMP; |
2029 | flist = test_then_block(ls); /* IF cond THEN block */ | 2125 | flist = parse_then(ls); |
2030 | while (ls->token == TK_elseif) { | 2126 | while (ls->token == TK_elseif) { /* Parse multiple 'elseif' blocks. */ |
2031 | concatjumps(fs, &escapelist, emit_jump(fs)); | 2127 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); |
2032 | patchtohere(fs, flist); | 2128 | jmp_tohere(fs, flist); |
2033 | flist = test_then_block(ls); /* ELSEIF cond THEN block */ | 2129 | flist = parse_then(ls); |
2034 | } | 2130 | } |
2035 | if (ls->token == TK_else) { | 2131 | if (ls->token == TK_else) { /* Parse optional 'else' block. */ |
2036 | concatjumps(fs, &escapelist, emit_jump(fs)); | 2132 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); |
2037 | patchtohere(fs, flist); | 2133 | jmp_tohere(fs, flist); |
2038 | lj_lex_next(ls); /* skip ELSE (after patch, for correct line info) */ | 2134 | lj_lex_next(ls); /* Skip 'else'. */ |
2039 | block(ls); /* `else' part */ | 2135 | parse_block(ls); |
2040 | } else { | ||
2041 | concatjumps(fs, &escapelist, flist); | ||
2042 | } | ||
2043 | patchtohere(fs, escapelist); | ||
2044 | checkmatch(ls, TK_end, TK_if, line); | ||
2045 | } | ||
2046 | |||
2047 | static void localfunc(LexState *ls) | ||
2048 | { | ||
2049 | ExpDesc v, b; | ||
2050 | FuncState *fs = ls->fs; | ||
2051 | new_localvar(ls, str_checkname(ls), 0); | ||
2052 | init_exp(&v, VLOCAL, fs->freereg); | ||
2053 | reserveregs(fs, 1); | ||
2054 | adjustlocalvars(ls, 1); | ||
2055 | body(ls, &b, 0, ls->linenumber); | ||
2056 | storevar(fs, &v, &b); | ||
2057 | /* debug information will only see the variable after this point! */ | ||
2058 | getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; | ||
2059 | } | ||
2060 | |||
2061 | static void localstat(LexState *ls) | ||
2062 | { | ||
2063 | /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ | ||
2064 | BCReg nvars = 0; | ||
2065 | BCReg nexps; | ||
2066 | ExpDesc e; | ||
2067 | do { | ||
2068 | new_localvar(ls, str_checkname(ls), nvars++); | ||
2069 | } while (testnext(ls, ',')); | ||
2070 | if (testnext(ls, '=')) { | ||
2071 | nexps = explist1(ls, &e); | ||
2072 | } else { | 2136 | } else { |
2073 | e.k = VVOID; | 2137 | jmp_append(fs, &escapelist, flist); |
2074 | nexps = 0; | ||
2075 | } | ||
2076 | adjust_assign(ls, nvars, nexps, &e); | ||
2077 | adjustlocalvars(ls, nvars); | ||
2078 | } | ||
2079 | |||
2080 | static int func_name(LexState *ls, ExpDesc *v) | ||
2081 | { | ||
2082 | /* func_name -> NAME {field} [`:' NAME] */ | ||
2083 | int needself = 0; | ||
2084 | singlevar(ls, v); | ||
2085 | while (ls->token == '.') | ||
2086 | field(ls, v); | ||
2087 | if (ls->token == ':') { | ||
2088 | needself = 1; | ||
2089 | field(ls, v); | ||
2090 | } | ||
2091 | return needself; | ||
2092 | } | ||
2093 | |||
2094 | static void funcstat(LexState *ls, BCLine line) | ||
2095 | { | ||
2096 | /* funcstat -> FUNCTION func_name body */ | ||
2097 | FuncState *fs; | ||
2098 | int needself; | ||
2099 | ExpDesc v, b; | ||
2100 | lj_lex_next(ls); /* skip FUNCTION */ | ||
2101 | needself = func_name(ls, &v); | ||
2102 | body(ls, &b, needself, line); | ||
2103 | fs = ls->fs; | ||
2104 | storevar(fs, &v, &b); | ||
2105 | proto_lineinfo(fs->pt)[fs->pc - 1] = line; | ||
2106 | } | ||
2107 | |||
2108 | static void exprstat(LexState *ls) | ||
2109 | { | ||
2110 | /* stat -> func | assignment */ | ||
2111 | FuncState *fs = ls->fs; | ||
2112 | struct LHS_assign v; | ||
2113 | primaryexp(ls, &v.v); | ||
2114 | if (v.v.k == VCALL) { /* stat -> func */ | ||
2115 | setbc_b(bcptr(fs, &v.v), 1); /* call statement uses no results */ | ||
2116 | } else { /* stat -> assignment */ | ||
2117 | v.prev = NULL; | ||
2118 | assignment(ls, &v, 1); | ||
2119 | } | ||
2120 | } | ||
2121 | |||
2122 | static int block_follow(LexToken token) | ||
2123 | { | ||
2124 | switch (token) { | ||
2125 | case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof: | ||
2126 | return 1; | ||
2127 | default: | ||
2128 | return 0; | ||
2129 | } | 2138 | } |
2139 | jmp_tohere(fs, escapelist); | ||
2140 | lex_match(ls, TK_end, TK_if, line); | ||
2130 | } | 2141 | } |
2131 | 2142 | ||
2132 | static void retstat(LexState *ls) | 2143 | /* -- Parse statements ---------------------------------------------------- */ |
2133 | { | ||
2134 | /* stat -> RETURN explist */ | ||
2135 | BCIns ins; | ||
2136 | FuncState *fs = ls->fs; | ||
2137 | lj_lex_next(ls); /* skip RETURN */ | ||
2138 | fs->pt->flags |= PROTO_HAS_RETURN; | ||
2139 | if (block_follow(ls->token) || ls->token == ';') { | ||
2140 | ins = BCINS_AD(BC_RET0, 0, 1); /* return no values */ | ||
2141 | } else { | ||
2142 | ExpDesc e; | ||
2143 | BCReg nret = explist1(ls, &e); /* optional return values */ | ||
2144 | if (nret == 1) { | ||
2145 | if (e.k == VCALL) { | ||
2146 | BCIns *i = bcptr(fs, &e); | ||
2147 | /* It doesn't pay off to add BC_VARGT just for 'return ...'. */ | ||
2148 | if (bc_op(*i) == BC_VARG) goto notailcall; | ||
2149 | fs->pc--; | ||
2150 | ins = BCINS_AD(bc_op(*i)-BC_CALL+BC_CALLT, bc_a(*i), bc_c(*i)); | ||
2151 | } else { | ||
2152 | ins = BCINS_AD(BC_RET1, exp2anyreg(fs, &e), 2); | ||
2153 | } | ||
2154 | } else { | ||
2155 | if (e.k == VCALL) { | ||
2156 | notailcall: | ||
2157 | setbc_b(bcptr(fs, &e), 0); | ||
2158 | ins = BCINS_AD(BC_RETM, fs->nactvar, e.u.s.aux - fs->nactvar); | ||
2159 | } else { | ||
2160 | exp2nextreg(fs, &e); /* values must go to the `stack' */ | ||
2161 | ins = BCINS_AD(BC_RET, fs->nactvar, nret+1); | ||
2162 | } | ||
2163 | } | ||
2164 | } | ||
2165 | if (fs->pt->flags & PROTO_HAS_FNEW) | ||
2166 | emitAJ(fs, BC_UCLO, 0, 0); | ||
2167 | emitINS(fs, ins); | ||
2168 | } | ||
2169 | 2144 | ||
2170 | static int statement(LexState *ls) | 2145 | /* Parse a statement. Returns 1 if it must be the last one in a chunk. */ |
2146 | static int parse_stmt(LexState *ls) | ||
2171 | { | 2147 | { |
2172 | BCLine line = ls->linenumber; /* may be needed for error messages */ | 2148 | BCLine line = ls->linenumber; |
2173 | switch (ls->token) { | 2149 | switch (ls->token) { |
2174 | case TK_if: | 2150 | case TK_if: |
2175 | ifstat(ls, line); | 2151 | parse_if(ls, line); |
2176 | return 0; | 2152 | break; |
2177 | case TK_while: | 2153 | case TK_while: |
2178 | whilestat(ls, line); | 2154 | parse_while(ls, line); |
2179 | return 0; | 2155 | break; |
2180 | case TK_do: | 2156 | case TK_do: |
2181 | lj_lex_next(ls); /* skip DO */ | 2157 | lj_lex_next(ls); |
2182 | block(ls); | 2158 | parse_block(ls); |
2183 | checkmatch(ls, TK_end, TK_do, line); | 2159 | lex_match(ls, TK_end, TK_do, line); |
2184 | return 0; | 2160 | break; |
2185 | case TK_for: | 2161 | case TK_for: |
2186 | forstat(ls, line); | 2162 | parse_for(ls, line); |
2187 | return 0; | 2163 | break; |
2188 | case TK_repeat: | 2164 | case TK_repeat: |
2189 | repeatstat(ls, line); | 2165 | parse_repeat(ls, line); |
2190 | return 0; | 2166 | break; |
2191 | case TK_function: | 2167 | case TK_function: |
2192 | funcstat(ls, line); | 2168 | parse_func(ls, line); |
2193 | return 0; | 2169 | break; |
2194 | case TK_local: | 2170 | case TK_local: |
2195 | lj_lex_next(ls); /* skip LOCAL */ | 2171 | lj_lex_next(ls); |
2196 | if (testnext(ls, TK_function)) /* local function? */ | 2172 | parse_local(ls); |
2197 | localfunc(ls); | 2173 | break; |
2198 | else | ||
2199 | localstat(ls); | ||
2200 | return 0; | ||
2201 | case TK_return: | 2174 | case TK_return: |
2202 | retstat(ls); | 2175 | parse_return(ls); |
2203 | return 1; /* must be last statement */ | 2176 | return 1; /* Must be last. */ |
2204 | case TK_break: | 2177 | case TK_break: |
2205 | lj_lex_next(ls); /* skip BREAK */ | 2178 | lj_lex_next(ls); |
2206 | breakstat(ls); | 2179 | parse_break(ls); |
2207 | return 1; /* must be last statement */ | 2180 | return 1; /* Must be last. */ |
2208 | default: | 2181 | default: |
2209 | exprstat(ls); | 2182 | parse_call_assign(ls); |
2210 | return 0; | 2183 | break; |
2211 | } | 2184 | } |
2185 | return 0; | ||
2212 | } | 2186 | } |
2213 | 2187 | ||
2214 | static void chunk(LexState *ls) | 2188 | /* A chunk is a list of statements optionally separated by semicolons. */ |
2189 | static void parse_chunk(LexState *ls) | ||
2215 | { | 2190 | { |
2216 | /* chunk -> { stat [`;'] } */ | ||
2217 | int islast = 0; | 2191 | int islast = 0; |
2218 | enterlevel(ls); | 2192 | synlevel_begin(ls); |
2219 | while (!islast && !block_follow(ls->token)) { | 2193 | while (!islast && !endofblock(ls->token)) { |
2220 | islast = statement(ls); | 2194 | islast = parse_stmt(ls); |
2221 | testnext(ls, ';'); | 2195 | lex_opt(ls, ';'); |
2222 | lua_assert(ls->fs->pt->framesize >= ls->fs->freereg && | 2196 | lua_assert(ls->fs->framesize >= ls->fs->freereg && |
2223 | ls->fs->freereg >= ls->fs->nactvar); | 2197 | ls->fs->freereg >= ls->fs->nactvar); |
2224 | ls->fs->freereg = ls->fs->nactvar; /* free registers */ | 2198 | ls->fs->freereg = ls->fs->nactvar; /* Free registers after each stmt. */ |
2225 | } | 2199 | } |
2226 | leavelevel(ls); | 2200 | synlevel_end(ls); |
2201 | } | ||
2202 | |||
2203 | /* Entry point of bytecode parser. */ | ||
2204 | GCproto *lj_parse(LexState *ls) | ||
2205 | { | ||
2206 | struct FuncState fs; | ||
2207 | GCproto *pt; | ||
2208 | ls->level = 0; | ||
2209 | fs_init(ls, &fs, 0); | ||
2210 | fs.flags |= PROTO_IS_VARARG; /* Main chunk is always a vararg func. */ | ||
2211 | lj_lex_next(ls); /* Read-ahead first token. */ | ||
2212 | parse_chunk(ls); | ||
2213 | if (ls->token != TK_eof) | ||
2214 | err_token(ls, TK_eof); | ||
2215 | pt = fs_finish(ls, ls->linenumber); | ||
2216 | lua_assert(fs.prev == NULL); | ||
2217 | lua_assert(ls->fs == NULL); | ||
2218 | lua_assert(pt->sizeuv == 0); | ||
2219 | return pt; | ||
2227 | } | 2220 | } |
2228 | 2221 | ||