diff options
Diffstat (limited to 'src/lj_parse.c')
| -rw-r--r-- | src/lj_parse.c | 360 |
1 files changed, 173 insertions, 187 deletions
diff --git a/src/lj_parse.c b/src/lj_parse.c index 96a5f2fc..66e5a034 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include "lj_gc.h" | 13 | #include "lj_gc.h" |
| 14 | #include "lj_err.h" | 14 | #include "lj_err.h" |
| 15 | #include "lj_debug.h" | 15 | #include "lj_debug.h" |
| 16 | #include "lj_buf.h" | ||
| 16 | #include "lj_str.h" | 17 | #include "lj_str.h" |
| 17 | #include "lj_tab.h" | 18 | #include "lj_tab.h" |
| 18 | #include "lj_func.h" | 19 | #include "lj_func.h" |
| @@ -21,6 +22,7 @@ | |||
| 21 | #if LJ_HASFFI | 22 | #if LJ_HASFFI |
| 22 | #include "lj_ctype.h" | 23 | #include "lj_ctype.h" |
| 23 | #endif | 24 | #endif |
| 25 | #include "lj_strfmt.h" | ||
| 24 | #include "lj_lex.h" | 26 | #include "lj_lex.h" |
| 25 | #include "lj_parse.h" | 27 | #include "lj_parse.h" |
| 26 | #include "lj_vm.h" | 28 | #include "lj_vm.h" |
| @@ -161,16 +163,22 @@ 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); | 163 | 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); | 164 | LJ_STATIC_ASSERT((int)BC_MODVV-(int)BC_ADDVV == (int)OPR_MOD-(int)OPR_ADD); |
| 163 | 165 | ||
| 166 | #ifdef LUA_USE_ASSERT | ||
| 167 | #define lj_assertFS(c, ...) (lj_assertG_(G(fs->L), (c), __VA_ARGS__)) | ||
| 168 | #else | ||
| 169 | #define lj_assertFS(c, ...) ((void)fs) | ||
| 170 | #endif | ||
| 171 | |||
| 164 | /* -- Error handling ------------------------------------------------------ */ | 172 | /* -- Error handling ------------------------------------------------------ */ |
| 165 | 173 | ||
| 166 | LJ_NORET LJ_NOINLINE static void err_syntax(LexState *ls, ErrMsg em) | 174 | LJ_NORET LJ_NOINLINE static void err_syntax(LexState *ls, ErrMsg em) |
| 167 | { | 175 | { |
| 168 | lj_lex_error(ls, ls->token, em); | 176 | lj_lex_error(ls, ls->tok, em); |
| 169 | } | 177 | } |
| 170 | 178 | ||
| 171 | LJ_NORET LJ_NOINLINE static void err_token(LexState *ls, LexToken token) | 179 | LJ_NORET LJ_NOINLINE static void err_token(LexState *ls, LexToken tok) |
| 172 | { | 180 | { |
| 173 | lj_lex_error(ls, ls->token, LJ_ERR_XTOKEN, lj_lex_token2str(ls, token)); | 181 | lj_lex_error(ls, ls->tok, LJ_ERR_XTOKEN, lj_lex_token2str(ls, tok)); |
| 174 | } | 182 | } |
| 175 | 183 | ||
| 176 | LJ_NORET static void err_limit(FuncState *fs, uint32_t limit, const char *what) | 184 | LJ_NORET static void err_limit(FuncState *fs, uint32_t limit, const char *what) |
| @@ -198,7 +206,7 @@ static BCReg const_num(FuncState *fs, ExpDesc *e) | |||
| 198 | { | 206 | { |
| 199 | lua_State *L = fs->L; | 207 | lua_State *L = fs->L; |
| 200 | TValue *o; | 208 | TValue *o; |
| 201 | lua_assert(expr_isnumk(e)); | 209 | lj_assertFS(expr_isnumk(e), "bad usage"); |
| 202 | o = lj_tab_set(L, fs->kt, &e->u.nval); | 210 | o = lj_tab_set(L, fs->kt, &e->u.nval); |
| 203 | if (tvhaskslot(o)) | 211 | if (tvhaskslot(o)) |
| 204 | return tvkslot(o); | 212 | return tvkslot(o); |
| @@ -223,7 +231,7 @@ static BCReg const_gc(FuncState *fs, GCobj *gc, uint32_t itype) | |||
| 223 | /* Add a string constant. */ | 231 | /* Add a string constant. */ |
| 224 | static BCReg const_str(FuncState *fs, ExpDesc *e) | 232 | static BCReg const_str(FuncState *fs, ExpDesc *e) |
| 225 | { | 233 | { |
| 226 | lua_assert(expr_isstrk(e) || e->k == VGLOBAL); | 234 | lj_assertFS(expr_isstrk(e) || e->k == VGLOBAL, "bad usage"); |
| 227 | return const_gc(fs, obj2gco(e->u.sval), LJ_TSTR); | 235 | return const_gc(fs, obj2gco(e->u.sval), LJ_TSTR); |
| 228 | } | 236 | } |
| 229 | 237 | ||
| @@ -311,7 +319,7 @@ static void jmp_patchins(FuncState *fs, BCPos pc, BCPos dest) | |||
| 311 | { | 319 | { |
| 312 | BCIns *jmp = &fs->bcbase[pc].ins; | 320 | BCIns *jmp = &fs->bcbase[pc].ins; |
| 313 | BCPos offset = dest-(pc+1)+BCBIAS_J; | 321 | BCPos offset = dest-(pc+1)+BCBIAS_J; |
| 314 | lua_assert(dest != NO_JMP); | 322 | lj_assertFS(dest != NO_JMP, "uninitialized jump target"); |
| 315 | if (offset > BCMAX_D) | 323 | if (offset > BCMAX_D) |
| 316 | err_syntax(fs->ls, LJ_ERR_XJUMP); | 324 | err_syntax(fs->ls, LJ_ERR_XJUMP); |
| 317 | setbc_d(jmp, offset); | 325 | setbc_d(jmp, offset); |
| @@ -360,7 +368,7 @@ static void jmp_patch(FuncState *fs, BCPos list, BCPos target) | |||
| 360 | if (target == fs->pc) { | 368 | if (target == fs->pc) { |
| 361 | jmp_tohere(fs, list); | 369 | jmp_tohere(fs, list); |
| 362 | } else { | 370 | } else { |
| 363 | lua_assert(target < fs->pc); | 371 | lj_assertFS(target < fs->pc, "bad jump target"); |
| 364 | jmp_patchval(fs, list, target, NO_REG, target); | 372 | jmp_patchval(fs, list, target, NO_REG, target); |
| 365 | } | 373 | } |
| 366 | } | 374 | } |
| @@ -390,7 +398,7 @@ static void bcreg_free(FuncState *fs, BCReg reg) | |||
| 390 | { | 398 | { |
| 391 | if (reg >= fs->nactvar) { | 399 | if (reg >= fs->nactvar) { |
| 392 | fs->freereg--; | 400 | fs->freereg--; |
| 393 | lua_assert(reg == fs->freereg); | 401 | lj_assertFS(reg == fs->freereg, "bad regfree"); |
| 394 | } | 402 | } |
| 395 | } | 403 | } |
| 396 | 404 | ||
| @@ -514,9 +522,9 @@ static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg) | |||
| 514 | ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)intV(tv)); | 522 | ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)intV(tv)); |
| 515 | else | 523 | else |
| 516 | #else | 524 | #else |
| 517 | lua_Number n = expr_numberV(e); | 525 | int64_t i64; |
| 518 | int32_t k = lj_num2int(n); | 526 | int32_t k; |
| 519 | if (checki16(k) && n == (lua_Number)k) | 527 | if (lj_num2int_cond(expr_numberV(e), i64, k, checki16((int32_t)i64))) |
| 520 | ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k); | 528 | ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k); |
| 521 | else | 529 | else |
| 522 | #endif | 530 | #endif |
| @@ -540,7 +548,7 @@ static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg) | |||
| 540 | } else if (e->k <= VKTRUE) { | 548 | } else if (e->k <= VKTRUE) { |
| 541 | ins = BCINS_AD(BC_KPRI, reg, const_pri(e)); | 549 | ins = BCINS_AD(BC_KPRI, reg, const_pri(e)); |
| 542 | } else { | 550 | } else { |
| 543 | lua_assert(e->k == VVOID || e->k == VJMP); | 551 | lj_assertFS(e->k == VVOID || e->k == VJMP, "bad expr type %d", e->k); |
| 544 | return; | 552 | return; |
| 545 | } | 553 | } |
| 546 | bcemit_INS(fs, ins); | 554 | bcemit_INS(fs, ins); |
| @@ -635,7 +643,7 @@ static void bcemit_store(FuncState *fs, ExpDesc *var, ExpDesc *e) | |||
| 635 | ins = BCINS_AD(BC_GSET, ra, const_str(fs, var)); | 643 | ins = BCINS_AD(BC_GSET, ra, const_str(fs, var)); |
| 636 | } else { | 644 | } else { |
| 637 | BCReg ra, rc; | 645 | BCReg ra, rc; |
| 638 | lua_assert(var->k == VINDEXED); | 646 | lj_assertFS(var->k == VINDEXED, "bad expr type %d", var->k); |
| 639 | ra = expr_toanyreg(fs, e); | 647 | ra = expr_toanyreg(fs, e); |
| 640 | rc = var->u.s.aux; | 648 | rc = var->u.s.aux; |
| 641 | if ((int32_t)rc < 0) { | 649 | if ((int32_t)rc < 0) { |
| @@ -643,10 +651,12 @@ static void bcemit_store(FuncState *fs, ExpDesc *var, ExpDesc *e) | |||
| 643 | } else if (rc > BCMAX_C) { | 651 | } else if (rc > BCMAX_C) { |
| 644 | ins = BCINS_ABC(BC_TSETB, ra, var->u.s.info, rc-(BCMAX_C+1)); | 652 | ins = BCINS_ABC(BC_TSETB, ra, var->u.s.info, rc-(BCMAX_C+1)); |
| 645 | } else { | 653 | } else { |
| 654 | #ifdef LUA_USE_ASSERT | ||
| 646 | /* Free late alloced key reg to avoid assert on free of value reg. */ | 655 | /* Free late alloced key reg to avoid assert on free of value reg. */ |
| 647 | /* This can only happen when called from expr_table(). */ | 656 | /* This can only happen when called from expr_table(). */ |
| 648 | lua_assert(e->k != VNONRELOC || ra < fs->nactvar || | 657 | if (e->k == VNONRELOC && ra >= fs->nactvar && rc >= ra) |
| 649 | rc < ra || (bcreg_free(fs, rc),1)); | 658 | bcreg_free(fs, rc); |
| 659 | #endif | ||
| 650 | ins = BCINS_ABC(BC_TSETV, ra, var->u.s.info, rc); | 660 | ins = BCINS_ABC(BC_TSETV, ra, var->u.s.info, rc); |
| 651 | } | 661 | } |
| 652 | } | 662 | } |
| @@ -657,19 +667,20 @@ static void bcemit_store(FuncState *fs, ExpDesc *var, ExpDesc *e) | |||
| 657 | /* Emit method lookup expression. */ | 667 | /* Emit method lookup expression. */ |
| 658 | static void bcemit_method(FuncState *fs, ExpDesc *e, ExpDesc *key) | 668 | static void bcemit_method(FuncState *fs, ExpDesc *e, ExpDesc *key) |
| 659 | { | 669 | { |
| 660 | BCReg idx, func, obj = expr_toanyreg(fs, e); | 670 | BCReg idx, func, fr2, obj = expr_toanyreg(fs, e); |
| 661 | expr_free(fs, e); | 671 | expr_free(fs, e); |
| 662 | func = fs->freereg; | 672 | func = fs->freereg; |
| 663 | bcemit_AD(fs, BC_MOV, func+1, obj); /* Copy object to first argument. */ | 673 | fr2 = fs->ls->fr2; |
| 664 | lua_assert(expr_isstrk(key)); | 674 | bcemit_AD(fs, BC_MOV, func+1+fr2, obj); /* Copy object to 1st argument. */ |
| 675 | lj_assertFS(expr_isstrk(key), "bad usage"); | ||
| 665 | idx = const_str(fs, key); | 676 | idx = const_str(fs, key); |
| 666 | if (idx <= BCMAX_C) { | 677 | if (idx <= BCMAX_C) { |
| 667 | bcreg_reserve(fs, 2); | 678 | bcreg_reserve(fs, 2+fr2); |
| 668 | bcemit_ABC(fs, BC_TGETS, func, obj, idx); | 679 | bcemit_ABC(fs, BC_TGETS, func, obj, idx); |
| 669 | } else { | 680 | } else { |
| 670 | bcreg_reserve(fs, 3); | 681 | bcreg_reserve(fs, 3+fr2); |
| 671 | bcemit_AD(fs, BC_KSTR, func+2, idx); | 682 | bcemit_AD(fs, BC_KSTR, func+2+fr2, idx); |
| 672 | bcemit_ABC(fs, BC_TGETV, func, obj, func+2); | 683 | bcemit_ABC(fs, BC_TGETV, func, obj, func+2+fr2); |
| 673 | fs->freereg--; | 684 | fs->freereg--; |
| 674 | } | 685 | } |
| 675 | e->u.s.info = func; | 686 | e->u.s.info = func; |
| @@ -771,8 +782,9 @@ static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2) | |||
| 771 | setnumV(&o, n); | 782 | setnumV(&o, n); |
| 772 | if (tvisnan(&o) || tvismzero(&o)) return 0; /* Avoid NaN and -0 as consts. */ | 783 | if (tvisnan(&o) || tvismzero(&o)) return 0; /* Avoid NaN and -0 as consts. */ |
| 773 | if (LJ_DUALNUM) { | 784 | if (LJ_DUALNUM) { |
| 774 | int32_t k = lj_num2int(n); | 785 | int64_t i64; |
| 775 | if ((lua_Number)k == n) { | 786 | int32_t k; |
| 787 | if (lj_num2int_check(n, i64, k)) { | ||
| 776 | setintV(&e1->u.nval, k); | 788 | setintV(&e1->u.nval, k); |
| 777 | return 1; | 789 | return 1; |
| 778 | } | 790 | } |
| @@ -801,7 +813,8 @@ static void bcemit_arith(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2) | |||
| 801 | else | 813 | else |
| 802 | rc = expr_toanyreg(fs, e2); | 814 | rc = expr_toanyreg(fs, e2); |
| 803 | /* 1st operand discharged by bcemit_binop_left, but need KNUM/KSHORT. */ | 815 | /* 1st operand discharged by bcemit_binop_left, but need KNUM/KSHORT. */ |
| 804 | lua_assert(expr_isnumk(e1) || e1->k == VNONRELOC); | 816 | lj_assertFS(expr_isnumk(e1) || e1->k == VNONRELOC, |
| 817 | "bad expr type %d", e1->k); | ||
| 805 | expr_toval(fs, e1); | 818 | expr_toval(fs, e1); |
| 806 | /* Avoid two consts to satisfy bytecode constraints. */ | 819 | /* Avoid two consts to satisfy bytecode constraints. */ |
| 807 | if (expr_isnumk(e1) && !expr_isnumk(e2) && | 820 | if (expr_isnumk(e1) && !expr_isnumk(e2) && |
| @@ -889,19 +902,20 @@ static void bcemit_binop(FuncState *fs, BinOpr op, ExpDesc *e1, ExpDesc *e2) | |||
| 889 | if (op <= OPR_POW) { | 902 | if (op <= OPR_POW) { |
| 890 | bcemit_arith(fs, op, e1, e2); | 903 | bcemit_arith(fs, op, e1, e2); |
| 891 | } else if (op == OPR_AND) { | 904 | } else if (op == OPR_AND) { |
| 892 | lua_assert(e1->t == NO_JMP); /* List must be closed. */ | 905 | lj_assertFS(e1->t == NO_JMP, "jump list not closed"); |
| 893 | expr_discharge(fs, e2); | 906 | expr_discharge(fs, e2); |
| 894 | jmp_append(fs, &e2->f, e1->f); | 907 | jmp_append(fs, &e2->f, e1->f); |
| 895 | *e1 = *e2; | 908 | *e1 = *e2; |
| 896 | } else if (op == OPR_OR) { | 909 | } else if (op == OPR_OR) { |
| 897 | lua_assert(e1->f == NO_JMP); /* List must be closed. */ | 910 | lj_assertFS(e1->f == NO_JMP, "jump list not closed"); |
| 898 | expr_discharge(fs, e2); | 911 | expr_discharge(fs, e2); |
| 899 | jmp_append(fs, &e2->t, e1->t); | 912 | jmp_append(fs, &e2->t, e1->t); |
| 900 | *e1 = *e2; | 913 | *e1 = *e2; |
| 901 | } else if (op == OPR_CONCAT) { | 914 | } else if (op == OPR_CONCAT) { |
| 902 | expr_toval(fs, e2); | 915 | expr_toval(fs, e2); |
| 903 | if (e2->k == VRELOCABLE && bc_op(*bcptr(fs, e2)) == BC_CAT) { | 916 | if (e2->k == VRELOCABLE && bc_op(*bcptr(fs, e2)) == BC_CAT) { |
| 904 | lua_assert(e1->u.s.info == bc_b(*bcptr(fs, e2))-1); | 917 | lj_assertFS(e1->u.s.info == bc_b(*bcptr(fs, e2))-1, |
| 918 | "bad CAT stack layout"); | ||
| 905 | expr_free(fs, e1); | 919 | expr_free(fs, e1); |
| 906 | setbc_b(bcptr(fs, e2), e1->u.s.info); | 920 | setbc_b(bcptr(fs, e2), e1->u.s.info); |
| 907 | e1->u.s.info = e2->u.s.info; | 921 | e1->u.s.info = e2->u.s.info; |
| @@ -913,8 +927,9 @@ static void bcemit_binop(FuncState *fs, BinOpr op, ExpDesc *e1, ExpDesc *e2) | |||
| 913 | } | 927 | } |
| 914 | e1->k = VRELOCABLE; | 928 | e1->k = VRELOCABLE; |
| 915 | } else { | 929 | } else { |
| 916 | lua_assert(op == OPR_NE || op == OPR_EQ || | 930 | lj_assertFS(op == OPR_NE || op == OPR_EQ || |
| 917 | op == OPR_LT || op == OPR_GE || op == OPR_LE || op == OPR_GT); | 931 | op == OPR_LT || op == OPR_GE || op == OPR_LE || op == OPR_GT, |
| 932 | "bad binop %d", op); | ||
| 918 | bcemit_comp(fs, op, e1, e2); | 933 | bcemit_comp(fs, op, e1, e2); |
| 919 | } | 934 | } |
| 920 | } | 935 | } |
| @@ -943,10 +958,10 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e) | |||
| 943 | e->u.s.info = fs->freereg-1; | 958 | e->u.s.info = fs->freereg-1; |
| 944 | e->k = VNONRELOC; | 959 | e->k = VNONRELOC; |
| 945 | } else { | 960 | } else { |
| 946 | lua_assert(e->k == VNONRELOC); | 961 | lj_assertFS(e->k == VNONRELOC, "bad expr type %d", e->k); |
| 947 | } | 962 | } |
| 948 | } else { | 963 | } else { |
| 949 | lua_assert(op == BC_UNM || op == BC_LEN); | 964 | lj_assertFS(op == BC_UNM || op == BC_LEN, "bad unop %d", op); |
| 950 | if (op == BC_UNM && !expr_hasjump(e)) { /* Constant-fold negations. */ | 965 | if (op == BC_UNM && !expr_hasjump(e)) { /* Constant-fold negations. */ |
| 951 | #if LJ_HASFFI | 966 | #if LJ_HASFFI |
| 952 | if (e->k == VKCDATA) { /* Fold in-place since cdata is not interned. */ | 967 | if (e->k == VKCDATA) { /* Fold in-place since cdata is not interned. */ |
| @@ -986,7 +1001,7 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e) | |||
| 986 | /* Check and consume optional token. */ | 1001 | /* Check and consume optional token. */ |
| 987 | static int lex_opt(LexState *ls, LexToken tok) | 1002 | static int lex_opt(LexState *ls, LexToken tok) |
| 988 | { | 1003 | { |
| 989 | if (ls->token == tok) { | 1004 | if (ls->tok == tok) { |
| 990 | lj_lex_next(ls); | 1005 | lj_lex_next(ls); |
| 991 | return 1; | 1006 | return 1; |
| 992 | } | 1007 | } |
| @@ -996,7 +1011,7 @@ static int lex_opt(LexState *ls, LexToken tok) | |||
| 996 | /* Check and consume token. */ | 1011 | /* Check and consume token. */ |
| 997 | static void lex_check(LexState *ls, LexToken tok) | 1012 | static void lex_check(LexState *ls, LexToken tok) |
| 998 | { | 1013 | { |
| 999 | if (ls->token != tok) | 1014 | if (ls->tok != tok) |
| 1000 | err_token(ls, tok); | 1015 | err_token(ls, tok); |
| 1001 | lj_lex_next(ls); | 1016 | lj_lex_next(ls); |
| 1002 | } | 1017 | } |
| @@ -1010,7 +1025,7 @@ static void lex_match(LexState *ls, LexToken what, LexToken who, BCLine line) | |||
| 1010 | } else { | 1025 | } else { |
| 1011 | const char *swhat = lj_lex_token2str(ls, what); | 1026 | const char *swhat = lj_lex_token2str(ls, what); |
| 1012 | const char *swho = lj_lex_token2str(ls, who); | 1027 | const char *swho = lj_lex_token2str(ls, who); |
| 1013 | lj_lex_error(ls, ls->token, LJ_ERR_XMATCH, swhat, swho, line); | 1028 | lj_lex_error(ls, ls->tok, LJ_ERR_XMATCH, swhat, swho, line); |
| 1014 | } | 1029 | } |
| 1015 | } | 1030 | } |
| 1016 | } | 1031 | } |
| @@ -1019,9 +1034,9 @@ static void lex_match(LexState *ls, LexToken what, LexToken who, BCLine line) | |||
| 1019 | static GCstr *lex_str(LexState *ls) | 1034 | static GCstr *lex_str(LexState *ls) |
| 1020 | { | 1035 | { |
| 1021 | GCstr *s; | 1036 | GCstr *s; |
| 1022 | if (ls->token != TK_name && (LJ_52 || ls->token != TK_goto)) | 1037 | if (ls->tok != TK_name && (LJ_52 || ls->tok != TK_goto)) |
| 1023 | err_token(ls, TK_name); | 1038 | err_token(ls, TK_name); |
| 1024 | s = strV(&ls->tokenval); | 1039 | s = strV(&ls->tokval); |
| 1025 | lj_lex_next(ls); | 1040 | lj_lex_next(ls); |
| 1026 | return s; | 1041 | return s; |
| 1027 | } | 1042 | } |
| @@ -1041,8 +1056,9 @@ static void var_new(LexState *ls, BCReg n, GCstr *name) | |||
| 1041 | lj_lex_error(ls, 0, LJ_ERR_XLIMC, LJ_MAX_VSTACK); | 1056 | lj_lex_error(ls, 0, LJ_ERR_XLIMC, LJ_MAX_VSTACK); |
| 1042 | lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo); | 1057 | lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo); |
| 1043 | } | 1058 | } |
| 1044 | lua_assert((uintptr_t)name < VARNAME__MAX || | 1059 | lj_assertFS((uintptr_t)name < VARNAME__MAX || |
| 1045 | lj_tab_getstr(fs->kt, name) != NULL); | 1060 | lj_tab_getstr(fs->kt, name) != NULL, |
| 1061 | "unanchored variable name"); | ||
| 1046 | /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */ | 1062 | /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */ |
| 1047 | setgcref(ls->vstack[vtop].name, obj2gco(name)); | 1063 | setgcref(ls->vstack[vtop].name, obj2gco(name)); |
| 1048 | fs->varmap[fs->nactvar+n] = (uint16_t)vtop; | 1064 | fs->varmap[fs->nactvar+n] = (uint16_t)vtop; |
| @@ -1097,7 +1113,7 @@ static MSize var_lookup_uv(FuncState *fs, MSize vidx, ExpDesc *e) | |||
| 1097 | return i; /* Already exists. */ | 1113 | return i; /* Already exists. */ |
| 1098 | /* Otherwise create a new one. */ | 1114 | /* Otherwise create a new one. */ |
| 1099 | checklimit(fs, fs->nuv, LJ_MAX_UPVAL, "upvalues"); | 1115 | checklimit(fs, fs->nuv, LJ_MAX_UPVAL, "upvalues"); |
| 1100 | lua_assert(e->k == VLOCAL || e->k == VUPVAL); | 1116 | lj_assertFS(e->k == VLOCAL || e->k == VUPVAL, "bad expr type %d", e->k); |
| 1101 | fs->uvmap[n] = (uint16_t)vidx; | 1117 | fs->uvmap[n] = (uint16_t)vidx; |
| 1102 | fs->uvtmp[n] = (uint16_t)(e->k == VLOCAL ? vidx : LJ_MAX_VSTACK+e->u.s.info); | 1118 | fs->uvtmp[n] = (uint16_t)(e->k == VLOCAL ? vidx : LJ_MAX_VSTACK+e->u.s.info); |
| 1103 | fs->nuv = n+1; | 1119 | fs->nuv = n+1; |
| @@ -1148,7 +1164,8 @@ static MSize gola_new(LexState *ls, GCstr *name, uint8_t info, BCPos pc) | |||
| 1148 | lj_lex_error(ls, 0, LJ_ERR_XLIMC, LJ_MAX_VSTACK); | 1164 | lj_lex_error(ls, 0, LJ_ERR_XLIMC, LJ_MAX_VSTACK); |
| 1149 | lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo); | 1165 | lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo); |
| 1150 | } | 1166 | } |
| 1151 | lua_assert(name == NAME_BREAK || lj_tab_getstr(fs->kt, name) != NULL); | 1167 | lj_assertFS(name == NAME_BREAK || lj_tab_getstr(fs->kt, name) != NULL, |
| 1168 | "unanchored label name"); | ||
| 1152 | /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */ | 1169 | /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */ |
| 1153 | setgcref(ls->vstack[vtop].name, obj2gco(name)); | 1170 | setgcref(ls->vstack[vtop].name, obj2gco(name)); |
| 1154 | ls->vstack[vtop].startpc = pc; | 1171 | ls->vstack[vtop].startpc = pc; |
| @@ -1178,8 +1195,9 @@ static void gola_close(LexState *ls, VarInfo *vg) | |||
| 1178 | FuncState *fs = ls->fs; | 1195 | FuncState *fs = ls->fs; |
| 1179 | BCPos pc = vg->startpc; | 1196 | BCPos pc = vg->startpc; |
| 1180 | BCIns *ip = &fs->bcbase[pc].ins; | 1197 | BCIns *ip = &fs->bcbase[pc].ins; |
| 1181 | lua_assert(gola_isgoto(vg)); | 1198 | lj_assertFS(gola_isgoto(vg), "expected goto"); |
| 1182 | lua_assert(bc_op(*ip) == BC_JMP || bc_op(*ip) == BC_UCLO); | 1199 | lj_assertFS(bc_op(*ip) == BC_JMP || bc_op(*ip) == BC_UCLO, |
| 1200 | "bad bytecode op %d", bc_op(*ip)); | ||
| 1183 | setbc_a(ip, vg->slot); | 1201 | setbc_a(ip, vg->slot); |
| 1184 | if (bc_op(*ip) == BC_JMP) { | 1202 | if (bc_op(*ip) == BC_JMP) { |
| 1185 | BCPos next = jmp_next(fs, pc); | 1203 | BCPos next = jmp_next(fs, pc); |
| @@ -1198,9 +1216,9 @@ static void gola_resolve(LexState *ls, FuncScope *bl, MSize idx) | |||
| 1198 | if (gcrefeq(vg->name, vl->name) && gola_isgoto(vg)) { | 1216 | if (gcrefeq(vg->name, vl->name) && gola_isgoto(vg)) { |
| 1199 | if (vg->slot < vl->slot) { | 1217 | if (vg->slot < vl->slot) { |
| 1200 | GCstr *name = strref(var_get(ls, ls->fs, vg->slot).name); | 1218 | GCstr *name = strref(var_get(ls, ls->fs, vg->slot).name); |
| 1201 | lua_assert((uintptr_t)name >= VARNAME__MAX); | 1219 | lj_assertLS((uintptr_t)name >= VARNAME__MAX, "expected goto name"); |
| 1202 | ls->linenumber = ls->fs->bcbase[vg->startpc].line; | 1220 | ls->linenumber = ls->fs->bcbase[vg->startpc].line; |
| 1203 | lua_assert(strref(vg->name) != NAME_BREAK); | 1221 | lj_assertLS(strref(vg->name) != NAME_BREAK, "unexpected break"); |
| 1204 | lj_lex_error(ls, 0, LJ_ERR_XGSCOPE, | 1222 | lj_lex_error(ls, 0, LJ_ERR_XGSCOPE, |
| 1205 | strdata(strref(vg->name)), strdata(name)); | 1223 | strdata(strref(vg->name)), strdata(name)); |
| 1206 | } | 1224 | } |
| @@ -1264,7 +1282,7 @@ static void fscope_begin(FuncState *fs, FuncScope *bl, int flags) | |||
| 1264 | bl->vstart = fs->ls->vtop; | 1282 | bl->vstart = fs->ls->vtop; |
| 1265 | bl->prev = fs->bl; | 1283 | bl->prev = fs->bl; |
| 1266 | fs->bl = bl; | 1284 | fs->bl = bl; |
| 1267 | lua_assert(fs->freereg == fs->nactvar); | 1285 | lj_assertFS(fs->freereg == fs->nactvar, "bad regalloc"); |
| 1268 | } | 1286 | } |
| 1269 | 1287 | ||
| 1270 | /* End a scope. */ | 1288 | /* End a scope. */ |
| @@ -1275,7 +1293,7 @@ static void fscope_end(FuncState *fs) | |||
| 1275 | fs->bl = bl->prev; | 1293 | fs->bl = bl->prev; |
| 1276 | var_remove(ls, bl->nactvar); | 1294 | var_remove(ls, bl->nactvar); |
| 1277 | fs->freereg = fs->nactvar; | 1295 | fs->freereg = fs->nactvar; |
| 1278 | lua_assert(bl->nactvar == fs->nactvar); | 1296 | lj_assertFS(bl->nactvar == fs->nactvar, "bad regalloc"); |
| 1279 | if ((bl->flags & (FSCOPE_UPVAL|FSCOPE_NOCLOSE)) == FSCOPE_UPVAL) | 1297 | if ((bl->flags & (FSCOPE_UPVAL|FSCOPE_NOCLOSE)) == FSCOPE_UPVAL) |
| 1280 | bcemit_AJ(fs, BC_UCLO, bl->nactvar, 0); | 1298 | bcemit_AJ(fs, BC_UCLO, bl->nactvar, 0); |
| 1281 | if ((bl->flags & FSCOPE_BREAK)) { | 1299 | if ((bl->flags & FSCOPE_BREAK)) { |
| @@ -1310,9 +1328,12 @@ static void fs_fixup_bc(FuncState *fs, GCproto *pt, BCIns *bc, MSize n) | |||
| 1310 | { | 1328 | { |
| 1311 | BCInsLine *base = fs->bcbase; | 1329 | BCInsLine *base = fs->bcbase; |
| 1312 | MSize i; | 1330 | MSize i; |
| 1331 | BCIns op; | ||
| 1313 | pt->sizebc = n; | 1332 | pt->sizebc = n; |
| 1314 | bc[0] = BCINS_AD((fs->flags & PROTO_VARARG) ? BC_FUNCV : BC_FUNCF, | 1333 | if (fs->ls->fr2 != LJ_FR2) op = BC_NOT; /* Mark non-native prototype. */ |
| 1315 | fs->framesize, 0); | 1334 | else if ((fs->flags & PROTO_VARARG)) op = BC_FUNCV; |
| 1335 | else op = BC_FUNCF; | ||
| 1336 | bc[0] = BCINS_AD(op, fs->framesize, 0); | ||
| 1316 | for (i = 1; i < n; i++) | 1337 | for (i = 1; i < n; i++) |
| 1317 | bc[i] = base[i].ins; | 1338 | bc[i] = base[i].ins; |
| 1318 | } | 1339 | } |
| @@ -1362,14 +1383,14 @@ static void fs_fixup_k(FuncState *fs, GCproto *pt, void *kptr) | |||
| 1362 | Node *n = &node[i]; | 1383 | Node *n = &node[i]; |
| 1363 | if (tvhaskslot(&n->val)) { | 1384 | if (tvhaskslot(&n->val)) { |
| 1364 | ptrdiff_t kidx = (ptrdiff_t)tvkslot(&n->val); | 1385 | ptrdiff_t kidx = (ptrdiff_t)tvkslot(&n->val); |
| 1365 | lua_assert(!tvisint(&n->key)); | 1386 | lj_assertFS(!tvisint(&n->key), "unexpected integer key"); |
| 1366 | if (tvisnum(&n->key)) { | 1387 | if (tvisnum(&n->key)) { |
| 1367 | TValue *tv = &((TValue *)kptr)[kidx]; | 1388 | TValue *tv = &((TValue *)kptr)[kidx]; |
| 1368 | if (LJ_DUALNUM) { | 1389 | if (LJ_DUALNUM) { |
| 1369 | lua_Number nn = numV(&n->key); | 1390 | int64_t i64; |
| 1370 | int32_t k = lj_num2int(nn); | 1391 | int32_t k; |
| 1371 | lua_assert(!tvismzero(&n->key)); | 1392 | lj_assertFS(!tvismzero(&n->key), "unexpected -0 key"); |
| 1372 | if ((lua_Number)k == nn) | 1393 | if (lj_num2int_check(numV(&n->key), i64, k)) |
| 1373 | setintV(tv, k); | 1394 | setintV(tv, k); |
| 1374 | else | 1395 | else |
| 1375 | *tv = n->key; | 1396 | *tv = n->key; |
| @@ -1416,98 +1437,66 @@ static void fs_fixup_line(FuncState *fs, GCproto *pt, | |||
| 1416 | uint8_t *li = (uint8_t *)lineinfo; | 1437 | uint8_t *li = (uint8_t *)lineinfo; |
| 1417 | do { | 1438 | do { |
| 1418 | BCLine delta = base[i].line - first; | 1439 | BCLine delta = base[i].line - first; |
| 1419 | lua_assert(delta >= 0 && delta < 256); | 1440 | lj_assertFS(delta >= 0 && delta < 256, "bad line delta"); |
| 1420 | li[i] = (uint8_t)delta; | 1441 | li[i] = (uint8_t)delta; |
| 1421 | } while (++i < n); | 1442 | } while (++i < n); |
| 1422 | } else if (LJ_LIKELY(numline < 65536)) { | 1443 | } else if (LJ_LIKELY(numline < 65536)) { |
| 1423 | uint16_t *li = (uint16_t *)lineinfo; | 1444 | uint16_t *li = (uint16_t *)lineinfo; |
| 1424 | do { | 1445 | do { |
| 1425 | BCLine delta = base[i].line - first; | 1446 | BCLine delta = base[i].line - first; |
| 1426 | lua_assert(delta >= 0 && delta < 65536); | 1447 | lj_assertFS(delta >= 0 && delta < 65536, "bad line delta"); |
| 1427 | li[i] = (uint16_t)delta; | 1448 | li[i] = (uint16_t)delta; |
| 1428 | } while (++i < n); | 1449 | } while (++i < n); |
| 1429 | } else { | 1450 | } else { |
| 1430 | uint32_t *li = (uint32_t *)lineinfo; | 1451 | uint32_t *li = (uint32_t *)lineinfo; |
| 1431 | do { | 1452 | do { |
| 1432 | BCLine delta = base[i].line - first; | 1453 | BCLine delta = base[i].line - first; |
| 1433 | lua_assert(delta >= 0); | 1454 | lj_assertFS(delta >= 0, "bad line delta"); |
| 1434 | li[i] = (uint32_t)delta; | 1455 | li[i] = (uint32_t)delta; |
| 1435 | } while (++i < n); | 1456 | } while (++i < n); |
| 1436 | } | 1457 | } |
| 1437 | } | 1458 | } |
| 1438 | 1459 | ||
| 1439 | /* Resize buffer if needed. */ | ||
| 1440 | static LJ_NOINLINE void fs_buf_resize(LexState *ls, MSize len) | ||
| 1441 | { | ||
| 1442 | MSize sz = ls->sb.sz * 2; | ||
| 1443 | while (ls->sb.n + len > sz) sz = sz * 2; | ||
| 1444 | lj_str_resizebuf(ls->L, &ls->sb, sz); | ||
| 1445 | } | ||
| 1446 | |||
| 1447 | static LJ_AINLINE void fs_buf_need(LexState *ls, MSize len) | ||
| 1448 | { | ||
| 1449 | if (LJ_UNLIKELY(ls->sb.n + len > ls->sb.sz)) | ||
| 1450 | fs_buf_resize(ls, len); | ||
| 1451 | } | ||
| 1452 | |||
| 1453 | /* Add string to buffer. */ | ||
| 1454 | static void fs_buf_str(LexState *ls, const char *str, MSize len) | ||
| 1455 | { | ||
| 1456 | char *p = ls->sb.buf + ls->sb.n; | ||
| 1457 | MSize i; | ||
| 1458 | ls->sb.n += len; | ||
| 1459 | for (i = 0; i < len; i++) p[i] = str[i]; | ||
| 1460 | } | ||
| 1461 | |||
| 1462 | /* Add ULEB128 value to buffer. */ | ||
| 1463 | static void fs_buf_uleb128(LexState *ls, uint32_t v) | ||
| 1464 | { | ||
| 1465 | MSize n = ls->sb.n; | ||
| 1466 | uint8_t *p = (uint8_t *)ls->sb.buf; | ||
| 1467 | for (; v >= 0x80; v >>= 7) | ||
| 1468 | p[n++] = (uint8_t)((v & 0x7f) | 0x80); | ||
| 1469 | p[n++] = (uint8_t)v; | ||
| 1470 | ls->sb.n = n; | ||
| 1471 | } | ||
| 1472 | |||
| 1473 | /* Prepare variable info for prototype. */ | 1460 | /* Prepare variable info for prototype. */ |
| 1474 | static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar) | 1461 | static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar) |
| 1475 | { | 1462 | { |
| 1476 | VarInfo *vs =ls->vstack, *ve; | 1463 | VarInfo *vs =ls->vstack, *ve; |
| 1477 | MSize i, n; | 1464 | MSize i, n; |
| 1478 | BCPos lastpc; | 1465 | BCPos lastpc; |
| 1479 | lj_str_resetbuf(&ls->sb); /* Copy to temp. string buffer. */ | 1466 | lj_buf_reset(&ls->sb); /* Copy to temp. string buffer. */ |
| 1480 | /* Store upvalue names. */ | 1467 | /* Store upvalue names. */ |
| 1481 | for (i = 0, n = fs->nuv; i < n; i++) { | 1468 | for (i = 0, n = fs->nuv; i < n; i++) { |
| 1482 | GCstr *s = strref(vs[fs->uvmap[i]].name); | 1469 | GCstr *s = strref(vs[fs->uvmap[i]].name); |
| 1483 | MSize len = s->len+1; | 1470 | MSize len = s->len+1; |
| 1484 | fs_buf_need(ls, len); | 1471 | char *p = lj_buf_more(&ls->sb, len); |
| 1485 | fs_buf_str(ls, strdata(s), len); | 1472 | p = lj_buf_wmem(p, strdata(s), len); |
| 1473 | ls->sb.w = p; | ||
| 1486 | } | 1474 | } |
| 1487 | *ofsvar = ls->sb.n; | 1475 | *ofsvar = sbuflen(&ls->sb); |
| 1488 | lastpc = 0; | 1476 | lastpc = 0; |
| 1489 | /* Store local variable names and compressed ranges. */ | 1477 | /* Store local variable names and compressed ranges. */ |
| 1490 | for (ve = vs + ls->vtop, vs += fs->vbase; vs < ve; vs++) { | 1478 | for (ve = vs + ls->vtop, vs += fs->vbase; vs < ve; vs++) { |
| 1491 | if (!gola_isgotolabel(vs)) { | 1479 | if (!gola_isgotolabel(vs)) { |
| 1492 | GCstr *s = strref(vs->name); | 1480 | GCstr *s = strref(vs->name); |
| 1493 | BCPos startpc; | 1481 | BCPos startpc; |
| 1482 | char *p; | ||
| 1494 | if ((uintptr_t)s < VARNAME__MAX) { | 1483 | if ((uintptr_t)s < VARNAME__MAX) { |
| 1495 | fs_buf_need(ls, 1 + 2*5); | 1484 | p = lj_buf_more(&ls->sb, 1 + 2*5); |
| 1496 | ls->sb.buf[ls->sb.n++] = (uint8_t)(uintptr_t)s; | 1485 | *p++ = (char)(uintptr_t)s; |
| 1497 | } else { | 1486 | } else { |
| 1498 | MSize len = s->len+1; | 1487 | MSize len = s->len+1; |
| 1499 | fs_buf_need(ls, len + 2*5); | 1488 | p = lj_buf_more(&ls->sb, len + 2*5); |
| 1500 | fs_buf_str(ls, strdata(s), len); | 1489 | p = lj_buf_wmem(p, strdata(s), len); |
| 1501 | } | 1490 | } |
| 1502 | startpc = vs->startpc; | 1491 | startpc = vs->startpc; |
| 1503 | fs_buf_uleb128(ls, startpc-lastpc); | 1492 | p = lj_strfmt_wuleb128(p, startpc-lastpc); |
| 1504 | fs_buf_uleb128(ls, vs->endpc-startpc); | 1493 | p = lj_strfmt_wuleb128(p, vs->endpc-startpc); |
| 1494 | ls->sb.w = p; | ||
| 1505 | lastpc = startpc; | 1495 | lastpc = startpc; |
| 1506 | } | 1496 | } |
| 1507 | } | 1497 | } |
| 1508 | fs_buf_need(ls, 1); | 1498 | lj_buf_putb(&ls->sb, '\0'); /* Terminator for varinfo. */ |
| 1509 | ls->sb.buf[ls->sb.n++] = '\0'; /* Terminator for varinfo. */ | 1499 | return sbuflen(&ls->sb); |
| 1510 | return ls->sb.n; | ||
| 1511 | } | 1500 | } |
| 1512 | 1501 | ||
| 1513 | /* Fixup variable info for prototype. */ | 1502 | /* Fixup variable info for prototype. */ |
| @@ -1515,7 +1504,7 @@ static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar) | |||
| 1515 | { | 1504 | { |
| 1516 | setmref(pt->uvinfo, p); | 1505 | setmref(pt->uvinfo, p); |
| 1517 | setmref(pt->varinfo, (char *)p + ofsvar); | 1506 | setmref(pt->varinfo, (char *)p + ofsvar); |
| 1518 | memcpy(p, ls->sb.buf, ls->sb.n); /* Copy from temp. string buffer. */ | 1507 | memcpy(p, ls->sb.b, sbuflen(&ls->sb)); /* Copy from temp. buffer. */ |
| 1519 | } | 1508 | } |
| 1520 | #else | 1509 | #else |
| 1521 | 1510 | ||
| @@ -1540,7 +1529,7 @@ static void fs_fixup_ret(FuncState *fs) | |||
| 1540 | } | 1529 | } |
| 1541 | fs->bl->flags |= FSCOPE_NOCLOSE; /* Handled above. */ | 1530 | fs->bl->flags |= FSCOPE_NOCLOSE; /* Handled above. */ |
| 1542 | fscope_end(fs); | 1531 | fscope_end(fs); |
| 1543 | lua_assert(fs->bl == NULL); | 1532 | lj_assertFS(fs->bl == NULL, "bad scope nesting"); |
| 1544 | /* May need to fixup returns encoded before first function was created. */ | 1533 | /* May need to fixup returns encoded before first function was created. */ |
| 1545 | if (fs->flags & PROTO_FIXUP_RETURN) { | 1534 | if (fs->flags & PROTO_FIXUP_RETURN) { |
| 1546 | BCPos pc; | 1535 | BCPos pc; |
| @@ -1605,14 +1594,14 @@ static GCproto *fs_finish(LexState *ls, BCLine line) | |||
| 1605 | fs_fixup_line(fs, pt, (void *)((char *)pt + ofsli), numline); | 1594 | fs_fixup_line(fs, pt, (void *)((char *)pt + ofsli), numline); |
| 1606 | fs_fixup_var(ls, pt, (uint8_t *)((char *)pt + ofsdbg), ofsvar); | 1595 | fs_fixup_var(ls, pt, (uint8_t *)((char *)pt + ofsdbg), ofsvar); |
| 1607 | 1596 | ||
| 1608 | lj_vmevent_send(L, BC, | 1597 | lj_vmevent_send(G(L), BC, |
| 1609 | setprotoV(L, L->top++, pt); | 1598 | setprotoV(V, V->top++, pt); |
| 1610 | ); | 1599 | ); |
| 1611 | 1600 | ||
| 1612 | L->top--; /* Pop table of constants. */ | 1601 | L->top--; /* Pop table of constants. */ |
| 1613 | ls->vtop = fs->vbase; /* Reset variable stack. */ | 1602 | ls->vtop = fs->vbase; /* Reset variable stack. */ |
| 1614 | ls->fs = fs->prev; | 1603 | ls->fs = fs->prev; |
| 1615 | lua_assert(ls->fs != NULL || ls->token == TK_eof); | 1604 | lj_assertL(ls->fs != NULL || ls->tok == TK_eof, "bad parser state"); |
| 1616 | return pt; | 1605 | return pt; |
| 1617 | } | 1606 | } |
| 1618 | 1607 | ||
| @@ -1668,9 +1657,9 @@ static void expr_index(FuncState *fs, ExpDesc *t, ExpDesc *e) | |||
| 1668 | } | 1657 | } |
| 1669 | } | 1658 | } |
| 1670 | #else | 1659 | #else |
| 1671 | lua_Number n = expr_numberV(e); | 1660 | int64_t i64; |
| 1672 | int32_t k = lj_num2int(n); | 1661 | int32_t k; |
| 1673 | if (checku8(k) && n == (lua_Number)k) { | 1662 | if (lj_num2int_cond(expr_numberV(e), i64, k, checku8((int32_t)i64))) { |
| 1674 | t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */ | 1663 | t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */ |
| 1675 | return; | 1664 | return; |
| 1676 | } | 1665 | } |
| @@ -1706,15 +1695,15 @@ static void expr_bracket(LexState *ls, ExpDesc *v) | |||
| 1706 | } | 1695 | } |
| 1707 | 1696 | ||
| 1708 | /* Get value of constant expression. */ | 1697 | /* Get value of constant expression. */ |
| 1709 | static void expr_kvalue(TValue *v, ExpDesc *e) | 1698 | static void expr_kvalue(FuncState *fs, TValue *v, ExpDesc *e) |
| 1710 | { | 1699 | { |
| 1700 | UNUSED(fs); | ||
| 1711 | if (e->k <= VKTRUE) { | 1701 | if (e->k <= VKTRUE) { |
| 1712 | setitype(v, ~(uint32_t)e->k); | 1702 | setpriV(v, ~(uint32_t)e->k); |
| 1713 | } else if (e->k == VKSTR) { | 1703 | } else if (e->k == VKSTR) { |
| 1714 | setgcref(v->gcr, obj2gco(e->u.sval)); | 1704 | setgcVraw(v, obj2gco(e->u.sval), LJ_TSTR); |
| 1715 | setitype(v, LJ_TSTR); | ||
| 1716 | } else { | 1705 | } else { |
| 1717 | lua_assert(tvisnumber(expr_numtv(e))); | 1706 | lj_assertFS(tvisnumber(expr_numtv(e)), "bad number constant"); |
| 1718 | *v = *expr_numtv(e); | 1707 | *v = *expr_numtv(e); |
| 1719 | } | 1708 | } |
| 1720 | } | 1709 | } |
| @@ -1725,7 +1714,7 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
| 1725 | FuncState *fs = ls->fs; | 1714 | FuncState *fs = ls->fs; |
| 1726 | BCLine line = ls->linenumber; | 1715 | BCLine line = ls->linenumber; |
| 1727 | GCtab *t = NULL; | 1716 | GCtab *t = NULL; |
| 1728 | int vcall = 0, needarr = 0, fixt = 0; | 1717 | int vcall = 0, needarr = 0; |
| 1729 | uint32_t narr = 1; /* First array index. */ | 1718 | uint32_t narr = 1; /* First array index. */ |
| 1730 | uint32_t nhash = 0; /* Number of hash entries. */ | 1719 | uint32_t nhash = 0; /* Number of hash entries. */ |
| 1731 | BCReg freg = fs->freereg; | 1720 | BCReg freg = fs->freereg; |
| @@ -1734,15 +1723,15 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
| 1734 | bcreg_reserve(fs, 1); | 1723 | bcreg_reserve(fs, 1); |
| 1735 | freg++; | 1724 | freg++; |
| 1736 | lex_check(ls, '{'); | 1725 | lex_check(ls, '{'); |
| 1737 | while (ls->token != '}') { | 1726 | while (ls->tok != '}') { |
| 1738 | ExpDesc key, val; | 1727 | ExpDesc key, val; |
| 1739 | vcall = 0; | 1728 | vcall = 0; |
| 1740 | if (ls->token == '[') { | 1729 | if (ls->tok == '[') { |
| 1741 | expr_bracket(ls, &key); /* Already calls expr_toval. */ | 1730 | expr_bracket(ls, &key); /* Already calls expr_toval. */ |
| 1742 | if (!expr_isk(&key)) expr_index(fs, e, &key); | 1731 | if (!expr_isk(&key)) expr_index(fs, e, &key); |
| 1743 | if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++; | 1732 | if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++; |
| 1744 | lex_check(ls, '='); | 1733 | lex_check(ls, '='); |
| 1745 | } else if ((ls->token == TK_name || (!LJ_52 && ls->token == TK_goto)) && | 1734 | } else if ((ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) && |
| 1746 | lj_lex_lookahead(ls) == '=') { | 1735 | lj_lex_lookahead(ls) == '=') { |
| 1747 | expr_str(ls, &key); | 1736 | expr_str(ls, &key); |
| 1748 | lex_check(ls, '='); | 1737 | lex_check(ls, '='); |
| @@ -1764,14 +1753,15 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
| 1764 | fs->bcbase[pc].ins = BCINS_AD(BC_TDUP, freg-1, kidx); | 1753 | fs->bcbase[pc].ins = BCINS_AD(BC_TDUP, freg-1, kidx); |
| 1765 | } | 1754 | } |
| 1766 | vcall = 0; | 1755 | vcall = 0; |
| 1767 | expr_kvalue(&k, &key); | 1756 | expr_kvalue(fs, &k, &key); |
| 1768 | v = lj_tab_set(fs->L, t, &k); | 1757 | v = lj_tab_set(fs->L, t, &k); |
| 1769 | lj_gc_anybarriert(fs->L, t); | 1758 | lj_gc_anybarriert(fs->L, t); |
| 1770 | if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */ | 1759 | if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */ |
| 1771 | expr_kvalue(v, &val); | 1760 | expr_kvalue(fs, v, &val); |
| 1772 | } else { /* Otherwise create dummy string key (avoids lj_tab_newkey). */ | 1761 | /* Mark nil value with table value itself to preserve the key. */ |
| 1773 | settabV(fs->L, v, t); /* Preserve key with table itself as value. */ | 1762 | if (key.k == VKSTR && tvisnil(v)) settabV(fs->L, v, t); |
| 1774 | fixt = 1; /* Fix this later, after all resizes. */ | 1763 | } else { /* Preserve the key for the following non-const store. */ |
| 1764 | settabV(fs->L, v, t); | ||
| 1775 | goto nonconst; | 1765 | goto nonconst; |
| 1776 | } | 1766 | } |
| 1777 | } else { | 1767 | } else { |
| @@ -1787,8 +1777,9 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
| 1787 | if (vcall) { | 1777 | if (vcall) { |
| 1788 | BCInsLine *ilp = &fs->bcbase[fs->pc-1]; | 1778 | BCInsLine *ilp = &fs->bcbase[fs->pc-1]; |
| 1789 | ExpDesc en; | 1779 | ExpDesc en; |
| 1790 | lua_assert(bc_a(ilp->ins) == freg && | 1780 | lj_assertFS(bc_a(ilp->ins) == freg && |
| 1791 | bc_op(ilp->ins) == (narr > 256 ? BC_TSETV : BC_TSETB)); | 1781 | bc_op(ilp->ins) == (narr > 256 ? BC_TSETV : BC_TSETB), |
| 1782 | "bad CALL code generation"); | ||
| 1792 | expr_init(&en, VKNUM, 0); | 1783 | expr_init(&en, VKNUM, 0); |
| 1793 | en.u.nval.u32.lo = narr-1; | 1784 | en.u.nval.u32.lo = narr-1; |
| 1794 | en.u.nval.u32.hi = 0x43300000; /* Biased integer to avoid denormals. */ | 1785 | en.u.nval.u32.hi = 0x43300000; /* Biased integer to avoid denormals. */ |
| @@ -1812,17 +1803,6 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
| 1812 | } else { | 1803 | } else { |
| 1813 | if (needarr && t->asize < narr) | 1804 | if (needarr && t->asize < narr) |
| 1814 | lj_tab_reasize(fs->L, t, narr-1); | 1805 | lj_tab_reasize(fs->L, t, narr-1); |
| 1815 | if (fixt) { /* Fix value for dummy keys in template table. */ | ||
| 1816 | Node *node = noderef(t->node); | ||
| 1817 | uint32_t i, hmask = t->hmask; | ||
| 1818 | for (i = 0; i <= hmask; i++) { | ||
| 1819 | Node *n = &node[i]; | ||
| 1820 | if (tvistab(&n->val)) { | ||
| 1821 | lua_assert(tabV(&n->val) == t); | ||
| 1822 | setnilV(&n->val); /* Turn value into nil. */ | ||
| 1823 | } | ||
| 1824 | } | ||
| 1825 | } | ||
| 1826 | lj_gc_check(fs->L); | 1806 | lj_gc_check(fs->L); |
| 1827 | } | 1807 | } |
| 1828 | } | 1808 | } |
| @@ -1835,11 +1815,11 @@ static BCReg parse_params(LexState *ls, int needself) | |||
| 1835 | lex_check(ls, '('); | 1815 | lex_check(ls, '('); |
| 1836 | if (needself) | 1816 | if (needself) |
| 1837 | var_new_lit(ls, nparams++, "self"); | 1817 | var_new_lit(ls, nparams++, "self"); |
| 1838 | if (ls->token != ')') { | 1818 | if (ls->tok != ')') { |
| 1839 | do { | 1819 | do { |
| 1840 | if (ls->token == TK_name || (!LJ_52 && ls->token == TK_goto)) { | 1820 | if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) { |
| 1841 | var_new(ls, nparams++, lex_str(ls)); | 1821 | var_new(ls, nparams++, lex_str(ls)); |
| 1842 | } else if (ls->token == TK_dots) { | 1822 | } else if (ls->tok == TK_dots) { |
| 1843 | lj_lex_next(ls); | 1823 | lj_lex_next(ls); |
| 1844 | fs->flags |= PROTO_VARARG; | 1824 | fs->flags |= PROTO_VARARG; |
| 1845 | break; | 1825 | break; |
| @@ -1849,7 +1829,7 @@ static BCReg parse_params(LexState *ls, int needself) | |||
| 1849 | } while (lex_opt(ls, ',')); | 1829 | } while (lex_opt(ls, ',')); |
| 1850 | } | 1830 | } |
| 1851 | var_add(ls, nparams); | 1831 | var_add(ls, nparams); |
| 1852 | lua_assert(fs->nactvar == nparams); | 1832 | lj_assertFS(fs->nactvar == nparams, "bad regalloc"); |
| 1853 | bcreg_reserve(fs, nparams); | 1833 | bcreg_reserve(fs, nparams); |
| 1854 | lex_check(ls, ')'); | 1834 | lex_check(ls, ')'); |
| 1855 | return nparams; | 1835 | return nparams; |
| @@ -1873,7 +1853,7 @@ static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line) | |||
| 1873 | fs.bclim = pfs->bclim - pfs->pc; | 1853 | fs.bclim = pfs->bclim - pfs->pc; |
| 1874 | bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */ | 1854 | bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */ |
| 1875 | parse_chunk(ls); | 1855 | parse_chunk(ls); |
| 1876 | if (ls->token != TK_end) lex_match(ls, TK_end, TK_function, line); | 1856 | if (ls->tok != TK_end) lex_match(ls, TK_end, TK_function, line); |
| 1877 | pt = fs_finish(ls, (ls->lastline = ls->linenumber)); | 1857 | pt = fs_finish(ls, (ls->lastline = ls->linenumber)); |
| 1878 | pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ | 1858 | pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ |
| 1879 | pfs->bclim = (BCPos)(ls->sizebcstack - oldbase); | 1859 | pfs->bclim = (BCPos)(ls->sizebcstack - oldbase); |
| @@ -1912,13 +1892,13 @@ static void parse_args(LexState *ls, ExpDesc *e) | |||
| 1912 | BCIns ins; | 1892 | BCIns ins; |
| 1913 | BCReg base; | 1893 | BCReg base; |
| 1914 | BCLine line = ls->linenumber; | 1894 | BCLine line = ls->linenumber; |
| 1915 | if (ls->token == '(') { | 1895 | if (ls->tok == '(') { |
| 1916 | #if !LJ_52 | 1896 | #if !LJ_52 |
| 1917 | if (line != ls->lastline) | 1897 | if (line != ls->lastline) |
| 1918 | err_syntax(ls, LJ_ERR_XAMBIG); | 1898 | err_syntax(ls, LJ_ERR_XAMBIG); |
| 1919 | #endif | 1899 | #endif |
| 1920 | lj_lex_next(ls); | 1900 | lj_lex_next(ls); |
| 1921 | if (ls->token == ')') { /* f(). */ | 1901 | if (ls->tok == ')') { /* f(). */ |
| 1922 | args.k = VVOID; | 1902 | args.k = VVOID; |
| 1923 | } else { | 1903 | } else { |
| 1924 | expr_list(ls, &args); | 1904 | expr_list(ls, &args); |
| @@ -1926,24 +1906,24 @@ static void parse_args(LexState *ls, ExpDesc *e) | |||
| 1926 | setbc_b(bcptr(fs, &args), 0); /* Pass on multiple results. */ | 1906 | setbc_b(bcptr(fs, &args), 0); /* Pass on multiple results. */ |
| 1927 | } | 1907 | } |
| 1928 | lex_match(ls, ')', '(', line); | 1908 | lex_match(ls, ')', '(', line); |
| 1929 | } else if (ls->token == '{') { | 1909 | } else if (ls->tok == '{') { |
| 1930 | expr_table(ls, &args); | 1910 | expr_table(ls, &args); |
| 1931 | } else if (ls->token == TK_string) { | 1911 | } else if (ls->tok == TK_string) { |
| 1932 | expr_init(&args, VKSTR, 0); | 1912 | expr_init(&args, VKSTR, 0); |
| 1933 | args.u.sval = strV(&ls->tokenval); | 1913 | args.u.sval = strV(&ls->tokval); |
| 1934 | lj_lex_next(ls); | 1914 | lj_lex_next(ls); |
| 1935 | } else { | 1915 | } else { |
| 1936 | err_syntax(ls, LJ_ERR_XFUNARG); | 1916 | err_syntax(ls, LJ_ERR_XFUNARG); |
| 1937 | return; /* Silence compiler. */ | 1917 | return; /* Silence compiler. */ |
| 1938 | } | 1918 | } |
| 1939 | lua_assert(e->k == VNONRELOC); | 1919 | lj_assertFS(e->k == VNONRELOC, "bad expr type %d", e->k); |
| 1940 | base = e->u.s.info; /* Base register for call. */ | 1920 | base = e->u.s.info; /* Base register for call. */ |
| 1941 | if (args.k == VCALL) { | 1921 | if (args.k == VCALL) { |
| 1942 | ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1); | 1922 | ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1 - ls->fr2); |
| 1943 | } else { | 1923 | } else { |
| 1944 | if (args.k != VVOID) | 1924 | if (args.k != VVOID) |
| 1945 | expr_tonextreg(fs, &args); | 1925 | expr_tonextreg(fs, &args); |
| 1946 | ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base); | 1926 | ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base - ls->fr2); |
| 1947 | } | 1927 | } |
| 1948 | expr_init(e, VCALL, bcemit_INS(fs, ins)); | 1928 | expr_init(e, VCALL, bcemit_INS(fs, ins)); |
| 1949 | e->u.s.aux = base; | 1929 | e->u.s.aux = base; |
| @@ -1956,33 +1936,34 @@ static void expr_primary(LexState *ls, ExpDesc *v) | |||
| 1956 | { | 1936 | { |
| 1957 | FuncState *fs = ls->fs; | 1937 | FuncState *fs = ls->fs; |
| 1958 | /* Parse prefix expression. */ | 1938 | /* Parse prefix expression. */ |
| 1959 | if (ls->token == '(') { | 1939 | if (ls->tok == '(') { |
| 1960 | BCLine line = ls->linenumber; | 1940 | BCLine line = ls->linenumber; |
| 1961 | lj_lex_next(ls); | 1941 | lj_lex_next(ls); |
| 1962 | expr(ls, v); | 1942 | expr(ls, v); |
| 1963 | lex_match(ls, ')', '(', line); | 1943 | lex_match(ls, ')', '(', line); |
| 1964 | expr_discharge(ls->fs, v); | 1944 | expr_discharge(ls->fs, v); |
| 1965 | } else if (ls->token == TK_name || (!LJ_52 && ls->token == TK_goto)) { | 1945 | } else if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) { |
| 1966 | var_lookup(ls, v); | 1946 | var_lookup(ls, v); |
| 1967 | } else { | 1947 | } else { |
| 1968 | err_syntax(ls, LJ_ERR_XSYMBOL); | 1948 | err_syntax(ls, LJ_ERR_XSYMBOL); |
| 1969 | } | 1949 | } |
| 1970 | for (;;) { /* Parse multiple expression suffixes. */ | 1950 | for (;;) { /* Parse multiple expression suffixes. */ |
| 1971 | if (ls->token == '.') { | 1951 | if (ls->tok == '.') { |
| 1972 | expr_field(ls, v); | 1952 | expr_field(ls, v); |
| 1973 | } else if (ls->token == '[') { | 1953 | } else if (ls->tok == '[') { |
| 1974 | ExpDesc key; | 1954 | ExpDesc key; |
| 1975 | expr_toanyreg(fs, v); | 1955 | expr_toanyreg(fs, v); |
| 1976 | expr_bracket(ls, &key); | 1956 | expr_bracket(ls, &key); |
| 1977 | expr_index(fs, v, &key); | 1957 | expr_index(fs, v, &key); |
| 1978 | } else if (ls->token == ':') { | 1958 | } else if (ls->tok == ':') { |
| 1979 | ExpDesc key; | 1959 | ExpDesc key; |
| 1980 | lj_lex_next(ls); | 1960 | lj_lex_next(ls); |
| 1981 | expr_str(ls, &key); | 1961 | expr_str(ls, &key); |
| 1982 | bcemit_method(fs, v, &key); | 1962 | bcemit_method(fs, v, &key); |
| 1983 | parse_args(ls, v); | 1963 | parse_args(ls, v); |
| 1984 | } else if (ls->token == '(' || ls->token == TK_string || ls->token == '{') { | 1964 | } else if (ls->tok == '(' || ls->tok == TK_string || ls->tok == '{') { |
| 1985 | expr_tonextreg(fs, v); | 1965 | expr_tonextreg(fs, v); |
| 1966 | if (ls->fr2) bcreg_reserve(fs, 1); | ||
| 1986 | parse_args(ls, v); | 1967 | parse_args(ls, v); |
| 1987 | } else { | 1968 | } else { |
| 1988 | break; | 1969 | break; |
| @@ -1993,14 +1974,14 @@ static void expr_primary(LexState *ls, ExpDesc *v) | |||
| 1993 | /* Parse simple expression. */ | 1974 | /* Parse simple expression. */ |
| 1994 | static void expr_simple(LexState *ls, ExpDesc *v) | 1975 | static void expr_simple(LexState *ls, ExpDesc *v) |
| 1995 | { | 1976 | { |
| 1996 | switch (ls->token) { | 1977 | switch (ls->tok) { |
| 1997 | case TK_number: | 1978 | case TK_number: |
| 1998 | expr_init(v, (LJ_HASFFI && tviscdata(&ls->tokenval)) ? VKCDATA : VKNUM, 0); | 1979 | expr_init(v, (LJ_HASFFI && tviscdata(&ls->tokval)) ? VKCDATA : VKNUM, 0); |
| 1999 | copyTV(ls->L, &v->u.nval, &ls->tokenval); | 1980 | copyTV(ls->L, &v->u.nval, &ls->tokval); |
| 2000 | break; | 1981 | break; |
| 2001 | case TK_string: | 1982 | case TK_string: |
| 2002 | expr_init(v, VKSTR, 0); | 1983 | expr_init(v, VKSTR, 0); |
| 2003 | v->u.sval = strV(&ls->tokenval); | 1984 | v->u.sval = strV(&ls->tokval); |
| 2004 | break; | 1985 | break; |
| 2005 | case TK_nil: | 1986 | case TK_nil: |
| 2006 | expr_init(v, VKNIL, 0); | 1987 | expr_init(v, VKNIL, 0); |
| @@ -2088,11 +2069,11 @@ static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit); | |||
| 2088 | static void expr_unop(LexState *ls, ExpDesc *v) | 2069 | static void expr_unop(LexState *ls, ExpDesc *v) |
| 2089 | { | 2070 | { |
| 2090 | BCOp op; | 2071 | BCOp op; |
| 2091 | if (ls->token == TK_not) { | 2072 | if (ls->tok == TK_not) { |
| 2092 | op = BC_NOT; | 2073 | op = BC_NOT; |
| 2093 | } else if (ls->token == '-') { | 2074 | } else if (ls->tok == '-') { |
| 2094 | op = BC_UNM; | 2075 | op = BC_UNM; |
| 2095 | } else if (ls->token == '#') { | 2076 | } else if (ls->tok == '#') { |
| 2096 | op = BC_LEN; | 2077 | op = BC_LEN; |
| 2097 | } else { | 2078 | } else { |
| 2098 | expr_simple(ls, v); | 2079 | expr_simple(ls, v); |
| @@ -2109,7 +2090,7 @@ static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit) | |||
| 2109 | BinOpr op; | 2090 | BinOpr op; |
| 2110 | synlevel_begin(ls); | 2091 | synlevel_begin(ls); |
| 2111 | expr_unop(ls, v); | 2092 | expr_unop(ls, v); |
| 2112 | op = token2binop(ls->token); | 2093 | op = token2binop(ls->tok); |
| 2113 | while (op != OPR_NOBINOPR && priority[op].left > limit) { | 2094 | while (op != OPR_NOBINOPR && priority[op].left > limit) { |
| 2114 | ExpDesc v2; | 2095 | ExpDesc v2; |
| 2115 | BinOpr nextop; | 2096 | BinOpr nextop; |
| @@ -2298,9 +2279,9 @@ static void parse_func(LexState *ls, BCLine line) | |||
| 2298 | lj_lex_next(ls); /* Skip 'function'. */ | 2279 | lj_lex_next(ls); /* Skip 'function'. */ |
| 2299 | /* Parse function name. */ | 2280 | /* Parse function name. */ |
| 2300 | var_lookup(ls, &v); | 2281 | var_lookup(ls, &v); |
| 2301 | while (ls->token == '.') /* Multiple dot-separated fields. */ | 2282 | while (ls->tok == '.') /* Multiple dot-separated fields. */ |
| 2302 | expr_field(ls, &v); | 2283 | expr_field(ls, &v); |
| 2303 | if (ls->token == ':') { /* Optional colon to signify method call. */ | 2284 | if (ls->tok == ':') { /* Optional colon to signify method call. */ |
| 2304 | needself = 1; | 2285 | needself = 1; |
| 2305 | expr_field(ls, &v); | 2286 | expr_field(ls, &v); |
| 2306 | } | 2287 | } |
| @@ -2313,9 +2294,9 @@ static void parse_func(LexState *ls, BCLine line) | |||
| 2313 | /* -- Control transfer statements ----------------------------------------- */ | 2294 | /* -- Control transfer statements ----------------------------------------- */ |
| 2314 | 2295 | ||
| 2315 | /* Check for end of block. */ | 2296 | /* Check for end of block. */ |
| 2316 | static int endofblock(LexToken token) | 2297 | static int parse_isend(LexToken tok) |
| 2317 | { | 2298 | { |
| 2318 | switch (token) { | 2299 | switch (tok) { |
| 2319 | case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof: | 2300 | case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof: |
| 2320 | return 1; | 2301 | return 1; |
| 2321 | default: | 2302 | default: |
| @@ -2330,18 +2311,22 @@ static void parse_return(LexState *ls) | |||
| 2330 | FuncState *fs = ls->fs; | 2311 | FuncState *fs = ls->fs; |
| 2331 | lj_lex_next(ls); /* Skip 'return'. */ | 2312 | lj_lex_next(ls); /* Skip 'return'. */ |
| 2332 | fs->flags |= PROTO_HAS_RETURN; | 2313 | fs->flags |= PROTO_HAS_RETURN; |
| 2333 | if (endofblock(ls->token) || ls->token == ';') { /* Bare return. */ | 2314 | if (parse_isend(ls->tok) || ls->tok == ';') { /* Bare return. */ |
| 2334 | ins = BCINS_AD(BC_RET0, 0, 1); | 2315 | ins = BCINS_AD(BC_RET0, 0, 1); |
| 2335 | } else { /* Return with one or more values. */ | 2316 | } else { /* Return with one or more values. */ |
| 2336 | ExpDesc e; /* Receives the _last_ expression in the list. */ | 2317 | ExpDesc e; /* Receives the _last_ expression in the list. */ |
| 2337 | BCReg nret = expr_list(ls, &e); | 2318 | BCReg nret = expr_list(ls, &e); |
| 2338 | if (nret == 1) { /* Return one result. */ | 2319 | if (nret == 1) { /* Return one result. */ |
| 2339 | if (e.k == VCALL) { /* Check for tail call. */ | 2320 | if (e.k == VCALL) { /* Check for tail call. */ |
| 2321 | #ifdef LUAJIT_DISABLE_TAILCALL | ||
| 2322 | goto notailcall; | ||
| 2323 | #else | ||
| 2340 | BCIns *ip = bcptr(fs, &e); | 2324 | BCIns *ip = bcptr(fs, &e); |
| 2341 | /* It doesn't pay off to add BC_VARGT just for 'return ...'. */ | 2325 | /* It doesn't pay off to add BC_VARGT just for 'return ...'. */ |
| 2342 | if (bc_op(*ip) == BC_VARG) goto notailcall; | 2326 | if (bc_op(*ip) == BC_VARG) goto notailcall; |
| 2343 | fs->pc--; | 2327 | fs->pc--; |
| 2344 | ins = BCINS_AD(bc_op(*ip)-BC_CALL+BC_CALLT, bc_a(*ip), bc_c(*ip)); | 2328 | ins = BCINS_AD(bc_op(*ip)-BC_CALL+BC_CALLT, bc_a(*ip), bc_c(*ip)); |
| 2329 | #endif | ||
| 2345 | } else { /* Can return the result from any register. */ | 2330 | } else { /* Can return the result from any register. */ |
| 2346 | ins = BCINS_AD(BC_RET1, expr_toanyreg(fs, &e), 2); | 2331 | ins = BCINS_AD(BC_RET1, expr_toanyreg(fs, &e), 2); |
| 2347 | } | 2332 | } |
| @@ -2396,18 +2381,18 @@ static void parse_label(LexState *ls) | |||
| 2396 | lex_check(ls, TK_label); | 2381 | lex_check(ls, TK_label); |
| 2397 | /* Recursively parse trailing statements: labels and ';' (Lua 5.2 only). */ | 2382 | /* Recursively parse trailing statements: labels and ';' (Lua 5.2 only). */ |
| 2398 | for (;;) { | 2383 | for (;;) { |
| 2399 | if (ls->token == TK_label) { | 2384 | if (ls->tok == TK_label) { |
| 2400 | synlevel_begin(ls); | 2385 | synlevel_begin(ls); |
| 2401 | parse_label(ls); | 2386 | parse_label(ls); |
| 2402 | synlevel_end(ls); | 2387 | synlevel_end(ls); |
| 2403 | } else if (LJ_52 && ls->token == ';') { | 2388 | } else if (LJ_52 && ls->tok == ';') { |
| 2404 | lj_lex_next(ls); | 2389 | lj_lex_next(ls); |
| 2405 | } else { | 2390 | } else { |
| 2406 | break; | 2391 | break; |
| 2407 | } | 2392 | } |
| 2408 | } | 2393 | } |
| 2409 | /* Trailing label is considered to be outside of scope. */ | 2394 | /* Trailing label is considered to be outside of scope. */ |
| 2410 | if (endofblock(ls->token) && ls->token != TK_until) | 2395 | if (parse_isend(ls->tok) && ls->tok != TK_until) |
| 2411 | ls->vstack[idx].slot = fs->bl->nactvar; | 2396 | ls->vstack[idx].slot = fs->bl->nactvar; |
| 2412 | gola_resolve(ls, fs->bl, idx); | 2397 | gola_resolve(ls, fs->bl, idx); |
| 2413 | } | 2398 | } |
| @@ -2564,7 +2549,8 @@ static void parse_for_iter(LexState *ls, GCstr *indexname) | |||
| 2564 | lex_check(ls, TK_in); | 2549 | lex_check(ls, TK_in); |
| 2565 | line = ls->linenumber; | 2550 | line = ls->linenumber; |
| 2566 | assign_adjust(ls, 3, expr_list(ls, &e), &e); | 2551 | assign_adjust(ls, 3, expr_list(ls, &e), &e); |
| 2567 | bcreg_bump(fs, 3); /* The iterator needs another 3 slots (func + 2 args). */ | 2552 | /* The iterator needs another 3 [4] slots (func [pc] | state ctl). */ |
| 2553 | bcreg_bump(fs, 3+ls->fr2); | ||
| 2568 | isnext = (nvars <= 5 && fs->pc > exprpc && predict_next(ls, fs, exprpc)); | 2554 | isnext = (nvars <= 5 && fs->pc > exprpc && predict_next(ls, fs, exprpc)); |
| 2569 | var_add(ls, 3); /* Hidden control variables. */ | 2555 | var_add(ls, 3); /* Hidden control variables. */ |
| 2570 | lex_check(ls, TK_do); | 2556 | lex_check(ls, TK_do); |
| @@ -2592,9 +2578,9 @@ static void parse_for(LexState *ls, BCLine line) | |||
| 2592 | fscope_begin(fs, &bl, FSCOPE_LOOP); | 2578 | fscope_begin(fs, &bl, FSCOPE_LOOP); |
| 2593 | lj_lex_next(ls); /* Skip 'for'. */ | 2579 | lj_lex_next(ls); /* Skip 'for'. */ |
| 2594 | varname = lex_str(ls); /* Get first variable name. */ | 2580 | varname = lex_str(ls); /* Get first variable name. */ |
| 2595 | if (ls->token == '=') | 2581 | if (ls->tok == '=') |
| 2596 | parse_for_num(ls, varname, line); | 2582 | parse_for_num(ls, varname, line); |
| 2597 | else if (ls->token == ',' || ls->token == TK_in) | 2583 | else if (ls->tok == ',' || ls->tok == TK_in) |
| 2598 | parse_for_iter(ls, varname); | 2584 | parse_for_iter(ls, varname); |
| 2599 | else | 2585 | else |
| 2600 | err_syntax(ls, LJ_ERR_XFOR); | 2586 | err_syntax(ls, LJ_ERR_XFOR); |
| @@ -2620,12 +2606,12 @@ static void parse_if(LexState *ls, BCLine line) | |||
| 2620 | BCPos flist; | 2606 | BCPos flist; |
| 2621 | BCPos escapelist = NO_JMP; | 2607 | BCPos escapelist = NO_JMP; |
| 2622 | flist = parse_then(ls); | 2608 | flist = parse_then(ls); |
| 2623 | while (ls->token == TK_elseif) { /* Parse multiple 'elseif' blocks. */ | 2609 | while (ls->tok == TK_elseif) { /* Parse multiple 'elseif' blocks. */ |
| 2624 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); | 2610 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); |
| 2625 | jmp_tohere(fs, flist); | 2611 | jmp_tohere(fs, flist); |
| 2626 | flist = parse_then(ls); | 2612 | flist = parse_then(ls); |
| 2627 | } | 2613 | } |
| 2628 | if (ls->token == TK_else) { /* Parse optional 'else' block. */ | 2614 | if (ls->tok == TK_else) { /* Parse optional 'else' block. */ |
| 2629 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); | 2615 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); |
| 2630 | jmp_tohere(fs, flist); | 2616 | jmp_tohere(fs, flist); |
| 2631 | lj_lex_next(ls); /* Skip 'else'. */ | 2617 | lj_lex_next(ls); /* Skip 'else'. */ |
| @@ -2643,7 +2629,7 @@ static void parse_if(LexState *ls, BCLine line) | |||
| 2643 | static int parse_stmt(LexState *ls) | 2629 | static int parse_stmt(LexState *ls) |
| 2644 | { | 2630 | { |
| 2645 | BCLine line = ls->linenumber; | 2631 | BCLine line = ls->linenumber; |
| 2646 | switch (ls->token) { | 2632 | switch (ls->tok) { |
| 2647 | case TK_if: | 2633 | case TK_if: |
| 2648 | parse_if(ls, line); | 2634 | parse_if(ls, line); |
| 2649 | break; | 2635 | break; |
| @@ -2702,11 +2688,12 @@ static void parse_chunk(LexState *ls) | |||
| 2702 | { | 2688 | { |
| 2703 | int islast = 0; | 2689 | int islast = 0; |
| 2704 | synlevel_begin(ls); | 2690 | synlevel_begin(ls); |
| 2705 | while (!islast && !endofblock(ls->token)) { | 2691 | while (!islast && !parse_isend(ls->tok)) { |
| 2706 | islast = parse_stmt(ls); | 2692 | islast = parse_stmt(ls); |
| 2707 | lex_opt(ls, ';'); | 2693 | lex_opt(ls, ';'); |
| 2708 | lua_assert(ls->fs->framesize >= ls->fs->freereg && | 2694 | lj_assertLS(ls->fs->framesize >= ls->fs->freereg && |
| 2709 | ls->fs->freereg >= ls->fs->nactvar); | 2695 | ls->fs->freereg >= ls->fs->nactvar, |
| 2696 | "bad regalloc"); | ||
| 2710 | ls->fs->freereg = ls->fs->nactvar; /* Free registers after each stmt. */ | 2697 | ls->fs->freereg = ls->fs->nactvar; /* Free registers after each stmt. */ |
| 2711 | } | 2698 | } |
| 2712 | synlevel_end(ls); | 2699 | synlevel_end(ls); |
| @@ -2737,13 +2724,12 @@ GCproto *lj_parse(LexState *ls) | |||
| 2737 | bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */ | 2724 | bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */ |
| 2738 | lj_lex_next(ls); /* Read-ahead first token. */ | 2725 | lj_lex_next(ls); /* Read-ahead first token. */ |
| 2739 | parse_chunk(ls); | 2726 | parse_chunk(ls); |
| 2740 | if (ls->token != TK_eof) | 2727 | if (ls->tok != TK_eof) |
| 2741 | err_token(ls, TK_eof); | 2728 | err_token(ls, TK_eof); |
| 2742 | pt = fs_finish(ls, ls->linenumber); | 2729 | pt = fs_finish(ls, ls->linenumber); |
| 2743 | L->top--; /* Drop chunkname. */ | 2730 | L->top--; /* Drop chunkname. */ |
| 2744 | lua_assert(fs.prev == NULL); | 2731 | lj_assertL(fs.prev == NULL && ls->fs == NULL, "mismatched frame nesting"); |
| 2745 | lua_assert(ls->fs == NULL); | 2732 | lj_assertL(pt->sizeuv == 0, "toplevel proto has upvalues"); |
| 2746 | lua_assert(pt->sizeuv == 0); | ||
| 2747 | return pt; | 2733 | return pt; |
| 2748 | } | 2734 | } |
| 2749 | 2735 | ||
