diff options
-rw-r--r-- | lcode.c | 35 | ||||
-rw-r--r-- | lcode.h | 1 | ||||
-rw-r--r-- | lparser.c | 14 | ||||
-rw-r--r-- | lparser.h | 5 | ||||
-rw-r--r-- | testes/code.lua | 17 |
5 files changed, 54 insertions, 18 deletions
@@ -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 | */ |
564 | int luaK_stringK (FuncState *fs, TString *s) { | 563 | static 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 | */ |
659 | static void const2exp (FuncState *fs, TValue *v, expdesc *e) { | 658 | static 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 | */ | ||
701 | static 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 | */ |
1221 | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { | 1234 | void 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 */ |
@@ -62,7 +62,6 @@ LUAI_FUNC void luaK_fixline (FuncState *fs, int line); | |||
62 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); | 62 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); |
63 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); | 63 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); |
64 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); | 64 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); |
65 | LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); | ||
66 | LUAI_FUNC void luaK_int (FuncState *fs, int reg, lua_Integer n); | 65 | LUAI_FUNC void luaK_int (FuncState *fs, int reg, lua_Integer n); |
67 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); | 66 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); |
68 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); | 67 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); |
@@ -156,13 +156,15 @@ static void init_exp (expdesc *e, expkind k, int i) { | |||
156 | } | 156 | } |
157 | 157 | ||
158 | 158 | ||
159 | static void codestring (LexState *ls, expdesc *e, TString *s) { | 159 | static 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 | ||
164 | static void codename (LexState *ls, expdesc *e) { | 166 | static 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: { |
@@ -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 | ||
412 | do -- 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) | ||
427 | end | ||
428 | |||
412 | print 'OK' | 429 | print 'OK' |
413 | 430 | ||