Selaa lähdekoodia

Fixed small issue with constant propagation

Constants directly assigned to other constants were not propagating:
For instance, in
  local <const> k1 = 10
  local <const> k2 = k1
'k2' were not treated as a compile-time constant.
Roberto Ierusalimschy 6 vuotta sitten
vanhempi
commit
8082906c05
2 muutettua tiedostoa jossa 21 lisäystä ja 7 poistoa
  1. 15 3
      lcode.c
  2. 6 4
      testes/code.lua

+ 15 - 3
lcode.c

@@ -67,6 +67,15 @@ static int tonumeral (const expdesc *e, TValue *v) {
 }
 
 
+/*
+** Get the constant value from a constant expression
+*/
+static TValue *const2val (FuncState *fs, const expdesc *e) {
+  lua_assert(e->k == VCONST);
+  return &fs->ls->dyd->actvar.arr[e->u.info].k;
+}
+
+
 /*
 ** If expression is a constant, fills 'v' with its value
 ** and returns 1. Otherwise, returns 0.
@@ -85,6 +94,10 @@ int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v) {
       setsvalue(fs->ls->L, v, e->u.strval);
       return 1;
     }
+    case VCONST: {
+      setobj(fs->ls->L, v, const2val(fs, e));
+      return 1;
+    }
     default: return tonumeral(e, v);
   }
 }
@@ -730,14 +743,13 @@ void luaK_setoneret (FuncState *fs, expdesc *e) {
 
 
 /*
-** Ensure that expression 'e' is not a variable.
+** Ensure that expression 'e' is not a variable (nor a constant).
 ** (Expression still may have jump lists.)
 */
 void luaK_dischargevars (FuncState *fs, expdesc *e) {
   switch (e->k) {
     case VCONST: {
-      TValue *val = &fs->ls->dyd->actvar.arr[e->u.info].k;
-      const2exp(val, e);
+      const2exp(const2val(fs, e), e);
       break;
     }
     case VLOCAL: {  /* already in a register */

+ 6 - 4
testes/code.lua

@@ -8,7 +8,8 @@ end
 print "testing code generation and optimizations"
 
 -- to test constant propagation
-local <const> k0 = 0
+local <const> k0aux = 0
+local <const> k0 = k0aux
 local <const> k1 = 1
 local <const> k3 = 3
 local <const> k6 = k3 + (k3 << k0)
@@ -410,8 +411,9 @@ checkequal(function () return 6 and true or nil end,
 
 
 do   -- string constants
+  local <const> k0 = "00000000000000000000000000000000000000000000000000"
   local function f1 ()
-    local <const> k = "00000000000000000000000000000000000000000000000000"
+    local <const> k = k0
     return function ()
              return function () return k end
            end
@@ -419,8 +421,8 @@ do   -- string constants
 
   local f2 = f1()
   local f3 = f2()
-  assert(f3() == string.rep("0", 50))
-  checkK(f3, f3())
+  assert(f3() == k0)
+  checkK(f3, k0)
   -- string is not needed by other functions
   assert(T.listk(f1)[1] == nil)
   assert(T.listk(f2)[1] == nil)