diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-09 13:16:06 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-09 13:16:06 -0200 |
| commit | b1379936cf35787d3ef3aab82d1607a3e1562eef (patch) | |
| tree | fe47cb5c35fddab945faf731f0bc175bf5431352 /lparser.c | |
| parent | 4e0de3a43cc30a83334c272cb7575bf8412bfeae (diff) | |
| download | lua-b1379936cf35787d3ef3aab82d1607a3e1562eef.tar.gz lua-b1379936cf35787d3ef3aab82d1607a3e1562eef.tar.bz2 lua-b1379936cf35787d3ef3aab82d1607a3e1562eef.zip | |
vararg back to '...' (but with another implementation)
new implementation should have zero overhead for non-vararg functions
Diffstat (limited to 'lparser.c')
| -rw-r--r-- | lparser.c | 22 |
1 files changed, 6 insertions, 16 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 2.175 2017/12/22 14:16:46 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 2.176 2018/02/07 15:18:04 roberto Exp roberto $ |
| 3 | ** Lua Parser | 3 | ** Lua Parser |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -568,6 +568,7 @@ static void close_func (LexState *ls) { | |||
| 568 | Proto *f = fs->f; | 568 | Proto *f = fs->f; |
| 569 | luaK_ret(fs, 0, 0); /* final return */ | 569 | luaK_ret(fs, 0, 0); /* final return */ |
| 570 | leaveblock(fs); | 570 | leaveblock(fs); |
| 571 | lua_assert(fs->bl == NULL); | ||
| 571 | luaK_finish(fs); | 572 | luaK_finish(fs); |
| 572 | luaM_shrinkvector(L, f->code, f->sizecode, fs->pc, Instruction); | 573 | luaM_shrinkvector(L, f->code, f->sizecode, fs->pc, Instruction); |
| 573 | luaM_shrinkvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte); | 574 | luaM_shrinkvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte); |
| @@ -577,7 +578,8 @@ static void close_func (LexState *ls) { | |||
| 577 | luaM_shrinkvector(L, f->p, f->sizep, fs->np, Proto *); | 578 | luaM_shrinkvector(L, f->p, f->sizep, fs->np, Proto *); |
| 578 | luaM_shrinkvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); | 579 | luaM_shrinkvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); |
| 579 | luaM_shrinkvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); | 580 | luaM_shrinkvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); |
| 580 | lua_assert(fs->bl == NULL); | 581 | if (f->is_vararg) |
| 582 | f->maxstacksize++; /* ensure space to copy the function */ | ||
| 581 | ls->fs = fs->prev; | 583 | ls->fs = fs->prev; |
| 582 | luaC_checkGC(L); | 584 | luaC_checkGC(L); |
| 583 | } | 585 | } |
| @@ -781,11 +783,6 @@ static void parlist (LexState *ls) { | |||
| 781 | } | 783 | } |
| 782 | case TK_DOTS: { /* param -> '...' */ | 784 | case TK_DOTS: { /* param -> '...' */ |
| 783 | luaX_next(ls); | 785 | luaX_next(ls); |
| 784 | if (testnext(ls, '=')) | ||
| 785 | new_localvar(ls, str_checkname(ls)); | ||
| 786 | else | ||
| 787 | new_localvarliteral(ls, "_ARG"); | ||
| 788 | nparams++; | ||
| 789 | isvararg = 1; | 786 | isvararg = 1; |
| 790 | break; | 787 | break; |
| 791 | } | 788 | } |
| @@ -795,10 +792,8 @@ static void parlist (LexState *ls) { | |||
| 795 | } | 792 | } |
| 796 | adjustlocalvars(ls, nparams); | 793 | adjustlocalvars(ls, nparams); |
| 797 | f->numparams = cast_byte(fs->nactvar); | 794 | f->numparams = cast_byte(fs->nactvar); |
| 798 | if (isvararg) { | 795 | if (isvararg) |
| 799 | f->numparams--; /* exclude vararg parameter */ | ||
| 800 | setvararg(fs, f->numparams); /* declared vararg */ | 796 | setvararg(fs, f->numparams); /* declared vararg */ |
| 801 | } | ||
| 802 | luaK_reserveregs(fs, fs->nactvar); /* reserve registers for parameters */ | 797 | luaK_reserveregs(fs, fs->nactvar); /* reserve registers for parameters */ |
| 803 | } | 798 | } |
| 804 | 799 | ||
| @@ -984,10 +979,9 @@ static void simpleexp (LexState *ls, expdesc *v) { | |||
| 984 | } | 979 | } |
| 985 | case TK_DOTS: { /* vararg */ | 980 | case TK_DOTS: { /* vararg */ |
| 986 | FuncState *fs = ls->fs; | 981 | FuncState *fs = ls->fs; |
| 987 | int lastparam = fs->f->numparams; | ||
| 988 | check_condition(ls, fs->f->is_vararg, | 982 | check_condition(ls, fs->f->is_vararg, |
| 989 | "cannot use '...' outside a vararg function"); | 983 | "cannot use '...' outside a vararg function"); |
| 990 | init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, lastparam, 1)); | 984 | init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 0, 1)); |
| 991 | break; | 985 | break; |
| 992 | } | 986 | } |
| 993 | case '{': { /* constructor */ | 987 | case '{': { /* constructor */ |
| @@ -1703,10 +1697,6 @@ static void mainfunc (LexState *ls, FuncState *fs) { | |||
| 1703 | expdesc v; | 1697 | expdesc v; |
| 1704 | open_func(ls, fs, &bl); | 1698 | open_func(ls, fs, &bl); |
| 1705 | setvararg(fs, 0); /* main function is always declared vararg */ | 1699 | setvararg(fs, 0); /* main function is always declared vararg */ |
| 1706 | fs->f->numparams = 0; | ||
| 1707 | new_localvarliteral(ls, "_ARG"); | ||
| 1708 | adjustlocalvars(ls, 1); | ||
| 1709 | luaK_reserveregs(fs, 1); /* reserve register for vararg */ | ||
| 1710 | init_exp(&v, VLOCAL, 0); /* create and... */ | 1700 | init_exp(&v, VLOCAL, 0); /* create and... */ |
| 1711 | newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ | 1701 | newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ |
| 1712 | luaX_next(ls); /* read first token */ | 1702 | luaX_next(ls); /* read first token */ |
