github.com/awirix/lua@v1.6.0/_lua5.1-tests/code.lua (about)

     1  
     2  if T==nil then
     3    (Message or print)('\a\n >>> testC not active: skipping opcode tests <<<\n\a')
     4    return
     5  end
     6  print "testing code generation and optimizations"
     7  
     8  
     9  -- this code gave an error for the code checker
    10  do
    11    local function f (a)
    12    for k,v,w in a do end
    13    end
    14  end
    15  
    16  
    17  function check (f, ...)
    18    local c = T.listcode(f)
    19    for i=1, arg.n do
    20      -- print(arg[i], c[i])
    21      assert(string.find(c[i], '- '..arg[i]..' *%d'))
    22    end
    23    assert(c[arg.n+2] == nil)
    24  end
    25  
    26  
    27  function checkequal (a, b)
    28    a = T.listcode(a)
    29    b = T.listcode(b)
    30    for i = 1, table.getn(a) do
    31      a[i] = string.gsub(a[i], '%b()', '')   -- remove line number
    32      b[i] = string.gsub(b[i], '%b()', '')   -- remove line number
    33      assert(a[i] == b[i])
    34    end
    35  end
    36  
    37  
    38  -- some basic instructions
    39  check(function ()
    40    (function () end){f()}
    41  end, 'CLOSURE', 'NEWTABLE', 'GETGLOBAL', 'CALL', 'SETLIST', 'CALL', 'RETURN')
    42  
    43  
    44  -- sequence of LOADNILs
    45  check(function ()
    46    local a,b,c
    47    local d; local e;
    48    a = nil; d=nil
    49  end, 'RETURN')
    50  
    51  
    52  -- single return
    53  check (function (a,b,c) return a end, 'RETURN')
    54  
    55  
    56  -- infinite loops
    57  check(function () while true do local a = -1 end end,
    58  'LOADK', 'JMP', 'RETURN')
    59  
    60  check(function () while 1 do local a = -1 end end,
    61  'LOADK', 'JMP', 'RETURN')
    62  
    63  check(function () repeat local x = 1 until false end,
    64  'LOADK', 'JMP', 'RETURN')
    65  
    66  check(function () repeat local x until nil end,
    67  'LOADNIL', 'JMP', 'RETURN')
    68  
    69  check(function () repeat local x = 1 until true end,
    70  'LOADK', 'RETURN')
    71  
    72  
    73  -- concat optimization
    74  check(function (a,b,c,d) return a..b..c..d end,
    75    'MOVE', 'MOVE', 'MOVE', 'MOVE', 'CONCAT', 'RETURN')
    76  
    77  -- not
    78  check(function () return not not nil end, 'LOADBOOL', 'RETURN')
    79  check(function () return not not false end, 'LOADBOOL', 'RETURN')
    80  check(function () return not not true end, 'LOADBOOL', 'RETURN')
    81  check(function () return not not 1 end, 'LOADBOOL', 'RETURN')
    82  
    83  -- direct access to locals
    84  check(function ()
    85    local a,b,c,d
    86    a = b*2
    87    c[4], a[b] = -((a + d/-20.5 - a[b]) ^ a.x), b
    88  end,
    89    'MUL',
    90    'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETTABLE', 'POW',
    91      'UNM', 'SETTABLE', 'SETTABLE', 'RETURN')
    92  
    93  
    94  -- direct access to constants
    95  check(function ()
    96    local a,b
    97    a.x = 0
    98    a.x = b
    99    a[b] = 'y'
   100    a = 1 - a
   101    b = 1/a
   102    b = 5+4
   103    a[true] = false
   104  end,
   105    'SETTABLE', 'SETTABLE', 'SETTABLE', 'SUB', 'DIV', 'LOADK',
   106    'SETTABLE', 'RETURN')
   107  
   108  local function f () return -((2^8 + -(-1)) % 8)/2 * 4 - 3 end
   109  
   110  check(f, 'LOADK', 'RETURN')
   111  assert(f() == -5)
   112  
   113  check(function ()
   114    local a,b,c
   115    b[c], a = c, b
   116    b[a], a = c, b
   117    a, b = c, a
   118    a = a
   119  end, 
   120    'MOVE', 'MOVE', 'SETTABLE',
   121    'MOVE', 'MOVE', 'MOVE', 'SETTABLE',
   122    'MOVE', 'MOVE', 'MOVE',
   123    -- no code for a = a
   124    'RETURN')
   125  
   126  
   127  -- x == nil , x ~= nil
   128  checkequal(function () if (a==nil) then a=1 end; if a~=nil then a=1 end end,
   129             function () if (a==9) then a=1 end; if a~=9 then a=1 end end)
   130  
   131  check(function () if a==nil then a=1 end end,
   132  'GETGLOBAL', 'EQ', 'JMP', 'LOADK', 'SETGLOBAL', 'RETURN')
   133  
   134  -- de morgan
   135  checkequal(function () local a; if not (a or b) then b=a end end,
   136             function () local a; if (not a and not b) then b=a end end)
   137  
   138  checkequal(function (l) local a; return 0 <= a and a <= l end,
   139             function (l) local a; return not (not(a >= 0) or not(a <= l)) end)
   140  
   141  
   142  print 'OK'
   143