aboutsummaryrefslogtreecommitdiff
path: root/testes/code.lua
diff options
context:
space:
mode:
Diffstat (limited to 'testes/code.lua')
-rw-r--r--testes/code.lua347
1 files changed, 347 insertions, 0 deletions
diff --git a/testes/code.lua b/testes/code.lua
new file mode 100644
index 00000000..e39c62ad
--- /dev/null
+++ b/testes/code.lua
@@ -0,0 +1,347 @@
1-- $Id: code.lua,v 1.55 2018/03/12 14:19:36 roberto Exp $
2-- See Copyright Notice in file all.lua
3
4if T==nil then
5 (Message or print)('\n >>> testC not active: skipping opcode tests <<<\n')
6 return
7end
8print "testing code generation and optimizations"
9
10
11-- this code gave an error for the code checker
12do
13 local function f (a)
14 for k,v,w in a do end
15 end
16end
17
18
19-- testing reuse in constant table
20local function checkKlist (func, list)
21 local k = T.listk(func)
22 assert(#k == #list)
23 for i = 1, #k do
24 assert(k[i] == list[i] and math.type(k[i]) == math.type(list[i]))
25 end
26end
27
28local function foo ()
29 local a
30 a = 3;
31 a = 0; a = 0.0; a = -7 + 7
32 a = 3.78/4; a = 3.78/4
33 a = -3.78/4; a = 3.78/4; a = -3.78/4
34 a = -3.79/4; a = 0.0; a = -0;
35 a = 3; a = 3.0; a = 3; a = 3.0
36end
37
38checkKlist(foo, {3.78/4, -3.78/4, -3.79/4})
39
40
41-- testing opcodes
42
43function check (f, ...)
44 local arg = {...}
45 local c = T.listcode(f)
46 for i=1, #arg do
47 local opcode = string.match(c[i], "%u%w+")
48 -- print(arg[i], opcode)
49 assert(arg[i] == opcode)
50 end
51 assert(c[#arg+2] == undef)
52end
53
54
55function checkequal (a, b)
56 a = T.listcode(a)
57 b = T.listcode(b)
58 for i = 1, #a do
59 a[i] = string.gsub(a[i], '%b()', '') -- remove line number
60 b[i] = string.gsub(b[i], '%b()', '') -- remove line number
61 assert(a[i] == b[i])
62 end
63end
64
65
66-- some basic instructions
67check(function ()
68 (function () end){f()}
69end, 'CLOSURE', 'NEWTABLE', 'GETTABUP', 'CALL', 'SETLIST', 'CALL', 'RETURN')
70
71
72-- sequence of LOADNILs
73check(function ()
74 local a,b,c
75 local d; local e;
76 local f,g,h;
77 d = nil; d=nil; b=nil; a=nil; c=nil;
78end, 'LOADNIL', 'RETURN0')
79
80check(function ()
81 local a,b,c,d = 1,1,1,1
82 d=nil;c=nil;b=nil;a=nil
83end, 'LOADI', 'LOADI', 'LOADI', 'LOADI', 'LOADNIL', 'RETURN0')
84
85do
86 local a,b,c,d = 1,1,1,1
87 d=nil;c=nil;b=nil;a=nil
88 assert(a == nil and b == nil and c == nil and d == nil)
89end
90
91
92-- single return
93check (function (a,b,c) return a end, 'RETURN1')
94
95
96-- infinite loops
97check(function () while true do local a = -1 end end,
98'LOADI', 'JMP', 'RETURN0')
99
100check(function () while 1 do local a = -1 end end,
101'LOADI', 'JMP', 'RETURN0')
102
103check(function () repeat local x = 1 until true end,
104'LOADI', 'RETURN0')
105
106
107-- concat optimization
108check(function (a,b,c,d) return a..b..c..d end,
109 'MOVE', 'MOVE', 'MOVE', 'MOVE', 'CONCAT', 'RETURN1')
110
111-- not
112check(function () return not not nil end, 'LOADBOOL', 'RETURN1')
113check(function () return not not false end, 'LOADBOOL', 'RETURN1')
114check(function () return not not true end, 'LOADBOOL', 'RETURN1')
115check(function () return not not 1 end, 'LOADBOOL', 'RETURN1')
116
117-- direct access to locals
118check(function ()
119 local a,b,c,d
120 a = b*a
121 c.x, a[b] = -((a + d/b - a[b]) ^ a.x), b
122end,
123 'LOADNIL',
124 'MUL',
125 'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETFIELD', 'POW',
126 'UNM', 'SETTABLE', 'SETFIELD', 'RETURN0')
127
128
129-- direct access to constants
130check(function ()
131 local a,b
132 a.x = 3.2
133 a.x = b
134 a[b] = 'x'
135end,
136 'LOADNIL', 'SETFIELD', 'SETFIELD', 'SETTABLE', 'RETURN0')
137
138-- "get/set table" with numeric indices
139check(function (a)
140 a[1] = a[100]
141 a[255] = a[256]
142 a[256] = 5
143end,
144 'GETI', 'SETI',
145 'LOADI', 'GETTABLE', 'SETI',
146 'LOADI', 'SETTABLE', 'RETURN0')
147
148check(function ()
149 local a,b
150 a = a - a
151 b = a/a
152 b = 5-4
153end,
154 'LOADNIL', 'SUB', 'DIV', 'LOADI', 'RETURN0')
155
156check(function ()
157 local a,b
158 a[true] = false
159end,
160 'LOADNIL', 'LOADBOOL', 'SETTABLE', 'RETURN0')
161
162
163-- equalities
164check(function (a) if a == 1 then return 2 end end,
165 'EQI', 'JMP', 'LOADI', 'RETURN1')
166
167check(function (a) if -4.0 == a then return 2 end end,
168 'EQI', 'JMP', 'LOADI', 'RETURN1')
169
170check(function (a) if a == "hi" then return 2 end end,
171 'EQK', 'JMP', 'LOADI', 'RETURN1')
172
173check(function (a) if a == 10000 then return 2 end end,
174 'EQK', 'JMP', 'LOADI', 'RETURN1') -- number too large
175
176check(function (a) if -10000 == a then return 2 end end,
177 'EQK', 'JMP', 'LOADI', 'RETURN1') -- number too large
178
179-- comparisons
180
181check(function (a) if -10 <= a then return 2 end end,
182 'GEI', 'JMP', 'LOADI', 'RETURN1')
183
184check(function (a) if 128.0 > a then return 2 end end,
185 'LTI', 'JMP', 'LOADI', 'RETURN1')
186
187check(function (a) if -127.0 < a then return 2 end end,
188 'GTI', 'JMP', 'LOADI', 'RETURN1')
189
190check(function (a) if 10 < a then return 2 end end,
191 'GTI', 'JMP', 'LOADI', 'RETURN1')
192
193check(function (a) if 129 < a then return 2 end end,
194 'LOADI', 'LT', 'JMP', 'LOADI', 'RETURN1')
195
196check(function (a) if a >= 23.0 then return 2 end end,
197 'GEI', 'JMP', 'LOADI', 'RETURN1')
198
199check(function (a) if a >= 23.1 then return 2 end end,
200 'LOADK', 'LE', 'JMP', 'LOADI', 'RETURN1')
201
202check(function (a) if a > 2300.0 then return 2 end end,
203 'LOADF', 'LT', 'JMP', 'LOADI', 'RETURN1')
204
205
206-- constant folding
207local function checkK (func, val)
208 check(func, 'LOADK', 'RETURN1')
209 local k = T.listk(func)
210 assert(#k == 1 and k[1] == val and math.type(k[1]) == math.type(val))
211 assert(func() == val)
212end
213
214local function checkI (func, val)
215 check(func, 'LOADI', 'RETURN1')
216 assert(#T.listk(func) == 0)
217 assert(func() == val)
218end
219
220local function checkF (func, val)
221 check(func, 'LOADF', 'RETURN1')
222 assert(#T.listk(func) == 0)
223 assert(func() == val)
224end
225
226checkF(function () return 0.0 end, 0.0)
227checkI(function () return 0 end, 0)
228checkI(function () return -0//1 end, 0)
229checkK(function () return 3^-1 end, 1/3)
230checkK(function () return (1 + 1)^(50 + 50) end, 2^100)
231checkK(function () return (-2)^(31 - 2) end, -0x20000000 + 0.0)
232checkF(function () return (-3^0 + 5) // 3.0 end, 1.0)
233checkI(function () return -3 % 5 end, 2)
234checkF(function () return -((2.0^8 + -(-1)) % 8)/2 * 4 - 3 end, -5.0)
235checkF(function () return -((2^8 + -(-1)) % 8)//2 * 4 - 3 end, -7.0)
236checkI(function () return 0xF0.0 | 0xCC.0 ~ 0xAA & 0xFD end, 0xF4)
237checkI(function () return ~(~0xFF0 | 0xFF0) end, 0)
238checkI(function () return ~~-1024.0 end, -1024)
239checkI(function () return ((100 << 6) << -4) >> 2 end, 100)
240
241-- borders around MAXARG_sBx ((((1 << 17) - 1) >> 1) == 65535)
242local sbx = ((1 << "17") - 1) >> 1 -- avoid folding
243checkI(function () return 65535 end, sbx)
244checkI(function () return -65535 end, -sbx)
245checkI(function () return 65536 end, sbx + 1)
246checkK(function () return 65537 end, sbx + 2)
247checkK(function () return -65536 end, -(sbx + 1))
248
249checkF(function () return 65535.0 end, sbx + 0.0)
250checkF(function () return -65535.0 end, -sbx + 0.0)
251checkF(function () return 65536.0 end, (sbx + 1.0))
252checkK(function () return 65537.0 end, (sbx + 2.0))
253checkK(function () return -65536.0 end, -(sbx + 1.0))
254
255
256-- immediate operands
257check(function (x) return x + 1 end, 'ADDI', 'RETURN1')
258check(function (x) return 128 + x end, 'ADDI', 'RETURN1')
259check(function (x) return x * -127 end, 'MULI', 'RETURN1')
260check(function (x) return 20 * x end, 'MULI', 'RETURN1')
261check(function (x) return x ^ -2 end, 'POWI', 'RETURN1')
262check(function (x) return x / 40 end, 'DIVI', 'RETURN1')
263check(function (x) return x // 1 end, 'IDIVI', 'RETURN1')
264check(function (x) return x % (100 - 10) end, 'MODI', 'RETURN1')
265check(function (x) return 1 << x end, 'SHLI', 'RETURN1')
266check(function (x) return x << 2 end, 'SHRI', 'RETURN1')
267check(function (x) return x >> 2 end, 'SHRI', 'RETURN1')
268check(function (x) return x & 1 end, 'BANDK', 'RETURN1')
269check(function (x) return 10 | x end, 'BORK', 'RETURN1')
270check(function (x) return -10 ~ x end, 'BXORK', 'RETURN1')
271
272-- no foldings (and immediate operands)
273check(function () return -0.0 end, 'LOADF', 'UNM', 'RETURN1')
274check(function () return 3/0 end, 'LOADI', 'DIVI', 'RETURN1')
275check(function () return 0%0 end, 'LOADI', 'MODI', 'RETURN1')
276check(function () return -4//0 end, 'LOADI', 'IDIVI', 'RETURN1')
277check(function (x) return x >> 2.0 end, 'LOADF', 'SHR', 'RETURN1')
278check(function (x) return x & 2.0 end, 'LOADF', 'BAND', 'RETURN1')
279
280-- basic 'for' loops
281check(function () for i = -10, 10.5 do end end,
282'LOADI', 'LOADK', 'LOADI', 'FORPREP1', 'FORLOOP1', 'RETURN0')
283check(function () for i = 0xfffffff, 10.0, 1 do end end,
284'LOADK', 'LOADF', 'LOADI', 'FORPREP1', 'FORLOOP1', 'RETURN0')
285
286-- bug in constant folding for 5.1
287check(function () return -nil end, 'LOADNIL', 'UNM', 'RETURN1')
288
289
290check(function ()
291 local a,b,c
292 b[c], a = c, b
293 b[a], a = c, b
294 a, b = c, a
295 a = a
296end,
297 'LOADNIL',
298 'MOVE', 'MOVE', 'SETTABLE',
299 'MOVE', 'MOVE', 'MOVE', 'SETTABLE',
300 'MOVE', 'MOVE', 'MOVE',
301 -- no code for a = a
302 'RETURN0')
303
304
305-- x == nil , x ~= nil
306-- checkequal(function (b) if (a==nil) then a=1 end; if a~=nil then a=1 end end,
307-- function () if (a==9) then a=1 end; if a~=9 then a=1 end end)
308
309-- check(function () if a==nil then a='a' end end,
310-- 'GETTABUP', 'EQ', 'JMP', 'SETTABUP', 'RETURN')
311
312do -- tests for table access in upvalues
313 local t
314 check(function () t.x = t.y end, 'GETTABUP', 'SETTABUP')
315 check(function (a) t[a()] = t[a()] end,
316 'MOVE', 'CALL', 'GETUPVAL', 'MOVE', 'CALL',
317 'GETUPVAL', 'GETTABLE', 'SETTABLE')
318end
319
320-- de morgan
321checkequal(function () local a; if not (a or b) then b=a end end,
322 function () local a; if (not a and not b) then b=a end end)
323
324checkequal(function (l) local a; return 0 <= a and a <= l end,
325 function (l) local a; return not (not(a >= 0) or not(a <= l)) end)
326
327
328-- if-goto optimizations
329check(function (a, b, c, d, e)
330 if a == b then goto l1;
331 elseif a == c then goto l2;
332 elseif a == d then goto l2;
333 else if a == e then goto l3;
334 else goto l3
335 end
336 end
337 ::l1:: ::l2:: ::l3:: ::l4::
338end, 'EQ', 'JMP', 'EQ', 'JMP', 'EQ', 'JMP', 'EQ', 'JMP', 'JMP',
339'CLOSE', 'CLOSE', 'CLOSE', 'CLOSE', 'RETURN0')
340
341checkequal(
342function (a) while a < 10 do a = a + 1 end end,
343function (a) while true do if not(a < 10) then break end; a = a + 1; end end
344)
345
346print 'OK'
347