diff options
Diffstat (limited to 'lparser.c')
| -rw-r--r-- | lparser.c | 29 |
1 files changed, 19 insertions, 10 deletions
| @@ -1041,9 +1041,10 @@ static void constructor (LexState *ls, expdesc *t) { | |||
| 1041 | /* }====================================================================== */ | 1041 | /* }====================================================================== */ |
| 1042 | 1042 | ||
| 1043 | 1043 | ||
| 1044 | static void setvararg (FuncState *fs, int nparams) { | 1044 | static void setvararg (FuncState *fs, int kind) { |
| 1045 | fs->f->flag |= PF_ISVARARG; | 1045 | lua_assert(kind & PF_ISVARARG); |
| 1046 | luaK_codeABC(fs, OP_VARARGPREP, nparams, 0, 0); | 1046 | fs->f->flag |= cast_byte(kind); |
| 1047 | luaK_codeABC(fs, OP_VARARGPREP, 0, 0, 0); | ||
| 1047 | } | 1048 | } |
| 1048 | 1049 | ||
| 1049 | 1050 | ||
| @@ -1052,7 +1053,7 @@ static void parlist (LexState *ls) { | |||
| 1052 | FuncState *fs = ls->fs; | 1053 | FuncState *fs = ls->fs; |
| 1053 | Proto *f = fs->f; | 1054 | Proto *f = fs->f; |
| 1054 | int nparams = 0; | 1055 | int nparams = 0; |
| 1055 | int isvararg = 0; | 1056 | int varargk = 0; |
| 1056 | if (ls->t.token != ')') { /* is 'parlist' not empty? */ | 1057 | if (ls->t.token != ')') { /* is 'parlist' not empty? */ |
| 1057 | do { | 1058 | do { |
| 1058 | switch (ls->t.token) { | 1059 | switch (ls->t.token) { |
| @@ -1062,19 +1063,27 @@ static void parlist (LexState *ls) { | |||
| 1062 | break; | 1063 | break; |
| 1063 | } | 1064 | } |
| 1064 | case TK_DOTS: { | 1065 | case TK_DOTS: { |
| 1066 | varargk |= PF_ISVARARG; | ||
| 1065 | luaX_next(ls); | 1067 | luaX_next(ls); |
| 1066 | isvararg = 1; | 1068 | if (testnext(ls, '=')) { |
| 1069 | new_varkind(ls, str_checkname(ls), RDKVATAB); | ||
| 1070 | varargk |= PF_VATAB; | ||
| 1071 | } | ||
| 1067 | break; | 1072 | break; |
| 1068 | } | 1073 | } |
| 1069 | default: luaX_syntaxerror(ls, "<name> or '...' expected"); | 1074 | default: luaX_syntaxerror(ls, "<name> or '...' expected"); |
| 1070 | } | 1075 | } |
| 1071 | } while (!isvararg && testnext(ls, ',')); | 1076 | } while (!varargk && testnext(ls, ',')); |
| 1072 | } | 1077 | } |
| 1073 | adjustlocalvars(ls, nparams); | 1078 | adjustlocalvars(ls, nparams); |
| 1074 | f->numparams = cast_byte(fs->nactvar); | 1079 | f->numparams = cast_byte(fs->nactvar); |
| 1075 | if (isvararg) | 1080 | if (varargk != 0) { |
| 1076 | setvararg(fs, f->numparams); /* declared vararg */ | 1081 | setvararg(fs, varargk); /* declared vararg */ |
| 1077 | luaK_reserveregs(fs, fs->nactvar); /* reserve registers for parameters */ | 1082 | if (varargk & PF_VATAB) |
| 1083 | adjustlocalvars(ls, 1); /* vararg table */ | ||
| 1084 | } | ||
| 1085 | /* reserve registers for parameters (and vararg variable, if present) */ | ||
| 1086 | luaK_reserveregs(fs, fs->nactvar); | ||
| 1078 | } | 1087 | } |
| 1079 | 1088 | ||
| 1080 | 1089 | ||
| @@ -2099,7 +2108,7 @@ static void mainfunc (LexState *ls, FuncState *fs) { | |||
| 2099 | BlockCnt bl; | 2108 | BlockCnt bl; |
| 2100 | Upvaldesc *env; | 2109 | Upvaldesc *env; |
| 2101 | open_func(ls, fs, &bl); | 2110 | open_func(ls, fs, &bl); |
| 2102 | setvararg(fs, 0); /* main function is always declared vararg */ | 2111 | setvararg(fs, PF_ISVARARG); /* main function is always vararg */ |
| 2103 | env = allocupvalue(fs); /* ...set environment upvalue */ | 2112 | env = allocupvalue(fs); /* ...set environment upvalue */ |
| 2104 | env->instack = 1; | 2113 | env->instack = 1; |
| 2105 | env->idx = 0; | 2114 | env->idx = 0; |
