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