diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-12-17 14:46:37 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-12-17 14:46:37 -0200 |
commit | 063d4e4543088e7a21965bda8ee5a0f952a9029e (patch) | |
tree | 6c3f2f8e98c26f071a94a32f9f2754396a66a9de /testes/code.lua | |
parent | e354c6355e7f48e087678ec49e340ca0696725b1 (diff) | |
download | lua-5.3.5.tar.gz lua-5.3.5.tar.bz2 lua-5.3.5.zip |
Lua 5.3.5 ported to gitv5.3.5
This is the first commit for the branch Lua 5.3. All source files
were copied from the official distribution of 5.3.5 in the Lua site.
The test files are the same of 5.3.4. The manual came from the
previous RCS repository, revision 1.167.1.2.
Diffstat (limited to 'testes/code.lua')
-rw-r--r-- | testes/code.lua | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/testes/code.lua b/testes/code.lua new file mode 100644 index 00000000..0b9d142d --- /dev/null +++ b/testes/code.lua | |||
@@ -0,0 +1,239 @@ | |||
1 | -- $Id: code.lua,v 1.42 2016/11/07 13:04:32 roberto Exp $ | ||
2 | -- See Copyright Notice in file all.lua | ||
3 | |||
4 | if T==nil then | ||
5 | (Message or print)('\n >>> testC not active: skipping opcode tests <<<\n') | ||
6 | return | ||
7 | end | ||
8 | print "testing code generation and optimizations" | ||
9 | |||
10 | |||
11 | -- this code gave an error for the code checker | ||
12 | do | ||
13 | local function f (a) | ||
14 | for k,v,w in a do end | ||
15 | end | ||
16 | end | ||
17 | |||
18 | |||
19 | -- testing reuse in constant table | ||
20 | local 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 | ||
26 | end | ||
27 | |||
28 | local 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 | ||
36 | end | ||
37 | |||
38 | checkKlist(foo, {3, 0, 0.0, 3.78/4, -3.78/4, -3.79/4, 3.0}) | ||
39 | |||
40 | |||
41 | -- testing opcodes | ||
42 | |||
43 | function check (f, ...) | ||
44 | local arg = {...} | ||
45 | local c = T.listcode(f) | ||
46 | for i=1, #arg do | ||
47 | -- print(arg[i], c[i]) | ||
48 | assert(string.find(c[i], '- '..arg[i]..' *%d')) | ||
49 | end | ||
50 | assert(c[#arg+2] == nil) | ||
51 | end | ||
52 | |||
53 | |||
54 | function checkequal (a, b) | ||
55 | a = T.listcode(a) | ||
56 | b = T.listcode(b) | ||
57 | for i = 1, #a do | ||
58 | a[i] = string.gsub(a[i], '%b()', '') -- remove line number | ||
59 | b[i] = string.gsub(b[i], '%b()', '') -- remove line number | ||
60 | assert(a[i] == b[i]) | ||
61 | end | ||
62 | end | ||
63 | |||
64 | |||
65 | -- some basic instructions | ||
66 | check(function () | ||
67 | (function () end){f()} | ||
68 | end, 'CLOSURE', 'NEWTABLE', 'GETTABUP', 'CALL', 'SETLIST', 'CALL', 'RETURN') | ||
69 | |||
70 | |||
71 | -- sequence of LOADNILs | ||
72 | check(function () | ||
73 | local a,b,c | ||
74 | local d; local e; | ||
75 | local f,g,h; | ||
76 | d = nil; d=nil; b=nil; a=nil; c=nil; | ||
77 | end, 'LOADNIL', 'RETURN') | ||
78 | |||
79 | check(function () | ||
80 | local a,b,c,d = 1,1,1,1 | ||
81 | d=nil;c=nil;b=nil;a=nil | ||
82 | end, 'LOADK', 'LOADK', 'LOADK', 'LOADK', 'LOADNIL', 'RETURN') | ||
83 | |||
84 | do | ||
85 | local a,b,c,d = 1,1,1,1 | ||
86 | d=nil;c=nil;b=nil;a=nil | ||
87 | assert(a == nil and b == nil and c == nil and d == nil) | ||
88 | end | ||
89 | |||
90 | |||
91 | -- single return | ||
92 | check (function (a,b,c) return a end, 'RETURN') | ||
93 | |||
94 | |||
95 | -- infinite loops | ||
96 | check(function () while true do local a = -1 end end, | ||
97 | 'LOADK', 'JMP', 'RETURN') | ||
98 | |||
99 | check(function () while 1 do local a = -1 end end, | ||
100 | 'LOADK', 'JMP', 'RETURN') | ||
101 | |||
102 | check(function () repeat local x = 1 until true end, | ||
103 | 'LOADK', 'RETURN') | ||
104 | |||
105 | |||
106 | -- concat optimization | ||
107 | check(function (a,b,c,d) return a..b..c..d end, | ||
108 | 'MOVE', 'MOVE', 'MOVE', 'MOVE', 'CONCAT', 'RETURN') | ||
109 | |||
110 | -- not | ||
111 | check(function () return not not nil end, 'LOADBOOL', 'RETURN') | ||
112 | check(function () return not not false end, 'LOADBOOL', 'RETURN') | ||
113 | check(function () return not not true end, 'LOADBOOL', 'RETURN') | ||
114 | check(function () return not not 1 end, 'LOADBOOL', 'RETURN') | ||
115 | |||
116 | -- direct access to locals | ||
117 | check(function () | ||
118 | local a,b,c,d | ||
119 | a = b*2 | ||
120 | c[2], a[b] = -((a + d/2 - a[b]) ^ a.x), b | ||
121 | end, | ||
122 | 'LOADNIL', | ||
123 | 'MUL', | ||
124 | 'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETTABLE', 'POW', | ||
125 | 'UNM', 'SETTABLE', 'SETTABLE', 'RETURN') | ||
126 | |||
127 | |||
128 | -- direct access to constants | ||
129 | check(function () | ||
130 | local a,b | ||
131 | a.x = 3.2 | ||
132 | a.x = b | ||
133 | a[b] = 'x' | ||
134 | end, | ||
135 | 'LOADNIL', 'SETTABLE', 'SETTABLE', 'SETTABLE', 'RETURN') | ||
136 | |||
137 | check(function () | ||
138 | local a,b | ||
139 | a = 1 - a | ||
140 | b = 1/a | ||
141 | b = 5-4 | ||
142 | end, | ||
143 | 'LOADNIL', 'SUB', 'DIV', 'LOADK', 'RETURN') | ||
144 | |||
145 | check(function () | ||
146 | local a,b | ||
147 | a[true] = false | ||
148 | end, | ||
149 | 'LOADNIL', 'SETTABLE', 'RETURN') | ||
150 | |||
151 | |||
152 | -- constant folding | ||
153 | local function checkK (func, val) | ||
154 | check(func, 'LOADK', 'RETURN') | ||
155 | local k = T.listk(func) | ||
156 | assert(#k == 1 and k[1] == val and math.type(k[1]) == math.type(val)) | ||
157 | assert(func() == val) | ||
158 | end | ||
159 | checkK(function () return 0.0 end, 0.0) | ||
160 | checkK(function () return 0 end, 0) | ||
161 | checkK(function () return -0//1 end, 0) | ||
162 | checkK(function () return 3^-1 end, 1/3) | ||
163 | checkK(function () return (1 + 1)^(50 + 50) end, 2^100) | ||
164 | checkK(function () return (-2)^(31 - 2) end, -0x20000000 + 0.0) | ||
165 | checkK(function () return (-3^0 + 5) // 3.0 end, 1.0) | ||
166 | checkK(function () return -3 % 5 end, 2) | ||
167 | checkK(function () return -((2.0^8 + -(-1)) % 8)/2 * 4 - 3 end, -5.0) | ||
168 | checkK(function () return -((2^8 + -(-1)) % 8)//2 * 4 - 3 end, -7.0) | ||
169 | checkK(function () return 0xF0.0 | 0xCC.0 ~ 0xAA & 0xFD end, 0xF4) | ||
170 | checkK(function () return ~(~0xFF0 | 0xFF0) end, 0) | ||
171 | checkK(function () return ~~-100024.0 end, -100024) | ||
172 | checkK(function () return ((100 << 6) << -4) >> 2 end, 100) | ||
173 | |||
174 | |||
175 | -- no foldings | ||
176 | check(function () return -0.0 end, 'LOADK', 'UNM', 'RETURN') | ||
177 | check(function () return 3/0 end, 'DIV', 'RETURN') | ||
178 | check(function () return 0%0 end, 'MOD', 'RETURN') | ||
179 | check(function () return -4//0 end, 'IDIV', 'RETURN') | ||
180 | |||
181 | -- bug in constant folding for 5.1 | ||
182 | check(function () return -nil end, 'LOADNIL', 'UNM', 'RETURN') | ||
183 | |||
184 | |||
185 | check(function () | ||
186 | local a,b,c | ||
187 | b[c], a = c, b | ||
188 | b[a], a = c, b | ||
189 | a, b = c, a | ||
190 | a = a | ||
191 | end, | ||
192 | 'LOADNIL', | ||
193 | 'MOVE', 'MOVE', 'SETTABLE', | ||
194 | 'MOVE', 'MOVE', 'MOVE', 'SETTABLE', | ||
195 | 'MOVE', 'MOVE', 'MOVE', | ||
196 | -- no code for a = a | ||
197 | 'RETURN') | ||
198 | |||
199 | |||
200 | -- x == nil , x ~= nil | ||
201 | checkequal(function () if (a==nil) then a=1 end; if a~=nil then a=1 end end, | ||
202 | function () if (a==9) then a=1 end; if a~=9 then a=1 end end) | ||
203 | |||
204 | check(function () if a==nil then a='a' end end, | ||
205 | 'GETTABUP', 'EQ', 'JMP', 'SETTABUP', 'RETURN') | ||
206 | |||
207 | -- de morgan | ||
208 | checkequal(function () local a; if not (a or b) then b=a end end, | ||
209 | function () local a; if (not a and not b) then b=a end end) | ||
210 | |||
211 | checkequal(function (l) local a; return 0 <= a and a <= l end, | ||
212 | function (l) local a; return not (not(a >= 0) or not(a <= l)) end) | ||
213 | |||
214 | |||
215 | -- if-goto optimizations | ||
216 | check(function (a, b, c, d, e) | ||
217 | if a == b then goto l1 | ||
218 | elseif a == c then goto l2 | ||
219 | elseif a == d then goto l2 | ||
220 | else if a == e then goto l3 | ||
221 | else goto l3 | ||
222 | end | ||
223 | end | ||
224 | ::l1:: ::l2:: ::l3:: ::l4:: | ||
225 | end, 'EQ', 'JMP', 'EQ', 'JMP', 'EQ', 'JMP', 'EQ', 'JMP', 'JMP', 'RETURN') | ||
226 | |||
227 | checkequal( | ||
228 | function (a) while a < 10 do a = a + 1 end end, | ||
229 | function (a) ::L2:: if not(a < 10) then goto L1 end; a = a + 1; | ||
230 | goto L2; ::L1:: end | ||
231 | ) | ||
232 | |||
233 | checkequal( | ||
234 | function (a) while a < 10 do a = a + 1 end end, | ||
235 | function (a) while true do if not(a < 10) then break end; a = a + 1; end end | ||
236 | ) | ||
237 | |||
238 | print 'OK' | ||
239 | |||