PageRenderTime 67ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/rpython/rtyper/lltypesystem/test/test_lltype.py

https://bitbucket.org/bwesterb/pypy
Python | 858 lines | 761 code | 90 blank | 7 comment | 17 complexity | f1af73f06c3760fe8e58122c5b0c72a6 MD5 | raw file
  1. from __future__ import with_statement
  2. import py
  3. from rpython.rtyper.lltypesystem.lltype import *
  4. from rpython.rtyper.lltypesystem import lltype, rffi
  5. from rpython.tool.identity_dict import identity_dict
  6. from rpython.tool import leakfinder
  7. def isweak(p, T):
  8. try:
  9. typeOf(p)
  10. except TypeError:
  11. return True
  12. return False
  13. def test_basics():
  14. S0 = GcStruct("s0", ('a', Signed), ('b', Signed))
  15. assert S0.a == Signed
  16. assert S0.b == Signed
  17. s0 = malloc(S0)
  18. print s0
  19. assert typeOf(s0) == Ptr(S0)
  20. py.test.raises(UninitializedMemoryAccess, "s0.a")
  21. s0.a = 1
  22. s0.b = s0.a
  23. assert s0.a == 1
  24. assert s0.b == 1
  25. assert typeOf(s0.a) == Signed
  26. # simple array
  27. Ar = GcArray(('v', Signed))
  28. x = malloc(Ar,0)
  29. print x
  30. assert len(x) == 0
  31. x = malloc(Ar,3)
  32. print x
  33. assert typeOf(x) == Ptr(Ar)
  34. assert isweak(x[0], Ar.OF)
  35. x[0].v = 1
  36. x[1].v = 2
  37. x[2].v = 3
  38. assert typeOf(x[0].v) == Signed
  39. assert [x[z].v for z in range(3)] == [1, 2, 3]
  40. #
  41. def define_list(T):
  42. List_typ = GcStruct("list",
  43. ("items", Ptr(GcArray(('item',T)))))
  44. def newlist():
  45. l = malloc(List_typ)
  46. items = malloc(List_typ.items.TO, 0)
  47. l.items = items
  48. return l
  49. def append(l, newitem):
  50. length = len(l.items)
  51. newitems = malloc(List_typ.items.TO, length+1)
  52. i = 0
  53. while i<length:
  54. newitems[i].item = l.items[i].item
  55. i += 1
  56. newitems[length].item = newitem
  57. l.items = newitems
  58. def item(l, i):
  59. return l.items[i].item
  60. return List_typ, newlist, append, item
  61. List_typ, inewlist, iappend, iitem = define_list(Signed)
  62. l = inewlist()
  63. assert typeOf(l) == Ptr(List_typ)
  64. iappend(l, 2)
  65. iappend(l, 3)
  66. assert len(l.items) == 2
  67. assert iitem(l, 0) == 2
  68. assert iitem(l, 1) == 3
  69. IWrap = GcStruct("iwrap", ('v', Signed))
  70. List_typ, iwnewlist, iwappend, iwitem = define_list(Ptr(IWrap))
  71. l = iwnewlist()
  72. assert typeOf(l) == Ptr(List_typ)
  73. iw2 = malloc(IWrap)
  74. iw3 = malloc(IWrap)
  75. iw2.v = 2
  76. iw3.v = 3
  77. assert iw3.v == 3
  78. iwappend(l, iw2)
  79. iwappend(l, iw3)
  80. assert len(l.items) == 2
  81. assert iwitem(l, 0).v == 2
  82. assert iwitem(l, 1).v == 3
  83. # not allowed
  84. S = Struct("s", ('v', Signed))
  85. List_typ, iwnewlistzzz, iwappendzzz, iwitemzzz = define_list(S) # works but
  86. l = iwnewlistzzz()
  87. S1 = GcStruct("strange", ('s', S))
  88. py.test.raises(TypeError, "iwappendzzz(l, malloc(S1).s)")
  89. def test_varsizestruct():
  90. S1 = GcStruct("s1", ('a', Signed), ('rest', Array(('v', Signed))))
  91. py.test.raises(TypeError, "malloc(S1)")
  92. s1 = malloc(S1, 4)
  93. s1.a = 0
  94. assert s1.a == 0
  95. assert isweak(s1.rest, S1.rest)
  96. assert len(s1.rest) == 4
  97. assert isweak(s1.rest[0], S1.rest.OF)
  98. s1.rest[0].v = 0
  99. assert typeOf(s1.rest[0].v) == Signed
  100. assert s1.rest[0].v == 0
  101. py.test.raises(IndexError, "s1.rest[4]")
  102. py.test.raises(IndexError, "s1.rest[-1]")
  103. s1.a = 17
  104. s1.rest[3].v = 5
  105. assert s1.a == 17
  106. assert s1.rest[3].v == 5
  107. py.test.raises(TypeError, "Struct('invalid', ('rest', Array(('v', Signed))), ('a', Signed))")
  108. py.test.raises(TypeError, "Struct('invalid', ('rest', GcArray(('v', Signed))), ('a', Signed))")
  109. py.test.raises(TypeError, "Struct('invalid', ('x', Struct('s1', ('a', Signed), ('rest', Array(('v', Signed))))))")
  110. py.test.raises(TypeError, "Struct('invalid', ('x', S1))")
  111. def test_substructure_ptr():
  112. S3 = Struct("s3", ('a', Signed))
  113. S2 = Struct("s2", ('s3', S3))
  114. S1 = GcStruct("s1", ('sub1', S2), ('sub2', S2))
  115. p1 = malloc(S1)
  116. assert isweak(p1.sub1, S2)
  117. assert isweak(p1.sub2, S2)
  118. assert isweak(p1.sub1.s3, S3)
  119. p2 = p1.sub1
  120. assert isweak(p2.s3, S3)
  121. def test_gc_substructure_ptr():
  122. S1 = GcStruct("s2", ('a', Signed))
  123. S2 = Struct("s3", ('a', Signed))
  124. S0 = GcStruct("s1", ('sub1', S1), ('sub2', S2))
  125. p1 = malloc(S0)
  126. assert typeOf(p1.sub1) == Ptr(S1)
  127. assert isweak(p1.sub2, S2)
  128. def test_cast_simple_widening():
  129. S2 = Struct("s2", ('a', Signed))
  130. S1 = Struct("s1", ('sub1', S2), ('sub2', S2))
  131. p1 = malloc(S1, immortal=True)
  132. p2 = p1.sub1
  133. p3 = p2
  134. assert typeOf(p3) == Ptr(S2)
  135. p4 = cast_pointer(Ptr(S1), p3)
  136. assert typeOf(p4) == Ptr(S1)
  137. assert p4 == p1
  138. py.test.raises(TypeError, "cast_pointer(Ptr(S1), p1.sub2)")
  139. SUnrelated = Struct("unrelated")
  140. py.test.raises(TypeError, "cast_pointer(Ptr(SUnrelated), p3)")
  141. S1bis = Struct("s1b", ('sub1', S2))
  142. p1b = malloc(S1bis, immortal=True)
  143. p2 = p1b.sub1
  144. py.test.raises(RuntimeError, "cast_pointer(Ptr(S1), p2)")
  145. def test_cast_simple_widening2():
  146. S2 = GcStruct("s2", ('a', Signed))
  147. S1 = GcStruct("s1", ('sub1', S2))
  148. p1 = malloc(S1)
  149. p2 = p1.sub1
  150. assert typeOf(p2) == Ptr(S2)
  151. p3 = cast_pointer(Ptr(S1), p2)
  152. assert p3 == p1
  153. p2 = malloc(S2)
  154. py.test.raises(RuntimeError, "cast_pointer(Ptr(S1), p2)")
  155. def test_cast_pointer():
  156. S3 = GcStruct("s3", ('a', Signed))
  157. S2 = GcStruct("s3", ('sub', S3))
  158. S1 = GcStruct("s1", ('sub', S2))
  159. p1 = malloc(S1)
  160. p2 = p1.sub
  161. p3 = p2.sub
  162. assert typeOf(p3) == Ptr(S3)
  163. assert typeOf(p2) == Ptr(S2)
  164. p12 = cast_pointer(Ptr(S1), p2)
  165. assert p12 == p1
  166. p13 = cast_pointer(Ptr(S1), p3)
  167. assert p13 == p1
  168. p21 = cast_pointer(Ptr(S2), p1)
  169. assert p21 == p2
  170. p23 = cast_pointer(Ptr(S2), p3)
  171. assert p23 == p2
  172. p31 = cast_pointer(Ptr(S3), p1)
  173. assert p31 == p3
  174. p32 = cast_pointer(Ptr(S3), p2)
  175. assert p32 == p3
  176. p3 = malloc(S3)
  177. p2 = malloc(S2)
  178. py.test.raises(RuntimeError, "cast_pointer(Ptr(S1), p3)")
  179. py.test.raises(RuntimeError, "cast_pointer(Ptr(S1), p2)")
  180. py.test.raises(RuntimeError, "cast_pointer(Ptr(S2), p3)")
  181. S0 = GcStruct("s0", ('sub', S1))
  182. p0 = malloc(S0)
  183. assert p0 == cast_pointer(Ptr(S0), p0)
  184. p3 = cast_pointer(Ptr(S3), p0)
  185. p03 = cast_pointer(Ptr(S0), p3)
  186. assert p0 == p03
  187. S1bis = GcStruct("s1b", ('sub', S2))
  188. assert S1bis != S1
  189. p1b = malloc(S1bis)
  190. p3 = p1b.sub.sub
  191. assert typeOf(p3) == Ptr(S3)
  192. assert p1b == cast_pointer(Ptr(S1bis), p3)
  193. py.test.raises(RuntimeError, "cast_pointer(Ptr(S1), p3)")
  194. def test_best_effort_gced_parent_detection():
  195. py.test.skip("test not relevant any more")
  196. S2 = Struct("s2", ('a', Signed))
  197. S1 = GcStruct("s1", ('sub1', S2), ('sub2', S2), ('tail', Array(('e', Signed))))
  198. p1 = malloc(S1, 1)
  199. p2 = p1.sub2
  200. p3 = p1.tail
  201. p3[0].e = 1
  202. assert p3[0].e == 1
  203. del p1
  204. import gc
  205. gc.collect()
  206. py.test.raises(RuntimeError, "p2.a")
  207. py.test.raises(RuntimeError, "p3[0]")
  208. def test_best_effort_gced_parent_for_arrays():
  209. py.test.skip("test not relevant any more")
  210. A1 = GcArray(('v', Signed))
  211. p1 = malloc(A1, 10)
  212. p1[5].v=3
  213. assert p1[5].v == 3
  214. p1_5 = p1[5]
  215. del p1
  216. import gc
  217. gc.collect()
  218. py.test.raises(RuntimeError, "p1_5.v")
  219. def test_examples():
  220. A1 = GcArray(('v', Signed))
  221. S = GcStruct("s", ('v', Signed))
  222. St = GcStruct("st", ('v', Signed),('trail', Array(('v', Signed))))
  223. PA1 = Ptr(A1)
  224. PS = Ptr(S)
  225. PSt = Ptr(St)
  226. ex_pa1 = PA1._example()
  227. ex_ps = PS._example()
  228. ex_pst = PSt._example()
  229. assert typeOf(ex_pa1) == PA1
  230. assert typeOf(ex_ps) == PS
  231. assert typeOf(ex_pst) == PSt
  232. assert ex_pa1[0].v == 0
  233. assert ex_ps.v == 0
  234. assert ex_pst.v == 0
  235. assert ex_pst.trail[0].v == 0
  236. def test_functions():
  237. F = FuncType((Signed,), Signed)
  238. py.test.raises(TypeError, "Struct('x', ('x', F))")
  239. PF = Ptr(F)
  240. pf = PF._example()
  241. assert pf(0) == 0
  242. py.test.raises(TypeError, pf, 0, 0)
  243. py.test.raises(TypeError, pf, 'a')
  244. def test_truargs():
  245. F = FuncType((Void, Signed, Void, Unsigned), Float)
  246. assert Void not in F._trueargs()
  247. def test_inconsistent_gc_containers():
  248. A = GcArray(('y', Signed))
  249. S = GcStruct('b', ('y', Signed))
  250. py.test.raises(TypeError, "Struct('a', ('x', S))")
  251. py.test.raises(TypeError, "GcStruct('a', ('x', Signed), ('y', S))")
  252. py.test.raises(TypeError, "Array(('x', S))")
  253. py.test.raises(TypeError, "GcArray(('x', S))")
  254. py.test.raises(TypeError, "Struct('a', ('x', A))")
  255. py.test.raises(TypeError, "GcStruct('a', ('x', A))")
  256. def test_forward_reference():
  257. F = GcForwardReference()
  258. S = GcStruct('abc', ('x', Ptr(F)))
  259. F.become(S)
  260. assert S.x == Ptr(S)
  261. py.test.raises(TypeError, "GcForwardReference().become(Struct('abc'))")
  262. ForwardReference().become(Struct('abc'))
  263. hash(S)
  264. def test_nullptr():
  265. S = Struct('s')
  266. p0 = nullptr(S)
  267. assert not p0
  268. assert typeOf(p0) == Ptr(S)
  269. def test_nullptr_cast():
  270. S = Struct('s')
  271. p0 = nullptr(S)
  272. assert not p0
  273. S1 = Struct("s1", ('s', S))
  274. p10 = cast_pointer(Ptr(S1), p0)
  275. assert typeOf(p10) == Ptr(S1)
  276. assert not p10
  277. def test_nullptr_opaque_cast():
  278. S = Struct('S')
  279. p0 = nullptr(S)
  280. O1 = OpaqueType('O1')
  281. O2 = OpaqueType('O2')
  282. p1 = cast_opaque_ptr(Ptr(O1), p0)
  283. assert not p1
  284. p2 = cast_opaque_ptr(Ptr(O2), p1)
  285. assert not p2
  286. p3 = cast_opaque_ptr(Ptr(S), p2)
  287. assert not p3
  288. def test_hash():
  289. S = ForwardReference()
  290. S.become(Struct('S', ('p', Ptr(S))))
  291. assert S == S
  292. hash(S) # assert no crash, and force the __cached_hash computation
  293. S1 = Struct('S', ('p', Ptr(S)))
  294. assert S1 == S
  295. assert S == S1
  296. assert hash(S1) == hash(S)
  297. def test_array_with_non_container_elements():
  298. As = GcArray(Signed)
  299. a = malloc(As, 3)
  300. assert typeOf(a) == Ptr(As)
  301. py.test.raises(UninitializedMemoryAccess, "a[0]")
  302. a[1] = 3
  303. assert a[1] == 3
  304. S = GcStruct('s', ('x', Signed))
  305. s = malloc(S)
  306. py.test.raises(TypeError, "a[1] = s")
  307. S = GcStruct('s', ('x', Signed))
  308. py.test.raises(TypeError, "Array(S)")
  309. py.test.raises(TypeError, "Array(As)")
  310. S = Struct('s', ('x', Signed))
  311. A = GcArray(S)
  312. a = malloc(A, 2)
  313. s = S._container_example() # should not happen anyway
  314. py.test.raises(TypeError, "a[0] = s")
  315. S = Struct('s', ('last', Array(S)))
  316. py.test.raises(TypeError, "Array(S)")
  317. def test_immortal_parent():
  318. S1 = GcStruct('substruct', ('x', Signed))
  319. S = GcStruct('parentstruct', ('s1', S1))
  320. p = malloc(S, immortal=True)
  321. p1 = p.s1
  322. p1.x = 5
  323. del p
  324. p = cast_pointer(Ptr(S), p1)
  325. assert p.s1.x == 5
  326. def test_getRuntimeTypeInfo():
  327. S = GcStruct('s', ('x', Signed))
  328. py.test.raises(ValueError, "getRuntimeTypeInfo(S)")
  329. S = GcStruct('s', ('x', Signed), rtti=True)
  330. pinfx = getRuntimeTypeInfo(S)
  331. pinf0 = attachRuntimeTypeInfo(S) # no-op, really
  332. assert pinf0._obj.about == S
  333. assert pinf0 == pinfx
  334. pinf = getRuntimeTypeInfo(S)
  335. assert pinf == pinf0
  336. pinf1 = getRuntimeTypeInfo(S)
  337. assert pinf == pinf1
  338. Z = GcStruct('z', ('x', Unsigned), rtti=True)
  339. assert getRuntimeTypeInfo(Z) != pinf0
  340. Sbis = GcStruct('s', ('x', Signed), rtti=True)
  341. assert getRuntimeTypeInfo(Sbis) != pinf0
  342. assert Sbis != S # the attached runtime type info distinguishes them
  343. Ster = GcStruct('s', ('x', Signed), rtti=True)
  344. assert Sbis != Ster # the attached runtime type info distinguishes them
  345. def test_getRuntimeTypeInfo_destrpointer():
  346. S = GcStruct('s', ('x', Signed), rtti=True)
  347. def f(s):
  348. s.x = 1
  349. def type_info_S(p):
  350. return getRuntimeTypeInfo(S)
  351. qp = functionptr(FuncType([Ptr(S)], Ptr(RuntimeTypeInfo)),
  352. "type_info_S",
  353. _callable=type_info_S)
  354. dp = functionptr(FuncType([Ptr(S)], Void),
  355. "destructor_funcptr",
  356. _callable=f)
  357. pinf0 = attachRuntimeTypeInfo(S, qp, destrptr=dp)
  358. assert pinf0._obj.about == S
  359. pinf = getRuntimeTypeInfo(S)
  360. assert pinf == pinf0
  361. pinf1 = getRuntimeTypeInfo(S)
  362. assert pinf == pinf1
  363. assert pinf._obj.destructor_funcptr == dp
  364. assert pinf._obj.query_funcptr == qp
  365. def test_runtime_type_info():
  366. S = GcStruct('s', ('x', Signed), rtti=True)
  367. attachRuntimeTypeInfo(S)
  368. s = malloc(S)
  369. s.x = 0
  370. assert runtime_type_info(s) == getRuntimeTypeInfo(S)
  371. S1 = GcStruct('s1', ('sub', S), ('x', Signed), rtti=True)
  372. attachRuntimeTypeInfo(S1)
  373. s1 = malloc(S1)
  374. s1.sub.x = 0
  375. s1.x = 0
  376. assert runtime_type_info(s1) == getRuntimeTypeInfo(S1)
  377. assert runtime_type_info(s1.sub) == getRuntimeTypeInfo(S1)
  378. assert runtime_type_info(cast_pointer(Ptr(S), s1)) == getRuntimeTypeInfo(S1)
  379. def dynamic_type_info_S(p):
  380. if p.x == 0:
  381. return getRuntimeTypeInfo(S)
  382. else:
  383. return getRuntimeTypeInfo(S1)
  384. fp = functionptr(FuncType([Ptr(S)], Ptr(RuntimeTypeInfo)),
  385. "dynamic_type_info_S",
  386. _callable=dynamic_type_info_S)
  387. attachRuntimeTypeInfo(S, fp)
  388. assert s.x == 0
  389. assert runtime_type_info(s) == getRuntimeTypeInfo(S)
  390. s.x = 1
  391. py.test.raises(RuntimeError, "runtime_type_info(s)")
  392. assert s1.sub.x == 0
  393. py.test.raises(RuntimeError, "runtime_type_info(s1.sub)")
  394. s1.sub.x = 1
  395. assert runtime_type_info(s1.sub) == getRuntimeTypeInfo(S1)
  396. def test_flavor_malloc():
  397. def isweak(p, T):
  398. return p._weak and typeOf(p).TO == T
  399. S = Struct('s', ('x', Signed))
  400. py.test.raises(TypeError, malloc, S)
  401. p = malloc(S, flavor="raw")
  402. assert typeOf(p).TO == S
  403. assert not isweak(p, S)
  404. p.x = 2
  405. free(p, flavor="raw")
  406. py.test.raises(RuntimeError, "p.x")
  407. T = GcStruct('T', ('y', Signed))
  408. p = malloc(T, flavor="gc")
  409. assert typeOf(p).TO == T
  410. assert not isweak(p, T)
  411. def test_opaque():
  412. O = OpaqueType('O')
  413. p1 = opaqueptr(O, 'p1', hello="world")
  414. assert typeOf(p1) == Ptr(O)
  415. assert p1._obj.hello == "world"
  416. assert parentlink(p1._obj) == (None, None)
  417. S = GcStruct('S', ('stuff', O))
  418. p2 = malloc(S)
  419. assert typeOf(p2) == Ptr(S)
  420. assert typeOf(p2.stuff) == Ptr(O)
  421. assert parentlink(p2.stuff._obj) == (p2._obj, 'stuff')
  422. def test_cast_opaque_ptr():
  423. O = GcOpaqueType('O')
  424. Q = GcOpaqueType('Q')
  425. S = GcStruct('S', ('x', Signed))
  426. s = malloc(S)
  427. o = cast_opaque_ptr(Ptr(O), s)
  428. assert typeOf(o).TO == O
  429. q = cast_opaque_ptr(Ptr(Q), o)
  430. assert typeOf(q).TO == Q
  431. p = cast_opaque_ptr(Ptr(S), q)
  432. assert typeOf(p).TO == S
  433. assert p == s
  434. O1 = OpaqueType('O')
  435. S1 = Struct('S1', ('x', Signed))
  436. s1 = malloc(S1, immortal=True)
  437. o1 = cast_opaque_ptr(Ptr(O1), s1)
  438. assert typeOf(o1).TO == O1
  439. p1 = cast_opaque_ptr(Ptr(S1), o1)
  440. assert typeOf(p1).TO == S1
  441. assert p1 == s1
  442. py.test.raises(TypeError, "cast_opaque_ptr(Ptr(S), o1)")
  443. py.test.raises(TypeError, "cast_opaque_ptr(Ptr(O1), s)")
  444. S2 = Struct('S2', ('z', Signed))
  445. py.test.raises(InvalidCast, "cast_opaque_ptr(Ptr(S2), o1)")
  446. BIG = GcStruct('BIG', ('s', S))
  447. UNRELATED = GcStruct('UNRELATED')
  448. big = malloc(BIG)
  449. unrelated = malloc(UNRELATED)
  450. p1 = cast_opaque_ptr(Ptr(O), big)
  451. p2 = cast_opaque_ptr(Ptr(O), big)
  452. assert p1 == p2
  453. p3 = cast_opaque_ptr(Ptr(O), big.s)
  454. assert p1 == p3
  455. p4 = cast_opaque_ptr(Ptr(O), unrelated)
  456. assert p1 != p4
  457. assert p3 != p4
  458. def test_is_atomic():
  459. U = Struct('inlined', ('z', Signed))
  460. A = Ptr(RuntimeTypeInfo)
  461. P = Ptr(GcStruct('p'))
  462. Q = GcStruct('q', ('i', Signed), ('u', U), ('p', P))
  463. O = OpaqueType('O')
  464. F = GcForwardReference()
  465. assert A._is_atomic() is True
  466. assert P._is_atomic() is False
  467. assert Q.i._is_atomic() is True
  468. assert Q.u._is_atomic() is True
  469. assert Q.p._is_atomic() is False
  470. assert Q._is_atomic() is False
  471. assert O._is_atomic() is False
  472. assert F._is_atomic() is False
  473. def test_adtmeths():
  474. def h_newstruct():
  475. return malloc(S)
  476. S = GcStruct('s', ('x', Signed),
  477. adtmeths={"h_newstruct": h_newstruct})
  478. s = S.h_newstruct()
  479. assert typeOf(s) == Ptr(S)
  480. def h_alloc(n):
  481. return malloc(A, n)
  482. def h_length(a):
  483. return len(a)
  484. A = GcArray(Signed,
  485. adtmeths={"h_alloc": h_alloc,
  486. "h_length": h_length,
  487. "stuff": 12})
  488. a = A.h_alloc(10)
  489. assert typeOf(a) == Ptr(A)
  490. assert len(a) == 10
  491. assert a.h_length() == 10
  492. assert a._lookup_adtmeth("h_length")() == 10
  493. assert a.stuff == 12
  494. assert a._lookup_adtmeth("stuff") == 12
  495. def test_adt_typemethod():
  496. def h_newstruct(S):
  497. return malloc(S)
  498. h_newstruct = typeMethod(h_newstruct)
  499. S = GcStruct('s', ('x', Signed),
  500. adtmeths={"h_newstruct": h_newstruct})
  501. s = S.h_newstruct()
  502. assert typeOf(s) == Ptr(S)
  503. Sprime = GcStruct('s', ('x', Signed),
  504. adtmeths={"h_newstruct": h_newstruct})
  505. assert S == Sprime
  506. def test_cast_primitive():
  507. cases = [
  508. (Float, 1, 1.0),
  509. (Float, r_singlefloat(2.1), float(r_singlefloat(2.1))),
  510. (Signed, 1.0, 1),
  511. (Unsigned, 1.0, 1),
  512. (Signed, r_uint(-1), -1),
  513. (Unsigned, -1, r_uint(-1)),
  514. (Char, ord('a'), 'a'),
  515. (Char, False, chr(0)),
  516. (Signed, 'x', ord('x')),
  517. (Unsigned, u"x", ord(u'x')),
  518. ]
  519. for TGT, orig_val, expect in cases:
  520. res = cast_primitive(TGT, orig_val)
  521. assert typeOf(res) == TGT
  522. assert res == expect
  523. res = cast_primitive(SingleFloat, 2.1)
  524. assert isinstance(res, r_singlefloat)
  525. assert float(res) == float(r_singlefloat(2.1))
  526. def test_cast_identical_array_ptr_types():
  527. A = GcArray(Signed)
  528. PA = Ptr(A)
  529. a = malloc(A, 2)
  530. assert cast_pointer(PA, a) == a
  531. def test_array_with_no_length():
  532. A = GcArray(Signed, hints={'nolength': True})
  533. a = malloc(A, 10)
  534. py.test.raises(TypeError, len, a)
  535. def test_dissect_ll_instance():
  536. assert list(dissect_ll_instance(1)) == [(Signed, 1)]
  537. GcS = GcStruct("S", ('x', Signed))
  538. s = malloc(GcS)
  539. s.x = 1
  540. assert list(dissect_ll_instance(s)) == [(Ptr(GcS), s), (GcS, s._obj), (Signed, 1)]
  541. A = GcArray(('x', Signed))
  542. a = malloc(A, 10)
  543. for i in range(10):
  544. a[i].x = i
  545. expected = [(Ptr(A), a), (A, a._obj)]
  546. for t in [((A.OF, a._obj.items[i]), (Signed, i)) for i in range(10)]:
  547. expected.extend(t)
  548. assert list(dissect_ll_instance(a)) == expected
  549. R = GcStruct("R", ('r', Ptr(GcForwardReference())))
  550. R.r.TO.become(R)
  551. r = malloc(R)
  552. r.r = r
  553. r_expected = [(Ptr(R), r), (R, r._obj)]
  554. assert list(dissect_ll_instance(r)) == r_expected
  555. B = GcArray(Ptr(R))
  556. b = malloc(B, 2)
  557. b[0] = b[1] = r
  558. b_expected = [(Ptr(B), b), (B, b._obj)]
  559. assert list(dissect_ll_instance(b)) == b_expected + r_expected
  560. memo = identity_dict()
  561. assert list(dissect_ll_instance(r, None, memo)) == r_expected
  562. assert list(dissect_ll_instance(b, None, memo)) == b_expected
  563. def test_fixedsizearray():
  564. A = FixedSizeArray(Signed, 5)
  565. assert A.OF == Signed
  566. assert A.length == 5
  567. assert A.item0 == A.item1 == A.item2 == A.item3 == A.item4 == Signed
  568. assert A._names == ('item0', 'item1', 'item2', 'item3', 'item4')
  569. a = malloc(A, immortal=True)
  570. a[0] = 5
  571. a[4] = 83
  572. assert a[0] == 5
  573. assert a[4] == 83
  574. assert a.item4 == 83
  575. py.test.raises(IndexError, "a[5] = 183")
  576. py.test.raises(IndexError, "a[-1]")
  577. assert len(a) == 5
  578. S = GcStruct('S', ('n1', Signed),
  579. ('a', A),
  580. ('n2', Signed))
  581. s = malloc(S)
  582. s.a[3] = 17
  583. assert s.a[3] == 17
  584. assert len(s.a) == 5
  585. py.test.raises(TypeError, "s.a = a")
  586. def test_direct_arrayitems():
  587. for a in [malloc(GcArray(Signed), 5),
  588. malloc(FixedSizeArray(Signed, 5), immortal=True)]:
  589. a[0] = 0
  590. a[1] = 10
  591. a[2] = 20
  592. a[3] = 30
  593. a[4] = 40
  594. b0 = direct_arrayitems(a)
  595. b1 = direct_ptradd(b0, 1)
  596. b2 = direct_ptradd(b1, 1)
  597. b3 = direct_ptradd(b0, 3)
  598. assert b0[0] == 0
  599. assert b0[1] == 10
  600. assert b0[4] == 40
  601. assert b1[0] == 10
  602. assert b1[1] == 20
  603. assert b2[0] == 20
  604. assert b2[1] == 30
  605. assert b3[-2] == 10
  606. assert b3[0] == 30
  607. assert b3[1] == 40
  608. assert b2[-2] == 0
  609. assert b1[3] == 40
  610. b2[0] = 23
  611. assert a[2] == 23
  612. b1[1] += 1
  613. assert a[2] == 24
  614. py.test.raises(IndexError, "b0[-1]")
  615. py.test.raises(IndexError, "b3[2]")
  616. py.test.raises(IndexError, "b1[4]")
  617. def test_direct_fieldptr():
  618. S = GcStruct('S', ('x', Signed), ('y', Signed))
  619. s = malloc(S)
  620. a = direct_fieldptr(s, 'y')
  621. a[0] = 34
  622. assert s.y == 34
  623. py.test.raises(IndexError, "a[1]")
  624. def test_odd_ints():
  625. T = GcStruct('T')
  626. S = GcStruct('S', ('t', T))
  627. s = cast_int_to_ptr(Ptr(S), 21)
  628. assert typeOf(s) == Ptr(S)
  629. assert cast_ptr_to_int(s) == 21
  630. t = cast_pointer(Ptr(T), s)
  631. assert typeOf(t) == Ptr(T)
  632. assert cast_ptr_to_int(t) == 21
  633. assert s == cast_pointer(Ptr(S), t)
  634. def test_str_of_dead_ptr():
  635. S = Struct('S', ('x', Signed))
  636. T = GcStruct('T', ('s', S))
  637. t = malloc(T)
  638. s = t.s
  639. del t
  640. import gc
  641. gc.collect()
  642. repr(s)
  643. def test_name_clash():
  644. import re
  645. fn = lltype.__file__
  646. if fn.lower().endswith('pyc') or fn.lower().endswith('pyo'):
  647. fn = fn[:-1]
  648. f = open(fn, 'r')
  649. data = f.read()
  650. f.close()
  651. words = dict.fromkeys(re.compile(r"[a-zA-Z][_a-zA-Z0-9]*").findall(data))
  652. words = words.keys()
  653. S = GcStruct('name_clash', *[(word, Signed) for word in words])
  654. s = malloc(S)
  655. for i, word in enumerate(words):
  656. setattr(s, word, i)
  657. for i, word in enumerate(words):
  658. assert getattr(s, word) == i
  659. def test_subarray_keeps_array_alive():
  660. A = Array(Signed)
  661. ptr = malloc(A, 10, immortal=True)
  662. ptr2 = direct_arrayitems(ptr)
  663. del ptr
  664. import gc; gc.collect(); gc.collect()
  665. ptr2[0] = 5 # crashes if the array was deallocated
  666. def test_identityhash():
  667. S = GcStruct('S', ('x', Signed))
  668. S2 = GcStruct('S2', ('super', S))
  669. S3 = GcStruct('S3', ('super', S2))
  670. py.test.raises(AssertionError, identityhash, nullptr(S2))
  671. s3 = malloc(S3)
  672. hash3 = identityhash(s3.super)
  673. assert hash3 == identityhash(s3)
  674. assert hash3 == identityhash(s3.super)
  675. assert hash3 == identityhash(s3.super.super)
  676. py.test.raises(ValueError, init_identity_hash, s3, hash3^1)
  677. py.test.raises(ValueError, init_identity_hash, s3.super, hash3^4)
  678. py.test.raises(ValueError, init_identity_hash, s3.super.super, hash3^9)
  679. s3 = malloc(S3)
  680. init_identity_hash(s3.super, -123)
  681. assert -123 == identityhash(s3)
  682. assert -123 == identityhash(s3.super)
  683. assert -123 == identityhash(s3.super.super)
  684. py.test.raises(ValueError, init_identity_hash, s3, 4313)
  685. py.test.raises(ValueError, init_identity_hash, s3.super, 0)
  686. py.test.raises(ValueError, init_identity_hash, s3.super.super, -124)
  687. from rpython.rtyper.lltypesystem import llmemory
  688. p3 = cast_opaque_ptr(llmemory.GCREF, s3)
  689. assert -123 == identityhash(p3)
  690. A = GcArray(Signed)
  691. a = malloc(A, 3)
  692. hash1 = identityhash(a)
  693. assert hash1 == identityhash(a)
  694. p = cast_opaque_ptr(llmemory.GCREF, a)
  695. assert hash1 == identityhash(p)
  696. def test_immutable_hint():
  697. S = GcStruct('S', ('x', lltype.Signed))
  698. assert S._immutable_field('x') == False
  699. #
  700. S = GcStruct('S', ('x', lltype.Signed), hints={'immutable': True})
  701. assert S._immutable_field('x') == True
  702. #
  703. class FieldListAccessor(object):
  704. def __init__(self, fields):
  705. self.fields = fields
  706. S = GcStruct('S', ('x', lltype.Signed),
  707. hints={'immutable_fields': FieldListAccessor({'x': 1234})})
  708. assert S._immutable_field('x') == 1234
  709. def test_typedef():
  710. T = Typedef(Signed, 'T')
  711. assert T == Signed
  712. assert Signed == T
  713. T2 = Typedef(T, 'T2')
  714. assert T2 == T
  715. assert T2.OF is Signed
  716. py.test.raises(TypeError, Ptr, T)
  717. assert rffi.CArrayPtr(T) == rffi.CArrayPtr(Signed)
  718. assert rffi.CArrayPtr(Signed) == rffi.CArrayPtr(T)
  719. F = FuncType((T,), T)
  720. assert F.RESULT == Signed
  721. assert F.ARGS == (Signed,)
  722. class TestTrackAllocation:
  723. def test_automatic_tracking(self):
  724. # calls to start_tracking_allocations/stop_tracking_allocations
  725. # should occur automatically from pypy/conftest.py. Check that.
  726. assert leakfinder.TRACK_ALLOCATIONS
  727. def test_track_allocation(self):
  728. """A malloc'd buffer fills the ALLOCATED dictionary"""
  729. assert leakfinder.TRACK_ALLOCATIONS
  730. assert not leakfinder.ALLOCATED
  731. buf = malloc(Array(Signed), 1, flavor="raw")
  732. assert len(leakfinder.ALLOCATED) == 1
  733. assert leakfinder.ALLOCATED.keys() == [buf._obj]
  734. free(buf, flavor="raw")
  735. assert not leakfinder.ALLOCATED
  736. def test_str_from_buffer(self):
  737. """gc-managed memory does not need to be freed"""
  738. size = 50
  739. raw_buf, gc_buf = rffi.alloc_buffer(size)
  740. for i in range(size): raw_buf[i] = 'a'
  741. rstr = rffi.str_from_buffer(raw_buf, gc_buf, size, size)
  742. rffi.keep_buffer_alive_until_here(raw_buf, gc_buf)
  743. assert not leakfinder.ALLOCATED
  744. def test_leak_traceback(self):
  745. """Test info stored for allocated items"""
  746. buf = malloc(Array(Signed), 1, flavor="raw")
  747. traceback = leakfinder.ALLOCATED.values()[0]
  748. lines = traceback.splitlines()
  749. assert 'malloc(' in lines[-1] and 'flavor="raw")' in lines[-1]
  750. # The traceback should not be too long
  751. print traceback
  752. free(buf, flavor="raw")
  753. def test_no_tracking(self):
  754. p1 = malloc(Array(Signed), 1, flavor='raw', track_allocation=False)
  755. p2 = malloc(Array(Signed), 1, flavor='raw', track_allocation=False)
  756. free(p2, flavor='raw', track_allocation=False)
  757. # p1 is not freed
  758. def test_scoped_allocator(self):
  759. with scoped_alloc(Array(Signed), 1) as array:
  760. array[0] = -42
  761. x = array[0]
  762. assert x == -42