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