PageRenderTime 29ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/rpython/rtyper/test/test_rpbc.py

https://bitbucket.org/pypy/pypy/
Python | 2072 lines | 1799 code | 248 blank | 25 comment | 236 complexity | 1ea9b5714e8b86266151f05e069e4956 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import py
  2. from rpython.annotator import model as annmodel
  3. from rpython.annotator import specialize
  4. from rpython.rtyper.lltypesystem.lltype import typeOf
  5. from rpython.rtyper.test.tool import BaseRtypingTest
  6. from rpython.rtyper.llannotation import SomePtr, lltype_to_annotation
  7. class MyBase:
  8. def m(self, x):
  9. return self.z + x
  10. class MySubclass(MyBase):
  11. def m(self, x):
  12. return self.z - x
  13. class MyStrangerSubclass(MyBase):
  14. def m(self, x, y):
  15. return x*y
  16. class MyBaseWithInit:
  17. def __init__(self, a):
  18. self.a1 = a
  19. class MySubclassWithInit(MyBaseWithInit):
  20. def __init__(self, a, b):
  21. MyBaseWithInit.__init__(self, a)
  22. self.b1 = b
  23. class MySubclassWithoutInit(MyBaseWithInit):
  24. pass
  25. class MySubclassWithoutMethods(MyBase):
  26. pass
  27. class Freezing:
  28. def _freeze_(self):
  29. return True
  30. def mymethod(self, y):
  31. return self.x + y
  32. class TestRPBC(BaseRtypingTest):
  33. def test_easy_call(self):
  34. def f(x):
  35. return x+1
  36. def g(y):
  37. return f(y+2)
  38. res = self.interpret(g, [5])
  39. assert res == 8
  40. def test_multiple_call(self):
  41. def f1(x):
  42. return x+1
  43. def f2(x):
  44. return x+2
  45. def g(y):
  46. if y < 0:
  47. f = f1
  48. else:
  49. f = f2
  50. return f(y+3)
  51. res = self.interpret(g, [-1])
  52. assert res == 3
  53. res = self.interpret(g, [1])
  54. assert res == 6
  55. def test_function_is_null(self):
  56. def f1(x):
  57. return x+1
  58. def f2(x):
  59. return x+2
  60. def g(x):
  61. if x < 0:
  62. return None
  63. elif x == 0:
  64. return f2
  65. else:
  66. return f1
  67. def fn(x):
  68. func = g(x)
  69. if func:
  70. return 42
  71. else:
  72. return 43
  73. assert self.interpret(fn, [1]) == 42
  74. assert self.interpret(fn, [-1]) == 43
  75. def test_method_call(self):
  76. def f(a, b):
  77. obj = MyBase()
  78. obj.z = a
  79. return obj.m(b)
  80. res = self.interpret(f, [4, 5])
  81. assert res == 9
  82. def test_virtual_method_call(self):
  83. def f(a, b):
  84. if a > 0:
  85. obj = MyBase()
  86. else:
  87. obj = MySubclass()
  88. obj.z = a
  89. return obj.m(b)
  90. res = self.interpret(f, [1, 2.3])
  91. assert res == 3.3
  92. res = self.interpret(f, [-1, 2.3])
  93. assert res == -3.3
  94. def test_stranger_subclass_1(self):
  95. def f1():
  96. obj = MyStrangerSubclass()
  97. obj.z = 100
  98. return obj.m(6, 7)
  99. res = self.interpret(f1, [])
  100. assert res == 42
  101. def test_stranger_subclass_2(self):
  102. def f2():
  103. obj = MyStrangerSubclass()
  104. obj.z = 100
  105. return obj.m(6, 7) + MyBase.m(obj, 58)
  106. res = self.interpret(f2, [])
  107. assert res == 200
  108. def test_class_init(self):
  109. def f(a):
  110. instance = MyBaseWithInit(a)
  111. return instance.a1
  112. assert self.interpret(f, [5]) == 5
  113. def test_class_init_2(self):
  114. def f(a, b):
  115. instance = MySubclassWithInit(a, b)
  116. return instance.a1 * instance.b1
  117. assert self.interpret(f, [6, 7]) == 42
  118. def test_class_calling_init(self):
  119. def f():
  120. instance = MySubclassWithInit(1, 2)
  121. instance.__init__(3, 4)
  122. return instance.a1 * instance.b1
  123. assert self.interpret(f, []) == 12
  124. def test_class_init_w_kwds(self):
  125. def f(a):
  126. instance = MyBaseWithInit(a=a)
  127. return instance.a1
  128. assert self.interpret(f, [5]) == 5
  129. def test_class_init_2_w_kwds(self):
  130. def f(a, b):
  131. instance = MySubclassWithInit(a, b=b)
  132. return instance.a1 * instance.b1
  133. assert self.interpret(f, [6, 7]) == 42
  134. def test_class_init_inherited(self):
  135. def f(a):
  136. instance = MySubclassWithoutInit(a)
  137. return instance.a1
  138. assert self.interpret(f, [42]) == 42
  139. def test_class_method_inherited(self):
  140. # The strange names for this test are taken from richards,
  141. # where the problem originally arose.
  142. class Task:
  143. def waitTask(self, a):
  144. return a+1
  145. def fn(self, a):
  146. raise NotImplementedError
  147. def runTask(self, a):
  148. return self.fn(a)
  149. class HandlerTask(Task):
  150. def fn(self, a):
  151. return self.waitTask(a)+2
  152. class DeviceTask(Task):
  153. def fn(self, a):
  154. return self.waitTask(a)+3
  155. def f(a, b):
  156. if b:
  157. inst = HandlerTask()
  158. else:
  159. inst = DeviceTask()
  160. return inst.runTask(a)
  161. assert self.interpret(f, [42, True]) == 45
  162. assert self.interpret(f, [42, False]) == 46
  163. def test_freezing(self):
  164. fr1 = Freezing()
  165. fr2 = Freezing()
  166. fr1.x = 5
  167. fr2.x = 6
  168. def g(fr):
  169. return fr.x
  170. def f(n):
  171. if n > 0:
  172. fr = fr1
  173. elif n < 0:
  174. fr = fr2
  175. else:
  176. fr = None
  177. return g(fr)
  178. res = self.interpret(f, [1])
  179. assert res == 5
  180. res = self.interpret(f, [-1])
  181. assert res == 6
  182. def test_call_frozen_pbc_simple(self):
  183. fr1 = Freezing()
  184. fr1.x = 5
  185. def f(n):
  186. return fr1.mymethod(n)
  187. res = self.interpret(f, [6])
  188. assert res == 11
  189. def test_call_frozen_pbc_simple_w_kwds(self):
  190. fr1 = Freezing()
  191. fr1.x = 5
  192. def f(n):
  193. return fr1.mymethod(y=n)
  194. res = self.interpret(f, [6])
  195. assert res == 11
  196. def test_call_frozen_pbc_multiple(self):
  197. fr1 = Freezing()
  198. fr2 = Freezing()
  199. fr1.x = 5
  200. fr2.x = 6
  201. def f(n):
  202. if n > 0:
  203. fr = fr1
  204. else:
  205. fr = fr2
  206. return fr.mymethod(n)
  207. res = self.interpret(f, [1])
  208. assert res == 6
  209. res = self.interpret(f, [-1])
  210. assert res == 5
  211. def test_call_frozen_pbc_multiple_w_kwds(self):
  212. fr1 = Freezing()
  213. fr2 = Freezing()
  214. fr1.x = 5
  215. fr2.x = 6
  216. def f(n):
  217. if n > 0:
  218. fr = fr1
  219. else:
  220. fr = fr2
  221. return fr.mymethod(y=n)
  222. res = self.interpret(f, [1])
  223. assert res == 6
  224. res = self.interpret(f, [-1])
  225. assert res == 5
  226. def test_is_among_frozen(self):
  227. fr1 = Freezing()
  228. fr2 = Freezing()
  229. def givefr1():
  230. return fr1
  231. def givefr2():
  232. return fr2
  233. def f(i):
  234. if i == 1:
  235. fr = givefr1()
  236. else:
  237. fr = givefr2()
  238. return fr is fr1
  239. res = self.interpret(f, [0])
  240. assert res is False
  241. res = self.interpret(f, [1])
  242. assert res is True
  243. def test_unbound_method(self):
  244. def f():
  245. inst = MySubclass()
  246. inst.z = 40
  247. return MyBase.m(inst, 2)
  248. res = self.interpret(f, [])
  249. assert res == 42
  250. def test_call_defaults(self):
  251. def g(a, b=2, c=3):
  252. return a+b+c
  253. def f1():
  254. return g(1)
  255. def f2():
  256. return g(1, 10)
  257. def f3():
  258. return g(1, 10, 100)
  259. res = self.interpret(f1, [])
  260. assert res == 1+2+3
  261. res = self.interpret(f2, [])
  262. assert res == 1+10+3
  263. res = self.interpret(f3, [])
  264. assert res == 1+10+100
  265. def test_call_memoized_function(self):
  266. fr1 = Freezing()
  267. fr2 = Freezing()
  268. def getorbuild(key):
  269. a = 1
  270. if key is fr1:
  271. result = eval("a+2")
  272. else:
  273. result = eval("a+6")
  274. return result
  275. getorbuild._annspecialcase_ = "specialize:memo"
  276. def f1(i):
  277. if i > 0:
  278. fr = fr1
  279. else:
  280. fr = fr2
  281. return getorbuild(fr)
  282. res = self.interpret(f1, [0])
  283. assert res == 7
  284. res = self.interpret(f1, [1])
  285. assert res == 3
  286. def test_call_memoized_function_with_bools(self):
  287. fr1 = Freezing()
  288. fr2 = Freezing()
  289. def getorbuild(key, flag1, flag2):
  290. a = 1
  291. if key is fr1:
  292. result = eval("a+2")
  293. else:
  294. result = eval("a+6")
  295. if flag1:
  296. result += 100
  297. if flag2:
  298. result += 1000
  299. return result
  300. getorbuild._annspecialcase_ = "specialize:memo"
  301. def f1(i):
  302. if i > 0:
  303. fr = fr1
  304. else:
  305. fr = fr2
  306. return getorbuild(fr, i % 2 == 0, i % 3 == 0)
  307. for n in [0, 1, 2, -3, 6]:
  308. res = self.interpret(f1, [n])
  309. assert res == f1(n)
  310. def test_call_memoized_cache(self):
  311. # this test checks that we add a separate field
  312. # per specialization and also it uses a subclass of
  313. # the standard rpython.rlib.cache.Cache
  314. from rpython.rlib.cache import Cache
  315. fr1 = Freezing()
  316. fr2 = Freezing()
  317. class Cache1(Cache):
  318. def _build(self, key):
  319. "NOT_RPYTHON"
  320. if key is fr1:
  321. return fr2
  322. else:
  323. return fr1
  324. class Cache2(Cache):
  325. def _build(self, key):
  326. "NOT_RPYTHON"
  327. a = 1
  328. if key is fr1:
  329. result = eval("a+2")
  330. else:
  331. result = eval("a+6")
  332. return result
  333. cache1 = Cache1()
  334. cache2 = Cache2()
  335. def f1(i):
  336. if i > 0:
  337. fr = fr1
  338. else:
  339. fr = fr2
  340. newfr = cache1.getorbuild(fr)
  341. return cache2.getorbuild(newfr)
  342. res = self.interpret(f1, [0])
  343. assert res == 3
  344. res = self.interpret(f1, [1])
  345. assert res == 7
  346. def test_call_memo_with_single_value(self):
  347. class A: pass
  348. def memofn(cls):
  349. return len(cls.__name__)
  350. memofn._annspecialcase_ = "specialize:memo"
  351. def f1():
  352. A() # make sure we have a ClassDef
  353. return memofn(A)
  354. res = self.interpret(f1, [])
  355. assert res == 1
  356. def test_call_memo_with_class(self):
  357. class A: pass
  358. class FooBar(A): pass
  359. def memofn(cls):
  360. return len(cls.__name__)
  361. memofn._annspecialcase_ = "specialize:memo"
  362. def f1(i):
  363. if i == 1:
  364. cls = A
  365. else:
  366. cls = FooBar
  367. FooBar() # make sure we have ClassDefs
  368. return memofn(cls)
  369. res = self.interpret(f1, [1])
  370. assert res == 1
  371. res = self.interpret(f1, [2])
  372. assert res == 6
  373. def test_call_memo_with_string(self):
  374. def memofn(s):
  375. return eval(s)
  376. memofn._annspecialcase_ = "specialize:memo"
  377. def f1(i):
  378. if i == 1:
  379. return memofn("6*7")
  380. else:
  381. return memofn("1+2+3+4")
  382. res = self.interpret(f1, [1])
  383. assert res == 42
  384. res = self.interpret(f1, [2])
  385. assert res == 10
  386. def test_rpbc_bound_method_static_call(self):
  387. class R:
  388. def meth(self):
  389. return 0
  390. r = R()
  391. m = r.meth
  392. def fn():
  393. return m()
  394. res = self.interpret(fn, [])
  395. assert res == 0
  396. def test_rpbc_bound_method_static_call_w_kwds(self):
  397. class R:
  398. def meth(self, x):
  399. return x
  400. r = R()
  401. m = r.meth
  402. def fn():
  403. return m(x=3)
  404. res = self.interpret(fn, [])
  405. assert res == 3
  406. def test_constant_return_disagreement(self):
  407. class R:
  408. def meth(self):
  409. return 0
  410. r = R()
  411. def fn():
  412. return r.meth()
  413. res = self.interpret(fn, [])
  414. assert res == 0
  415. def test_None_is_false(self):
  416. def fn(i):
  417. if i == 0:
  418. v = None
  419. else:
  420. v = fn
  421. return bool(v)
  422. res = self.interpret(fn, [1])
  423. assert res is True
  424. res = self.interpret(fn, [0])
  425. assert res is False
  426. def test_classpbc_getattr(self):
  427. class A:
  428. myvalue = 123
  429. class B(A):
  430. myvalue = 456
  431. def f(i):
  432. if i == 0:
  433. v = A
  434. else:
  435. v = B
  436. return v.myvalue
  437. res = self.interpret(f, [0])
  438. assert res == 123
  439. res = self.interpret(f, [1])
  440. assert res == 456
  441. def test_function_or_None(self):
  442. def g1():
  443. return 42
  444. def f(i):
  445. g = None
  446. if i > 5:
  447. g = g1
  448. if i > 6:
  449. return g()
  450. else:
  451. return 12
  452. res = self.interpret(f, [0])
  453. assert res == 12
  454. res = self.interpret(f, [6])
  455. assert res == 12
  456. res = self.interpret(f, [7])
  457. assert res == 42
  458. def test_simple_function_pointer(self):
  459. def f1(x):
  460. return x + 1
  461. def f2(x):
  462. return x + 2
  463. l = [f1, f2]
  464. def pointersimple(i):
  465. return l[i](i)
  466. res = self.interpret(pointersimple, [1])
  467. assert res == 3
  468. def test_classdef_getattr(self):
  469. class A:
  470. myvalue = 123
  471. class B(A):
  472. myvalue = 456
  473. def f(i):
  474. B() # for A and B to have classdefs
  475. if i == 0:
  476. v = A
  477. else:
  478. v = B
  479. return v.myvalue
  480. res = self.interpret(f, [0])
  481. assert res == 123
  482. res = self.interpret(f, [1])
  483. assert res == 456
  484. def test_call_classes(self):
  485. class A: pass
  486. class B(A): pass
  487. def f(i):
  488. if i == 1:
  489. cls = B
  490. else:
  491. cls = A
  492. return cls()
  493. res = self.interpret(f, [0])
  494. assert self.class_name(res) == 'A'
  495. res = self.interpret(f, [1])
  496. assert self.class_name(res) == 'B'
  497. def test_call_classes_or_None(self):
  498. class A: pass
  499. class B(A): pass
  500. def f(i):
  501. if i == -1:
  502. cls = None
  503. elif i == 1:
  504. cls = B
  505. else:
  506. cls = A
  507. return cls()
  508. res = self.interpret(f, [0])
  509. assert self.class_name(res) == 'A'
  510. res = self.interpret(f, [1])
  511. assert self.class_name(res) == 'B'
  512. #def f(i):
  513. # if i == -1:
  514. # cls = None
  515. # else:
  516. # cls = A
  517. # return cls()
  518. #res = self.interpret(f, [0])
  519. #assert self.class_name(res) == 'A'
  520. def test_call_classes_with_init2(self):
  521. class A:
  522. def __init__(self, z):
  523. self.z = z
  524. class B(A):
  525. def __init__(self, z, x=42):
  526. A.__init__(self, z)
  527. self.extra = x
  528. def f(i, z):
  529. if i == 1:
  530. cls = B
  531. else:
  532. cls = A
  533. return cls(z)
  534. res = self.interpret(f, [0, 5])
  535. assert self.class_name(res) == 'A'
  536. assert self.read_attr(res, "z") == 5
  537. res = self.interpret(f, [1, -7645])
  538. assert self.class_name(res) == 'B'
  539. assert self.read_attr(res, "z") == -7645
  540. assert self.read_attr(res, "extra") == 42
  541. def test_conv_from_None(self):
  542. class A(object): pass
  543. def none():
  544. return None
  545. def f(i):
  546. if i == 1:
  547. return none()
  548. else:
  549. return "ab"
  550. res = self.interpret(f, [1])
  551. assert not res
  552. res = self.interpret(f, [0])
  553. assert self.ll_to_string(res) == "ab"
  554. def g(i):
  555. if i == 1:
  556. return none()
  557. else:
  558. return A()
  559. res = self.interpret(g, [1])
  560. assert not res
  561. res = self.interpret(g, [0])
  562. assert self.class_name(res) == 'A'
  563. def test_conv_from_classpbcset_to_larger(self):
  564. class A(object): pass
  565. class B(A): pass
  566. class C(A): pass
  567. def a():
  568. return A
  569. def b():
  570. return B
  571. def g(i):
  572. if i == 1:
  573. cls = a()
  574. else:
  575. cls = b()
  576. return cls()
  577. res = self.interpret(g, [0])
  578. assert self.class_name(res) == 'B'
  579. res = self.interpret(g, [1])
  580. assert self.class_name(res) == 'A'
  581. def bc(j):
  582. if j == 1:
  583. return B
  584. else:
  585. return C
  586. def g(i, j):
  587. if i == 1:
  588. cls = a()
  589. else:
  590. cls = bc(j)
  591. return cls()
  592. res = self.interpret(g, [0, 0])
  593. assert self.class_name(res) == 'C'
  594. res = self.interpret(g, [0, 1])
  595. assert self.class_name(res) == 'B'
  596. res = self.interpret(g, [1, 0])
  597. assert self.class_name(res) == 'A'
  598. def test_call_starargs(self):
  599. def g(x=-100, *arg):
  600. return x + len(arg)
  601. def f(i):
  602. if i == -1:
  603. return g()
  604. elif i == 0:
  605. return g(4)
  606. elif i == 1:
  607. return g(5, 15)
  608. elif i == 2:
  609. return g(7, 17, 27)
  610. else:
  611. return g(10, 198, 1129, 13984)
  612. res = self.interpret(f, [-1])
  613. assert res == -100
  614. res = self.interpret(f, [0])
  615. assert res == 4
  616. res = self.interpret(f, [1])
  617. assert res == 6
  618. res = self.interpret(f, [2])
  619. assert res == 9
  620. res = self.interpret(f, [3])
  621. assert res == 13
  622. def test_call_keywords(self):
  623. def g(a=1, b=2, c=3):
  624. return 100*a+10*b+c
  625. def f(i):
  626. if i == 0:
  627. return g(a=7)
  628. elif i == 1:
  629. return g(b=11)
  630. elif i == 2:
  631. return g(c=13)
  632. elif i == 3:
  633. return g(a=7, b=11)
  634. elif i == 4:
  635. return g(b=7, a=11)
  636. elif i == 5:
  637. return g(a=7, c=13)
  638. elif i == 6:
  639. return g(c=7, a=13)
  640. elif i == 7:
  641. return g(a=7,b=11,c=13)
  642. elif i == 8:
  643. return g(a=7,c=11,b=13)
  644. elif i == 9:
  645. return g(b=7,a=11,c=13)
  646. else:
  647. return g(b=7,c=11,a=13)
  648. for i in range(11):
  649. res = self.interpret(f, [i])
  650. assert res == f(i)
  651. def test_call_star_and_keywords(self):
  652. def g(a=1, b=2, c=3):
  653. return 100*a+10*b+c
  654. def f(i, x):
  655. if x == 1:
  656. j = 11
  657. else:
  658. j = 22
  659. if i == 0:
  660. return g(7)
  661. elif i == 1:
  662. return g(7,*(j,))
  663. elif i == 2:
  664. return g(7,*(11,j))
  665. elif i == 3:
  666. return g(a=7)
  667. elif i == 4:
  668. return g(b=7, *(j,))
  669. elif i == 5:
  670. return g(b=7, c=13, *(j,))
  671. elif i == 6:
  672. return g(c=7, b=13, *(j,))
  673. elif i == 7:
  674. return g(c=7,*(j,))
  675. elif i == 8:
  676. return g(c=7,*(11,j))
  677. else:
  678. return 0
  679. for i in range(9):
  680. for x in range(1):
  681. res = self.interpret(f, [i, x])
  682. assert res == f(i, x)
  683. def test_call_star_and_keywords_starargs(self):
  684. def g(a=1, b=2, c=3, *rest):
  685. return 1000*len(rest)+100*a+10*b+c
  686. def f(i, x):
  687. if x == 1:
  688. j = 13
  689. else:
  690. j = 31
  691. if i == 0:
  692. return g()
  693. elif i == 1:
  694. return g(*(j,))
  695. elif i == 2:
  696. return g(*(13, j))
  697. elif i == 3:
  698. return g(*(13, j, 19))
  699. elif i == 4:
  700. return g(*(13, j, 19, 21))
  701. elif i == 5:
  702. return g(7)
  703. elif i == 6:
  704. return g(7, *(j,))
  705. elif i == 7:
  706. return g(7, *(13, j))
  707. elif i == 8:
  708. return g(7, *(13, 17, j))
  709. elif i == 9:
  710. return g(7, *(13, 17, j, 21))
  711. elif i == 10:
  712. return g(7, 9)
  713. elif i == 11:
  714. return g(7, 9, *(j,))
  715. elif i == 12:
  716. return g(7, 9, *(j, 17))
  717. elif i == 13:
  718. return g(7, 9, *(13, j, 19))
  719. elif i == 14:
  720. return g(7, 9, 11)
  721. elif i == 15:
  722. return g(7, 9, 11, *(j,))
  723. elif i == 16:
  724. return g(7, 9, 11, *(13, j))
  725. elif i == 17:
  726. return g(7, 9, 11, *(13, 17, j))
  727. elif i == 18:
  728. return g(7, 9, 11, 2)
  729. elif i == 19:
  730. return g(7, 9, 11, 2, *(j,))
  731. elif i == 20:
  732. return g(7, 9, 11, 2, *(13, j))
  733. else:
  734. return 0
  735. for i in range(21):
  736. for x in range(1):
  737. res = self.interpret(f, [i, x])
  738. assert res == f(i, x)
  739. def test_conv_from_funcpbcset_to_larger(self):
  740. def f1():
  741. return 7
  742. def f2():
  743. return 11
  744. def f3():
  745. return 13
  746. def a():
  747. return f1
  748. def b():
  749. return f2
  750. def g(i):
  751. if i == 1:
  752. f = a()
  753. else:
  754. f = b()
  755. return f()
  756. res = self.interpret(g, [0])
  757. assert res == 11
  758. res = self.interpret(g, [1])
  759. assert res == 7
  760. def bc(j):
  761. if j == 1:
  762. return f2
  763. else:
  764. return f3
  765. def g(i, j):
  766. if i == 1:
  767. cls = a()
  768. else:
  769. cls = bc(j)
  770. return cls()
  771. res = self.interpret(g, [0, 0])
  772. assert res == 13
  773. res = self.interpret(g, [0, 1])
  774. assert res == 11
  775. res = self.interpret(g, [1, 0])
  776. assert res == 7
  777. def test_call_special_starargs_method(self):
  778. class Star:
  779. def __init__(self, d):
  780. self.d = d
  781. def meth(self, *args):
  782. return self.d + len(args)
  783. def f(i, j):
  784. s = Star(i)
  785. return s.meth(i, j)
  786. res = self.interpret(f, [3, 0])
  787. assert res == 5
  788. def test_call_star_method(self):
  789. class N:
  790. def __init__(self, d):
  791. self.d = d
  792. def meth(self, a, b):
  793. return self.d + a + b
  794. def f(i, j):
  795. n = N(i)
  796. return n.meth(*(i, j))
  797. res = self.interpret(f, [3, 7])
  798. assert res == 13
  799. def test_call_star_special_starargs_method(self):
  800. class N:
  801. def __init__(self, d):
  802. self.d = d
  803. def meth(self, *args):
  804. return self.d + len(args)
  805. def f(i, j):
  806. n = N(i)
  807. return n.meth(*(i, j))
  808. res = self.interpret(f, [3, 0])
  809. assert res == 5
  810. def test_various_patterns_but_one_signature_method(self):
  811. class A:
  812. def meth(self, a, b=0):
  813. raise NotImplementedError
  814. class B(A):
  815. def meth(self, a, b=0):
  816. return a+b
  817. class C(A):
  818. def meth(self, a, b=0):
  819. return a*b
  820. def f(i):
  821. if i == 0:
  822. x = B()
  823. else:
  824. x = C()
  825. r1 = x.meth(1)
  826. r2 = x.meth(3, 2)
  827. r3 = x.meth(7, b=11)
  828. return r1+r2+r3
  829. res = self.interpret(f, [0])
  830. assert res == 1+3+2+7+11
  831. res = self.interpret(f, [1])
  832. assert res == 3*2+11*7
  833. def test_multiple_ll_one_hl_op(self):
  834. class E(Exception):
  835. pass
  836. class A(object):
  837. pass
  838. class B(A):
  839. pass
  840. class C(object):
  841. def method(self, x):
  842. if x:
  843. raise E()
  844. else:
  845. return A()
  846. class D(C):
  847. def method(self, x):
  848. if x:
  849. raise E()
  850. else:
  851. return B()
  852. def call(x):
  853. c = D()
  854. c.method(x)
  855. try:
  856. c.method(x + 1)
  857. except E:
  858. pass
  859. c = C()
  860. c.method(x)
  861. try:
  862. return c.method(x + 1)
  863. except E:
  864. return None
  865. res = self.interpret(call, [0])
  866. def test_multiple_pbc_with_void_attr(self):
  867. class A:
  868. def _freeze_(self):
  869. return True
  870. a1 = A()
  871. a2 = A()
  872. unique = A()
  873. unique.result = 42
  874. a1.value = unique
  875. a2.value = unique
  876. def g(a):
  877. return a.value.result
  878. def f(i):
  879. if i == 1:
  880. a = a1
  881. else:
  882. a = a2
  883. return g(a)
  884. res = self.interpret(f, [0])
  885. assert res == 42
  886. res = self.interpret(f, [1])
  887. assert res == 42
  888. def test_function_or_none(self):
  889. def h(y):
  890. return y+84
  891. def g(y):
  892. return y+42
  893. def f(x, y):
  894. if x == 1:
  895. func = g
  896. elif x == 2:
  897. func = h
  898. else:
  899. func = None
  900. if func:
  901. return func(y)
  902. return -1
  903. res = self.interpret(f, [1, 100])
  904. assert res == 142
  905. res = self.interpret(f, [2, 100])
  906. assert res == 184
  907. res = self.interpret(f, [3, 100])
  908. assert res == -1
  909. def test_pbc_getattr_conversion(self):
  910. fr1 = Freezing()
  911. fr2 = Freezing()
  912. fr3 = Freezing()
  913. fr1.value = 10
  914. fr2.value = 5
  915. fr3.value = 2.5
  916. def pick12(i):
  917. if i > 0:
  918. return fr1
  919. else:
  920. return fr2
  921. def pick23(i):
  922. if i > 5:
  923. return fr2
  924. else:
  925. return fr3
  926. def f(i):
  927. x = pick12(i)
  928. y = pick23(i)
  929. return x.value, y.value
  930. for i in [0, 5, 10]:
  931. res = self.interpret(f, [i])
  932. item0, item1 = self.ll_unpack_tuple(res, 2)
  933. assert type(item0) is int # precise
  934. assert type(item1) in (float, int) # we get int on JS
  935. assert item0 == f(i)[0]
  936. assert item1 == f(i)[1]
  937. def test_pbc_getattr_conversion_with_classes(self):
  938. class base: pass
  939. class fr1(base): pass
  940. class fr2(base): pass
  941. class fr3(base): pass
  942. fr1.value = 10
  943. fr2.value = 5
  944. fr3.value = 2.5
  945. def pick12(i):
  946. if i > 0:
  947. return fr1
  948. else:
  949. return fr2
  950. def pick23(i):
  951. if i > 5:
  952. return fr2
  953. else:
  954. return fr3
  955. def f(i):
  956. x = pick12(i)
  957. y = pick23(i)
  958. return x.value, y.value
  959. for i in [0, 5, 10]:
  960. res = self.interpret(f, [i])
  961. item0, item1 = self.ll_unpack_tuple(res, 2)
  962. assert type(item0) is int # precise
  963. assert type(item1) in (float, int) # we get int on JS
  964. assert item0 == f(i)[0]
  965. assert item1 == f(i)[1]
  966. def test_pbc_imprecise_attrfamily(self):
  967. fr1 = Freezing(); fr1.x = 5; fr1.y = [8]
  968. fr2 = Freezing(); fr2.x = 6; fr2.y = ["string"]
  969. def head(fr):
  970. return fr.y[0]
  971. def f(n):
  972. if n == 1:
  973. fr = fr1
  974. else:
  975. fr = fr2
  976. return head(fr1) + fr.x
  977. res = self.interpret(f, [2])
  978. assert res == 8 + 6
  979. def test_multiple_specialized_functions(self):
  980. def myadder(x, y): # int,int->int or str,str->str
  981. return x+y
  982. def myfirst(x, y): # int,int->int or str,str->str
  983. return x
  984. def mysecond(x, y): # int,int->int or str,str->str
  985. return y
  986. myadder._annspecialcase_ = 'specialize:argtype(0)'
  987. myfirst._annspecialcase_ = 'specialize:argtype(0)'
  988. mysecond._annspecialcase_ = 'specialize:argtype(0)'
  989. def f(i):
  990. if i == 0:
  991. g = myfirst
  992. elif i == 1:
  993. g = mysecond
  994. else:
  995. g = myadder
  996. s = g("hel", "lo")
  997. n = g(40, 2)
  998. return len(s) * n
  999. for i in range(3):
  1000. res = self.interpret(f, [i])
  1001. assert res == f(i)
  1002. def test_specialized_method_of_frozen(self):
  1003. class space:
  1004. def _freeze_(self):
  1005. return True
  1006. def __init__(self, tag):
  1007. self.tag = tag
  1008. def wrap(self, x):
  1009. if isinstance(x, int):
  1010. return self.tag + '< %d >' % x
  1011. else:
  1012. return self.tag + x
  1013. wrap._annspecialcase_ = 'specialize:argtype(1)'
  1014. space1 = space("tag1:")
  1015. space2 = space("tag2:")
  1016. def f(i):
  1017. if i == 1:
  1018. sp = space1
  1019. else:
  1020. sp = space2
  1021. w1 = sp.wrap('hello')
  1022. w2 = sp.wrap(42)
  1023. return w1 + w2
  1024. res = self.interpret(f, [1])
  1025. assert self.ll_to_string(res) == 'tag1:hellotag1:< 42 >'
  1026. res = self.interpret(f, [0])
  1027. assert self.ll_to_string(res) == 'tag2:hellotag2:< 42 >'
  1028. def test_specialized_method(self):
  1029. class A:
  1030. def __init__(self, tag):
  1031. self.tag = tag
  1032. def wrap(self, x):
  1033. if isinstance(x, int):
  1034. return self.tag + '< %d >' % x
  1035. else:
  1036. return self.tag + x
  1037. wrap._annspecialcase_ = 'specialize:argtype(1)'
  1038. a1 = A("tag1:")
  1039. a2 = A("tag2:")
  1040. def f(i):
  1041. if i == 1:
  1042. sp = a1
  1043. else:
  1044. sp = a2
  1045. w1 = sp.wrap('hello')
  1046. w2 = sp.wrap(42)
  1047. return w1 + w2
  1048. res = self.interpret(f, [1])
  1049. assert self.ll_to_string(res) == 'tag1:hellotag1:< 42 >'
  1050. res = self.interpret(f, [0])
  1051. assert self.ll_to_string(res) == 'tag2:hellotag2:< 42 >'
  1052. def test_precise_method_call_1(self):
  1053. class A(object):
  1054. def meth(self, x=5):
  1055. return x+1
  1056. class B(A):
  1057. def meth(self, x=5):
  1058. return x+2
  1059. class C(A):
  1060. pass
  1061. def f(i, n):
  1062. # call both A.meth and B.meth with an explicit argument
  1063. if i > 0:
  1064. x = A()
  1065. else:
  1066. x = B()
  1067. result1 = x.meth(n)
  1068. # now call A.meth only, using the default argument
  1069. result2 = C().meth()
  1070. return result1 * result2
  1071. for i in [0, 1]:
  1072. res = self.interpret(f, [i, 1234])
  1073. assert res == f(i, 1234)
  1074. def test_precise_method_call_2(self):
  1075. class A(object):
  1076. def meth(self, x=5):
  1077. return x+1
  1078. class B(A):
  1079. def meth(self, x=5):
  1080. return x+2
  1081. class C(A):
  1082. def meth(self, x=5):
  1083. return x+3
  1084. def f(i, n):
  1085. # call both A.meth and B.meth with an explicit argument
  1086. if i > 0:
  1087. x = A()
  1088. else:
  1089. x = B()
  1090. result1 = x.meth(n)
  1091. # now call A.meth and C.meth, using the default argument
  1092. if i > 0:
  1093. x = C()
  1094. else:
  1095. x = A()
  1096. result2 = x.meth()
  1097. return result1 * result2
  1098. for i in [0, 1]:
  1099. res = self.interpret(f, [i, 1234])
  1100. assert res == f(i, 1234)
  1101. def test_disjoint_pbcs(self):
  1102. class Frozen(object):
  1103. def __init__(self, v):
  1104. self.v = v
  1105. def _freeze_(self):
  1106. return True
  1107. fr1 = Frozen(2)
  1108. fr2 = Frozen(3)
  1109. def g1(x):
  1110. return x.v
  1111. def g2(y):
  1112. return y.v
  1113. def h(x):
  1114. return x is not None
  1115. def h2(x):
  1116. return x is fr1
  1117. def f():
  1118. a = g1(fr1)
  1119. b = g2(fr2)
  1120. h(None)
  1121. return (h(fr1) + 10*h(fr2) + 100*a + 1000*b +
  1122. 10000*h2(fr1) + 100000*h2(fr2))
  1123. res = self.interpret(f, [])
  1124. assert res == 13211
  1125. def test_disjoint_pbcs_2(self):
  1126. class Frozen(object):
  1127. def __init__(self, v):
  1128. self.v = v
  1129. def _freeze_(self):
  1130. return True
  1131. fr1 = Frozen(1)
  1132. fr2 = Frozen(2)
  1133. fr3 = Frozen(3)
  1134. def getv(x):
  1135. return x.v
  1136. def h(x):
  1137. return (x is not None) + 2*(x is fr2) + 3*(x is fr3)
  1138. def f(n):
  1139. if n == 1:
  1140. fr = fr1
  1141. else:
  1142. fr = fr2
  1143. total = getv(fr)
  1144. if n == 3:
  1145. fr = fr3
  1146. h(None)
  1147. return total + 10*h(fr)
  1148. res = self.interpret(f, [3])
  1149. assert res == 42
  1150. def test_convert_multiple_to_single(self):
  1151. class A:
  1152. def meth(self, fr):
  1153. return 65
  1154. class B(A):
  1155. def meth(self, fr):
  1156. return 66
  1157. fr1 = Freezing()
  1158. fr2 = Freezing()
  1159. def f():
  1160. return A().meth(fr1) * B().meth(fr2)
  1161. res = self.interpret(f, [])
  1162. assert res == 65*66
  1163. def test_convert_multiple_to_single_method_of_frozen_pbc(self):
  1164. class A:
  1165. def meth(self, frmeth):
  1166. return frmeth(100)
  1167. class B(A):
  1168. def meth(self, frmeth):
  1169. return frmeth(1000)
  1170. fr1 = Freezing(); fr1.x = 65
  1171. fr2 = Freezing(); fr2.x = 66
  1172. def f():
  1173. return A().meth(fr1.mymethod) * B().meth(fr2.mymethod)
  1174. res = self.interpret(f, [])
  1175. assert res == 165 * 1066
  1176. def test_convert_none_to_frozen_pbc(self):
  1177. fr1 = Freezing(); fr1.x = 65
  1178. fr2 = Freezing(); fr2.y = 65
  1179. def g(fr):
  1180. return fr.x
  1181. def identity(z):
  1182. return z
  1183. def f(n): # NB. this crashes with n == 0
  1184. if n == 0:
  1185. fr = identity(None)
  1186. else:
  1187. fr = fr1
  1188. return g(fr)
  1189. res = self.interpret(f, [1])
  1190. assert res == 65
  1191. def test_multiple_attribute_access_patterns(self):
  1192. class Base(object):
  1193. pass
  1194. class A(Base):
  1195. value = 1000
  1196. def meth(self): return self.n + 1
  1197. class B(A):
  1198. def meth(self): return self.n + 2
  1199. class C(Base):
  1200. value = 2000
  1201. def meth(self): ShouldNotBeSeen
  1202. def AorB(n):
  1203. if n == 5: return A
  1204. else: return B
  1205. def BorC(n):
  1206. if n == 3: return B
  1207. else: return C
  1208. def f(n):
  1209. value = BorC(n).value
  1210. x = B()
  1211. x.n = 100
  1212. return value + AorB(n).meth(x)
  1213. for i in [1, 3, 5]:
  1214. res = self.interpret(f, [i])
  1215. assert res == f(i)
  1216. def test_function_as_frozen_pbc(self):
  1217. def f1(): pass
  1218. def f2(): pass
  1219. def choose(n):
  1220. if n == 1:
  1221. return f1
  1222. else:
  1223. return f2
  1224. def f(n):
  1225. return choose(n) is f1
  1226. res = self.interpret(f, [1])
  1227. assert res == True
  1228. res = self.interpret(f, [2])
  1229. assert res == False
  1230. def test_call_from_list(self):
  1231. def f0(n): return n+200
  1232. def f1(n): return n+192
  1233. def f2(n): return n+46
  1234. def f3(n): return n+2987
  1235. def f4(n): return n+217
  1236. lst = [f0, f1, f2, f3, f4]
  1237. def f(i, n):
  1238. return lst[i](n)
  1239. for i in range(5):
  1240. res = self.interpret(f, [i, 1000])
  1241. assert res == f(i, 1000)
  1242. def test_None_is_None(self):
  1243. def g():
  1244. return None
  1245. def f():
  1246. return g() is None
  1247. res = self.interpret(f, [])
  1248. assert res == True
  1249. def test_except_class_call(self):
  1250. class A:
  1251. pass # no constructor
  1252. def f():
  1253. try:
  1254. A()
  1255. IndexError()
  1256. return 12
  1257. except ValueError:
  1258. return 23
  1259. res = self.interpret(f, [])
  1260. assert res == 12
  1261. def test_exception_with_non_empty_baseclass(self):
  1262. class BE(Exception):
  1263. pass
  1264. class E1(BE):
  1265. pass
  1266. class E2(BE):
  1267. pass
  1268. def f(x):
  1269. if x:
  1270. e = E1()
  1271. else:
  1272. e = E2()
  1273. witness = E1()
  1274. witness.x = 42
  1275. e.x = 3
  1276. return witness.x
  1277. res = self.interpret(f, [0])
  1278. assert res == 42
  1279. res = self.interpret(f, [1])
  1280. assert res == 42
  1281. def test_funcornone_to_func(self):
  1282. def g(y):
  1283. return y*2
  1284. def f(x):
  1285. if x > 0:
  1286. g1 = g
  1287. else:
  1288. g1 = None
  1289. x += 1
  1290. if g1:
  1291. return g1(x)
  1292. else:
  1293. return -1
  1294. res = self.interpret(f, [20])
  1295. assert res == 42
  1296. def test_specialize_functionarg(self):
  1297. def f(x, y):
  1298. return x + y
  1299. def g(x, y, z):
  1300. return x + y + z
  1301. def functionarg(func, *extraargs):
  1302. return func(42, *extraargs)
  1303. functionarg._annspecialcase_ = "specialize:arg(0)"
  1304. def call_functionarg():
  1305. return functionarg(f, 1) + functionarg(g, 1, 2)
  1306. assert call_functionarg() == 2 * 42 + 4
  1307. res = self.interpret(call_functionarg, [])
  1308. assert res == 2 * 42 + 4
  1309. def test_convert_multiple_classes_to_single(self):
  1310. class A:
  1311. result = 321
  1312. def meth(self, n):
  1313. if n:
  1314. return A
  1315. else:
  1316. return B
  1317. class B(A):
  1318. result = 123
  1319. def meth(self, n):
  1320. return B
  1321. def f(n):
  1322. A().meth(n)
  1323. cls = B().meth(n)
  1324. return cls().result
  1325. res = self.interpret(f, [5])
  1326. assert res == 123
  1327. def test_is_among_functions(self):
  1328. def g1(): pass
  1329. def g2(): pass
  1330. def g3(): pass
  1331. def f(n):
  1332. if n > 5:
  1333. g = g2
  1334. else:
  1335. g = g1
  1336. g()
  1337. g3()
  1338. return g is g3
  1339. res = self.interpret(f, [2])
  1340. assert res == False
  1341. def test_is_among_functions_2(self):
  1342. def g1(): pass
  1343. def g2(): pass
  1344. def f(n):
  1345. if n > 5:
  1346. g = g2
  1347. else:
  1348. g = g1
  1349. g()
  1350. return g is g2
  1351. res = self.interpret(f, [2])
  1352. assert res == False
  1353. res = self.interpret(f, [8])
  1354. assert res == True
  1355. def test_is_among_functions_3(self):
  1356. def g0(): pass
  1357. def g1(): pass
  1358. def g2(): pass
  1359. def g3(): pass
  1360. def g4(): pass
  1361. def g5(): pass
  1362. def g6(): pass
  1363. def g7(): pass
  1364. glist = [g0, g1, g2, g3, g4, g5, g6, g7]
  1365. def f(n):
  1366. if n > 5:
  1367. g = g2
  1368. else:
  1369. g = g1
  1370. h = glist[n]
  1371. g()
  1372. h()
  1373. return g is h
  1374. res = self.interpret(f, [2])
  1375. assert res == False
  1376. res = self.interpret(f, [1])
  1377. assert res == True
  1378. res = self.interpret(f, [6])
  1379. assert res == False
  1380. def test_shrink_pbc_set(self):
  1381. def g1():
  1382. return 10
  1383. def g2():
  1384. return 20
  1385. def g3():
  1386. return 30
  1387. def h1(g): # g in {g1, g2}
  1388. return 1 + g()
  1389. def h2(g): # g in {g1, g2, g3}
  1390. return 2 + g()
  1391. def f(n):
  1392. if n > 5: g = g1
  1393. else: g = g2
  1394. if n % 2: h = h1
  1395. else: h = h2
  1396. res = h(g)
  1397. if n > 7: g = g3
  1398. h2(g)
  1399. return res
  1400. res = self.interpret(f, [7])
  1401. assert res == 11
  1402. def test_single_pbc_getattr(self):
  1403. class C:
  1404. def __init__(self, v1, v2):
  1405. self.v1 = v1
  1406. self.v2 = v2
  1407. def _freeze_(self):
  1408. return True
  1409. c1 = C(11, lambda: "hello")
  1410. c2 = C(22, lambda: 623)
  1411. def f1(l, c):
  1412. l.append(c.v1)
  1413. def f2(c):
  1414. return c.v2
  1415. def f3(c):
  1416. return c.v2
  1417. def g():
  1418. l = []
  1419. f1(l, c1)
  1420. f1(l, c2)
  1421. return f2(c1)(), f3(c2)()
  1422. res = self.interpret(g, [])
  1423. item0, item1 = self.ll_unpack_tuple(res, 2)
  1424. assert self.ll_to_string(item0) == "hello"
  1425. assert item1 == 623
  1426. def test_always_raising_methods(self):
  1427. class Base:
  1428. def m(self):
  1429. raise KeyError
  1430. class A(Base):
  1431. def m(self):
  1432. return 42
  1433. class B(Base):
  1434. pass
  1435. def f(n):
  1436. if n > 3:
  1437. o = A()
  1438. else:
  1439. o = B()
  1440. try:
  1441. o.m()
  1442. except KeyError:
  1443. assert 0
  1444. return B().m()
  1445. self.interpret_raises(KeyError, f, [7])
  1446. def test_possible_missing_attribute_access(self):
  1447. py.test.skip("Should explode or give some warning")
  1448. class Base(object):
  1449. pass
  1450. class A(Base):
  1451. a = 1
  1452. b = 2
  1453. class B(Base):
  1454. a = 2
  1455. b = 2
  1456. class C(Base):
  1457. b = 8
  1458. def f(n):
  1459. if n > 3:
  1460. x = A
  1461. elif n > 1:
  1462. x = B
  1463. else:
  1464. x = C
  1465. if n > 0:
  1466. return x.a
  1467. return 9
  1468. self.interpret(f, [int])
  1469. def test_funcpointer_default_value(self):
  1470. def foo(x): return x+1
  1471. class Foo:
  1472. func = None
  1473. def __init__(self, n):
  1474. if n == 1:
  1475. self.func = foo
  1476. def fn(n):
  1477. a = Foo(n)
  1478. if a.func:
  1479. return a.func(n)
  1480. return -1
  1481. res = self.interpret(fn, [0])
  1482. assert res == -1
  1483. def test_is_none(self):
  1484. from rpython.rlib.nonconst import NonConstant
  1485. def g(x):
  1486. return NonConstant(g) is None
  1487. res = self.interpret(g, [1])
  1488. assert not res
  1489. def test_pbc_of_classes_not_all_used(self):
  1490. class Base(object): pass
  1491. class A(Base): pass
  1492. class B(Base): pass
  1493. def poke(lst):
  1494. pass
  1495. def g():
  1496. A()
  1497. poke([A, B])
  1498. self.interpret(g, [])
  1499. def test_pbc_of_classes_isinstance_only(self):
  1500. class Base(object): pass
  1501. class ASub(Base): pass
  1502. def g():
  1503. x = Base()
  1504. return isinstance(x, ASub)
  1505. res = self.interpret(g, [])
  1506. assert res == False
  1507. def test_class___name__(self):
  1508. class Base(object): pass
  1509. class ASub(Base): pass
  1510. def g(n):
  1511. if n == 1:
  1512. x = Base()
  1513. else:
  1514. x = ASub()
  1515. return x.__class__.__name__
  1516. res = self.interpret(g, [1])
  1517. assert self.ll_to_string(res) == "Base"
  1518. res = self.interpret(g, [2])
  1519. assert self.ll_to_string(res) == "ASub"
  1520. def test_str_class(self):
  1521. class Base(object): pass
  1522. class ASub(Base): pass
  1523. def g(n):
  1524. if n == 1:
  1525. x = Base()
  1526. else:
  1527. x = ASub()
  1528. return str(x.__class__)
  1529. res = self.interpret(g, [1])
  1530. assert self.ll_to_string(res) == "Base"
  1531. res = self.interpret(g, [2])
  1532. assert self.ll_to_string(res) == "ASub"
  1533. def test_bug_callfamily(self):
  1534. def cb1():
  1535. xxx # never actually called
  1536. def cb2():
  1537. pass
  1538. def g(cb, result):
  1539. assert (cb is None) == (result == 0)
  1540. def h(cb):
  1541. cb()
  1542. def f():
  1543. g(None, 0)
  1544. g(cb1, 1)
  1545. g(cb2, 2)
  1546. h(cb2)
  1547. return 42
  1548. res = self.interpret(f, [])
  1549. assert res == 42
  1550. # ____________________________________________________________
  1551. def test_hlinvoke_simple():
  1552. def f(a,b):
  1553. return a + b
  1554. from rpython.translator import translator
  1555. from rpython.annotator import annrpython
  1556. a = annrpython.RPythonAnnotator()
  1557. s_f = a.bookkeeper.immutablevalue(f)
  1558. a.bookkeeper.emulate_pbc_call('f', s_f, [annmodel.SomeInteger(), annmodel.SomeInteger()])
  1559. a.complete()
  1560. from rpython.rtyper import rtyper
  1561. rt = rtyper.RPythonTyper(a)
  1562. rt.specialize()
  1563. def ll_h(R, f, x):
  1564. from rpython.rlib.objectmodel import hlinvoke
  1565. return hlinvoke(R, f, x, 2)
  1566. from rpython.rtyper import annlowlevel
  1567. r_f = rt.getrepr(s_f)
  1568. s_R = a.bookkeeper.immutablevalue(r_f)
  1569. s_ll_f = lltype_to_annotation(r_f.lowleveltype)
  1570. ll_h_graph = annlowlevel.annotate_lowlevel_helper(a, ll_h, [s_R, s_ll_f, annmodel.SomeInteger()])
  1571. assert a.binding(ll_h_graph.getreturnvar()).knowntype == int
  1572. rt.specialize_more_blocks()
  1573. from rpython.rtyper.llinterp import LLInterpreter
  1574. interp = LLInterpreter(rt)
  1575. #a.translator.view()
  1576. res = interp.eval_graph(ll_h_graph, [None, None, 3])
  1577. assert res == 5
  1578. def test_hlinvoke_simple2():
  1579. def f1(a,b):
  1580. return a + b
  1581. def f2(a,b):
  1582. return a - b
  1583. from rpython.annotator import annrpython
  1584. a = annrpython.RPythonAnnotator()
  1585. def g(i):
  1586. if i:
  1587. f = f1
  1588. else:
  1589. f = f2
  1590. f(5,4)
  1591. f(3,2)
  1592. a.build_types(g, [int])
  1593. from rpython.rtyper import rtyper
  1594. rt = rtyper.RPythonTyper(a)
  1595. rt.specialize()
  1596. def ll_h(R, f, x):
  1597. from rpython.rlib.objectmodel import hlinvoke
  1598. return hlinvoke(R, f, x, 2)
  1599. from rpython.rtyper import annlowlevel
  1600. f1desc = a.bookkeeper.getdesc(f1)
  1601. f2desc = a.bookkeeper.getdesc(f2)
  1602. s_f = annmodel.SomePBC([f1desc, f2desc])
  1603. r_f = rt.getrepr(s_f)
  1604. s_R = a.bookkeeper.immutablevalue(r_f)
  1605. s_ll_f = lltype_to_annotation(r_f.lowleveltype)
  1606. ll_h_graph= annlowlevel.annotate_lowlevel_helper(a, ll_h, [s_R, s_ll_f, annmodel.SomeInteger()])
  1607. assert a.binding(ll_h_graph.getreturnvar()).knowntype == int
  1608. rt.specialize_more_blocks()
  1609. from rpython.rtyper.llinterp import LLInterpreter
  1610. interp = LLInterpreter(rt)
  1611. #a.translator.view()
  1612. res = interp.eval_graph(ll_h_graph, [None, r_f.convert_desc(f1desc), 3])
  1613. assert res == 5
  1614. res = interp.eval_graph(ll_h_graph, [None, r_f.convert_desc(f2desc), 3])
  1615. assert res == 1
  1616. def test_hlinvoke_hltype():
  1617. class A(object):
  1618. def __init__(self, v):
  1619. self.v = v
  1620. def f(a):
  1621. return A(a)
  1622. from rpython.annotator import annrpython
  1623. a = annrpython.RPythonAnnotator()
  1624. def g():
  1625. a = A(None)
  1626. f(a)
  1627. a.build_types(g, [])
  1628. from rpython.rtyper import rtyper
  1629. from rpython.rtyper import rclass
  1630. rt = rtyper.RPythonTyper(a)
  1631. rt.specialize()
  1632. def ll_h(R, f, a):
  1633. from rpython.rlib.objectmodel import hlinvoke
  1634. return hlinvoke(R, f, a)
  1635. from rpython.rtyper import annlowlevel
  1636. s_f = a.bookkeeper.immutablevalue(f)
  1637. r_f = rt.getrepr(s_f)
  1638. s_R = a.bookkeeper.immutablevalue(r_f)
  1639. s_ll_f = lltype_to_annotation(r_f.lowleveltype)
  1640. A_repr = rclass.getinstancerepr(rt, a.bookkeeper.getdesc(A).
  1641. getuniqueclassdef())
  1642. ll_h_graph = annlowlevel.annotate_lowlevel_helper(
  1643. a, ll_h, [s_R, s_ll_f, SomePtr(A_repr.lowleveltype)])
  1644. s = a.binding(ll_h_graph.getreturnvar())
  1645. assert s.ll_ptrtype == A_repr.lowleveltype
  1646. rt.specialize_more_blocks()
  1647. from rpython.rtyper.llinterp import LLInterpreter
  1648. interp = LLInterpreter(rt)
  1649. #a.translator.view()
  1650. c_a = A_repr.convert_const(A(None))
  1651. res = interp.eval_graph(ll_h_graph, [None, None, c_a])
  1652. assert typeOf(res) == A_repr.lowleveltype
  1653. def test_hlinvoke_method_hltype():
  1654. class A(object):
  1655. def __init__(self, v):
  1656. self.v = v
  1657. class Impl(object):
  1658. def f(self, a):
  1659. return A(a)
  1660. from rpython.annotator import annrpython
  1661. a = annrpython.RPythonAnnotator()
  1662. def g():
  1663. a = A(None)
  1664. i = Impl()
  1665. i.f(a)
  1666. a.build_types(g, [])
  1667. from rpython.rtyper import rtyper
  1668. from rpython.rtyper import rclass
  1669. rt = rtyper.RPythonTyper(a)
  1670. rt.specialize()
  1671. def ll_h(R, f, a):
  1672. from rpython.rlib.objectmodel import hlinvoke
  1673. return hlinvoke(R, f, a)
  1674. from rpython.rtyper import annlowlevel
  1675. Impl_def = a.bookkeeper.getdesc(Impl).getuniqueclassdef()
  1676. Impl_f_desc = a.bookkeeper.getmethoddesc(
  1677. a.bookkeeper.getdesc(Impl.f.im_func),
  1678. Impl_def,
  1679. Impl_def,
  1680. 'f')
  1681. s_f = annmodel.SomePBC([Impl_f_desc])
  1682. r_f = rt.getrepr(s_f)
  1683. s_R = a.bookkeeper.immutablevalue(r_f)
  1684. s_ll_f = lltype_to_annotation(r_f.lowleveltype)
  1685. A_repr = rclass.getinstancerepr(rt, a.bookkeeper.getdesc(A).
  1686. getuniqueclassdef())
  1687. ll_h_graph = annlowlevel.annotate_lowlevel_helper(
  1688. a, ll_h, [s_R, s_ll_f, SomePtr(A_repr.lowleveltype)])
  1689. s = a.binding(ll_h_graph.getreturnvar())
  1690. assert s.ll_ptrtype == A_repr.lowleveltype
  1691. rt.specialize_more_blocks()
  1692. from rpython.rtyper.llinterp import LLInterpreter
  1693. interp = LLInterpreter(rt)
  1694. # low-level value is just the instance
  1695. c_f = rclass.getinstancerepr(rt, Impl_def).convert_const(Impl())
  1696. c_a = A_repr.convert_const(A(None))
  1697. res = interp.eval_graph(ll_h_graph, [None, c_f, c_a])
  1698. assert typeOf(res) == A_repr.lowleveltype
  1699. def test_hlinvoke_pbc_method_hltype():
  1700. class A(object):
  1701. def __init__(self, v):
  1702. self.v = v
  1703. class Impl(object):
  1704. def _freeze_(self):
  1705. return True
  1706. def f(self, a):
  1707. return A(a)
  1708. from rpython.annotator import annrpython
  1709. a = annrpython.RPythonAnnotator()
  1710. i = Impl()
  1711. def g():
  1712. a = A(None)
  1713. i.f(a)
  1714. a.build_types(g, [])
  1715. from rpython.rtyper import rtyper
  1716. from rpython.rtyper import rclass
  1717. rt = rtyper.RPythonTyper(a)
  1718. rt.specialize()
  1719. def ll_h(R, f, a):
  1720. from rpython.rlib.objectmodel import hlinvoke
  1721. return hlinvoke(R, f, a)
  1722. from rpython.rtyper import annlowlevel
  1723. s_f = a.bookkeeper.immutablevalue(i.f)
  1724. r_f = rt.getrepr(s_f)
  1725. s_R = a.bookkeeper.immutablevalue(r_f)
  1726. s_ll_f = lltype_to_annotation(r_f.lowleveltype)
  1727. A_repr = rclass.getinstancerepr(rt, a.bookkeeper.getdesc(A).
  1728. getuniqueclassdef())
  1729. ll_h_graph = annlowlevel.annotate_lowlevel_helper(
  1730. a, ll_h, [s_R, s_ll_f, SomePtr(A_repr.lowleveltype)])
  1731. s = a.binding(ll_h_graph.getreturnvar())
  1732. assert s.ll_ptrtype == A_repr.lowleveltype
  1733. rt.specialize_more_blocks()
  1734. from rpython.rtyper.llinterp import LLInterpreter
  1735. interp = LLInterpreter(rt)
  1736. c_f = r_f.convert_const(i.f)
  1737. c_a = A_repr.convert_const(A(None))
  1738. res = interp.eval_graph(ll_h_graph, [None, c_f, c_a])
  1739. assert typeOf(res) == A_repr.lowleveltype
  1740. # ____________________________________________________________
  1741. class TestSmallFuncSets(TestRPBC):
  1742. def setup_class(cls):
  1743. from rpython.config.translationoption import get_combined_translation_config
  1744. cls.config = get_combined_translation_config(translating=True)
  1745. cls.config.translation.withsmallfuncsets = 3
  1746. def interpret(self, fn, args, **kwds):
  1747. kwds['config'] = self.config
  1748. return TestRPBC.interpret(fn, args, **kwds)
  1749. def test_class_missing_base_method_should_crash(self):
  1750. class Base(object):
  1751. pass # no method 'm' here
  1752. class A(Base):
  1753. def m(self):
  1754. return 42
  1755. class B(Base):
  1756. def m(self):
  1757. return 63
  1758. def g(n):
  1759. if n == 1:
  1760. return A()
  1761. elif n == 2:
  1762. return B()
  1763. else:
  1764. return Base()
  1765. def f(n):
  1766. return g(n).m()
  1767. assert self.interpret(f, [1]) == 42
  1768. assert self.interpret(f, [2]) == 63
  1769. e = py.test.raises(ValueError, self.interpret, f, [3])
  1770. assert str(e.value).startswith(r"exit case '\xff' not found")
  1771. @py.test.mark.parametrize('limit', [3, 5])
  1772. def test_conversion_table(self, limit):
  1773. # with limit==3, check conversion from Char to Ptr(Func).
  1774. # with limit>3, check conversion from Char to Char.
  1775. def f1():
  1776. return 111
  1777. def f2():
  1778. return 222
  1779. def f3():
  1780. return 333
  1781. def g(n):
  1782. if n & 1:
  1783. return f1
  1784. else:
  1785. return f2
  1786. def f(n):
  1787. x = g(n) # can be f1 or f2
  1788. if n > 10:
  1789. x = f3 # now can be f1 or f2 or f3
  1790. return x()
  1791. from rpython.config.translationoption import get_combined_translation_config
  1792. self.config = get_combined_translation_config(translating=True)
  1793. self.config.translation.withsmallfuncsets = limit
  1794. assert self.interpret(f, [3]) == 111
  1795. assert self.interpret(f, [4]) == 222
  1796. assert self.interpret(f, [13]) == 333
  1797. assert self.interpret(f, [14]) == 333
  1798. def test_smallfuncsets_basic():
  1799. from rpython.translator.translator import TranslationContext, graphof
  1800. from rpython.config.translationoption import get_combined_translation_config
  1801. from rpython.rtyper.llinterp import LLInterpreter
  1802. config = get_combined_translation_config(translating=True)
  1803. config.translation.withsmallfuncsets = 10
  1804. def g(x):
  1805. return x + 1
  1806. def h(x):
  1807. return x - 1
  1808. def f(x, y):
  1809. if y > 0:
  1810. func = g
  1811. else:
  1812. func = h
  1813. return func(x)
  1814. t = TranslationContext(config=config)
  1815. a = t.buildannotator()
  1816. a.build_types(f, [int, int])
  1817. rtyper = t.buildrtyper()
  1818. rtyper.specialize()
  1819. graph = graphof(t, f)
  1820. interp = LLInterpreter(rtyper)
  1821. res = interp.eval_graph(graph, [0, 0])
  1822. assert res == -1
  1823. res = interp.eval_graph(graph, [0, 1])
  1824. assert res == 1