aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto I <roberto@inf.puc-rio.br>2025-09-24 18:33:08 -0300
committerRoberto I <roberto@inf.puc-rio.br>2025-09-24 18:33:08 -0300
commit25c54fe60e22d05cdfaa48c64372d354efa59547 (patch)
tree3ccaeded5e4363db358f73b7c8fc6b9f414a2f2a /lparser.c
parent0cc3c9447cca9abae9738ee77c24d88801c3916c (diff)
downloadlua-25c54fe60e22d05cdfaa48c64372d354efa59547.tar.gz
lua-25c54fe60e22d05cdfaa48c64372d354efa59547.tar.bz2
lua-25c54fe60e22d05cdfaa48c64372d354efa59547.zip
Optimization for vararg tables
A vararg table can be virtual. If the vararg table is used only as a base in indexing expressions, the code does not need to create an actual table for it. Instead, it compiles the indexing expressions into direct accesses to the internal vararg data.
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/lparser.c b/lparser.c
index 8b909f3d..408b8e21 100644
--- a/lparser.c
+++ b/lparser.c
@@ -279,7 +279,9 @@ static void init_var (FuncState *fs, expdesc *e, int vidx) {
279 279
280 280
281/* 281/*
282** Raises an error if variable described by 'e' is read only 282** Raises an error if variable described by 'e' is read only; moreover,
283** if 'e' is t[exp] where t is the vararg parameter, change it to index
284** a real table. (Virtual vararg tables cannot be changed.)
283*/ 285*/
284static void check_readonly (LexState *ls, expdesc *e) { 286static void check_readonly (LexState *ls, expdesc *e) {
285 FuncState *fs = ls->fs; 287 FuncState *fs = ls->fs;
@@ -301,6 +303,10 @@ static void check_readonly (LexState *ls, expdesc *e) {
301 varname = up->name; 303 varname = up->name;
302 break; 304 break;
303 } 305 }
306 case VVARGIND: {
307 fs->f->flag |= PF_VATAB; /* function will need a vararg table */
308 e->k = VINDEXED;
309 } /* FALLTHROUGH */
304 case VINDEXUP: case VINDEXSTR: case VINDEXED: { /* global variable */ 310 case VINDEXUP: case VINDEXSTR: case VINDEXED: { /* global variable */
305 if (e->u.ind.ro) /* read-only? */ 311 if (e->u.ind.ro) /* read-only? */
306 varname = tsvalue(&fs->f->k[e->u.ind.keystr]); 312 varname = tsvalue(&fs->f->k[e->u.ind.keystr]);
@@ -1073,7 +1079,7 @@ static void parlist (LexState *ls) {
1073 case TK_DOTS: { 1079 case TK_DOTS: {
1074 varargk |= PF_ISVARARG; 1080 varargk |= PF_ISVARARG;
1075 luaX_next(ls); 1081 luaX_next(ls);
1076 if (testnext(ls, '=')) { 1082 if (testnext(ls, '|')) {
1077 new_varkind(ls, str_checkname(ls), RDKVAVAR); 1083 new_varkind(ls, str_checkname(ls), RDKVAVAR);
1078 varargk |= PF_VAVAR; 1084 varargk |= PF_VAVAR;
1079 } 1085 }