PageRenderTime 101ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/rpython/translator/c/test/test_lltyped.py

https://bitbucket.org/pypy/pypy/
Python | 1049 lines | 1014 code | 26 blank | 9 comment | 19 complexity | c80a738c1adc5869fa95039a65aa20c8 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import py, random
  2. from rpython.rtyper.lltypesystem.lltype import *
  3. from rpython.rtyper.lltypesystem import rffi
  4. from rpython.translator.c.test.test_genc import compile
  5. from rpython.tool.sourcetools import func_with_new_name
  6. class TestLowLevelType(object):
  7. def getcompiled(self, func, argtypes):
  8. return compile(func, argtypes, backendopt=False)
  9. def test_simple(self):
  10. S = GcStruct("s", ('v', Signed))
  11. def llf():
  12. s = malloc(S)
  13. return s.v
  14. fn = self.getcompiled(llf, [])
  15. assert fn() == 0
  16. def test_simple2(self):
  17. S = Struct("s", ('v', Signed))
  18. S2 = GcStruct("s2", ('a',S), ('b',S))
  19. def llf():
  20. s = malloc(S2)
  21. s.a.v = 6
  22. s.b.v = 12
  23. return s.a.v + s.b.v
  24. fn = self.getcompiled(llf, [])
  25. assert fn() == 18
  26. def test_fixedsizearray(self):
  27. S = Struct("s", ('v', Signed))
  28. A7 = FixedSizeArray(Signed, 7)
  29. A3 = FixedSizeArray(S, 3)
  30. A42 = FixedSizeArray(A7, 6)
  31. BIG = GcStruct("big", ("a7", A7), ("a3", A3), ("a42", A42))
  32. def llf():
  33. big = malloc(BIG)
  34. a7 = big.a7
  35. a3 = big.a3
  36. a42 = big.a42
  37. a7[0] = -1
  38. a7.item6 = -2
  39. a3[0].v = -3
  40. a3[2].v = -4
  41. a42[0][0] = -5
  42. a42[5][6] = -6
  43. assert a7[0] == -1
  44. assert a7[6] == -2
  45. assert a3[0].v == -3
  46. assert a3.item2.v == -4
  47. assert a42[0][0] == -5
  48. assert a42[5][6] == -6
  49. return len(a42)*100 + len(a42[4])
  50. fn = self.getcompiled(llf, [])
  51. res = fn()
  52. assert fn() == 607
  53. def test_recursivearray(self):
  54. A = ForwardReference()
  55. A.become(FixedSizeArray(Struct("S", ('a', Ptr(A))), 5))
  56. TREE = Struct("TREE", ("root", A), ("other", A))
  57. tree = malloc(TREE, immortal=True)
  58. def llf():
  59. tree.root[0].a = tree.root
  60. tree.root[1].a = tree.other
  61. assert tree.root[0].a[0].a[0].a[0].a[0].a[1].a == tree.other
  62. fn = self.getcompiled(llf, [])
  63. fn()
  64. def test_prebuilt_array(self):
  65. A = FixedSizeArray(Signed, 5)
  66. a = malloc(A, immortal=True)
  67. a[0] = 8
  68. a[1] = 5
  69. a[2] = 12
  70. a[3] = 12
  71. a[4] = 15
  72. def llf():
  73. s = ''
  74. for i in range(5):
  75. s += chr(64+a[i])
  76. assert s == "HELLO"
  77. fn = self.getcompiled(llf, [])
  78. fn()
  79. def test_call_with_fixedsizearray(self):
  80. A = FixedSizeArray(Struct('s1', ('x', Signed)), 5)
  81. S = GcStruct('s', ('a', Ptr(A)))
  82. a = malloc(A, immortal=True)
  83. a[1].x = 123
  84. def g(x):
  85. return x[1].x
  86. def llf():
  87. s = malloc(S)
  88. s.a = a
  89. return g(s.a)
  90. fn = self.getcompiled(llf, [])
  91. res = fn()
  92. assert res == 123
  93. def test_more_prebuilt_arrays(self):
  94. A = FixedSizeArray(Struct('s1', ('x', Signed)), 5)
  95. S = Struct('s', ('a1', Ptr(A)), ('a2', A))
  96. s = malloc(S, zero=True, immortal=True)
  97. s.a1 = malloc(A, immortal=True)
  98. s.a1[2].x = 50
  99. s.a2[2].x = 60
  100. def llf(n):
  101. if n == 1:
  102. a = s.a1
  103. else:
  104. a = s.a2
  105. return a[2].x
  106. fn = self.getcompiled(llf, [int])
  107. res = fn(1)
  108. assert res == 50
  109. res = fn(2)
  110. assert res == 60
  111. def test_fnptr_with_fixedsizearray(self):
  112. A = ForwardReference()
  113. F = FuncType([Ptr(A)], Signed)
  114. A.become(FixedSizeArray(Struct('s1', ('f', Ptr(F)), ('n', Signed)), 5))
  115. a = malloc(A, immortal=True)
  116. a[3].n = 42
  117. def llf(n):
  118. if a[n].f:
  119. return a[n].f(a)
  120. else:
  121. return -1
  122. fn = self.getcompiled(llf, [int])
  123. res = fn(4)
  124. assert res == -1
  125. def test_direct_arrayitems(self):
  126. for a in [malloc(GcArray(Signed), 5),
  127. malloc(FixedSizeArray(Signed, 5), immortal=True),
  128. malloc(Array(Signed, hints={'nolength': True}), 5,
  129. immortal=True),
  130. ]:
  131. a[0] = 0
  132. a[1] = 10
  133. a[2] = 20
  134. a[3] = 30
  135. a[4] = 40
  136. b0 = direct_arrayitems(a)
  137. b1 = direct_ptradd(b0, 1)
  138. b2 = direct_ptradd(b1, 1)
  139. def llf(n):
  140. b0 = direct_arrayitems(a)
  141. b3 = direct_ptradd(direct_ptradd(b0, 5), -2)
  142. saved = a[n]
  143. a[n] = 1000
  144. try:
  145. return b0[0] + b3[-2] + b2[1] + b1[3]
  146. finally:
  147. a[n] = saved
  148. fn = self.getcompiled(llf, [int])
  149. res = fn(0)
  150. assert res == 1000 + 10 + 30 + 40
  151. res = fn(1)
  152. assert res == 0 + 1000 + 30 + 40
  153. res = fn(2)
  154. assert res == 0 + 10 + 30 + 40
  155. res = fn(3)
  156. assert res == 0 + 10 + 1000 + 40
  157. res = fn(4)
  158. assert res == 0 + 10 + 30 + 1000
  159. def test_structarray_add(self):
  160. from rpython.rtyper.lltypesystem import llmemory
  161. S = Struct("S", ("x", Signed))
  162. PS = Ptr(S)
  163. size = llmemory.sizeof(S)
  164. A = GcArray(S)
  165. itemoffset = llmemory.itemoffsetof(A, 0)
  166. def llf(n):
  167. a = malloc(A, 5)
  168. a[0].x = 1
  169. a[1].x = 2
  170. a[2].x = 3
  171. a[3].x = 42
  172. a[4].x = 4
  173. adr_s = llmemory.cast_ptr_to_adr(a)
  174. adr_s += itemoffset + size * n
  175. s = llmemory.cast_adr_to_ptr(adr_s, PS)
  176. return s.x
  177. fn = self.getcompiled(llf, [int])
  178. res = fn(3)
  179. assert res == 42
  180. def test_direct_fieldptr(self):
  181. S = GcStruct('S', ('x', Signed), ('y', Signed))
  182. def llf(n):
  183. s = malloc(S)
  184. a = direct_fieldptr(s, 'y')
  185. a[0] = n
  186. return s.y
  187. fn = self.getcompiled(llf, [int])
  188. res = fn(34)
  189. assert res == 34
  190. def test_prebuilt_subarrays(self):
  191. a1 = malloc(GcArray(Signed), 5, zero=True)
  192. a2 = malloc(FixedSizeArray(Signed, 5), immortal=True)
  193. s = malloc(GcStruct('S', ('x', Signed), ('y', Signed)), zero=True)
  194. a1[3] = 7000
  195. a2[1] = 600
  196. s.x = 50
  197. s.y = 4
  198. p1 = direct_ptradd(direct_arrayitems(a1), 3)
  199. p2 = direct_ptradd(direct_arrayitems(a2), 1)
  200. p3 = direct_fieldptr(s, 'x')
  201. p4 = direct_fieldptr(s, 'y')
  202. def llf():
  203. a1[3] += 1000
  204. a2[1] += 100
  205. s.x += 10
  206. s.y += 1
  207. return p1[0] + p2[0] + p3[0] + p4[0]
  208. fn = self.getcompiled(llf, [])
  209. res = fn()
  210. assert res == 8765
  211. def test_union(self):
  212. U = Struct('U', ('s', Signed), ('c', Char),
  213. hints={'union': True})
  214. u = malloc(U, immortal=True)
  215. def llf(c):
  216. u.s = 0x10203040
  217. u.c = chr(c)
  218. return u.s
  219. fn = self.getcompiled(llf, [int])
  220. res = fn(0x33)
  221. assert res in [0x10203033, 0x33203040,
  222. # big endian 64 bit machine
  223. 0x3300000010203040]
  224. def test_sizeof_void_array(self):
  225. from rpython.rtyper.lltypesystem import llmemory
  226. A = Array(Void)
  227. size1 = llmemory.sizeof(A, 1)
  228. size2 = llmemory.sizeof(A, 14)
  229. def f(x):
  230. if x:
  231. return size1
  232. else:
  233. return size2
  234. fn = self.getcompiled(f, [int])
  235. res1 = fn(1)
  236. res2 = fn(0)
  237. assert res1 == res2
  238. def test_cast_primitive(self):
  239. def f(x):
  240. x = cast_primitive(UnsignedLongLong, x)
  241. x <<= 60
  242. x /= 3
  243. x <<= 1
  244. x = cast_primitive(SignedLongLong, x)
  245. x >>= 32
  246. return cast_primitive(Signed, x)
  247. fn = self.getcompiled(f, [int])
  248. res = fn(14)
  249. assert res == -1789569707
  250. def test_prebuilt_integers(self):
  251. from rpython.rlib.unroll import unrolling_iterable
  252. from rpython.rtyper.lltypesystem import rffi
  253. class Prebuilt:
  254. pass
  255. p = Prebuilt()
  256. NUMBER_TYPES = rffi.NUMBER_TYPES
  257. names = unrolling_iterable([TYPE.__name__ for TYPE in NUMBER_TYPES])
  258. for name, TYPE in zip(names, NUMBER_TYPES):
  259. value = cast_primitive(TYPE, 1)
  260. setattr(p, name, value)
  261. def f(x):
  262. total = x
  263. for name in names:
  264. total += rffi.cast(Signed, getattr(p, name))
  265. return total
  266. fn = self.getcompiled(f, [int])
  267. res = fn(100)
  268. assert res == 100 + len(list(names))
  269. def test_force_cast(self):
  270. from rpython.rtyper.annlowlevel import llstr
  271. from rpython.rtyper.lltypesystem.rstr import STR
  272. from rpython.rtyper.lltypesystem import rffi, llmemory, lltype
  273. P = lltype.Ptr(lltype.FixedSizeArray(lltype.Char, 1))
  274. def f():
  275. a = llstr("xyz")
  276. b = (llmemory.cast_ptr_to_adr(a) + llmemory.offsetof(STR, 'chars')
  277. + llmemory.itemoffsetof(STR.chars, 0))
  278. buf = rffi.cast(rffi.VOIDP, b)
  279. return buf[2]
  280. fn = self.getcompiled(f, [])
  281. res = fn()
  282. assert res == 'z'
  283. def test_array_nolength(self):
  284. A = Array(Signed, hints={'nolength': True})
  285. a1 = malloc(A, 3, immortal=True)
  286. a1[0] = 30
  287. a1[1] = 300
  288. a1[2] = 3000
  289. a1dummy = malloc(A, 2, immortal=True)
  290. def f(n):
  291. if n & 1:
  292. src = a1dummy
  293. else:
  294. src = a1
  295. a2 = malloc(A, n, flavor='raw')
  296. for i in range(n):
  297. a2[i] = src[i % 3] + i
  298. res = a2[n // 2]
  299. free(a2, flavor='raw')
  300. return res
  301. fn = self.getcompiled(f, [int])
  302. res = fn(100)
  303. assert res == 3050
  304. def test_gcarray_nolength(self):
  305. A = GcArray(Signed, hints={'nolength': True})
  306. a1 = malloc(A, 3, immortal=True)
  307. a1[0] = 30
  308. a1[1] = 300
  309. a1[2] = 3000
  310. a1dummy = malloc(A, 2, immortal=True)
  311. def f(n):
  312. if n & 1:
  313. src = a1dummy
  314. else:
  315. src = a1
  316. a2 = malloc(A, n)
  317. for i in range(n):
  318. a2[i] = src[i % 3] + i
  319. res = a2[n // 2]
  320. return res
  321. fn = self.getcompiled(f, [int])
  322. res = fn(100)
  323. assert res == 3050
  324. def test_structarray_nolength(self):
  325. S = Struct('S', ('x', Signed))
  326. A = Array(S, hints={'nolength': True})
  327. a1 = malloc(A, 3, immortal=True)
  328. a1[0].x = 30
  329. a1[1].x = 300
  330. a1[2].x = 3000
  331. a1dummy = malloc(A, 2, immortal=True)
  332. def f(n):
  333. if n & 1:
  334. src = a1dummy
  335. else:
  336. src = a1
  337. a2 = malloc(A, n, flavor='raw')
  338. for i in range(n):
  339. a2[i].x = src[i % 3].x + i
  340. res = a2[n // 2].x
  341. free(a2, flavor='raw')
  342. return res
  343. fn = self.getcompiled(f, [int])
  344. res = fn(100)
  345. assert res == 3050
  346. def test_zero_raw_malloc(self):
  347. S = Struct('S', ('x', Signed), ('y', Signed))
  348. def f(n):
  349. for i in range(n):
  350. p = malloc(S, flavor='raw', zero=True)
  351. if p.x != 0 or p.y != 0:
  352. free(p, flavor='raw')
  353. return -1
  354. p.x = i
  355. p.y = i
  356. free(p, flavor='raw')
  357. return 42
  358. fn = self.getcompiled(f, [int])
  359. res = fn(100)
  360. assert res == 42
  361. def test_zero_raw_malloc_varsize(self):
  362. # we don't support at the moment raw+zero mallocs with a length
  363. # field to initialize
  364. S = Struct('S', ('x', Signed), ('y', Array(Signed, hints={'nolength': True})))
  365. def f(n):
  366. for length in range(n-1, -1, -1):
  367. p = malloc(S, length, flavor='raw', zero=True)
  368. try:
  369. if p.x != 0:
  370. return -1
  371. p.x = n
  372. for j in range(length):
  373. if p.y[j] != 0:
  374. return -3
  375. p.y[j] = n^j
  376. finally:
  377. free(p, flavor='raw')
  378. return 42
  379. fn = self.getcompiled(f, [int])
  380. res = fn(100)
  381. assert res == 42
  382. def test_arithmetic_cornercases(self):
  383. import operator, sys
  384. from rpython.rlib.unroll import unrolling_iterable
  385. from rpython.rlib.rarithmetic import r_longlong, r_ulonglong
  386. class Undefined:
  387. def __eq__(self, other):
  388. return True
  389. undefined = Undefined()
  390. def getmin(cls):
  391. if cls is int:
  392. return -sys.maxint-1
  393. elif cls.SIGNED:
  394. return cls(-(cls.MASK>>1)-1)
  395. else:
  396. return cls(0)
  397. getmin._annspecialcase_ = 'specialize:memo'
  398. def getmax(cls):
  399. if cls is int:
  400. return sys.maxint
  401. elif cls.SIGNED:
  402. return cls(cls.MASK>>1)
  403. else:
  404. return cls(cls.MASK)
  405. getmax._annspecialcase_ = 'specialize:memo'
  406. maxlonglong = long(getmax(r_longlong))
  407. classes = unrolling_iterable([int, r_uint, r_longlong, r_ulonglong])
  408. operators = unrolling_iterable([operator.add,
  409. operator.sub,
  410. operator.mul,
  411. operator.floordiv,
  412. operator.mod,
  413. operator.lshift,
  414. operator.rshift])
  415. def f(n):
  416. result = ()
  417. for cls in classes:
  418. nn = cls(n)
  419. for OP in operators:
  420. x = getmin(cls)
  421. res1 = OP(x, nn)
  422. result = result + (res1,)
  423. x = getmax(cls)
  424. res1 = OP(x, nn)
  425. result = result + (res1,)
  426. return str(result)
  427. fn = self.getcompiled(f, [int])
  428. res = fn(1)
  429. print res
  430. assert eval(res) == (
  431. # int
  432. -sys.maxint, undefined, # add
  433. undefined, sys.maxint-1, # sub
  434. -sys.maxint-1, sys.maxint, # mul
  435. -sys.maxint-1, sys.maxint, # floordiv
  436. 0, 0, # mod
  437. 0, -2, # lshift
  438. (-sys.maxint-1)//2, sys.maxint//2, # rshift
  439. # r_uint
  440. 1, 0, # add
  441. sys.maxint*2+1, sys.maxint*2, # sub
  442. 0, sys.maxint*2+1, # mul
  443. 0, sys.maxint*2+1, # floordiv
  444. 0, 0, # mod
  445. 0, sys.maxint*2, # lshift
  446. 0, sys.maxint, # rshift
  447. # r_longlong
  448. -maxlonglong, undefined, # add
  449. undefined, maxlonglong-1, # sub
  450. -maxlonglong-1, maxlonglong, # mul
  451. -maxlonglong-1, maxlonglong, # floordiv
  452. 0, 0, # mod
  453. 0, -2, # lshift
  454. (-maxlonglong-1)//2, maxlonglong//2, # rshift
  455. # r_ulonglong
  456. 1, 0, # add
  457. maxlonglong*2+1, maxlonglong*2, # sub
  458. 0, maxlonglong*2+1, # mul
  459. 0, maxlonglong*2+1, # floordiv
  460. 0, 0, # mod
  461. 0, maxlonglong*2, # lshift
  462. 0, maxlonglong, # rshift
  463. )
  464. res = fn(5)
  465. print res
  466. assert eval(res) == (
  467. # int
  468. -sys.maxint+4, undefined, # add
  469. undefined, sys.maxint-5, # sub
  470. undefined, undefined, # mul
  471. (-sys.maxint-1)//5, sys.maxint//5, # floordiv
  472. (-sys.maxint-1)%5, sys.maxint%5, # mod
  473. 0, -32, # lshift
  474. (-sys.maxint-1)//32, sys.maxint//32, # rshift
  475. # r_uint
  476. 5, 4, # add
  477. sys.maxint*2-3, sys.maxint*2-4, # sub
  478. 0, sys.maxint*2-3, # mul
  479. 0, (sys.maxint*2+1)//5, # floordiv
  480. 0, (sys.maxint*2+1)%5, # mod
  481. 0, sys.maxint*2-30, # lshift
  482. 0, sys.maxint>>4, # rshift
  483. # r_longlong
  484. -maxlonglong+4, undefined, # add
  485. undefined, maxlonglong-5, # sub
  486. undefined, undefined, # mul
  487. (-maxlonglong-1)//5, maxlonglong//5, # floordiv
  488. (-maxlonglong-1)%5, maxlonglong%5, # mod
  489. 0, -32, # lshift
  490. (-maxlonglong-1)//32, maxlonglong//32,# rshift
  491. # r_ulonglong
  492. 5, 4, # add
  493. maxlonglong*2-3, maxlonglong*2-4, # sub
  494. 0, maxlonglong*2-3, # mul
  495. 0, (maxlonglong*2+1)//5, # floordiv
  496. 0, (maxlonglong*2+1)%5, # mod
  497. 0, maxlonglong*2-30, # lshift
  498. 0, maxlonglong>>4, # rshift
  499. )
  500. def test_direct_ptradd_barebone(self):
  501. from rpython.rtyper.lltypesystem import rffi
  502. ARRAY_OF_CHAR = Array(Char, hints={'nolength': True})
  503. def llf():
  504. data = "hello, world!"
  505. a = malloc(ARRAY_OF_CHAR, len(data), flavor='raw')
  506. for i in xrange(len(data)):
  507. a[i] = data[i]
  508. a2 = rffi.ptradd(a, 2)
  509. assert typeOf(a2) == typeOf(a) == Ptr(ARRAY_OF_CHAR)
  510. for i in xrange(len(data) - 2):
  511. assert a2[i] == a[i + 2]
  512. free(a, flavor='raw')
  513. fn = self.getcompiled(llf, [])
  514. fn()
  515. def test_r_singlefloat(self):
  516. z = r_singlefloat(0.4)
  517. def g(n):
  518. if n > 0:
  519. return r_singlefloat(n * 0.1)
  520. else:
  521. return z
  522. def llf(n):
  523. return float(g(n))
  524. fn = self.getcompiled(llf, [int])
  525. res = fn(21)
  526. assert res != 2.1 # precision lost
  527. assert abs(res - 2.1) < 1E-6
  528. res = fn(-5)
  529. assert res != 0.4 # precision lost
  530. assert abs(res - 0.4) < 1E-6
  531. def test_array_of_array(self):
  532. C = FixedSizeArray(Signed, 7)
  533. B = Array(C)
  534. A = FixedSizeArray(C, 6)
  535. b = malloc(B, 5, immortal=True)
  536. b[3][4] = 999
  537. a = malloc(A, immortal=True)
  538. a[2][5] = 888000
  539. def llf():
  540. return b[3][4] + a[2][5]
  541. fn = self.getcompiled(llf, [])
  542. assert fn() == 888999
  543. def test_prebuilt_nolength_array(self):
  544. A = Array(Signed, hints={'nolength': True})
  545. a = malloc(A, 5, immortal=True)
  546. a[0] = 8
  547. a[1] = 5
  548. a[2] = 12
  549. a[3] = 12
  550. a[4] = 15
  551. def llf():
  552. s = ''
  553. for i in range(5):
  554. s += chr(64+a[i])
  555. assert s == "HELLO"
  556. fn = self.getcompiled(llf, [])
  557. fn()
  558. def test_prebuilt_nolength_char_array(self):
  559. for lastchar in ('\x00', 'X'):
  560. A = Array(Char, hints={'nolength': True})
  561. a = malloc(A, 6, immortal=True)
  562. a[0] = '8'
  563. a[1] = '5'
  564. a[2] = '?'
  565. a[3] = '!'
  566. a[4] = lastchar
  567. a[5] = '\x00'
  568. def llf():
  569. s = ''
  570. for i in range(5):
  571. s += a[i]
  572. assert s == "85?!" + lastchar
  573. fn = self.getcompiled(llf, [])
  574. fn()
  575. def test_prebuilt_raw_arrays(self):
  576. from rpython.rtyper.lltypesystem import rffi, ll2ctypes
  577. #
  578. def make_test_function(cast, haslength, length):
  579. a = malloc(A, length, flavor='raw', immortal=True)
  580. # two cases: a zero-terminated array if length == 6 or 1030,
  581. # a non-zero-terminated array if length == 557 or 1031
  582. for i in range(length):
  583. a[i] = cast(256 - 5 + i)
  584. def llf():
  585. for i in range(length):
  586. if a[i] != cast(256 - 5 + i):
  587. return False
  588. if haslength and len(a) != length:
  589. return False
  590. return True
  591. return func_with_new_name(llf, repr((A, haslength, length)))
  592. #
  593. testfns = []
  594. records = []
  595. for OF, cast in [(Void, lambda n: None),
  596. (Char, lambda n: chr(n & 0xFF)),
  597. (Signed, lambda n: n)]:
  598. for A, haslength in [(rffi.CArray(OF), False),
  599. (Array(OF), True)]:
  600. for length in [0, 6, 557, 1030, 1031]:
  601. testfns.append(make_test_function(cast, haslength, length))
  602. records.append((A, haslength, length))
  603. def llf():
  604. i = 0
  605. for fn in testfns:
  606. if not fn():
  607. return i # returns the index of the failing function
  608. i += 1
  609. return -42
  610. fn = self.getcompiled(llf, [])
  611. res = fn()
  612. assert res == -42, "failing function: %r" % (records[res],)
  613. def test_prebuilt_ll2ctypes_array(self):
  614. from rpython.rtyper.lltypesystem import rffi, ll2ctypes
  615. A = rffi.CArray(Char)
  616. a = malloc(A, 6, flavor='raw', immortal=True)
  617. a[0] = 'a'
  618. a[1] = 'b'
  619. a[2] = 'c'
  620. a[3] = 'd'
  621. a[4] = '\x00'
  622. a[5] = '\x00'
  623. # side effects when converting to c structure
  624. ll2ctypes.lltype2ctypes(a)
  625. def llf():
  626. s = ''
  627. for i in range(4):
  628. s += a[i]
  629. return 'abcd' == s
  630. fn = self.getcompiled(llf, [])
  631. assert fn()
  632. def test_ll2ctypes_array_from_c(self):
  633. from rpython.rtyper.lltypesystem import rffi, ll2ctypes
  634. A = rffi.CArray(Char)
  635. a = malloc(A, 6, flavor='raw', immortal=True)
  636. a[0] = 'a'
  637. a[1] = 'b'
  638. a[2] = 'c'
  639. a[3] = 'd'
  640. a[4] = '\x00'
  641. a[5] = '\x00'
  642. # side effects when converting to c structure
  643. c = ll2ctypes.lltype2ctypes(a)
  644. a = ll2ctypes.ctypes2lltype(Ptr(A), c)
  645. def llf():
  646. s = ''
  647. for i in range(4):
  648. s += a[i]
  649. return s == 'abcd'
  650. fn = self.getcompiled(llf, [])
  651. assert fn()
  652. def test_cast_to_void_array(self):
  653. from rpython.rtyper.lltypesystem import rffi
  654. def llf():
  655. TYPE = Ptr(rffi.CArray(Void))
  656. y = rffi.cast(TYPE, 0)
  657. fn = self.getcompiled(llf, [])
  658. fn()
  659. def test_llgroup(self):
  660. from rpython.rtyper.lltypesystem.test import test_llgroup
  661. f = test_llgroup.build_test()
  662. fn = self.getcompiled(f, [])
  663. res = fn()
  664. assert res == 42
  665. def test_llgroup_size_limit(self):
  666. yield self._test_size_limit, True
  667. yield self._test_size_limit, False
  668. def _test_size_limit(self, toobig):
  669. import sys
  670. from rpython.rtyper.lltypesystem import llgroup
  671. from rpython.rtyper.lltypesystem.lloperation import llop
  672. from rpython.translator.platform import CompilationError
  673. if toobig and sys.maxint > 2147483647:
  674. py.test.skip("not easy to test groups too big on 64-bit platforms")
  675. grp = llgroup.group("big")
  676. S1 = Struct('S1', ('x', Signed), ('y', Signed),
  677. ('z', Signed), ('u', Signed),
  678. ('x2', Signed), ('y2', Signed),
  679. ('z2', Signed), ('u2', Signed),
  680. ('x3', Signed), ('y3', Signed),
  681. ('z3', Signed), ('u3', Signed),
  682. ('x4', Signed), ('y4', Signed),
  683. ('z4', Signed), ('u4', Signed))
  684. goffsets = []
  685. for i in range(4096 + toobig):
  686. ofs = grp.add_member(malloc(S1, immortal=True))
  687. goffsets.append(llgroup.CombinedSymbolic(ofs, 0))
  688. grpptr = grp._as_ptr()
  689. def f(n):
  690. o = llop.extract_ushort(llgroup.HALFWORD, goffsets[n])
  691. p = llop.get_group_member(Ptr(S1), grpptr, o)
  692. p.x = 5
  693. for i in range(len(goffsets)):
  694. if i != n:
  695. o = llop.extract_ushort(llgroup.HALFWORD, goffsets[i])
  696. q = llop.get_group_member(Ptr(S1), grpptr, o)
  697. q.x = 666
  698. return p.x
  699. if toobig:
  700. py.test.raises(CompilationError, self.getcompiled, f, [int])
  701. else:
  702. fn = self.getcompiled(f, [int])
  703. res = fn(len(goffsets)-1)
  704. assert res == 5
  705. def test_round_up_for_allocation(self):
  706. import platform
  707. from rpython.rtyper.lltypesystem import llmemory, llarena
  708. S = Struct('S', ('x', Char), ('y', Char))
  709. M = Struct('M', ('x', Char), ('y', Signed))
  710. is_arm = platform.machine().startswith('arm')
  711. #
  712. def g():
  713. ssize = llarena.round_up_for_allocation(llmemory.sizeof(S))
  714. msize = llarena.round_up_for_allocation(llmemory.sizeof(M))
  715. smsize = llarena.round_up_for_allocation(llmemory.sizeof(S),
  716. llmemory.sizeof(M))
  717. mssize = llarena.round_up_for_allocation(llmemory.sizeof(M),
  718. llmemory.sizeof(S))
  719. return ssize, msize, smsize, mssize
  720. #
  721. glob_sizes = g()
  722. #
  723. def check((ssize, msize, smsize, mssize)):
  724. if is_arm:
  725. # ARM has stronger rules about aligned memory access
  726. # so according to the rules for round_up_for_allocation
  727. # we get two words here
  728. assert ssize == llmemory.sizeof(Signed) * 2
  729. else:
  730. assert ssize == llmemory.sizeof(Signed)
  731. assert msize == llmemory.sizeof(Signed) * 2
  732. assert smsize == msize
  733. assert mssize == msize
  734. #
  735. def f():
  736. check(glob_sizes)
  737. check(g())
  738. return 42
  739. #
  740. fn = self.getcompiled(f, [])
  741. res = fn()
  742. assert res == 42
  743. def test_llarena(self):
  744. from rpython.rtyper.lltypesystem import llmemory, llarena
  745. #
  746. def f():
  747. a = llarena.arena_malloc(800, False)
  748. llarena.arena_reset(a, 800, 2)
  749. llarena.arena_free(a)
  750. #
  751. fn = self.getcompiled(f, [])
  752. fn()
  753. def test_padding_in_prebuilt_struct(self):
  754. from rpython.rtyper.lltypesystem import rffi
  755. from rpython.rtyper.tool import rffi_platform
  756. eci = rffi_platform.eci_from_header("""
  757. typedef struct {
  758. char c1; /* followed by one byte of padding */
  759. short s1;
  760. char c2; /* followed by 3 bytes of padding */
  761. int i2;
  762. char c3; /* followed by 3 or 7 bytes of padding */
  763. long l3;
  764. char c4;
  765. } foobar_t;
  766. """)
  767. class CConfig:
  768. _compilation_info_ = eci
  769. STRUCT = rffi_platform.Struct("foobar_t",
  770. [("c1", Signed),
  771. ("s1", Signed),
  772. ("l3", Signed)])
  773. S = rffi_platform.configure(CConfig)['STRUCT']
  774. assert 'get_padding_drop' in S._hints
  775. assert 'eci' in S._hints
  776. s1 = malloc(S, immortal=True)
  777. s1.c_c1 = rffi.cast(S.c_c1, -12)
  778. s1.c_s1 = rffi.cast(S.c_s1, -7843)
  779. s1.c_l3 = -98765432
  780. s2 = malloc(S, immortal=True)
  781. s2.c_c1 = rffi.cast(S.c_c1, -123)
  782. s2.c_s1 = rffi.cast(S.c_s1, -789)
  783. s2.c_l3 = -9999999
  784. #
  785. def f(n):
  786. if n > 5:
  787. s = s1
  788. else:
  789. s = s2
  790. return s.c_l3
  791. #
  792. fn = self.getcompiled(f, [int])
  793. res = fn(10)
  794. assert res == -98765432
  795. res = fn(1)
  796. assert res == -9999999
  797. def test_render_immortal(self):
  798. A = FixedSizeArray(Signed, 1)
  799. a1 = malloc(A, flavor='raw')
  800. render_immortal(a1)
  801. a1[0] = 42
  802. def llf():
  803. a2 = malloc(A, flavor='raw')
  804. render_immortal(a2)
  805. a2[0] = 3
  806. return a1[0] + a2[0]
  807. fn = self.getcompiled(llf, [])
  808. assert fn() == 45
  809. def test_rstring_to_float(self):
  810. from rpython.rlib.rfloat import rstring_to_float
  811. def llf(i):
  812. s = ['42.3', '123.4'][i]
  813. return rstring_to_float(s)
  814. fn = self.getcompiled(llf, [int])
  815. assert fn(0) == 42.3
  816. def test_raw_array_field(self):
  817. from rpython.rtyper.lltypesystem import rffi
  818. S = Struct('S', ('array', rffi.CArray(Signed)))
  819. def llf(i):
  820. s = malloc(S, i, flavor='raw')
  821. s.array[i-2] = 42
  822. x = s.array[i-2]
  823. free(s, flavor='raw')
  824. return x
  825. fn = self.getcompiled(llf, [int])
  826. assert fn(5) == 42
  827. def test_raw_array_field_prebuilt(self):
  828. from rpython.rtyper.lltypesystem import rffi
  829. S = Struct('S', ('array', rffi.CArray(Signed)))
  830. s0 = malloc(S, 0, flavor='raw', immortal=True)
  831. s1 = malloc(S, 1, flavor='raw', immortal=True)
  832. s1.array[0] = 521
  833. s2 = malloc(S, 2, flavor='raw', immortal=True)
  834. s2.array[0] = 12
  835. s2.array[1] = 34
  836. def llf(i):
  837. if i == 0: s = s0
  838. elif i == 1: s = s1
  839. else: s = s2
  840. x = 10
  841. if i > 0:
  842. x += s.array[i-1]
  843. return x
  844. fn = self.getcompiled(llf, [int])
  845. assert fn(0) == 10
  846. assert fn(1) == 10 + 521
  847. assert fn(2) == 10 + 34
  848. def test_const_char_star(self):
  849. from rpython.translator.tool.cbuild import ExternalCompilationInfo
  850. eci = ExternalCompilationInfo(includes=["stdlib.h"])
  851. atoi = rffi.llexternal('atoi', [rffi.CONST_CCHARP], rffi.INT,
  852. compilation_info=eci)
  853. def f(n):
  854. s = malloc(rffi.CCHARP.TO, 2, flavor='raw')
  855. s[0] = '9'
  856. s[1] = '\0'
  857. res = atoi(rffi.cast(rffi.CONST_CCHARP, s))
  858. free(s, flavor='raw')
  859. return res
  860. fn = self.getcompiled(f, [int])
  861. assert fn(0) == 9
  862. def test_call_null_funcptr(self):
  863. fnptr = nullptr(FuncType([], Void))
  864. def f(n):
  865. if n > 10:
  866. fnptr() # never reached, or so we hope
  867. return n
  868. fn = self.getcompiled(f, [int])
  869. assert fn(6) == 6
  870. def test_likely_unlikely(self):
  871. from rpython.rlib.objectmodel import likely, unlikely
  872. def f(n):
  873. if unlikely(n > 50):
  874. return -10
  875. if likely(n > 5):
  876. return 42
  877. return 3
  878. fn = self.getcompiled(f, [int])
  879. assert fn(0) == 3
  880. assert fn(10) == 42
  881. assert fn(100) == -10
  882. def test_cast_to_bool_1(self):
  883. def f(n):
  884. return cast_primitive(Bool, n)
  885. fn = self.getcompiled(f, [int])
  886. assert fn(0) == False
  887. assert fn(1) == True
  888. assert fn(256) == True
  889. assert fn(-2**24) == True
  890. def test_cast_to_bool_1_longlong(self):
  891. def f(n):
  892. return cast_primitive(Bool, n)
  893. fn = self.getcompiled(f, [r_longlong])
  894. assert fn(r_longlong(0)) == False
  895. assert fn(r_longlong(1)) == True
  896. assert fn(r_longlong(256)) == True
  897. assert fn(r_longlong(2**32)) == True
  898. def test_cast_to_bool_2(self):
  899. def f(n):
  900. return rffi.cast(Bool, n)
  901. fn = self.getcompiled(f, [int])
  902. assert fn(0) == False
  903. assert fn(1) == True
  904. assert fn(256) == True
  905. assert fn(-2**24) == True
  906. def test_cast_to_bool_2_longlong(self):
  907. def f(n):
  908. return rffi.cast(Bool, n)
  909. fn = self.getcompiled(f, [r_longlong])
  910. assert fn(r_longlong(0)) == False
  911. assert fn(r_longlong(1)) == True
  912. assert fn(r_longlong(256)) == True
  913. assert fn(r_longlong(2**32)) == True
  914. def test_extra_item_after_alloc(self):
  915. from rpython.rlib import rgc
  916. from rpython.rtyper.lltypesystem import lltype
  917. from rpython.rtyper.lltypesystem import rstr
  918. # all STR objects should be allocated with enough space for one
  919. # extra char. Check this for prebuilt strings, and for dynamically
  920. # allocated ones with the default GC for tests. Use strings of 8,
  921. # 16 and 24 chars because if the extra char is missing, writing to it
  922. # is likely to cause corruption in nearby structures.
  923. sizes = [random.choice([8, 16, 24]) for i in range(100)]
  924. A = lltype.Struct('A', ('x', lltype.Signed))
  925. prebuilt = [(rstr.mallocstr(sz),
  926. lltype.malloc(A, flavor='raw', immortal=True))
  927. for sz in sizes]
  928. k = 0
  929. for i, (s, a) in enumerate(prebuilt):
  930. a.x = i
  931. for i in range(len(s.chars)):
  932. k += 1
  933. if k == 256:
  934. k = 1
  935. s.chars[i] = chr(k)
  936. def check(lst):
  937. hashes = []
  938. for i, (s, a) in enumerate(lst):
  939. assert a.x == i
  940. rgc.ll_write_final_null_char(s)
  941. for i, (s, a) in enumerate(lst):
  942. assert a.x == i # check it was not overwritten
  943. def f():
  944. check(prebuilt)
  945. lst1 = []
  946. for i, sz in enumerate(sizes):
  947. s = rstr.mallocstr(sz)
  948. a = lltype.malloc(A, flavor='raw')
  949. a.x = i
  950. lst1.append((s, a))
  951. check(lst1)
  952. for _, a in lst1:
  953. lltype.free(a, flavor='raw')
  954. return 42
  955. fn = self.getcompiled(f, [])
  956. assert fn() == 42