PageRenderTime 66ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/Lib/test/test_llvm.py

http://unladen-swallow.googlecode.com/
Python | 4509 lines | 4472 code | 22 blank | 15 comment | 23 complexity | c6186551698179e045ff3bb4d270ec9f MD5 | raw file
Possible License(s): 0BSD, BSD-3-Clause
  1. # Tests for our minimal LLVM wrappers
  2. import __future__
  3. from test import test_dynamic
  4. from test import test_support
  5. try:
  6. import _llvm
  7. except ImportError:
  8. raise test_support.TestSkipped("not built against LLVM")
  9. import __builtin__
  10. import contextlib
  11. import functools
  12. import gc
  13. import sys
  14. import types
  15. import unittest
  16. import weakref
  17. # Calculate default LLVM optimization level.
  18. def _foo():
  19. pass
  20. DEFAULT_OPT_LEVEL = _foo.__code__.co_optimization
  21. del _foo
  22. # Various constants that feed into the hotness model.
  23. HOTNESS_CALL = 10 # Points for a function entry.
  24. HOTNESS_LOOP = 1 # Points for a taken loop backedge.
  25. JIT_SPIN_COUNT = _llvm.get_hotness_threshold() / HOTNESS_CALL + 1000
  26. JIT_OPT_LEVEL = sys.flags.optimize if sys.flags.optimize > 2 else 2
  27. @contextlib.contextmanager
  28. def set_jit_control(new_level):
  29. orig_level = _llvm.get_jit_control()
  30. _llvm.set_jit_control(new_level)
  31. try:
  32. yield
  33. finally:
  34. _llvm.set_jit_control(orig_level)
  35. def at_each_optimization_level(func):
  36. """Decorator for test functions, to run them at each optimization level."""
  37. levels = [None, -1, 0, 1, 2]
  38. if DEFAULT_OPT_LEVEL != -1:
  39. levels = [level for level in levels if level >= DEFAULT_OPT_LEVEL]
  40. @functools.wraps(func)
  41. def result(self):
  42. for level in levels:
  43. func(self, level)
  44. return result
  45. def compile_for_llvm(function_name, def_string, optimization_level=-1,
  46. globals_dict=None):
  47. """Compiles function_name, defined in def_string to be run through LLVM.
  48. Compiles and runs def_string in a temporary namespace, pulls the
  49. function named 'function_name' out of that namespace, optimizes it
  50. at level 'optimization_level', -1 for the default optimization,
  51. and marks it to be JITted and run through LLVM.
  52. """
  53. namespace = {}
  54. if globals_dict is None:
  55. globals_dict = globals()
  56. exec def_string in globals_dict, namespace
  57. func = namespace[function_name]
  58. if optimization_level is not None:
  59. if optimization_level >= DEFAULT_OPT_LEVEL:
  60. func.__code__.co_optimization = optimization_level
  61. func.__code__.co_use_jit = True
  62. return func
  63. def spin_until_hot(func, *training_args):
  64. """Compile a function by calling it until it is hot.
  65. Calls a function JIT_SPIN_COUNT times with each of training_args as
  66. arguments and returns a list containing the return values from each
  67. iteration. When testing feedback directed optimizations, this function is
  68. used to gather feedback in the code object before performaing JIT
  69. compilation.
  70. To inject different training arguments into the function while it is being
  71. spun up, you can pass multiple tuples of arguments to this function, like
  72. so:
  73. spin_until_hot(mul, [1, 3], [1.0, 3.0])
  74. This will cause the function to be trained on both integer and floating
  75. point inputs.
  76. """
  77. if not training_args: # An empty training_args isn't what you meant.
  78. training_args = [[]]
  79. results = []
  80. with set_jit_control("whenhot"):
  81. for _ in xrange(JIT_SPIN_COUNT):
  82. for args in training_args:
  83. results.append(func(*args))
  84. return results
  85. class ExtraAssertsTestCase(unittest.TestCase):
  86. def assertRaisesWithArgs(self, expected_exception_type,
  87. expected_args, f, *args, **kwargs):
  88. try:
  89. f(*args, **kwargs)
  90. except expected_exception_type, real_exception:
  91. pass
  92. else:
  93. self.fail("%r not raised" % expected_exception_type)
  94. self.assertEquals(real_exception.args, expected_args)
  95. def assertContains(self, obj, container):
  96. if obj not in container:
  97. self.fail("%r not found in %r" % (obj, container))
  98. def assertNotContains(self, obj, container):
  99. if obj in container:
  100. self.fail("%r found in %r" % (obj, container))
  101. class LlvmTestCase(unittest.TestCase):
  102. """Common base class for LLVM-focused tests.
  103. Features provided:
  104. - Assert that the code doesn't bail to the interpreter.
  105. """
  106. def setUp(self):
  107. sys.setbailerror(True)
  108. self._old_jit_control = _llvm.get_jit_control()
  109. _llvm.set_jit_control("whenhot")
  110. def tearDown(self):
  111. sys.setbailerror(False)
  112. _llvm.set_jit_control(self._old_jit_control)
  113. class GeneralCompilationTests(ExtraAssertsTestCase, LlvmTestCase):
  114. def test_uncreatable(self):
  115. # Functions can only be created by their static factories.
  116. self.assertRaises(TypeError, _llvm._function)
  117. def test_use_llvm(self):
  118. # Regression test: setting co_use_jit without setting an optimization
  119. # level used to segfault when the function was called.
  120. def foo():
  121. return 5
  122. foo.__code__.co_use_jit = True
  123. foo()
  124. @at_each_optimization_level
  125. def test_llvm_compile(self, level):
  126. # Makes no sense at level None
  127. if level is None:
  128. return
  129. def f(x):
  130. pass
  131. f = _llvm.compile(f.func_code, level)
  132. self.assertTrue(isinstance(f, _llvm._function))
  133. self.assertRaises(TypeError, _llvm.compile, f, level)
  134. def test_co_llvm(self):
  135. def f():
  136. return 1 + 2
  137. spin_until_hot(f, [])
  138. str_co_llvm = str(f.__code__.co_llvm)
  139. # After code objects are compiled to machine code, the IR form
  140. # is mostly cleared out. However, we want to be able to print
  141. # the IR generated for any particular function, so this tests
  142. # that it gets regenerated when we ask for its string
  143. # representation. The cleared-out form is around 5 lines
  144. # long, while all full functions are much longer.
  145. self.assertTrue(10 < len(str_co_llvm.split('\n')), msg=str_co_llvm)
  146. @at_each_optimization_level
  147. def test_run_simple_function(self, level):
  148. foo = compile_for_llvm("foo", """
  149. def foo():
  150. pass
  151. """, level)
  152. self.assertEquals(None, foo())
  153. @at_each_optimization_level
  154. def test_constants(self, level):
  155. foo = compile_for_llvm("foo", """
  156. def foo(x):
  157. if x: x[...]
  158. return [1, 2L, 3.2, 7j, (), "Hello", u"Hello", None]
  159. """, level)
  160. self.assertEquals([1, 2L, 3.2, 7j, (), "Hello", u"Hello", None],
  161. foo(False))
  162. def test_same_named_functions_coexist(self):
  163. foo1 = compile_for_llvm("foo", """
  164. def foo(a):
  165. return a
  166. """)
  167. foo2 = compile_for_llvm("foo", """
  168. def foo():
  169. return 7
  170. """)
  171. self.assertEquals("Hello", foo1("Hello"))
  172. self.assertEquals(7, foo2())
  173. def test_stack_pointer_optimized_to_register(self):
  174. def test_func():
  175. # We may have to add opcode uses to here as we find things
  176. # that break the stack pointer optimization.
  177. return sum(range(*[1, 10, 3]))
  178. # Run mem2reg.
  179. test_func.__code__.co_optimization = 2
  180. self.assertFalse("%stack_pointer_addr = alloca"
  181. in str(test_func.__code__.co_llvm))
  182. # -Xjit=always will cause this test to always fail.
  183. if _llvm.get_jit_control() != "always":
  184. def test_fetch_unset_co_llvm(self):
  185. def test_func():
  186. pass
  187. test_func.__code__.co_use_jit = True
  188. # Just setting co_use_jit doesn't force code generation.
  189. self.assertEqual(str(test_func.__code__.co_llvm), "None")
  190. @at_each_optimization_level
  191. def test_return_arg(self, level):
  192. foo = compile_for_llvm("foo", """
  193. def foo(a):
  194. return a
  195. """, level)
  196. self.assertEquals(3, foo(3))
  197. self.assertEquals("Hello", foo("Hello"))
  198. @at_each_optimization_level
  199. def test_unbound_local(self, level):
  200. foo = compile_for_llvm("foo", """
  201. def foo():
  202. a = a
  203. """, level)
  204. try:
  205. foo()
  206. except UnboundLocalError as e:
  207. self.assertEquals(
  208. str(e), "local variable 'a' referenced before assignment")
  209. else:
  210. self.fail("Expected UnboundLocalError")
  211. @at_each_optimization_level
  212. def test_assign(self, level):
  213. foo = compile_for_llvm("foo", """
  214. def foo(a):
  215. b = a
  216. return b
  217. """, level)
  218. self.assertEquals(3, foo(3))
  219. self.assertEquals("Hello", foo("Hello"))
  220. @at_each_optimization_level
  221. def test_raising_getiter(self, level):
  222. class RaisingIter(object):
  223. def __iter__(self):
  224. raise RuntimeError
  225. loop = compile_for_llvm("loop", """
  226. def loop(range):
  227. for i in range:
  228. pass
  229. """, level)
  230. self.assertRaises(RuntimeError, loop, RaisingIter())
  231. @at_each_optimization_level
  232. def test_raising_next(self, level):
  233. class RaisingNext(object):
  234. def __iter__(self):
  235. return self
  236. def next(self):
  237. raise RuntimeError
  238. loop = compile_for_llvm("loop", """
  239. def loop(range):
  240. for i in range:
  241. pass
  242. """, level)
  243. self.assertRaises(RuntimeError, loop, RaisingNext())
  244. @at_each_optimization_level
  245. def test_import_name(self, level):
  246. importer = compile_for_llvm("importer", """
  247. def importer():
  248. import os
  249. return os
  250. """, level)
  251. import os
  252. self.assertEqual(importer(), os)
  253. @at_each_optimization_level
  254. def test_loop(self, level):
  255. loop = compile_for_llvm("loop", """
  256. def loop(range):
  257. for i in range:
  258. pass
  259. """, level)
  260. r = iter(range(12))
  261. self.assertEquals(None, loop(r))
  262. self.assertRaises(StopIteration, next, r)
  263. @at_each_optimization_level
  264. def test_return_from_loop(self, level):
  265. loop = compile_for_llvm("loop", """
  266. def loop(range):
  267. for i in range:
  268. return i
  269. """, level)
  270. self.assertEquals(1, loop([1,2,3]))
  271. @at_each_optimization_level
  272. def test_finally(self, level):
  273. cleanup = compile_for_llvm("cleanup", """
  274. def cleanup(obj):
  275. try:
  276. return 3
  277. finally:
  278. obj['x'] = 2
  279. """, level)
  280. obj = {}
  281. self.assertEquals(3, cleanup(obj))
  282. self.assertEquals({'x': 2}, obj)
  283. @at_each_optimization_level
  284. def test_nested_finally(self, level):
  285. cleanup = compile_for_llvm("cleanup", """
  286. def cleanup(obj):
  287. try:
  288. try:
  289. return 3
  290. finally:
  291. obj['x'] = 2
  292. finally:
  293. obj['y'] = 3
  294. """, level)
  295. obj = {}
  296. self.assertEquals(3, cleanup(obj))
  297. self.assertEquals({'x': 2, 'y': 3}, obj)
  298. @at_each_optimization_level
  299. def test_finally_fallthrough(self, level):
  300. cleanup = compile_for_llvm("cleanup", """
  301. def cleanup(obj):
  302. try:
  303. obj['y'] = 3
  304. finally:
  305. obj['x'] = 2
  306. return 3
  307. """, level)
  308. obj = {}
  309. self.assertEquals(3, cleanup(obj))
  310. self.assertEquals({'x': 2, 'y': 3}, obj)
  311. @at_each_optimization_level
  312. def test_exception_out_of_finally(self, level):
  313. cleanup = compile_for_llvm("cleanup", """
  314. def cleanup(obj):
  315. try:
  316. obj['x'] = 2
  317. finally:
  318. a = a
  319. obj['y'] = 3
  320. return 3
  321. """, level)
  322. obj = {}
  323. self.assertRaises(UnboundLocalError, cleanup, obj)
  324. self.assertEquals({'x': 2}, obj)
  325. @at_each_optimization_level
  326. def test_exception_through_finally(self, level):
  327. cleanup = compile_for_llvm("cleanup", """
  328. def cleanup(obj):
  329. try:
  330. a = a
  331. finally:
  332. obj['x'] = 2
  333. """, level)
  334. obj = {}
  335. self.assertRaises(UnboundLocalError, cleanup, obj)
  336. self.assertEquals({'x': 2}, obj)
  337. @at_each_optimization_level
  338. def test_return_in_finally_overrides(self, level):
  339. cleanup = compile_for_llvm("cleanup", """
  340. def cleanup():
  341. try:
  342. return 3
  343. finally:
  344. return 2
  345. """, level)
  346. self.assertEquals(2, cleanup())
  347. @at_each_optimization_level
  348. def test_except(self, level):
  349. catch = compile_for_llvm("catch", """
  350. def catch(obj):
  351. try:
  352. raise ZeroDivisionError
  353. except:
  354. obj["x"] = 2
  355. """, level)
  356. obj = {}
  357. self.assertEquals(None, catch(obj))
  358. self.assertEquals({"x": 2}, obj)
  359. @at_each_optimization_level
  360. def test_filtered_except(self, level):
  361. catch = compile_for_llvm("catch", """
  362. def catch(exc_type, obj):
  363. try:
  364. 1 / 0
  365. except exc_type:
  366. obj["x"] = 2
  367. """, level)
  368. obj = {}
  369. self.assertEquals(None, catch(ZeroDivisionError, obj))
  370. self.assertEquals({"x": 2}, obj)
  371. obj = {}
  372. self.assertRaises(ZeroDivisionError, catch, UnboundLocalError, obj)
  373. self.assertEquals({}, obj)
  374. @at_each_optimization_level
  375. def test_filtered_except_var(self, level):
  376. catch = compile_for_llvm("catch", """
  377. def catch():
  378. try:
  379. 1 / 0
  380. except ZeroDivisionError, exc:
  381. return exc
  382. """, level)
  383. exc = catch()
  384. self.assertEquals(ZeroDivisionError, type(exc))
  385. self.assertEquals(('integer division or modulo by zero',), exc.args)
  386. @at_each_optimization_level
  387. def test_except_skipped_on_fallthrough(self, level):
  388. catch = compile_for_llvm("catch", """
  389. def catch(obj):
  390. try:
  391. obj["x"] = 2
  392. except:
  393. obj["y"] = 3
  394. return 7
  395. """, level)
  396. obj = {}
  397. self.assertEquals(7, catch(obj))
  398. self.assertEquals({"x": 2}, obj)
  399. @at_each_optimization_level
  400. def test_else_hit_on_fallthrough(self, level):
  401. catch = compile_for_llvm("catch", """
  402. def catch(obj):
  403. try:
  404. obj["x"] = 2
  405. except:
  406. obj["y"] = 3
  407. else:
  408. obj["z"] = 4
  409. return 7
  410. """, level)
  411. obj = {}
  412. self.assertEquals(7, catch(obj))
  413. self.assertEquals({"x": 2, "z": 4}, obj)
  414. @at_each_optimization_level
  415. def test_else_skipped_on_catch(self, level):
  416. catch = compile_for_llvm("catch", """
  417. def catch(obj):
  418. try:
  419. a = a
  420. except:
  421. obj["y"] = 3
  422. else:
  423. obj["z"] = 4
  424. return 7
  425. """, level)
  426. obj = {}
  427. self.assertEquals(7, catch(obj))
  428. self.assertEquals({"y": 3}, obj)
  429. @at_each_optimization_level
  430. def test_raise_from_except(self, level):
  431. catch = compile_for_llvm("catch", """
  432. def catch(obj):
  433. try:
  434. raise ZeroDivisionError
  435. except:
  436. a = a
  437. obj["x"] = 2
  438. """, level)
  439. obj = {}
  440. self.assertRaises(UnboundLocalError, catch, obj)
  441. self.assertEquals({}, obj)
  442. @at_each_optimization_level
  443. def test_nested_except(self, level):
  444. catch = compile_for_llvm("catch", """
  445. def catch(obj):
  446. try:
  447. try:
  448. 1 / 0
  449. except:
  450. obj["x"] = 2
  451. a = a
  452. except:
  453. obj["y"] = 3
  454. """, level)
  455. obj = {}
  456. self.assertEquals(None, catch(obj))
  457. self.assertEquals({"x": 2, "y": 3}, obj)
  458. @at_each_optimization_level
  459. def test_nested_except_skipped_on_fallthrough(self, level):
  460. catch = compile_for_llvm("catch", """
  461. def catch(obj):
  462. try:
  463. try:
  464. raise ZeroDivisionError
  465. except:
  466. obj["x"] = 2
  467. except:
  468. obj["y"] = 3
  469. """, level)
  470. obj = {}
  471. self.assertEquals(None, catch(obj))
  472. self.assertEquals({"x": 2}, obj)
  473. @at_each_optimization_level
  474. def test_nested_finally_doesnt_block_catch(self, level):
  475. # Raise from the try.
  476. catch = compile_for_llvm("catch", """
  477. def catch(obj):
  478. try:
  479. try:
  480. 1 / 0
  481. finally:
  482. obj["x"] = 2
  483. except:
  484. obj["y"] = 3
  485. """, level)
  486. obj = {}
  487. self.assertEquals(None, catch(obj))
  488. self.assertEquals({"x": 2, "y": 3}, obj)
  489. # And raise from the finally.
  490. catch = compile_for_llvm("catch", """
  491. def catch(obj):
  492. try:
  493. try:
  494. obj["x"] = 2
  495. finally:
  496. raise ZeroDivisionError
  497. except:
  498. obj["y"] = 3
  499. """, level)
  500. obj = {}
  501. self.assertEquals(None, catch(obj))
  502. self.assertEquals({"x": 2, "y": 3}, obj)
  503. @at_each_optimization_level
  504. def test_nested_except_goes_through_finally(self, level):
  505. # Raise from the try.
  506. catch = compile_for_llvm("catch", """
  507. def catch(obj):
  508. try:
  509. try:
  510. 1 / 0
  511. except:
  512. obj["x"] = 2
  513. finally:
  514. obj["y"] = 3
  515. """, level)
  516. obj = {}
  517. self.assertEquals(None, catch(obj))
  518. self.assertEquals({"x": 2, "y": 3}, obj)
  519. # And raise from the except.
  520. catch = compile_for_llvm("catch", """
  521. def catch(obj):
  522. try:
  523. try:
  524. raise UnboundLocalError
  525. except:
  526. 1 / 0
  527. finally:
  528. obj["y"] = 3
  529. """, level)
  530. obj = {}
  531. self.assertRaises(ZeroDivisionError, catch, obj)
  532. self.assertEquals({"y": 3}, obj)
  533. @at_each_optimization_level
  534. def test_finally_in_finally(self, level):
  535. catch = compile_for_llvm("catch", """
  536. def catch(obj):
  537. try:
  538. raise ZeroDivisionError
  539. finally:
  540. try:
  541. a = a
  542. finally:
  543. obj["x"] = 2
  544. """, level)
  545. obj = {}
  546. self.assertRaises(UnboundLocalError, catch, obj)
  547. self.assertEquals({"x": 2}, obj)
  548. @at_each_optimization_level
  549. def test_subexception_caught_in_finally(self, level):
  550. catch = compile_for_llvm("catch", """
  551. def catch(obj):
  552. try:
  553. 1 / 0
  554. finally:
  555. try:
  556. a = a
  557. except:
  558. obj["x"] = 2
  559. """, level)
  560. obj = {}
  561. self.assertRaises(ZeroDivisionError, catch, obj)
  562. self.assertEquals({"x": 2}, obj)
  563. @at_each_optimization_level
  564. def test_delete_fast(self, level):
  565. delit = compile_for_llvm('delit', """
  566. def delit(x):
  567. y = 2
  568. z = 3
  569. del y
  570. del x
  571. return z
  572. """, level)
  573. self.assertEquals(delit(1), 3)
  574. useit = compile_for_llvm('useit', """
  575. def useit(x):
  576. del x
  577. return x
  578. """, level)
  579. self.assertRaises(UnboundLocalError, useit, 1)
  580. misuseit = compile_for_llvm('misuseit', 'def misuseit(x): del y',
  581. level)
  582. self.assertRaises(UnboundLocalError, misuseit, 1)
  583. reuseit = compile_for_llvm('reuseit', """
  584. def reuseit(x):
  585. del x
  586. x = 3
  587. return x
  588. """, level)
  589. self.assertEquals(reuseit(1), 3)
  590. @at_each_optimization_level
  591. def test_call_function(self, level):
  592. f1 = compile_for_llvm("f1", "def f1(x): return x()", level)
  593. self.assertEquals(f1(lambda: 5), 5)
  594. def raise_exc():
  595. raise ValueError
  596. self.assertRaises(ValueError, f1, raise_exc)
  597. f2 = compile_for_llvm("f2", "def f2(x, y, z): return x(y, 2, z)",
  598. level)
  599. self.assertEquals(f2(lambda *args: args, 1, 3), (1, 2, 3))
  600. f3 = compile_for_llvm("f3", "def f3(x, y, z): return x(y(z()))",
  601. level)
  602. self.assertEquals(f3(lambda x: x+1, lambda x: x+2, lambda: 0), 3)
  603. @at_each_optimization_level
  604. def test_load_global(self, level):
  605. our_globals = dict(globals()) # Isolate the test's global effects.
  606. testvalue = 'test global value'
  607. loadglobal = compile_for_llvm('loadglobal',
  608. 'def loadglobal(): return testvalue',
  609. level, our_globals)
  610. our_globals['testvalue'] = testvalue
  611. self.assertEquals(loadglobal(), testvalue)
  612. loadbuiltin = compile_for_llvm('loadbuiltin',
  613. 'def loadbuiltin(): return str',
  614. level)
  615. self.assertEquals(loadbuiltin(), str)
  616. nosuchglobal = compile_for_llvm('nosuchglobal', '''
  617. def nosuchglobal():
  618. return there_better_be_no_such_global
  619. ''', level)
  620. self.assertRaises(NameError, nosuchglobal)
  621. @at_each_optimization_level
  622. def test_store_global(self, level):
  623. our_globals = dict(globals()) # Isolate the test's global effects.
  624. setglobal = compile_for_llvm('setglobal', '''
  625. def setglobal(x):
  626. global _test_global
  627. _test_global = x
  628. ''', level, our_globals)
  629. testvalue = "test global value"
  630. self.assertTrue('_test_global' not in our_globals)
  631. setglobal(testvalue)
  632. self.assertContains('_test_global', our_globals)
  633. self.assertEquals(our_globals['_test_global'], testvalue)
  634. @at_each_optimization_level
  635. def test_delete_global(self, level):
  636. our_globals = dict(globals()) # Isolate the test's global effects.
  637. delglobal = compile_for_llvm('delglobal', '''
  638. def delglobal():
  639. global _test_global
  640. del _test_global
  641. ''', level, our_globals)
  642. our_globals['_test_global'] = 'test global value'
  643. self.assertContains('_test_global', our_globals)
  644. delglobal()
  645. self.assertTrue('_test_global' not in our_globals)
  646. @at_each_optimization_level
  647. def test_load_name(self, level):
  648. our_globals = dict(globals()) # Isolate the test's global effects.
  649. testvalue = 'test name value'
  650. loadlocal = compile_for_llvm('loadlocal', '''
  651. def loadlocal():
  652. exec 'testvalue = "Hello"'
  653. return testvalue
  654. ''', level, our_globals)
  655. our_globals['testvalue'] = testvalue
  656. self.assertEquals(loadlocal(), 'Hello')
  657. our_globals = dict(globals())
  658. loadglobal = compile_for_llvm('loadglobal', '''
  659. def loadglobal():
  660. exec ''
  661. return testvalue
  662. ''', level, our_globals)
  663. our_globals['testvalue'] = testvalue
  664. self.assertEquals(loadglobal(), testvalue)
  665. loadbuiltin = compile_for_llvm('loadbuiltin', '''
  666. def loadbuiltin():
  667. exec ''
  668. return str
  669. ''', level)
  670. self.assertEquals(loadbuiltin(), str)
  671. nosuchname = compile_for_llvm('nosuchname', '''
  672. def nosuchname():
  673. exec ''
  674. return there_better_be_no_such_name
  675. ''', level)
  676. self.assertRaises(NameError, nosuchname)
  677. @at_each_optimization_level
  678. def test_store_name(self, level):
  679. set_local = compile('a = 3', '<string>', 'exec')
  680. if level is not None:
  681. set_local.co_optimization = level
  682. set_local.co_use_jit = True
  683. exec set_local
  684. self.assertEquals(a, 3)
  685. @at_each_optimization_level
  686. def test_delete_name(self, level):
  687. do_del = compile('del a', '<string>', 'exec')
  688. if level is not None:
  689. do_del.co_optimization = level
  690. do_del.co_use_jit = True
  691. exec 'a = 3'
  692. self.assertEquals(a, 3)
  693. exec do_del
  694. try:
  695. a
  696. except NameError:
  697. pass
  698. else:
  699. self.fail('Expected "a" to be deleted')
  700. try:
  701. exec compile('del nonexistent', '<string>', 'exec')
  702. except NameError, e:
  703. self.assertEquals(e.args, ('name \'nonexistent\' is not defined',))
  704. else:
  705. self.fail('Expected not to find "nonexistent"')
  706. @at_each_optimization_level
  707. def test_simple_if_stmt(self, level):
  708. simple_if = compile_for_llvm("simple_if", """
  709. def simple_if(x):
  710. if x:
  711. return "true"
  712. """, level)
  713. self.assertEquals(simple_if(True), "true")
  714. self.assertEquals(simple_if(False), None)
  715. simple_if_else = compile_for_llvm("simple_if_else", """
  716. def simple_if_else(x):
  717. if x:
  718. return "true"
  719. else:
  720. return "false"
  721. """, level)
  722. self.assertEquals(simple_if_else("not false"), "true")
  723. self.assertEquals(simple_if_else(""), "false")
  724. @at_each_optimization_level
  725. def test_if_stmt_exceptions(self, level):
  726. if_exception = compile_for_llvm("if_exception", """
  727. def if_exception(x):
  728. if x:
  729. return 1
  730. """, level)
  731. class Unboolable(object):
  732. def __nonzero__(self):
  733. raise RuntimeError
  734. self.assertRaises(RuntimeError, if_exception, Unboolable())
  735. @at_each_optimization_level
  736. def test_complex_if(self, level):
  737. complex_if = compile_for_llvm("complex_if", """
  738. def complex_if(x, y, z):
  739. if x:
  740. if y:
  741. return 1
  742. else:
  743. if z:
  744. return 2
  745. return 1 / 0
  746. else:
  747. return 3
  748. """, level)
  749. self.assertEquals(complex_if(True, True, False), 1)
  750. self.assertEquals(complex_if(True, False, True), 2)
  751. self.assertEquals(complex_if(False, True, True), 3)
  752. self.assertRaises(ZeroDivisionError, complex_if, True, False, False)
  753. # Asserts aren't compiled when -O is passed.
  754. if sys.flags.optimize < 1:
  755. @at_each_optimization_level
  756. def test_assert(self, level):
  757. f = compile_for_llvm("f", "def f(x): assert x", level)
  758. self.assertEquals(f(1), None)
  759. self.assertRaises(AssertionError, f, 0)
  760. @at_each_optimization_level
  761. def test_and(self, level):
  762. and1 = compile_for_llvm("and1",
  763. "def and1(x, y): return x and y", level)
  764. self.assertEquals(and1("x", "y"), "y")
  765. self.assertEquals(and1((), "y"), ())
  766. self.assertEquals(and1((), ""), ())
  767. and2 = compile_for_llvm("and2",
  768. "def and2(x, y): return x+1 and y+1",
  769. level)
  770. self.assertEquals(and2(-1, "5"), 0)
  771. self.assertRaises(TypeError, and2, "5", 5)
  772. self.assertRaises(TypeError, and2, 5, "5")
  773. @at_each_optimization_level
  774. def test_or(self, level):
  775. or1 = compile_for_llvm("or1", "def or1(x, y): return x or y", level)
  776. self.assertEquals(or1("x", "y"), "x")
  777. self.assertEquals(or1((), "y"), "y")
  778. self.assertEquals(or1((), ""), "")
  779. or2 = compile_for_llvm("or2",
  780. "def or2(x, y): return x+1 or y+1", level)
  781. self.assertEquals(or2(5, "5"), 6)
  782. self.assertRaises(TypeError, or2, "5", 5)
  783. self.assertRaises(TypeError, or2, -1, "5")
  784. @at_each_optimization_level
  785. def test_complex_or(self, level):
  786. complex_or = compile_for_llvm('complex_or', '''
  787. def complex_or(a, b, c):
  788. return a or b or c
  789. ''', level)
  790. self.assertEquals(complex_or(1, 2, 0), 1)
  791. self.assertEquals(complex_or(1, 2, 3), 1)
  792. self.assertEquals(complex_or(3, 0, 0), 3)
  793. self.assertEquals(complex_or(0, 3, 0), 3)
  794. self.assertEquals(complex_or(0, 0, 1), 1)
  795. self.assertEquals(complex_or(0, 0, 0), 0)
  796. complex_or_and = compile_for_llvm('complex_or_and', '''
  797. def complex_or_and(a, b, c):
  798. return a or b and c
  799. ''', level)
  800. self.assertEquals(complex_or_and(3, 0, 0), 3)
  801. self.assertEquals(complex_or_and("", 3, 0), 0)
  802. self.assertEquals(complex_or_and("", 0, 1), 0)
  803. self.assertEquals(complex_or_and(0, 3, 1), 1)
  804. @at_each_optimization_level
  805. def test_complex_and(self, level):
  806. complex_and = compile_for_llvm('complex_and', '''
  807. def complex_and(a, b, c):
  808. return a and b and c
  809. ''', level)
  810. self.assertEquals(complex_and(3, 0, ""), 0)
  811. self.assertEquals(complex_and(3, 2, 0), 0)
  812. self.assertEquals(complex_and(3, 2, 1), 1)
  813. self.assertEquals(complex_and(0, 3, 2), 0)
  814. self.assertEquals(complex_and(3, 0, 2), 0)
  815. complex_and_or = compile_for_llvm('complex_and_or', '''
  816. def complex_and_or(a, b, c):
  817. return a and b or c
  818. ''', level)
  819. self.assertEquals(complex_and_or(3, "", 0), 0)
  820. self.assertEquals(complex_and_or(1, 3, 0), 3)
  821. self.assertEquals(complex_and_or(1, 3, 2), 3)
  822. self.assertEquals(complex_and_or(0, 3, 1), 1)
  823. @at_each_optimization_level
  824. def test_break(self, level):
  825. break_one = compile_for_llvm("break_one", """
  826. def break_one(x):
  827. for y in [1, 2]:
  828. x["break"] = y
  829. break
  830. x["post break"] = y
  831. else:
  832. x["else"] = True
  833. return x
  834. """, level)
  835. self.assertEqual(break_one({}), {"break": 1})
  836. nested = compile_for_llvm("nested", """
  837. def nested(x):
  838. for y in [1, 2]:
  839. for z in [3, 4]:
  840. x["break"] = z
  841. break
  842. x["post break"] = z
  843. else:
  844. x["inner else"] = True
  845. x["outer"] = y
  846. else:
  847. x["else"] = True
  848. return x
  849. """, level)
  850. self.assertEqual(nested({}), {"break": 3, "outer": 2, "else": True})
  851. @at_each_optimization_level
  852. def test_continue(self, level):
  853. # CONTINUE_LOOP is only used inside a try/except block. Otherwise,
  854. # the continue statement is lowered to a JUMP_ABSOLUTE.
  855. continue_one = compile_for_llvm("continue_one", """
  856. def continue_one(x):
  857. for y in [1, 2]:
  858. if y:
  859. x["continue"] = y
  860. try:
  861. continue
  862. except:
  863. pass
  864. finally:
  865. x["finally"] = y
  866. 1 / 0
  867. else:
  868. x["else"] = True
  869. return x
  870. """, level)
  871. self.assertEqual(continue_one({}), {"continue": 2, "else": True,
  872. "finally": 2})
  873. nested = compile_for_llvm("nested", """
  874. def nested(x):
  875. for y in [1, 2]:
  876. for z in [3, 4]:
  877. if z:
  878. x["continue"] = z
  879. try:
  880. continue
  881. except:
  882. pass
  883. 1 / 0
  884. else:
  885. x["inner else"] = True
  886. x["outer"] = y
  887. else:
  888. x["else"] = True
  889. return x
  890. """, level)
  891. self.assertEqual(nested({}), {"continue": 4, "outer": 2,
  892. "inner else": True, "else": True})
  893. @at_each_optimization_level
  894. def test_load_attr(self, level):
  895. load_attr = compile_for_llvm('load_attr',
  896. 'def load_attr(o): return o.attr',
  897. level)
  898. load_attr.attr = 1
  899. self.assertEquals(load_attr(load_attr), 1)
  900. self.assertRaises(AttributeError, load_attr, object())
  901. @at_each_optimization_level
  902. def test_store_attr(self, level):
  903. store_attr = compile_for_llvm('store_attr',
  904. 'def store_attr(o): o.attr = 2',
  905. level)
  906. store_attr(store_attr)
  907. self.assertEquals(store_attr.attr, 2)
  908. self.assertRaises(AttributeError, store_attr, object())
  909. @at_each_optimization_level
  910. def test_delete_attr(self, level):
  911. delete_attr = compile_for_llvm('delete_attr',
  912. 'def delete_attr(o): del o.attr',
  913. level)
  914. delete_attr.attr = 3
  915. delete_attr(delete_attr)
  916. self.assertFalse(hasattr(delete_attr, 'attr'))
  917. self.assertRaises(AttributeError, delete_attr, object())
  918. @at_each_optimization_level
  919. def test_call_varargs(self, level):
  920. f1 = compile_for_llvm("f1", "def f1(x, args): return x(*args)",
  921. level)
  922. def receiver1(a, b):
  923. return a, b
  924. self.assertEquals(f1(receiver1, (1, 2)), (1, 2))
  925. self.assertRaises(TypeError, f1, receiver1, None)
  926. self.assertRaises(TypeError, f1, None, (1, 2))
  927. f2 = compile_for_llvm("f2",
  928. "def f2(x, args): return x(1, 2, *args)",
  929. level)
  930. def receiver2(a, *args):
  931. return a, args
  932. self.assertEquals(f2(receiver2, (3, 4, 5)), (1, (2, 3, 4, 5)))
  933. @at_each_optimization_level
  934. def test_call_kwargs(self, level):
  935. f = compile_for_llvm("f",
  936. "def f(x, kwargs): return x(a=1, **kwargs)",
  937. level)
  938. def receiver(**kwargs):
  939. return kwargs
  940. self.assertEquals(f(receiver, {'b': 2, 'c': 3}),
  941. {'a': 1, 'b': 2, 'c': 3})
  942. @at_each_optimization_level
  943. def test_call_args_kwargs(self, level):
  944. f = compile_for_llvm("f", """
  945. def f(x, args, kwargs):
  946. return x(1, d=4, *args, **kwargs)
  947. """, level)
  948. def receiver(*args, **kwargs):
  949. return args, kwargs
  950. self.assertEquals(f(receiver, (2, 3), {'e': 5, 'f': 6}),
  951. ((1, 2, 3), {'d': 4, 'e': 5, 'f': 6}))
  952. @at_each_optimization_level
  953. def test_varargs_func(self, level):
  954. f = compile_for_llvm("f", """
  955. def f(*args):
  956. return zip(*args)
  957. """, level)
  958. self.assertEqual(f([1], [2]), [(1, 2)])
  959. @at_each_optimization_level
  960. def test_kwargs_func(self, level):
  961. f = compile_for_llvm("f", """
  962. def f(**kwargs):
  963. return dict(**kwargs)
  964. """, level)
  965. self.assertEqual(f(a=3), {"a": 3})
  966. @at_each_optimization_level
  967. def test_build_slice(self, level):
  968. class Sliceable(object):
  969. def __getitem__(self, item):
  970. return item
  971. # Test BUILD_SLICE_TWO; make sure we didn't swap arguments.
  972. slice_two = compile_for_llvm('slice_two',
  973. 'def slice_two(o): return o[1:2:]',
  974. level)
  975. self.assertEquals(slice_two(Sliceable()), slice(1, 2, None))
  976. # Test BUILD_SLICE_THREE.
  977. slice_three = compile_for_llvm('slice_three',
  978. 'def slice_three(o): return o[1:2:3]',
  979. level)
  980. self.assertEquals(slice_three(Sliceable()), slice(1, 2, 3))
  981. # No way to make BUILD_SLICE_* raise exceptions.
  982. @at_each_optimization_level
  983. def test_with(self, level):
  984. class SimpleCM(object):
  985. def __enter__(self):
  986. self.enter = True
  987. def __exit__(self, *exc_info):
  988. self.exit = True
  989. with_simple = compile_for_llvm('with_simple', '''
  990. def with_simple(self, x):
  991. with x:
  992. self.assertEqual(x.__dict__, {"enter": True})
  993. self.assertEqual(x.__dict__, {"enter": True, "exit": True})
  994. ''', level)
  995. with_simple(self, SimpleCM())
  996. with_raise = compile_for_llvm('with_raise', '''
  997. def with_raise(self, x):
  998. with x:
  999. self.assertEqual(x.__dict__, {"enter": True})
  1000. raise ArithmeticError
  1001. ''', level)
  1002. x = SimpleCM()
  1003. self.assertRaises(ArithmeticError, with_raise, self, x)
  1004. self.assertEqual(x.__dict__, {'enter': True, 'exit': True})
  1005. with_return = compile_for_llvm('with_return', '''
  1006. def with_return(self, x):
  1007. with x:
  1008. self.assertEqual(x.__dict__, {"enter": True})
  1009. return 55
  1010. ''', level)
  1011. x = SimpleCM()
  1012. self.assertEqual(with_return(self, x), 55)
  1013. self.assertEqual(x.__dict__, {'enter': True, 'exit': True})
  1014. class SwallowingCM(object):
  1015. def __enter__(self):
  1016. self.enter = True
  1017. def __exit__(self, *exc_info):
  1018. self.exit = True
  1019. return True # Swallow the raised exception
  1020. with_swallow = compile_for_llvm('with_swallow', '''
  1021. def with_swallow(self, x):
  1022. with x:
  1023. self.assertEqual(x.__dict__, {"enter": True})
  1024. raise ArithmeticError
  1025. return 55
  1026. ''', level)
  1027. x = SwallowingCM()
  1028. self.assertEqual(with_swallow(self, x), 55)
  1029. self.assertEqual(x.__dict__, {'enter': True, 'exit': True})
  1030. class BustedExitCM(object):
  1031. def __enter__(self):
  1032. self.enter = True
  1033. def __exit__(self, *exc_info):
  1034. self.exit = True
  1035. class A(object):
  1036. def __nonzero__(self):
  1037. raise ArithmeticError
  1038. return A() # Test error paths in WITH_CLEANUP
  1039. with_ignored_bad_exit = compile_for_llvm('with_ignored_bad_exit', '''
  1040. def with_ignored_bad_exit(self, x):
  1041. with x:
  1042. self.assertEqual(x.__dict__, {"enter": True})
  1043. return 55
  1044. ''', level)
  1045. x = BustedExitCM()
  1046. self.assertEqual(with_ignored_bad_exit(self, x), 55)
  1047. self.assertEqual(x.__dict__, {'enter': True, 'exit': True})
  1048. with_bad_exit = compile_for_llvm('with_bad_exit', '''
  1049. def with_bad_exit(self, x):
  1050. with x:
  1051. self.assertEqual(x.__dict__, {"enter": True})
  1052. raise KeyError
  1053. return 55
  1054. ''', level)
  1055. x = BustedExitCM()
  1056. self.assertRaises(ArithmeticError, with_bad_exit, self, x)
  1057. self.assertEqual(x.__dict__, {'enter': True, 'exit': True})
  1058. class RaisingCM(object):
  1059. def __enter__(self):
  1060. self.enter = True
  1061. def __exit__(self, *exc_info):
  1062. self.exit = True
  1063. raise ArithmeticError
  1064. with_error = compile_for_llvm('with_error', '''
  1065. def with_error(self, x):
  1066. with x:
  1067. return 55
  1068. ''', level)
  1069. x = RaisingCM()
  1070. self.assertRaises(ArithmeticError, with_error, self, x)
  1071. self.assertEqual(x.__dict__, {'enter': True, 'exit': True})
  1072. class NestedCM(object):
  1073. def __init__(self):
  1074. self.enter = 0
  1075. self.exit = 0
  1076. def __enter__(self):
  1077. self.enter += 1
  1078. def __exit__(self, *exc_info):
  1079. self.exit += 1
  1080. with_yield = compile_for_llvm('with_yield', '''
  1081. def with_yield(self, x):
  1082. with x:
  1083. self.assertEqual(x.__dict__, {"enter": 1, "exit": 0})
  1084. yield 7
  1085. self.assertEqual(x.__dict__, {"enter": 1, "exit": 0})
  1086. yield 8
  1087. self.assertEqual(x.__dict__, {"enter": 1, "exit": 1})
  1088. ''', level)
  1089. x = NestedCM()
  1090. self.assertEqual(list(with_yield(self, x)), [7, 8])
  1091. with_nested = compile_for_llvm('with_nested', '''
  1092. def with_nested(self, x):
  1093. with x:
  1094. self.assertEqual(x.__dict__, {"enter": 1, "exit": 0})
  1095. with x:
  1096. self.assertEqual(x.__dict__, {"enter": 2, "exit": 0})
  1097. self.assertEqual(x.__dict__, {"enter": 2, "exit": 1})
  1098. self.assertEqual(x.__dict__, {"enter": 2, "exit": 2})
  1099. ''', level)
  1100. x = NestedCM()
  1101. with_nested(self, x)
  1102. @at_each_optimization_level
  1103. def test_raise(self, level):
  1104. raise_onearg = compile_for_llvm('raise_onearg', '''
  1105. def raise_onearg(x):
  1106. raise x
  1107. ''', level)
  1108. self.assertRaises(OpExc, raise_onearg, OpExc);
  1109. raise_twoargs = compile_for_llvm('raise_twoargs', '''
  1110. def raise_twoargs(x, y):
  1111. raise x, y
  1112. ''', level)
  1113. self.assertRaisesWithArgs(OpExc, ('twoarg',),
  1114. raise_twoargs, OpExc, OpExc('twoarg'));
  1115. @at_each_optimization_level
  1116. def test_reraise(self, level):
  1117. raise_noargs = compile_for_llvm('raise_noargs', '''
  1118. def raise_noargs():
  1119. raise
  1120. ''', level)
  1121. exc = OpExc('exc')
  1122. def setup_traceback(e):
  1123. raise e
  1124. try:
  1125. setup_traceback(exc)
  1126. except OpExc:
  1127. # orig_tb and exc re-used for raise_threeargs.
  1128. orig_tb = sys.exc_info()[2]
  1129. try:
  1130. raise_noargs()
  1131. except OpExc, e:
  1132. new_tb = sys.exc_info()[2]
  1133. # Test that we got the right exception and the right
  1134. # traceback. Test both equality and identity for more
  1135. # convenient error displays when things aren't as expected.
  1136. self.assertEquals(e, exc)
  1137. self.assertTrue(e is exc)
  1138. self.assertEquals(new_tb.tb_next, orig_tb)
  1139. self.assertTrue(new_tb.tb_next is orig_tb)
  1140. else:
  1141. self.fail('expected OpExc exception')
  1142. else:
  1143. self.fail('expected OpExc exception')
  1144. raise_threeargs = compile_for_llvm('raise_threeargs', '''
  1145. def raise_threeargs(x, y, z):
  1146. raise x, y, z
  1147. ''', level)
  1148. # Explicit version of the no-args raise.
  1149. try:
  1150. # Re-using exc and orig_tb from raise_noargs.
  1151. raise_threeargs(OpExc, exc, orig_tb)
  1152. except OpExc, e:
  1153. new_tb = sys.exc_info()[2]
  1154. self.assertEquals(e, exc)
  1155. self.assertTrue(e is exc)
  1156. self.assertEquals(new_tb.tb_next, orig_tb)
  1157. self.assertTrue(new_tb.tb_next is orig_tb)
  1158. else:
  1159. self.fail('expected OpExc exception')
  1160. @at_each_optimization_level
  1161. def test_complex_reraise(self, level):
  1162. reraise = compile_for_llvm('reraise', '''
  1163. def reraise(raiser, exctype):
  1164. try:
  1165. raiser()
  1166. except:
  1167. try:
  1168. raise
  1169. except exctype:
  1170. return "inner"
  1171. return "middle"
  1172. return "outer"
  1173. ''', level)
  1174. def raiser():
  1175. raise ZeroDivisionError
  1176. self.assertEquals(reraise(raiser, ZeroDivisionError),
  1177. "inner")
  1178. self.assertRaises(ZeroDivisionError, reraise, raiser, TypeError)
  1179. @at_each_optimization_level
  1180. def test_simple_yield(self, level):
  1181. generator = compile_for_llvm("generator", """
  1182. def generator():
  1183. yield 1
  1184. yield 2
  1185. yield 3
  1186. """, level)
  1187. g = generator()
  1188. self.assertEquals(1, g.next())
  1189. self.assertEquals(2, g.next())
  1190. self.assertEquals(3, g.next())
  1191. self.assertRaises(StopIteration, g.next)
  1192. @at_each_optimization_level
  1193. def test_yield_in_loop(self, level):
  1194. generator = compile_for_llvm("generator", """
  1195. def generator(x):
  1196. for i in x:
  1197. yield i
  1198. """, level)
  1199. g = generator([1, 2, 3, 4])
  1200. self.assertEquals([1, 2, 3, 4], list(g))
  1201. cross_product = compile_for_llvm("cross_product", """
  1202. def cross_product(x, y):
  1203. for i in x:
  1204. for j in y:
  1205. yield (i, j)
  1206. """, level)
  1207. g = cross_product([1, 2], [3, 4])
  1208. self.assertEquals([(1,3), (1,4), (2,3), (2,4)], list(g))
  1209. @at_each_optimization_level
  1210. def test_yield_saves_block_stack(self, level):
  1211. generator = compile_for_llvm("generator", """
  1212. def generator(x):
  1213. yield "starting"
  1214. for i in x:
  1215. try:
  1216. try:
  1217. 1 / i
  1218. yield ("survived", i)
  1219. finally:
  1220. yield ("finally", i)
  1221. except ZeroDivisionError:
  1222. yield "caught exception"
  1223. yield "done looping"
  1224. """, level)
  1225. self.assertEquals(list(generator([0, 1, 2])),
  1226. ["starting",
  1227. ("finally", 0),
  1228. "caught exception",
  1229. ("survived", 1),
  1230. ("finally", 1),
  1231. ("survived", 2),
  1232. ("finally", 2),
  1233. "done looping"])
  1234. @at_each_optimization_level
  1235. def test_generator_send(self, level):
  1236. generator = compile_for_llvm("generator", """
  1237. def generator():
  1238. yield (yield 1)
  1239. """, level)
  1240. g = generator()
  1241. self.assertEquals(1, g.next())
  1242. self.assertEquals("Hello world", g.send("Hello world"))
  1243. self.assertRaises(StopIteration, g.send, 3)
  1244. @at_each_optimization_level
  1245. def test_generator_throw(self, level):
  1246. generator = compile_for_llvm("generator", """
  1247. def generator(obj):
  1248. try:
  1249. yield "starting"
  1250. except ArithmeticError:
  1251. obj["caught"] = 1
  1252. finally:
  1253. obj["finally"] = 1
  1254. yield "done"
  1255. """, level)
  1256. obj = {}
  1257. g = generator(obj)
  1258. self.assertEquals("starting", g.next())
  1259. self.assertEquals("done", g.throw(ArithmeticError))
  1260. self.assertEquals(None, g.close())
  1261. self.assertEquals({"caught": 1, "finally": 1}, obj)
  1262. obj = {}
  1263. g = generator(obj)
  1264. self.assertEquals("starting", g.next())
  1265. self.assertRaises(UnboundLocalError, g.throw, UnboundLocalError)
  1266. self.assertRaises(StopIteration, g.next)
  1267. self.assertEquals({"finally": 1}, obj)
  1268. # Getting this to work under -Xjit=always is a pain in the ass, and not
  1269. # worth the effort IMHO.
  1270. if _llvm.get_jit_control() != "always":
  1271. def test_toggle_generator(self):
  1272. # Toggling between native code and the interpreter between yields
  1273. # used to cause crashes because f_lasti doesn't get translated
  1274. # between the scheme used for LLVM and the scheme used for the
  1275. # interpreter. Currently, due to our generator pseudo
  1276. # on-stack-replacement, these assignments take effect on generator
  1277. # reentry.
  1278. def generator():
  1279. yield 1
  1280. generator.func_code.co_use_jit = True
  1281. yield 2
  1282. generator.func_code.co_use_jit = False
  1283. yield 3
  1284. self.assertEqual(list(generator()), [1, 2, 3])
  1285. @at_each_optimization_level
  1286. def test_closure(self, level):
  1287. make_closure = compile_for_llvm('make_closure', '''
  1288. def make_closure(a, level):
  1289. b = 5
  1290. c = 3
  1291. def inner(d, e=5):
  1292. c = d + 1
  1293. return a, b, c, d, e
  1294. if level is not None:
  1295. inner.__code__.co_use_jit = True
  1296. inner.__code__.co_optimization = level
  1297. b = 2
  1298. return inner
  1299. ''', level)
  1300. inner = make_closure(1, level)
  1301. self.assertEquals(inner(4), (1, 2, 5, 4, 5))
  1302. self.assertRaises(TypeError, inner, "5")
  1303. @at_each_optimization_level
  1304. def test_closure_unbound_freevar(self, level):
  1305. unbound_freevar = compile_for_llvm('unbound_freevar', '''
  1306. def unbound_freevar(level):
  1307. if 0:
  1308. b = 2
  1309. def inner():
  1310. return b
  1311. if level is not None:
  1312. inner.__code__.co_use_jit = True
  1313. inner.__code__.co_optimization = level
  1314. return inner
  1315. ''', level)
  1316. inner = unbound_freevar(level)
  1317. self.assertRaisesWithArgs(NameError,
  1318. ("free variable 'b' referenced before "
  1319. "assignment in enclosing scope",), inner)
  1320. @at_each_optimization_level
  1321. def test_closure_unbound_local(self, level):
  1322. unbound_local = compile_for_llvm('unbound_local', '''
  1323. def unbound_local(level):
  1324. def inner():
  1325. if 0:
  1326. b = 3
  1327. return b
  1328. if level is not None:
  1329. inner.__code__.co_use_jit = True
  1330. inner.__code__.co_optimization = level
  1331. return inner
  1332. ''', level)
  1333. inner = unbound_local(level)
  1334. self.assertRaisesWithArgs(UnboundLocalError,
  1335. ("local variable 'b' referenced before assignment",), inner)
  1336. @at_each_optimization_level
  1337. def test_ends_with_unconditional_jump(self, level):
  1338. foo = compile_for_llvm('foo', '''
  1339. from opcode import opmap
  1340. from types import CodeType, FunctionType
  1341. foo_bytecode = [
  1342. opmap["JUMP_FORWARD"], 4, 0, # 0 JUMP_FORWARD 4 (to 7)
  1343. opmap["LOAD_CONST"], 0, 0, # 3 LOAD_CONST 0 (1)
  1344. opmap["RETURN_VALUE"], # 6 RETURN_VALUE
  1345. opmap["JUMP_ABSOLUTE"], 3, 0, # 7 JUMP_ABSOLUTE 3
  1346. ]
  1347. foo_code = CodeType(0, 0, 1, 0, "".join(chr(x) for x in foo_bytecode),
  1348. (1,), (), (), "<string>", "foo", 1, "")
  1349. foo = FunctionType(foo_code, globals())
  1350. ''', level)
  1351. self.assertEquals(1, foo())
  1352. class LoopExceptionInteractionTests(LlvmTestCase):
  1353. @at_each_optimization_level
  1354. def test_except_through_loop_caught(self, level):
  1355. nested = compile_for_llvm('nested', '''
  1356. def nested(lst, obj):
  1357. try:
  1358. for x in lst:
  1359. raise UnboundLocalError
  1360. except:
  1361. obj["x"] = 2
  1362. # Make sure the block stack is ok.
  1363. try:
  1364. for x in lst:
  1365. return x
  1366. finally:
  1367. obj["y"] = 3
  1368. ''', level)
  1369. obj = {}
  1370. self.assertEquals(1, nested([1,2,3], obj))
  1371. self.assertEquals({"x": 2, "y": 3}, obj)
  1372. @at_each_optimization_level
  1373. def test_except_in_loop(self, level):
  1374. nested = compile_for_llvm('nested', '''
  1375. def nested(lst, obj):
  1376. try:
  1377. for x in lst:
  1378. try:
  1379. a = a
  1380. except ZeroDivisionError:
  1381. obj["x"] = 2
  1382. except UnboundLocalError:
  1383. obj["z"] = 4
  1384. # Make sure the block stack is ok.
  1385. try:
  1386. for x in lst:
  1387. return x
  1388. finally:
  1389. obj["y"] = 3
  1390. ''', level)
  1391. obj = {}
  1392. self.assertEquals(1, nested([1,2,3], obj))
  1393. self.assertEquals({"z": 4, "y": 3}, obj)
  1394. @at_each_optimization_level
  1395. def test_except_through_loop_finally(self, level):
  1396. nested = compile_for_llvm('nested', '''
  1397. def nested(lst, obj):
  1398. try:
  1399. for x in lst:
  1400. a = a
  1401. finally:
  1402. obj["x"] = 2
  1403. ''', level)
  1404. obj = {}
  1405. self.assertRaises(UnboundLocalError, nested, [1,2,3], obj)
  1406. self.assertEquals({"x": 2}, obj)
  1407. @at_each_optimization_level
  1408. def test_break_in_try(self, level):
  1409. break_one = compile_for_llvm("break_one", """
  1410. def break_one(x):
  1411. for y in [1, 2]:
  1412. try:
  1413. x["break"] = y
  1414. break
  1415. x["post break"] = y
  1416. except ZeroDivisionError:
  1417. x["except"] = 77
  1418. finally:
  1419. x["finally"] = y
  1420. else:
  1421. x["else"] = True
  1422. # Make sure the block stack is ok.
  1423. try:
  1424. 1 / 0
  1425. except ZeroDivisionError:
  1426. x["except"] = ZeroDivisionError
  1427. return x
  1428. """, level)
  1429. self.assertEqual(break_one({}), {"break": 1, "finally": 1,
  1430. "except": ZeroDivisionError})
  1431. def cause_bail_on_next_line():
  1432. sys.settrace(lambda *args: None)
  1433. class BailoutTests(ExtraAssertsTestCase):
  1434. @at_each_optimization_level
  1435. def test_bail_inside_loop(self, level):
  1436. # We had a bug where the block stack in the compiled version
  1437. # of the below function used contiguous small integers to
  1438. # identify block handlers. When we bailed out to the
  1439. # interpreter, it expected an handler's identifier to be the
  1440. # index of the opcode that started the code for the handler.
  1441. # This mismatch caused a crash.
  1442. loop = compile_for_llvm("loop", """
  1443. def loop():
  1444. for i in [1, 2]:
  1445. # Use try/finally to get "break" to emit a BREAK_LOOP opcode
  1446. # instead of just jumping out of the loop.
  1447. try:
  1448. cause_bail_on_next_line()
  1449. break
  1450. finally:
  1451. pass
  1452. return i
  1453. """, level)
  1454. orig_trace = sys.gettrace()
  1455. try:
  1456. self.assertEquals(loop(), 1)
  1457. finally:
  1458. sys.settrace(orig_trace)
  1459. def test_use_correct_unwind_reason_when_bailing(self):
  1460. # Previously the LLVM-generated code and the eval loop were using
  1461. # different integers to indicate why we're popping the Python stack. In
  1462. # most cases these integers were invisible to the other side (eval loop
  1463. # vs machine code), but if we bail while unwinding the stack, the
  1464. # integers used by the machine code are exposed to the eval loop.
  1465. #
  1466. # Here's what's going on (use the dis module to follow along at home):
  1467. # 1. try: compiles to a SETUP_FINALLY that registers "len([])" as
  1468. # the finally: handler.
  1469. # 2. "cause_bail()" will flip the thread-local tracing flags.
  1470. # 3. The "return" part of "return cause_bail()" sets the return value
  1471. # and stack unwinding reason (UNWIND_RETURN), then jumps to the
  1472. # unwinder.
  1473. # 4. The stack unwinder does its thing: it pushes the return value and
  1474. # the unwinding reason (UNWIND_RETURN) onto the stack in that order,
  1475. # then jumps to the finally: handler that SETUP_FINALLY registered
  1476. # ("len([])").
  1477. # 5. LLVM emits a per-line prologue that checks the thread-local
  1478. # tracing flag, and if that flag is true, bailing to the interpreter.
  1479. # 6. At this point, the LLVM version of UNWIND_RETURN is on top of the
  1480. # Python stack. The eval loop will now continue where the native code
  1481. # left off, executing len([]).
  1482. # 7. The END_FINALLY opcode that terminates the finally block kicks in
  1483. # and starts trying to handle pending exceptions or return values. It
  1484. # knows what to do by matching the top of the stack (the unwind
  1485. # reason) against its own list of reasons. When the eval loop and
  1486. # native code disagreed about the numerical values for these reasons,
  1487. # LLVM's UNWIND_RETURN was the eval loop's UNWIND_EXCEPTION. This
  1488. # would trigger a debugging assert in the eval loop, since
  1489. # PyErr_Occurred() indicated that indeed *no* exception was live.
  1490. sys.setbailerror(False)
  1491. def cause_bail():
  1492. sys.settrace(lambda *args: None)
  1493. foo = compile_for_llvm("foo", """
  1494. def foo():
  1495. try:
  1496. return cause_bail()
  1497. finally:
  1498. len([]) # This can be anything.
  1499. """, optimization_level=None, globals_dict={"cause_bail": cause_bail})
  1500. foo.__code__.co_use_jit = True
  1501. orig_func = sys.gettrace()
  1502. try:
  1503. foo()
  1504. finally:
  1505. sys.settrace(orig_func)
  1506. # Even though we bailed, the machine code is still valid.
  1507. self.assertTrue(foo.__code__.co_use_jit)
  1508. # Tests for div/truediv won't work right if we enable true
  1509. # division in this test.
  1510. assert 1/2 == 0, "Do not run test_llvm with -Qnew"
  1511. class Operand(object):
  1512. """Helper class for testing operations."""
  1513. # Regular binary arithmetic operations.
  1514. def __add__(self, other):
  1515. return ('add', other)
  1516. def __sub__(self, other):
  1517. return ('sub', other)
  1518. def __mul__(self, other):
  1519. return ('mul', other)
  1520. def __div__(self, other):
  1521. return ('div', other)
  1522. def __truediv__(self, other):
  1523. return ('truediv', other)
  1524. def __floordiv__(self, other):
  1525. return ('floordiv', other)
  1526. def __mod__(self, other):
  1527. return ('mod', other)
  1528. def __pow__(self, other):
  1529. return ('pow', other)
  1530. def __lshift__(self, other):
  1531. return ('lshift', other)
  1532. def __rshift__(self, other):
  1533. return ('rshift', other)
  1534. def __and__(self, other):
  1535. return ('and', other)
  1536. def __or__(self, other):
  1537. return ('or', other)
  1538. def __xor__(self, other):
  1539. return ('xor', other)
  1540. # Unary operations.
  1541. def __invert__(self):
  1542. return ('invert')
  1543. def __pos__(self):
  1544. return ('pos')
  1545. def __neg__(self):
  1546. return ('neg')
  1547. def __repr__(self):
  1548. return ('repr')
  1549. # Right-hand binary arithmetic operations.
  1550. def __radd__(self, other):
  1551. return ('radd', other)
  1552. def __rsub__(self, other):
  1553. return ('rsub', other)
  1554. def __rmul__(self, other):
  1555. return ('rmul', other)
  1556. def __rdiv__(self, other):
  1557. return ('rdiv', other)
  1558. def __rtruediv__(self, other):
  1559. return ('rtruediv', other)
  1560. def __rfloordiv__(self, other):
  1561. return ('rfloordiv', other)
  1562. def __rmod__(self, other):
  1563. return ('rmod', other)
  1564. def __rpow__(self, other):
  1565. return ('rpow', other)
  1566. def __rlshift__(self, other):
  1567. return ('rlshift', other)
  1568. def __rrshift__(self, other):
  1569. return ('rrshift', other)
  1570. def __rand__(self, other):
  1571. return ('rand', other)
  1572. def __ror__(self, other):
  1573. return ('ror', other)
  1574. def __rxor__(self, other):
  1575. return ('rxor', other)
  1576. # In-place binary arithmetic operations.
  1577. def __iadd__(self, other):
  1578. return ('iadd', other)
  1579. def __isub__(self, other):
  1580. return ('isub', other)
  1581. def __imul__(self, other):
  1582. return ('imul', other)
  1583. def __idiv__(self, other):
  1584. return ('idiv', other)
  1585. def __itruediv__(self, other):
  1586. return ('itruediv', other)
  1587. def __ifloordiv__(self, other):
  1588. return ('ifloordiv', other)
  1589. def __imod__(self, other):
  1590. return ('imod', other)
  1591. def __ipow__(self, other):
  1592. return ('ipow', other)
  1593. def __ilshift__(self, other):
  1594. return ('ilshift', other)
  1595. def __irshift__(self, other):
  1596. return ('irshift', other)
  1597. def __iand__(self, other):
  1598. return ('iand', other)
  1599. def __ior__(self, other):
  1600. return ('ior', other)
  1601. def __ixor__(self, other):
  1602. return ('ixor', other)
  1603. # Comparisons.
  1604. def __cmp__(self, other):
  1605. return ('cmp', other)
  1606. def __eq__(self, other):
  1607. return ('eq', other)
  1608. def __ne__(self, other):
  1609. return ('ne', other)
  1610. def __lt__(self, other):
  1611. return ('lt', other)
  1612. def __le__(self, other):
  1613. return ('le', other)
  1614. def __gt__(self, other):
  1615. return ('gt', other)
  1616. def __ge__(self, other):
  1617. return ('ge', other)
  1618. # Misc operations.
  1619. def __getitem__(self, item):
  1620. return ('getitem', item)
  1621. def __getslice__(self, start, stop):
  1622. return ('getslice', start, stop)
  1623. class RecordingOperand(object):
  1624. """Helper class for testing operations that can't return messages"""
  1625. def __init__(self, value=None):
  1626. self._ops = []
  1627. self._value = value
  1628. def __add__(self, other):
  1629. self._ops.append(('add', other))
  1630. return ('add', other)
  1631. def __contains__(self, other):
  1632. self._ops.append(('contains', other))
  1633. return other in self._value
  1634. def __getitem__(self, index):
  1635. self._ops.append(('getitem', index))
  1636. return self._value
  1637. def __setitem__(self, item, value):
  1638. self._ops.append(('setitem', item, value))
  1639. def __delitem__(self, item):
  1640. self._ops.append(('delitem', item))
  1641. def __nonzero__(self):
  1642. self._ops.append('nonzero')
  1643. return bool(self._value)
  1644. def __getslice__(self, start, stop):
  1645. operation = ('getslice', start, stop)
  1646. self._ops.append(operation)
  1647. return operation
  1648. def __setslice__(self, start, stop, seq):
  1649. self._ops.append(('setslice', start, stop, seq))
  1650. def __delslice__(self, start, stop):
  1651. self._ops.append(('delslice', start, stop))
  1652. class OpExc(Exception):
  1653. pass
  1654. class RaisingOperand(object):
  1655. # Regular binary arithmetic operations.
  1656. def __add__(self, other):
  1657. raise OpExc('add', other)
  1658. def __sub__(self, other):
  1659. raise OpExc('sub', other)
  1660. def __mul__(self, other):
  1661. raise OpExc('mul', other)
  1662. def __div__(self, other):
  1663. raise OpExc('div', other)
  1664. def __truediv__(self, other):
  1665. raise OpExc('truediv', other)
  1666. def __floordiv__(self, other):
  1667. raise OpExc('floordiv', other)
  1668. def __mod__(self, other):
  1669. raise OpExc('mod', other)
  1670. def __pow__(self, other):
  1671. raise OpExc('pow', other)
  1672. def __lshift__(self, other):
  1673. raise OpExc('lshift', other)
  1674. def __rshift__(self, other):
  1675. raise OpExc('rshift', other)
  1676. def __and__(self, other):
  1677. raise OpExc('and', other)
  1678. def __or__(self, other):
  1679. raise OpExc('or', other)
  1680. def __xor__(self, other):
  1681. raise OpExc('xor', other)
  1682. # Unary operations,
  1683. def __nonzero__(self):
  1684. raise OpExc('nonzero')
  1685. def __invert__(self):
  1686. raise OpExc('invert')
  1687. def __pos__(self):
  1688. raise OpExc('pos')
  1689. def __neg__(self):
  1690. raise OpExc('neg')
  1691. def __repr__(self):
  1692. raise OpExc('repr')
  1693. # right-hand binary arithmetic operations.
  1694. def __radd__(self, other):
  1695. raise OpExc('radd', other)
  1696. def __rsub__(self, other):
  1697. raise OpExc('rsub', other)
  1698. def __rmul__(self, other):
  1699. raise OpExc('rmul', other)
  1700. def __rdiv__(self, other):
  1701. raise OpExc('rdiv', other)
  1702. def __rtruediv__(self, other):
  1703. raise OpExc('rtruediv', other)
  1704. def __rfloordiv__(self, other):
  1705. raise OpExc('rfloordiv', other)
  1706. def __rmod__(self, other):
  1707. raise OpExc('rmod', other)
  1708. def __rpow__(self, other):
  1709. raise OpExc('rpow', other)
  1710. def __rlshift__(self, other):
  1711. raise OpExc('rlshift', other)
  1712. def __rrshift__(self, other):
  1713. raise OpExc('rrshift', other)
  1714. def __rand__(self, other):
  1715. raise OpExc('rand', other)
  1716. def __ror__(self, other):
  1717. raise OpExc('ror', other)
  1718. def __rxor__(self, other):
  1719. raise OpExc('rxor', other)
  1720. # In-place binary arithmetic operations.
  1721. def __iadd__(self, other):
  1722. raise OpExc('iadd', other)
  1723. def __isub__(self, other):
  1724. raise OpExc('isub', other)
  1725. def __imul__(self, other):
  1726. raise OpExc('imul', other)
  1727. def __idiv__(self, other):
  1728. raise OpExc('idiv', other)
  1729. def __itruediv__(self, other):
  1730. raise OpExc('itruediv', other)
  1731. def __ifloordiv__(self, other):
  1732. raise OpExc('ifloordiv', other)
  1733. def __imod__(self, other):
  1734. raise OpExc('imod', other)
  1735. def __ipow__(self, other):
  1736. raise OpExc('ipow', other)
  1737. def __ilshift__(self, other):
  1738. raise OpExc('ilshift', other)
  1739. def __irshift__(self, other):
  1740. raise OpExc('irshift', other)
  1741. def __iand__(self, other):
  1742. raise OpExc('iand', other)
  1743. def __ior__(self, other):
  1744. raise OpExc('ior', other)
  1745. def __ixor__(self, other):
  1746. raise OpExc('ixor', other)
  1747. # Comparison.
  1748. def __cmp__(self, other):
  1749. raise OpExc('cmp', other)
  1750. def __eq__(self, other):
  1751. raise OpExc('eq', other)
  1752. def __ne__(self, other):
  1753. raise OpExc('ne', other)
  1754. def __lt__(self, other):
  1755. raise OpExc('lt', other)
  1756. def __le__(self, other):
  1757. raise OpExc('le', other)
  1758. def __gt__(self,other):
  1759. raise OpExc('gt', other)
  1760. def __ge__(self, other):
  1761. raise OpExc('ge', other)
  1762. def __contains__(self, other):
  1763. raise OpExc('contains', other)
  1764. # Indexing.
  1765. def __getitem__(self, item):
  1766. raise OpExc('getitem', item)
  1767. def __setitem__(self, item, value):
  1768. raise OpExc('setitem', item, value)
  1769. def __delitem__(self, item):
  1770. raise OpExc('delitem', item)
  1771. # Classic slices
  1772. def __getslice__(self, start, stop):
  1773. raise OpExc('getslice', start, stop)
  1774. def __setslice__(self, start, stop, seq):
  1775. raise OpExc('setslice', start, stop, seq)
  1776. def __delslice__(self, start, stop):
  1777. raise OpExc('delslice', start, stop)
  1778. class OperatorTests(ExtraAssertsTestCase, LlvmTestCase):
  1779. @at_each_optimization_level
  1780. def test_basic_arithmetic(self, level):
  1781. operators = {
  1782. '+': 'add',
  1783. '-': 'sub',
  1784. '*': 'mul',
  1785. '/': 'div',
  1786. '//': 'floordiv',
  1787. '%': 'mod',
  1788. '**': 'pow',
  1789. '<<': 'lshift',
  1790. '>>': 'rshift',
  1791. '&': 'and',
  1792. '|': 'or',
  1793. '^': 'xor'}
  1794. for op, method in operators.items():
  1795. normal = compile_for_llvm('normal', '''
  1796. def normal(x):
  1797. return x %s 1
  1798. ''' % op, level)
  1799. self.assertEquals(normal(Operand()), (method, 1))
  1800. self.assertRaisesWithArgs(OpExc, (method, 1),
  1801. normal, RaisingOperand())
  1802. righthand = compile_for_llvm('righthand', '''
  1803. def righthand(x):
  1804. return 2 %s x
  1805. ''' % op, level)
  1806. self.assertEquals(righthand(Operand()), ('r' + method, 2))
  1807. self.assertRaisesWithArgs(OpExc, ('r' + method, 2),
  1808. righthand, RaisingOperand())
  1809. inplace = compile_for_llvm('inplace', '''
  1810. def inplace(x):
  1811. x %s= 3
  1812. return x
  1813. ''' % op, level)
  1814. self.assertEquals(inplace(Operand()), ('i' + method, 3))
  1815. self.assertRaisesWithArgs(OpExc, ('i' + method, 3),
  1816. inplace, RaisingOperand())
  1817. @at_each_optimization_level
  1818. def test_truediv(self, level):
  1819. div_code = compile('''
  1820. def div(x):
  1821. return x / 1
  1822. ''', 'div_code', 'exec', flags=__future__.division.compiler_flag)
  1823. div = compile_for_llvm('div', div_code, level)
  1824. self.assertEquals(div(Operand()), ('truediv', 1))
  1825. self.assertRaisesWithArgs(OpExc, ('truediv', 1),
  1826. div, RaisingOperand())
  1827. rdiv_code = compile('''
  1828. def rdiv(x):
  1829. return 2 / x
  1830. ''', 'rdiv_code', 'exec', flags=__future__.division.compiler_flag)
  1831. rdiv = compile_for_llvm('rdiv', rdiv_code, level)
  1832. self.assertEquals(rdiv(Operand()), ('rtruediv', 2))
  1833. self.assertRaisesWithArgs(OpExc, ('rtruediv', 2),
  1834. rdiv, RaisingOperand())
  1835. idiv_code = compile('''
  1836. def idiv(x):
  1837. x /= 3;
  1838. return x
  1839. ''', 'idiv_code', 'exec', flags=__future__.division.compiler_flag)
  1840. idiv = compile_for_llvm('idiv', idiv_code, level)
  1841. self.assertEquals(idiv(Operand()), ('itruediv', 3))
  1842. self.assertRaisesWithArgs(OpExc, ('itruediv', 3),
  1843. idiv, RaisingOperand())
  1844. @at_each_optimization_level
  1845. def test_subscr(self, level):
  1846. subscr = compile_for_llvm('subscr',
  1847. 'def subscr(x): return x["item"]',
  1848. level)
  1849. self.assertEquals(subscr(Operand()), ('getitem', 'item'))
  1850. self.assertRaisesWithArgs(OpExc, ('getitem', 'item'),
  1851. subscr, RaisingOperand())
  1852. @at_each_optimization_level
  1853. def test_store_subscr(self, level):
  1854. store_subscr = compile_for_llvm('store_subscr', '''
  1855. def store_subscr(x):
  1856. x['item'] = 4
  1857. return x
  1858. ''', level)
  1859. self.assertEquals(store_subscr(RecordingOperand())._ops,
  1860. [('setitem', 'item', 4)])
  1861. self.assertRaisesWithArgs(OpExc, ('setitem', 'item', 4),
  1862. store_subscr, RaisingOperand())
  1863. @at_each_optimization_level
  1864. def test_subscr_augassign(self, level):
  1865. subscr_augassign = compile_for_llvm('subscr_augassign', '''
  1866. def subscr_augassign(x):
  1867. x[0] += 2
  1868. return x
  1869. ''', level)
  1870. self.assertEquals(subscr_augassign(RecordingOperand(3))._ops,
  1871. [('getitem', 0), ('setitem', 0, 5)])
  1872. # Test getitem raising an exception
  1873. self.assertRaisesWithArgs(OpExc, ('getitem', 0),
  1874. subscr_augassign, RaisingOperand())
  1875. # Test iadd raising an exception.
  1876. self.assertRaisesWithArgs(OpExc, ('iadd', 2),
  1877. subscr_augassign, [RaisingOperand()])
  1878. # Test setitem raising an exception
  1879. class SetitemRaisingOperand(RaisingOperand):
  1880. def __getitem__(self, item):
  1881. return 5
  1882. self.assertRaisesWithArgs(OpExc, ('setitem', 0, 7),
  1883. subscr_augassign, SetitemRaisingOperand())
  1884. @at_each_optimization_level
  1885. def test_invert(self, level):
  1886. invert = compile_for_llvm('invert',
  1887. 'def invert(x): return ~x', level)
  1888. self.assertEquals(invert(Operand()), 'invert')
  1889. self.assertRaisesWithArgs(OpExc, ('invert',),
  1890. invert, RaisingOperand())
  1891. @at_each_optimization_level
  1892. def test_pos(self, level):
  1893. pos = compile_for_llvm('pos', 'def pos(x): return +x', level)
  1894. self.assertEquals(pos(Operand()), 'pos')
  1895. self.assertRaisesWithArgs(OpExc, ('pos',),
  1896. pos, RaisingOperand())
  1897. @at_each_optimization_level
  1898. def test_neg(self, level):
  1899. neg = compile_for_llvm('neg', 'def neg(x): return -x', level)
  1900. self.assertEquals(neg(Operand()), 'neg')
  1901. self.assertRaisesWithArgs(OpExc, ('neg',),
  1902. neg, RaisingOperand())
  1903. @at_each_optimization_level
  1904. def test_convert(self, level):
  1905. convert = compile_for_llvm('convert',
  1906. 'def convert(x): return `x`', level)
  1907. self.assertEquals(convert(Operand()), 'repr')
  1908. self.assertRaisesWithArgs(OpExc, ('repr',),
  1909. convert, RaisingOperand())
  1910. @at_each_optimization_level
  1911. def test_not(self, level):
  1912. not_ = compile_for_llvm('not_', '''
  1913. def not_(x):
  1914. y = not x
  1915. return x
  1916. ''', level)
  1917. self.assertEquals(not_(RecordingOperand())._ops, ['nonzero'])
  1918. self.assertRaisesWithArgs(OpExc, ('nonzero',),
  1919. not_, RaisingOperand())
  1920. @at_each_optimization_level
  1921. def test_slice_none(self, level):
  1922. getslice_none = compile_for_llvm('getslice_none',
  1923. 'def getslice_none(x): return x[:]',
  1924. level)
  1925. self.assertEquals(getslice_none(Operand()),
  1926. ('getslice', 0, sys.maxint))
  1927. self.assertRaisesWithArgs(OpExc, ('getslice', 0, sys.maxint),
  1928. getslice_none, RaisingOperand())
  1929. setslice_none = compile_for_llvm('setslice_none', '''
  1930. def setslice_none(x):
  1931. x[:] = [0]
  1932. return x
  1933. ''', level)
  1934. self.assertEquals(setslice_none(RecordingOperand())._ops,
  1935. [('setslice', 0, sys.maxint, [0])])
  1936. self.assertRaisesWithArgs(OpExc, ('setslice', 0, sys.maxint, [0]),
  1937. setslice_none, RaisingOperand())
  1938. delslice_none = compile_for_llvm('delslice_none', '''
  1939. def delslice_none(x):
  1940. del x[:]
  1941. return x
  1942. ''', level)
  1943. self.assertEquals(delslice_none(RecordingOperand())._ops,
  1944. [('delslice', 0, sys.maxint)])
  1945. self.assertRaisesWithArgs(OpExc, ('delslice', 0, sys.maxint),
  1946. delslice_none, RaisingOperand())
  1947. augassign_none = compile_for_llvm('augassign_none', '''
  1948. def augassign_none(x):
  1949. x[:] += (0,)
  1950. return x
  1951. ''', level)
  1952. self.assertEquals(augassign_none(RecordingOperand())._ops, [
  1953. # The result of op.__getslice__(0, sys.maxint), and ..
  1954. ('getslice', 0, sys.maxint),
  1955. # ... the result of op.__setslice__(0, sys.maxint, seq) ..
  1956. ('setslice', 0, sys.maxint,
  1957. # .. with seq being op.__getslice__(0, sys.maxint) + (0,)
  1958. ('getslice', 0, sys.maxint, 0))])
  1959. @at_each_optimization_level
  1960. def test_slice_left(self, level):
  1961. getslice_left = compile_for_llvm('getslice_left', '''
  1962. def getslice_left(x, y):
  1963. return x[y:]
  1964. ''', level)
  1965. self.assertEquals(getslice_left(Operand(), 5),
  1966. ('getslice', 5, sys.maxint))
  1967. self.assertRaisesWithArgs(OpExc, ('getslice', 5, sys.maxint),
  1968. getslice_left, RaisingOperand(), 5)
  1969. setslice_left = compile_for_llvm('setslice_left', '''
  1970. def setslice_left(x, y):
  1971. x[y:] = [1]
  1972. return x
  1973. ''', level)
  1974. self.assertEquals(setslice_left(RecordingOperand(), 5)._ops,
  1975. [('setslice', 5, sys.maxint, [1])])
  1976. self.assertRaisesWithArgs(OpExc, ('setslice', 5, sys.maxint, [1]),
  1977. setslice_left, RaisingOperand(), 5)
  1978. delslice_left = compile_for_llvm('delslice_left', '''
  1979. def delslice_left(x, y):
  1980. del x[y:]
  1981. return x
  1982. ''', level)
  1983. self.assertEquals(delslice_left(RecordingOperand(), 5)._ops,
  1984. [('delslice', 5, sys.maxint)])
  1985. self.assertRaisesWithArgs(OpExc, ('delslice', 5, sys.maxint),
  1986. delslice_left, RaisingOperand(), 5)
  1987. augassign_left = compile_for_llvm('augassign_left', '''
  1988. def augassign_left(x, y):
  1989. x[y:] += (1,)
  1990. return x
  1991. ''', level)
  1992. self.assertEquals(augassign_left(RecordingOperand(), 2)._ops, [
  1993. # The result of op.__getslice__(2, sys.maxint), and ..
  1994. ('getslice', 2, sys.maxint),
  1995. # ... the result of op.__setslice__(2, sys.maxint, seq) ..
  1996. ('setslice', 2, sys.maxint,
  1997. # .. with seq being op.__getslice__(2, sys.maxint) + (1,)
  1998. ('getslice', 2, sys.maxint, 1))])
  1999. @at_each_optimization_level
  2000. def test_slice_right(self, level):
  2001. getslice_right = compile_for_llvm('getslice_right', '''
  2002. def getslice_right(x, y):
  2003. return x[:y]
  2004. ''', level)
  2005. self.assertEquals(getslice_right(Operand(), 10),
  2006. ('getslice', 0, 10))
  2007. self.assertRaisesWithArgs(OpExc, ('getslice', 0, 10),
  2008. getslice_right, RaisingOperand(), 10)
  2009. setslice_right = compile_for_llvm('setslice_right', '''
  2010. def setslice_right(x, y):
  2011. x[:y] = [2]
  2012. return x
  2013. ''', level)
  2014. self.assertEquals(setslice_right(RecordingOperand(), 10)._ops,
  2015. [('setslice', 0, 10, [2])])
  2016. self.assertRaisesWithArgs(OpExc, ('setslice', 0, 10, [2]),
  2017. setslice_right, RaisingOperand(), 10)
  2018. delslice_right = compile_for_llvm('delslice_right', '''
  2019. def delslice_right(x, y):
  2020. del x[:y]
  2021. return x
  2022. ''', level)
  2023. self.assertEquals(delslice_right(RecordingOperand(), 10)._ops,
  2024. [('delslice', 0, 10)])
  2025. self.assertRaisesWithArgs(OpExc, ('delslice', 0, 10),
  2026. delslice_right, RaisingOperand(), 10)
  2027. augassign_right = compile_for_llvm('augassign_right', '''
  2028. def augassign_right(x, y):
  2029. x[:y] += (2,)
  2030. return x
  2031. ''', level)
  2032. self.assertEquals(augassign_right(RecordingOperand(), 1)._ops, [
  2033. # The result of op.__getslice__(0, 1), and ..
  2034. ('getslice', 0, 1),
  2035. # ... the result of op.__setslice__(0, 1, seq) ..
  2036. ('setslice', 0, 1,
  2037. # .. with seq being op.__getslice__(0, 1) + (2,)
  2038. ('getslice', 0, 1, 2))])
  2039. @at_each_optimization_level
  2040. def test_slice_both(self, level):
  2041. getslice_both = compile_for_llvm('getslice_both', '''
  2042. def getslice_both(x, y, z):
  2043. return x[y:z]
  2044. ''', level)
  2045. self.assertEquals(getslice_both(Operand(), 4, -6),
  2046. ('getslice', 4, -6))
  2047. self.assertRaisesWithArgs(OpExc, ('getslice', 4, -6),
  2048. getslice_both, RaisingOperand(), 4, -6)
  2049. setslice_both = compile_for_llvm('setslice_both', '''
  2050. def setslice_both(x, y, z):
  2051. x[y:z] = [3]
  2052. return x
  2053. ''', level)
  2054. self.assertEquals(setslice_both(RecordingOperand(), 4, -6)._ops,
  2055. [('setslice', 4, -6, [3])])
  2056. self.assertRaisesWithArgs(OpExc, ('setslice', 4, -6, [3]),
  2057. setslice_both, RaisingOperand(), 4, -6)
  2058. delslice_both = compile_for_llvm('delslice_both', '''
  2059. def delslice_both(x, y, z):
  2060. del x[y:z]
  2061. return x
  2062. ''', level)
  2063. self.assertEquals(delslice_both(RecordingOperand(), 4, -6)._ops,
  2064. [('delslice', 4, -6)])
  2065. self.assertRaisesWithArgs(OpExc, ('delslice', 4, -6),
  2066. delslice_both, RaisingOperand(), 4, -6)
  2067. augassign_both = compile_for_llvm('augassign_both', '''
  2068. def augassign_both(x, y, z):
  2069. x[y:z] += (3,)
  2070. return x
  2071. ''', level)
  2072. self.assertEquals(augassign_both(RecordingOperand(), 1, 2)._ops, [
  2073. # The result of op.__getslice__(1, 2), and ..
  2074. ('getslice', 1, 2),
  2075. # ... the result of op.__setslice__(1, 2, seq) ..
  2076. ('setslice', 1, 2,
  2077. # .. with seq being op.__getslice__(1, 2) + (3,)
  2078. ('getslice', 1, 2, 3))])
  2079. @at_each_optimization_level
  2080. def test_is(self, level):
  2081. is_ = compile_for_llvm('is_', 'def is_(x, y): return x is y', level)
  2082. # Don't rely on Python making separate literal 1's the same object.
  2083. one = 1
  2084. self.assertTrue(is_(one, one))
  2085. self.assertFalse(is_(2, 3))
  2086. @at_each_optimization_level
  2087. def test_is_not(self, level):
  2088. is_not = compile_for_llvm('is_not',
  2089. 'def is_not(x, y): return x is not y',
  2090. level)
  2091. # Don't rely on Python making separate literal 1's the same object.
  2092. one = 1
  2093. self.assertFalse(is_not(one, one))
  2094. self.assertTrue(is_not(2, 3))
  2095. @at_each_optimization_level
  2096. def test_eq(self, level):
  2097. eq = compile_for_llvm('eq', 'def eq(x, y): return x == y', level)
  2098. self.assertEquals(eq(Operand(), 6), ('eq', 6))
  2099. self.assertEquals(eq(7, Operand()), ('eq', 7))
  2100. self.assertRaisesWithArgs(OpExc, ('eq', 1), eq, RaisingOperand(), 1)
  2101. self.assertRaisesWithArgs(OpExc, ('eq', 1), eq, 1, RaisingOperand())
  2102. @at_each_optimization_level
  2103. def test_ne(self, level):
  2104. ne = compile_for_llvm('ne', 'def ne(x, y): return x != y', level)
  2105. self.assertEquals(ne(Operand(), 6), ('ne', 6))
  2106. self.assertEquals(ne(7, Operand()), ('ne', 7))
  2107. self.assertRaisesWithArgs(OpExc, ('ne', 1), ne, RaisingOperand(), 1)
  2108. self.assertRaisesWithArgs(OpExc, ('ne', 1), ne, 1, RaisingOperand())
  2109. @at_each_optimization_level
  2110. def test_lt(self, level):
  2111. lt = compile_for_llvm('lt', 'def lt(x, y): return x < y', level)
  2112. self.assertEquals(lt(Operand(), 6), ('lt', 6))
  2113. self.assertEquals(lt(7, Operand()), ('gt', 7))
  2114. self.assertRaisesWithArgs(OpExc, ('lt', 1), lt, RaisingOperand(), 1)
  2115. self.assertRaisesWithArgs(OpExc, ('gt', 1), lt, 1, RaisingOperand())
  2116. @at_each_optimization_level
  2117. def test_le(self, level):
  2118. le = compile_for_llvm('le', 'def le(x, y): return x <= y', level)
  2119. self.assertEquals(le(Operand(), 6), ('le', 6))
  2120. self.assertEquals(le(7, Operand()), ('ge', 7))
  2121. self.assertRaisesWithArgs(OpExc, ('le', 1), le, RaisingOperand(), 1)
  2122. self.assertRaisesWithArgs(OpExc, ('ge', 1), le, 1, RaisingOperand())
  2123. @at_each_optimization_level
  2124. def test_gt(self, level):
  2125. gt = compile_for_llvm('gt', 'def gt(x, y): return x > y', level)
  2126. self.assertEquals(gt(Operand(), 6), ('gt', 6))
  2127. self.assertEquals(gt(7, Operand()), ('lt', 7))
  2128. self.assertRaisesWithArgs(OpExc, ('gt', 1), gt, RaisingOperand(), 1)
  2129. self.assertRaisesWithArgs(OpExc, ('lt', 1), gt, 1, RaisingOperand())
  2130. @at_each_optimization_level
  2131. def test_ge(self, level):
  2132. ge = compile_for_llvm('ge', 'def ge(x, y): return x >= y', level)
  2133. self.assertEquals(ge(Operand(), 6), ('ge', 6))
  2134. self.assertEquals(ge(7, Operand()), ('le', 7))
  2135. self.assertRaisesWithArgs(OpExc, ('ge', 1), ge, RaisingOperand(), 1)
  2136. self.assertRaisesWithArgs(OpExc, ('le', 1), ge, 1, RaisingOperand())
  2137. @at_each_optimization_level
  2138. def test_in(self, level):
  2139. in_ = compile_for_llvm('in_', 'def in_(x, y): return x in y', level)
  2140. self.assertTrue(in_(1, [1, 2]))
  2141. self.assertFalse(in_(1, [0, 2]))
  2142. op = RecordingOperand([1])
  2143. self.assertTrue(in_(1, op))
  2144. self.assertEquals(op._ops, [('contains', 1)])
  2145. self.assertRaisesWithArgs(OpExc, ('contains', 1),
  2146. in_, 1, RaisingOperand())
  2147. @at_each_optimization_level
  2148. def test_not_in(self, level):
  2149. not_in = compile_for_llvm('not_in',
  2150. 'def not_in(x, y): return x not in y',
  2151. level)
  2152. self.assertFalse(not_in(1, [1, 2]))
  2153. self.assertTrue(not_in(1, [0, 2]))
  2154. op = RecordingOperand([])
  2155. self.assertTrue(not_in(1, op))
  2156. self.assertEquals(op._ops, [('contains', 1)])
  2157. self.assertRaisesWithArgs(OpExc, ('contains', 1),
  2158. not_in, 1, RaisingOperand())
  2159. @at_each_optimization_level
  2160. def test_listcomp(self, level):
  2161. listcomp = compile_for_llvm('listcomp', '''
  2162. def listcomp(x):
  2163. return [ item + 1 for item in x ]
  2164. ''', level)
  2165. self.assertEquals(listcomp([1, 2, 3]), [2, 3, 4])
  2166. listcomp_exc = compile_for_llvm('listcomp_exc', '''
  2167. def listcomp_exc(x):
  2168. return [ item + 5 for item in x ]
  2169. ''', level)
  2170. op = RecordingOperand()
  2171. self.assertRaisesWithArgs(OpExc, ('add', 5),
  2172. listcomp_exc, [op, RaisingOperand(), op])
  2173. # Test that the last Operand wasn't touched, and we didn't
  2174. # leak references.
  2175. self.assertEquals(op._ops, [('add', 5)])
  2176. class LiteralsTests(LlvmTestCase):
  2177. @at_each_optimization_level
  2178. def test_build_tuple(self, level):
  2179. t1 = compile_for_llvm('t1', 'def t1(): return (1, 2, 3)', level)
  2180. self.assertEquals(t1(), (1, 2, 3))
  2181. t2 = compile_for_llvm('t2', 'def t2(x): return (1, x + 1, 3)', level)
  2182. self.assertEquals(t2(1), (1, 2, 3))
  2183. self.assertRaises(TypeError, t2, "1")
  2184. t3 = compile_for_llvm('t3',
  2185. 'def t3(x): return ([1], x, (3, x + 1), 2, 1)',
  2186. level)
  2187. self.assertEquals(t3(2), ([1], 2, (3, 3), 2, 1))
  2188. self.assertRaises(TypeError, t3, "2")
  2189. @at_each_optimization_level
  2190. def test_unpack_tuple(self, level):
  2191. unpack = compile_for_llvm('unpack', '''
  2192. def unpack(x):
  2193. a, b, (c, d) = x
  2194. return (a, b, c, d)
  2195. ''', level)
  2196. self.assertEquals(unpack((1, 2, (3, 4))), (1, 2, 3, 4))
  2197. self.assertRaises(TypeError, unpack, None)
  2198. self.assertRaises(ValueError, unpack, (1, 2, (3, 4, 5)))
  2199. self.assertRaises(ValueError, unpack, (1, 2))
  2200. @at_each_optimization_level
  2201. def test_build_list(self, level):
  2202. l1 = compile_for_llvm('l1', 'def l1(): return [1, 2, 3]', level)
  2203. self.assertEquals(l1(), [1, 2, 3])
  2204. l2 = compile_for_llvm('l2', 'def l2(x): return [1, x + 1, 3]', level)
  2205. self.assertEquals(l2(1), [1, 2, 3])
  2206. self.assertRaises(TypeError, l2, "1")
  2207. l3 = compile_for_llvm('l3',
  2208. 'def l3(x): return [(1,), x, [3, x + 1], 2, 1]',
  2209. level)
  2210. self.assertEquals(l3(2), [(1,), 2, [3, 3], 2, 1])
  2211. self.assertRaises(TypeError, l3, "2")
  2212. @at_each_optimization_level
  2213. def test_build_map(self, level):
  2214. f1 = compile_for_llvm('f1', 'def f1(x): return {1: x, x + 1: 4}',
  2215. level)
  2216. self.assertEquals(f1(2), {1: 2, 3: 4})
  2217. self.assertRaises(TypeError, f1, '2')
  2218. f2 = compile_for_llvm('f2', 'def f2(x): return {1: {x: 3}, x: 5}',
  2219. level)
  2220. self.assertEquals(f2(2), {1: {2: 3}, 2: 5})
  2221. self.assertRaises(TypeError, f2, {})
  2222. class OptimizationTests(LlvmTestCase, ExtraAssertsTestCase):
  2223. def test_manual_optimization(self):
  2224. foo = compile_for_llvm("foo", "def foo(): return 5",
  2225. optimization_level=None)
  2226. foo.__code__.co_optimization = 2
  2227. self.assertContains("getelementptr", str(foo.__code__.co_llvm))
  2228. self.assertEqual(foo(), 5)
  2229. def test_hotness(self):
  2230. foo = compile_for_llvm("foo", "def foo(): pass",
  2231. optimization_level=None)
  2232. iterations = JIT_SPIN_COUNT
  2233. [foo() for _ in xrange(iterations)]
  2234. self.assertEqual(foo.__code__.co_hotness, iterations * 10)
  2235. self.assertEqual(foo.__code__.co_use_jit, True)
  2236. self.assertEqual(foo.__code__.co_optimization, JIT_OPT_LEVEL)
  2237. self.assertContains("getelementptr", str(foo.__code__.co_llvm))
  2238. def test_for_loop_hotness(self):
  2239. # Test that long-running for loops count toward the hotness metric. A
  2240. # function doing 1e6 iterations per call should be worthy of
  2241. # optimization.
  2242. foo = compile_for_llvm("foo", """
  2243. def foo():
  2244. for x in xrange(1000000):
  2245. pass
  2246. """, optimization_level=None)
  2247. self.assertEqual(foo.__code__.co_hotness, 0)
  2248. self.assertFalse(foo.__code__.co_use_jit)
  2249. foo()
  2250. # +1 point each for 1e6 loop iterations.
  2251. hotness = HOTNESS_CALL + HOTNESS_LOOP * 1000000
  2252. self.assertEqual(foo.__code__.co_hotness, hotness)
  2253. foo() # Hot-or-not calculations are done on function-entry.
  2254. self.assertTrue(foo.__code__.co_use_jit)
  2255. def test_nested_for_loop_hotness(self):
  2256. # Verify our understanding of how the hotness model deals with nested
  2257. # for loops. This can be confusing, and we don't want to change it
  2258. # accidentally.
  2259. foo = compile_for_llvm("foo", """
  2260. def foo():
  2261. for x in xrange(50):
  2262. for y in xrange(70):
  2263. pass
  2264. """, optimization_level=None)
  2265. self.assertEqual(foo.__code__.co_hotness, 0)
  2266. self.assertFalse(foo.__code__.co_use_jit)
  2267. foo()
  2268. # 50 outer loop iterations, 3500 inner loop iterations.
  2269. hotness = HOTNESS_CALL + (HOTNESS_LOOP * 3500) + (HOTNESS_LOOP * 50)
  2270. self.assertEqual(foo.__code__.co_hotness, hotness)
  2271. def test_for_loop_jump_threading_hotness(self):
  2272. # Regression test: the bytecode peephole optimizer does some limited
  2273. # jump threading, which caused problems for one earlier attempt at
  2274. # tuning the hotness model.
  2275. foo = compile_for_llvm("foo", """
  2276. def foo():
  2277. for x in xrange(1000000):
  2278. if x % 2: # Alternate between the two branches
  2279. x = 8 # Nonsense
  2280. """, optimization_level=None)
  2281. self.assertEqual(foo.__code__.co_hotness, 0)
  2282. self.assertFalse(foo.__code__.co_use_jit)
  2283. foo()
  2284. hotness = HOTNESS_CALL + HOTNESS_LOOP * 1000000
  2285. self.assertEqual(foo.__code__.co_hotness, hotness)
  2286. def test_early_for_loop_exit_hotness(self):
  2287. # Make sure we understand how the hotness model counts early exits from
  2288. # for loops.
  2289. foo = compile_for_llvm("foo", """
  2290. def foo():
  2291. for x in xrange(1000):
  2292. return True
  2293. """, optimization_level=None)
  2294. self.assertEqual(foo.__code__.co_hotness, 0)
  2295. self.assertFalse(foo.__code__.co_use_jit)
  2296. foo()
  2297. # Note that we don't count the loop in any way, since we never take
  2298. # a loop backedge.
  2299. self.assertEqual(foo.__code__.co_hotness, HOTNESS_CALL)
  2300. def test_while_loop_hotness(self):
  2301. # Verify our understanding of how the hotness model deals with while
  2302. # loops: we don't want to change it accidentally.
  2303. foo = compile_for_llvm("foo", """
  2304. def foo():
  2305. i = 1000000
  2306. while i:
  2307. i -= 1
  2308. """, optimization_level=None)
  2309. self.assertEqual(foo.__code__.co_hotness, 0)
  2310. self.assertFalse(foo.__code__.co_use_jit)
  2311. foo()
  2312. hotness = HOTNESS_CALL + HOTNESS_LOOP * 1000000
  2313. self.assertEqual(foo.__code__.co_hotness, hotness)
  2314. def test_generator_hotness(self):
  2315. foo = compile_for_llvm("foo", """
  2316. def foo():
  2317. yield 5
  2318. yield 6
  2319. """, optimization_level=None)
  2320. iterations = JIT_SPIN_COUNT
  2321. l = [foo() for _ in xrange(iterations)]
  2322. self.assertEqual(foo.__code__.co_hotness, iterations * HOTNESS_CALL)
  2323. l = map(list, l)
  2324. self.assertEqual(foo.__code__.co_hotness, iterations * HOTNESS_CALL)
  2325. self.assertEqual(foo.__code__.co_use_jit, True)
  2326. self.assertEqual(foo.__code__.co_optimization, JIT_OPT_LEVEL)
  2327. def test_generator_hotness_osr(self):
  2328. foo = compile_for_llvm("foo", """
  2329. def foo(iterations):
  2330. for i in xrange(iterations):
  2331. yield i
  2332. """, optimization_level=None)
  2333. iterations = JIT_SPIN_COUNT * HOTNESS_CALL / HOTNESS_LOOP
  2334. for _ in foo(iterations):
  2335. pass
  2336. # We don't currently increment the hotness counter on loop backedges in
  2337. # the compiled code, so the hotness stops growing when it passes the
  2338. # threshold.
  2339. self.assertEqual(foo.__code__.co_hotness, 100001)
  2340. self.assertTrue(foo.__code__.co_use_jit)
  2341. self.assertEqual(foo.__code__.co_optimization, JIT_OPT_LEVEL)
  2342. def test_fast_load_global(self):
  2343. # Make sure that hot functions use the optimized LOAD_GLOBAL
  2344. # implementation. We do this by asserting that if their assumptions
  2345. # about globals/builtins no longer hold, they bail.
  2346. with test_support.swap_attr(__builtin__, "len", len):
  2347. foo = compile_for_llvm("foo", """
  2348. def foo(x, callback):
  2349. callback()
  2350. return len(x)
  2351. """, optimization_level=None)
  2352. spin_until_hot(foo, [[], lambda: None])
  2353. self.assertEqual(foo.__code__.co_use_jit, True)
  2354. def change_builtins():
  2355. self.assertEqual(foo.__code__.co_use_jit, True)
  2356. __builtin__.len = lambda x: 7
  2357. def run_test():
  2358. self.assertEqual(foo.__code__.co_use_jit, True)
  2359. self.assertEqual(foo.__code__.co_fatalbailcount, 0)
  2360. sys.setbailerror(True)
  2361. try:
  2362. self.assertRaises(RuntimeError, foo, [], change_builtins)
  2363. finally:
  2364. sys.setbailerror(False)
  2365. self.assertEqual(foo.__code__.co_fatalbailcount, 1)
  2366. self.assertEqual(foo.__code__.co_use_jit, False)
  2367. run_test()
  2368. def test_global_dict_mismatch(self):
  2369. # Test that calling a function with a globals dict other than the one
  2370. # we assumed during compilation works successfully.
  2371. globals_1 = globals().copy()
  2372. globals_2 = globals().copy()
  2373. globals_1['x'] = 1
  2374. globals_2['x'] = 2
  2375. load_x_1 = compile_for_llvm("load_x_1", """
  2376. def load_x_1():
  2377. return x
  2378. """, optimization_level=None, globals_dict=globals_1)
  2379. # Make a new function with the other globals dict and assign it
  2380. # load_x_1's code object.
  2381. load_x_2 = compile_for_llvm("load_x_2", """
  2382. def load_x_2():
  2383. pass
  2384. """, optimization_level=None, globals_dict=globals_2)
  2385. load_x_2.__code__ = load_x_1.__code__
  2386. # We have to compile the code objects by setting jit control to
  2387. # "always" and not passing optimization_level to compile_for_llvm,
  2388. # or we won't assume a globals dictionary during compilation on the
  2389. # first call.
  2390. with set_jit_control("always"):
  2391. x1 = load_x_1()
  2392. x2 = load_x_2()
  2393. self.assertEqual(x1, 1)
  2394. self.assertEqual(x2, 2)
  2395. def test_get_correct_globals(self):
  2396. # Extracted from test_math.MathTests.testFsum. Trigger the compilation
  2397. # of a hot function from another module; at one point in the
  2398. # optimization of LOAD_GLOBAL, this caused errors because we were using
  2399. # the wrong globals dictionary. We included it here as a simple
  2400. # regression test.
  2401. if "random" in sys.modules:
  2402. del sys.modules["random"]
  2403. from random import gauss # A pure-Python function in another module.
  2404. def foo():
  2405. for _ in xrange(1000 * 200):
  2406. v = gauss(0, 0.7) ** 7
  2407. foo()
  2408. self.assertEquals(gauss.__code__.co_use_jit, True)
  2409. def test_global_name_unknown_at_compilation_time(self):
  2410. # Extracted from Sympy: the global `match` is unknown when foo() becomes
  2411. # hot, but will be known by the time `trigger` has items. This used
  2412. # to raise a NameError while compiling foo() to LLVM IR.
  2413. #
  2414. # The code-under-test is written like this to avoid conditional jumps,
  2415. # which may contain their own guards.
  2416. foo = compile_for_llvm("foo", """
  2417. def foo(trigger):
  2418. for x in trigger:
  2419. return match
  2420. return 5
  2421. """, optimization_level=None)
  2422. spin_until_hot(foo, [[]])
  2423. self.assertEquals(foo.__code__.co_use_jit, True)
  2424. self.assertEquals(foo([]), 5)
  2425. # Set `match` so that we can run foo(True) and have it work correctly.
  2426. global match
  2427. match = 7
  2428. self.assertEquals(foo([1]), 7)
  2429. # Looking up `match` doesn't depend on any pointers cached in the IR,
  2430. # so changing the globals didn't invalidate the code.
  2431. self.assertEquals(foo.__code__.co_use_jit, True)
  2432. self.assertEquals(foo.__code__.co_fatalbailcount, 0)
  2433. del match
  2434. def test_print_ir_after_LOAD_GLOBAL_fatal_bail(self):
  2435. # Regression test: this used to segfault when trying to print co_llvm
  2436. # after a fatal bail out of a function using the optimized LOAD_GLOBAL.
  2437. # The fatal bail code left the support infrastructure for LOAD_GLOBAL
  2438. # in a corrupted state.
  2439. foo = compile_for_llvm("foo", """
  2440. def foo():
  2441. return len
  2442. """, optimization_level=None)
  2443. spin_until_hot(foo)
  2444. self.assertTrue(foo.__code__.co_use_jit)
  2445. # Force a fatal bail.
  2446. with test_support.swap_attr(__builtin__, "len", lambda x: 42):
  2447. foo()
  2448. # This used to cause a segfault.
  2449. self.assertTrue(str(foo.__code__.co_llvm))
  2450. def test_setprofile_in_leaf_function(self):
  2451. # Make sure that the fast version of CALL_FUNCTION supports profiling.
  2452. data = []
  2453. def record_profile(*args):
  2454. data.append(args)
  2455. def profiling_leaf():
  2456. sys.setprofile(record_profile)
  2457. def outer(leaf):
  2458. [leaf(), len([])]
  2459. spin_until_hot(outer, [lambda: None])
  2460. self.assertTrue(outer.__code__.co_use_jit)
  2461. sys.setbailerror(False)
  2462. outer(profiling_leaf)
  2463. sys.setprofile(None)
  2464. len_event = data[1]
  2465. # Slice off the frame object.
  2466. self.assertEqual(len_event[1:], ("c_call", len))
  2467. def test_fastcalls_bail_on_unknown_function(self):
  2468. # If the function is different than the one that we've assumed, we
  2469. # need to bail to the interpreter.
  2470. def foo(f):
  2471. return f([])
  2472. spin_until_hot(foo, [len])
  2473. self.assertTrue(foo.__code__.co_use_jit)
  2474. self.assertRaises(RuntimeError, foo, lambda x: 7)
  2475. # Make sure bailing does the right thing.
  2476. self.assertTrue(foo.__code__.co_use_jit)
  2477. sys.setbailerror(False)
  2478. self.assertEqual(foo(lambda x: 7), 7)
  2479. def test_guard_failure_blocks_native_code(self):
  2480. # Until we can recompile things, failing a guard should force use of the
  2481. # eval loop forever after. Even once we can recompile things, we should
  2482. # limit how often we're willing to recompile highly-dynamic functions.
  2483. # test_mutants has a good example of this.
  2484. # Compile like this so we get a new code object every time.
  2485. foo = compile_for_llvm("foo", "def foo(): return len([])",
  2486. optimization_level=None)
  2487. spin_until_hot(foo, [])
  2488. self.assertEqual(foo.__code__.co_use_jit, True)
  2489. self.assertEqual(foo.__code__.co_fatalbailcount, 0)
  2490. self.assertEqual(foo(), 0)
  2491. with test_support.swap_attr(__builtin__, "len", lambda x: 7):
  2492. self.assertEqual(foo.__code__.co_use_jit, False)
  2493. self.assertEqual(foo.__code__.co_fatalbailcount, 1)
  2494. # Since we can't recompile things yet, co_use_jit should be left
  2495. # at False and execution should use the eval loop.
  2496. spin_until_hot(foo, [])
  2497. self.assertEqual(foo.__code__.co_use_jit, False)
  2498. self.assertEqual(foo(), 7)
  2499. def test_fast_calls_method(self):
  2500. # This used to crash at one point while developing CALL_FUNCTION's
  2501. # FDO-ified machine code. We include it here as a simple regression
  2502. # test.
  2503. d = dict.fromkeys(range(12000))
  2504. foo = compile_for_llvm('foo', 'def foo(x): return x()',
  2505. optimization_level=None)
  2506. spin_until_hot(foo, [d.popitem])
  2507. self.assertTrue(foo.__code__.co_use_jit)
  2508. k, v = foo(d.popitem)
  2509. self.assertTrue(k < 12000, k)
  2510. self.assertEqual(v, None)
  2511. def test_fast_calls_two_arguments(self):
  2512. # Test our ability to optimize calls to METH_ARG_RANGE/arity=2 functions.
  2513. foo = compile_for_llvm('foo', 'def foo(x): return isinstance(x, int)',
  2514. optimization_level=None)
  2515. spin_until_hot(foo, [5])
  2516. self.assertTrue(foo.__code__.co_use_jit)
  2517. self.assertTrue(foo(5))
  2518. self.assertFalse(foo([]))
  2519. self.assertContains("@isinstance", str(foo.__code__.co_llvm))
  2520. def test_fast_calls_three_arguments(self):
  2521. # Test our ability to optimize calls to METH_ARG_RANGE/arity=3 functions.
  2522. foo = compile_for_llvm('foo', 'def foo(x): setattr(x, "y", 5)',
  2523. optimization_level=None)
  2524. class Object(object):
  2525. pass
  2526. x = Object()
  2527. spin_until_hot(foo, [x])
  2528. self.assertEqual(x.y, 5)
  2529. self.assertTrue(foo.__code__.co_use_jit)
  2530. self.assertContains("@setattr", str(foo.__code__.co_llvm))
  2531. def test_fast_calls_variadic_arguments(self):
  2532. # Test our ability to optimize calls to METH_ARG_RANGE functions.
  2533. foo = compile_for_llvm('foo', 'def foo(x): return sum(x, 1)',
  2534. optimization_level=None)
  2535. input = [1, 2]
  2536. spin_until_hot(foo, [input])
  2537. self.assertTrue(foo.__code__.co_use_jit)
  2538. self.assertEqual(foo([2, 3]), 6)
  2539. self.assertRaises(TypeError, foo, 5)
  2540. self.assertContains("@sum", str(foo.__code__.co_llvm))
  2541. def test_fast_calls_variadic_arguments_missing_args(self):
  2542. # Test our ability to optimize calls to METH_ARG_RANGE functions.
  2543. # Call with #args < max arity.
  2544. foo = compile_for_llvm('foo', 'def foo(x): return sum(x)',
  2545. optimization_level=None)
  2546. input = [1, 2]
  2547. spin_until_hot(foo, [input])
  2548. self.assertTrue(foo.__code__.co_use_jit)
  2549. self.assertEqual(foo([2, 3]), 5)
  2550. self.assertRaises(TypeError, foo, 5)
  2551. self.assertContains("@sum", str(foo.__code__.co_llvm))
  2552. def test_fast_calls_same_method_different_invocant(self):
  2553. # For all strings, x.join will resolve to the same C function, so
  2554. # it should use the fast version of CALL_FUNCTION that calls the
  2555. # function pointer directly.
  2556. foo = compile_for_llvm('foo', 'def foo(x): return x.join(["c", "d"])',
  2557. optimization_level=None)
  2558. spin_until_hot(foo, ["a"], ["c"])
  2559. self.assertTrue(foo.__code__.co_use_jit)
  2560. self.assertEqual(foo("a"), "cad")
  2561. # A new, unknown-to-the-feedback-system instance should reuse the
  2562. # same function, just with a different invocant.
  2563. self.assertEqual(foo("b"), "cbd")
  2564. def _string_formatting_specialization_test(self, good_type, bail_type):
  2565. # If we specialize on 8-bit strings, Unicode will bail, and vice-versa.
  2566. good_string = good_type("ab%sd")
  2567. bail_string = bail_type("ab%sd")
  2568. foo = compile_for_llvm("foo", "def foo(a, b): return a % b",
  2569. optimization_level=None)
  2570. spin_until_hot(foo, [good_string, 5])
  2571. self.assertTrue(foo.__code__.co_use_jit)
  2572. self.assertEquals(foo(good_string, 5), "ab5d")
  2573. self.assertEquals(type(foo(good_string, 5)), good_type)
  2574. # Test guard conditions.
  2575. self.assertRaises(RuntimeError, foo, 5, 2)
  2576. self.assertRaises(RuntimeError, foo, bail_string, "c")
  2577. sys.setbailerror(False)
  2578. self.assertEquals(foo(5, 2), 1)
  2579. self.assertEquals(foo(bail_string, "c"), bail_type("abcd"))
  2580. self.assertEquals(type(foo(bail_string, "c")), bail_type)
  2581. def test_str_formatting_specialization(self):
  2582. self._string_formatting_specialization_test(str, unicode)
  2583. def test_unicode_formatting_specialization(self):
  2584. self._string_formatting_specialization_test(unicode, str)
  2585. def test_inconsistent_binop_training(self):
  2586. # Force some polymorphism into this function, then make sure we don't
  2587. # do any inlining of multiplication.
  2588. mul = compile_for_llvm("mul", "def mul(a, b): return a * b",
  2589. optimization_level=None)
  2590. spin_until_hot(mul, [3, 4], [3.0, 4.0])
  2591. self.assertTrue(mul.__code__.co_use_jit)
  2592. self.assertContains("PyNumber_Multiply", str(mul.__code__.co_llvm))
  2593. self.assertEquals(mul(3, 4), 12)
  2594. self.assertEquals(mul(3.0, 4.0), 12.0)
  2595. def test_inlining_modulo_ints(self):
  2596. mod = compile_for_llvm("mod", "def mod(a, b): return a % b",
  2597. optimization_level=None)
  2598. # Prime with ints.
  2599. spin_until_hot(mod, [8, 3])
  2600. self.assertTrue(mod.__code__.co_use_jit)
  2601. self.assertEqual(mod(8, 3), 2)
  2602. self.assertEqual(mod(9, 2), 1)
  2603. self.assertEqual(mod(9, 1), 0)
  2604. self.assertEqual(mod(9, -1), 0)
  2605. self.assertEqual(mod(-9, 1), 0)
  2606. self.assertEqual(mod(-10, -4), -2)
  2607. # Test bailing.
  2608. self.assertRaises(RuntimeError, mod, 5.0, 2)
  2609. self.assertRaises(RuntimeError, mod, 5, 2.0)
  2610. self.assertRaises(RuntimeError, mod, 9, 0)
  2611. self.assertRaises(RuntimeError, mod, -sys.maxint - 1, -1)
  2612. # Test correctly handling error/special cases.
  2613. sys.setbailerror(False)
  2614. self.assertRaises(ZeroDivisionError, mod, 9, 0)
  2615. x = mod(-sys.maxint - 1, -1)
  2616. self.assertEqual(x, 0L)
  2617. self.assertEqual(type(x), long)
  2618. def test_inlining_add_sub_on_ints_and_floats(self):
  2619. # Test our ability to optimize addition and subtraction on ints and
  2620. # floats by inlining their implementations.
  2621. foo_float = compile_for_llvm('foo', 'def foo(a, b, c): return a+b-c',
  2622. optimization_level=None)
  2623. foo_int = compile_for_llvm('foo', 'def foo(a, b, c): return a+b-c',
  2624. optimization_level=None)
  2625. self.assertEqual(foo_float(1.0, 2.0, 3.0), 0.0)
  2626. self.assertEqual(foo_int(1, 2, 3), 0)
  2627. # Specialize foo_float and foo_int on their respective types.
  2628. spin_until_hot(foo_float, [1.0, 2.0, 3.0])
  2629. spin_until_hot(foo_int, [1, 2, 3])
  2630. self.assertTrue(foo_float.__code__.co_use_jit)
  2631. self.assertTrue(foo_int.__code__.co_use_jit)
  2632. # Test bailing
  2633. self.assertRaises(RuntimeError, foo_float, 1.0, 1.0, 1)
  2634. self.assertRaises(RuntimeError, foo_int, 1, 1, 1.0)
  2635. self.assertRaises(RuntimeError, foo_float, 1.0, 1.0, object())
  2636. self.assertRaises(RuntimeError, foo_int, 1, 1, object())
  2637. self.assertRaises(RuntimeError, foo_float, 1.0, 1.0, (1,))
  2638. self.assertRaises(RuntimeError, foo_int, 1, 1, (1,))
  2639. self.assertRaises(RuntimeError, foo_float, 1.0, 1.0, True)
  2640. self.assertRaises(RuntimeError, foo_int, 1, 1, True)
  2641. # Test PyIntType overflow
  2642. self.assertRaises(RuntimeError, foo_int, sys.maxint, sys.maxint, 1)
  2643. # Test if bailing still gives a correct result
  2644. sys.setbailerror(False)
  2645. self.assertEqual(foo_float(1.0, 1.0, 1), 1.0)
  2646. self.assertEqual(foo_int(1, 1, 1.0), 1.0)
  2647. self.assertRaises(TypeError, foo_float, 1.0, 1.0, object())
  2648. self.assertRaises(TypeError, foo_int, 1, 1, object())
  2649. self.assertRaises(TypeError, foo_float, 1.0, 1.0, (1,))
  2650. self.assertRaises(TypeError, foo_int, 1, 1, (1,))
  2651. self.assertEqual(foo_float(1.0, 1.0, True), 1.0)
  2652. self.assertEqual(foo_int(1, 1, True), 1)
  2653. # Test if PyIntType overflow gives a correct result
  2654. self.assertEqual(foo_int(sys.maxint, sys.maxint, 1),
  2655. long(sys.maxint)+long(sys.maxint)-1)
  2656. def test_inlining_mult_div_on_ints_and_floats(self):
  2657. # Test our ability to optimize certain binary ops by inlining them
  2658. # TODO(collinwinter): reduce duplication here.
  2659. foo_float = compile_for_llvm('foo', 'def foo(a, b, c): return (a*b)/c',
  2660. optimization_level=None)
  2661. foo_int = compile_for_llvm('foo', 'def foo(a, b, c): return (a*b)/c',
  2662. optimization_level=None)
  2663. mul_float_int = compile_for_llvm('foo', 'def foo(a, b): return a * b',
  2664. optimization_level=None)
  2665. div_float_int = compile_for_llvm('foo', 'def foo(a, b): return a / b',
  2666. optimization_level=None)
  2667. self.assertEqual(foo_float(1.0, 2.0, 2.0), 1.0)
  2668. self.assertEqual(foo_int(1, 2, 2), 1)
  2669. # Specialize foo_float and foo_int on their respective types.
  2670. spin_until_hot(foo_float, [1.0, 2.0, 2.0])
  2671. spin_until_hot(foo_int, [1, 2, 2])
  2672. spin_until_hot(mul_float_int, [1.0, 2])
  2673. spin_until_hot(div_float_int, [1.0, 2])
  2674. self.assertTrue(foo_float.__code__.co_use_jit)
  2675. self.assertTrue(foo_int.__code__.co_use_jit)
  2676. self.assertTrue(mul_float_int.__code__.co_use_jit)
  2677. self.assertTrue(div_float_int.__code__.co_use_jit)
  2678. for func in [foo_float, foo_int, mul_float_int, div_float_int]:
  2679. self.assertFalse("PyNumber_Multiply" in str(func.__code__.co_llvm))
  2680. self.assertFalse("PyNumber_Divide" in str(func.__code__.co_llvm))
  2681. # Test bailing
  2682. self.assertRaises(RuntimeError, foo_float, 1, 1.0, 1.0)
  2683. self.assertRaises(RuntimeError, foo_float, 1.0, 1, 1.0)
  2684. self.assertRaises(RuntimeError, foo_float, 1.0, 1.0, 1)
  2685. self.assertRaises(RuntimeError, foo_int, 1.0, 1, 1)
  2686. self.assertRaises(RuntimeError, foo_int, 1, 1.0, 1)
  2687. self.assertRaises(RuntimeError, foo_int, 1, 1, 1.0)
  2688. self.assertRaises(RuntimeError, mul_float_int, 2.0, 1.0)
  2689. self.assertRaises(RuntimeError, mul_float_int, 2, 1.0)
  2690. self.assertRaises(RuntimeError, div_float_int, 2.0, 1.0)
  2691. self.assertRaises(RuntimeError, div_float_int, 2, 1.0)
  2692. # Test bailing, ZeroDivision
  2693. self.assertRaises(RuntimeError, foo_float, 1.0, 1.0, 0.0)
  2694. self.assertRaises(RuntimeError, foo_int, 1, 1, 0)
  2695. self.assertRaises(RuntimeError, div_float_int, 1.0, 0)
  2696. # Test int overflow
  2697. self.assertRaises(RuntimeError, foo_int, sys.maxint, sys.maxint, 1)
  2698. # Floats do not overflow like ints do; this should not bail.
  2699. self.assertEqual(mul_float_int(float(sys.maxint), sys.maxint),
  2700. float(sys.maxint) * sys.maxint)
  2701. # Test if bailing still gives a correct result
  2702. sys.setbailerror(False)
  2703. self.assertEqual(foo_float(1.0, 1.0, 1), 1.0)
  2704. self.assertEqual(foo_int(1, 1, 1.0), 1.0)
  2705. self.assertEqual(mul_float_int(2.0, 1), 2.0)
  2706. self.assertEqual(mul_float_int(2, 1.0), 2.0)
  2707. self.assertEqual(div_float_int(2.0, 1), 2.0)
  2708. self.assertEqual(div_float_int(2, 1.0), 2.0)
  2709. self.assertRaises(ZeroDivisionError, foo_float, 1.0, 1.0, 0.0)
  2710. self.assertRaises(ZeroDivisionError, foo_int, 1, 1, 0)
  2711. self.assertRaises(ZeroDivisionError, div_float_int, 1.0, 0)
  2712. # Test if overflow gives a correct result
  2713. self.assertEqual(foo_int(sys.maxint, sys.maxint, 1),
  2714. long(sys.maxint) * long(sys.maxint))
  2715. self.assertEqual(mul_float_int(float(sys.maxint), sys.maxint),
  2716. float(sys.maxint) * sys.maxint)
  2717. def getitem_inlining_test(self, getitem_type):
  2718. # Test BINARY_SUBSCR specialization for indexing a sequence with an int.
  2719. foo = compile_for_llvm('foo', 'def foo(a, b): return a[b]',
  2720. optimization_level=None)
  2721. a = getitem_type([1])
  2722. spin_until_hot(foo, [a, 0])
  2723. self.assertTrue(foo.__code__.co_use_jit)
  2724. self.assertEqual(foo(a, 0), 1)
  2725. self.assertEqual(foo(a, -1), 1)
  2726. # Make sure unexpected types bail to the interpreter.
  2727. self.assertRaises(RuntimeError, foo, object(), 0)
  2728. self.assertRaises(RuntimeError, foo, a, object())
  2729. self.assertRaises(RuntimeError, foo, a, True)
  2730. self.assertRaises(RuntimeError, foo, a, (0,))
  2731. # Testing for out-of-bounds conditions.
  2732. self.assertRaises(RuntimeError, foo, a, -10)
  2733. self.assertRaises(RuntimeError, foo, a, 10)
  2734. # Make sure unexpected types are still handled correctly after bailing.
  2735. sys.setbailerror(False)
  2736. self.assertRaises(TypeError, foo, object(), 0)
  2737. self.assertRaises(TypeError, foo, a, object())
  2738. self.assertRaises(TypeError, foo, a, (0,))
  2739. # Testing for out-of-bounds conditions.
  2740. self.assertRaises(IndexError, foo, a, True)
  2741. self.assertRaises(IndexError, foo, a, -10)
  2742. self.assertRaises(IndexError, foo, a, 10)
  2743. def test_inlining_list_getitem(self):
  2744. self.getitem_inlining_test(list)
  2745. def test_inlining_tuple_getitem(self):
  2746. self.getitem_inlining_test(tuple)
  2747. def test_inlining_list_setitem(self):
  2748. # Test STORE_SUBSCR specialization for indexing a list with an int.
  2749. foo = compile_for_llvm('foo', 'def foo(a, b, c): a[b] = c',
  2750. optimization_level=None)
  2751. a = [1]
  2752. spin_until_hot(foo, [a, 0, 10])
  2753. self.assertTrue(foo.__code__.co_use_jit)
  2754. self.assertEqual(a[0], 10)
  2755. # Test negative indices.
  2756. foo(a, -1, 15)
  2757. self.assertEqual(a[0], 15)
  2758. # We should only have specialized on the list/index types, not the value
  2759. # being stored.
  2760. foo(a, 0, "abc")
  2761. self.assertEqual(a[0], "abc")
  2762. # Make sure unexpected types bail to the interpreter.
  2763. self.assertRaises(RuntimeError, foo, object(), 0, 10)
  2764. self.assertRaises(RuntimeError, foo, a, object(), 10)
  2765. self.assertRaises(RuntimeError, foo, a, True, 10)
  2766. self.assertRaises(RuntimeError, foo, a, (0,), 10)
  2767. # Testing for out-of-bounds conditions.
  2768. self.assertRaises(RuntimeError, foo, a, -10, 10)
  2769. self.assertRaises(RuntimeError, foo, a, 10, 10)
  2770. # Make sure unexpected types are still handled correctly after bailing.
  2771. sys.setbailerror(False)
  2772. self.assertRaises(TypeError, foo, object(), 0, 10)
  2773. self.assertRaises(TypeError, foo, a, object(), 10)
  2774. self.assertRaises(TypeError, foo, a, (0,), 10)
  2775. # Testing for out-of-bounds conditions.
  2776. self.assertRaises(IndexError, foo, a, True, 10)
  2777. self.assertRaises(IndexError, foo, a, -10, 10)
  2778. self.assertRaises(IndexError, foo, a, 10, 10)
  2779. def _test_inlining_cmpop_generic(self, op, test_vals):
  2780. """
  2781. test_vals should be something like:
  2782. [
  2783. (3, 3), # True
  2784. (3, 4), # False
  2785. (3.0, 3), # bails
  2786. (3, 3.0), # bails
  2787. ]
  2788. """
  2789. sys.setbailerror(True)
  2790. cmpop_func = compile_for_llvm("cmpop_func",
  2791. "def cmpop_func(a, b): return a %s b" % op,
  2792. optimization_level=None)
  2793. true_vals, false_vals, bails_lhs, bails_rhs, bails_true, bails_false =\
  2794. test_vals
  2795. spin_until_hot(cmpop_func, true_vals)
  2796. self.assertTrue(cmpop_func.__code__.co_use_jit)
  2797. self.assertTrue(cmpop_func(*true_vals))
  2798. self.assertFalse(cmpop_func(*false_vals))
  2799. self.assertRaises(RuntimeError, cmpop_func, *bails_lhs)
  2800. self.assertRaises(RuntimeError, cmpop_func, *bails_rhs)
  2801. sys.setbailerror(False)
  2802. self.assertTrue(cmpop_func(*bails_true))
  2803. self.assertFalse(cmpop_func(*bails_false))
  2804. def test_inline_cmpops(self):
  2805. self._test_inlining_cmpop_generic("<", [
  2806. (3, 4),
  2807. (4, 3),
  2808. (2.0, 3),
  2809. (2, 3.0),
  2810. (2.0, 3.0),
  2811. (4.0, 3),
  2812. ])
  2813. self._test_inlining_cmpop_generic("<=", [
  2814. (3, 3),
  2815. (4, 3),
  2816. (3.0, 3),
  2817. (2, 3.0),
  2818. (3.0, 3),
  2819. (4.0, 3),
  2820. ])
  2821. self._test_inlining_cmpop_generic("==", [
  2822. (3, 3),
  2823. (4, 3),
  2824. (3.0, 3),
  2825. (2, 3.0),
  2826. (3.0, 3),
  2827. (4.0, 3),
  2828. ])
  2829. self._test_inlining_cmpop_generic("!=", [
  2830. (4, 3),
  2831. (3, 3),
  2832. (3.0, 3),
  2833. (2, 3.0),
  2834. (4.0, 3),
  2835. (3.0, 3),
  2836. ])
  2837. self._test_inlining_cmpop_generic(">", [
  2838. (4, 3),
  2839. (3, 4),
  2840. (2.0, 3),
  2841. (2, 3.0),
  2842. (4.0, 3),
  2843. (3.0, 4),
  2844. ])
  2845. self._test_inlining_cmpop_generic(">=", [
  2846. (4, 3),
  2847. (3, 4),
  2848. (2.0, 3),
  2849. (2, 3.0),
  2850. (4.0, 3),
  2851. (3.0, 4),
  2852. ])
  2853. self._test_inlining_cmpop_generic(">", [
  2854. (4.0, 3.0),
  2855. (3.0, 4.0),
  2856. (2.0, 3),
  2857. (2, 3.0),
  2858. (4, 3.0),
  2859. (3, 4.0),
  2860. ])
  2861. def test_inlining_string_len(self):
  2862. self.len_inlining_test("abcdef", length=6, unexpected_arg=[])
  2863. def test_inlining_unicode_len(self):
  2864. self.len_inlining_test(u"abcdef", length=6, unexpected_arg=[])
  2865. def test_inlining_list_len(self):
  2866. self.len_inlining_test([1, 2, 3, 4], length=4, unexpected_arg="")
  2867. def test_inlining_tuple_len(self):
  2868. self.len_inlining_test((1, 2, 3), length=3, unexpected_arg=[])
  2869. def test_inlining_dict_len(self):
  2870. self.len_inlining_test({1: 2, 3: 4}, length=2, unexpected_arg=[])
  2871. def len_inlining_test(self, arg, length, unexpected_arg):
  2872. foo = compile_for_llvm('foo', 'def foo(s): return len(s)',
  2873. optimization_level=None)
  2874. spin_until_hot(foo, [arg])
  2875. self.assertTrue(foo.__code__.co_use_jit)
  2876. self.assertEqual(foo(arg), length)
  2877. ir = str(foo.__code__.co_llvm)
  2878. self.assertContains("PyInt_FromSsize_t", ir)
  2879. self.assertNotContains("_PyEval_CallFunction", ir)
  2880. self.assertNotContains("@len", ir)
  2881. # Make sure unexpected types bail to the interpreter
  2882. self.assertRaises(RuntimeError, foo, unexpected_arg)
  2883. @at_each_optimization_level
  2884. def test_access_frame_locals_via_vars(self, level):
  2885. # We need to be able to call vars() inside an LLVM-compiled function
  2886. # and have it still work. This complicates some LLVM-side optimizations.
  2887. foo = compile_for_llvm("foo", """
  2888. def foo(x):
  2889. y = 7
  2890. return vars()
  2891. """, optimization_level=level)
  2892. got_vars = foo(8)
  2893. self.assertEqual(got_vars, {"x": 8, "y": 7})
  2894. @at_each_optimization_level
  2895. def test_access_frame_locals_via_dir(self, level):
  2896. # We need to be able to call dir() inside an LLVM-compiled function
  2897. # and have it still work. This complicates some LLVM-side optimizations.
  2898. foo = compile_for_llvm("foo", """
  2899. def foo(x):
  2900. y = 7
  2901. return dir()
  2902. """, optimization_level=level)
  2903. got_dir = foo(8)
  2904. self.assertEqual(set(got_dir), set(["x", "y"]))
  2905. @at_each_optimization_level
  2906. def test_access_frame_locals_via_locals(self, level):
  2907. # We need to be able to call locals() inside an LLVM-compiled function
  2908. # and have it still work. This complicates some LLVM-side optimizations.
  2909. foo = compile_for_llvm("foo", """
  2910. def foo(x):
  2911. z = 9
  2912. y = 7
  2913. del z
  2914. return locals()
  2915. """, optimization_level=level)
  2916. got_locals = foo(8)
  2917. self.assertEqual(got_locals, {"x": 8, "y": 7})
  2918. @at_each_optimization_level
  2919. def test_access_frame_locals_via_traceback(self, level):
  2920. # Some production code, like Django's fancy debugging pages, rely on
  2921. # being able to pull locals out of frame objects. This complicates some
  2922. # LLVM-side optimizations.
  2923. foo = compile_for_llvm("foo", """
  2924. def foo(x):
  2925. y = 7
  2926. raise ZeroDivisionError
  2927. """, optimization_level=level)
  2928. try:
  2929. foo(8)
  2930. except ZeroDivisionError:
  2931. tb = sys.exc_info()[2]
  2932. else:
  2933. self.fail("Failed to raise ZeroDivisionError")
  2934. # Sanity check to make sure we're getting the right frame.
  2935. self.assertEqual(tb.tb_next.tb_frame.f_code.co_name, "foo")
  2936. self.assertEqual(tb.tb_next.tb_frame.f_locals, {"y": 7, "x": 8})
  2937. @at_each_optimization_level
  2938. def test_access_frame_locals_in_finally_via_traceback(self, level):
  2939. # Some production code, like Django's fancy debugging pages, rely on
  2940. # being able to pull locals out of frame objects. This complicates some
  2941. # LLVM-side optimizations. This particular case is a strange corner
  2942. # case Jeffrey Yasskin thought up.
  2943. foo = compile_for_llvm("foo", """
  2944. def foo(x):
  2945. y = 7
  2946. try:
  2947. raise ZeroDivisionError
  2948. finally:
  2949. z = 9
  2950. """, optimization_level=level)
  2951. try:
  2952. foo(8)
  2953. except ZeroDivisionError:
  2954. tb = sys.exc_info()[2]
  2955. else:
  2956. self.fail("Failed to raise ZeroDivisionError")
  2957. # Sanity check to make sure we're getting the right frame.
  2958. self.assertEqual(tb.tb_next.tb_frame.f_code.co_name, "foo")
  2959. self.assertEqual(tb.tb_next.tb_frame.f_locals, {"y": 7, "x": 8, "z": 9})
  2960. def test_POP_JUMP_IF_FALSE_training_consistent(self):
  2961. # If we have runtime feedback, we'd like to be able to omit untaken
  2962. # branches to a) reduce code size, b) give the optimizers less input.
  2963. # We only do this if the branch is consistent (always 100%
  2964. # taken/not-taken).
  2965. foo = compile_for_llvm("foo", """
  2966. def foo(x):
  2967. if x:
  2968. return 7
  2969. hex(1)
  2970. return 8
  2971. """, optimization_level=None)
  2972. spin_until_hot(foo, [True])
  2973. self.assertTrue(foo.__code__.co_use_jit)
  2974. self.assertEqual(foo(True), 7)
  2975. self.assertRaises(RuntimeError, foo, False)
  2976. self.assertEqual(foo.__code__.co_fatalbailcount, 0)
  2977. sys.setbailerror(False)
  2978. self.assertTrue(foo.__code__.co_use_jit)
  2979. self.assertEqual(foo(False), 8)
  2980. # Make sure we didn't actually compile the untaken branch to LLVM IR.
  2981. self.assertTrue("@hex" not in str(foo.__code__.co_llvm))
  2982. def test_POP_JUMP_IF_FALSE_training_inconsistent(self):
  2983. # If we have runtime feedback, we'd like to be able to omit untaken
  2984. # branches. We can't do this, though, if the branch is inconsistent.
  2985. foo = compile_for_llvm("foo", """
  2986. def foo(x):
  2987. if x:
  2988. return 7
  2989. hex(1)
  2990. return 8
  2991. """, optimization_level=None)
  2992. spin_until_hot(foo, [True], [False])
  2993. self.assertTrue(foo.__code__.co_use_jit)
  2994. self.assertEqual(foo(True), 7)
  2995. self.assertEqual(foo(False), 8) # Does not raise RuntimeError
  2996. # Make sure we compiled both branches to LLVM IR.
  2997. self.assertContains("@hex", str(foo.__code__.co_llvm))
  2998. def test_POP_JUMP_IF_TRUE_training_consistent(self):
  2999. # If we have runtime feedback, we'd like to be able to omit untaken
  3000. # branches to a) reduce code size, b) give the optimizers less input.
  3001. # We only do this if the branch is consistent (always 100%
  3002. # taken/not-taken).
  3003. foo = compile_for_llvm("foo", """
  3004. def foo(x):
  3005. if not x:
  3006. return 7
  3007. hex(1)
  3008. return 8
  3009. """, optimization_level=None)
  3010. spin_until_hot(foo, [False])
  3011. self.assertTrue(foo.__code__.co_use_jit)
  3012. self.assertEqual(foo(False), 7)
  3013. self.assertRaises(RuntimeError, foo, True)
  3014. self.assertEqual(foo.__code__.co_fatalbailcount, 0)
  3015. sys.setbailerror(False)
  3016. self.assertTrue(foo.__code__.co_use_jit)
  3017. self.assertEqual(foo(True), 8)
  3018. # Make sure we didn't actually compile the untaken branch to LLVM IR.
  3019. self.assertTrue("@hex" not in str(foo.__code__.co_llvm))
  3020. def test_POP_JUMP_IF_TRUE_training_inconsistent(self):
  3021. # If we have runtime feedback, we'd like to be able to omit untaken
  3022. # branches. We can't do this, though, if the branch is inconsistent.
  3023. foo = compile_for_llvm("foo", """
  3024. def foo(x):
  3025. if not x:
  3026. return 7
  3027. hex(1)
  3028. return 8
  3029. """, optimization_level=None)
  3030. spin_until_hot(foo, [True], [False])
  3031. self.assertTrue(foo.__code__.co_use_jit)
  3032. self.assertEqual(foo(False), 7)
  3033. self.assertEqual(foo(True), 8) # Does not raise RuntimeError
  3034. # Make sure we compiled both branches to LLVM IR.
  3035. self.assertContains("@hex", str(foo.__code__.co_llvm))
  3036. def test_JUMP_IF_FALSE_OR_POP_training_consistent(self):
  3037. # If we have runtime feedback, we'd like to be able to omit untaken
  3038. # branches to a) reduce code size, b) give the optimizers less input.
  3039. # We only do this if the branch is consistent (always 100%
  3040. # taken/not-taken).
  3041. foo = compile_for_llvm("foo", """
  3042. def foo(x):
  3043. return x and hex(1)
  3044. """, optimization_level=None)
  3045. spin_until_hot(foo, [False])
  3046. self.assertTrue(foo.__code__.co_use_jit)
  3047. self.assertEqual(foo(False), False)
  3048. self.assertRaises(RuntimeError, foo, True)
  3049. self.assertEqual(foo.__code__.co_fatalbailcount, 0)
  3050. sys.setbailerror(False)
  3051. self.assertTrue(foo.__code__.co_use_jit)
  3052. self.assertEqual(foo(True), '0x1')
  3053. # Make sure we didn't actually compile the untaken branch to LLVM IR.
  3054. self.assertTrue("@hex" not in str(foo.__code__.co_llvm))
  3055. def test_JUMP_IF_FALSE_OR_POP_training_inconsistent(self):
  3056. # If we have runtime feedback, we'd like to be able to omit untaken
  3057. # branches. We can't do this, though, if the branch is inconsistent.
  3058. foo = compile_for_llvm("foo", """
  3059. def foo(x):
  3060. return x and hex(1)
  3061. """, optimization_level=None)
  3062. spin_until_hot(foo, [True], [False])
  3063. self.assertTrue(foo.__code__.co_use_jit)
  3064. self.assertEqual(foo(False), False)
  3065. self.assertEqual(foo(True), '0x1') # Does not raise RuntimeError
  3066. # Make sure we compiled both branches to LLVM IR.
  3067. self.assertContains("@hex", str(foo.__code__.co_llvm))
  3068. def test_JUMP_IF_TRUE_OR_POP_training_consistent(self):
  3069. # If we have runtime feedback, we'd like to be able to omit untaken
  3070. # branches to a) reduce code size, b) give the optimizers less input.
  3071. # We only do this if the branch is consistent (always 100%
  3072. # taken/not-taken).
  3073. foo = compile_for_llvm("foo", """
  3074. def foo(x):
  3075. return x or hex(1)
  3076. """, optimization_level=None)
  3077. spin_until_hot(foo, [True])
  3078. self.assertTrue(foo.__code__.co_use_jit)
  3079. self.assertEqual(foo(True), True)
  3080. self.assertRaises(RuntimeError, foo, False)
  3081. self.assertEqual(foo.__code__.co_fatalbailcount, 0)
  3082. sys.setbailerror(False)
  3083. self.assertTrue(foo.__code__.co_use_jit)
  3084. self.assertEqual(foo(False), '0x1')
  3085. # Make sure we didn't actually compile the untaken branch to LLVM IR.
  3086. self.assertTrue("@hex" not in str(foo.__code__.co_llvm))
  3087. def test_JUMP_IF_TRUE_OR_POP_training_inconsistent(self):
  3088. # If we have runtime feedback, we'd like to be able to omit untaken
  3089. # branches. We can't do this, though, if the branch is inconsistent.
  3090. foo = compile_for_llvm("foo", """
  3091. def foo(x):
  3092. return x or hex(1)
  3093. """, optimization_level=None)
  3094. spin_until_hot(foo, [True], [False])
  3095. self.assertTrue(foo.__code__.co_use_jit)
  3096. self.assertEqual(foo(True), True)
  3097. self.assertEqual(foo(False), '0x1') # Does not raise RuntimeError
  3098. # Make sure we compiled both branches to LLVM IR.
  3099. self.assertContains("@hex", str(foo.__code__.co_llvm))
  3100. def test_import_does_not_bail(self):
  3101. # Regression test: this simple import (which hits sys.modules!) used
  3102. # to cause invalidation due to no-op assignments to the globals dict
  3103. # done deep within the import machinery.
  3104. foo = compile_for_llvm("foo", """
  3105. def foo():
  3106. import os
  3107. return len([])
  3108. """, optimization_level=None)
  3109. import os # Make sure this is in sys.modules.
  3110. spin_until_hot(foo)
  3111. # If we get here, we haven't bailed, but double-check to be sure.
  3112. self.assertTrue(foo.__code__.co_use_jit)
  3113. def test_load_attr_fast_bails(self):
  3114. # Test that this simple object uses fast attribute lookup. We do this
  3115. # by checking that it bails when we stick a descriptor on the class for
  3116. # that attribute.
  3117. class C(object):
  3118. def __init__(self, foo=0):
  3119. self.foo = foo
  3120. def get_foo(c):
  3121. return c.foo
  3122. c = C()
  3123. spin_until_hot(get_foo, [c])
  3124. self.assertTrue(get_foo.__code__.co_use_jit)
  3125. # Check that the code bails correctly by passing an argument of another
  3126. # type.
  3127. class D(object):
  3128. def __init__(self):
  3129. self.foo = -1
  3130. d = D()
  3131. sys.setbailerror(True)
  3132. self.assertRaises(RuntimeError, get_foo, d)
  3133. # Check that another object of the same type doesn't bail.
  3134. c2 = C(foo=-1)
  3135. self.assertEqual(get_foo(c2), -1)
  3136. # Check that even though it bails, it gets the right answer.
  3137. sys.setbailerror(False)
  3138. self.assertEqual(get_foo(d), -1)
  3139. def test_load_attr_fast_new_descriptor_invalidates(self):
  3140. # Test that this simple object uses fast attribute lookup. We do this
  3141. # by modifying the type and checking that it invalidates the code.
  3142. class C(object):
  3143. def __init__(self):
  3144. self.foo = 0
  3145. def get_foo(c):
  3146. return c.foo
  3147. c = C()
  3148. spin_until_hot(get_foo, [c])
  3149. self.assertTrue(get_foo.__code__.co_use_jit)
  3150. # Check that invalidating the code by assigning a descriptor works.
  3151. # The descriptor on the type will override the object attribute.
  3152. def new_get_foo(self):
  3153. return -1
  3154. C.foo = property(new_get_foo)
  3155. self.assertFalse(get_foo.__code__.co_use_jit)
  3156. self.assertEqual(c.foo, -1)
  3157. self.assertEqual(get_foo(c), -1)
  3158. def test_load_attr_fast_no_dict(self):
  3159. # Test that an object with no dict, ie one using slots, uses fast
  3160. # attribute lookup. We do this by modifying the type and checking that
  3161. # it invalidates the code.
  3162. class C(object):
  3163. __slots__ = ('foo',)
  3164. def __init__(self):
  3165. self.foo = 0
  3166. def get_foo(c):
  3167. return c.foo
  3168. c = C()
  3169. self.assertFalse(hasattr(c, '__dict__'))
  3170. spin_until_hot(get_foo, [c])
  3171. self.assertTrue(get_foo.__code__.co_use_jit)
  3172. # Check that invalidating the code by assigning a descriptor works.
  3173. # The descriptor on the type will override the object attribute.
  3174. def new_get_foo(self):
  3175. return -1
  3176. C.foo = property(new_get_foo)
  3177. self.assertFalse(get_foo.__code__.co_use_jit)
  3178. self.assertEqual(c.foo, -1)
  3179. self.assertEqual(get_foo(c), -1)
  3180. def test_load_attr_fast_with_data_descriptor(self):
  3181. # Test that this simple object uses fast attribute lookup. We do this
  3182. # by checking that it bails when we modify the data descriptor. We do
  3183. # this by modifying the type and checking that it invalidates the code.
  3184. class C(object):
  3185. @property
  3186. def foo(self):
  3187. return 0
  3188. def get_foo(c):
  3189. return c.foo
  3190. c = C()
  3191. spin_until_hot(get_foo, [c])
  3192. self.assertTrue(get_foo.__code__.co_use_jit)
  3193. # Check that invalidating the code by assigning a descriptor works.
  3194. def new_foo(self):
  3195. return -1
  3196. C.foo = property(new_foo)
  3197. self.assertFalse(get_foo.__code__.co_use_jit)
  3198. self.assertEqual(c.foo, -1)
  3199. self.assertEqual(get_foo(c), -1)
  3200. def test_load_attr_fast_mutate_descriptor_type(self):
  3201. # Make two descriptor classes and them mutate the class of an instance
  3202. # from one to the other.
  3203. class DescrOne(object):
  3204. def __get__(self, inst, type=None):
  3205. return 1
  3206. def __set__(self, inst, value):
  3207. raise AttributeError
  3208. def __delete__(self, inst, value):
  3209. raise AttributeError
  3210. class DescrTwo(object):
  3211. def __get__(self, inst, type=None):
  3212. return 2
  3213. def __set__(self, inst, value):
  3214. raise AttributeError
  3215. def __delete__(self, inst, value):
  3216. raise AttributeError
  3217. class C(object):
  3218. foo = DescrOne()
  3219. c = C()
  3220. def get_foo(c):
  3221. return c.foo
  3222. def test_mutate_descriptor():
  3223. self.assertEqual(get_foo(c), 1)
  3224. # We can't do C.foo, because that calls __get__
  3225. descr = C.__dict__["foo"].__class__ = DescrTwo
  3226. self.assertEqual(get_foo(c), 2)
  3227. # First check that our descriptor works as intended in the interpreter.
  3228. test_mutate_descriptor()
  3229. # Reset C.foo to a fresh DescrOne instance.
  3230. C.foo = DescrOne()
  3231. # Test them in the compiled code. We're concerned with correctness,
  3232. # not speed, so we turn off errors on bails.
  3233. spin_until_hot(get_foo, [c])
  3234. sys.setbailerror(False)
  3235. self.assertTrue(get_foo.__code__.co_use_jit)
  3236. test_mutate_descriptor()
  3237. self.assertTrue(get_foo.__code__.co_use_jit)
  3238. # Check that we were optimizing LOAD_ATTR by mutating the type.
  3239. C.foo = 3
  3240. self.assertFalse(get_foo.__code__.co_use_jit)
  3241. def test_load_attr_fast_mutate_non_data_descr_to_data_descr(self):
  3242. # Make a non-data descriptor class and a data-descriptor class and see
  3243. # if switching between them causes breakage.
  3244. class NonDataDescr(object):
  3245. def __get__(self, inst, type=None):
  3246. return 1
  3247. # By not defining __set__, we are not a data descriptor, which
  3248. # lowers our lookup precedence.
  3249. class DataDescr(object):
  3250. def __get__(self, inst, type=None):
  3251. return 3
  3252. def __set__(self, inst, value):
  3253. raise AttributeError
  3254. def __delete__(self, inst, value):
  3255. raise AttributeError
  3256. class C(object):
  3257. foo = NonDataDescr()
  3258. c = C()
  3259. def get_foo():
  3260. return c.foo
  3261. def test_mutate_descriptor():
  3262. self.assertEqual(get_foo(), 1)
  3263. c.foo = 2
  3264. self.assertEqual(C.foo, 1)
  3265. self.assertEqual(get_foo(), 2)
  3266. C.__dict__["foo"].__class__ = DataDescr
  3267. self.assertEqual(C.foo, 3)
  3268. self.assertEqual(get_foo(), 3)
  3269. # Reset the descriptor type and delete the attribute shadowing the
  3270. # descriptor.
  3271. C.__dict__["foo"].__class__ = NonDataDescr
  3272. del c.foo
  3273. # Ratify our theories about descriptor semantics in the interpreter.
  3274. test_mutate_descriptor()
  3275. # Test them in the compiled code. We're concerned with correctness,
  3276. # not speed, so we turn off errors on bails.
  3277. spin_until_hot(get_foo, [])
  3278. sys.setbailerror(False)
  3279. self.assertTrue(get_foo.__code__.co_use_jit)
  3280. test_mutate_descriptor()
  3281. # Note that the code is *not* invalidated when we mutate the class of
  3282. # the descriptor because we cannot listen for modifications. Instead,
  3283. # we have a guard on the type of the descriptor.
  3284. self.assertTrue(get_foo.__code__.co_use_jit)
  3285. # Check that we were optimizing LOAD_ATTR by mutating the type.
  3286. C.foo = 4
  3287. self.assertFalse(get_foo.__code__.co_use_jit)
  3288. def test_load_attr_fast_mutate_descriptor_to_non_descriptor(self):
  3289. # Make a descriptor class and then mutate the class so that it's a
  3290. # vanilla object instead of a descriptor.
  3291. class MyDescr(object):
  3292. def __init__(self):
  3293. self.value = 1
  3294. def __get__(self, inst, type=None):
  3295. return self.value
  3296. def __set__(self, inst, value):
  3297. raise AttributeError
  3298. def __delete__(self, inst, value):
  3299. raise AttributeError
  3300. class VanillaObject(object):
  3301. pass
  3302. class C(object):
  3303. foo = MyDescr()
  3304. c = C()
  3305. def get_foo():
  3306. return c.foo
  3307. def test_mutate_descriptor():
  3308. descr = C.__dict__["foo"] # Again, C.foo would call __get__.
  3309. descr.value = 1
  3310. self.assertEqual(get_foo(), 1)
  3311. descr.value = 2
  3312. self.assertEqual(get_foo(), 2)
  3313. descr.value = 3
  3314. descr.__class__ = VanillaObject
  3315. self.assertTrue(isinstance(get_foo(), VanillaObject))
  3316. self.assertEqual(get_foo().value, 3)
  3317. # Ratify our theories about descriptor semantics in the interpreter.
  3318. test_mutate_descriptor()
  3319. # Reset the class of the foo descriptor to MyDescr.
  3320. C.__dict__["foo"].__class__ = MyDescr
  3321. # Test them in the compiled code. We're concerned with correctness,
  3322. # not speed, so we turn off errors on bails.
  3323. spin_until_hot(get_foo, [])
  3324. sys.setbailerror(False)
  3325. self.assertTrue(get_foo.__code__.co_use_jit)
  3326. test_mutate_descriptor()
  3327. # Note that the code is *not* invalidated when we mutate the class of
  3328. # the descriptor because we cannot listen for modifications. Instead,
  3329. # we have a guard on the type of the descriptor.
  3330. self.assertTrue(get_foo.__code__.co_use_jit)
  3331. # Check that we were optimizing LOAD_ATTR by mutating the type.
  3332. C.foo = 4
  3333. self.assertFalse(get_foo.__code__.co_use_jit)
  3334. def test_load_attr_fast_mutate_descriptor_method(self):
  3335. # Make a descriptor class and then mutate mutate its __get__ method to
  3336. # return something else.
  3337. class MyDescr(object):
  3338. def __get__(self, inst, type=None):
  3339. return 1
  3340. def __set__(self, inst, value):
  3341. raise AttributeError
  3342. def __delete__(self, inst, value):
  3343. raise AttributeError
  3344. def new_get(self, inst, type=None):
  3345. return 2
  3346. old_get = MyDescr.__get__
  3347. class C(object):
  3348. foo = MyDescr()
  3349. c = C()
  3350. def get_foo():
  3351. return c.foo
  3352. def test_mutate_descriptor():
  3353. self.assertEqual(c.foo, 1)
  3354. MyDescr.__get__ = new_get
  3355. self.assertEqual(c.foo, 2)
  3356. # Ratify our theories about descriptor semantics in the interpreter.
  3357. test_mutate_descriptor()
  3358. # Reset the __get__ method.
  3359. MyDescr.__get__ = old_get
  3360. # Test them in the compiled code. We're concerned with correctness,
  3361. # not speed, so we turn off errors on bails.
  3362. spin_until_hot(get_foo, [])
  3363. sys.setbailerror(False)
  3364. self.assertTrue(get_foo.__code__.co_use_jit)
  3365. test_mutate_descriptor()
  3366. # Mutating the descriptor type invalidates the code.
  3367. self.assertFalse(get_foo.__code__.co_use_jit)
  3368. def test_load_attr_fast_freed_type(self):
  3369. # Train a code object on a certain type, and then free it. The code
  3370. # should not be holding a reference to the type, so it should become
  3371. # invalidated.
  3372. class C(object):
  3373. @property
  3374. def foo(self):
  3375. return 1
  3376. def get_foo(o):
  3377. return o.foo
  3378. c = C()
  3379. spin_until_hot(get_foo, [c])
  3380. self.assertTrue(get_foo.__code__.co_use_jit)
  3381. # Do this song and dance to free C.
  3382. ref = weakref.ref(C)
  3383. _llvm.clear_feedback(get_foo)
  3384. del c
  3385. del C
  3386. gc.collect() # Yes, this is necessary, the type gets in cycles.
  3387. self.assertEqual(ref(), None) # Check that C was really freed.
  3388. # Now that C is gone, the machine code should be invalid.
  3389. self.assertFalse(get_foo.__code__.co_use_jit)
  3390. def test_load_attr_fast_invalidates_during_call(self):
  3391. # Make sure we properly bail if we are invalidated while the method is
  3392. # running.
  3393. class C(object):
  3394. foo = 1
  3395. invalidate_code = False
  3396. def maybe_invalidate():
  3397. # This must be a separate function from get_foo, because the
  3398. # conditional will be cold when we change its value, and it will
  3399. # cause a bail. Because the functions are separate, it will not
  3400. # cause a bail in the get_foo code.
  3401. if invalidate_code:
  3402. C.foo = 2
  3403. def get_foo(o):
  3404. try:
  3405. maybe_invalidate()
  3406. except RuntimeError:
  3407. assert False, "maybe_invalidate bailed!"
  3408. return o.foo # This should bail if we've been invalidated.
  3409. c = C()
  3410. spin_until_hot(get_foo, [c])
  3411. self.assertTrue(get_foo.__code__.co_use_jit)
  3412. self.assertEqual(get_foo(c), 1)
  3413. invalidate_code = True
  3414. sys.setbailerror(False)
  3415. self.assertEqual(get_foo(c), 2)
  3416. self.assertFalse(get_foo.__code__.co_use_jit)
  3417. def test_store_attr_fast_bails(self):
  3418. class C(object):
  3419. pass
  3420. c = C()
  3421. def set_attr(o, x):
  3422. o.foo = x
  3423. spin_until_hot(set_attr, [c, 0])
  3424. # Check that this bails properly when called on itself, a function.
  3425. self.assertRaises(RuntimeError, set_attr, set_attr, 1)
  3426. # Check that when it bails, it does the correct thing.
  3427. sys.setbailerror(False)
  3428. set_attr(set_attr, 1)
  3429. self.assertEqual(set_attr.foo, 1)
  3430. set_attr(set_attr, 2)
  3431. self.assertEqual(set_attr.foo, 2)
  3432. def test_store_attr_fast_invalidates(self):
  3433. class C(object):
  3434. pass
  3435. c = C()
  3436. def set_attr(o, x):
  3437. o.foo = x
  3438. spin_until_hot(set_attr, [c, 0])
  3439. # Check that sticking a foo descriptor on C invalidates the code.
  3440. C.foo = property(lambda self: -1)
  3441. self.assertFalse(set_attr.__code__.co_use_jit)
  3442. self.assertEqual(c.foo, -1)
  3443. self.assertRaises(AttributeError, set_attr, c, 0)
  3444. self.assertEqual(c.foo, -1)
  3445. def test_store_attr_fast_mutate_vanilla_object_to_data_descriptor(self):
  3446. # Make a non-data descriptor class and a data-descriptor class and see
  3447. # if switching between them causes breakage.
  3448. class VanillaObject(object):
  3449. pass
  3450. class DataDescr(object):
  3451. def __get__(self, inst, type=None):
  3452. return inst._foo
  3453. def __set__(self, inst, value):
  3454. inst._foo = value
  3455. def __delete__(self, inst, value):
  3456. raise AttributeError
  3457. obj = VanillaObject()
  3458. class C(object):
  3459. foo = obj
  3460. c = C()
  3461. def set_foo(x):
  3462. c.foo = x
  3463. def test_mutate_descriptor():
  3464. self.assertEqual(c.foo, obj)
  3465. # Setting foo on c will shadow a non-data descriptor.
  3466. set_foo(2)
  3467. self.assertEqual(C.foo, obj)
  3468. self.assertEqual(c.foo, 2)
  3469. # Reset things by dropping the shadowing attribute.
  3470. del c.foo
  3471. # After we change the class, the new setter should be called, which
  3472. # sets c._foo as the backing store for c.foo. We test that __set__
  3473. # is called by checking both c._foo and c.foo.
  3474. C.__dict__["foo"].__class__ = DataDescr
  3475. unique_obj = VanillaObject()
  3476. set_foo(unique_obj)
  3477. self.assertEqual(c._foo, unique_obj)
  3478. self.assertEqual(c.foo, unique_obj)
  3479. # Reset the descriptor type.
  3480. C.__dict__["foo"].__class__ = VanillaObject
  3481. # Ratify our theories about descriptor semantics in the interpreter.
  3482. test_mutate_descriptor()
  3483. # Test them in the compiled code. We're concerned with correctness,
  3484. # not speed, so we turn off errors on bails.
  3485. spin_until_hot(set_foo, [0])
  3486. # Delete any stale foo attribute shadowing the non-data descriptor.
  3487. del c.foo
  3488. sys.setbailerror(False)
  3489. self.assertTrue(set_foo.__code__.co_use_jit)
  3490. test_mutate_descriptor()
  3491. # Note that the code is *not* invalidated when we mutate the class of
  3492. # the descriptor because we cannot listen for modifications. Instead,
  3493. # we have a guard on the type of the descriptor.
  3494. self.assertTrue(set_foo.__code__.co_use_jit)
  3495. # Check that it bails.
  3496. sys.setbailerror(True)
  3497. C.__dict__["foo"].__class__ = DataDescr
  3498. self.assertRaises(RuntimeError, set_foo, 0)
  3499. C.__dict__["foo"].__class__ = VanillaObject
  3500. # Check that we were optimizing LOAD_ATTR by mutating the type.
  3501. C.foo = 4
  3502. self.assertFalse(set_foo.__code__.co_use_jit)
  3503. def test_two_imports(self):
  3504. # Regression test: at one point in development, this would blow up due
  3505. # to adding the same watcher to sys.modules twice.
  3506. foo = compile_for_llvm("foo", """
  3507. def foo():
  3508. import os
  3509. import os
  3510. return os
  3511. """, optimization_level=None)
  3512. spin_until_hot(foo)
  3513. import os
  3514. self.assertTrue(foo.__code__.co_use_jit)
  3515. self.assertEqual(foo(), os)
  3516. self.assertTrue("_PyEval_ImportName" not in str(foo.__code__.co_llvm))
  3517. def test_cache_imports(self):
  3518. foo = compile_for_llvm("foo", """
  3519. def foo():
  3520. import os
  3521. return os
  3522. """, optimization_level=None)
  3523. spin_until_hot(foo)
  3524. import os
  3525. self.assertTrue(foo.__code__.co_use_jit)
  3526. self.assertEqual(foo(), os)
  3527. self.assertTrue("_PyEval_ImportName" not in str(foo.__code__.co_llvm))
  3528. def test_cache_imports_monomorphic_imports_only(self):
  3529. # Test that we refuse to optimize polymorphic imports.
  3530. foo = compile_for_llvm("foo", """
  3531. def foo():
  3532. import os
  3533. return os
  3534. """, optimization_level=None)
  3535. # Verify things work like we expect: mucking with sys.modules["x"]
  3536. # should change the result of "import x".
  3537. import os
  3538. self.assertEqual(foo(), os)
  3539. with test_support.swap_item(sys.modules, "os", 5):
  3540. self.assertEqual(foo(), 5)
  3541. self.assertFalse(foo.__code__.co_use_jit)
  3542. self.assertEqual(foo.__code__.co_fatalbailcount, 0)
  3543. # Normally we call _clear_feedback() here, but we want the 5 to count
  3544. # as a separate module.
  3545. spin_until_hot(foo)
  3546. self.assertEqual(foo.__code__.co_fatalbailcount, 0)
  3547. self.assertTrue(foo.__code__.co_use_jit)
  3548. self.assertEqual(foo(), os)
  3549. self.assertTrue("_PyEval_ImportName" in str(foo.__code__.co_llvm))
  3550. # Changing sys.modules will *not* trigger a fatal bail to the
  3551. # interpreter, since we couldn't use the IMPORT_NAME optimization.
  3552. with test_support.swap_item(sys.modules, "os", 5):
  3553. self.assertEqual(foo(), 5)
  3554. self.assertTrue(foo.__code__.co_use_jit)
  3555. self.assertEqual(foo.__code__.co_fatalbailcount, 0)
  3556. def test_cache_imports_robust_against_sys_modules_changes(self):
  3557. foo = compile_for_llvm("foo", """
  3558. def foo():
  3559. import os
  3560. return os
  3561. """, optimization_level=None)
  3562. # Verify things work like we expect: mucking with sys.modules["x"]
  3563. # should change the result of "import x".
  3564. import os
  3565. self.assertEqual(foo(), os)
  3566. with test_support.swap_item(sys.modules, "os", 5):
  3567. self.assertEqual(foo(), 5)
  3568. self.assertFalse(foo.__code__.co_use_jit)
  3569. self.assertEqual(foo.__code__.co_fatalbailcount, 0)
  3570. _llvm.clear_feedback(foo) # Don't let that 5 ruin things!
  3571. spin_until_hot(foo)
  3572. self.assertEqual(foo.__code__.co_fatalbailcount, 0)
  3573. self.assertTrue(foo.__code__.co_use_jit)
  3574. self.assertEqual(foo(), os)
  3575. # Changing sys.modules will trigger a fatal bail to the interpreter.
  3576. with test_support.swap_item(sys.modules, "os", 5):
  3577. self.assertEqual(foo(), 5)
  3578. self.assertFalse(foo.__code__.co_use_jit)
  3579. self.assertEqual(foo.__code__.co_fatalbailcount, 1)
  3580. def test_cache_imports_robust_against_target_assignments(self):
  3581. foo = compile_for_llvm("foo", """
  3582. def foo():
  3583. import os.path
  3584. return os.path
  3585. """, optimization_level=None)
  3586. # Verify things work like we expect.
  3587. import os.path
  3588. self.assertEqual(foo(), os.path)
  3589. _llvm.clear_feedback(foo)
  3590. spin_until_hot(foo)
  3591. self.assertEqual(foo.__code__.co_fatalbailcount, 0)
  3592. self.assertTrue(foo.__code__.co_use_jit)
  3593. self.assertEqual(foo(), os.path)
  3594. # This doesn't change sys.modules, but it still needs to work.
  3595. import os
  3596. with test_support.swap_attr(os, "path", 5):
  3597. self.assertEqual(foo(), 5)
  3598. self.assertTrue(foo.__code__.co_use_jit)
  3599. self.assertEqual(foo.__code__.co_fatalbailcount, 0)
  3600. def test_cache_imports_robust_against_parent_assignments(self):
  3601. foo = compile_for_llvm("foo", """
  3602. def foo():
  3603. from os.path import exists
  3604. return exists
  3605. """, optimization_level=None)
  3606. # Verify that our understanding of Python is correct: this kind of
  3607. # import should ignore changes to os in favor of the module associated
  3608. # with "os.path" in sys.modules.
  3609. import os
  3610. import os.path
  3611. real_exists = os.path.exists
  3612. class Module(object):
  3613. exists = lambda: "foo"
  3614. with test_support.swap_attr(os, "path", Module):
  3615. self.assertEqual(foo(), real_exists)
  3616. # Get us some FDO LLVM code.
  3617. _llvm.clear_feedback(foo)
  3618. spin_until_hot(foo)
  3619. self.assertTrue(foo.__code__.co_use_jit)
  3620. self.assertEqual(foo.__code__.co_fatalbailcount, 0)
  3621. # Make sure everything still works.
  3622. self.assertEqual(foo(), os.path.exists)
  3623. with test_support.swap_attr(os, "path", Module):
  3624. self.assertEqual(foo(), real_exists)
  3625. self.assertTrue(foo.__code__.co_use_jit)
  3626. self.assertEqual(foo.__code__.co_fatalbailcount, 0)
  3627. def test_cache_imports_robust_against_import_builtin_changes(self):
  3628. foo = compile_for_llvm("foo", """
  3629. def foo():
  3630. import os
  3631. return os
  3632. """, optimization_level=None)
  3633. # Verify things work like we expect: swapping out __import__ should
  3634. # be able to preempt sys.modules.
  3635. with test_support.swap_attr(__builtin__, "__import__", lambda *args: 5):
  3636. self.assertEqual(foo(), 5)
  3637. _llvm.clear_feedback(foo)
  3638. spin_until_hot(foo)
  3639. import os
  3640. self.assertTrue(foo.__code__.co_use_jit)
  3641. self.assertEqual(foo.__code__.co_fatalbailcount, 0)
  3642. self.assertEqual(foo(), os)
  3643. # This doesn't change sys.modules, but it still needs to work. This
  3644. # should invalidate the machine code.
  3645. sys.setbailerror(True)
  3646. with test_support.swap_attr(__builtin__, "__import__", lambda *args: 5):
  3647. self.assertEqual(foo(), 5)
  3648. self.assertEqual(foo.__code__.co_fatalbailcount, 1)
  3649. self.assertFalse(foo.__code__.co_use_jit)
  3650. class LoadMethodTests(LlvmTestCase, ExtraAssertsTestCase):
  3651. """Tests for the LOAD_METHOD/CALL_METHOD opcode optimization."""
  3652. def test_basic(self):
  3653. receiver_cell = [None] # The method self arg goes here.
  3654. class C(object):
  3655. def meth(self):
  3656. receiver_cell[0] = self
  3657. c = C()
  3658. foo = compile_for_llvm("foo", "def foo(c): c.meth()",
  3659. optimization_level=None)
  3660. foo(c)
  3661. self.assertEqual(c, receiver_cell[0])
  3662. spin_until_hot.__code__.co_use_jit = True
  3663. spin_until_hot(foo, [c])
  3664. receiver_cell[0] = None # Reset the cell.
  3665. foo(c)
  3666. self.assertEqual(c, receiver_cell[0])
  3667. def test_c_method_descr(self):
  3668. foo = compile_for_llvm("foo", "def foo(l): l.append(1)",
  3669. optimization_level=None)
  3670. spin_until_hot(foo, [[]])
  3671. l = []
  3672. foo(l)
  3673. self.assertEqual(l, [1])
  3674. def test_c_method_descr_arg_range(self):
  3675. # This test used to raise a SystemError for failed function
  3676. # verification because we weren't passing an extra NULL for the
  3677. # optional argument to pop.
  3678. foo = compile_for_llvm("foo", """\
  3679. def foo(l):
  3680. l.append(0) # Just so we'll have something to pop.
  3681. l.pop()
  3682. """, optimization_level=None)
  3683. spin_until_hot(foo, [[]])
  3684. foo([])
  3685. def test_module_method(self):
  3686. tracer = sys.gettrace()
  3687. foo = compile_for_llvm("foo", "def foo(): return sys.gettrace()",
  3688. optimization_level=None)
  3689. self.assertEqual(foo(), tracer)
  3690. spin_until_hot(foo, [])
  3691. self.assertEqual(foo(), tracer)
  3692. def test_nested_method_calls(self):
  3693. class C(object):
  3694. def bar(self, arg):
  3695. return arg
  3696. def baz(self):
  3697. return 1
  3698. c = C()
  3699. foo = compile_for_llvm("foo", "def foo(c): return c.bar(c.baz())",
  3700. optimization_level=None)
  3701. self.assertEqual(foo(c), 1)
  3702. spin_until_hot(foo, [c])
  3703. self.assertEqual(foo(c), 1)
  3704. def test_other_class_methods(self):
  3705. # This test only tests the interpreter, but it's testing the
  3706. # _PyObject_ShouldBindMethod function that we also use in the JIT
  3707. # compiler.
  3708. receiver_cell = [None]
  3709. class C(object):
  3710. def bar(self):
  3711. receiver_cell[0] = self
  3712. class D(object):
  3713. def bar(self):
  3714. pass
  3715. D.bar = C.bar # This won't work.
  3716. d = D()
  3717. self.assertRaises(TypeError, d.bar)
  3718. # This will, however, grab the underlying function, and work.
  3719. D.bar = C.__dict__["bar"]
  3720. d.bar() # This should not raise.
  3721. def test_object_attrs(self):
  3722. # Test that we don't optimize method access to an object attribute,
  3723. # even though it looks like a method access.
  3724. class C(object):
  3725. def bar(self):
  3726. return 2
  3727. c = C()
  3728. c.bar = lambda: 1
  3729. foo = compile_for_llvm("foo", "def foo(c): return c.bar()",
  3730. optimization_level=None)
  3731. self.assertEqual(foo(c), 1)
  3732. spin_until_hot(foo, [c])
  3733. self.assertEqual(foo(c), 1)
  3734. # This should not bail, because LOAD_METHOD should fall back to
  3735. # LOAD_ATTR when the feedback says we're not loading methods.
  3736. del c.bar
  3737. self.assertEqual(foo(c), 2)
  3738. def test_already_bound(self):
  3739. # Test that we don't optimize method access to an already bound method,
  3740. # even though it looks like a method access.
  3741. receiver_cell = [None]
  3742. class C(object):
  3743. pass
  3744. # We need two classes so we don't optimize the load attribute, which
  3745. # will invalidate the machine code if we change C.
  3746. class D(object):
  3747. def baz(self):
  3748. receiver_cell[0] = self
  3749. c = C()
  3750. d = D()
  3751. C.baz = d.baz # Put this bound method on the class.
  3752. foo = compile_for_llvm("foo", "def foo(c): c.baz()",
  3753. optimization_level=None)
  3754. spin_until_hot(foo, [c], [d])
  3755. # Check that c.baz() sets receiver_cell[0] to d. If we didn't check if
  3756. # a method were already bound, we might have rebound D.baz to c.
  3757. receiver_cell[0] = None
  3758. foo(c)
  3759. self.assertEqual(receiver_cell[0], d)
  3760. def test_unknown_method(self):
  3761. # Train the function on two different types so that the classic
  3762. # LOAD_ATTR optimization doesn't apply, forcing us to use a different
  3763. # code path.
  3764. receiver_cell = [None]
  3765. class C(object):
  3766. def meth(self):
  3767. receiver_cell[0] = self
  3768. class D(object):
  3769. def meth(self):
  3770. receiver_cell[0] = self
  3771. foo = compile_for_llvm("foo", "def foo(o): o.meth()",
  3772. optimization_level=None)
  3773. c = C()
  3774. d = D()
  3775. spin_until_hot(foo, [c], [d])
  3776. foo(c)
  3777. self.assertEqual(receiver_cell[0], c)
  3778. foo(d)
  3779. self.assertEqual(receiver_cell[0], d)
  3780. class InliningTests(LlvmTestCase, ExtraAssertsTestCase):
  3781. def test_manual_optimization(self):
  3782. foo = compile_for_llvm("foo", "def foo(): return 5",
  3783. optimization_level=None)
  3784. foo.__code__.co_optimization = 0
  3785. self.assertContains("@_PyLlvm_WrapDecref", str(foo.__code__.co_llvm))
  3786. # Run inlining.
  3787. foo.__code__.co_optimization = 2
  3788. self.assertNotContains("@_PyLlvm_WrapDecref", str(foo.__code__.co_llvm))
  3789. class TypeBasedAnalysisTests(LlvmTestCase, ExtraAssertsTestCase):
  3790. def test_tbaa_metadata(self):
  3791. foo = compile_for_llvm("foo", "def foo(a,b,c): return a+b+c",
  3792. optimization_level=None)
  3793. spin_until_hot(foo, [1, 2, 3])
  3794. self.assertContains("!PyTBAA", str(foo.__code__.co_llvm))
  3795. foo = compile_for_llvm("foo", "def foo(a,b,c): return a+b+c",
  3796. optimization_level=None)
  3797. spin_until_hot(foo, [1.0, 2.0, 3.0])
  3798. self.assertContains("!PyTBAA", str(foo.__code__.co_llvm))
  3799. def test_guard_removal(self):
  3800. foo = compile_for_llvm("foo", "def foo(a,b,c): return a+b+c",
  3801. optimization_level=None)
  3802. spin_until_hot(foo, [1, 2, 3])
  3803. # The type guard from the intermediate value should be removed,
  3804. # leaving 3 type checks in place.
  3805. # This currently breaks in debug builds, so skip the test.
  3806. if not hasattr(sys, "gettotalrefcount"):
  3807. self.assertEqual(str(foo.__code__.co_llvm).count("PyInt_Type"), 3)
  3808. class LlvmRebindBuiltinsTests(test_dynamic.RebindBuiltinsTests):
  3809. def configure_func(self, func, *args):
  3810. # Spin the function until it triggers as hot. Setting co_optimization
  3811. # doesn't trigger the full range of optimizations.
  3812. spin_until_hot(func, args)
  3813. def test_changing_globals_invalidates_function(self):
  3814. foo = compile_for_llvm("foo", "def foo(): return len(range(3))",
  3815. optimization_level=None)
  3816. self.configure_func(foo)
  3817. self.assertEqual(foo.__code__.co_use_jit, True)
  3818. with test_support.swap_item(globals(), "len", lambda x: 7):
  3819. self.assertEqual(foo.__code__.co_use_jit, False)
  3820. def test_changing_builtins_invalidates_function(self):
  3821. foo = compile_for_llvm("foo", "def foo(): return len(range(3))",
  3822. optimization_level=None)
  3823. self.configure_func(foo)
  3824. self.assertEqual(foo.__code__.co_use_jit, True)
  3825. with test_support.swap_attr(__builtin__, "len", lambda x: 7):
  3826. self.assertEqual(foo.__code__.co_use_jit, False)
  3827. def test_nondict_builtins_class(self):
  3828. # Regression test: this used to trigger a fatal assertion when trying
  3829. # to watch an instance of D; assertions from pure-Python code are a
  3830. # no-no.
  3831. class D(dict):
  3832. pass
  3833. foo = compile_for_llvm("foo", "def foo(): return len",
  3834. optimization_level=None,
  3835. globals_dict=D(globals()))
  3836. foo.__code__.co_use_jit = True
  3837. foo()
  3838. class SetJitControlTests(LlvmTestCase):
  3839. def test_jit_never(self):
  3840. def foo():
  3841. pass
  3842. foo.__code__.co_use_jit = False
  3843. _llvm.set_jit_control("never")
  3844. for _ in xrange(JIT_SPIN_COUNT):
  3845. foo()
  3846. self.assertFalse(foo.__code__.co_use_jit,
  3847. "Foo was JITed despite being run under -Xjit=never.")
  3848. def test_jit_always(self):
  3849. def foo():
  3850. pass
  3851. foo.__code__.co_use_jit = False
  3852. foo()
  3853. self.assertFalse(foo.__code__.co_use_jit,
  3854. "Expected one call not to cause JITing.")
  3855. _llvm.set_jit_control("always")
  3856. foo()
  3857. self.assertTrue(foo.__code__.co_use_jit,
  3858. "Setting -X flag to jit=always had no effect.")
  3859. def test_wrong_type(self):
  3860. self.assertRaises(TypeError, _llvm.set_jit_control, 1)
  3861. def test_bad_string(self):
  3862. self.assertRaises(ValueError, _llvm.set_jit_control, "asdf")
  3863. def modify_code_object(code_obj, **changes):
  3864. order = ["argcount", "nlocals", "stacksize", "flags", "code",
  3865. "consts", "names", "varnames", "filename", "name",
  3866. "firstlineno", "lnotab", "freevars", "cellvars"]
  3867. members = []
  3868. for attr in order:
  3869. if attr in changes:
  3870. members.append(changes[attr])
  3871. else:
  3872. full_attr = "co_" + attr
  3873. members.append(getattr(code_obj, full_attr))
  3874. return types.CodeType(*members)
  3875. class CrashRegressionTests(unittest.TestCase):
  3876. """Tests for segfaults uncovered by fuzz testing."""
  3877. def compile_and_test(self, code_obj, new_bytecode):
  3878. code = modify_code_object(code_obj, code="".join(new_bytecode))
  3879. def test():
  3880. code.co_optimization = 2
  3881. self.assertRaises(SystemError, test)
  3882. def test_bad_locals(self):
  3883. # This used to crash because co_nlocals was greater than
  3884. # len(co_varnames).
  3885. code = modify_code_object(modify_code_object.__code__, nlocals=1000)
  3886. def test():
  3887. code.co_optimization = 2
  3888. self.assertRaises(IndexError, test)
  3889. def test_bad_load_attr_index(self):
  3890. def golden():
  3891. return foo.bar
  3892. # Incorrect name indices used to cause a segfault in the JIT compiler.
  3893. bytecode = list(golden.__code__.co_code)
  3894. bytecode[4] = chr(200) # LOAD_ATTR argument.
  3895. self.compile_and_test(golden.__code__, bytecode)
  3896. def test_bad_compare_op(self):
  3897. def golden():
  3898. return a < 5
  3899. # Incorrect compare ops used to cause a segfault in the JIT compiler.
  3900. bytecode = list(golden.__code__.co_code)
  3901. bytecode[7] = chr(200) # COMPARE_OP argument.
  3902. self.compile_and_test(golden.__code__, bytecode)
  3903. def test_bad_load_fast_index(self):
  3904. def golden(a):
  3905. return a
  3906. # Incorrect LOAD_FAST args used to cause a segfault in LLVM.
  3907. bytecode = list(golden.__code__.co_code)
  3908. bytecode[1] = chr(200) # LOAD_FAST argument.
  3909. self.compile_and_test(golden.__code__, bytecode)
  3910. def test_bad_load_const_index(self):
  3911. def golden():
  3912. return 5
  3913. # Incorrect LOAD_CONST args used to segfault the JIT compiler.
  3914. bytecode = list(golden.__code__.co_code)
  3915. bytecode[1] = chr(204) # LOAD_CONST argument.
  3916. self.compile_and_test(golden.__code__, bytecode)
  3917. def test_jump_to_data(self):
  3918. def golden():
  3919. if x:
  3920. return 5
  3921. bytecode = list(golden.__code__.co_code)
  3922. bytecode[4] = chr(11) # Jump to the LOAD_CONST's argument field.
  3923. self.compile_and_test(golden.__code__, bytecode)
  3924. def test_bad_build_list(self):
  3925. def golden():
  3926. return []
  3927. bytecode = list(golden.__code__.co_code)
  3928. bytecode[2] = chr(200) # Create a huge list.
  3929. self.compile_and_test(golden.__code__, bytecode)
  3930. def test_cache_imports_null_watching(self):
  3931. # We used to crash when compiling code using cached imports when the
  3932. # watching list was NULL.
  3933. def foo():
  3934. import os
  3935. foo() # Gather the tiniest amount of feedback about what os is.
  3936. # Compile foo in a way that doesn't provide globals and builtins
  3937. # dictionaries.
  3938. foo.__code__.co_optimization = 2
  3939. foo.__code__.co_use_jit = True
  3940. # Also assert that we were able to perform the optimzation anyway by
  3941. # testing the code's sensitivity to changing sys.modules.
  3942. foo()
  3943. self.assertTrue(foo.__code__.co_use_jit)
  3944. sys.modules["this-is-not-a-module"] = None
  3945. del sys.modules["this-is-not-a-module"]
  3946. self.assertFalse(foo.__code__.co_use_jit)
  3947. def test_main():
  3948. if __name__ == "__main__" and len(sys.argv) > 1:
  3949. tests = []
  3950. for test_name in sys.argv[1:]:
  3951. test = globals().get(test_name)
  3952. if not test:
  3953. print >>sys.stderr, "Error: cannot find test", test_name
  3954. return
  3955. tests.append(test)
  3956. else:
  3957. tests = [LoopExceptionInteractionTests, GeneralCompilationTests,
  3958. OperatorTests, LiteralsTests, BailoutTests, InliningTests,
  3959. LlvmRebindBuiltinsTests, OptimizationTests,
  3960. SetJitControlTests, TypeBasedAnalysisTests,
  3961. CrashRegressionTests, LoadMethodTests]
  3962. if sys.flags.optimize >= 1:
  3963. print >>sys.stderr, "test_llvm -- skipping some tests due to -O flag."
  3964. sys.stderr.flush()
  3965. test_support.run_unittest(*tests)
  3966. if __name__ == "__main__":
  3967. test_main()