Mercurial
comparison third_party/luajit/src/lj_parse.c @ 186:8cf4ec5e2191 hg-web
Fixed merge conflict.
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Fri, 23 Jan 2026 22:38:59 -0800 |
| parents | 94705b5986b3 |
| children |
comparison
equal
deleted
inserted
replaced
| 176:fed99fc04e12 | 186:8cf4ec5e2191 |
|---|---|
| 1 /* | |
| 2 ** Lua parser (source code -> bytecode). | |
| 3 ** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h | |
| 4 ** | |
| 5 ** Major portions taken verbatim or adapted from the Lua interpreter. | |
| 6 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h | |
| 7 */ | |
| 8 | |
| 9 #define lj_parse_c | |
| 10 #define LUA_CORE | |
| 11 | |
| 12 #include "lj_obj.h" | |
| 13 #include "lj_gc.h" | |
| 14 #include "lj_err.h" | |
| 15 #include "lj_debug.h" | |
| 16 #include "lj_buf.h" | |
| 17 #include "lj_str.h" | |
| 18 #include "lj_tab.h" | |
| 19 #include "lj_func.h" | |
| 20 #include "lj_state.h" | |
| 21 #include "lj_bc.h" | |
| 22 #if LJ_HASFFI | |
| 23 #include "lj_ctype.h" | |
| 24 #endif | |
| 25 #include "lj_strfmt.h" | |
| 26 #include "lj_lex.h" | |
| 27 #include "lj_parse.h" | |
| 28 #include "lj_vm.h" | |
| 29 #include "lj_vmevent.h" | |
| 30 | |
| 31 /* -- Parser structures and definitions ----------------------------------- */ | |
| 32 | |
| 33 /* Expression kinds. */ | |
| 34 typedef enum { | |
| 35 /* Constant expressions must be first and in this order: */ | |
| 36 VKNIL, | |
| 37 VKFALSE, | |
| 38 VKTRUE, | |
| 39 VKSTR, /* sval = string value */ | |
| 40 VKNUM, /* nval = number value */ | |
| 41 VKLAST = VKNUM, | |
| 42 VKCDATA, /* nval = cdata value, not treated as a constant expression */ | |
| 43 /* Non-constant expressions follow: */ | |
| 44 VLOCAL, /* info = local register, aux = vstack index */ | |
| 45 VUPVAL, /* info = upvalue index, aux = vstack index */ | |
| 46 VGLOBAL, /* sval = string value */ | |
| 47 VINDEXED, /* info = table register, aux = index reg/byte/string const */ | |
| 48 VJMP, /* info = instruction PC */ | |
| 49 VRELOCABLE, /* info = instruction PC */ | |
| 50 VNONRELOC, /* info = result register */ | |
| 51 VCALL, /* info = instruction PC, aux = base */ | |
| 52 VVOID | |
| 53 } ExpKind; | |
| 54 | |
| 55 /* Expression descriptor. */ | |
| 56 typedef struct ExpDesc { | |
| 57 union { | |
| 58 struct { | |
| 59 uint32_t info; /* Primary info. */ | |
| 60 uint32_t aux; /* Secondary info. */ | |
| 61 } s; | |
| 62 TValue nval; /* Number value. */ | |
| 63 GCstr *sval; /* String value. */ | |
| 64 } u; | |
| 65 ExpKind k; | |
| 66 BCPos t; /* True condition jump list. */ | |
| 67 BCPos f; /* False condition jump list. */ | |
| 68 } ExpDesc; | |
| 69 | |
| 70 /* Macros for expressions. */ | |
| 71 #define expr_hasjump(e) ((e)->t != (e)->f) | |
| 72 | |
| 73 #define expr_isk(e) ((e)->k <= VKLAST) | |
| 74 #define expr_isk_nojump(e) (expr_isk(e) && !expr_hasjump(e)) | |
| 75 #define expr_isnumk(e) ((e)->k == VKNUM) | |
| 76 #define expr_isnumk_nojump(e) (expr_isnumk(e) && !expr_hasjump(e)) | |
| 77 #define expr_isstrk(e) ((e)->k == VKSTR) | |
| 78 | |
| 79 #define expr_numtv(e) check_exp(expr_isnumk((e)), &(e)->u.nval) | |
| 80 #define expr_numberV(e) numberVnum(expr_numtv((e))) | |
| 81 | |
| 82 /* Initialize expression. */ | |
| 83 static LJ_AINLINE void expr_init(ExpDesc *e, ExpKind k, uint32_t info) | |
| 84 { | |
| 85 e->k = k; | |
| 86 e->u.s.info = info; | |
| 87 e->f = e->t = NO_JMP; | |
| 88 } | |
| 89 | |
| 90 /* Check number constant for +-0. */ | |
| 91 static int expr_numiszero(ExpDesc *e) | |
| 92 { | |
| 93 TValue *o = expr_numtv(e); | |
| 94 return tvisint(o) ? (intV(o) == 0) : tviszero(o); | |
| 95 } | |
| 96 | |
| 97 /* Per-function linked list of scope blocks. */ | |
| 98 typedef struct FuncScope { | |
| 99 struct FuncScope *prev; /* Link to outer scope. */ | |
| 100 MSize vstart; /* Start of block-local variables. */ | |
| 101 uint8_t nactvar; /* Number of active vars outside the scope. */ | |
| 102 uint8_t flags; /* Scope flags. */ | |
| 103 } FuncScope; | |
| 104 | |
| 105 #define FSCOPE_LOOP 0x01 /* Scope is a (breakable) loop. */ | |
| 106 #define FSCOPE_BREAK 0x02 /* Break used in scope. */ | |
| 107 #define FSCOPE_GOLA 0x04 /* Goto or label used in scope. */ | |
| 108 #define FSCOPE_UPVAL 0x08 /* Upvalue in scope. */ | |
| 109 #define FSCOPE_NOCLOSE 0x10 /* Do not close upvalues. */ | |
| 110 | |
| 111 #define NAME_BREAK ((GCstr *)(uintptr_t)1) | |
| 112 | |
| 113 /* Index into variable stack. */ | |
| 114 typedef uint16_t VarIndex; | |
| 115 #define LJ_MAX_VSTACK (65536 - LJ_MAX_UPVAL) | |
| 116 | |
| 117 /* Variable/goto/label info. */ | |
| 118 #define VSTACK_VAR_RW 0x01 /* R/W variable. */ | |
| 119 #define VSTACK_GOTO 0x02 /* Pending goto. */ | |
| 120 #define VSTACK_LABEL 0x04 /* Label. */ | |
| 121 | |
| 122 /* Per-function state. */ | |
| 123 typedef struct FuncState { | |
| 124 GCtab *kt; /* Hash table for constants. */ | |
| 125 LexState *ls; /* Lexer state. */ | |
| 126 lua_State *L; /* Lua state. */ | |
| 127 FuncScope *bl; /* Current scope. */ | |
| 128 struct FuncState *prev; /* Enclosing function. */ | |
| 129 BCPos pc; /* Next bytecode position. */ | |
| 130 BCPos lasttarget; /* Bytecode position of last jump target. */ | |
| 131 BCPos jpc; /* Pending jump list to next bytecode. */ | |
| 132 BCReg freereg; /* First free register. */ | |
| 133 BCReg nactvar; /* Number of active local variables. */ | |
| 134 BCReg nkn, nkgc; /* Number of lua_Number/GCobj constants */ | |
| 135 BCLine linedefined; /* First line of the function definition. */ | |
| 136 BCInsLine *bcbase; /* Base of bytecode stack. */ | |
| 137 BCPos bclim; /* Limit of bytecode stack. */ | |
| 138 MSize vbase; /* Base of variable stack for this function. */ | |
| 139 uint8_t flags; /* Prototype flags. */ | |
| 140 uint8_t numparams; /* Number of parameters. */ | |
| 141 uint8_t framesize; /* Fixed frame size. */ | |
| 142 uint8_t nuv; /* Number of upvalues */ | |
| 143 VarIndex varmap[LJ_MAX_LOCVAR]; /* Map from register to variable idx. */ | |
| 144 VarIndex uvmap[LJ_MAX_UPVAL]; /* Map from upvalue to variable idx. */ | |
| 145 VarIndex uvtmp[LJ_MAX_UPVAL]; /* Temporary upvalue map. */ | |
| 146 } FuncState; | |
| 147 | |
| 148 /* Binary and unary operators. ORDER OPR */ | |
| 149 typedef enum BinOpr { | |
| 150 OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, /* ORDER ARITH */ | |
| 151 OPR_CONCAT, | |
| 152 OPR_NE, OPR_EQ, | |
| 153 OPR_LT, OPR_GE, OPR_LE, OPR_GT, | |
| 154 OPR_AND, OPR_OR, | |
| 155 OPR_NOBINOPR | |
| 156 } BinOpr; | |
| 157 | |
| 158 LJ_STATIC_ASSERT((int)BC_ISGE-(int)BC_ISLT == (int)OPR_GE-(int)OPR_LT); | |
| 159 LJ_STATIC_ASSERT((int)BC_ISLE-(int)BC_ISLT == (int)OPR_LE-(int)OPR_LT); | |
| 160 LJ_STATIC_ASSERT((int)BC_ISGT-(int)BC_ISLT == (int)OPR_GT-(int)OPR_LT); | |
| 161 LJ_STATIC_ASSERT((int)BC_SUBVV-(int)BC_ADDVV == (int)OPR_SUB-(int)OPR_ADD); | |
| 162 LJ_STATIC_ASSERT((int)BC_MULVV-(int)BC_ADDVV == (int)OPR_MUL-(int)OPR_ADD); | |
| 163 LJ_STATIC_ASSERT((int)BC_DIVVV-(int)BC_ADDVV == (int)OPR_DIV-(int)OPR_ADD); | |
| 164 LJ_STATIC_ASSERT((int)BC_MODVV-(int)BC_ADDVV == (int)OPR_MOD-(int)OPR_ADD); | |
| 165 | |
| 166 #ifdef LUA_USE_ASSERT | |
| 167 #define lj_assertFS(c, ...) (lj_assertG_(G(fs->L), (c), __VA_ARGS__)) | |
| 168 #else | |
| 169 #define lj_assertFS(c, ...) ((void)fs) | |
| 170 #endif | |
| 171 | |
| 172 /* -- Error handling ------------------------------------------------------ */ | |
| 173 | |
| 174 LJ_NORET LJ_NOINLINE static void err_syntax(LexState *ls, ErrMsg em) | |
| 175 { | |
| 176 lj_lex_error(ls, ls->tok, em); | |
| 177 } | |
| 178 | |
| 179 LJ_NORET LJ_NOINLINE static void err_token(LexState *ls, LexToken tok) | |
| 180 { | |
| 181 lj_lex_error(ls, ls->tok, LJ_ERR_XTOKEN, lj_lex_token2str(ls, tok)); | |
| 182 } | |
| 183 | |
| 184 LJ_NORET static void err_limit(FuncState *fs, uint32_t limit, const char *what) | |
| 185 { | |
| 186 if (fs->linedefined == 0) | |
| 187 lj_lex_error(fs->ls, 0, LJ_ERR_XLIMM, limit, what); | |
| 188 else | |
| 189 lj_lex_error(fs->ls, 0, LJ_ERR_XLIMF, fs->linedefined, limit, what); | |
| 190 } | |
| 191 | |
| 192 #define checklimit(fs, v, l, m) if ((v) >= (l)) err_limit(fs, l, m) | |
| 193 #define checklimitgt(fs, v, l, m) if ((v) > (l)) err_limit(fs, l, m) | |
| 194 #define checkcond(ls, c, em) { if (!(c)) err_syntax(ls, em); } | |
| 195 | |
| 196 /* -- Management of constants --------------------------------------------- */ | |
| 197 | |
| 198 /* Return bytecode encoding for primitive constant. */ | |
| 199 #define const_pri(e) check_exp((e)->k <= VKTRUE, (e)->k) | |
| 200 | |
| 201 #define tvhaskslot(o) ((o)->u32.hi == 0) | |
| 202 #define tvkslot(o) ((o)->u32.lo) | |
| 203 | |
| 204 /* Add a number constant. */ | |
| 205 static BCReg const_num(FuncState *fs, ExpDesc *e) | |
| 206 { | |
| 207 lua_State *L = fs->L; | |
| 208 TValue *o; | |
| 209 lj_assertFS(expr_isnumk(e), "bad usage"); | |
| 210 o = lj_tab_set(L, fs->kt, &e->u.nval); | |
| 211 if (tvhaskslot(o)) | |
| 212 return tvkslot(o); | |
| 213 o->u64 = fs->nkn; | |
| 214 return fs->nkn++; | |
| 215 } | |
| 216 | |
| 217 /* Add a GC object constant. */ | |
| 218 static BCReg const_gc(FuncState *fs, GCobj *gc, uint32_t itype) | |
| 219 { | |
| 220 lua_State *L = fs->L; | |
| 221 TValue key, *o; | |
| 222 setgcV(L, &key, gc, itype); | |
| 223 /* NOBARRIER: the key is new or kept alive. */ | |
| 224 o = lj_tab_set(L, fs->kt, &key); | |
| 225 if (tvhaskslot(o)) | |
| 226 return tvkslot(o); | |
| 227 o->u64 = fs->nkgc; | |
| 228 return fs->nkgc++; | |
| 229 } | |
| 230 | |
| 231 /* Add a string constant. */ | |
| 232 static BCReg const_str(FuncState *fs, ExpDesc *e) | |
| 233 { | |
| 234 lj_assertFS(expr_isstrk(e) || e->k == VGLOBAL, "bad usage"); | |
| 235 return const_gc(fs, obj2gco(e->u.sval), LJ_TSTR); | |
| 236 } | |
| 237 | |
| 238 /* Anchor string constant to avoid GC. */ | |
| 239 GCstr *lj_parse_keepstr(LexState *ls, const char *str, size_t len) | |
| 240 { | |
| 241 /* NOBARRIER: the key is new or kept alive. */ | |
| 242 lua_State *L = ls->L; | |
| 243 GCstr *s = lj_str_new(L, str, len); | |
| 244 TValue *tv = lj_tab_setstr(L, ls->fs->kt, s); | |
| 245 if (tvisnil(tv)) setboolV(tv, 1); | |
| 246 lj_gc_check(L); | |
| 247 return s; | |
| 248 } | |
| 249 | |
| 250 #if LJ_HASFFI | |
| 251 /* Anchor cdata to avoid GC. */ | |
| 252 void lj_parse_keepcdata(LexState *ls, TValue *tv, GCcdata *cd) | |
| 253 { | |
| 254 /* NOBARRIER: the key is new or kept alive. */ | |
| 255 lua_State *L = ls->L; | |
| 256 setcdataV(L, tv, cd); | |
| 257 setboolV(lj_tab_set(L, ls->fs->kt, tv), 1); | |
| 258 } | |
| 259 #endif | |
| 260 | |
| 261 /* -- Jump list handling -------------------------------------------------- */ | |
| 262 | |
| 263 /* Get next element in jump list. */ | |
| 264 static BCPos jmp_next(FuncState *fs, BCPos pc) | |
| 265 { | |
| 266 ptrdiff_t delta = bc_j(fs->bcbase[pc].ins); | |
| 267 if ((BCPos)delta == NO_JMP) | |
| 268 return NO_JMP; | |
| 269 else | |
| 270 return (BCPos)(((ptrdiff_t)pc+1)+delta); | |
| 271 } | |
| 272 | |
| 273 /* Check if any of the instructions on the jump list produce no value. */ | |
| 274 static int jmp_novalue(FuncState *fs, BCPos list) | |
| 275 { | |
| 276 for (; list != NO_JMP; list = jmp_next(fs, list)) { | |
| 277 BCIns p = fs->bcbase[list >= 1 ? list-1 : list].ins; | |
| 278 if (!(bc_op(p) == BC_ISTC || bc_op(p) == BC_ISFC || bc_a(p) == NO_REG)) | |
| 279 return 1; | |
| 280 } | |
| 281 return 0; | |
| 282 } | |
| 283 | |
| 284 /* Patch register of test instructions. */ | |
| 285 static int jmp_patchtestreg(FuncState *fs, BCPos pc, BCReg reg) | |
| 286 { | |
| 287 BCInsLine *ilp = &fs->bcbase[pc >= 1 ? pc-1 : pc]; | |
| 288 BCOp op = bc_op(ilp->ins); | |
| 289 if (op == BC_ISTC || op == BC_ISFC) { | |
| 290 if (reg != NO_REG && reg != bc_d(ilp->ins)) { | |
| 291 setbc_a(&ilp->ins, reg); | |
| 292 } else { /* Nothing to store or already in the right register. */ | |
| 293 setbc_op(&ilp->ins, op+(BC_IST-BC_ISTC)); | |
| 294 setbc_a(&ilp->ins, 0); | |
| 295 } | |
| 296 } else if (bc_a(ilp->ins) == NO_REG) { | |
| 297 if (reg == NO_REG) { | |
| 298 ilp->ins = BCINS_AJ(BC_JMP, bc_a(fs->bcbase[pc].ins), 0); | |
| 299 } else { | |
| 300 setbc_a(&ilp->ins, reg); | |
| 301 if (reg >= bc_a(ilp[1].ins)) | |
| 302 setbc_a(&ilp[1].ins, reg+1); | |
| 303 } | |
| 304 } else { | |
| 305 return 0; /* Cannot patch other instructions. */ | |
| 306 } | |
| 307 return 1; | |
| 308 } | |
| 309 | |
| 310 /* Drop values for all instructions on jump list. */ | |
| 311 static void jmp_dropval(FuncState *fs, BCPos list) | |
| 312 { | |
| 313 for (; list != NO_JMP; list = jmp_next(fs, list)) | |
| 314 jmp_patchtestreg(fs, list, NO_REG); | |
| 315 } | |
| 316 | |
| 317 /* Patch jump instruction to target. */ | |
| 318 static void jmp_patchins(FuncState *fs, BCPos pc, BCPos dest) | |
| 319 { | |
| 320 BCIns *jmp = &fs->bcbase[pc].ins; | |
| 321 BCPos offset = dest-(pc+1)+BCBIAS_J; | |
| 322 lj_assertFS(dest != NO_JMP, "uninitialized jump target"); | |
| 323 if (offset > BCMAX_D) | |
| 324 err_syntax(fs->ls, LJ_ERR_XJUMP); | |
| 325 setbc_d(jmp, offset); | |
| 326 } | |
| 327 | |
| 328 /* Append to jump list. */ | |
| 329 static void jmp_append(FuncState *fs, BCPos *l1, BCPos l2) | |
| 330 { | |
| 331 if (l2 == NO_JMP) { | |
| 332 return; | |
| 333 } else if (*l1 == NO_JMP) { | |
| 334 *l1 = l2; | |
| 335 } else { | |
| 336 BCPos list = *l1; | |
| 337 BCPos next; | |
| 338 while ((next = jmp_next(fs, list)) != NO_JMP) /* Find last element. */ | |
| 339 list = next; | |
| 340 jmp_patchins(fs, list, l2); | |
| 341 } | |
| 342 } | |
| 343 | |
| 344 /* Patch jump list and preserve produced values. */ | |
| 345 static void jmp_patchval(FuncState *fs, BCPos list, BCPos vtarget, | |
| 346 BCReg reg, BCPos dtarget) | |
| 347 { | |
| 348 while (list != NO_JMP) { | |
| 349 BCPos next = jmp_next(fs, list); | |
| 350 if (jmp_patchtestreg(fs, list, reg)) | |
| 351 jmp_patchins(fs, list, vtarget); /* Jump to target with value. */ | |
| 352 else | |
| 353 jmp_patchins(fs, list, dtarget); /* Jump to default target. */ | |
| 354 list = next; | |
| 355 } | |
| 356 } | |
| 357 | |
| 358 /* Jump to following instruction. Append to list of pending jumps. */ | |
| 359 static void jmp_tohere(FuncState *fs, BCPos list) | |
| 360 { | |
| 361 fs->lasttarget = fs->pc; | |
| 362 jmp_append(fs, &fs->jpc, list); | |
| 363 } | |
| 364 | |
| 365 /* Patch jump list to target. */ | |
| 366 static void jmp_patch(FuncState *fs, BCPos list, BCPos target) | |
| 367 { | |
| 368 if (target == fs->pc) { | |
| 369 jmp_tohere(fs, list); | |
| 370 } else { | |
| 371 lj_assertFS(target < fs->pc, "bad jump target"); | |
| 372 jmp_patchval(fs, list, target, NO_REG, target); | |
| 373 } | |
| 374 } | |
| 375 | |
| 376 /* -- Bytecode register allocator ----------------------------------------- */ | |
| 377 | |
| 378 /* Bump frame size. */ | |
| 379 static void bcreg_bump(FuncState *fs, BCReg n) | |
| 380 { | |
| 381 BCReg sz = fs->freereg + n; | |
| 382 if (sz > fs->framesize) { | |
| 383 if (sz >= LJ_MAX_SLOTS) | |
| 384 err_syntax(fs->ls, LJ_ERR_XSLOTS); | |
| 385 fs->framesize = (uint8_t)sz; | |
| 386 } | |
| 387 } | |
| 388 | |
| 389 /* Reserve registers. */ | |
| 390 static void bcreg_reserve(FuncState *fs, BCReg n) | |
| 391 { | |
| 392 bcreg_bump(fs, n); | |
| 393 fs->freereg += n; | |
| 394 } | |
| 395 | |
| 396 /* Free register. */ | |
| 397 static void bcreg_free(FuncState *fs, BCReg reg) | |
| 398 { | |
| 399 if (reg >= fs->nactvar) { | |
| 400 fs->freereg--; | |
| 401 lj_assertFS(reg == fs->freereg, "bad regfree"); | |
| 402 } | |
| 403 } | |
| 404 | |
| 405 /* Free register for expression. */ | |
| 406 static void expr_free(FuncState *fs, ExpDesc *e) | |
| 407 { | |
| 408 if (e->k == VNONRELOC) | |
| 409 bcreg_free(fs, e->u.s.info); | |
| 410 } | |
| 411 | |
| 412 /* -- Bytecode emitter ---------------------------------------------------- */ | |
| 413 | |
| 414 /* Emit bytecode instruction. */ | |
| 415 static BCPos bcemit_INS(FuncState *fs, BCIns ins) | |
| 416 { | |
| 417 BCPos pc = fs->pc; | |
| 418 LexState *ls = fs->ls; | |
| 419 jmp_patchval(fs, fs->jpc, pc, NO_REG, pc); | |
| 420 fs->jpc = NO_JMP; | |
| 421 if (LJ_UNLIKELY(pc >= fs->bclim)) { | |
| 422 ptrdiff_t base = fs->bcbase - ls->bcstack; | |
| 423 checklimit(fs, ls->sizebcstack, LJ_MAX_BCINS, "bytecode instructions"); | |
| 424 lj_mem_growvec(fs->L, ls->bcstack, ls->sizebcstack, LJ_MAX_BCINS,BCInsLine); | |
| 425 fs->bclim = (BCPos)(ls->sizebcstack - base); | |
| 426 fs->bcbase = ls->bcstack + base; | |
| 427 } | |
| 428 fs->bcbase[pc].ins = ins; | |
| 429 fs->bcbase[pc].line = ls->lastline; | |
| 430 fs->pc = pc+1; | |
| 431 return pc; | |
| 432 } | |
| 433 | |
| 434 #define bcemit_ABC(fs, o, a, b, c) bcemit_INS(fs, BCINS_ABC(o, a, b, c)) | |
| 435 #define bcemit_AD(fs, o, a, d) bcemit_INS(fs, BCINS_AD(o, a, d)) | |
| 436 #define bcemit_AJ(fs, o, a, j) bcemit_INS(fs, BCINS_AJ(o, a, j)) | |
| 437 | |
| 438 #define bcptr(fs, e) (&(fs)->bcbase[(e)->u.s.info].ins) | |
| 439 | |
| 440 /* -- Bytecode emitter for expressions ------------------------------------ */ | |
| 441 | |
| 442 /* Discharge non-constant expression to any register. */ | |
| 443 static void expr_discharge(FuncState *fs, ExpDesc *e) | |
| 444 { | |
| 445 BCIns ins; | |
| 446 if (e->k == VUPVAL) { | |
| 447 ins = BCINS_AD(BC_UGET, 0, e->u.s.info); | |
| 448 } else if (e->k == VGLOBAL) { | |
| 449 ins = BCINS_AD(BC_GGET, 0, const_str(fs, e)); | |
| 450 } else if (e->k == VINDEXED) { | |
| 451 BCReg rc = e->u.s.aux; | |
| 452 if ((int32_t)rc < 0) { | |
| 453 ins = BCINS_ABC(BC_TGETS, 0, e->u.s.info, ~rc); | |
| 454 } else if (rc > BCMAX_C) { | |
| 455 ins = BCINS_ABC(BC_TGETB, 0, e->u.s.info, rc-(BCMAX_C+1)); | |
| 456 } else { | |
| 457 bcreg_free(fs, rc); | |
| 458 ins = BCINS_ABC(BC_TGETV, 0, e->u.s.info, rc); | |
| 459 } | |
| 460 bcreg_free(fs, e->u.s.info); | |
| 461 } else if (e->k == VCALL) { | |
| 462 e->u.s.info = e->u.s.aux; | |
| 463 e->k = VNONRELOC; | |
| 464 return; | |
| 465 } else if (e->k == VLOCAL) { | |
| 466 e->k = VNONRELOC; | |
| 467 return; | |
| 468 } else { | |
| 469 return; | |
| 470 } | |
| 471 e->u.s.info = bcemit_INS(fs, ins); | |
| 472 e->k = VRELOCABLE; | |
| 473 } | |
| 474 | |
| 475 /* Emit bytecode to set a range of registers to nil. */ | |
| 476 static void bcemit_nil(FuncState *fs, BCReg from, BCReg n) | |
| 477 { | |
| 478 if (fs->pc > fs->lasttarget) { /* No jumps to current position? */ | |
| 479 BCIns *ip = &fs->bcbase[fs->pc-1].ins; | |
| 480 BCReg pto, pfrom = bc_a(*ip); | |
| 481 switch (bc_op(*ip)) { /* Try to merge with the previous instruction. */ | |
| 482 case BC_KPRI: | |
| 483 if (bc_d(*ip) != ~LJ_TNIL) break; | |
| 484 if (from == pfrom) { | |
| 485 if (n == 1) return; | |
| 486 } else if (from == pfrom+1) { | |
| 487 from = pfrom; | |
| 488 n++; | |
| 489 } else { | |
| 490 break; | |
| 491 } | |
| 492 *ip = BCINS_AD(BC_KNIL, from, from+n-1); /* Replace KPRI. */ | |
| 493 return; | |
| 494 case BC_KNIL: | |
| 495 pto = bc_d(*ip); | |
| 496 if (pfrom <= from && from <= pto+1) { /* Can we connect both ranges? */ | |
| 497 if (from+n-1 > pto) | |
| 498 setbc_d(ip, from+n-1); /* Patch previous instruction range. */ | |
| 499 return; | |
| 500 } | |
| 501 break; | |
| 502 default: | |
| 503 break; | |
| 504 } | |
| 505 } | |
| 506 /* Emit new instruction or replace old instruction. */ | |
| 507 bcemit_INS(fs, n == 1 ? BCINS_AD(BC_KPRI, from, VKNIL) : | |
| 508 BCINS_AD(BC_KNIL, from, from+n-1)); | |
| 509 } | |
| 510 | |
| 511 /* Discharge an expression to a specific register. Ignore branches. */ | |
| 512 static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg) | |
| 513 { | |
| 514 BCIns ins; | |
| 515 expr_discharge(fs, e); | |
| 516 if (e->k == VKSTR) { | |
| 517 ins = BCINS_AD(BC_KSTR, reg, const_str(fs, e)); | |
| 518 } else if (e->k == VKNUM) { | |
| 519 #if LJ_DUALNUM | |
| 520 cTValue *tv = expr_numtv(e); | |
| 521 if (tvisint(tv) && checki16(intV(tv))) | |
| 522 ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)intV(tv)); | |
| 523 else | |
| 524 #else | |
| 525 lua_Number n = expr_numberV(e); | |
| 526 int32_t k = lj_num2int(n); | |
| 527 if (checki16(k) && n == (lua_Number)k) | |
| 528 ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k); | |
| 529 else | |
| 530 #endif | |
| 531 ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e)); | |
| 532 #if LJ_HASFFI | |
| 533 } else if (e->k == VKCDATA) { | |
| 534 fs->flags |= PROTO_FFI; | |
| 535 ins = BCINS_AD(BC_KCDATA, reg, | |
| 536 const_gc(fs, obj2gco(cdataV(&e->u.nval)), LJ_TCDATA)); | |
| 537 #endif | |
| 538 } else if (e->k == VRELOCABLE) { | |
| 539 setbc_a(bcptr(fs, e), reg); | |
| 540 goto noins; | |
| 541 } else if (e->k == VNONRELOC) { | |
| 542 if (reg == e->u.s.info) | |
| 543 goto noins; | |
| 544 ins = BCINS_AD(BC_MOV, reg, e->u.s.info); | |
| 545 } else if (e->k == VKNIL) { | |
| 546 bcemit_nil(fs, reg, 1); | |
| 547 goto noins; | |
| 548 } else if (e->k <= VKTRUE) { | |
| 549 ins = BCINS_AD(BC_KPRI, reg, const_pri(e)); | |
| 550 } else { | |
| 551 lj_assertFS(e->k == VVOID || e->k == VJMP, "bad expr type %d", e->k); | |
| 552 return; | |
| 553 } | |
| 554 bcemit_INS(fs, ins); | |
| 555 noins: | |
| 556 e->u.s.info = reg; | |
| 557 e->k = VNONRELOC; | |
| 558 } | |
| 559 | |
| 560 /* Forward declaration. */ | |
| 561 static BCPos bcemit_jmp(FuncState *fs); | |
| 562 | |
| 563 /* Discharge an expression to a specific register. */ | |
| 564 static void expr_toreg(FuncState *fs, ExpDesc *e, BCReg reg) | |
| 565 { | |
| 566 expr_toreg_nobranch(fs, e, reg); | |
| 567 if (e->k == VJMP) | |
| 568 jmp_append(fs, &e->t, e->u.s.info); /* Add it to the true jump list. */ | |
| 569 if (expr_hasjump(e)) { /* Discharge expression with branches. */ | |
| 570 BCPos jend, jfalse = NO_JMP, jtrue = NO_JMP; | |
| 571 if (jmp_novalue(fs, e->t) || jmp_novalue(fs, e->f)) { | |
| 572 BCPos jval = (e->k == VJMP) ? NO_JMP : bcemit_jmp(fs); | |
| 573 jfalse = bcemit_AD(fs, BC_KPRI, reg, VKFALSE); | |
| 574 bcemit_AJ(fs, BC_JMP, fs->freereg, 1); | |
| 575 jtrue = bcemit_AD(fs, BC_KPRI, reg, VKTRUE); | |
| 576 jmp_tohere(fs, jval); | |
| 577 } | |
| 578 jend = fs->pc; | |
| 579 fs->lasttarget = jend; | |
| 580 jmp_patchval(fs, e->f, jend, reg, jfalse); | |
| 581 jmp_patchval(fs, e->t, jend, reg, jtrue); | |
| 582 } | |
| 583 e->f = e->t = NO_JMP; | |
| 584 e->u.s.info = reg; | |
| 585 e->k = VNONRELOC; | |
| 586 } | |
| 587 | |
| 588 /* Discharge an expression to the next free register. */ | |
| 589 static void expr_tonextreg(FuncState *fs, ExpDesc *e) | |
| 590 { | |
| 591 expr_discharge(fs, e); | |
| 592 expr_free(fs, e); | |
| 593 bcreg_reserve(fs, 1); | |
| 594 expr_toreg(fs, e, fs->freereg - 1); | |
| 595 } | |
| 596 | |
| 597 /* Discharge an expression to any register. */ | |
| 598 static BCReg expr_toanyreg(FuncState *fs, ExpDesc *e) | |
| 599 { | |
| 600 expr_discharge(fs, e); | |
| 601 if (e->k == VNONRELOC) { | |
| 602 if (!expr_hasjump(e)) return e->u.s.info; /* Already in a register. */ | |
| 603 if (e->u.s.info >= fs->nactvar) { | |
| 604 expr_toreg(fs, e, e->u.s.info); /* Discharge to temp. register. */ | |
| 605 return e->u.s.info; | |
| 606 } | |
| 607 } | |
| 608 expr_tonextreg(fs, e); /* Discharge to next register. */ | |
| 609 return e->u.s.info; | |
| 610 } | |
| 611 | |
| 612 /* Partially discharge expression to a value. */ | |
| 613 static void expr_toval(FuncState *fs, ExpDesc *e) | |
| 614 { | |
| 615 if (expr_hasjump(e)) | |
| 616 expr_toanyreg(fs, e); | |
| 617 else | |
| 618 expr_discharge(fs, e); | |
| 619 } | |
| 620 | |
| 621 /* Emit store for LHS expression. */ | |
| 622 static void bcemit_store(FuncState *fs, ExpDesc *var, ExpDesc *e) | |
| 623 { | |
| 624 BCIns ins; | |
| 625 if (var->k == VLOCAL) { | |
| 626 fs->ls->vstack[var->u.s.aux].info |= VSTACK_VAR_RW; | |
| 627 expr_free(fs, e); | |
| 628 expr_toreg(fs, e, var->u.s.info); | |
| 629 return; | |
| 630 } else if (var->k == VUPVAL) { | |
| 631 fs->ls->vstack[var->u.s.aux].info |= VSTACK_VAR_RW; | |
| 632 expr_toval(fs, e); | |
| 633 if (e->k <= VKTRUE) | |
| 634 ins = BCINS_AD(BC_USETP, var->u.s.info, const_pri(e)); | |
| 635 else if (e->k == VKSTR) | |
| 636 ins = BCINS_AD(BC_USETS, var->u.s.info, const_str(fs, e)); | |
| 637 else if (e->k == VKNUM) | |
| 638 ins = BCINS_AD(BC_USETN, var->u.s.info, const_num(fs, e)); | |
| 639 else | |
| 640 ins = BCINS_AD(BC_USETV, var->u.s.info, expr_toanyreg(fs, e)); | |
| 641 } else if (var->k == VGLOBAL) { | |
| 642 BCReg ra = expr_toanyreg(fs, e); | |
| 643 ins = BCINS_AD(BC_GSET, ra, const_str(fs, var)); | |
| 644 } else { | |
| 645 BCReg ra, rc; | |
| 646 lj_assertFS(var->k == VINDEXED, "bad expr type %d", var->k); | |
| 647 ra = expr_toanyreg(fs, e); | |
| 648 rc = var->u.s.aux; | |
| 649 if ((int32_t)rc < 0) { | |
| 650 ins = BCINS_ABC(BC_TSETS, ra, var->u.s.info, ~rc); | |
| 651 } else if (rc > BCMAX_C) { | |
| 652 ins = BCINS_ABC(BC_TSETB, ra, var->u.s.info, rc-(BCMAX_C+1)); | |
| 653 } else { | |
| 654 #ifdef LUA_USE_ASSERT | |
| 655 /* Free late alloced key reg to avoid assert on free of value reg. */ | |
| 656 /* This can only happen when called from expr_table(). */ | |
| 657 if (e->k == VNONRELOC && ra >= fs->nactvar && rc >= ra) | |
| 658 bcreg_free(fs, rc); | |
| 659 #endif | |
| 660 ins = BCINS_ABC(BC_TSETV, ra, var->u.s.info, rc); | |
| 661 } | |
| 662 } | |
| 663 bcemit_INS(fs, ins); | |
| 664 expr_free(fs, e); | |
| 665 } | |
| 666 | |
| 667 /* Emit method lookup expression. */ | |
| 668 static void bcemit_method(FuncState *fs, ExpDesc *e, ExpDesc *key) | |
| 669 { | |
| 670 BCReg idx, func, obj = expr_toanyreg(fs, e); | |
| 671 expr_free(fs, e); | |
| 672 func = fs->freereg; | |
| 673 bcemit_AD(fs, BC_MOV, func+1+LJ_FR2, obj); /* Copy object to 1st argument. */ | |
| 674 lj_assertFS(expr_isstrk(key), "bad usage"); | |
| 675 idx = const_str(fs, key); | |
| 676 if (idx <= BCMAX_C) { | |
| 677 bcreg_reserve(fs, 2+LJ_FR2); | |
| 678 bcemit_ABC(fs, BC_TGETS, func, obj, idx); | |
| 679 } else { | |
| 680 bcreg_reserve(fs, 3+LJ_FR2); | |
| 681 bcemit_AD(fs, BC_KSTR, func+2+LJ_FR2, idx); | |
| 682 bcemit_ABC(fs, BC_TGETV, func, obj, func+2+LJ_FR2); | |
| 683 fs->freereg--; | |
| 684 } | |
| 685 e->u.s.info = func; | |
| 686 e->k = VNONRELOC; | |
| 687 } | |
| 688 | |
| 689 /* -- Bytecode emitter for branches --------------------------------------- */ | |
| 690 | |
| 691 /* Emit unconditional branch. */ | |
| 692 static BCPos bcemit_jmp(FuncState *fs) | |
| 693 { | |
| 694 BCPos jpc = fs->jpc; | |
| 695 BCPos j = fs->pc - 1; | |
| 696 BCIns *ip = &fs->bcbase[j].ins; | |
| 697 fs->jpc = NO_JMP; | |
| 698 if ((int32_t)j >= (int32_t)fs->lasttarget && bc_op(*ip) == BC_UCLO) { | |
| 699 setbc_j(ip, NO_JMP); | |
| 700 fs->lasttarget = j+1; | |
| 701 } else { | |
| 702 j = bcemit_AJ(fs, BC_JMP, fs->freereg, NO_JMP); | |
| 703 } | |
| 704 jmp_append(fs, &j, jpc); | |
| 705 return j; | |
| 706 } | |
| 707 | |
| 708 /* Invert branch condition of bytecode instruction. */ | |
| 709 static void invertcond(FuncState *fs, ExpDesc *e) | |
| 710 { | |
| 711 BCIns *ip = &fs->bcbase[e->u.s.info - 1].ins; | |
| 712 setbc_op(ip, bc_op(*ip)^1); | |
| 713 } | |
| 714 | |
| 715 /* Emit conditional branch. */ | |
| 716 static BCPos bcemit_branch(FuncState *fs, ExpDesc *e, int cond) | |
| 717 { | |
| 718 BCPos pc; | |
| 719 if (e->k == VRELOCABLE) { | |
| 720 BCIns *ip = bcptr(fs, e); | |
| 721 if (bc_op(*ip) == BC_NOT) { | |
| 722 *ip = BCINS_AD(cond ? BC_ISF : BC_IST, 0, bc_d(*ip)); | |
| 723 return bcemit_jmp(fs); | |
| 724 } | |
| 725 } | |
| 726 if (e->k != VNONRELOC) { | |
| 727 bcreg_reserve(fs, 1); | |
| 728 expr_toreg_nobranch(fs, e, fs->freereg-1); | |
| 729 } | |
| 730 bcemit_AD(fs, cond ? BC_ISTC : BC_ISFC, NO_REG, e->u.s.info); | |
| 731 pc = bcemit_jmp(fs); | |
| 732 expr_free(fs, e); | |
| 733 return pc; | |
| 734 } | |
| 735 | |
| 736 /* Emit branch on true condition. */ | |
| 737 static void bcemit_branch_t(FuncState *fs, ExpDesc *e) | |
| 738 { | |
| 739 BCPos pc; | |
| 740 expr_discharge(fs, e); | |
| 741 if (e->k == VKSTR || e->k == VKNUM || e->k == VKTRUE) | |
| 742 pc = NO_JMP; /* Never jump. */ | |
| 743 else if (e->k == VJMP) | |
| 744 invertcond(fs, e), pc = e->u.s.info; | |
| 745 else if (e->k == VKFALSE || e->k == VKNIL) | |
| 746 expr_toreg_nobranch(fs, e, NO_REG), pc = bcemit_jmp(fs); | |
| 747 else | |
| 748 pc = bcemit_branch(fs, e, 0); | |
| 749 jmp_append(fs, &e->f, pc); | |
| 750 jmp_tohere(fs, e->t); | |
| 751 e->t = NO_JMP; | |
| 752 } | |
| 753 | |
| 754 /* Emit branch on false condition. */ | |
| 755 static void bcemit_branch_f(FuncState *fs, ExpDesc *e) | |
| 756 { | |
| 757 BCPos pc; | |
| 758 expr_discharge(fs, e); | |
| 759 if (e->k == VKNIL || e->k == VKFALSE) | |
| 760 pc = NO_JMP; /* Never jump. */ | |
| 761 else if (e->k == VJMP) | |
| 762 pc = e->u.s.info; | |
| 763 else if (e->k == VKSTR || e->k == VKNUM || e->k == VKTRUE) | |
| 764 expr_toreg_nobranch(fs, e, NO_REG), pc = bcemit_jmp(fs); | |
| 765 else | |
| 766 pc = bcemit_branch(fs, e, 1); | |
| 767 jmp_append(fs, &e->t, pc); | |
| 768 jmp_tohere(fs, e->f); | |
| 769 e->f = NO_JMP; | |
| 770 } | |
| 771 | |
| 772 /* -- Bytecode emitter for operators -------------------------------------- */ | |
| 773 | |
| 774 /* Try constant-folding of arithmetic operators. */ | |
| 775 static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2) | |
| 776 { | |
| 777 TValue o; | |
| 778 lua_Number n; | |
| 779 if (!expr_isnumk_nojump(e1) || !expr_isnumk_nojump(e2)) return 0; | |
| 780 n = lj_vm_foldarith(expr_numberV(e1), expr_numberV(e2), (int)opr-OPR_ADD); | |
| 781 setnumV(&o, n); | |
| 782 if (tvisnan(&o) || tvismzero(&o)) return 0; /* Avoid NaN and -0 as consts. */ | |
| 783 if (LJ_DUALNUM) { | |
| 784 int32_t k = lj_num2int(n); | |
| 785 if ((lua_Number)k == n) { | |
| 786 setintV(&e1->u.nval, k); | |
| 787 return 1; | |
| 788 } | |
| 789 } | |
| 790 setnumV(&e1->u.nval, n); | |
| 791 return 1; | |
| 792 } | |
| 793 | |
| 794 /* Emit arithmetic operator. */ | |
| 795 static void bcemit_arith(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2) | |
| 796 { | |
| 797 BCReg rb, rc, t; | |
| 798 uint32_t op; | |
| 799 if (foldarith(opr, e1, e2)) | |
| 800 return; | |
| 801 if (opr == OPR_POW) { | |
| 802 op = BC_POW; | |
| 803 rc = expr_toanyreg(fs, e2); | |
| 804 rb = expr_toanyreg(fs, e1); | |
| 805 } else { | |
| 806 op = opr-OPR_ADD+BC_ADDVV; | |
| 807 /* Must discharge 2nd operand first since VINDEXED might free regs. */ | |
| 808 expr_toval(fs, e2); | |
| 809 if (expr_isnumk(e2) && (rc = const_num(fs, e2)) <= BCMAX_C) | |
| 810 op -= BC_ADDVV-BC_ADDVN; | |
| 811 else | |
| 812 rc = expr_toanyreg(fs, e2); | |
| 813 /* 1st operand discharged by bcemit_binop_left, but need KNUM/KSHORT. */ | |
| 814 lj_assertFS(expr_isnumk(e1) || e1->k == VNONRELOC, | |
| 815 "bad expr type %d", e1->k); | |
| 816 expr_toval(fs, e1); | |
| 817 /* Avoid two consts to satisfy bytecode constraints. */ | |
| 818 if (expr_isnumk(e1) && !expr_isnumk(e2) && | |
| 819 (t = const_num(fs, e1)) <= BCMAX_B) { | |
| 820 rb = rc; rc = t; op -= BC_ADDVV-BC_ADDNV; | |
| 821 } else { | |
| 822 rb = expr_toanyreg(fs, e1); | |
| 823 } | |
| 824 } | |
| 825 /* Using expr_free might cause asserts if the order is wrong. */ | |
| 826 if (e1->k == VNONRELOC && e1->u.s.info >= fs->nactvar) fs->freereg--; | |
| 827 if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--; | |
| 828 e1->u.s.info = bcemit_ABC(fs, op, 0, rb, rc); | |
| 829 e1->k = VRELOCABLE; | |
| 830 } | |
| 831 | |
| 832 /* Emit comparison operator. */ | |
| 833 static void bcemit_comp(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2) | |
| 834 { | |
| 835 ExpDesc *eret = e1; | |
| 836 BCIns ins; | |
| 837 expr_toval(fs, e1); | |
| 838 if (opr == OPR_EQ || opr == OPR_NE) { | |
| 839 BCOp op = opr == OPR_EQ ? BC_ISEQV : BC_ISNEV; | |
| 840 BCReg ra; | |
| 841 if (expr_isk(e1)) { e1 = e2; e2 = eret; } /* Need constant in 2nd arg. */ | |
| 842 ra = expr_toanyreg(fs, e1); /* First arg must be in a reg. */ | |
| 843 expr_toval(fs, e2); | |
| 844 switch (e2->k) { | |
| 845 case VKNIL: case VKFALSE: case VKTRUE: | |
| 846 ins = BCINS_AD(op+(BC_ISEQP-BC_ISEQV), ra, const_pri(e2)); | |
| 847 break; | |
| 848 case VKSTR: | |
| 849 ins = BCINS_AD(op+(BC_ISEQS-BC_ISEQV), ra, const_str(fs, e2)); | |
| 850 break; | |
| 851 case VKNUM: | |
| 852 ins = BCINS_AD(op+(BC_ISEQN-BC_ISEQV), ra, const_num(fs, e2)); | |
| 853 break; | |
| 854 default: | |
| 855 ins = BCINS_AD(op, ra, expr_toanyreg(fs, e2)); | |
| 856 break; | |
| 857 } | |
| 858 } else { | |
| 859 uint32_t op = opr-OPR_LT+BC_ISLT; | |
| 860 BCReg ra, rd; | |
| 861 if ((op-BC_ISLT) & 1) { /* GT -> LT, GE -> LE */ | |
| 862 e1 = e2; e2 = eret; /* Swap operands. */ | |
| 863 op = ((op-BC_ISLT)^3)+BC_ISLT; | |
| 864 expr_toval(fs, e1); | |
| 865 ra = expr_toanyreg(fs, e1); | |
| 866 rd = expr_toanyreg(fs, e2); | |
| 867 } else { | |
| 868 rd = expr_toanyreg(fs, e2); | |
| 869 ra = expr_toanyreg(fs, e1); | |
| 870 } | |
| 871 ins = BCINS_AD(op, ra, rd); | |
| 872 } | |
| 873 /* Using expr_free might cause asserts if the order is wrong. */ | |
| 874 if (e1->k == VNONRELOC && e1->u.s.info >= fs->nactvar) fs->freereg--; | |
| 875 if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--; | |
| 876 bcemit_INS(fs, ins); | |
| 877 eret->u.s.info = bcemit_jmp(fs); | |
| 878 eret->k = VJMP; | |
| 879 } | |
| 880 | |
| 881 /* Fixup left side of binary operator. */ | |
| 882 static void bcemit_binop_left(FuncState *fs, BinOpr op, ExpDesc *e) | |
| 883 { | |
| 884 if (op == OPR_AND) { | |
| 885 bcemit_branch_t(fs, e); | |
| 886 } else if (op == OPR_OR) { | |
| 887 bcemit_branch_f(fs, e); | |
| 888 } else if (op == OPR_CONCAT) { | |
| 889 expr_tonextreg(fs, e); | |
| 890 } else if (op == OPR_EQ || op == OPR_NE) { | |
| 891 if (!expr_isk_nojump(e)) expr_toanyreg(fs, e); | |
| 892 } else { | |
| 893 if (!expr_isnumk_nojump(e)) expr_toanyreg(fs, e); | |
| 894 } | |
| 895 } | |
| 896 | |
| 897 /* Emit binary operator. */ | |
| 898 static void bcemit_binop(FuncState *fs, BinOpr op, ExpDesc *e1, ExpDesc *e2) | |
| 899 { | |
| 900 if (op <= OPR_POW) { | |
| 901 bcemit_arith(fs, op, e1, e2); | |
| 902 } else if (op == OPR_AND) { | |
| 903 lj_assertFS(e1->t == NO_JMP, "jump list not closed"); | |
| 904 expr_discharge(fs, e2); | |
| 905 jmp_append(fs, &e2->f, e1->f); | |
| 906 *e1 = *e2; | |
| 907 } else if (op == OPR_OR) { | |
| 908 lj_assertFS(e1->f == NO_JMP, "jump list not closed"); | |
| 909 expr_discharge(fs, e2); | |
| 910 jmp_append(fs, &e2->t, e1->t); | |
| 911 *e1 = *e2; | |
| 912 } else if (op == OPR_CONCAT) { | |
| 913 expr_toval(fs, e2); | |
| 914 if (e2->k == VRELOCABLE && bc_op(*bcptr(fs, e2)) == BC_CAT) { | |
| 915 lj_assertFS(e1->u.s.info == bc_b(*bcptr(fs, e2))-1, | |
| 916 "bad CAT stack layout"); | |
| 917 expr_free(fs, e1); | |
| 918 setbc_b(bcptr(fs, e2), e1->u.s.info); | |
| 919 e1->u.s.info = e2->u.s.info; | |
| 920 } else { | |
| 921 expr_tonextreg(fs, e2); | |
| 922 expr_free(fs, e2); | |
| 923 expr_free(fs, e1); | |
| 924 e1->u.s.info = bcemit_ABC(fs, BC_CAT, 0, e1->u.s.info, e2->u.s.info); | |
| 925 } | |
| 926 e1->k = VRELOCABLE; | |
| 927 } else { | |
| 928 lj_assertFS(op == OPR_NE || op == OPR_EQ || | |
| 929 op == OPR_LT || op == OPR_GE || op == OPR_LE || op == OPR_GT, | |
| 930 "bad binop %d", op); | |
| 931 bcemit_comp(fs, op, e1, e2); | |
| 932 } | |
| 933 } | |
| 934 | |
| 935 /* Emit unary operator. */ | |
| 936 static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e) | |
| 937 { | |
| 938 if (op == BC_NOT) { | |
| 939 /* Swap true and false lists. */ | |
| 940 { BCPos temp = e->f; e->f = e->t; e->t = temp; } | |
| 941 jmp_dropval(fs, e->f); | |
| 942 jmp_dropval(fs, e->t); | |
| 943 expr_discharge(fs, e); | |
| 944 if (e->k == VKNIL || e->k == VKFALSE) { | |
| 945 e->k = VKTRUE; | |
| 946 return; | |
| 947 } else if (expr_isk(e) || (LJ_HASFFI && e->k == VKCDATA)) { | |
| 948 e->k = VKFALSE; | |
| 949 return; | |
| 950 } else if (e->k == VJMP) { | |
| 951 invertcond(fs, e); | |
| 952 return; | |
| 953 } else if (e->k == VRELOCABLE) { | |
| 954 bcreg_reserve(fs, 1); | |
| 955 setbc_a(bcptr(fs, e), fs->freereg-1); | |
| 956 e->u.s.info = fs->freereg-1; | |
| 957 e->k = VNONRELOC; | |
| 958 } else { | |
| 959 lj_assertFS(e->k == VNONRELOC, "bad expr type %d", e->k); | |
| 960 } | |
| 961 } else { | |
| 962 lj_assertFS(op == BC_UNM || op == BC_LEN, "bad unop %d", op); | |
| 963 if (op == BC_UNM && !expr_hasjump(e)) { /* Constant-fold negations. */ | |
| 964 #if LJ_HASFFI | |
| 965 if (e->k == VKCDATA) { /* Fold in-place since cdata is not interned. */ | |
| 966 GCcdata *cd = cdataV(&e->u.nval); | |
| 967 uint64_t *p = (uint64_t *)cdataptr(cd); | |
| 968 if (cd->ctypeid == CTID_COMPLEX_DOUBLE) | |
| 969 p[1] ^= U64x(80000000,00000000); | |
| 970 else | |
| 971 *p = ~*p+1u; | |
| 972 return; | |
| 973 } else | |
| 974 #endif | |
| 975 if (expr_isnumk(e) && !expr_numiszero(e)) { /* Avoid folding to -0. */ | |
| 976 TValue *o = expr_numtv(e); | |
| 977 if (tvisint(o)) { | |
| 978 int32_t k = intV(o), negk = (int32_t)(~(uint32_t)k+1u); | |
| 979 if (k == negk) | |
| 980 setnumV(o, -(lua_Number)k); | |
| 981 else | |
| 982 setintV(o, negk); | |
| 983 return; | |
| 984 } else { | |
| 985 o->u64 ^= U64x(80000000,00000000); | |
| 986 return; | |
| 987 } | |
| 988 } | |
| 989 } | |
| 990 expr_toanyreg(fs, e); | |
| 991 } | |
| 992 expr_free(fs, e); | |
| 993 e->u.s.info = bcemit_AD(fs, op, 0, e->u.s.info); | |
| 994 e->k = VRELOCABLE; | |
| 995 } | |
| 996 | |
| 997 /* -- Lexer support ------------------------------------------------------- */ | |
| 998 | |
| 999 /* Check and consume optional token. */ | |
| 1000 static int lex_opt(LexState *ls, LexToken tok) | |
| 1001 { | |
| 1002 if (ls->tok == tok) { | |
| 1003 lj_lex_next(ls); | |
| 1004 return 1; | |
| 1005 } | |
| 1006 return 0; | |
| 1007 } | |
| 1008 | |
| 1009 /* Check and consume token. */ | |
| 1010 static void lex_check(LexState *ls, LexToken tok) | |
| 1011 { | |
| 1012 if (ls->tok != tok) | |
| 1013 err_token(ls, tok); | |
| 1014 lj_lex_next(ls); | |
| 1015 } | |
| 1016 | |
| 1017 /* Check for matching token. */ | |
| 1018 static void lex_match(LexState *ls, LexToken what, LexToken who, BCLine line) | |
| 1019 { | |
| 1020 if (!lex_opt(ls, what)) { | |
| 1021 if (line == ls->linenumber) { | |
| 1022 err_token(ls, what); | |
| 1023 } else { | |
| 1024 const char *swhat = lj_lex_token2str(ls, what); | |
| 1025 const char *swho = lj_lex_token2str(ls, who); | |
| 1026 lj_lex_error(ls, ls->tok, LJ_ERR_XMATCH, swhat, swho, line); | |
| 1027 } | |
| 1028 } | |
| 1029 } | |
| 1030 | |
| 1031 /* Check for string token. */ | |
| 1032 static GCstr *lex_str(LexState *ls) | |
| 1033 { | |
| 1034 GCstr *s; | |
| 1035 if (ls->tok != TK_name && (LJ_52 || ls->tok != TK_goto)) | |
| 1036 err_token(ls, TK_name); | |
| 1037 s = strV(&ls->tokval); | |
| 1038 lj_lex_next(ls); | |
| 1039 return s; | |
| 1040 } | |
| 1041 | |
| 1042 /* -- Variable handling --------------------------------------------------- */ | |
| 1043 | |
| 1044 #define var_get(ls, fs, i) ((ls)->vstack[(fs)->varmap[(i)]]) | |
| 1045 | |
| 1046 /* Define a new local variable. */ | |
| 1047 static void var_new(LexState *ls, BCReg n, GCstr *name) | |
| 1048 { | |
| 1049 FuncState *fs = ls->fs; | |
| 1050 MSize vtop = ls->vtop; | |
| 1051 checklimit(fs, fs->nactvar+n, LJ_MAX_LOCVAR, "local variables"); | |
| 1052 if (LJ_UNLIKELY(vtop >= ls->sizevstack)) { | |
| 1053 if (ls->sizevstack >= LJ_MAX_VSTACK) | |
| 1054 lj_lex_error(ls, 0, LJ_ERR_XLIMC, LJ_MAX_VSTACK); | |
| 1055 lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo); | |
| 1056 } | |
| 1057 lj_assertFS((uintptr_t)name < VARNAME__MAX || | |
| 1058 lj_tab_getstr(fs->kt, name) != NULL, | |
| 1059 "unanchored variable name"); | |
| 1060 /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */ | |
| 1061 setgcref(ls->vstack[vtop].name, obj2gco(name)); | |
| 1062 fs->varmap[fs->nactvar+n] = (uint16_t)vtop; | |
| 1063 ls->vtop = vtop+1; | |
| 1064 } | |
| 1065 | |
| 1066 #define var_new_lit(ls, n, v) \ | |
| 1067 var_new(ls, (n), lj_parse_keepstr(ls, "" v, sizeof(v)-1)) | |
| 1068 | |
| 1069 #define var_new_fixed(ls, n, vn) \ | |
| 1070 var_new(ls, (n), (GCstr *)(uintptr_t)(vn)) | |
| 1071 | |
| 1072 /* Add local variables. */ | |
| 1073 static void var_add(LexState *ls, BCReg nvars) | |
| 1074 { | |
| 1075 FuncState *fs = ls->fs; | |
| 1076 BCReg nactvar = fs->nactvar; | |
| 1077 while (nvars--) { | |
| 1078 VarInfo *v = &var_get(ls, fs, nactvar); | |
| 1079 v->startpc = fs->pc; | |
| 1080 v->slot = nactvar++; | |
| 1081 v->info = 0; | |
| 1082 } | |
| 1083 fs->nactvar = nactvar; | |
| 1084 } | |
| 1085 | |
| 1086 /* Remove local variables. */ | |
| 1087 static void var_remove(LexState *ls, BCReg tolevel) | |
| 1088 { | |
| 1089 FuncState *fs = ls->fs; | |
| 1090 while (fs->nactvar > tolevel) | |
| 1091 var_get(ls, fs, --fs->nactvar).endpc = fs->pc; | |
| 1092 } | |
| 1093 | |
| 1094 /* Lookup local variable name. */ | |
| 1095 static BCReg var_lookup_local(FuncState *fs, GCstr *n) | |
| 1096 { | |
| 1097 int i; | |
| 1098 for (i = fs->nactvar-1; i >= 0; i--) { | |
| 1099 if (n == strref(var_get(fs->ls, fs, i).name)) | |
| 1100 return (BCReg)i; | |
| 1101 } | |
| 1102 return (BCReg)-1; /* Not found. */ | |
| 1103 } | |
| 1104 | |
| 1105 /* Lookup or add upvalue index. */ | |
| 1106 static MSize var_lookup_uv(FuncState *fs, MSize vidx, ExpDesc *e) | |
| 1107 { | |
| 1108 MSize i, n = fs->nuv; | |
| 1109 for (i = 0; i < n; i++) | |
| 1110 if (fs->uvmap[i] == vidx) | |
| 1111 return i; /* Already exists. */ | |
| 1112 /* Otherwise create a new one. */ | |
| 1113 checklimit(fs, fs->nuv, LJ_MAX_UPVAL, "upvalues"); | |
| 1114 lj_assertFS(e->k == VLOCAL || e->k == VUPVAL, "bad expr type %d", e->k); | |
| 1115 fs->uvmap[n] = (uint16_t)vidx; | |
| 1116 fs->uvtmp[n] = (uint16_t)(e->k == VLOCAL ? vidx : LJ_MAX_VSTACK+e->u.s.info); | |
| 1117 fs->nuv = n+1; | |
| 1118 return n; | |
| 1119 } | |
| 1120 | |
| 1121 /* Forward declaration. */ | |
| 1122 static void fscope_uvmark(FuncState *fs, BCReg level); | |
| 1123 | |
| 1124 /* Recursively lookup variables in enclosing functions. */ | |
| 1125 static MSize var_lookup_(FuncState *fs, GCstr *name, ExpDesc *e, int first) | |
| 1126 { | |
| 1127 if (fs) { | |
| 1128 BCReg reg = var_lookup_local(fs, name); | |
| 1129 if ((int32_t)reg >= 0) { /* Local in this function? */ | |
| 1130 expr_init(e, VLOCAL, reg); | |
| 1131 if (!first) | |
| 1132 fscope_uvmark(fs, reg); /* Scope now has an upvalue. */ | |
| 1133 return (MSize)(e->u.s.aux = (uint32_t)fs->varmap[reg]); | |
| 1134 } else { | |
| 1135 MSize vidx = var_lookup_(fs->prev, name, e, 0); /* Var in outer func? */ | |
| 1136 if ((int32_t)vidx >= 0) { /* Yes, make it an upvalue here. */ | |
| 1137 e->u.s.info = (uint8_t)var_lookup_uv(fs, vidx, e); | |
| 1138 e->k = VUPVAL; | |
| 1139 return vidx; | |
| 1140 } | |
| 1141 } | |
| 1142 } else { /* Not found in any function, must be a global. */ | |
| 1143 expr_init(e, VGLOBAL, 0); | |
| 1144 e->u.sval = name; | |
| 1145 } | |
| 1146 return (MSize)-1; /* Global. */ | |
| 1147 } | |
| 1148 | |
| 1149 /* Lookup variable name. */ | |
| 1150 #define var_lookup(ls, e) \ | |
| 1151 var_lookup_((ls)->fs, lex_str(ls), (e), 1) | |
| 1152 | |
| 1153 /* -- Goto an label handling ---------------------------------------------- */ | |
| 1154 | |
| 1155 /* Add a new goto or label. */ | |
| 1156 static MSize gola_new(LexState *ls, GCstr *name, uint8_t info, BCPos pc) | |
| 1157 { | |
| 1158 FuncState *fs = ls->fs; | |
| 1159 MSize vtop = ls->vtop; | |
| 1160 if (LJ_UNLIKELY(vtop >= ls->sizevstack)) { | |
| 1161 if (ls->sizevstack >= LJ_MAX_VSTACK) | |
| 1162 lj_lex_error(ls, 0, LJ_ERR_XLIMC, LJ_MAX_VSTACK); | |
| 1163 lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo); | |
| 1164 } | |
| 1165 lj_assertFS(name == NAME_BREAK || lj_tab_getstr(fs->kt, name) != NULL, | |
| 1166 "unanchored label name"); | |
| 1167 /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */ | |
| 1168 setgcref(ls->vstack[vtop].name, obj2gco(name)); | |
| 1169 ls->vstack[vtop].startpc = pc; | |
| 1170 ls->vstack[vtop].slot = (uint8_t)fs->nactvar; | |
| 1171 ls->vstack[vtop].info = info; | |
| 1172 ls->vtop = vtop+1; | |
| 1173 return vtop; | |
| 1174 } | |
| 1175 | |
| 1176 #define gola_isgoto(v) ((v)->info & VSTACK_GOTO) | |
| 1177 #define gola_islabel(v) ((v)->info & VSTACK_LABEL) | |
| 1178 #define gola_isgotolabel(v) ((v)->info & (VSTACK_GOTO|VSTACK_LABEL)) | |
| 1179 | |
| 1180 /* Patch goto to jump to label. */ | |
| 1181 static void gola_patch(LexState *ls, VarInfo *vg, VarInfo *vl) | |
| 1182 { | |
| 1183 FuncState *fs = ls->fs; | |
| 1184 BCPos pc = vg->startpc; | |
| 1185 setgcrefnull(vg->name); /* Invalidate pending goto. */ | |
| 1186 setbc_a(&fs->bcbase[pc].ins, vl->slot); | |
| 1187 jmp_patch(fs, pc, vl->startpc); | |
| 1188 } | |
| 1189 | |
| 1190 /* Patch goto to close upvalues. */ | |
| 1191 static void gola_close(LexState *ls, VarInfo *vg) | |
| 1192 { | |
| 1193 FuncState *fs = ls->fs; | |
| 1194 BCPos pc = vg->startpc; | |
| 1195 BCIns *ip = &fs->bcbase[pc].ins; | |
| 1196 lj_assertFS(gola_isgoto(vg), "expected goto"); | |
| 1197 lj_assertFS(bc_op(*ip) == BC_JMP || bc_op(*ip) == BC_UCLO, | |
| 1198 "bad bytecode op %d", bc_op(*ip)); | |
| 1199 setbc_a(ip, vg->slot); | |
| 1200 if (bc_op(*ip) == BC_JMP) { | |
| 1201 BCPos next = jmp_next(fs, pc); | |
| 1202 if (next != NO_JMP) jmp_patch(fs, next, pc); /* Jump to UCLO. */ | |
| 1203 setbc_op(ip, BC_UCLO); /* Turn into UCLO. */ | |
| 1204 setbc_j(ip, NO_JMP); | |
| 1205 } | |
| 1206 } | |
| 1207 | |
| 1208 /* Resolve pending forward gotos for label. */ | |
| 1209 static void gola_resolve(LexState *ls, FuncScope *bl, MSize idx) | |
| 1210 { | |
| 1211 VarInfo *vg = ls->vstack + bl->vstart; | |
| 1212 VarInfo *vl = ls->vstack + idx; | |
| 1213 for (; vg < vl; vg++) | |
| 1214 if (gcrefeq(vg->name, vl->name) && gola_isgoto(vg)) { | |
| 1215 if (vg->slot < vl->slot) { | |
| 1216 GCstr *name = strref(var_get(ls, ls->fs, vg->slot).name); | |
| 1217 lj_assertLS((uintptr_t)name >= VARNAME__MAX, "expected goto name"); | |
| 1218 ls->linenumber = ls->fs->bcbase[vg->startpc].line; | |
| 1219 lj_assertLS(strref(vg->name) != NAME_BREAK, "unexpected break"); | |
| 1220 lj_lex_error(ls, 0, LJ_ERR_XGSCOPE, | |
| 1221 strdata(strref(vg->name)), strdata(name)); | |
| 1222 } | |
| 1223 gola_patch(ls, vg, vl); | |
| 1224 } | |
| 1225 } | |
| 1226 | |
| 1227 /* Fixup remaining gotos and labels for scope. */ | |
| 1228 static void gola_fixup(LexState *ls, FuncScope *bl) | |
| 1229 { | |
| 1230 VarInfo *v = ls->vstack + bl->vstart; | |
| 1231 VarInfo *ve = ls->vstack + ls->vtop; | |
| 1232 for (; v < ve; v++) { | |
| 1233 GCstr *name = strref(v->name); | |
| 1234 if (name != NULL) { /* Only consider remaining valid gotos/labels. */ | |
| 1235 if (gola_islabel(v)) { | |
| 1236 VarInfo *vg; | |
| 1237 setgcrefnull(v->name); /* Invalidate label that goes out of scope. */ | |
| 1238 for (vg = v+1; vg < ve; vg++) /* Resolve pending backward gotos. */ | |
| 1239 if (strref(vg->name) == name && gola_isgoto(vg)) { | |
| 1240 if ((bl->flags&FSCOPE_UPVAL) && vg->slot > v->slot) | |
| 1241 gola_close(ls, vg); | |
| 1242 gola_patch(ls, vg, v); | |
| 1243 } | |
| 1244 } else if (gola_isgoto(v)) { | |
| 1245 if (bl->prev) { /* Propagate goto or break to outer scope. */ | |
| 1246 bl->prev->flags |= name == NAME_BREAK ? FSCOPE_BREAK : FSCOPE_GOLA; | |
| 1247 v->slot = bl->nactvar; | |
| 1248 if ((bl->flags & FSCOPE_UPVAL)) | |
| 1249 gola_close(ls, v); | |
| 1250 } else { /* No outer scope: undefined goto label or no loop. */ | |
| 1251 ls->linenumber = ls->fs->bcbase[v->startpc].line; | |
| 1252 if (name == NAME_BREAK) | |
| 1253 lj_lex_error(ls, 0, LJ_ERR_XBREAK); | |
| 1254 else | |
| 1255 lj_lex_error(ls, 0, LJ_ERR_XLUNDEF, strdata(name)); | |
| 1256 } | |
| 1257 } | |
| 1258 } | |
| 1259 } | |
| 1260 } | |
| 1261 | |
| 1262 /* Find existing label. */ | |
| 1263 static VarInfo *gola_findlabel(LexState *ls, GCstr *name) | |
| 1264 { | |
| 1265 VarInfo *v = ls->vstack + ls->fs->bl->vstart; | |
| 1266 VarInfo *ve = ls->vstack + ls->vtop; | |
| 1267 for (; v < ve; v++) | |
| 1268 if (strref(v->name) == name && gola_islabel(v)) | |
| 1269 return v; | |
| 1270 return NULL; | |
| 1271 } | |
| 1272 | |
| 1273 /* -- Scope handling ------------------------------------------------------ */ | |
| 1274 | |
| 1275 /* Begin a scope. */ | |
| 1276 static void fscope_begin(FuncState *fs, FuncScope *bl, int flags) | |
| 1277 { | |
| 1278 bl->nactvar = (uint8_t)fs->nactvar; | |
| 1279 bl->flags = flags; | |
| 1280 bl->vstart = fs->ls->vtop; | |
| 1281 bl->prev = fs->bl; | |
| 1282 fs->bl = bl; | |
| 1283 lj_assertFS(fs->freereg == fs->nactvar, "bad regalloc"); | |
| 1284 } | |
| 1285 | |
| 1286 /* End a scope. */ | |
| 1287 static void fscope_end(FuncState *fs) | |
| 1288 { | |
| 1289 FuncScope *bl = fs->bl; | |
| 1290 LexState *ls = fs->ls; | |
| 1291 fs->bl = bl->prev; | |
| 1292 var_remove(ls, bl->nactvar); | |
| 1293 fs->freereg = fs->nactvar; | |
| 1294 lj_assertFS(bl->nactvar == fs->nactvar, "bad regalloc"); | |
| 1295 if ((bl->flags & (FSCOPE_UPVAL|FSCOPE_NOCLOSE)) == FSCOPE_UPVAL) | |
| 1296 bcemit_AJ(fs, BC_UCLO, bl->nactvar, 0); | |
| 1297 if ((bl->flags & FSCOPE_BREAK)) { | |
| 1298 if ((bl->flags & FSCOPE_LOOP)) { | |
| 1299 MSize idx = gola_new(ls, NAME_BREAK, VSTACK_LABEL, fs->pc); | |
| 1300 ls->vtop = idx; /* Drop break label immediately. */ | |
| 1301 gola_resolve(ls, bl, idx); | |
| 1302 } else { /* Need the fixup step to propagate the breaks. */ | |
| 1303 gola_fixup(ls, bl); | |
| 1304 return; | |
| 1305 } | |
| 1306 } | |
| 1307 if ((bl->flags & FSCOPE_GOLA)) { | |
| 1308 gola_fixup(ls, bl); | |
| 1309 } | |
| 1310 } | |
| 1311 | |
| 1312 /* Mark scope as having an upvalue. */ | |
| 1313 static void fscope_uvmark(FuncState *fs, BCReg level) | |
| 1314 { | |
| 1315 FuncScope *bl; | |
| 1316 for (bl = fs->bl; bl && bl->nactvar > level; bl = bl->prev) | |
| 1317 ; | |
| 1318 if (bl) | |
| 1319 bl->flags |= FSCOPE_UPVAL; | |
| 1320 } | |
| 1321 | |
| 1322 /* -- Function state management ------------------------------------------- */ | |
| 1323 | |
| 1324 /* Fixup bytecode for prototype. */ | |
| 1325 static void fs_fixup_bc(FuncState *fs, GCproto *pt, BCIns *bc, MSize n) | |
| 1326 { | |
| 1327 BCInsLine *base = fs->bcbase; | |
| 1328 MSize i; | |
| 1329 pt->sizebc = n; | |
| 1330 bc[0] = BCINS_AD((fs->flags & PROTO_VARARG) ? BC_FUNCV : BC_FUNCF, | |
| 1331 fs->framesize, 0); | |
| 1332 for (i = 1; i < n; i++) | |
| 1333 bc[i] = base[i].ins; | |
| 1334 } | |
| 1335 | |
| 1336 /* Fixup upvalues for child prototype, step #2. */ | |
| 1337 static void fs_fixup_uv2(FuncState *fs, GCproto *pt) | |
| 1338 { | |
| 1339 VarInfo *vstack = fs->ls->vstack; | |
| 1340 uint16_t *uv = proto_uv(pt); | |
| 1341 MSize i, n = pt->sizeuv; | |
| 1342 for (i = 0; i < n; i++) { | |
| 1343 VarIndex vidx = uv[i]; | |
| 1344 if (vidx >= LJ_MAX_VSTACK) | |
| 1345 uv[i] = vidx - LJ_MAX_VSTACK; | |
| 1346 else if ((vstack[vidx].info & VSTACK_VAR_RW)) | |
| 1347 uv[i] = vstack[vidx].slot | PROTO_UV_LOCAL; | |
| 1348 else | |
| 1349 uv[i] = vstack[vidx].slot | PROTO_UV_LOCAL | PROTO_UV_IMMUTABLE; | |
| 1350 } | |
| 1351 } | |
| 1352 | |
| 1353 /* Fixup constants for prototype. */ | |
| 1354 static void fs_fixup_k(FuncState *fs, GCproto *pt, void *kptr) | |
| 1355 { | |
| 1356 GCtab *kt; | |
| 1357 TValue *array; | |
| 1358 Node *node; | |
| 1359 MSize i, hmask; | |
| 1360 checklimitgt(fs, fs->nkn, BCMAX_D+1, "constants"); | |
| 1361 checklimitgt(fs, fs->nkgc, BCMAX_D+1, "constants"); | |
| 1362 setmref(pt->k, kptr); | |
| 1363 pt->sizekn = fs->nkn; | |
| 1364 pt->sizekgc = fs->nkgc; | |
| 1365 kt = fs->kt; | |
| 1366 array = tvref(kt->array); | |
| 1367 for (i = 0; i < kt->asize; i++) | |
| 1368 if (tvhaskslot(&array[i])) { | |
| 1369 TValue *tv = &((TValue *)kptr)[tvkslot(&array[i])]; | |
| 1370 if (LJ_DUALNUM) | |
| 1371 setintV(tv, (int32_t)i); | |
| 1372 else | |
| 1373 setnumV(tv, (lua_Number)i); | |
| 1374 } | |
| 1375 node = noderef(kt->node); | |
| 1376 hmask = kt->hmask; | |
| 1377 for (i = 0; i <= hmask; i++) { | |
| 1378 Node *n = &node[i]; | |
| 1379 if (tvhaskslot(&n->val)) { | |
| 1380 ptrdiff_t kidx = (ptrdiff_t)tvkslot(&n->val); | |
| 1381 lj_assertFS(!tvisint(&n->key), "unexpected integer key"); | |
| 1382 if (tvisnum(&n->key)) { | |
| 1383 TValue *tv = &((TValue *)kptr)[kidx]; | |
| 1384 if (LJ_DUALNUM) { | |
| 1385 lua_Number nn = numV(&n->key); | |
| 1386 int32_t k = lj_num2int(nn); | |
| 1387 lj_assertFS(!tvismzero(&n->key), "unexpected -0 key"); | |
| 1388 if ((lua_Number)k == nn) | |
| 1389 setintV(tv, k); | |
| 1390 else | |
| 1391 *tv = n->key; | |
| 1392 } else { | |
| 1393 *tv = n->key; | |
| 1394 } | |
| 1395 } else { | |
| 1396 GCobj *o = gcV(&n->key); | |
| 1397 setgcref(((GCRef *)kptr)[~kidx], o); | |
| 1398 lj_gc_objbarrier(fs->L, pt, o); | |
| 1399 if (tvisproto(&n->key)) | |
| 1400 fs_fixup_uv2(fs, gco2pt(o)); | |
| 1401 } | |
| 1402 } | |
| 1403 } | |
| 1404 } | |
| 1405 | |
| 1406 /* Fixup upvalues for prototype, step #1. */ | |
| 1407 static void fs_fixup_uv1(FuncState *fs, GCproto *pt, uint16_t *uv) | |
| 1408 { | |
| 1409 setmref(pt->uv, uv); | |
| 1410 pt->sizeuv = fs->nuv; | |
| 1411 memcpy(uv, fs->uvtmp, fs->nuv*sizeof(VarIndex)); | |
| 1412 } | |
| 1413 | |
| 1414 #ifndef LUAJIT_DISABLE_DEBUGINFO | |
| 1415 /* Prepare lineinfo for prototype. */ | |
| 1416 static size_t fs_prep_line(FuncState *fs, BCLine numline) | |
| 1417 { | |
| 1418 return (fs->pc-1) << (numline < 256 ? 0 : numline < 65536 ? 1 : 2); | |
| 1419 } | |
| 1420 | |
| 1421 /* Fixup lineinfo for prototype. */ | |
| 1422 static void fs_fixup_line(FuncState *fs, GCproto *pt, | |
| 1423 void *lineinfo, BCLine numline) | |
| 1424 { | |
| 1425 BCInsLine *base = fs->bcbase + 1; | |
| 1426 BCLine first = fs->linedefined; | |
| 1427 MSize i = 0, n = fs->pc-1; | |
| 1428 pt->firstline = fs->linedefined; | |
| 1429 pt->numline = numline; | |
| 1430 setmref(pt->lineinfo, lineinfo); | |
| 1431 if (LJ_LIKELY(numline < 256)) { | |
| 1432 uint8_t *li = (uint8_t *)lineinfo; | |
| 1433 do { | |
| 1434 BCLine delta = base[i].line - first; | |
| 1435 lj_assertFS(delta >= 0 && delta < 256, "bad line delta"); | |
| 1436 li[i] = (uint8_t)delta; | |
| 1437 } while (++i < n); | |
| 1438 } else if (LJ_LIKELY(numline < 65536)) { | |
| 1439 uint16_t *li = (uint16_t *)lineinfo; | |
| 1440 do { | |
| 1441 BCLine delta = base[i].line - first; | |
| 1442 lj_assertFS(delta >= 0 && delta < 65536, "bad line delta"); | |
| 1443 li[i] = (uint16_t)delta; | |
| 1444 } while (++i < n); | |
| 1445 } else { | |
| 1446 uint32_t *li = (uint32_t *)lineinfo; | |
| 1447 do { | |
| 1448 BCLine delta = base[i].line - first; | |
| 1449 lj_assertFS(delta >= 0, "bad line delta"); | |
| 1450 li[i] = (uint32_t)delta; | |
| 1451 } while (++i < n); | |
| 1452 } | |
| 1453 } | |
| 1454 | |
| 1455 /* Prepare variable info for prototype. */ | |
| 1456 static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar) | |
| 1457 { | |
| 1458 VarInfo *vs =ls->vstack, *ve; | |
| 1459 MSize i, n; | |
| 1460 BCPos lastpc; | |
| 1461 lj_buf_reset(&ls->sb); /* Copy to temp. string buffer. */ | |
| 1462 /* Store upvalue names. */ | |
| 1463 for (i = 0, n = fs->nuv; i < n; i++) { | |
| 1464 GCstr *s = strref(vs[fs->uvmap[i]].name); | |
| 1465 MSize len = s->len+1; | |
| 1466 char *p = lj_buf_more(&ls->sb, len); | |
| 1467 p = lj_buf_wmem(p, strdata(s), len); | |
| 1468 ls->sb.w = p; | |
| 1469 } | |
| 1470 *ofsvar = sbuflen(&ls->sb); | |
| 1471 lastpc = 0; | |
| 1472 /* Store local variable names and compressed ranges. */ | |
| 1473 for (ve = vs + ls->vtop, vs += fs->vbase; vs < ve; vs++) { | |
| 1474 if (!gola_isgotolabel(vs)) { | |
| 1475 GCstr *s = strref(vs->name); | |
| 1476 BCPos startpc; | |
| 1477 char *p; | |
| 1478 if ((uintptr_t)s < VARNAME__MAX) { | |
| 1479 p = lj_buf_more(&ls->sb, 1 + 2*5); | |
| 1480 *p++ = (char)(uintptr_t)s; | |
| 1481 } else { | |
| 1482 MSize len = s->len+1; | |
| 1483 p = lj_buf_more(&ls->sb, len + 2*5); | |
| 1484 p = lj_buf_wmem(p, strdata(s), len); | |
| 1485 } | |
| 1486 startpc = vs->startpc; | |
| 1487 p = lj_strfmt_wuleb128(p, startpc-lastpc); | |
| 1488 p = lj_strfmt_wuleb128(p, vs->endpc-startpc); | |
| 1489 ls->sb.w = p; | |
| 1490 lastpc = startpc; | |
| 1491 } | |
| 1492 } | |
| 1493 lj_buf_putb(&ls->sb, '\0'); /* Terminator for varinfo. */ | |
| 1494 return sbuflen(&ls->sb); | |
| 1495 } | |
| 1496 | |
| 1497 /* Fixup variable info for prototype. */ | |
| 1498 static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar) | |
| 1499 { | |
| 1500 setmref(pt->uvinfo, p); | |
| 1501 setmref(pt->varinfo, (char *)p + ofsvar); | |
| 1502 memcpy(p, ls->sb.b, sbuflen(&ls->sb)); /* Copy from temp. buffer. */ | |
| 1503 } | |
| 1504 #else | |
| 1505 | |
| 1506 /* Initialize with empty debug info, if disabled. */ | |
| 1507 #define fs_prep_line(fs, numline) (UNUSED(numline), 0) | |
| 1508 #define fs_fixup_line(fs, pt, li, numline) \ | |
| 1509 pt->firstline = pt->numline = 0, setmref((pt)->lineinfo, NULL) | |
| 1510 #define fs_prep_var(ls, fs, ofsvar) (UNUSED(ofsvar), 0) | |
| 1511 #define fs_fixup_var(ls, pt, p, ofsvar) \ | |
| 1512 setmref((pt)->uvinfo, NULL), setmref((pt)->varinfo, NULL) | |
| 1513 | |
| 1514 #endif | |
| 1515 | |
| 1516 /* Check if bytecode op returns. */ | |
| 1517 static int bcopisret(BCOp op) | |
| 1518 { | |
| 1519 switch (op) { | |
| 1520 case BC_CALLMT: case BC_CALLT: | |
| 1521 case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1: | |
| 1522 return 1; | |
| 1523 default: | |
| 1524 return 0; | |
| 1525 } | |
| 1526 } | |
| 1527 | |
| 1528 /* Fixup return instruction for prototype. */ | |
| 1529 static void fs_fixup_ret(FuncState *fs) | |
| 1530 { | |
| 1531 BCPos lastpc = fs->pc; | |
| 1532 if (lastpc <= fs->lasttarget || !bcopisret(bc_op(fs->bcbase[lastpc-1].ins))) { | |
| 1533 if ((fs->bl->flags & FSCOPE_UPVAL)) | |
| 1534 bcemit_AJ(fs, BC_UCLO, 0, 0); | |
| 1535 bcemit_AD(fs, BC_RET0, 0, 1); /* Need final return. */ | |
| 1536 } | |
| 1537 fs->bl->flags |= FSCOPE_NOCLOSE; /* Handled above. */ | |
| 1538 fscope_end(fs); | |
| 1539 lj_assertFS(fs->bl == NULL, "bad scope nesting"); | |
| 1540 /* May need to fixup returns encoded before first function was created. */ | |
| 1541 if (fs->flags & PROTO_FIXUP_RETURN) { | |
| 1542 BCPos pc; | |
| 1543 for (pc = 1; pc < lastpc; pc++) { | |
| 1544 BCIns ins = fs->bcbase[pc].ins; | |
| 1545 BCPos offset; | |
| 1546 switch (bc_op(ins)) { | |
| 1547 case BC_CALLMT: case BC_CALLT: | |
| 1548 case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1: | |
| 1549 offset = bcemit_INS(fs, ins); /* Copy original instruction. */ | |
| 1550 fs->bcbase[offset].line = fs->bcbase[pc].line; | |
| 1551 offset = offset-(pc+1)+BCBIAS_J; | |
| 1552 if (offset > BCMAX_D) | |
| 1553 err_syntax(fs->ls, LJ_ERR_XFIXUP); | |
| 1554 /* Replace with UCLO plus branch. */ | |
| 1555 fs->bcbase[pc].ins = BCINS_AD(BC_UCLO, 0, offset); | |
| 1556 break; | |
| 1557 case BC_FNEW: | |
| 1558 return; /* We're done. */ | |
| 1559 default: | |
| 1560 break; | |
| 1561 } | |
| 1562 } | |
| 1563 } | |
| 1564 } | |
| 1565 | |
| 1566 /* Finish a FuncState and return the new prototype. */ | |
| 1567 static GCproto *fs_finish(LexState *ls, BCLine line) | |
| 1568 { | |
| 1569 lua_State *L = ls->L; | |
| 1570 FuncState *fs = ls->fs; | |
| 1571 BCLine numline = line - fs->linedefined; | |
| 1572 size_t sizept, ofsk, ofsuv, ofsli, ofsdbg, ofsvar; | |
| 1573 GCproto *pt; | |
| 1574 | |
| 1575 /* Apply final fixups. */ | |
| 1576 fs_fixup_ret(fs); | |
| 1577 | |
| 1578 /* Calculate total size of prototype including all colocated arrays. */ | |
| 1579 sizept = sizeof(GCproto) + fs->pc*sizeof(BCIns) + fs->nkgc*sizeof(GCRef); | |
| 1580 sizept = (sizept + sizeof(TValue)-1) & ~(sizeof(TValue)-1); | |
| 1581 ofsk = sizept; sizept += fs->nkn*sizeof(TValue); | |
| 1582 ofsuv = sizept; sizept += ((fs->nuv+1)&~1)*2; | |
| 1583 ofsli = sizept; sizept += fs_prep_line(fs, numline); | |
| 1584 ofsdbg = sizept; sizept += fs_prep_var(ls, fs, &ofsvar); | |
| 1585 | |
| 1586 /* Allocate prototype and initialize its fields. */ | |
| 1587 pt = (GCproto *)lj_mem_newgco(L, (MSize)sizept); | |
| 1588 pt->gct = ~LJ_TPROTO; | |
| 1589 pt->sizept = (MSize)sizept; | |
| 1590 pt->trace = 0; | |
| 1591 pt->flags = (uint8_t)(fs->flags & ~(PROTO_HAS_RETURN|PROTO_FIXUP_RETURN)); | |
| 1592 pt->numparams = fs->numparams; | |
| 1593 pt->framesize = fs->framesize; | |
| 1594 setgcref(pt->chunkname, obj2gco(ls->chunkname)); | |
| 1595 | |
| 1596 /* Close potentially uninitialized gap between bc and kgc. */ | |
| 1597 *(uint32_t *)((char *)pt + ofsk - sizeof(GCRef)*(fs->nkgc+1)) = 0; | |
| 1598 fs_fixup_bc(fs, pt, (BCIns *)((char *)pt + sizeof(GCproto)), fs->pc); | |
| 1599 fs_fixup_k(fs, pt, (void *)((char *)pt + ofsk)); | |
| 1600 fs_fixup_uv1(fs, pt, (uint16_t *)((char *)pt + ofsuv)); | |
| 1601 fs_fixup_line(fs, pt, (void *)((char *)pt + ofsli), numline); | |
| 1602 fs_fixup_var(ls, pt, (uint8_t *)((char *)pt + ofsdbg), ofsvar); | |
| 1603 | |
| 1604 lj_vmevent_send(L, BC, | |
| 1605 setprotoV(L, L->top++, pt); | |
| 1606 ); | |
| 1607 | |
| 1608 L->top--; /* Pop table of constants. */ | |
| 1609 ls->vtop = fs->vbase; /* Reset variable stack. */ | |
| 1610 ls->fs = fs->prev; | |
| 1611 lj_assertL(ls->fs != NULL || ls->tok == TK_eof, "bad parser state"); | |
| 1612 return pt; | |
| 1613 } | |
| 1614 | |
| 1615 /* Initialize a new FuncState. */ | |
| 1616 static void fs_init(LexState *ls, FuncState *fs) | |
| 1617 { | |
| 1618 lua_State *L = ls->L; | |
| 1619 fs->prev = ls->fs; ls->fs = fs; /* Append to list. */ | |
| 1620 fs->ls = ls; | |
| 1621 fs->vbase = ls->vtop; | |
| 1622 fs->L = L; | |
| 1623 fs->pc = 0; | |
| 1624 fs->lasttarget = 0; | |
| 1625 fs->jpc = NO_JMP; | |
| 1626 fs->freereg = 0; | |
| 1627 fs->nkgc = 0; | |
| 1628 fs->nkn = 0; | |
| 1629 fs->nactvar = 0; | |
| 1630 fs->nuv = 0; | |
| 1631 fs->bl = NULL; | |
| 1632 fs->flags = 0; | |
| 1633 fs->framesize = 1; /* Minimum frame size. */ | |
| 1634 fs->kt = lj_tab_new(L, 0, 0); | |
| 1635 /* Anchor table of constants in stack to avoid being collected. */ | |
| 1636 settabV(L, L->top, fs->kt); | |
| 1637 incr_top(L); | |
| 1638 } | |
| 1639 | |
| 1640 /* -- Expressions --------------------------------------------------------- */ | |
| 1641 | |
| 1642 /* Forward declaration. */ | |
| 1643 static void expr(LexState *ls, ExpDesc *v); | |
| 1644 | |
| 1645 /* Return string expression. */ | |
| 1646 static void expr_str(LexState *ls, ExpDesc *e) | |
| 1647 { | |
| 1648 expr_init(e, VKSTR, 0); | |
| 1649 e->u.sval = lex_str(ls); | |
| 1650 } | |
| 1651 | |
| 1652 /* Return index expression. */ | |
| 1653 static void expr_index(FuncState *fs, ExpDesc *t, ExpDesc *e) | |
| 1654 { | |
| 1655 /* Already called: expr_toval(fs, e). */ | |
| 1656 t->k = VINDEXED; | |
| 1657 if (expr_isnumk(e)) { | |
| 1658 #if LJ_DUALNUM | |
| 1659 if (tvisint(expr_numtv(e))) { | |
| 1660 int32_t k = intV(expr_numtv(e)); | |
| 1661 if (checku8(k)) { | |
| 1662 t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */ | |
| 1663 return; | |
| 1664 } | |
| 1665 } | |
| 1666 #else | |
| 1667 lua_Number n = expr_numberV(e); | |
| 1668 int32_t k = lj_num2int(n); | |
| 1669 if (checku8(k) && n == (lua_Number)k) { | |
| 1670 t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */ | |
| 1671 return; | |
| 1672 } | |
| 1673 #endif | |
| 1674 } else if (expr_isstrk(e)) { | |
| 1675 BCReg idx = const_str(fs, e); | |
| 1676 if (idx <= BCMAX_C) { | |
| 1677 t->u.s.aux = ~idx; /* -256..-1: const string key */ | |
| 1678 return; | |
| 1679 } | |
| 1680 } | |
| 1681 t->u.s.aux = expr_toanyreg(fs, e); /* 0..255: register */ | |
| 1682 } | |
| 1683 | |
| 1684 /* Parse index expression with named field. */ | |
| 1685 static void expr_field(LexState *ls, ExpDesc *v) | |
| 1686 { | |
| 1687 FuncState *fs = ls->fs; | |
| 1688 ExpDesc key; | |
| 1689 expr_toanyreg(fs, v); | |
| 1690 lj_lex_next(ls); /* Skip dot or colon. */ | |
| 1691 expr_str(ls, &key); | |
| 1692 expr_index(fs, v, &key); | |
| 1693 } | |
| 1694 | |
| 1695 /* Parse index expression with brackets. */ | |
| 1696 static void expr_bracket(LexState *ls, ExpDesc *v) | |
| 1697 { | |
| 1698 lj_lex_next(ls); /* Skip '['. */ | |
| 1699 expr(ls, v); | |
| 1700 expr_toval(ls->fs, v); | |
| 1701 lex_check(ls, ']'); | |
| 1702 } | |
| 1703 | |
| 1704 /* Get value of constant expression. */ | |
| 1705 static void expr_kvalue(FuncState *fs, TValue *v, ExpDesc *e) | |
| 1706 { | |
| 1707 UNUSED(fs); | |
| 1708 if (e->k <= VKTRUE) { | |
| 1709 setpriV(v, ~(uint32_t)e->k); | |
| 1710 } else if (e->k == VKSTR) { | |
| 1711 setgcVraw(v, obj2gco(e->u.sval), LJ_TSTR); | |
| 1712 } else { | |
| 1713 lj_assertFS(tvisnumber(expr_numtv(e)), "bad number constant"); | |
| 1714 *v = *expr_numtv(e); | |
| 1715 } | |
| 1716 } | |
| 1717 | |
| 1718 /* Parse table constructor expression. */ | |
| 1719 static void expr_table(LexState *ls, ExpDesc *e) | |
| 1720 { | |
| 1721 FuncState *fs = ls->fs; | |
| 1722 BCLine line = ls->linenumber; | |
| 1723 GCtab *t = NULL; | |
| 1724 int vcall = 0, needarr = 0, fixt = 0; | |
| 1725 uint32_t narr = 1; /* First array index. */ | |
| 1726 uint32_t nhash = 0; /* Number of hash entries. */ | |
| 1727 BCReg freg = fs->freereg; | |
| 1728 BCPos pc = bcemit_AD(fs, BC_TNEW, freg, 0); | |
| 1729 expr_init(e, VNONRELOC, freg); | |
| 1730 bcreg_reserve(fs, 1); | |
| 1731 freg++; | |
| 1732 lex_check(ls, '{'); | |
| 1733 while (ls->tok != '}') { | |
| 1734 ExpDesc key, val; | |
| 1735 vcall = 0; | |
| 1736 if (ls->tok == '[') { | |
| 1737 expr_bracket(ls, &key); /* Already calls expr_toval. */ | |
| 1738 if (!expr_isk(&key)) expr_index(fs, e, &key); | |
| 1739 if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++; | |
| 1740 lex_check(ls, '='); | |
| 1741 } else if ((ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) && | |
| 1742 lj_lex_lookahead(ls) == '=') { | |
| 1743 expr_str(ls, &key); | |
| 1744 lex_check(ls, '='); | |
| 1745 nhash++; | |
| 1746 } else { | |
| 1747 expr_init(&key, VKNUM, 0); | |
| 1748 setintV(&key.u.nval, (int)narr); | |
| 1749 narr++; | |
| 1750 needarr = vcall = 1; | |
| 1751 } | |
| 1752 expr(ls, &val); | |
| 1753 if (expr_isk(&key) && key.k != VKNIL && | |
| 1754 (key.k == VKSTR || expr_isk_nojump(&val))) { | |
| 1755 TValue k, *v; | |
| 1756 if (!t) { /* Create template table on demand. */ | |
| 1757 BCReg kidx; | |
| 1758 t = lj_tab_new(fs->L, needarr ? narr : 0, hsize2hbits(nhash)); | |
| 1759 kidx = const_gc(fs, obj2gco(t), LJ_TTAB); | |
| 1760 fs->bcbase[pc].ins = BCINS_AD(BC_TDUP, freg-1, kidx); | |
| 1761 } | |
| 1762 vcall = 0; | |
| 1763 expr_kvalue(fs, &k, &key); | |
| 1764 v = lj_tab_set(fs->L, t, &k); | |
| 1765 lj_gc_anybarriert(fs->L, t); | |
| 1766 if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */ | |
| 1767 expr_kvalue(fs, v, &val); | |
| 1768 } else { /* Otherwise create dummy string key (avoids lj_tab_newkey). */ | |
| 1769 settabV(fs->L, v, t); /* Preserve key with table itself as value. */ | |
| 1770 fixt = 1; /* Fix this later, after all resizes. */ | |
| 1771 goto nonconst; | |
| 1772 } | |
| 1773 } else { | |
| 1774 nonconst: | |
| 1775 if (val.k != VCALL) { expr_toanyreg(fs, &val); vcall = 0; } | |
| 1776 if (expr_isk(&key)) expr_index(fs, e, &key); | |
| 1777 bcemit_store(fs, e, &val); | |
| 1778 } | |
| 1779 fs->freereg = freg; | |
| 1780 if (!lex_opt(ls, ',') && !lex_opt(ls, ';')) break; | |
| 1781 } | |
| 1782 lex_match(ls, '}', '{', line); | |
| 1783 if (vcall) { | |
| 1784 BCInsLine *ilp = &fs->bcbase[fs->pc-1]; | |
| 1785 ExpDesc en; | |
| 1786 lj_assertFS(bc_a(ilp->ins) == freg && | |
| 1787 bc_op(ilp->ins) == (narr > 256 ? BC_TSETV : BC_TSETB), | |
| 1788 "bad CALL code generation"); | |
| 1789 expr_init(&en, VKNUM, 0); | |
| 1790 en.u.nval.u32.lo = narr-1; | |
| 1791 en.u.nval.u32.hi = 0x43300000; /* Biased integer to avoid denormals. */ | |
| 1792 if (narr > 256) { fs->pc--; ilp--; } | |
| 1793 ilp->ins = BCINS_AD(BC_TSETM, freg, const_num(fs, &en)); | |
| 1794 setbc_b(&ilp[-1].ins, 0); | |
| 1795 } | |
| 1796 if (pc == fs->pc-1) { /* Make expr relocable if possible. */ | |
| 1797 e->u.s.info = pc; | |
| 1798 fs->freereg--; | |
| 1799 e->k = VRELOCABLE; | |
| 1800 } else { | |
| 1801 e->k = VNONRELOC; /* May have been changed by expr_index. */ | |
| 1802 } | |
| 1803 if (!t) { /* Construct TNEW RD: hhhhhaaaaaaaaaaa. */ | |
| 1804 BCIns *ip = &fs->bcbase[pc].ins; | |
| 1805 if (!needarr) narr = 0; | |
| 1806 else if (narr < 3) narr = 3; | |
| 1807 else if (narr > 0x7ff) narr = 0x7ff; | |
| 1808 setbc_d(ip, narr|(hsize2hbits(nhash)<<11)); | |
| 1809 } else { | |
| 1810 if (needarr && t->asize < narr) | |
| 1811 lj_tab_reasize(fs->L, t, narr-1); | |
| 1812 if (fixt) { /* Fix value for dummy keys in template table. */ | |
| 1813 Node *node = noderef(t->node); | |
| 1814 uint32_t i, hmask = t->hmask; | |
| 1815 for (i = 0; i <= hmask; i++) { | |
| 1816 Node *n = &node[i]; | |
| 1817 if (tvistab(&n->val)) { | |
| 1818 lj_assertFS(tabV(&n->val) == t, "bad dummy key in template table"); | |
| 1819 setnilV(&n->val); /* Turn value into nil. */ | |
| 1820 } | |
| 1821 } | |
| 1822 } | |
| 1823 lj_gc_check(fs->L); | |
| 1824 } | |
| 1825 } | |
| 1826 | |
| 1827 /* Parse function parameters. */ | |
| 1828 static BCReg parse_params(LexState *ls, int needself) | |
| 1829 { | |
| 1830 FuncState *fs = ls->fs; | |
| 1831 BCReg nparams = 0; | |
| 1832 lex_check(ls, '('); | |
| 1833 if (needself) | |
| 1834 var_new_lit(ls, nparams++, "self"); | |
| 1835 if (ls->tok != ')') { | |
| 1836 do { | |
| 1837 if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) { | |
| 1838 var_new(ls, nparams++, lex_str(ls)); | |
| 1839 } else if (ls->tok == TK_dots) { | |
| 1840 lj_lex_next(ls); | |
| 1841 fs->flags |= PROTO_VARARG; | |
| 1842 break; | |
| 1843 } else { | |
| 1844 err_syntax(ls, LJ_ERR_XPARAM); | |
| 1845 } | |
| 1846 } while (lex_opt(ls, ',')); | |
| 1847 } | |
| 1848 var_add(ls, nparams); | |
| 1849 lj_assertFS(fs->nactvar == nparams, "bad regalloc"); | |
| 1850 bcreg_reserve(fs, nparams); | |
| 1851 lex_check(ls, ')'); | |
| 1852 return nparams; | |
| 1853 } | |
| 1854 | |
| 1855 /* Forward declaration. */ | |
| 1856 static void parse_chunk(LexState *ls); | |
| 1857 | |
| 1858 /* Parse body of a function. */ | |
| 1859 static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line) | |
| 1860 { | |
| 1861 FuncState fs, *pfs = ls->fs; | |
| 1862 FuncScope bl; | |
| 1863 GCproto *pt; | |
| 1864 ptrdiff_t oldbase = pfs->bcbase - ls->bcstack; | |
| 1865 fs_init(ls, &fs); | |
| 1866 fscope_begin(&fs, &bl, 0); | |
| 1867 fs.linedefined = line; | |
| 1868 fs.numparams = (uint8_t)parse_params(ls, needself); | |
| 1869 fs.bcbase = pfs->bcbase + pfs->pc; | |
| 1870 fs.bclim = pfs->bclim - pfs->pc; | |
| 1871 bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */ | |
| 1872 parse_chunk(ls); | |
| 1873 if (ls->tok != TK_end) lex_match(ls, TK_end, TK_function, line); | |
| 1874 pt = fs_finish(ls, (ls->lastline = ls->linenumber)); | |
| 1875 pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ | |
| 1876 pfs->bclim = (BCPos)(ls->sizebcstack - oldbase); | |
| 1877 /* Store new prototype in the constant array of the parent. */ | |
| 1878 expr_init(e, VRELOCABLE, | |
| 1879 bcemit_AD(pfs, BC_FNEW, 0, const_gc(pfs, obj2gco(pt), LJ_TPROTO))); | |
| 1880 #if LJ_HASFFI | |
| 1881 pfs->flags |= (fs.flags & PROTO_FFI); | |
| 1882 #endif | |
| 1883 if (!(pfs->flags & PROTO_CHILD)) { | |
| 1884 if (pfs->flags & PROTO_HAS_RETURN) | |
| 1885 pfs->flags |= PROTO_FIXUP_RETURN; | |
| 1886 pfs->flags |= PROTO_CHILD; | |
| 1887 } | |
| 1888 lj_lex_next(ls); | |
| 1889 } | |
| 1890 | |
| 1891 /* Parse expression list. Last expression is left open. */ | |
| 1892 static BCReg expr_list(LexState *ls, ExpDesc *v) | |
| 1893 { | |
| 1894 BCReg n = 1; | |
| 1895 expr(ls, v); | |
| 1896 while (lex_opt(ls, ',')) { | |
| 1897 expr_tonextreg(ls->fs, v); | |
| 1898 expr(ls, v); | |
| 1899 n++; | |
| 1900 } | |
| 1901 return n; | |
| 1902 } | |
| 1903 | |
| 1904 /* Parse function argument list. */ | |
| 1905 static void parse_args(LexState *ls, ExpDesc *e) | |
| 1906 { | |
| 1907 FuncState *fs = ls->fs; | |
| 1908 ExpDesc args; | |
| 1909 BCIns ins; | |
| 1910 BCReg base; | |
| 1911 BCLine line = ls->linenumber; | |
| 1912 if (ls->tok == '(') { | |
| 1913 #if !LJ_52 | |
| 1914 if (line != ls->lastline) | |
| 1915 err_syntax(ls, LJ_ERR_XAMBIG); | |
| 1916 #endif | |
| 1917 lj_lex_next(ls); | |
| 1918 if (ls->tok == ')') { /* f(). */ | |
| 1919 args.k = VVOID; | |
| 1920 } else { | |
| 1921 expr_list(ls, &args); | |
| 1922 if (args.k == VCALL) /* f(a, b, g()) or f(a, b, ...). */ | |
| 1923 setbc_b(bcptr(fs, &args), 0); /* Pass on multiple results. */ | |
| 1924 } | |
| 1925 lex_match(ls, ')', '(', line); | |
| 1926 } else if (ls->tok == '{') { | |
| 1927 expr_table(ls, &args); | |
| 1928 } else if (ls->tok == TK_string) { | |
| 1929 expr_init(&args, VKSTR, 0); | |
| 1930 args.u.sval = strV(&ls->tokval); | |
| 1931 lj_lex_next(ls); | |
| 1932 } else { | |
| 1933 err_syntax(ls, LJ_ERR_XFUNARG); | |
| 1934 return; /* Silence compiler. */ | |
| 1935 } | |
| 1936 lj_assertFS(e->k == VNONRELOC, "bad expr type %d", e->k); | |
| 1937 base = e->u.s.info; /* Base register for call. */ | |
| 1938 if (args.k == VCALL) { | |
| 1939 ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1 - LJ_FR2); | |
| 1940 } else { | |
| 1941 if (args.k != VVOID) | |
| 1942 expr_tonextreg(fs, &args); | |
| 1943 ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base - LJ_FR2); | |
| 1944 } | |
| 1945 expr_init(e, VCALL, bcemit_INS(fs, ins)); | |
| 1946 e->u.s.aux = base; | |
| 1947 fs->bcbase[fs->pc - 1].line = line; | |
| 1948 fs->freereg = base+1; /* Leave one result by default. */ | |
| 1949 } | |
| 1950 | |
| 1951 /* Parse primary expression. */ | |
| 1952 static void expr_primary(LexState *ls, ExpDesc *v) | |
| 1953 { | |
| 1954 FuncState *fs = ls->fs; | |
| 1955 /* Parse prefix expression. */ | |
| 1956 if (ls->tok == '(') { | |
| 1957 BCLine line = ls->linenumber; | |
| 1958 lj_lex_next(ls); | |
| 1959 expr(ls, v); | |
| 1960 lex_match(ls, ')', '(', line); | |
| 1961 expr_discharge(ls->fs, v); | |
| 1962 } else if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) { | |
| 1963 var_lookup(ls, v); | |
| 1964 } else { | |
| 1965 err_syntax(ls, LJ_ERR_XSYMBOL); | |
| 1966 } | |
| 1967 for (;;) { /* Parse multiple expression suffixes. */ | |
| 1968 if (ls->tok == '.') { | |
| 1969 expr_field(ls, v); | |
| 1970 } else if (ls->tok == '[') { | |
| 1971 ExpDesc key; | |
| 1972 expr_toanyreg(fs, v); | |
| 1973 expr_bracket(ls, &key); | |
| 1974 expr_index(fs, v, &key); | |
| 1975 } else if (ls->tok == ':') { | |
| 1976 ExpDesc key; | |
| 1977 lj_lex_next(ls); | |
| 1978 expr_str(ls, &key); | |
| 1979 bcemit_method(fs, v, &key); | |
| 1980 parse_args(ls, v); | |
| 1981 } else if (ls->tok == '(' || ls->tok == TK_string || ls->tok == '{') { | |
| 1982 expr_tonextreg(fs, v); | |
| 1983 if (LJ_FR2) bcreg_reserve(fs, 1); | |
| 1984 parse_args(ls, v); | |
| 1985 } else { | |
| 1986 break; | |
| 1987 } | |
| 1988 } | |
| 1989 } | |
| 1990 | |
| 1991 /* Parse simple expression. */ | |
| 1992 static void expr_simple(LexState *ls, ExpDesc *v) | |
| 1993 { | |
| 1994 switch (ls->tok) { | |
| 1995 case TK_number: | |
| 1996 expr_init(v, (LJ_HASFFI && tviscdata(&ls->tokval)) ? VKCDATA : VKNUM, 0); | |
| 1997 copyTV(ls->L, &v->u.nval, &ls->tokval); | |
| 1998 break; | |
| 1999 case TK_string: | |
| 2000 expr_init(v, VKSTR, 0); | |
| 2001 v->u.sval = strV(&ls->tokval); | |
| 2002 break; | |
| 2003 case TK_nil: | |
| 2004 expr_init(v, VKNIL, 0); | |
| 2005 break; | |
| 2006 case TK_true: | |
| 2007 expr_init(v, VKTRUE, 0); | |
| 2008 break; | |
| 2009 case TK_false: | |
| 2010 expr_init(v, VKFALSE, 0); | |
| 2011 break; | |
| 2012 case TK_dots: { /* Vararg. */ | |
| 2013 FuncState *fs = ls->fs; | |
| 2014 BCReg base; | |
| 2015 checkcond(ls, fs->flags & PROTO_VARARG, LJ_ERR_XDOTS); | |
| 2016 bcreg_reserve(fs, 1); | |
| 2017 base = fs->freereg-1; | |
| 2018 expr_init(v, VCALL, bcemit_ABC(fs, BC_VARG, base, 2, fs->numparams)); | |
| 2019 v->u.s.aux = base; | |
| 2020 break; | |
| 2021 } | |
| 2022 case '{': /* Table constructor. */ | |
| 2023 expr_table(ls, v); | |
| 2024 return; | |
| 2025 case TK_function: | |
| 2026 lj_lex_next(ls); | |
| 2027 parse_body(ls, v, 0, ls->linenumber); | |
| 2028 return; | |
| 2029 default: | |
| 2030 expr_primary(ls, v); | |
| 2031 return; | |
| 2032 } | |
| 2033 lj_lex_next(ls); | |
| 2034 } | |
| 2035 | |
| 2036 /* Manage syntactic levels to avoid blowing up the stack. */ | |
| 2037 static void synlevel_begin(LexState *ls) | |
| 2038 { | |
| 2039 if (++ls->level >= LJ_MAX_XLEVEL) | |
| 2040 lj_lex_error(ls, 0, LJ_ERR_XLEVELS); | |
| 2041 } | |
| 2042 | |
| 2043 #define synlevel_end(ls) ((ls)->level--) | |
| 2044 | |
| 2045 /* Convert token to binary operator. */ | |
| 2046 static BinOpr token2binop(LexToken tok) | |
| 2047 { | |
| 2048 switch (tok) { | |
| 2049 case '+': return OPR_ADD; | |
| 2050 case '-': return OPR_SUB; | |
| 2051 case '*': return OPR_MUL; | |
| 2052 case '/': return OPR_DIV; | |
| 2053 case '%': return OPR_MOD; | |
| 2054 case '^': return OPR_POW; | |
| 2055 case TK_concat: return OPR_CONCAT; | |
| 2056 case TK_ne: return OPR_NE; | |
| 2057 case TK_eq: return OPR_EQ; | |
| 2058 case '<': return OPR_LT; | |
| 2059 case TK_le: return OPR_LE; | |
| 2060 case '>': return OPR_GT; | |
| 2061 case TK_ge: return OPR_GE; | |
| 2062 case TK_and: return OPR_AND; | |
| 2063 case TK_or: return OPR_OR; | |
| 2064 default: return OPR_NOBINOPR; | |
| 2065 } | |
| 2066 } | |
| 2067 | |
| 2068 /* Priorities for each binary operator. ORDER OPR. */ | |
| 2069 static const struct { | |
| 2070 uint8_t left; /* Left priority. */ | |
| 2071 uint8_t right; /* Right priority. */ | |
| 2072 } priority[] = { | |
| 2073 {6,6}, {6,6}, {7,7}, {7,7}, {7,7}, /* ADD SUB MUL DIV MOD */ | |
| 2074 {10,9}, {5,4}, /* POW CONCAT (right associative) */ | |
| 2075 {3,3}, {3,3}, /* EQ NE */ | |
| 2076 {3,3}, {3,3}, {3,3}, {3,3}, /* LT GE GT LE */ | |
| 2077 {2,2}, {1,1} /* AND OR */ | |
| 2078 }; | |
| 2079 | |
| 2080 #define UNARY_PRIORITY 8 /* Priority for unary operators. */ | |
| 2081 | |
| 2082 /* Forward declaration. */ | |
| 2083 static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit); | |
| 2084 | |
| 2085 /* Parse unary expression. */ | |
| 2086 static void expr_unop(LexState *ls, ExpDesc *v) | |
| 2087 { | |
| 2088 BCOp op; | |
| 2089 if (ls->tok == TK_not) { | |
| 2090 op = BC_NOT; | |
| 2091 } else if (ls->tok == '-') { | |
| 2092 op = BC_UNM; | |
| 2093 } else if (ls->tok == '#') { | |
| 2094 op = BC_LEN; | |
| 2095 } else { | |
| 2096 expr_simple(ls, v); | |
| 2097 return; | |
| 2098 } | |
| 2099 lj_lex_next(ls); | |
| 2100 expr_binop(ls, v, UNARY_PRIORITY); | |
| 2101 bcemit_unop(ls->fs, op, v); | |
| 2102 } | |
| 2103 | |
| 2104 /* Parse binary expressions with priority higher than the limit. */ | |
| 2105 static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit) | |
| 2106 { | |
| 2107 BinOpr op; | |
| 2108 synlevel_begin(ls); | |
| 2109 expr_unop(ls, v); | |
| 2110 op = token2binop(ls->tok); | |
| 2111 while (op != OPR_NOBINOPR && priority[op].left > limit) { | |
| 2112 ExpDesc v2; | |
| 2113 BinOpr nextop; | |
| 2114 lj_lex_next(ls); | |
| 2115 bcemit_binop_left(ls->fs, op, v); | |
| 2116 /* Parse binary expression with higher priority. */ | |
| 2117 nextop = expr_binop(ls, &v2, priority[op].right); | |
| 2118 bcemit_binop(ls->fs, op, v, &v2); | |
| 2119 op = nextop; | |
| 2120 } | |
| 2121 synlevel_end(ls); | |
| 2122 return op; /* Return unconsumed binary operator (if any). */ | |
| 2123 } | |
| 2124 | |
| 2125 /* Parse expression. */ | |
| 2126 static void expr(LexState *ls, ExpDesc *v) | |
| 2127 { | |
| 2128 expr_binop(ls, v, 0); /* Priority 0: parse whole expression. */ | |
| 2129 } | |
| 2130 | |
| 2131 /* Assign expression to the next register. */ | |
| 2132 static void expr_next(LexState *ls) | |
| 2133 { | |
| 2134 ExpDesc e; | |
| 2135 expr(ls, &e); | |
| 2136 expr_tonextreg(ls->fs, &e); | |
| 2137 } | |
| 2138 | |
| 2139 /* Parse conditional expression. */ | |
| 2140 static BCPos expr_cond(LexState *ls) | |
| 2141 { | |
| 2142 ExpDesc v; | |
| 2143 expr(ls, &v); | |
| 2144 if (v.k == VKNIL) v.k = VKFALSE; | |
| 2145 bcemit_branch_t(ls->fs, &v); | |
| 2146 return v.f; | |
| 2147 } | |
| 2148 | |
| 2149 /* -- Assignments --------------------------------------------------------- */ | |
| 2150 | |
| 2151 /* List of LHS variables. */ | |
| 2152 typedef struct LHSVarList { | |
| 2153 ExpDesc v; /* LHS variable. */ | |
| 2154 struct LHSVarList *prev; /* Link to previous LHS variable. */ | |
| 2155 } LHSVarList; | |
| 2156 | |
| 2157 /* Eliminate write-after-read hazards for local variable assignment. */ | |
| 2158 static void assign_hazard(LexState *ls, LHSVarList *lh, const ExpDesc *v) | |
| 2159 { | |
| 2160 FuncState *fs = ls->fs; | |
| 2161 BCReg reg = v->u.s.info; /* Check against this variable. */ | |
| 2162 BCReg tmp = fs->freereg; /* Rename to this temp. register (if needed). */ | |
| 2163 int hazard = 0; | |
| 2164 for (; lh; lh = lh->prev) { | |
| 2165 if (lh->v.k == VINDEXED) { | |
| 2166 if (lh->v.u.s.info == reg) { /* t[i], t = 1, 2 */ | |
| 2167 hazard = 1; | |
| 2168 lh->v.u.s.info = tmp; | |
| 2169 } | |
| 2170 if (lh->v.u.s.aux == reg) { /* t[i], i = 1, 2 */ | |
| 2171 hazard = 1; | |
| 2172 lh->v.u.s.aux = tmp; | |
| 2173 } | |
| 2174 } | |
| 2175 } | |
| 2176 if (hazard) { | |
| 2177 bcemit_AD(fs, BC_MOV, tmp, reg); /* Rename conflicting variable. */ | |
| 2178 bcreg_reserve(fs, 1); | |
| 2179 } | |
| 2180 } | |
| 2181 | |
| 2182 /* Adjust LHS/RHS of an assignment. */ | |
| 2183 static void assign_adjust(LexState *ls, BCReg nvars, BCReg nexps, ExpDesc *e) | |
| 2184 { | |
| 2185 FuncState *fs = ls->fs; | |
| 2186 int32_t extra = (int32_t)nvars - (int32_t)nexps; | |
| 2187 if (e->k == VCALL) { | |
| 2188 extra++; /* Compensate for the VCALL itself. */ | |
| 2189 if (extra < 0) extra = 0; | |
| 2190 setbc_b(bcptr(fs, e), extra+1); /* Fixup call results. */ | |
| 2191 if (extra > 1) bcreg_reserve(fs, (BCReg)extra-1); | |
| 2192 } else { | |
| 2193 if (e->k != VVOID) | |
| 2194 expr_tonextreg(fs, e); /* Close last expression. */ | |
| 2195 if (extra > 0) { /* Leftover LHS are set to nil. */ | |
| 2196 BCReg reg = fs->freereg; | |
| 2197 bcreg_reserve(fs, (BCReg)extra); | |
| 2198 bcemit_nil(fs, reg, (BCReg)extra); | |
| 2199 } | |
| 2200 } | |
| 2201 if (nexps > nvars) | |
| 2202 ls->fs->freereg -= nexps - nvars; /* Drop leftover regs. */ | |
| 2203 } | |
| 2204 | |
| 2205 /* Recursively parse assignment statement. */ | |
| 2206 static void parse_assignment(LexState *ls, LHSVarList *lh, BCReg nvars) | |
| 2207 { | |
| 2208 ExpDesc e; | |
| 2209 checkcond(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, LJ_ERR_XSYNTAX); | |
| 2210 if (lex_opt(ls, ',')) { /* Collect LHS list and recurse upwards. */ | |
| 2211 LHSVarList vl; | |
| 2212 vl.prev = lh; | |
| 2213 expr_primary(ls, &vl.v); | |
| 2214 if (vl.v.k == VLOCAL) | |
| 2215 assign_hazard(ls, lh, &vl.v); | |
| 2216 checklimit(ls->fs, ls->level + nvars, LJ_MAX_XLEVEL, "variable names"); | |
| 2217 parse_assignment(ls, &vl, nvars+1); | |
| 2218 } else { /* Parse RHS. */ | |
| 2219 BCReg nexps; | |
| 2220 lex_check(ls, '='); | |
| 2221 nexps = expr_list(ls, &e); | |
| 2222 if (nexps == nvars) { | |
| 2223 if (e.k == VCALL) { | |
| 2224 if (bc_op(*bcptr(ls->fs, &e)) == BC_VARG) { /* Vararg assignment. */ | |
| 2225 ls->fs->freereg--; | |
| 2226 e.k = VRELOCABLE; | |
| 2227 } else { /* Multiple call results. */ | |
| 2228 e.u.s.info = e.u.s.aux; /* Base of call is not relocatable. */ | |
| 2229 e.k = VNONRELOC; | |
| 2230 } | |
| 2231 } | |
| 2232 bcemit_store(ls->fs, &lh->v, &e); | |
| 2233 return; | |
| 2234 } | |
| 2235 assign_adjust(ls, nvars, nexps, &e); | |
| 2236 } | |
| 2237 /* Assign RHS to LHS and recurse downwards. */ | |
| 2238 expr_init(&e, VNONRELOC, ls->fs->freereg-1); | |
| 2239 bcemit_store(ls->fs, &lh->v, &e); | |
| 2240 } | |
| 2241 | |
| 2242 /* Parse call statement or assignment. */ | |
| 2243 static void parse_call_assign(LexState *ls) | |
| 2244 { | |
| 2245 FuncState *fs = ls->fs; | |
| 2246 LHSVarList vl; | |
| 2247 expr_primary(ls, &vl.v); | |
| 2248 if (vl.v.k == VCALL) { /* Function call statement. */ | |
| 2249 setbc_b(bcptr(fs, &vl.v), 1); /* No results. */ | |
| 2250 } else { /* Start of an assignment. */ | |
| 2251 vl.prev = NULL; | |
| 2252 parse_assignment(ls, &vl, 1); | |
| 2253 } | |
| 2254 } | |
| 2255 | |
| 2256 /* Parse 'local' statement. */ | |
| 2257 static void parse_local(LexState *ls) | |
| 2258 { | |
| 2259 if (lex_opt(ls, TK_function)) { /* Local function declaration. */ | |
| 2260 ExpDesc v, b; | |
| 2261 FuncState *fs = ls->fs; | |
| 2262 var_new(ls, 0, lex_str(ls)); | |
| 2263 expr_init(&v, VLOCAL, fs->freereg); | |
| 2264 v.u.s.aux = fs->varmap[fs->freereg]; | |
| 2265 bcreg_reserve(fs, 1); | |
| 2266 var_add(ls, 1); | |
| 2267 parse_body(ls, &b, 0, ls->linenumber); | |
| 2268 /* bcemit_store(fs, &v, &b) without setting VSTACK_VAR_RW. */ | |
| 2269 expr_free(fs, &b); | |
| 2270 expr_toreg(fs, &b, v.u.s.info); | |
| 2271 /* The upvalue is in scope, but the local is only valid after the store. */ | |
| 2272 var_get(ls, fs, fs->nactvar - 1).startpc = fs->pc; | |
| 2273 } else { /* Local variable declaration. */ | |
| 2274 ExpDesc e; | |
| 2275 BCReg nexps, nvars = 0; | |
| 2276 do { /* Collect LHS. */ | |
| 2277 var_new(ls, nvars++, lex_str(ls)); | |
| 2278 } while (lex_opt(ls, ',')); | |
| 2279 if (lex_opt(ls, '=')) { /* Optional RHS. */ | |
| 2280 nexps = expr_list(ls, &e); | |
| 2281 } else { /* Or implicitly set to nil. */ | |
| 2282 e.k = VVOID; | |
| 2283 nexps = 0; | |
| 2284 } | |
| 2285 assign_adjust(ls, nvars, nexps, &e); | |
| 2286 var_add(ls, nvars); | |
| 2287 } | |
| 2288 } | |
| 2289 | |
| 2290 /* Parse 'function' statement. */ | |
| 2291 static void parse_func(LexState *ls, BCLine line) | |
| 2292 { | |
| 2293 FuncState *fs; | |
| 2294 ExpDesc v, b; | |
| 2295 int needself = 0; | |
| 2296 lj_lex_next(ls); /* Skip 'function'. */ | |
| 2297 /* Parse function name. */ | |
| 2298 var_lookup(ls, &v); | |
| 2299 while (ls->tok == '.') /* Multiple dot-separated fields. */ | |
| 2300 expr_field(ls, &v); | |
| 2301 if (ls->tok == ':') { /* Optional colon to signify method call. */ | |
| 2302 needself = 1; | |
| 2303 expr_field(ls, &v); | |
| 2304 } | |
| 2305 parse_body(ls, &b, needself, line); | |
| 2306 fs = ls->fs; | |
| 2307 bcemit_store(fs, &v, &b); | |
| 2308 fs->bcbase[fs->pc - 1].line = line; /* Set line for the store. */ | |
| 2309 } | |
| 2310 | |
| 2311 /* -- Control transfer statements ----------------------------------------- */ | |
| 2312 | |
| 2313 /* Check for end of block. */ | |
| 2314 static int parse_isend(LexToken tok) | |
| 2315 { | |
| 2316 switch (tok) { | |
| 2317 case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof: | |
| 2318 return 1; | |
| 2319 default: | |
| 2320 return 0; | |
| 2321 } | |
| 2322 } | |
| 2323 | |
| 2324 /* Parse 'return' statement. */ | |
| 2325 static void parse_return(LexState *ls) | |
| 2326 { | |
| 2327 BCIns ins; | |
| 2328 FuncState *fs = ls->fs; | |
| 2329 lj_lex_next(ls); /* Skip 'return'. */ | |
| 2330 fs->flags |= PROTO_HAS_RETURN; | |
| 2331 if (parse_isend(ls->tok) || ls->tok == ';') { /* Bare return. */ | |
| 2332 ins = BCINS_AD(BC_RET0, 0, 1); | |
| 2333 } else { /* Return with one or more values. */ | |
| 2334 ExpDesc e; /* Receives the _last_ expression in the list. */ | |
| 2335 BCReg nret = expr_list(ls, &e); | |
| 2336 if (nret == 1) { /* Return one result. */ | |
| 2337 if (e.k == VCALL) { /* Check for tail call. */ | |
| 2338 BCIns *ip = bcptr(fs, &e); | |
| 2339 /* It doesn't pay off to add BC_VARGT just for 'return ...'. */ | |
| 2340 if (bc_op(*ip) == BC_VARG) goto notailcall; | |
| 2341 fs->pc--; | |
| 2342 ins = BCINS_AD(bc_op(*ip)-BC_CALL+BC_CALLT, bc_a(*ip), bc_c(*ip)); | |
| 2343 } else { /* Can return the result from any register. */ | |
| 2344 ins = BCINS_AD(BC_RET1, expr_toanyreg(fs, &e), 2); | |
| 2345 } | |
| 2346 } else { | |
| 2347 if (e.k == VCALL) { /* Append all results from a call. */ | |
| 2348 notailcall: | |
| 2349 setbc_b(bcptr(fs, &e), 0); | |
| 2350 ins = BCINS_AD(BC_RETM, fs->nactvar, e.u.s.aux - fs->nactvar); | |
| 2351 } else { | |
| 2352 expr_tonextreg(fs, &e); /* Force contiguous registers. */ | |
| 2353 ins = BCINS_AD(BC_RET, fs->nactvar, nret+1); | |
| 2354 } | |
| 2355 } | |
| 2356 } | |
| 2357 if (fs->flags & PROTO_CHILD) | |
| 2358 bcemit_AJ(fs, BC_UCLO, 0, 0); /* May need to close upvalues first. */ | |
| 2359 bcemit_INS(fs, ins); | |
| 2360 } | |
| 2361 | |
| 2362 /* Parse 'break' statement. */ | |
| 2363 static void parse_break(LexState *ls) | |
| 2364 { | |
| 2365 ls->fs->bl->flags |= FSCOPE_BREAK; | |
| 2366 gola_new(ls, NAME_BREAK, VSTACK_GOTO, bcemit_jmp(ls->fs)); | |
| 2367 } | |
| 2368 | |
| 2369 /* Parse 'goto' statement. */ | |
| 2370 static void parse_goto(LexState *ls) | |
| 2371 { | |
| 2372 FuncState *fs = ls->fs; | |
| 2373 GCstr *name = lex_str(ls); | |
| 2374 VarInfo *vl = gola_findlabel(ls, name); | |
| 2375 if (vl) /* Treat backwards goto within same scope like a loop. */ | |
| 2376 bcemit_AJ(fs, BC_LOOP, vl->slot, -1); /* No BC range check. */ | |
| 2377 fs->bl->flags |= FSCOPE_GOLA; | |
| 2378 gola_new(ls, name, VSTACK_GOTO, bcemit_jmp(fs)); | |
| 2379 } | |
| 2380 | |
| 2381 /* Parse label. */ | |
| 2382 static void parse_label(LexState *ls) | |
| 2383 { | |
| 2384 FuncState *fs = ls->fs; | |
| 2385 GCstr *name; | |
| 2386 MSize idx; | |
| 2387 fs->lasttarget = fs->pc; | |
| 2388 fs->bl->flags |= FSCOPE_GOLA; | |
| 2389 lj_lex_next(ls); /* Skip '::'. */ | |
| 2390 name = lex_str(ls); | |
| 2391 if (gola_findlabel(ls, name)) | |
| 2392 lj_lex_error(ls, 0, LJ_ERR_XLDUP, strdata(name)); | |
| 2393 idx = gola_new(ls, name, VSTACK_LABEL, fs->pc); | |
| 2394 lex_check(ls, TK_label); | |
| 2395 /* Recursively parse trailing statements: labels and ';' (Lua 5.2 only). */ | |
| 2396 for (;;) { | |
| 2397 if (ls->tok == TK_label) { | |
| 2398 synlevel_begin(ls); | |
| 2399 parse_label(ls); | |
| 2400 synlevel_end(ls); | |
| 2401 } else if (LJ_52 && ls->tok == ';') { | |
| 2402 lj_lex_next(ls); | |
| 2403 } else { | |
| 2404 break; | |
| 2405 } | |
| 2406 } | |
| 2407 /* Trailing label is considered to be outside of scope. */ | |
| 2408 if (parse_isend(ls->tok) && ls->tok != TK_until) | |
| 2409 ls->vstack[idx].slot = fs->bl->nactvar; | |
| 2410 gola_resolve(ls, fs->bl, idx); | |
| 2411 } | |
| 2412 | |
| 2413 /* -- Blocks, loops and conditional statements ---------------------------- */ | |
| 2414 | |
| 2415 /* Parse a block. */ | |
| 2416 static void parse_block(LexState *ls) | |
| 2417 { | |
| 2418 FuncState *fs = ls->fs; | |
| 2419 FuncScope bl; | |
| 2420 fscope_begin(fs, &bl, 0); | |
| 2421 parse_chunk(ls); | |
| 2422 fscope_end(fs); | |
| 2423 } | |
| 2424 | |
| 2425 /* Parse 'while' statement. */ | |
| 2426 static void parse_while(LexState *ls, BCLine line) | |
| 2427 { | |
| 2428 FuncState *fs = ls->fs; | |
| 2429 BCPos start, loop, condexit; | |
| 2430 FuncScope bl; | |
| 2431 lj_lex_next(ls); /* Skip 'while'. */ | |
| 2432 start = fs->lasttarget = fs->pc; | |
| 2433 condexit = expr_cond(ls); | |
| 2434 fscope_begin(fs, &bl, FSCOPE_LOOP); | |
| 2435 lex_check(ls, TK_do); | |
| 2436 loop = bcemit_AD(fs, BC_LOOP, fs->nactvar, 0); | |
| 2437 parse_block(ls); | |
| 2438 jmp_patch(fs, bcemit_jmp(fs), start); | |
| 2439 lex_match(ls, TK_end, TK_while, line); | |
| 2440 fscope_end(fs); | |
| 2441 jmp_tohere(fs, condexit); | |
| 2442 jmp_patchins(fs, loop, fs->pc); | |
| 2443 } | |
| 2444 | |
| 2445 /* Parse 'repeat' statement. */ | |
| 2446 static void parse_repeat(LexState *ls, BCLine line) | |
| 2447 { | |
| 2448 FuncState *fs = ls->fs; | |
| 2449 BCPos loop = fs->lasttarget = fs->pc; | |
| 2450 BCPos condexit; | |
| 2451 FuncScope bl1, bl2; | |
| 2452 fscope_begin(fs, &bl1, FSCOPE_LOOP); /* Breakable loop scope. */ | |
| 2453 fscope_begin(fs, &bl2, 0); /* Inner scope. */ | |
| 2454 lj_lex_next(ls); /* Skip 'repeat'. */ | |
| 2455 bcemit_AD(fs, BC_LOOP, fs->nactvar, 0); | |
| 2456 parse_chunk(ls); | |
| 2457 lex_match(ls, TK_until, TK_repeat, line); | |
| 2458 condexit = expr_cond(ls); /* Parse condition (still inside inner scope). */ | |
| 2459 if (!(bl2.flags & FSCOPE_UPVAL)) { /* No upvalues? Just end inner scope. */ | |
| 2460 fscope_end(fs); | |
| 2461 } else { /* Otherwise generate: cond: UCLO+JMP out, !cond: UCLO+JMP loop. */ | |
| 2462 parse_break(ls); /* Break from loop and close upvalues. */ | |
| 2463 jmp_tohere(fs, condexit); | |
| 2464 fscope_end(fs); /* End inner scope and close upvalues. */ | |
| 2465 condexit = bcemit_jmp(fs); | |
| 2466 } | |
| 2467 jmp_patch(fs, condexit, loop); /* Jump backwards if !cond. */ | |
| 2468 jmp_patchins(fs, loop, fs->pc); | |
| 2469 fscope_end(fs); /* End loop scope. */ | |
| 2470 } | |
| 2471 | |
| 2472 /* Parse numeric 'for'. */ | |
| 2473 static void parse_for_num(LexState *ls, GCstr *varname, BCLine line) | |
| 2474 { | |
| 2475 FuncState *fs = ls->fs; | |
| 2476 BCReg base = fs->freereg; | |
| 2477 FuncScope bl; | |
| 2478 BCPos loop, loopend; | |
| 2479 /* Hidden control variables. */ | |
| 2480 var_new_fixed(ls, FORL_IDX, VARNAME_FOR_IDX); | |
| 2481 var_new_fixed(ls, FORL_STOP, VARNAME_FOR_STOP); | |
| 2482 var_new_fixed(ls, FORL_STEP, VARNAME_FOR_STEP); | |
| 2483 /* Visible copy of index variable. */ | |
| 2484 var_new(ls, FORL_EXT, varname); | |
| 2485 lex_check(ls, '='); | |
| 2486 expr_next(ls); | |
| 2487 lex_check(ls, ','); | |
| 2488 expr_next(ls); | |
| 2489 if (lex_opt(ls, ',')) { | |
| 2490 expr_next(ls); | |
| 2491 } else { | |
| 2492 bcemit_AD(fs, BC_KSHORT, fs->freereg, 1); /* Default step is 1. */ | |
| 2493 bcreg_reserve(fs, 1); | |
| 2494 } | |
| 2495 var_add(ls, 3); /* Hidden control variables. */ | |
| 2496 lex_check(ls, TK_do); | |
| 2497 loop = bcemit_AJ(fs, BC_FORI, base, NO_JMP); | |
| 2498 fscope_begin(fs, &bl, 0); /* Scope for visible variables. */ | |
| 2499 var_add(ls, 1); | |
| 2500 bcreg_reserve(fs, 1); | |
| 2501 parse_block(ls); | |
| 2502 fscope_end(fs); | |
| 2503 /* Perform loop inversion. Loop control instructions are at the end. */ | |
| 2504 loopend = bcemit_AJ(fs, BC_FORL, base, NO_JMP); | |
| 2505 fs->bcbase[loopend].line = line; /* Fix line for control ins. */ | |
| 2506 jmp_patchins(fs, loopend, loop+1); | |
| 2507 jmp_patchins(fs, loop, fs->pc); | |
| 2508 } | |
| 2509 | |
| 2510 /* Try to predict whether the iterator is next() and specialize the bytecode. | |
| 2511 ** Detecting next() and pairs() by name is simplistic, but quite effective. | |
| 2512 ** The interpreter backs off if the check for the closure fails at runtime. | |
| 2513 */ | |
| 2514 static int predict_next(LexState *ls, FuncState *fs, BCPos pc) | |
| 2515 { | |
| 2516 BCIns ins = fs->bcbase[pc].ins; | |
| 2517 GCstr *name; | |
| 2518 cTValue *o; | |
| 2519 switch (bc_op(ins)) { | |
| 2520 case BC_MOV: | |
| 2521 if (bc_d(ins) >= fs->nactvar) return 0; | |
| 2522 name = gco2str(gcref(var_get(ls, fs, bc_d(ins)).name)); | |
| 2523 break; | |
| 2524 case BC_UGET: | |
| 2525 name = gco2str(gcref(ls->vstack[fs->uvmap[bc_d(ins)]].name)); | |
| 2526 break; | |
| 2527 case BC_GGET: | |
| 2528 /* There's no inverse index (yet), so lookup the strings. */ | |
| 2529 o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "pairs")); | |
| 2530 if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins)) | |
| 2531 return 1; | |
| 2532 o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "next")); | |
| 2533 if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins)) | |
| 2534 return 1; | |
| 2535 return 0; | |
| 2536 default: | |
| 2537 return 0; | |
| 2538 } | |
| 2539 return (name->len == 5 && !strcmp(strdata(name), "pairs")) || | |
| 2540 (name->len == 4 && !strcmp(strdata(name), "next")); | |
| 2541 } | |
| 2542 | |
| 2543 /* Parse 'for' iterator. */ | |
| 2544 static void parse_for_iter(LexState *ls, GCstr *indexname) | |
| 2545 { | |
| 2546 FuncState *fs = ls->fs; | |
| 2547 ExpDesc e; | |
| 2548 BCReg nvars = 0; | |
| 2549 BCLine line; | |
| 2550 BCReg base = fs->freereg + 3; | |
| 2551 BCPos loop, loopend, exprpc = fs->pc; | |
| 2552 FuncScope bl; | |
| 2553 int isnext; | |
| 2554 /* Hidden control variables. */ | |
| 2555 var_new_fixed(ls, nvars++, VARNAME_FOR_GEN); | |
| 2556 var_new_fixed(ls, nvars++, VARNAME_FOR_STATE); | |
| 2557 var_new_fixed(ls, nvars++, VARNAME_FOR_CTL); | |
| 2558 /* Visible variables returned from iterator. */ | |
| 2559 var_new(ls, nvars++, indexname); | |
| 2560 while (lex_opt(ls, ',')) | |
| 2561 var_new(ls, nvars++, lex_str(ls)); | |
| 2562 lex_check(ls, TK_in); | |
| 2563 line = ls->linenumber; | |
| 2564 assign_adjust(ls, 3, expr_list(ls, &e), &e); | |
| 2565 /* The iterator needs another 3 [4] slots (func [pc] | state ctl). */ | |
| 2566 bcreg_bump(fs, 3+LJ_FR2); | |
| 2567 isnext = (nvars <= 5 && predict_next(ls, fs, exprpc)); | |
| 2568 var_add(ls, 3); /* Hidden control variables. */ | |
| 2569 lex_check(ls, TK_do); | |
| 2570 loop = bcemit_AJ(fs, isnext ? BC_ISNEXT : BC_JMP, base, NO_JMP); | |
| 2571 fscope_begin(fs, &bl, 0); /* Scope for visible variables. */ | |
| 2572 var_add(ls, nvars-3); | |
| 2573 bcreg_reserve(fs, nvars-3); | |
| 2574 parse_block(ls); | |
| 2575 fscope_end(fs); | |
| 2576 /* Perform loop inversion. Loop control instructions are at the end. */ | |
| 2577 jmp_patchins(fs, loop, fs->pc); | |
| 2578 bcemit_ABC(fs, isnext ? BC_ITERN : BC_ITERC, base, nvars-3+1, 2+1); | |
| 2579 loopend = bcemit_AJ(fs, BC_ITERL, base, NO_JMP); | |
| 2580 fs->bcbase[loopend-1].line = line; /* Fix line for control ins. */ | |
| 2581 fs->bcbase[loopend].line = line; | |
| 2582 jmp_patchins(fs, loopend, loop+1); | |
| 2583 } | |
| 2584 | |
| 2585 /* Parse 'for' statement. */ | |
| 2586 static void parse_for(LexState *ls, BCLine line) | |
| 2587 { | |
| 2588 FuncState *fs = ls->fs; | |
| 2589 GCstr *varname; | |
| 2590 FuncScope bl; | |
| 2591 fscope_begin(fs, &bl, FSCOPE_LOOP); | |
| 2592 lj_lex_next(ls); /* Skip 'for'. */ | |
| 2593 varname = lex_str(ls); /* Get first variable name. */ | |
| 2594 if (ls->tok == '=') | |
| 2595 parse_for_num(ls, varname, line); | |
| 2596 else if (ls->tok == ',' || ls->tok == TK_in) | |
| 2597 parse_for_iter(ls, varname); | |
| 2598 else | |
| 2599 err_syntax(ls, LJ_ERR_XFOR); | |
| 2600 lex_match(ls, TK_end, TK_for, line); | |
| 2601 fscope_end(fs); /* Resolve break list. */ | |
| 2602 } | |
| 2603 | |
| 2604 /* Parse condition and 'then' block. */ | |
| 2605 static BCPos parse_then(LexState *ls) | |
| 2606 { | |
| 2607 BCPos condexit; | |
| 2608 lj_lex_next(ls); /* Skip 'if' or 'elseif'. */ | |
| 2609 condexit = expr_cond(ls); | |
| 2610 lex_check(ls, TK_then); | |
| 2611 parse_block(ls); | |
| 2612 return condexit; | |
| 2613 } | |
| 2614 | |
| 2615 /* Parse 'if' statement. */ | |
| 2616 static void parse_if(LexState *ls, BCLine line) | |
| 2617 { | |
| 2618 FuncState *fs = ls->fs; | |
| 2619 BCPos flist; | |
| 2620 BCPos escapelist = NO_JMP; | |
| 2621 flist = parse_then(ls); | |
| 2622 while (ls->tok == TK_elseif) { /* Parse multiple 'elseif' blocks. */ | |
| 2623 jmp_append(fs, &escapelist, bcemit_jmp(fs)); | |
| 2624 jmp_tohere(fs, flist); | |
| 2625 flist = parse_then(ls); | |
| 2626 } | |
| 2627 if (ls->tok == TK_else) { /* Parse optional 'else' block. */ | |
| 2628 jmp_append(fs, &escapelist, bcemit_jmp(fs)); | |
| 2629 jmp_tohere(fs, flist); | |
| 2630 lj_lex_next(ls); /* Skip 'else'. */ | |
| 2631 parse_block(ls); | |
| 2632 } else { | |
| 2633 jmp_append(fs, &escapelist, flist); | |
| 2634 } | |
| 2635 jmp_tohere(fs, escapelist); | |
| 2636 lex_match(ls, TK_end, TK_if, line); | |
| 2637 } | |
| 2638 | |
| 2639 /* -- Parse statements ---------------------------------------------------- */ | |
| 2640 | |
| 2641 /* Parse a statement. Returns 1 if it must be the last one in a chunk. */ | |
| 2642 static int parse_stmt(LexState *ls) | |
| 2643 { | |
| 2644 BCLine line = ls->linenumber; | |
| 2645 switch (ls->tok) { | |
| 2646 case TK_if: | |
| 2647 parse_if(ls, line); | |
| 2648 break; | |
| 2649 case TK_while: | |
| 2650 parse_while(ls, line); | |
| 2651 break; | |
| 2652 case TK_do: | |
| 2653 lj_lex_next(ls); | |
| 2654 parse_block(ls); | |
| 2655 lex_match(ls, TK_end, TK_do, line); | |
| 2656 break; | |
| 2657 case TK_for: | |
| 2658 parse_for(ls, line); | |
| 2659 break; | |
| 2660 case TK_repeat: | |
| 2661 parse_repeat(ls, line); | |
| 2662 break; | |
| 2663 case TK_function: | |
| 2664 parse_func(ls, line); | |
| 2665 break; | |
| 2666 case TK_local: | |
| 2667 lj_lex_next(ls); | |
| 2668 parse_local(ls); | |
| 2669 break; | |
| 2670 case TK_return: | |
| 2671 parse_return(ls); | |
| 2672 return 1; /* Must be last. */ | |
| 2673 case TK_break: | |
| 2674 lj_lex_next(ls); | |
| 2675 parse_break(ls); | |
| 2676 return !LJ_52; /* Must be last in Lua 5.1. */ | |
| 2677 #if LJ_52 | |
| 2678 case ';': | |
| 2679 lj_lex_next(ls); | |
| 2680 break; | |
| 2681 #endif | |
| 2682 case TK_label: | |
| 2683 parse_label(ls); | |
| 2684 break; | |
| 2685 case TK_goto: | |
| 2686 if (LJ_52 || lj_lex_lookahead(ls) == TK_name) { | |
| 2687 lj_lex_next(ls); | |
| 2688 parse_goto(ls); | |
| 2689 break; | |
| 2690 } | |
| 2691 /* fallthrough */ | |
| 2692 default: | |
| 2693 parse_call_assign(ls); | |
| 2694 break; | |
| 2695 } | |
| 2696 return 0; | |
| 2697 } | |
| 2698 | |
| 2699 /* A chunk is a list of statements optionally separated by semicolons. */ | |
| 2700 static void parse_chunk(LexState *ls) | |
| 2701 { | |
| 2702 int islast = 0; | |
| 2703 synlevel_begin(ls); | |
| 2704 while (!islast && !parse_isend(ls->tok)) { | |
| 2705 islast = parse_stmt(ls); | |
| 2706 lex_opt(ls, ';'); | |
| 2707 lj_assertLS(ls->fs->framesize >= ls->fs->freereg && | |
| 2708 ls->fs->freereg >= ls->fs->nactvar, | |
| 2709 "bad regalloc"); | |
| 2710 ls->fs->freereg = ls->fs->nactvar; /* Free registers after each stmt. */ | |
| 2711 } | |
| 2712 synlevel_end(ls); | |
| 2713 } | |
| 2714 | |
| 2715 /* Entry point of bytecode parser. */ | |
| 2716 GCproto *lj_parse(LexState *ls) | |
| 2717 { | |
| 2718 FuncState fs; | |
| 2719 FuncScope bl; | |
| 2720 GCproto *pt; | |
| 2721 lua_State *L = ls->L; | |
| 2722 #ifdef LUAJIT_DISABLE_DEBUGINFO | |
| 2723 ls->chunkname = lj_str_newlit(L, "="); | |
| 2724 #else | |
| 2725 ls->chunkname = lj_str_newz(L, ls->chunkarg); | |
| 2726 #endif | |
| 2727 setstrV(L, L->top, ls->chunkname); /* Anchor chunkname string. */ | |
| 2728 incr_top(L); | |
| 2729 ls->level = 0; | |
| 2730 fs_init(ls, &fs); | |
| 2731 fs.linedefined = 0; | |
| 2732 fs.numparams = 0; | |
| 2733 fs.bcbase = NULL; | |
| 2734 fs.bclim = 0; | |
| 2735 fs.flags |= PROTO_VARARG; /* Main chunk is always a vararg func. */ | |
| 2736 fscope_begin(&fs, &bl, 0); | |
| 2737 bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */ | |
| 2738 lj_lex_next(ls); /* Read-ahead first token. */ | |
| 2739 parse_chunk(ls); | |
| 2740 if (ls->tok != TK_eof) | |
| 2741 err_token(ls, TK_eof); | |
| 2742 pt = fs_finish(ls, ls->linenumber); | |
| 2743 L->top--; /* Drop chunkname. */ | |
| 2744 lj_assertL(fs.prev == NULL && ls->fs == NULL, "mismatched frame nesting"); | |
| 2745 lj_assertL(pt->sizeuv == 0, "toplevel proto has upvalues"); | |
| 2746 return pt; | |
| 2747 } | |
| 2748 |