Skip to content

Commit 8343862

Browse files
igormunkinkyukhin
authored andcommitted
test: add tests from tarantool source tree
Introduced structure has the following benefits: * Excess testing machinery currently is not required directly in luajit repo considering whole CI process setup for tarantool and its static linking with libluajit * All new tests related to luajit fixes and enhancements can be added within a single patch with the corresponding changeset NB!: All added test chunks use tarantool tap module
1 parent 48f463e commit 8343862

File tree

5 files changed

+264
-0
lines changed

5 files changed

+264
-0
lines changed

test/fold_bug_LuaJIT_505.test.lua

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env tarantool
2+
3+
tap = require('tap')
4+
5+
test = tap.test("505")
6+
test:plan(1)
7+
8+
-- Test file to demonstrate Lua fold machinery icorrect behavior, details:
9+
-- https://github.com/LuaJIT/LuaJIT/issues/505
10+
11+
jit.opt.start("hotloop=1")
12+
for _ = 1, 20 do
13+
local value = "abc"
14+
local pos_c = string.find(value, "c", 1, true)
15+
local value2 = string.sub(value, 1, pos_c - 1)
16+
local pos_b = string.find(value2, "b", 2, true)
17+
assert(pos_b == 2, "FAIL: position of 'b' is " .. pos_b)
18+
end
19+
20+
test:ok("PASS")

test/gh.test.lua

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env tarantool
2+
3+
-- Miscellaneous test for LuaJIT bugs
4+
tap = require('tap')
5+
6+
test = tap.test("gh")
7+
test:plan(2)
8+
--
9+
-- gh-3196: incorrect string length if Lua hash returns 0
10+
--
11+
h = "\x1F\x93\xE2\x1C\xCA\xDE\x28\x08\x26\x01\xED\x0A\x2F\xE4\x21\x02\x97\x77\xD9\x3E"
12+
test:is(h:len(), 20)
13+
14+
h = "\x0F\x93\xE2\x1C\xCA\xDE\x28\x08\x26\x01\xED\x0A\x2F\xE4\x21\x02\x97\x77\xD9\x3E"
15+
test:is(h:len(), 20)
16+
17+
test:check()

