aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c35
-rw-r--r--lcode.h1
-rw-r--r--lparser.c14
-rw-r--r--lparser.h5
-rw-r--r--testes/code.lua17
5 files changed, 54 insertions, 18 deletions
diff --git a/lcode.c b/lcode.c
index e57ad284..40efcff3 100644
--- a/lcode.c
+++ b/lcode.c
@@ -81,9 +81,8 @@ int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v) {
81 case VNIL: 81 case VNIL:
82 setnilvalue(v); 82 setnilvalue(v);
83 return 1; 83 return 1;
84 case VK: { 84 case VKSTR: {
85 TValue *k = &fs->f->k[e->u.info]; 85 setsvalue(fs->ls->L, v, e->u.strval);
86 setobj(fs->ls->L, v, k);
87 return 1; 86 return 1;
88 } 87 }
89 default: return tonumeral(e, v); 88 default: return tonumeral(e, v);
@@ -561,7 +560,7 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
561/* 560/*
562** Add a string to list of constants and return its index. 561** Add a string to list of constants and return its index.
563*/ 562*/
564int luaK_stringK (FuncState *fs, TString *s) { 563static int stringK (FuncState *fs, TString *s) {
565 TValue o; 564 TValue o;
566 setsvalue(fs->ls->L, &o, s); 565 setsvalue(fs->ls->L, &o, s);
567 return addk(fs, &o, &o); /* use string itself as key */ 566 return addk(fs, &o, &o); /* use string itself as key */
@@ -656,7 +655,7 @@ static void luaK_float (FuncState *fs, int reg, lua_Number f) {
656/* 655/*
657** Convert a constant in 'v' into an expression description 'e' 656** Convert a constant in 'v' into an expression description 'e'
658*/ 657*/
659static void const2exp (FuncState *fs, TValue *v, expdesc *e) { 658static void const2exp (TValue *v, expdesc *e) {
660 switch (ttypetag(v)) { 659 switch (ttypetag(v)) {
661 case LUA_TNUMINT: 660 case LUA_TNUMINT:
662 e->k = VKINT; e->u.ival = ivalue(v); 661 e->k = VKINT; e->u.ival = ivalue(v);
@@ -671,7 +670,7 @@ static void const2exp (FuncState *fs, TValue *v, expdesc *e) {
671 e->k = VNIL; 670 e->k = VNIL;
672 break; 671 break;
673 case LUA_TSHRSTR: case LUA_TLNGSTR: 672 case LUA_TSHRSTR: case LUA_TLNGSTR:
674 e->k = VK; e->u.info = luaK_stringK(fs, tsvalue(v)); 673 e->k = VKSTR; e->u.strval = tsvalue(v);
675 break; 674 break;
676 default: lua_assert(0); 675 default: lua_assert(0);
677 } 676 }
@@ -697,6 +696,16 @@ void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
697 696
698 697
699/* 698/*
699** Convert a VKSTR to a VK
700*/
701static void str2K (FuncState *fs, expdesc *e) {
702 lua_assert(e->k == VKSTR);
703 e->u.info = stringK(fs, e->u.strval);
704 e->k = VK;
705}
706
707
708/*
700** Fix an expression to return one result. 709** Fix an expression to return one result.
701** If expression is not a multi-ret expression (function call or 710** If expression is not a multi-ret expression (function call or
702** vararg), it already returns one result, so nothing needs to be done. 711** vararg), it already returns one result, so nothing needs to be done.
@@ -728,7 +737,7 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
728 switch (e->k) { 737 switch (e->k) {
729 case VCONST: { 738 case VCONST: {
730 TValue *val = &fs->ls->dyd->actvar.arr[e->u.info].k; 739 TValue *val = &fs->ls->dyd->actvar.arr[e->u.info].k;
731 const2exp(fs, val, e); 740 const2exp(val, e);
732 break; 741 break;
733 } 742 }
734 case VLOCAL: { /* already in a register */ 743 case VLOCAL: { /* already in a register */
@@ -789,6 +798,9 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
789 luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); 798 luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
790 break; 799 break;
791 } 800 }
801 case VKSTR: {
802 str2K(fs, e);
803 } /* FALLTHROUGH */
792 case VK: { 804 case VK: {
793 luaK_codek(fs, reg, e->u.info); 805 luaK_codek(fs, reg, e->u.info);
794 break; 806 break;
@@ -949,6 +961,7 @@ static int luaK_exp2K (FuncState *fs, expdesc *e) {
949 case VNIL: info = nilK(fs); break; 961 case VNIL: info = nilK(fs); break;
950 case VKINT: info = luaK_intK(fs, e->u.ival); break; 962 case VKINT: info = luaK_intK(fs, e->u.ival); break;
951 case VKFLT: info = luaK_numberK(fs, e->u.nval); break; 963 case VKFLT: info = luaK_numberK(fs, e->u.nval); break;
964 case VKSTR: info = stringK(fs, e->u.strval); break;
952 case VK: info = e->u.info; break; 965 case VK: info = e->u.info; break;
953 default: return 0; /* not a constant */ 966 default: return 0; /* not a constant */
954 } 967 }
@@ -1083,7 +1096,7 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
1083 pc = e->u.info; /* save jump position */ 1096 pc = e->u.info; /* save jump position */
1084 break; 1097 break;
1085 } 1098 }
1086 case VK: case VKFLT: case VKINT: case VTRUE: { 1099 case VK: case VKFLT: case VKINT: case VKSTR: case VTRUE: {
1087 pc = NO_JUMP; /* always true; do nothing */ 1100 pc = NO_JUMP; /* always true; do nothing */
1088 break; 1101 break;
1089 } 1102 }
@@ -1133,7 +1146,7 @@ static void codenot (FuncState *fs, expdesc *e) {
1133 e->k = VTRUE; /* true == not nil == not false */ 1146 e->k = VTRUE; /* true == not nil == not false */
1134 break; 1147 break;
1135 } 1148 }
1136 case VK: case VKFLT: case VKINT: case VTRUE: { 1149 case VK: case VKFLT: case VKINT: case VKSTR: case VTRUE: {
1137 e->k = VFALSE; /* false == not "x" == not 0.5 == not 1 == not true */ 1150 e->k = VFALSE; /* false == not "x" == not 0.5 == not 1 == not true */
1138 break; 1151 break;
1139 } 1152 }
@@ -1219,9 +1232,11 @@ static int isSCnumber (expdesc *e, lua_Integer *i, int *isfloat) {
1219** values in registers. 1232** values in registers.
1220*/ 1233*/
1221void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { 1234void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
1235 if (k->k == VKSTR)
1236 str2K(fs, k);
1222 lua_assert(!hasjumps(t) && 1237 lua_assert(!hasjumps(t) &&
1223 (t->k == VLOCAL || t->k == VNONRELOC || t->k == VUPVAL)); 1238 (t->k == VLOCAL || t->k == VNONRELOC || t->k == VUPVAL));
1224 if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non string? */ 1239 if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non 'Kstr'? */
1225 luaK_exp2anyreg(fs, t); /* put it in a register */ 1240 luaK_exp2anyreg(fs, t); /* put it in a register */
1226 if (t->k == VUPVAL) { 1241 if (t->k == VUPVAL) {
1227 t->u.ind.t = t->u.info; /* upvalue index */ 1242 t->u.ind.t = t->u.info; /* upvalue index */
diff --git a/lcode.h b/lcode.h
index 0c12bb64..8cecd538 100644
--- a/lcode.h
+++ b/lcode.h
@@ -62,7 +62,6 @@ LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
62LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); 62LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
63LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); 63LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
64LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); 64LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
65LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
66LUAI_FUNC void luaK_int (FuncState *fs, int reg, lua_Integer n); 65LUAI_FUNC void luaK_int (FuncState *fs, int reg, lua_Integer n);
67LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); 66LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
68LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); 67LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
diff --git a/lparser.c b/lparser.c
index ea810006..b70c609e 100644
--- a/lparser.c
+++ b/lparser.c
@@ -156,13 +156,15 @@ static void init_exp (expdesc *e, expkind k, int i) {
156} 156}
157 157
158 158
159static void codestring (LexState *ls, expdesc *e, TString *s) { 159static void codestring (expdesc *e, TString *s) {
160 init_exp(e, VK, luaK_stringK(ls->fs, s)); 160 e->f = e->t = NO_JUMP;
161 e->k = VKSTR;
162 e->u.strval = s;
161} 163}
162 164
163 165
164static void codename (LexState *ls, expdesc *e) { 166static void codename (LexState *ls, expdesc *e) {
165 codestring(ls, e, str_checkname(ls)); 167 codestring(e, str_checkname(ls));
166} 168}
167 169
168 170
@@ -445,7 +447,7 @@ static void singlevar (LexState *ls, expdesc *var) {
445 expdesc key; 447 expdesc key;
446 singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ 448 singlevaraux(fs, ls->envn, var, 1); /* get environment variable */
447 lua_assert(var->k != VVOID); /* this one must exist */ 449 lua_assert(var->k != VVOID); /* this one must exist */
448 codestring(ls, &key, varname); /* key is variable name */ 450 codestring(&key, varname); /* key is variable name */
449 luaK_indexed(fs, var, &key); /* env[varname] */ 451 luaK_indexed(fs, var, &key); /* env[varname] */
450 } 452 }
451} 453}
@@ -1019,7 +1021,7 @@ static void funcargs (LexState *ls, expdesc *f, int line) {
1019 break; 1021 break;
1020 } 1022 }
1021 case TK_STRING: { /* funcargs -> STRING */ 1023 case TK_STRING: { /* funcargs -> STRING */
1022 codestring(ls, &args, ls->t.seminfo.ts); 1024 codestring(&args, ls->t.seminfo.ts);
1023 luaX_next(ls); /* must use 'seminfo' before 'next' */ 1025 luaX_next(ls); /* must use 'seminfo' before 'next' */
1024 break; 1026 break;
1025 } 1027 }
@@ -1127,7 +1129,7 @@ static void simpleexp (LexState *ls, expdesc *v) {
1127 break; 1129 break;
1128 } 1130 }
1129 case TK_STRING: { 1131 case TK_STRING: {
1130 codestring(ls, v, ls->t.seminfo.ts); 1132 codestring(v, ls->t.seminfo.ts);
1131 break; 1133 break;
1132 } 1134 }
1133 case TK_NIL: { 1135 case TK_NIL: {
diff --git a/lparser.h b/lparser.h
index d9b734bf..f528f013 100644
--- a/lparser.h
+++ b/lparser.h
@@ -30,7 +30,9 @@ typedef enum {
30 VFALSE, /* constant false */ 30 VFALSE, /* constant false */
31 VK, /* constant in 'k'; info = index of constant in 'k' */ 31 VK, /* constant in 'k'; info = index of constant in 'k' */
32 VKFLT, /* floating constant; nval = numerical float value */ 32 VKFLT, /* floating constant; nval = numerical float value */
33 VKINT, /* integer constant; nval = numerical integer value */ 33 VKINT, /* integer constant; ival = numerical integer value */
34 VKSTR, /* string constant; strval = TString address;
35 (string is fixed by the lexer) */
34 VNONRELOC, /* expression has its value in a fixed register; 36 VNONRELOC, /* expression has its value in a fixed register;
35 info = result register */ 37 info = result register */
36 VLOCAL, /* local variable; var.ridx = local register; 38 VLOCAL, /* local variable; var.ridx = local register;
@@ -67,6 +69,7 @@ typedef struct expdesc {
67 union { 69 union {
68 lua_Integer ival; /* for VKINT */ 70 lua_Integer ival; /* for VKINT */
69 lua_Number nval; /* for VKFLT */ 71 lua_Number nval; /* for VKFLT */
72 TString *strval; /* for VKSTR */
70 int info; /* for generic use */ 73 int info; /* for generic use */
71 struct { /* for indexed variables */ 74 struct { /* for indexed variables */
72 short idx; /* index (R or "long" K) */ 75 short idx; /* index (R or "long" K) */
diff --git a/testes/code.lua b/testes/code.lua
index b2702c61..b5091458 100644
--- a/testes/code.lua
+++ b/testes/code.lua
@@ -409,5 +409,22 @@ checkequal(function () return 6 and true or nil end,
409 function () return k6 and kTrue or kNil end) 409 function () return k6 and kTrue or kNil end)
410 410
411 411
412do -- string constants
413 local function f1 ()
414 local <const> k = "00000000000000000000000000000000000000000000000000"
415 return function ()
416 return function () return k end
417 end
418 end
419
420 local f2 = f1()
421 local f3 = f2()
422 assert(f3() == string.rep("0", 50))
423 checkK(f3, f3())
424 -- string is not needed by other functions
425 assert(T.listk(f1)[1] == nil)
426 assert(T.listk(f2)[1] == nil)
427end
428
412print 'OK' 429print 'OK'
413 430