diff options
Diffstat (limited to 'lparser.c')
-rw-r--r-- | lparser.c | 29 |
1 files changed, 7 insertions, 22 deletions
@@ -815,7 +815,7 @@ typedef struct ConsControl { | |||
815 | expdesc v; /* last list item read */ | 815 | expdesc v; /* last list item read */ |
816 | expdesc *t; /* table descriptor */ | 816 | expdesc *t; /* table descriptor */ |
817 | int nh; /* total number of 'record' elements */ | 817 | int nh; /* total number of 'record' elements */ |
818 | int na; /* total number of array elements */ | 818 | int na; /* number of array elements already stored */ |
819 | int tostore; /* number of array elements pending to be stored */ | 819 | int tostore; /* number of array elements pending to be stored */ |
820 | } ConsControl; | 820 | } ConsControl; |
821 | 821 | ||
@@ -847,6 +847,7 @@ static void closelistfield (FuncState *fs, ConsControl *cc) { | |||
847 | cc->v.k = VVOID; | 847 | cc->v.k = VVOID; |
848 | if (cc->tostore == LFIELDS_PER_FLUSH) { | 848 | if (cc->tostore == LFIELDS_PER_FLUSH) { |
849 | luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */ | 849 | luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */ |
850 | cc->na += cc->tostore; | ||
850 | cc->tostore = 0; /* no more items pending */ | 851 | cc->tostore = 0; /* no more items pending */ |
851 | } | 852 | } |
852 | } | 853 | } |
@@ -864,13 +865,13 @@ static void lastlistfield (FuncState *fs, ConsControl *cc) { | |||
864 | luaK_exp2nextreg(fs, &cc->v); | 865 | luaK_exp2nextreg(fs, &cc->v); |
865 | luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); | 866 | luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); |
866 | } | 867 | } |
868 | cc->na += cc->tostore; | ||
867 | } | 869 | } |
868 | 870 | ||
869 | 871 | ||
870 | static void listfield (LexState *ls, ConsControl *cc) { | 872 | static void listfield (LexState *ls, ConsControl *cc) { |
871 | /* listfield -> exp */ | 873 | /* listfield -> exp */ |
872 | expr(ls, &cc->v); | 874 | expr(ls, &cc->v); |
873 | cc->na++; | ||
874 | cc->tostore++; | 875 | cc->tostore++; |
875 | } | 876 | } |
876 | 877 | ||
@@ -897,22 +898,6 @@ static void field (LexState *ls, ConsControl *cc) { | |||
897 | } | 898 | } |
898 | 899 | ||
899 | 900 | ||
900 | static void settablesize (FuncState *fs, ConsControl *cc, int pc) { | ||
901 | Instruction *inst = &fs->f->code[pc]; | ||
902 | int rc = (cc->nh == 0) ? 0 : luaO_ceillog2(cc->nh) + 1; | ||
903 | int rb = cc->na; | ||
904 | int extra = 0; | ||
905 | if (rb >= LIMTABSZ) { | ||
906 | extra = rb / LFIELDS_PER_FLUSH; | ||
907 | rb = rb % LFIELDS_PER_FLUSH + LIMTABSZ; | ||
908 | checklimit(fs, extra, MAXARG_Ax, "items in a constructor"); | ||
909 | } | ||
910 | SETARG_C(*inst, rc); /* set initial table size */ | ||
911 | SETARG_B(*inst, rb); /* set initial array size */ | ||
912 | SETARG_Ax(*(inst + 1), extra); | ||
913 | } | ||
914 | |||
915 | |||
916 | static void constructor (LexState *ls, expdesc *t) { | 901 | static void constructor (LexState *ls, expdesc *t) { |
917 | /* constructor -> '{' [ field { sep field } [sep] ] '}' | 902 | /* constructor -> '{' [ field { sep field } [sep] ] '}' |
918 | sep -> ',' | ';' */ | 903 | sep -> ',' | ';' */ |
@@ -920,12 +905,12 @@ static void constructor (LexState *ls, expdesc *t) { | |||
920 | int line = ls->linenumber; | 905 | int line = ls->linenumber; |
921 | int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); | 906 | int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); |
922 | ConsControl cc; | 907 | ConsControl cc; |
923 | luaK_codeextraarg(fs, 0); | 908 | luaK_code(fs, 0); /* space for extra arg. */ |
924 | cc.na = cc.nh = cc.tostore = 0; | 909 | cc.na = cc.nh = cc.tostore = 0; |
925 | cc.t = t; | 910 | cc.t = t; |
926 | init_exp(t, VRELOC, pc); | 911 | init_exp(t, VNONRELOC, fs->freereg); /* table will be at stack top */ |
912 | luaK_reserveregs(fs, 1); | ||
927 | init_exp(&cc.v, VVOID, 0); /* no value (yet) */ | 913 | init_exp(&cc.v, VVOID, 0); /* no value (yet) */ |
928 | luaK_exp2nextreg(ls->fs, t); /* fix it at stack top */ | ||
929 | checknext(ls, '{'); | 914 | checknext(ls, '{'); |
930 | do { | 915 | do { |
931 | lua_assert(cc.v.k == VVOID || cc.tostore > 0); | 916 | lua_assert(cc.v.k == VVOID || cc.tostore > 0); |
@@ -935,7 +920,7 @@ static void constructor (LexState *ls, expdesc *t) { | |||
935 | } while (testnext(ls, ',') || testnext(ls, ';')); | 920 | } while (testnext(ls, ',') || testnext(ls, ';')); |
936 | check_match(ls, '}', '{', line); | 921 | check_match(ls, '}', '{', line); |
937 | lastlistfield(fs, &cc); | 922 | lastlistfield(fs, &cc); |
938 | settablesize(fs, &cc, pc); | 923 | luaK_settablesize(fs, pc, t->u.info, cc.na, cc.nh); |
939 | } | 924 | } |
940 | 925 | ||
941 | /* }====================================================================== */ | 926 | /* }====================================================================== */ |