diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-07 13:18:04 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-07 13:18:04 -0200 |
commit | 318a9a5859826d7af0294664e206236fc8814319 (patch) | |
tree | 31a00af286880036e5ef165fbbdaf7df9a04cfc1 /lparser.c | |
parent | 73d797ce7ea4c547cb97e39633a71a242c7356c8 (diff) | |
download | lua-318a9a5859826d7af0294664e206236fc8814319.tar.gz lua-318a9a5859826d7af0294664e206236fc8814319.tar.bz2 lua-318a9a5859826d7af0294664e206236fc8814319.zip |
new opcode 'PREPVARARG'
(avoids test for vararg function in all function calls)
Diffstat (limited to 'lparser.c')
-rw-r--r-- | lparser.c | 22 |
1 files changed, 16 insertions, 6 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 2.174 2017/12/18 17:49:31 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 2.175 2017/12/22 14:16:46 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 | */ |
@@ -759,12 +759,18 @@ static void constructor (LexState *ls, expdesc *t) { | |||
759 | /* }====================================================================== */ | 759 | /* }====================================================================== */ |
760 | 760 | ||
761 | 761 | ||
762 | static void setvararg (FuncState *fs, int nparams) { | ||
763 | fs->f->is_vararg = 1; | ||
764 | luaK_codeABC(fs, OP_PREPVARARG, nparams, 0, 0); | ||
765 | } | ||
766 | |||
762 | 767 | ||
763 | static void parlist (LexState *ls) { | 768 | static void parlist (LexState *ls) { |
764 | /* parlist -> [ param { ',' param } ] */ | 769 | /* parlist -> [ param { ',' param } ] */ |
765 | FuncState *fs = ls->fs; | 770 | FuncState *fs = ls->fs; |
766 | Proto *f = fs->f; | 771 | Proto *f = fs->f; |
767 | int nparams = 0; | 772 | int nparams = 0; |
773 | int isvararg = 0; | ||
768 | if (ls->t.token != ')') { /* is 'parlist' not empty? */ | 774 | if (ls->t.token != ')') { /* is 'parlist' not empty? */ |
769 | do { | 775 | do { |
770 | switch (ls->t.token) { | 776 | switch (ls->t.token) { |
@@ -779,17 +785,21 @@ static void parlist (LexState *ls) { | |||
779 | new_localvar(ls, str_checkname(ls)); | 785 | new_localvar(ls, str_checkname(ls)); |
780 | else | 786 | else |
781 | new_localvarliteral(ls, "_ARG"); | 787 | new_localvarliteral(ls, "_ARG"); |
782 | f->is_vararg = 1; /* declared vararg */ | ||
783 | nparams++; | 788 | nparams++; |
789 | isvararg = 1; | ||
784 | break; | 790 | break; |
785 | } | 791 | } |
786 | default: luaX_syntaxerror(ls, "<name> or '...' expected"); | 792 | default: luaX_syntaxerror(ls, "<name> or '...' expected"); |
787 | } | 793 | } |
788 | } while (!f->is_vararg && testnext(ls, ',')); | 794 | } while (!isvararg && testnext(ls, ',')); |
789 | } | 795 | } |
790 | adjustlocalvars(ls, nparams); | 796 | adjustlocalvars(ls, nparams); |
791 | f->numparams = cast_byte(fs->nactvar) - f->is_vararg; | 797 | f->numparams = cast_byte(fs->nactvar); |
792 | luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ | 798 | if (isvararg) { |
799 | f->numparams--; /* exclude vararg parameter */ | ||
800 | setvararg(fs, f->numparams); /* declared vararg */ | ||
801 | } | ||
802 | luaK_reserveregs(fs, fs->nactvar); /* reserve registers for parameters */ | ||
793 | } | 803 | } |
794 | 804 | ||
795 | 805 | ||
@@ -1692,7 +1702,7 @@ static void mainfunc (LexState *ls, FuncState *fs) { | |||
1692 | BlockCnt bl; | 1702 | BlockCnt bl; |
1693 | expdesc v; | 1703 | expdesc v; |
1694 | open_func(ls, fs, &bl); | 1704 | open_func(ls, fs, &bl); |
1695 | fs->f->is_vararg = 1; /* main function is always declared vararg */ | 1705 | setvararg(fs, 0); /* main function is always declared vararg */ |
1696 | fs->f->numparams = 0; | 1706 | fs->f->numparams = 0; |
1697 | new_localvarliteral(ls, "_ARG"); | 1707 | new_localvarliteral(ls, "_ARG"); |
1698 | adjustlocalvars(ls, 1); | 1708 | adjustlocalvars(ls, 1); |