github.com/hirochachacha/plua@v0.0.0-20170217012138-c82f520cc725/testdata/lua-5.3.3-tests/code.lua (about)

     1  -- $Id: code.lua,v 1.41 2014/12/26 17:18:43 roberto Exp $
     2  
     3  if T==nil then
     4    (Message or print)('\n >>> testC not active: skipping opcode tests <<<\n')
     5    return
     6  end
     7  print "testing code generation and optimizations"
     8  
     9  
    10  -- this code gave an error for the code checker
    11  do
    12    local function f (a)
    13    for k,v,w in a do end
    14    end
    15  end
    16  
    17  
    18  -- testing reuse in constant table
    19  local function checkKlist (func, list)
    20    local k = T.listk(func)
    21    assert(#k == #list)
    22    for i = 1, #k do
    23      assert(k[i] == list[i] and math.type(k[i]) == math.type(list[i]))
    24    end
    25  end
    26  
    27  local function foo ()
    28    local a
    29    a = 3;
    30    a = 0; a = 0.0; a = -7 + 7
    31    a = 3.78/4; a = 3.78/4
    32    a = -3.78/4; a = 3.78/4; a = -3.78/4
    33    a = -3.79/4; a = 0.0; a = -0;
    34    a = 3; a = 3.0; a = 3; a = 3.0
    35  end
    36  
    37  checkKlist(foo, {3, 0, 0.0, 3.78/4, -3.78/4, -3.79/4, 3.0})
    38  
    39  
    40  -- testing opcodes
    41  
    42  function check (f, ...)
    43    local arg = {...}
    44    local c = T.listcode(f)
    45    for i=1, #arg do
    46      -- print(arg[i], c[i])
    47      assert(string.find(c[i], '- '..arg[i]..' *%d'))
    48    end
    49    assert(c[#arg+2] == nil)
    50  end
    51  
    52  
    53  function checkequal (a, b)
    54    a = T.listcode(a)
    55    b = T.listcode(b)
    56    for i = 1, #a do
    57      a[i] = string.gsub(a[i], '%b()', '')   -- remove line number
    58      b[i] = string.gsub(b[i], '%b()', '')   -- remove line number
    59      assert(a[i] == b[i])
    60    end
    61  end
    62  
    63  
    64  -- some basic instructions
    65  check(function ()
    66    (function () end){f()}
    67  end, 'CLOSURE', 'NEWTABLE', 'GETTABUP', 'CALL', 'SETLIST', 'CALL', 'RETURN')
    68  
    69  
    70  -- sequence of LOADNILs
    71  check(function ()
    72    local a,b,c
    73    local d; local e;
    74    local f,g,h;
    75    d = nil; d=nil; b=nil; a=nil; c=nil;
    76  end, 'LOADNIL', 'RETURN')
    77  
    78  check(function ()
    79    local a,b,c,d = 1,1,1,1
    80    d=nil;c=nil;b=nil;a=nil
    81  end, 'LOADK', 'LOADK', 'LOADK', 'LOADK', 'LOADNIL', 'RETURN')
    82  
    83  do
    84    local a,b,c,d = 1,1,1,1
    85    d=nil;c=nil;b=nil;a=nil
    86    assert(a == nil and b == nil and c == nil and d == nil)
    87  end
    88  
    89  
    90  -- single return
    91  check (function (a,b,c) return a end, 'RETURN')
    92  
    93  
    94  -- infinite loops
    95  check(function () while true do local a = -1 end end,
    96  'LOADK', 'JMP', 'RETURN')
    97  
    98  check(function () while 1 do local a = -1 end end,
    99  'LOADK', 'JMP', 'RETURN')
   100  
   101  check(function () repeat local x = 1 until true end,
   102  'LOADK', 'RETURN')
   103  
   104  
   105  -- concat optimization
   106  check(function (a,b,c,d) return a..b..c..d end,
   107    'MOVE', 'MOVE', 'MOVE', 'MOVE', 'CONCAT', 'RETURN')
   108  
   109  -- not
   110  check(function () return not not nil end, 'LOADBOOL', 'RETURN')
   111  check(function () return not not false end, 'LOADBOOL', 'RETURN')
   112  check(function () return not not true end, 'LOADBOOL', 'RETURN')
   113  check(function () return not not 1 end, 'LOADBOOL', 'RETURN')
   114  
   115  -- direct access to locals
   116  check(function ()
   117    local a,b,c,d
   118    a = b*2
   119    c[4], a[b] = -((a + d/-20.5 - a[b]) ^ a.x), b
   120  end,
   121    'LOADNIL',
   122    'MUL',
   123    'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETTABLE', 'POW',
   124      'UNM', 'SETTABLE', 'SETTABLE', 'RETURN')
   125  
   126  
   127  -- direct access to constants
   128  check(function ()
   129    local a,b
   130    a.x = 0
   131    a.x = b
   132    a[b] = 'y'
   133    a = 1 - a
   134    b = 1/a
   135    b = 5+4
   136    a[true] = false
   137  end,
   138    'LOADNIL',
   139    'SETTABLE', 'SETTABLE', 'SETTABLE', 'SUB', 'DIV', 'LOADK',
   140    'SETTABLE', 'RETURN')
   141  
   142  
   143  -- constant folding
   144  local function checkK (func, val)
   145    check(func, 'LOADK', 'RETURN')
   146    local k = T.listk(func)
   147    assert(#k == 1 and k[1] == val and math.type(k[1]) == math.type(val))
   148    assert(func() == val)
   149  end
   150  checkK(function () return 0.0 end, 0.0)
   151  checkK(function () return 0 end, 0)
   152  checkK(function () return -0//1 end, 0)
   153  checkK(function () return 3^-1 end, 1/3)
   154  checkK(function () return (1 + 1)^(50 + 50) end, 2^100)
   155  checkK(function () return (-2)^(31 - 2) end, -0x20000000 + 0.0)
   156  checkK(function () return (-3^0 + 5) // 3.0 end, 1.0)
   157  checkK(function () return -3 % 5 end, 2)
   158  checkK(function () return -((2.0^8 + -(-1)) % 8)/2 * 4 - 3 end, -5.0)
   159  checkK(function () return -((2^8 + -(-1)) % 8)//2 * 4 - 3 end, -7.0)
   160  checkK(function () return 0xF0.0 | 0xCC.0 ~ 0xAA & 0xFD end, 0xF4)
   161  checkK(function () return ~(~0xFF0 | 0xFF0) end, 0)
   162  checkK(function () return ~~-100024.0 end, -100024)
   163  checkK(function () return ((100 << 6) << -4) >> 2 end, 100)
   164  
   165  
   166  -- no foldings
   167  check(function () return -0.0 end, 'LOADK', 'UNM', 'RETURN')
   168  check(function () return 3/0 end, 'DIV', 'RETURN')
   169  check(function () return 0%0 end, 'MOD', 'RETURN')
   170  check(function () return -4//0 end, 'IDIV', 'RETURN')
   171  
   172  -- bug in constant folding for 5.1
   173  check(function () return -nil end, 'LOADNIL', 'UNM', 'RETURN')
   174  
   175  
   176  check(function ()
   177    local a,b,c
   178    b[c], a = c, b
   179    b[a], a = c, b
   180    a, b = c, a
   181    a = a
   182  end, 
   183    'LOADNIL',
   184    'MOVE', 'MOVE', 'SETTABLE',
   185    'MOVE', 'MOVE', 'MOVE', 'SETTABLE',
   186    'MOVE', 'MOVE', 'MOVE',
   187    -- no code for a = a
   188    'RETURN')
   189  
   190  
   191  -- x == nil , x ~= nil
   192  checkequal(function () if (a==nil) then a=1 end; if a~=nil then a=1 end end,
   193             function () if (a==9) then a=1 end; if a~=9 then a=1 end end)
   194  
   195  check(function () if a==nil then a=1 end end,
   196  'GETTABUP', 'EQ', 'JMP', 'SETTABUP', 'RETURN')
   197  
   198  -- de morgan
   199  checkequal(function () local a; if not (a or b) then b=a end end,
   200             function () local a; if (not a and not b) then b=a end end)
   201  
   202  checkequal(function (l) local a; return 0 <= a and a <= l end,
   203             function (l) local a; return not (not(a >= 0) or not(a <= l)) end)
   204  
   205  
   206  -- if-goto optimizations
   207  check(function (a)
   208          if a == 1 then goto l1
   209          elseif a == 2 then goto l2
   210          elseif a == 3 then goto l2
   211          else if a == 4 then goto l3
   212               else goto l3
   213               end
   214          end
   215          ::l1:: ::l2:: ::l3:: ::l4:: 
   216  end, 'EQ', 'JMP', 'EQ', 'JMP', 'EQ', 'JMP', 'EQ', 'JMP', 'JMP', 'RETURN')
   217  
   218  checkequal(
   219  function (a) while a < 10 do a = a + 1 end end,
   220  function (a) ::L2:: if not(a < 10) then goto L1 end; a = a + 1;
   221                  goto L2; ::L1:: end
   222  )
   223  
   224  checkequal(
   225  function (a) while a < 10 do a = a + 1 end end,
   226  function (a) while true do if not(a < 10) then break end; a = a + 1; end end
   227  )
   228  
   229  print 'OK'
   230