diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-05-11 11:51:58 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-05-11 11:51:58 -0300 |
commit | 5b1ab8efdcb7b48cab8148a407266c467d57114c (patch) | |
tree | 1ec673c0171801c24854220e0fbc7ef6c19c7ed1 | |
parent | 7ade1557627cf3f09c23c892ee227b7386f28414 (diff) | |
download | lua-5b1ab8efdcb7b48cab8148a407266c467d57114c.tar.gz lua-5b1ab8efdcb7b48cab8148a407266c467d57114c.tar.bz2 lua-5b1ab8efdcb7b48cab8148a407266c467d57114c.zip |
'expdesc' doesn't depend on 'actvar' for var. info.
In preparation for 'global *', the structure 'expdesc' does not point
to 'actvar.arr' for information about global variables.
-rw-r--r-- | lcode.c | 9 | ||||
-rw-r--r-- | lparser.c | 15 | ||||
-rw-r--r-- | lparser.h | 16 |
3 files changed, 23 insertions, 17 deletions
@@ -753,10 +753,11 @@ void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { | |||
753 | /* | 753 | /* |
754 | ** Convert a VKSTR to a VK | 754 | ** Convert a VKSTR to a VK |
755 | */ | 755 | */ |
756 | static void str2K (FuncState *fs, expdesc *e) { | 756 | static int str2K (FuncState *fs, expdesc *e) { |
757 | lua_assert(e->k == VKSTR); | 757 | lua_assert(e->k == VKSTR); |
758 | e->u.info = stringK(fs, e->u.strval); | 758 | e->u.info = stringK(fs, e->u.strval); |
759 | e->k = VK; | 759 | e->k = VK; |
760 | return e->u.info; | ||
760 | } | 761 | } |
761 | 762 | ||
762 | 763 | ||
@@ -1307,8 +1308,9 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { | |||
1307 | ** values in registers. | 1308 | ** values in registers. |
1308 | */ | 1309 | */ |
1309 | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { | 1310 | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { |
1311 | int keystr = -1; | ||
1310 | if (k->k == VKSTR) | 1312 | if (k->k == VKSTR) |
1311 | str2K(fs, k); | 1313 | keystr = str2K(fs, k); |
1312 | lua_assert(!hasjumps(t) && | 1314 | lua_assert(!hasjumps(t) && |
1313 | (t->k == VLOCAL || t->k == VNONRELOC || t->k == VUPVAL)); | 1315 | (t->k == VLOCAL || t->k == VNONRELOC || t->k == VUPVAL)); |
1314 | if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non 'Kstr'? */ | 1316 | if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non 'Kstr'? */ |
@@ -1336,7 +1338,8 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { | |||
1336 | t->k = VINDEXED; | 1338 | t->k = VINDEXED; |
1337 | } | 1339 | } |
1338 | } | 1340 | } |
1339 | t->u.ind.vidx = -1; /* by default, not a declared global */ | 1341 | t->u.ind.keystr = keystr; /* string index in 'k' */ |
1342 | t->u.ind.ro = 0; /* by default, not read-only */ | ||
1340 | } | 1343 | } |
1341 | 1344 | ||
1342 | 1345 | ||
@@ -304,11 +304,9 @@ static void check_readonly (LexState *ls, expdesc *e) { | |||
304 | varname = up->name; | 304 | varname = up->name; |
305 | break; | 305 | break; |
306 | } | 306 | } |
307 | case VINDEXUP: case VINDEXSTR: case VINDEXED: { | 307 | case VINDEXUP: case VINDEXSTR: case VINDEXED: { /* global variable */ |
308 | int vidx = e->u.ind.vidx; | 308 | if (e->u.ind.ro) /* read-only? */ |
309 | /* is it a read-only declared global? */ | 309 | varname = tsvalue(&fs->f->k[e->u.ind.keystr]); |
310 | if (vidx != -1 && ls->dyd->actvar.arr[vidx].vd.kind == GDKCONST) | ||
311 | varname = ls->dyd->actvar.arr[vidx].vd.name; | ||
312 | break; | 310 | break; |
313 | } | 311 | } |
314 | default: | 312 | default: |
@@ -483,8 +481,6 @@ static void buildvar (LexState *ls, TString *varname, expdesc *var) { | |||
483 | if (var->k == VGLOBAL) { /* global name? */ | 481 | if (var->k == VGLOBAL) { /* global name? */ |
484 | expdesc key; | 482 | expdesc key; |
485 | int info = var->u.info; | 483 | int info = var->u.info; |
486 | lua_assert(info == -1 || | ||
487 | eqstr(ls->dyd->actvar.arr[info].vd.name, varname)); | ||
488 | /* global by default in the scope of a global declaration? */ | 484 | /* global by default in the scope of a global declaration? */ |
489 | if (info == -1 && fs->bl->globdec) | 485 | if (info == -1 && fs->bl->globdec) |
490 | luaK_semerror(ls, "variable '%s' not declared", getstr(varname)); | 486 | luaK_semerror(ls, "variable '%s' not declared", getstr(varname)); |
@@ -495,7 +491,10 @@ static void buildvar (LexState *ls, TString *varname, expdesc *var) { | |||
495 | luaK_exp2anyregup(fs, var); /* but could be a constant */ | 491 | luaK_exp2anyregup(fs, var); /* but could be a constant */ |
496 | codestring(&key, varname); /* key is variable name */ | 492 | codestring(&key, varname); /* key is variable name */ |
497 | luaK_indexed(fs, var, &key); /* env[varname] */ | 493 | luaK_indexed(fs, var, &key); /* env[varname] */ |
498 | var->u.ind.vidx = cast_short(info); /* mark it as a declared global */ | 494 | if (info != -1 && ls->dyd->actvar.arr[info].vd.kind == GDKCONST) |
495 | var->u.ind.ro = 1; /* mark variable as read-only */ | ||
496 | else /* anyway must be a global */ | ||
497 | lua_assert(info == -1 || ls->dyd->actvar.arr[info].vd.kind == GDKREG); | ||
499 | } | 498 | } |
500 | } | 499 | } |
501 | 500 | ||
@@ -45,16 +45,19 @@ typedef enum { | |||
45 | info = absolute index in 'actvar.arr' */ | 45 | info = absolute index in 'actvar.arr' */ |
46 | VINDEXED, /* indexed variable; | 46 | VINDEXED, /* indexed variable; |
47 | ind.t = table register; | 47 | ind.t = table register; |
48 | ind.idx = key's R index */ | 48 | ind.idx = key's R index; |
49 | ind.ro = true if it represents a read-only global; | ||
50 | ind.keystr = if key is a string, index in 'k' of that string; | ||
51 | -1 if key is not a string */ | ||
49 | VINDEXUP, /* indexed upvalue; | 52 | VINDEXUP, /* indexed upvalue; |
50 | ind.t = table upvalue; | 53 | ind.idx = key's K index; |
51 | ind.idx = key's K index */ | 54 | ind.* as in VINDEXED */ |
52 | VINDEXI, /* indexed variable with constant integer; | 55 | VINDEXI, /* indexed variable with constant integer; |
53 | ind.t = table register; | 56 | ind.t = table register; |
54 | ind.idx = key's value */ | 57 | ind.idx = key's value */ |
55 | VINDEXSTR, /* indexed variable with literal string; | 58 | VINDEXSTR, /* indexed variable with literal string; |
56 | ind.t = table register; | 59 | ind.idx = key's K index; |
57 | ind.idx = key's K index */ | 60 | ind.* as in VINDEXED */ |
58 | VJMP, /* expression is a test/comparison; | 61 | VJMP, /* expression is a test/comparison; |
59 | info = pc of corresponding jump instruction */ | 62 | info = pc of corresponding jump instruction */ |
60 | VRELOC, /* expression can put result in any register; | 63 | VRELOC, /* expression can put result in any register; |
@@ -77,8 +80,9 @@ typedef struct expdesc { | |||
77 | int info; /* for generic use */ | 80 | int info; /* for generic use */ |
78 | struct { /* for indexed variables */ | 81 | struct { /* for indexed variables */ |
79 | short idx; /* index (R or "long" K) */ | 82 | short idx; /* index (R or "long" K) */ |
80 | short vidx; /* index in 'actvar.arr' or -1 if not a declared global */ | ||
81 | lu_byte t; /* table (register or upvalue) */ | 83 | lu_byte t; /* table (register or upvalue) */ |
84 | lu_byte ro; /* true if variable is read-only */ | ||
85 | int keystr; /* index in 'k' of string key, or -1 if not a string */ | ||
82 | } ind; | 86 | } ind; |
83 | struct { /* for local variables */ | 87 | struct { /* for local variables */ |
84 | lu_byte ridx; /* register holding the variable */ | 88 | lu_byte ridx; /* register holding the variable */ |