diff options
Diffstat (limited to 'src/lj_parse.c')
-rw-r--r-- | src/lj_parse.c | 301 |
1 files changed, 144 insertions, 157 deletions
diff --git a/src/lj_parse.c b/src/lj_parse.c index 58353bab..78df8b5d 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 | ||
@@ -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 | } |
@@ -660,16 +670,16 @@ static void bcemit_method(FuncState *fs, ExpDesc *e, ExpDesc *key) | |||
660 | BCReg idx, func, obj = expr_toanyreg(fs, e); | 670 | BCReg idx, func, 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 | bcemit_AD(fs, BC_MOV, func+1+LJ_FR2, obj); /* Copy object to 1st argument. */ |
664 | lua_assert(expr_isstrk(key)); | 674 | lj_assertFS(expr_isstrk(key), "bad usage"); |
665 | idx = const_str(fs, key); | 675 | idx = const_str(fs, key); |
666 | if (idx <= BCMAX_C) { | 676 | if (idx <= BCMAX_C) { |
667 | bcreg_reserve(fs, 2); | 677 | bcreg_reserve(fs, 2+LJ_FR2); |
668 | bcemit_ABC(fs, BC_TGETS, func, obj, idx); | 678 | bcemit_ABC(fs, BC_TGETS, func, obj, idx); |
669 | } else { | 679 | } else { |
670 | bcreg_reserve(fs, 3); | 680 | bcreg_reserve(fs, 3+LJ_FR2); |
671 | bcemit_AD(fs, BC_KSTR, func+2, idx); | 681 | bcemit_AD(fs, BC_KSTR, func+2+LJ_FR2, idx); |
672 | bcemit_ABC(fs, BC_TGETV, func, obj, func+2); | 682 | bcemit_ABC(fs, BC_TGETV, func, obj, func+2+LJ_FR2); |
673 | fs->freereg--; | 683 | fs->freereg--; |
674 | } | 684 | } |
675 | e->u.s.info = func; | 685 | e->u.s.info = func; |
@@ -801,7 +811,8 @@ static void bcemit_arith(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2) | |||
801 | else | 811 | else |
802 | rc = expr_toanyreg(fs, e2); | 812 | rc = expr_toanyreg(fs, e2); |
803 | /* 1st operand discharged by bcemit_binop_left, but need KNUM/KSHORT. */ | 813 | /* 1st operand discharged by bcemit_binop_left, but need KNUM/KSHORT. */ |
804 | lua_assert(expr_isnumk(e1) || e1->k == VNONRELOC); | 814 | lj_assertFS(expr_isnumk(e1) || e1->k == VNONRELOC, |
815 | "bad expr type %d", e1->k); | ||
805 | expr_toval(fs, e1); | 816 | expr_toval(fs, e1); |
806 | /* Avoid two consts to satisfy bytecode constraints. */ | 817 | /* Avoid two consts to satisfy bytecode constraints. */ |
807 | if (expr_isnumk(e1) && !expr_isnumk(e2) && | 818 | if (expr_isnumk(e1) && !expr_isnumk(e2) && |
@@ -889,19 +900,20 @@ static void bcemit_binop(FuncState *fs, BinOpr op, ExpDesc *e1, ExpDesc *e2) | |||
889 | if (op <= OPR_POW) { | 900 | if (op <= OPR_POW) { |
890 | bcemit_arith(fs, op, e1, e2); | 901 | bcemit_arith(fs, op, e1, e2); |
891 | } else if (op == OPR_AND) { | 902 | } else if (op == OPR_AND) { |
892 | lua_assert(e1->t == NO_JMP); /* List must be closed. */ | 903 | lj_assertFS(e1->t == NO_JMP, "jump list not closed"); |
893 | expr_discharge(fs, e2); | 904 | expr_discharge(fs, e2); |
894 | jmp_append(fs, &e2->f, e1->f); | 905 | jmp_append(fs, &e2->f, e1->f); |
895 | *e1 = *e2; | 906 | *e1 = *e2; |
896 | } else if (op == OPR_OR) { | 907 | } else if (op == OPR_OR) { |
897 | lua_assert(e1->f == NO_JMP); /* List must be closed. */ | 908 | lj_assertFS(e1->f == NO_JMP, "jump list not closed"); |
898 | expr_discharge(fs, e2); | 909 | expr_discharge(fs, e2); |
899 | jmp_append(fs, &e2->t, e1->t); | 910 | jmp_append(fs, &e2->t, e1->t); |
900 | *e1 = *e2; | 911 | *e1 = *e2; |
901 | } else if (op == OPR_CONCAT) { | 912 | } else if (op == OPR_CONCAT) { |
902 | expr_toval(fs, e2); | 913 | expr_toval(fs, e2); |
903 | if (e2->k == VRELOCABLE && bc_op(*bcptr(fs, e2)) == BC_CAT) { | 914 | if (e2->k == VRELOCABLE && bc_op(*bcptr(fs, e2)) == BC_CAT) { |
904 | lua_assert(e1->u.s.info == bc_b(*bcptr(fs, e2))-1); | 915 | lj_assertFS(e1->u.s.info == bc_b(*bcptr(fs, e2))-1, |
916 | "bad CAT stack layout"); | ||
905 | expr_free(fs, e1); | 917 | expr_free(fs, e1); |
906 | setbc_b(bcptr(fs, e2), e1->u.s.info); | 918 | setbc_b(bcptr(fs, e2), e1->u.s.info); |
907 | e1->u.s.info = e2->u.s.info; | 919 | e1->u.s.info = e2->u.s.info; |
@@ -913,8 +925,9 @@ static void bcemit_binop(FuncState *fs, BinOpr op, ExpDesc *e1, ExpDesc *e2) | |||
913 | } | 925 | } |
914 | e1->k = VRELOCABLE; | 926 | e1->k = VRELOCABLE; |
915 | } else { | 927 | } else { |
916 | lua_assert(op == OPR_NE || op == OPR_EQ || | 928 | lj_assertFS(op == OPR_NE || op == OPR_EQ || |
917 | op == OPR_LT || op == OPR_GE || op == OPR_LE || op == OPR_GT); | 929 | op == OPR_LT || op == OPR_GE || op == OPR_LE || op == OPR_GT, |
930 | "bad binop %d", op); | ||
918 | bcemit_comp(fs, op, e1, e2); | 931 | bcemit_comp(fs, op, e1, e2); |
919 | } | 932 | } |
920 | } | 933 | } |
@@ -943,10 +956,10 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e) | |||
943 | e->u.s.info = fs->freereg-1; | 956 | e->u.s.info = fs->freereg-1; |
944 | e->k = VNONRELOC; | 957 | e->k = VNONRELOC; |
945 | } else { | 958 | } else { |
946 | lua_assert(e->k == VNONRELOC); | 959 | lj_assertFS(e->k == VNONRELOC, "bad expr type %d", e->k); |
947 | } | 960 | } |
948 | } else { | 961 | } else { |
949 | lua_assert(op == BC_UNM || op == BC_LEN); | 962 | lj_assertFS(op == BC_UNM || op == BC_LEN, "bad unop %d", op); |
950 | if (op == BC_UNM && !expr_hasjump(e)) { /* Constant-fold negations. */ | 963 | if (op == BC_UNM && !expr_hasjump(e)) { /* Constant-fold negations. */ |
951 | #if LJ_HASFFI | 964 | #if LJ_HASFFI |
952 | if (e->k == VKCDATA) { /* Fold in-place since cdata is not interned. */ | 965 | if (e->k == VKCDATA) { /* Fold in-place since cdata is not interned. */ |
@@ -986,7 +999,7 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e) | |||
986 | /* Check and consume optional token. */ | 999 | /* Check and consume optional token. */ |
987 | static int lex_opt(LexState *ls, LexToken tok) | 1000 | static int lex_opt(LexState *ls, LexToken tok) |
988 | { | 1001 | { |
989 | if (ls->token == tok) { | 1002 | if (ls->tok == tok) { |
990 | lj_lex_next(ls); | 1003 | lj_lex_next(ls); |
991 | return 1; | 1004 | return 1; |
992 | } | 1005 | } |
@@ -996,7 +1009,7 @@ static int lex_opt(LexState *ls, LexToken tok) | |||
996 | /* Check and consume token. */ | 1009 | /* Check and consume token. */ |
997 | static void lex_check(LexState *ls, LexToken tok) | 1010 | static void lex_check(LexState *ls, LexToken tok) |
998 | { | 1011 | { |
999 | if (ls->token != tok) | 1012 | if (ls->tok != tok) |
1000 | err_token(ls, tok); | 1013 | err_token(ls, tok); |
1001 | lj_lex_next(ls); | 1014 | lj_lex_next(ls); |
1002 | } | 1015 | } |
@@ -1010,7 +1023,7 @@ static void lex_match(LexState *ls, LexToken what, LexToken who, BCLine line) | |||
1010 | } else { | 1023 | } else { |
1011 | const char *swhat = lj_lex_token2str(ls, what); | 1024 | const char *swhat = lj_lex_token2str(ls, what); |
1012 | const char *swho = lj_lex_token2str(ls, who); | 1025 | const char *swho = lj_lex_token2str(ls, who); |
1013 | lj_lex_error(ls, ls->token, LJ_ERR_XMATCH, swhat, swho, line); | 1026 | lj_lex_error(ls, ls->tok, LJ_ERR_XMATCH, swhat, swho, line); |
1014 | } | 1027 | } |
1015 | } | 1028 | } |
1016 | } | 1029 | } |
@@ -1019,9 +1032,9 @@ static void lex_match(LexState *ls, LexToken what, LexToken who, BCLine line) | |||
1019 | static GCstr *lex_str(LexState *ls) | 1032 | static GCstr *lex_str(LexState *ls) |
1020 | { | 1033 | { |
1021 | GCstr *s; | 1034 | GCstr *s; |
1022 | if (ls->token != TK_name && (LJ_52 || ls->token != TK_goto)) | 1035 | if (ls->tok != TK_name && (LJ_52 || ls->tok != TK_goto)) |
1023 | err_token(ls, TK_name); | 1036 | err_token(ls, TK_name); |
1024 | s = strV(&ls->tokenval); | 1037 | s = strV(&ls->tokval); |
1025 | lj_lex_next(ls); | 1038 | lj_lex_next(ls); |
1026 | return s; | 1039 | return s; |
1027 | } | 1040 | } |
@@ -1041,8 +1054,9 @@ static void var_new(LexState *ls, BCReg n, GCstr *name) | |||
1041 | lj_lex_error(ls, 0, LJ_ERR_XLIMC, LJ_MAX_VSTACK); | 1054 | 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); | 1055 | lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo); |
1043 | } | 1056 | } |
1044 | lua_assert((uintptr_t)name < VARNAME__MAX || | 1057 | lj_assertFS((uintptr_t)name < VARNAME__MAX || |
1045 | lj_tab_getstr(fs->kt, name) != NULL); | 1058 | lj_tab_getstr(fs->kt, name) != NULL, |
1059 | "unanchored variable name"); | ||
1046 | /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */ | 1060 | /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */ |
1047 | setgcref(ls->vstack[vtop].name, obj2gco(name)); | 1061 | setgcref(ls->vstack[vtop].name, obj2gco(name)); |
1048 | fs->varmap[fs->nactvar+n] = (uint16_t)vtop; | 1062 | fs->varmap[fs->nactvar+n] = (uint16_t)vtop; |
@@ -1097,7 +1111,7 @@ static MSize var_lookup_uv(FuncState *fs, MSize vidx, ExpDesc *e) | |||
1097 | return i; /* Already exists. */ | 1111 | return i; /* Already exists. */ |
1098 | /* Otherwise create a new one. */ | 1112 | /* Otherwise create a new one. */ |
1099 | checklimit(fs, fs->nuv, LJ_MAX_UPVAL, "upvalues"); | 1113 | checklimit(fs, fs->nuv, LJ_MAX_UPVAL, "upvalues"); |
1100 | lua_assert(e->k == VLOCAL || e->k == VUPVAL); | 1114 | lj_assertFS(e->k == VLOCAL || e->k == VUPVAL, "bad expr type %d", e->k); |
1101 | fs->uvmap[n] = (uint16_t)vidx; | 1115 | fs->uvmap[n] = (uint16_t)vidx; |
1102 | fs->uvtmp[n] = (uint16_t)(e->k == VLOCAL ? vidx : LJ_MAX_VSTACK+e->u.s.info); | 1116 | fs->uvtmp[n] = (uint16_t)(e->k == VLOCAL ? vidx : LJ_MAX_VSTACK+e->u.s.info); |
1103 | fs->nuv = n+1; | 1117 | fs->nuv = n+1; |
@@ -1148,7 +1162,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); | 1162 | 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); | 1163 | lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo); |
1150 | } | 1164 | } |
1151 | lua_assert(name == NAME_BREAK || lj_tab_getstr(fs->kt, name) != NULL); | 1165 | lj_assertFS(name == NAME_BREAK || lj_tab_getstr(fs->kt, name) != NULL, |
1166 | "unanchored label name"); | ||
1152 | /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */ | 1167 | /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */ |
1153 | setgcref(ls->vstack[vtop].name, obj2gco(name)); | 1168 | setgcref(ls->vstack[vtop].name, obj2gco(name)); |
1154 | ls->vstack[vtop].startpc = pc; | 1169 | ls->vstack[vtop].startpc = pc; |
@@ -1178,8 +1193,9 @@ static void gola_close(LexState *ls, VarInfo *vg) | |||
1178 | FuncState *fs = ls->fs; | 1193 | FuncState *fs = ls->fs; |
1179 | BCPos pc = vg->startpc; | 1194 | BCPos pc = vg->startpc; |
1180 | BCIns *ip = &fs->bcbase[pc].ins; | 1195 | BCIns *ip = &fs->bcbase[pc].ins; |
1181 | lua_assert(gola_isgoto(vg)); | 1196 | lj_assertFS(gola_isgoto(vg), "expected goto"); |
1182 | lua_assert(bc_op(*ip) == BC_JMP || bc_op(*ip) == BC_UCLO); | 1197 | lj_assertFS(bc_op(*ip) == BC_JMP || bc_op(*ip) == BC_UCLO, |
1198 | "bad bytecode op %d", bc_op(*ip)); | ||
1183 | setbc_a(ip, vg->slot); | 1199 | setbc_a(ip, vg->slot); |
1184 | if (bc_op(*ip) == BC_JMP) { | 1200 | if (bc_op(*ip) == BC_JMP) { |
1185 | BCPos next = jmp_next(fs, pc); | 1201 | BCPos next = jmp_next(fs, pc); |
@@ -1198,9 +1214,9 @@ static void gola_resolve(LexState *ls, FuncScope *bl, MSize idx) | |||
1198 | if (gcrefeq(vg->name, vl->name) && gola_isgoto(vg)) { | 1214 | if (gcrefeq(vg->name, vl->name) && gola_isgoto(vg)) { |
1199 | if (vg->slot < vl->slot) { | 1215 | if (vg->slot < vl->slot) { |
1200 | GCstr *name = strref(var_get(ls, ls->fs, vg->slot).name); | 1216 | GCstr *name = strref(var_get(ls, ls->fs, vg->slot).name); |
1201 | lua_assert((uintptr_t)name >= VARNAME__MAX); | 1217 | lj_assertLS((uintptr_t)name >= VARNAME__MAX, "expected goto name"); |
1202 | ls->linenumber = ls->fs->bcbase[vg->startpc].line; | 1218 | ls->linenumber = ls->fs->bcbase[vg->startpc].line; |
1203 | lua_assert(strref(vg->name) != NAME_BREAK); | 1219 | lj_assertLS(strref(vg->name) != NAME_BREAK, "unexpected break"); |
1204 | lj_lex_error(ls, 0, LJ_ERR_XGSCOPE, | 1220 | lj_lex_error(ls, 0, LJ_ERR_XGSCOPE, |
1205 | strdata(strref(vg->name)), strdata(name)); | 1221 | strdata(strref(vg->name)), strdata(name)); |
1206 | } | 1222 | } |
@@ -1264,7 +1280,7 @@ static void fscope_begin(FuncState *fs, FuncScope *bl, int flags) | |||
1264 | bl->vstart = fs->ls->vtop; | 1280 | bl->vstart = fs->ls->vtop; |
1265 | bl->prev = fs->bl; | 1281 | bl->prev = fs->bl; |
1266 | fs->bl = bl; | 1282 | fs->bl = bl; |
1267 | lua_assert(fs->freereg == fs->nactvar); | 1283 | lj_assertFS(fs->freereg == fs->nactvar, "bad regalloc"); |
1268 | } | 1284 | } |
1269 | 1285 | ||
1270 | /* End a scope. */ | 1286 | /* End a scope. */ |
@@ -1275,7 +1291,7 @@ static void fscope_end(FuncState *fs) | |||
1275 | fs->bl = bl->prev; | 1291 | fs->bl = bl->prev; |
1276 | var_remove(ls, bl->nactvar); | 1292 | var_remove(ls, bl->nactvar); |
1277 | fs->freereg = fs->nactvar; | 1293 | fs->freereg = fs->nactvar; |
1278 | lua_assert(bl->nactvar == fs->nactvar); | 1294 | lj_assertFS(bl->nactvar == fs->nactvar, "bad regalloc"); |
1279 | if ((bl->flags & (FSCOPE_UPVAL|FSCOPE_NOCLOSE)) == FSCOPE_UPVAL) | 1295 | if ((bl->flags & (FSCOPE_UPVAL|FSCOPE_NOCLOSE)) == FSCOPE_UPVAL) |
1280 | bcemit_AJ(fs, BC_UCLO, bl->nactvar, 0); | 1296 | bcemit_AJ(fs, BC_UCLO, bl->nactvar, 0); |
1281 | if ((bl->flags & FSCOPE_BREAK)) { | 1297 | if ((bl->flags & FSCOPE_BREAK)) { |
@@ -1362,13 +1378,13 @@ static void fs_fixup_k(FuncState *fs, GCproto *pt, void *kptr) | |||
1362 | Node *n = &node[i]; | 1378 | Node *n = &node[i]; |
1363 | if (tvhaskslot(&n->val)) { | 1379 | if (tvhaskslot(&n->val)) { |
1364 | ptrdiff_t kidx = (ptrdiff_t)tvkslot(&n->val); | 1380 | ptrdiff_t kidx = (ptrdiff_t)tvkslot(&n->val); |
1365 | lua_assert(!tvisint(&n->key)); | 1381 | lj_assertFS(!tvisint(&n->key), "unexpected integer key"); |
1366 | if (tvisnum(&n->key)) { | 1382 | if (tvisnum(&n->key)) { |
1367 | TValue *tv = &((TValue *)kptr)[kidx]; | 1383 | TValue *tv = &((TValue *)kptr)[kidx]; |
1368 | if (LJ_DUALNUM) { | 1384 | if (LJ_DUALNUM) { |
1369 | lua_Number nn = numV(&n->key); | 1385 | lua_Number nn = numV(&n->key); |
1370 | int32_t k = lj_num2int(nn); | 1386 | int32_t k = lj_num2int(nn); |
1371 | lua_assert(!tvismzero(&n->key)); | 1387 | lj_assertFS(!tvismzero(&n->key), "unexpected -0 key"); |
1372 | if ((lua_Number)k == nn) | 1388 | if ((lua_Number)k == nn) |
1373 | setintV(tv, k); | 1389 | setintV(tv, k); |
1374 | else | 1390 | else |
@@ -1416,98 +1432,66 @@ static void fs_fixup_line(FuncState *fs, GCproto *pt, | |||
1416 | uint8_t *li = (uint8_t *)lineinfo; | 1432 | uint8_t *li = (uint8_t *)lineinfo; |
1417 | do { | 1433 | do { |
1418 | BCLine delta = base[i].line - first; | 1434 | BCLine delta = base[i].line - first; |
1419 | lua_assert(delta >= 0 && delta < 256); | 1435 | lj_assertFS(delta >= 0 && delta < 256, "bad line delta"); |
1420 | li[i] = (uint8_t)delta; | 1436 | li[i] = (uint8_t)delta; |
1421 | } while (++i < n); | 1437 | } while (++i < n); |
1422 | } else if (LJ_LIKELY(numline < 65536)) { | 1438 | } else if (LJ_LIKELY(numline < 65536)) { |
1423 | uint16_t *li = (uint16_t *)lineinfo; | 1439 | uint16_t *li = (uint16_t *)lineinfo; |
1424 | do { | 1440 | do { |
1425 | BCLine delta = base[i].line - first; | 1441 | BCLine delta = base[i].line - first; |
1426 | lua_assert(delta >= 0 && delta < 65536); | 1442 | lj_assertFS(delta >= 0 && delta < 65536, "bad line delta"); |
1427 | li[i] = (uint16_t)delta; | 1443 | li[i] = (uint16_t)delta; |
1428 | } while (++i < n); | 1444 | } while (++i < n); |
1429 | } else { | 1445 | } else { |
1430 | uint32_t *li = (uint32_t *)lineinfo; | 1446 | uint32_t *li = (uint32_t *)lineinfo; |
1431 | do { | 1447 | do { |
1432 | BCLine delta = base[i].line - first; | 1448 | BCLine delta = base[i].line - first; |
1433 | lua_assert(delta >= 0); | 1449 | lj_assertFS(delta >= 0, "bad line delta"); |
1434 | li[i] = (uint32_t)delta; | 1450 | li[i] = (uint32_t)delta; |
1435 | } while (++i < n); | 1451 | } while (++i < n); |
1436 | } | 1452 | } |
1437 | } | 1453 | } |
1438 | 1454 | ||
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. */ | 1455 | /* Prepare variable info for prototype. */ |
1474 | static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar) | 1456 | static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar) |
1475 | { | 1457 | { |
1476 | VarInfo *vs =ls->vstack, *ve; | 1458 | VarInfo *vs =ls->vstack, *ve; |
1477 | MSize i, n; | 1459 | MSize i, n; |
1478 | BCPos lastpc; | 1460 | BCPos lastpc; |
1479 | lj_str_resetbuf(&ls->sb); /* Copy to temp. string buffer. */ | 1461 | lj_buf_reset(&ls->sb); /* Copy to temp. string buffer. */ |
1480 | /* Store upvalue names. */ | 1462 | /* Store upvalue names. */ |
1481 | for (i = 0, n = fs->nuv; i < n; i++) { | 1463 | for (i = 0, n = fs->nuv; i < n; i++) { |
1482 | GCstr *s = strref(vs[fs->uvmap[i]].name); | 1464 | GCstr *s = strref(vs[fs->uvmap[i]].name); |
1483 | MSize len = s->len+1; | 1465 | MSize len = s->len+1; |
1484 | fs_buf_need(ls, len); | 1466 | char *p = lj_buf_more(&ls->sb, len); |
1485 | fs_buf_str(ls, strdata(s), len); | 1467 | p = lj_buf_wmem(p, strdata(s), len); |
1468 | ls->sb.w = p; | ||
1486 | } | 1469 | } |
1487 | *ofsvar = ls->sb.n; | 1470 | *ofsvar = sbuflen(&ls->sb); |
1488 | lastpc = 0; | 1471 | lastpc = 0; |
1489 | /* Store local variable names and compressed ranges. */ | 1472 | /* Store local variable names and compressed ranges. */ |
1490 | for (ve = vs + ls->vtop, vs += fs->vbase; vs < ve; vs++) { | 1473 | for (ve = vs + ls->vtop, vs += fs->vbase; vs < ve; vs++) { |
1491 | if (!gola_isgotolabel(vs)) { | 1474 | if (!gola_isgotolabel(vs)) { |
1492 | GCstr *s = strref(vs->name); | 1475 | GCstr *s = strref(vs->name); |
1493 | BCPos startpc; | 1476 | BCPos startpc; |
1477 | char *p; | ||
1494 | if ((uintptr_t)s < VARNAME__MAX) { | 1478 | if ((uintptr_t)s < VARNAME__MAX) { |
1495 | fs_buf_need(ls, 1 + 2*5); | 1479 | p = lj_buf_more(&ls->sb, 1 + 2*5); |
1496 | ls->sb.buf[ls->sb.n++] = (uint8_t)(uintptr_t)s; | 1480 | *p++ = (char)(uintptr_t)s; |
1497 | } else { | 1481 | } else { |
1498 | MSize len = s->len+1; | 1482 | MSize len = s->len+1; |
1499 | fs_buf_need(ls, len + 2*5); | 1483 | p = lj_buf_more(&ls->sb, len + 2*5); |
1500 | fs_buf_str(ls, strdata(s), len); | 1484 | p = lj_buf_wmem(p, strdata(s), len); |
1501 | } | 1485 | } |
1502 | startpc = vs->startpc; | 1486 | startpc = vs->startpc; |
1503 | fs_buf_uleb128(ls, startpc-lastpc); | 1487 | p = lj_strfmt_wuleb128(p, startpc-lastpc); |
1504 | fs_buf_uleb128(ls, vs->endpc-startpc); | 1488 | p = lj_strfmt_wuleb128(p, vs->endpc-startpc); |
1489 | ls->sb.w = p; | ||
1505 | lastpc = startpc; | 1490 | lastpc = startpc; |
1506 | } | 1491 | } |
1507 | } | 1492 | } |
1508 | fs_buf_need(ls, 1); | 1493 | lj_buf_putb(&ls->sb, '\0'); /* Terminator for varinfo. */ |
1509 | ls->sb.buf[ls->sb.n++] = '\0'; /* Terminator for varinfo. */ | 1494 | return sbuflen(&ls->sb); |
1510 | return ls->sb.n; | ||
1511 | } | 1495 | } |
1512 | 1496 | ||
1513 | /* Fixup variable info for prototype. */ | 1497 | /* Fixup variable info for prototype. */ |
@@ -1515,7 +1499,7 @@ static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar) | |||
1515 | { | 1499 | { |
1516 | setmref(pt->uvinfo, p); | 1500 | setmref(pt->uvinfo, p); |
1517 | setmref(pt->varinfo, (char *)p + ofsvar); | 1501 | setmref(pt->varinfo, (char *)p + ofsvar); |
1518 | memcpy(p, ls->sb.buf, ls->sb.n); /* Copy from temp. string buffer. */ | 1502 | memcpy(p, ls->sb.b, sbuflen(&ls->sb)); /* Copy from temp. buffer. */ |
1519 | } | 1503 | } |
1520 | #else | 1504 | #else |
1521 | 1505 | ||
@@ -1552,7 +1536,7 @@ static void fs_fixup_ret(FuncState *fs) | |||
1552 | } | 1536 | } |
1553 | fs->bl->flags |= FSCOPE_NOCLOSE; /* Handled above. */ | 1537 | fs->bl->flags |= FSCOPE_NOCLOSE; /* Handled above. */ |
1554 | fscope_end(fs); | 1538 | fscope_end(fs); |
1555 | lua_assert(fs->bl == NULL); | 1539 | lj_assertFS(fs->bl == NULL, "bad scope nesting"); |
1556 | /* May need to fixup returns encoded before first function was created. */ | 1540 | /* May need to fixup returns encoded before first function was created. */ |
1557 | if (fs->flags & PROTO_FIXUP_RETURN) { | 1541 | if (fs->flags & PROTO_FIXUP_RETURN) { |
1558 | BCPos pc; | 1542 | BCPos pc; |
@@ -1624,7 +1608,7 @@ static GCproto *fs_finish(LexState *ls, BCLine line) | |||
1624 | L->top--; /* Pop table of constants. */ | 1608 | L->top--; /* Pop table of constants. */ |
1625 | ls->vtop = fs->vbase; /* Reset variable stack. */ | 1609 | ls->vtop = fs->vbase; /* Reset variable stack. */ |
1626 | ls->fs = fs->prev; | 1610 | ls->fs = fs->prev; |
1627 | lua_assert(ls->fs != NULL || ls->token == TK_eof); | 1611 | lj_assertL(ls->fs != NULL || ls->tok == TK_eof, "bad parser state"); |
1628 | return pt; | 1612 | return pt; |
1629 | } | 1613 | } |
1630 | 1614 | ||
@@ -1718,15 +1702,15 @@ static void expr_bracket(LexState *ls, ExpDesc *v) | |||
1718 | } | 1702 | } |
1719 | 1703 | ||
1720 | /* Get value of constant expression. */ | 1704 | /* Get value of constant expression. */ |
1721 | static void expr_kvalue(TValue *v, ExpDesc *e) | 1705 | static void expr_kvalue(FuncState *fs, TValue *v, ExpDesc *e) |
1722 | { | 1706 | { |
1707 | UNUSED(fs); | ||
1723 | if (e->k <= VKTRUE) { | 1708 | if (e->k <= VKTRUE) { |
1724 | setitype(v, ~(uint32_t)e->k); | 1709 | setpriV(v, ~(uint32_t)e->k); |
1725 | } else if (e->k == VKSTR) { | 1710 | } else if (e->k == VKSTR) { |
1726 | setgcref(v->gcr, obj2gco(e->u.sval)); | 1711 | setgcVraw(v, obj2gco(e->u.sval), LJ_TSTR); |
1727 | setitype(v, LJ_TSTR); | ||
1728 | } else { | 1712 | } else { |
1729 | lua_assert(tvisnumber(expr_numtv(e))); | 1713 | lj_assertFS(tvisnumber(expr_numtv(e)), "bad number constant"); |
1730 | *v = *expr_numtv(e); | 1714 | *v = *expr_numtv(e); |
1731 | } | 1715 | } |
1732 | } | 1716 | } |
@@ -1746,15 +1730,15 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
1746 | bcreg_reserve(fs, 1); | 1730 | bcreg_reserve(fs, 1); |
1747 | freg++; | 1731 | freg++; |
1748 | lex_check(ls, '{'); | 1732 | lex_check(ls, '{'); |
1749 | while (ls->token != '}') { | 1733 | while (ls->tok != '}') { |
1750 | ExpDesc key, val; | 1734 | ExpDesc key, val; |
1751 | vcall = 0; | 1735 | vcall = 0; |
1752 | if (ls->token == '[') { | 1736 | if (ls->tok == '[') { |
1753 | expr_bracket(ls, &key); /* Already calls expr_toval. */ | 1737 | expr_bracket(ls, &key); /* Already calls expr_toval. */ |
1754 | if (!expr_isk(&key)) expr_index(fs, e, &key); | 1738 | if (!expr_isk(&key)) expr_index(fs, e, &key); |
1755 | if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++; | 1739 | if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++; |
1756 | lex_check(ls, '='); | 1740 | lex_check(ls, '='); |
1757 | } else if ((ls->token == TK_name || (!LJ_52 && ls->token == TK_goto)) && | 1741 | } else if ((ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) && |
1758 | lj_lex_lookahead(ls) == '=') { | 1742 | lj_lex_lookahead(ls) == '=') { |
1759 | expr_str(ls, &key); | 1743 | expr_str(ls, &key); |
1760 | lex_check(ls, '='); | 1744 | lex_check(ls, '='); |
@@ -1776,11 +1760,11 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
1776 | fs->bcbase[pc].ins = BCINS_AD(BC_TDUP, freg-1, kidx); | 1760 | fs->bcbase[pc].ins = BCINS_AD(BC_TDUP, freg-1, kidx); |
1777 | } | 1761 | } |
1778 | vcall = 0; | 1762 | vcall = 0; |
1779 | expr_kvalue(&k, &key); | 1763 | expr_kvalue(fs, &k, &key); |
1780 | v = lj_tab_set(fs->L, t, &k); | 1764 | v = lj_tab_set(fs->L, t, &k); |
1781 | lj_gc_anybarriert(fs->L, t); | 1765 | lj_gc_anybarriert(fs->L, t); |
1782 | if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */ | 1766 | if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */ |
1783 | expr_kvalue(v, &val); | 1767 | expr_kvalue(fs, v, &val); |
1784 | } else { /* Otherwise create dummy string key (avoids lj_tab_newkey). */ | 1768 | } else { /* Otherwise create dummy string key (avoids lj_tab_newkey). */ |
1785 | settabV(fs->L, v, t); /* Preserve key with table itself as value. */ | 1769 | settabV(fs->L, v, t); /* Preserve key with table itself as value. */ |
1786 | fixt = 1; /* Fix this later, after all resizes. */ | 1770 | fixt = 1; /* Fix this later, after all resizes. */ |
@@ -1799,8 +1783,9 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
1799 | if (vcall) { | 1783 | if (vcall) { |
1800 | BCInsLine *ilp = &fs->bcbase[fs->pc-1]; | 1784 | BCInsLine *ilp = &fs->bcbase[fs->pc-1]; |
1801 | ExpDesc en; | 1785 | ExpDesc en; |
1802 | lua_assert(bc_a(ilp->ins) == freg && | 1786 | lj_assertFS(bc_a(ilp->ins) == freg && |
1803 | bc_op(ilp->ins) == (narr > 256 ? BC_TSETV : BC_TSETB)); | 1787 | bc_op(ilp->ins) == (narr > 256 ? BC_TSETV : BC_TSETB), |
1788 | "bad CALL code generation"); | ||
1804 | expr_init(&en, VKNUM, 0); | 1789 | expr_init(&en, VKNUM, 0); |
1805 | en.u.nval.u32.lo = narr-1; | 1790 | en.u.nval.u32.lo = narr-1; |
1806 | en.u.nval.u32.hi = 0x43300000; /* Biased integer to avoid denormals. */ | 1791 | en.u.nval.u32.hi = 0x43300000; /* Biased integer to avoid denormals. */ |
@@ -1830,7 +1815,7 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
1830 | for (i = 0; i <= hmask; i++) { | 1815 | for (i = 0; i <= hmask; i++) { |
1831 | Node *n = &node[i]; | 1816 | Node *n = &node[i]; |
1832 | if (tvistab(&n->val)) { | 1817 | if (tvistab(&n->val)) { |
1833 | lua_assert(tabV(&n->val) == t); | 1818 | lj_assertFS(tabV(&n->val) == t, "bad dummy key in template table"); |
1834 | setnilV(&n->val); /* Turn value into nil. */ | 1819 | setnilV(&n->val); /* Turn value into nil. */ |
1835 | } | 1820 | } |
1836 | } | 1821 | } |
@@ -1847,11 +1832,11 @@ static BCReg parse_params(LexState *ls, int needself) | |||
1847 | lex_check(ls, '('); | 1832 | lex_check(ls, '('); |
1848 | if (needself) | 1833 | if (needself) |
1849 | var_new_lit(ls, nparams++, "self"); | 1834 | var_new_lit(ls, nparams++, "self"); |
1850 | if (ls->token != ')') { | 1835 | if (ls->tok != ')') { |
1851 | do { | 1836 | do { |
1852 | if (ls->token == TK_name || (!LJ_52 && ls->token == TK_goto)) { | 1837 | if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) { |
1853 | var_new(ls, nparams++, lex_str(ls)); | 1838 | var_new(ls, nparams++, lex_str(ls)); |
1854 | } else if (ls->token == TK_dots) { | 1839 | } else if (ls->tok == TK_dots) { |
1855 | lj_lex_next(ls); | 1840 | lj_lex_next(ls); |
1856 | fs->flags |= PROTO_VARARG; | 1841 | fs->flags |= PROTO_VARARG; |
1857 | break; | 1842 | break; |
@@ -1861,7 +1846,7 @@ static BCReg parse_params(LexState *ls, int needself) | |||
1861 | } while (lex_opt(ls, ',')); | 1846 | } while (lex_opt(ls, ',')); |
1862 | } | 1847 | } |
1863 | var_add(ls, nparams); | 1848 | var_add(ls, nparams); |
1864 | lua_assert(fs->nactvar == nparams); | 1849 | lj_assertFS(fs->nactvar == nparams, "bad regalloc"); |
1865 | bcreg_reserve(fs, nparams); | 1850 | bcreg_reserve(fs, nparams); |
1866 | lex_check(ls, ')'); | 1851 | lex_check(ls, ')'); |
1867 | return nparams; | 1852 | return nparams; |
@@ -1885,7 +1870,7 @@ static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line) | |||
1885 | fs.bclim = pfs->bclim - pfs->pc; | 1870 | fs.bclim = pfs->bclim - pfs->pc; |
1886 | bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */ | 1871 | bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */ |
1887 | parse_chunk(ls); | 1872 | parse_chunk(ls); |
1888 | if (ls->token != TK_end) lex_match(ls, TK_end, TK_function, line); | 1873 | if (ls->tok != TK_end) lex_match(ls, TK_end, TK_function, line); |
1889 | pt = fs_finish(ls, (ls->lastline = ls->linenumber)); | 1874 | pt = fs_finish(ls, (ls->lastline = ls->linenumber)); |
1890 | pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ | 1875 | pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ |
1891 | pfs->bclim = (BCPos)(ls->sizebcstack - oldbase); | 1876 | pfs->bclim = (BCPos)(ls->sizebcstack - oldbase); |
@@ -1924,13 +1909,13 @@ static void parse_args(LexState *ls, ExpDesc *e) | |||
1924 | BCIns ins; | 1909 | BCIns ins; |
1925 | BCReg base; | 1910 | BCReg base; |
1926 | BCLine line = ls->linenumber; | 1911 | BCLine line = ls->linenumber; |
1927 | if (ls->token == '(') { | 1912 | if (ls->tok == '(') { |
1928 | #if !LJ_52 | 1913 | #if !LJ_52 |
1929 | if (line != ls->lastline) | 1914 | if (line != ls->lastline) |
1930 | err_syntax(ls, LJ_ERR_XAMBIG); | 1915 | err_syntax(ls, LJ_ERR_XAMBIG); |
1931 | #endif | 1916 | #endif |
1932 | lj_lex_next(ls); | 1917 | lj_lex_next(ls); |
1933 | if (ls->token == ')') { /* f(). */ | 1918 | if (ls->tok == ')') { /* f(). */ |
1934 | args.k = VVOID; | 1919 | args.k = VVOID; |
1935 | } else { | 1920 | } else { |
1936 | expr_list(ls, &args); | 1921 | expr_list(ls, &args); |
@@ -1938,24 +1923,24 @@ static void parse_args(LexState *ls, ExpDesc *e) | |||
1938 | setbc_b(bcptr(fs, &args), 0); /* Pass on multiple results. */ | 1923 | setbc_b(bcptr(fs, &args), 0); /* Pass on multiple results. */ |
1939 | } | 1924 | } |
1940 | lex_match(ls, ')', '(', line); | 1925 | lex_match(ls, ')', '(', line); |
1941 | } else if (ls->token == '{') { | 1926 | } else if (ls->tok == '{') { |
1942 | expr_table(ls, &args); | 1927 | expr_table(ls, &args); |
1943 | } else if (ls->token == TK_string) { | 1928 | } else if (ls->tok == TK_string) { |
1944 | expr_init(&args, VKSTR, 0); | 1929 | expr_init(&args, VKSTR, 0); |
1945 | args.u.sval = strV(&ls->tokenval); | 1930 | args.u.sval = strV(&ls->tokval); |
1946 | lj_lex_next(ls); | 1931 | lj_lex_next(ls); |
1947 | } else { | 1932 | } else { |
1948 | err_syntax(ls, LJ_ERR_XFUNARG); | 1933 | err_syntax(ls, LJ_ERR_XFUNARG); |
1949 | return; /* Silence compiler. */ | 1934 | return; /* Silence compiler. */ |
1950 | } | 1935 | } |
1951 | lua_assert(e->k == VNONRELOC); | 1936 | lj_assertFS(e->k == VNONRELOC, "bad expr type %d", e->k); |
1952 | base = e->u.s.info; /* Base register for call. */ | 1937 | base = e->u.s.info; /* Base register for call. */ |
1953 | if (args.k == VCALL) { | 1938 | if (args.k == VCALL) { |
1954 | ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1); | 1939 | ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1 - LJ_FR2); |
1955 | } else { | 1940 | } else { |
1956 | if (args.k != VVOID) | 1941 | if (args.k != VVOID) |
1957 | expr_tonextreg(fs, &args); | 1942 | expr_tonextreg(fs, &args); |
1958 | ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base); | 1943 | ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base - LJ_FR2); |
1959 | } | 1944 | } |
1960 | expr_init(e, VCALL, bcemit_INS(fs, ins)); | 1945 | expr_init(e, VCALL, bcemit_INS(fs, ins)); |
1961 | e->u.s.aux = base; | 1946 | e->u.s.aux = base; |
@@ -1968,33 +1953,34 @@ static void expr_primary(LexState *ls, ExpDesc *v) | |||
1968 | { | 1953 | { |
1969 | FuncState *fs = ls->fs; | 1954 | FuncState *fs = ls->fs; |
1970 | /* Parse prefix expression. */ | 1955 | /* Parse prefix expression. */ |
1971 | if (ls->token == '(') { | 1956 | if (ls->tok == '(') { |
1972 | BCLine line = ls->linenumber; | 1957 | BCLine line = ls->linenumber; |
1973 | lj_lex_next(ls); | 1958 | lj_lex_next(ls); |
1974 | expr(ls, v); | 1959 | expr(ls, v); |
1975 | lex_match(ls, ')', '(', line); | 1960 | lex_match(ls, ')', '(', line); |
1976 | expr_discharge(ls->fs, v); | 1961 | expr_discharge(ls->fs, v); |
1977 | } else if (ls->token == TK_name || (!LJ_52 && ls->token == TK_goto)) { | 1962 | } else if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) { |
1978 | var_lookup(ls, v); | 1963 | var_lookup(ls, v); |
1979 | } else { | 1964 | } else { |
1980 | err_syntax(ls, LJ_ERR_XSYMBOL); | 1965 | err_syntax(ls, LJ_ERR_XSYMBOL); |
1981 | } | 1966 | } |
1982 | for (;;) { /* Parse multiple expression suffixes. */ | 1967 | for (;;) { /* Parse multiple expression suffixes. */ |
1983 | if (ls->token == '.') { | 1968 | if (ls->tok == '.') { |
1984 | expr_field(ls, v); | 1969 | expr_field(ls, v); |
1985 | } else if (ls->token == '[') { | 1970 | } else if (ls->tok == '[') { |
1986 | ExpDesc key; | 1971 | ExpDesc key; |
1987 | expr_toanyreg(fs, v); | 1972 | expr_toanyreg(fs, v); |
1988 | expr_bracket(ls, &key); | 1973 | expr_bracket(ls, &key); |
1989 | expr_index(fs, v, &key); | 1974 | expr_index(fs, v, &key); |
1990 | } else if (ls->token == ':') { | 1975 | } else if (ls->tok == ':') { |
1991 | ExpDesc key; | 1976 | ExpDesc key; |
1992 | lj_lex_next(ls); | 1977 | lj_lex_next(ls); |
1993 | expr_str(ls, &key); | 1978 | expr_str(ls, &key); |
1994 | bcemit_method(fs, v, &key); | 1979 | bcemit_method(fs, v, &key); |
1995 | parse_args(ls, v); | 1980 | parse_args(ls, v); |
1996 | } else if (ls->token == '(' || ls->token == TK_string || ls->token == '{') { | 1981 | } else if (ls->tok == '(' || ls->tok == TK_string || ls->tok == '{') { |
1997 | expr_tonextreg(fs, v); | 1982 | expr_tonextreg(fs, v); |
1983 | if (LJ_FR2) bcreg_reserve(fs, 1); | ||
1998 | parse_args(ls, v); | 1984 | parse_args(ls, v); |
1999 | } else { | 1985 | } else { |
2000 | break; | 1986 | break; |
@@ -2005,14 +1991,14 @@ static void expr_primary(LexState *ls, ExpDesc *v) | |||
2005 | /* Parse simple expression. */ | 1991 | /* Parse simple expression. */ |
2006 | static void expr_simple(LexState *ls, ExpDesc *v) | 1992 | static void expr_simple(LexState *ls, ExpDesc *v) |
2007 | { | 1993 | { |
2008 | switch (ls->token) { | 1994 | switch (ls->tok) { |
2009 | case TK_number: | 1995 | case TK_number: |
2010 | expr_init(v, (LJ_HASFFI && tviscdata(&ls->tokenval)) ? VKCDATA : VKNUM, 0); | 1996 | expr_init(v, (LJ_HASFFI && tviscdata(&ls->tokval)) ? VKCDATA : VKNUM, 0); |
2011 | copyTV(ls->L, &v->u.nval, &ls->tokenval); | 1997 | copyTV(ls->L, &v->u.nval, &ls->tokval); |
2012 | break; | 1998 | break; |
2013 | case TK_string: | 1999 | case TK_string: |
2014 | expr_init(v, VKSTR, 0); | 2000 | expr_init(v, VKSTR, 0); |
2015 | v->u.sval = strV(&ls->tokenval); | 2001 | v->u.sval = strV(&ls->tokval); |
2016 | break; | 2002 | break; |
2017 | case TK_nil: | 2003 | case TK_nil: |
2018 | expr_init(v, VKNIL, 0); | 2004 | expr_init(v, VKNIL, 0); |
@@ -2100,11 +2086,11 @@ static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit); | |||
2100 | static void expr_unop(LexState *ls, ExpDesc *v) | 2086 | static void expr_unop(LexState *ls, ExpDesc *v) |
2101 | { | 2087 | { |
2102 | BCOp op; | 2088 | BCOp op; |
2103 | if (ls->token == TK_not) { | 2089 | if (ls->tok == TK_not) { |
2104 | op = BC_NOT; | 2090 | op = BC_NOT; |
2105 | } else if (ls->token == '-') { | 2091 | } else if (ls->tok == '-') { |
2106 | op = BC_UNM; | 2092 | op = BC_UNM; |
2107 | } else if (ls->token == '#') { | 2093 | } else if (ls->tok == '#') { |
2108 | op = BC_LEN; | 2094 | op = BC_LEN; |
2109 | } else { | 2095 | } else { |
2110 | expr_simple(ls, v); | 2096 | expr_simple(ls, v); |
@@ -2121,7 +2107,7 @@ static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit) | |||
2121 | BinOpr op; | 2107 | BinOpr op; |
2122 | synlevel_begin(ls); | 2108 | synlevel_begin(ls); |
2123 | expr_unop(ls, v); | 2109 | expr_unop(ls, v); |
2124 | op = token2binop(ls->token); | 2110 | op = token2binop(ls->tok); |
2125 | while (op != OPR_NOBINOPR && priority[op].left > limit) { | 2111 | while (op != OPR_NOBINOPR && priority[op].left > limit) { |
2126 | ExpDesc v2; | 2112 | ExpDesc v2; |
2127 | BinOpr nextop; | 2113 | BinOpr nextop; |
@@ -2310,9 +2296,9 @@ static void parse_func(LexState *ls, BCLine line) | |||
2310 | lj_lex_next(ls); /* Skip 'function'. */ | 2296 | lj_lex_next(ls); /* Skip 'function'. */ |
2311 | /* Parse function name. */ | 2297 | /* Parse function name. */ |
2312 | var_lookup(ls, &v); | 2298 | var_lookup(ls, &v); |
2313 | while (ls->token == '.') /* Multiple dot-separated fields. */ | 2299 | while (ls->tok == '.') /* Multiple dot-separated fields. */ |
2314 | expr_field(ls, &v); | 2300 | expr_field(ls, &v); |
2315 | if (ls->token == ':') { /* Optional colon to signify method call. */ | 2301 | if (ls->tok == ':') { /* Optional colon to signify method call. */ |
2316 | needself = 1; | 2302 | needself = 1; |
2317 | expr_field(ls, &v); | 2303 | expr_field(ls, &v); |
2318 | } | 2304 | } |
@@ -2325,9 +2311,9 @@ static void parse_func(LexState *ls, BCLine line) | |||
2325 | /* -- Control transfer statements ----------------------------------------- */ | 2311 | /* -- Control transfer statements ----------------------------------------- */ |
2326 | 2312 | ||
2327 | /* Check for end of block. */ | 2313 | /* Check for end of block. */ |
2328 | static int endofblock(LexToken token) | 2314 | static int parse_isend(LexToken tok) |
2329 | { | 2315 | { |
2330 | switch (token) { | 2316 | switch (tok) { |
2331 | case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof: | 2317 | case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof: |
2332 | return 1; | 2318 | return 1; |
2333 | default: | 2319 | default: |
@@ -2342,7 +2328,7 @@ static void parse_return(LexState *ls) | |||
2342 | FuncState *fs = ls->fs; | 2328 | FuncState *fs = ls->fs; |
2343 | lj_lex_next(ls); /* Skip 'return'. */ | 2329 | lj_lex_next(ls); /* Skip 'return'. */ |
2344 | fs->flags |= PROTO_HAS_RETURN; | 2330 | fs->flags |= PROTO_HAS_RETURN; |
2345 | if (endofblock(ls->token) || ls->token == ';') { /* Bare return. */ | 2331 | if (parse_isend(ls->tok) || ls->tok == ';') { /* Bare return. */ |
2346 | ins = BCINS_AD(BC_RET0, 0, 1); | 2332 | ins = BCINS_AD(BC_RET0, 0, 1); |
2347 | } else { /* Return with one or more values. */ | 2333 | } else { /* Return with one or more values. */ |
2348 | ExpDesc e; /* Receives the _last_ expression in the list. */ | 2334 | ExpDesc e; /* Receives the _last_ expression in the list. */ |
@@ -2408,18 +2394,18 @@ static void parse_label(LexState *ls) | |||
2408 | lex_check(ls, TK_label); | 2394 | lex_check(ls, TK_label); |
2409 | /* Recursively parse trailing statements: labels and ';' (Lua 5.2 only). */ | 2395 | /* Recursively parse trailing statements: labels and ';' (Lua 5.2 only). */ |
2410 | for (;;) { | 2396 | for (;;) { |
2411 | if (ls->token == TK_label) { | 2397 | if (ls->tok == TK_label) { |
2412 | synlevel_begin(ls); | 2398 | synlevel_begin(ls); |
2413 | parse_label(ls); | 2399 | parse_label(ls); |
2414 | synlevel_end(ls); | 2400 | synlevel_end(ls); |
2415 | } else if (LJ_52 && ls->token == ';') { | 2401 | } else if (LJ_52 && ls->tok == ';') { |
2416 | lj_lex_next(ls); | 2402 | lj_lex_next(ls); |
2417 | } else { | 2403 | } else { |
2418 | break; | 2404 | break; |
2419 | } | 2405 | } |
2420 | } | 2406 | } |
2421 | /* Trailing label is considered to be outside of scope. */ | 2407 | /* Trailing label is considered to be outside of scope. */ |
2422 | if (endofblock(ls->token) && ls->token != TK_until) | 2408 | if (parse_isend(ls->tok) && ls->tok != TK_until) |
2423 | ls->vstack[idx].slot = fs->bl->nactvar; | 2409 | ls->vstack[idx].slot = fs->bl->nactvar; |
2424 | gola_resolve(ls, fs->bl, idx); | 2410 | gola_resolve(ls, fs->bl, idx); |
2425 | } | 2411 | } |
@@ -2575,7 +2561,8 @@ static void parse_for_iter(LexState *ls, GCstr *indexname) | |||
2575 | lex_check(ls, TK_in); | 2561 | lex_check(ls, TK_in); |
2576 | line = ls->linenumber; | 2562 | line = ls->linenumber; |
2577 | assign_adjust(ls, 3, expr_list(ls, &e), &e); | 2563 | assign_adjust(ls, 3, expr_list(ls, &e), &e); |
2578 | bcreg_bump(fs, 3); /* The iterator needs another 3 slots (func + 2 args). */ | 2564 | /* The iterator needs another 3 [4] slots (func [pc] | state ctl). */ |
2565 | bcreg_bump(fs, 3+LJ_FR2); | ||
2579 | isnext = (nvars <= 5 && predict_next(ls, fs, exprpc)); | 2566 | isnext = (nvars <= 5 && predict_next(ls, fs, exprpc)); |
2580 | var_add(ls, 3); /* Hidden control variables. */ | 2567 | var_add(ls, 3); /* Hidden control variables. */ |
2581 | lex_check(ls, TK_do); | 2568 | lex_check(ls, TK_do); |
@@ -2603,9 +2590,9 @@ static void parse_for(LexState *ls, BCLine line) | |||
2603 | fscope_begin(fs, &bl, FSCOPE_LOOP); | 2590 | fscope_begin(fs, &bl, FSCOPE_LOOP); |
2604 | lj_lex_next(ls); /* Skip 'for'. */ | 2591 | lj_lex_next(ls); /* Skip 'for'. */ |
2605 | varname = lex_str(ls); /* Get first variable name. */ | 2592 | varname = lex_str(ls); /* Get first variable name. */ |
2606 | if (ls->token == '=') | 2593 | if (ls->tok == '=') |
2607 | parse_for_num(ls, varname, line); | 2594 | parse_for_num(ls, varname, line); |
2608 | else if (ls->token == ',' || ls->token == TK_in) | 2595 | else if (ls->tok == ',' || ls->tok == TK_in) |
2609 | parse_for_iter(ls, varname); | 2596 | parse_for_iter(ls, varname); |
2610 | else | 2597 | else |
2611 | err_syntax(ls, LJ_ERR_XFOR); | 2598 | err_syntax(ls, LJ_ERR_XFOR); |
@@ -2631,12 +2618,12 @@ static void parse_if(LexState *ls, BCLine line) | |||
2631 | BCPos flist; | 2618 | BCPos flist; |
2632 | BCPos escapelist = NO_JMP; | 2619 | BCPos escapelist = NO_JMP; |
2633 | flist = parse_then(ls); | 2620 | flist = parse_then(ls); |
2634 | while (ls->token == TK_elseif) { /* Parse multiple 'elseif' blocks. */ | 2621 | while (ls->tok == TK_elseif) { /* Parse multiple 'elseif' blocks. */ |
2635 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); | 2622 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); |
2636 | jmp_tohere(fs, flist); | 2623 | jmp_tohere(fs, flist); |
2637 | flist = parse_then(ls); | 2624 | flist = parse_then(ls); |
2638 | } | 2625 | } |
2639 | if (ls->token == TK_else) { /* Parse optional 'else' block. */ | 2626 | if (ls->tok == TK_else) { /* Parse optional 'else' block. */ |
2640 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); | 2627 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); |
2641 | jmp_tohere(fs, flist); | 2628 | jmp_tohere(fs, flist); |
2642 | lj_lex_next(ls); /* Skip 'else'. */ | 2629 | lj_lex_next(ls); /* Skip 'else'. */ |
@@ -2654,7 +2641,7 @@ static void parse_if(LexState *ls, BCLine line) | |||
2654 | static int parse_stmt(LexState *ls) | 2641 | static int parse_stmt(LexState *ls) |
2655 | { | 2642 | { |
2656 | BCLine line = ls->linenumber; | 2643 | BCLine line = ls->linenumber; |
2657 | switch (ls->token) { | 2644 | switch (ls->tok) { |
2658 | case TK_if: | 2645 | case TK_if: |
2659 | parse_if(ls, line); | 2646 | parse_if(ls, line); |
2660 | break; | 2647 | break; |
@@ -2713,11 +2700,12 @@ static void parse_chunk(LexState *ls) | |||
2713 | { | 2700 | { |
2714 | int islast = 0; | 2701 | int islast = 0; |
2715 | synlevel_begin(ls); | 2702 | synlevel_begin(ls); |
2716 | while (!islast && !endofblock(ls->token)) { | 2703 | while (!islast && !parse_isend(ls->tok)) { |
2717 | islast = parse_stmt(ls); | 2704 | islast = parse_stmt(ls); |
2718 | lex_opt(ls, ';'); | 2705 | lex_opt(ls, ';'); |
2719 | lua_assert(ls->fs->framesize >= ls->fs->freereg && | 2706 | lj_assertLS(ls->fs->framesize >= ls->fs->freereg && |
2720 | ls->fs->freereg >= ls->fs->nactvar); | 2707 | ls->fs->freereg >= ls->fs->nactvar, |
2708 | "bad regalloc"); | ||
2721 | ls->fs->freereg = ls->fs->nactvar; /* Free registers after each stmt. */ | 2709 | ls->fs->freereg = ls->fs->nactvar; /* Free registers after each stmt. */ |
2722 | } | 2710 | } |
2723 | synlevel_end(ls); | 2711 | synlevel_end(ls); |
@@ -2748,13 +2736,12 @@ GCproto *lj_parse(LexState *ls) | |||
2748 | bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */ | 2736 | bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */ |
2749 | lj_lex_next(ls); /* Read-ahead first token. */ | 2737 | lj_lex_next(ls); /* Read-ahead first token. */ |
2750 | parse_chunk(ls); | 2738 | parse_chunk(ls); |
2751 | if (ls->token != TK_eof) | 2739 | if (ls->tok != TK_eof) |
2752 | err_token(ls, TK_eof); | 2740 | err_token(ls, TK_eof); |
2753 | pt = fs_finish(ls, ls->linenumber); | 2741 | pt = fs_finish(ls, ls->linenumber); |
2754 | L->top--; /* Drop chunkname. */ | 2742 | L->top--; /* Drop chunkname. */ |
2755 | lua_assert(fs.prev == NULL); | 2743 | lj_assertL(fs.prev == NULL && ls->fs == NULL, "mismatched frame nesting"); |
2756 | lua_assert(ls->fs == NULL); | 2744 | lj_assertL(pt->sizeuv == 0, "toplevel proto has upvalues"); |
2757 | lua_assert(pt->sizeuv == 0); | ||
2758 | return pt; | 2745 | return pt; |
2759 | } | 2746 | } |
2760 | 2747 | ||