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 */ |