test/suite.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[default]
2+
core = app
3+
description = Luajit tests
4+
is_parallel = True
5+
pretest_clean = True
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
#!/usr/bin/env tarantool
2+
3+
tap = require('tap')
4+
5+
test = tap.test("494")
6+
test:plan(1)
7+
8+
-- Test file to demonstrate Lua table hash chain bugs discussed in
9+
-- https://github.com/LuaJIT/LuaJIT/issues/494
10+
-- Credit: prepared by Peter Cawley here with minor edits:
11+
-- https://gist.github.com/corsix/1fc9b13a2dd5f3659417b62dd54d4500
12+
13+
--- Plumbing
14+
ffi = require"ffi"
15+
ffi.cdef"char* strstr(const char*, const char*)"
16+
strstr = ffi.C.strstr
17+
cast = ffi.cast
18+
str_hash_offset = cast("uint32_t*", strstr("*", ""))[-2] == 1 and 3 or 2
19+
function str_hash(s)
20+
return cast("uint32_t*", strstr(s, "")) - str_hash_offset
21+
end
22+
table_new = require"table.new"
23+
24+
--- Prepare some objects
25+
victims = {}
26+
orig_hash = {}
27+
for c in ("abcdef"):gmatch"." do
28+
v = c .. "{09add58a-13a4-44e0-a52c-d44d0f9b2b95}"
29+
victims[c] = v
30+
orig_hash[c] = str_hash(v)[0]
31+
end
32+
collectgarbage()
33+
34+
do --- Basic version of the problem
35+
for k, v in pairs(victims) do
36+
str_hash(v)[0] = 0
37+
end
38+
t = table_new(0, 8)
39+
-- Make chain a -> b -> c -> d, all with a as primary
40+
t[victims.a] = true
41+
t[victims.d] = true
42+
t[victims.c] = true
43+
t[victims.b] = true
44+
-- Change c's primary to b, and d's primary to c
45+
t[victims.d] = nil
46+
t[victims.c] = nil
47+
str_hash(victims.c)[0] = 5
48+
str_hash(victims.d)[0] = 6
49+
t[victims.c] = true
50+
t[victims.d] = true
51+
-- Insert something with b as primary
52+
str_hash(victims.e)[0] = 5
53+
t[victims.e] = true
54+
-- Check for consistency
55+
for c in ("abcde"):gmatch"." do
56+
assert(t[victims[c]], c)
57+
end
58+
end
59+
collectgarbage()
60+
61+
do --- Just `mn != freenode` can lead to infinite loops
62+
for k, v in pairs(victims) do
63+
str_hash(v)[0] = 0
64+
end
65+
t = table_new(0, 8)
66+
-- Make chain a -> b -> c -> d, all with a as primary
67+
t[victims.a] = true
68+
t[victims.d] = true
69+
t[victims.c] = true
70+
t[victims.b] = true
71+
-- Change c's primary to b, and d's primary to d
72+
t[victims.d] = nil
73+
t[victims.c] = nil
74+
str_hash(victims.c)[0] = 5
75+
str_hash(victims.d)[0] = 7
76+
t[victims.c] = true
77+
t[victims.d] = true
78+
-- Insert something with b as primary
79+
str_hash(victims.e)[0] = 5
80+
t[victims.e] = true
81+
-- Insert something with d as primary (infinite lookup loop)
82+
str_hash(victims.f)[0] = 7
83+
t[victims.f] = true
84+
end
85+
collectgarbage()
86+
87+
do --- Just `mn != nn` can lead to infinite loops
88+
for k, v in pairs(victims) do
89+
str_hash(v)[0] = 0
90+
end
91+
t = table_new(0, 8)
92+
-- Make chain a -> b -> c -> d -> e, all with a as primary
93+
t[victims.a] = true
94+
t[victims.e] = true
95+
t[victims.d] = true
96+
t[victims.c] = true
97+
t[victims.b] = true
98+
-- Change c's primary to b, d's primary to d, and e's primary to d
99+
t[victims.e] = nil
100+
t[victims.d] = nil
101+
t[victims.c] = nil
102+
str_hash(victims.c)[0] = 4
103+
str_hash(victims.d)[0] = 6
104+
str_hash(victims.e)[0] = 6
105+
t[victims.c] = true
106+
t[victims.d] = true
107+
t[victims.e] = true
108+
-- Insert something with b as primary (infinite rechaining loop)
109+
str_hash(victims.f)[0] = 4
110+
t[victims.f] = true
111+
end
112+
113+
for i = 0, 10 do --- Non-strings can need rechaining too
114+
collectgarbage()
115+
116+
k = tonumber((("0x%xp-1074"):format(i)))
117+
str_hash(victims.a)[0] = 0
118+
str_hash(victims.b)[0] = 0
119+
t = table_new(0, 4)
120+
-- a -> b, both with a as primary
121+
t[victims.a] = true
122+
t[victims.b] = true
123+
-- Change b's primary to b
124+
t[victims.b] = nil
125+
str_hash(victims.b)[0] = 3
126+
t[victims.b] = true
127+
-- Might get a -> b -> k, with k's primary as b
128+
t[k] = true
129+
-- Change b's primary to a
130+
t[victims.b] = nil
131+
str_hash(victims.b)[0] = 0
132+
t[victims.b] = true
133+
-- Insert something with b as primary
134+
str_hash(victims.c)[0] = 3
135+
t[victims.c] = true
136+
-- Check for consistency
137+
assert(t[k], i)
138+
end
139+
140+
for i = 0, 10 do --- Non-strings can be moved to freenode
141+
collectgarbage()
142+
143+
k = false
144+
str_hash(victims.a)[0] = 0
145+
str_hash(victims.b)[0] = 0
146+
t = table_new(0, 4)
147+
-- a -> k -> b, all with a as primary
148+
t[victims.a] = true
149+
t[victims.b] = true
150+
t[k] = true
151+
-- Change b's primary to k
152+
t[victims.b] = nil
153+
str_hash(victims.b)[0] = 2
154+
t[victims.b] = true
155+
-- Insert a non-string with primary of k
156+
t[tonumber((("0x%xp-1074"):format(i)))] = true
157+
-- Check for consistency
158+
assert(t[victims.b], i)
159+
end
160+
collectgarbage()
161+
162+
do --- Do not forget to advance freenode in the not-string case
163+
t = table_new(0, 4)
164+
-- Chain of colliding numbers
165+
t[0x0p-1074] = true
166+
t[0x4p-1074] = true
167+
t[0x8p-1074] = true
168+
-- Steal middle node of the chain to be a main node (infinite walking loop)
169+
t[0x2p-1074] = true
170+
end
171+
collectgarbage()
172+
173+
--- Restore interpreter invariants, just in case
174+
for c, v in pairs(victims) do
175+
str_hash(v)[0] = orig_hash[c]
176+
end
177+
178+
test:ok("PASS")

test/unsink_64_kptr.test.lua

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env tarantool
2+
3+
tap = require('tap')
4+
5+
test = tap.test("232")
6+
test:plan(1)
7+
8+
--- From: Thibault Charbonnier <thibaultcha@me.com>
9+
--- tests: ffi: added a test case unsinking a 64-bit pointer from a constant.
10+
---
11+
--- This test case reproduces the issue observed at:
12+
--- https://github.com/openresty/lua-resty-core/issues/232 and was
13+
--- contributed by @lukego and myself.
14+
---
15+
--- Co-authored-by: Luke Gorrie <lukego@gmail.com>
16+
---
17+
local ffi = require("ffi")
18+
19+
local array = ffi.new("struct { int x; } [1]")
20+
21+
-- This test forces the VM to unsink a pointer that was constructed
22+
-- from a constant. The IR will include a 'cnewi' instruction to
23+
-- allocate an FFI pointer object, the pointer value will be an IR
24+
-- constant, the allocation will be sunk, and the allocation will
25+
-- at some point be "unsunk" due to a reference in the snapshot for
26+
-- a taken exit.
27+
28+
-- Note: JIT will recognize <array> as a "singleton" and allow its
29+
-- address to be inlined ("constified") instead of looking up the
30+
-- upvalue at runtime.
31+
32+
local function fn(i)
33+
local struct = array[0] -- Load pointer that the JIT will constify.
34+
if i == 1000 then end -- Force trace exit when i==1000.
35+
struct.x = 0 -- Ensure that 'struct' is live after exit.
36+
end
37+
38+
-- Loop over the function to make it compile and take a trace exit
39+
-- during the final iteration.
40+
for i = 1, 1000 do
41+
fn(i)
42+
end
43+
44+
test:ok("PASS")

0 commit comments

Comments
 (0)