PageRenderTime 1466ms CodeModel.GetById 725ms app.highlight 449ms RepoModel.GetById 175ms app.codeStats 1ms

/Lib/test/test_llvm.py

http://unladen-swallow.googlecode.com/
Python | 4509 lines | 4472 code | 22 blank | 15 comment | 24 complexity | c6186551698179e045ff3bb4d270ec9f MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1# Tests for our minimal LLVM wrappers
   2import __future__
   3
   4from test import test_dynamic
   5from test import test_support
   6
   7try:
   8    import _llvm
   9except ImportError:
  10    raise test_support.TestSkipped("not built against LLVM")
  11
  12import __builtin__
  13import contextlib
  14import functools
  15import gc
  16import sys
  17import types
  18import unittest
  19import weakref
  20
  21
  22# Calculate default LLVM optimization level.
  23def _foo():
  24    pass
  25DEFAULT_OPT_LEVEL = _foo.__code__.co_optimization
  26del _foo
  27
  28
  29# Various constants that feed into the hotness model.
  30HOTNESS_CALL = 10  # Points for a function entry.
  31HOTNESS_LOOP = 1   # Points for a taken loop backedge.
  32
  33JIT_SPIN_COUNT = _llvm.get_hotness_threshold() / HOTNESS_CALL + 1000
  34JIT_OPT_LEVEL = sys.flags.optimize if sys.flags.optimize > 2 else 2
  35
  36
  37@contextlib.contextmanager
  38def set_jit_control(new_level):
  39    orig_level = _llvm.get_jit_control()
  40    _llvm.set_jit_control(new_level)
  41    try:
  42        yield
  43    finally:
  44        _llvm.set_jit_control(orig_level)
  45
  46
  47def at_each_optimization_level(func):
  48    """Decorator for test functions, to run them at each optimization level."""
  49    levels = [None, -1, 0, 1, 2]
  50    if DEFAULT_OPT_LEVEL != -1:
  51        levels = [level for level in levels if level >= DEFAULT_OPT_LEVEL]
  52    @functools.wraps(func)
  53    def result(self):
  54        for level in levels:
  55            func(self, level)
  56    return result
  57
  58
  59def compile_for_llvm(function_name, def_string, optimization_level=-1,
  60                     globals_dict=None):
  61    """Compiles function_name, defined in def_string to be run through LLVM.
  62
  63    Compiles and runs def_string in a temporary namespace, pulls the
  64    function named 'function_name' out of that namespace, optimizes it
  65    at level 'optimization_level', -1 for the default optimization,
  66    and marks it to be JITted and run through LLVM.
  67
  68    """
  69    namespace = {}
  70    if globals_dict is None:
  71        globals_dict = globals()
  72    exec def_string in globals_dict, namespace
  73    func = namespace[function_name]
  74    if optimization_level is not None:
  75        if optimization_level >= DEFAULT_OPT_LEVEL:
  76            func.__code__.co_optimization = optimization_level
  77        func.__code__.co_use_jit = True
  78    return func
  79
  80
  81def spin_until_hot(func, *training_args):
  82    """Compile a function by calling it until it is hot.
  83
  84    Calls a function JIT_SPIN_COUNT times with each of training_args as
  85    arguments and returns a list containing the return values from each
  86    iteration.  When testing feedback directed optimizations, this function is
  87    used to gather feedback in the code object before performaing JIT
  88    compilation.
  89
  90    To inject different training arguments into the function while it is being
  91    spun up, you can pass multiple tuples of arguments to this function, like
  92    so:
  93
  94    spin_until_hot(mul, [1, 3], [1.0, 3.0])
  95
  96    This will cause the function to be trained on both integer and floating
  97    point inputs.
  98    """
  99    if not training_args:  # An empty training_args isn't what you meant.
 100        training_args = [[]]
 101
 102    results = []
 103    with set_jit_control("whenhot"):
 104        for _ in xrange(JIT_SPIN_COUNT):
 105            for args in training_args:
 106                results.append(func(*args))
 107    return results
 108
 109
 110class ExtraAssertsTestCase(unittest.TestCase):
 111    def assertRaisesWithArgs(self, expected_exception_type,
 112                             expected_args, f, *args, **kwargs):
 113        try:
 114            f(*args, **kwargs)
 115        except expected_exception_type, real_exception:
 116            pass
 117        else:
 118            self.fail("%r not raised" % expected_exception_type)
 119        self.assertEquals(real_exception.args, expected_args)
 120
 121    def assertContains(self, obj, container):
 122        if obj not in container:
 123            self.fail("%r not found in %r" % (obj, container))
 124
 125    def assertNotContains(self, obj, container):
 126        if obj in container:
 127            self.fail("%r found in %r" % (obj, container))
 128
 129
 130class LlvmTestCase(unittest.TestCase):
 131
 132    """Common base class for LLVM-focused tests.
 133
 134    Features provided:
 135        - Assert that the code doesn't bail to the interpreter.
 136    """
 137
 138    def setUp(self):
 139        sys.setbailerror(True)
 140        self._old_jit_control = _llvm.get_jit_control()
 141        _llvm.set_jit_control("whenhot")
 142
 143    def tearDown(self):
 144        sys.setbailerror(False)
 145        _llvm.set_jit_control(self._old_jit_control)
 146
 147
 148class GeneralCompilationTests(ExtraAssertsTestCase, LlvmTestCase):
 149
 150    def test_uncreatable(self):
 151        # Functions can only be created by their static factories.
 152        self.assertRaises(TypeError, _llvm._function)
 153
 154    def test_use_llvm(self):
 155        # Regression test: setting co_use_jit without setting an optimization
 156        # level used to segfault when the function was called.
 157        def foo():
 158            return 5
 159        foo.__code__.co_use_jit = True
 160        foo()
 161
 162    @at_each_optimization_level
 163    def test_llvm_compile(self, level):
 164        # Makes no sense at level None
 165        if level is None:
 166            return
 167        def f(x):
 168            pass
 169        f = _llvm.compile(f.func_code, level)
 170        self.assertTrue(isinstance(f, _llvm._function))
 171        self.assertRaises(TypeError, _llvm.compile, f, level)
 172
 173    def test_co_llvm(self):
 174        def f():
 175            return 1 + 2
 176        spin_until_hot(f, [])
 177        str_co_llvm = str(f.__code__.co_llvm)
 178        # After code objects are compiled to machine code, the IR form
 179        # is mostly cleared out. However, we want to be able to print
 180        # the IR generated for any particular function, so this tests
 181        # that it gets regenerated when we ask for its string
 182        # representation.  The cleared-out form is around 5 lines
 183        # long, while all full functions are much longer.
 184        self.assertTrue(10 < len(str_co_llvm.split('\n')), msg=str_co_llvm)
 185
 186    @at_each_optimization_level
 187    def test_run_simple_function(self, level):
 188        foo = compile_for_llvm("foo", """
 189def foo():
 190    pass
 191""", level)
 192        self.assertEquals(None, foo())
 193
 194    @at_each_optimization_level
 195    def test_constants(self, level):
 196        foo = compile_for_llvm("foo", """
 197def foo(x):
 198    if x: x[...]
 199    return [1, 2L, 3.2, 7j, (), "Hello", u"Hello", None]
 200""", level)
 201        self.assertEquals([1, 2L, 3.2, 7j, (), "Hello", u"Hello", None],
 202                          foo(False))
 203
 204    def test_same_named_functions_coexist(self):
 205        foo1 = compile_for_llvm("foo", """
 206def foo(a):
 207    return a
 208""")
 209        foo2 = compile_for_llvm("foo", """
 210def foo():
 211    return 7
 212""")
 213        self.assertEquals("Hello", foo1("Hello"))
 214        self.assertEquals(7, foo2())
 215
 216    def test_stack_pointer_optimized_to_register(self):
 217        def test_func():
 218            # We may have to add opcode uses to here as we find things
 219            # that break the stack pointer optimization.
 220            return sum(range(*[1, 10, 3]))
 221        # Run mem2reg.
 222        test_func.__code__.co_optimization = 2
 223        self.assertFalse("%stack_pointer_addr = alloca"
 224                         in str(test_func.__code__.co_llvm))
 225
 226    # -Xjit=always will cause this test to always fail.
 227    if _llvm.get_jit_control() != "always":
 228        def test_fetch_unset_co_llvm(self):
 229            def test_func():
 230                pass
 231            test_func.__code__.co_use_jit = True
 232            # Just setting co_use_jit doesn't force code generation.
 233            self.assertEqual(str(test_func.__code__.co_llvm), "None")
 234
 235    @at_each_optimization_level
 236    def test_return_arg(self, level):
 237        foo = compile_for_llvm("foo", """
 238def foo(a):
 239    return a
 240""", level)
 241        self.assertEquals(3, foo(3))
 242        self.assertEquals("Hello", foo("Hello"))
 243
 244    @at_each_optimization_level
 245    def test_unbound_local(self, level):
 246        foo = compile_for_llvm("foo", """
 247def foo():
 248    a = a
 249""", level)
 250        try:
 251            foo()
 252        except UnboundLocalError as e:
 253            self.assertEquals(
 254                str(e), "local variable 'a' referenced before assignment")
 255        else:
 256            self.fail("Expected UnboundLocalError")
 257
 258    @at_each_optimization_level
 259    def test_assign(self, level):
 260        foo = compile_for_llvm("foo", """
 261def foo(a):
 262    b = a
 263    return b
 264""", level)
 265        self.assertEquals(3, foo(3))
 266        self.assertEquals("Hello", foo("Hello"))
 267
 268    @at_each_optimization_level
 269    def test_raising_getiter(self, level):
 270        class RaisingIter(object):
 271            def __iter__(self):
 272                raise RuntimeError
 273        loop = compile_for_llvm("loop", """
 274def loop(range):
 275    for i in range:
 276        pass
 277""", level)
 278        self.assertRaises(RuntimeError, loop, RaisingIter())
 279
 280    @at_each_optimization_level
 281    def test_raising_next(self, level):
 282        class RaisingNext(object):
 283            def __iter__(self):
 284                return self
 285            def next(self):
 286                raise RuntimeError
 287        loop = compile_for_llvm("loop", """
 288def loop(range):
 289    for i in range:
 290        pass
 291""", level)
 292        self.assertRaises(RuntimeError, loop, RaisingNext())
 293
 294    @at_each_optimization_level
 295    def test_import_name(self, level):
 296        importer = compile_for_llvm("importer", """
 297def importer():
 298    import os
 299    return os
 300""", level)
 301        import os
 302        self.assertEqual(importer(), os)
 303
 304    @at_each_optimization_level
 305    def test_loop(self, level):
 306        loop = compile_for_llvm("loop", """
 307def loop(range):
 308    for i in range:
 309        pass
 310""", level)
 311        r = iter(range(12))
 312        self.assertEquals(None, loop(r))
 313        self.assertRaises(StopIteration, next, r)
 314
 315    @at_each_optimization_level
 316    def test_return_from_loop(self, level):
 317        loop = compile_for_llvm("loop", """
 318def loop(range):
 319    for i in range:
 320        return i
 321""", level)
 322        self.assertEquals(1, loop([1,2,3]))
 323
 324    @at_each_optimization_level
 325    def test_finally(self, level):
 326        cleanup = compile_for_llvm("cleanup", """
 327def cleanup(obj):
 328    try:
 329        return 3
 330    finally:
 331        obj['x'] = 2
 332""", level)
 333        obj = {}
 334        self.assertEquals(3, cleanup(obj))
 335        self.assertEquals({'x': 2}, obj)
 336
 337    @at_each_optimization_level
 338    def test_nested_finally(self, level):
 339        cleanup = compile_for_llvm("cleanup", """
 340def cleanup(obj):
 341    try:
 342        try:
 343            return 3
 344        finally:
 345            obj['x'] = 2
 346    finally:
 347        obj['y'] = 3
 348""", level)
 349        obj = {}
 350        self.assertEquals(3, cleanup(obj))
 351        self.assertEquals({'x': 2, 'y': 3}, obj)
 352
 353    @at_each_optimization_level
 354    def test_finally_fallthrough(self, level):
 355        cleanup = compile_for_llvm("cleanup", """
 356def cleanup(obj):
 357    try:
 358        obj['y'] = 3
 359    finally:
 360        obj['x'] = 2
 361    return 3
 362""", level)
 363        obj = {}
 364        self.assertEquals(3, cleanup(obj))
 365        self.assertEquals({'x': 2, 'y': 3}, obj)
 366
 367    @at_each_optimization_level
 368    def test_exception_out_of_finally(self, level):
 369        cleanup = compile_for_llvm("cleanup", """
 370def cleanup(obj):
 371    try:
 372        obj['x'] = 2
 373    finally:
 374        a = a
 375        obj['y'] = 3
 376    return 3
 377""", level)
 378        obj = {}
 379        self.assertRaises(UnboundLocalError, cleanup, obj)
 380        self.assertEquals({'x': 2}, obj)
 381
 382    @at_each_optimization_level
 383    def test_exception_through_finally(self, level):
 384        cleanup = compile_for_llvm("cleanup", """
 385def cleanup(obj):
 386    try:
 387        a = a
 388    finally:
 389        obj['x'] = 2
 390""", level)
 391        obj = {}
 392        self.assertRaises(UnboundLocalError, cleanup, obj)
 393        self.assertEquals({'x': 2}, obj)
 394
 395    @at_each_optimization_level
 396    def test_return_in_finally_overrides(self, level):
 397        cleanup = compile_for_llvm("cleanup", """
 398def cleanup():
 399    try:
 400        return 3
 401    finally:
 402        return 2
 403""", level)
 404        self.assertEquals(2, cleanup())
 405
 406    @at_each_optimization_level
 407    def test_except(self, level):
 408        catch = compile_for_llvm("catch", """
 409def catch(obj):
 410    try:
 411        raise ZeroDivisionError
 412    except:
 413        obj["x"] = 2
 414""", level)
 415        obj = {}
 416        self.assertEquals(None, catch(obj))
 417        self.assertEquals({"x": 2}, obj)
 418
 419    @at_each_optimization_level
 420    def test_filtered_except(self, level):
 421        catch = compile_for_llvm("catch", """
 422def catch(exc_type, obj):
 423    try:
 424        1 / 0
 425    except exc_type:
 426        obj["x"] = 2
 427""", level)
 428        obj = {}
 429        self.assertEquals(None, catch(ZeroDivisionError, obj))
 430        self.assertEquals({"x": 2}, obj)
 431        obj = {}
 432        self.assertRaises(ZeroDivisionError, catch, UnboundLocalError, obj)
 433        self.assertEquals({}, obj)
 434
 435    @at_each_optimization_level
 436    def test_filtered_except_var(self, level):
 437        catch = compile_for_llvm("catch", """
 438def catch():
 439    try:
 440        1 / 0
 441    except ZeroDivisionError, exc:
 442        return exc
 443""", level)
 444        exc = catch()
 445        self.assertEquals(ZeroDivisionError, type(exc))
 446        self.assertEquals(('integer division or modulo by zero',), exc.args)
 447
 448    @at_each_optimization_level
 449    def test_except_skipped_on_fallthrough(self, level):
 450        catch = compile_for_llvm("catch", """
 451def catch(obj):
 452    try:
 453        obj["x"] = 2
 454    except:
 455        obj["y"] = 3
 456    return 7
 457""", level)
 458        obj = {}
 459        self.assertEquals(7, catch(obj))
 460        self.assertEquals({"x": 2}, obj)
 461
 462    @at_each_optimization_level
 463    def test_else_hit_on_fallthrough(self, level):
 464        catch = compile_for_llvm("catch", """
 465def catch(obj):
 466    try:
 467        obj["x"] = 2
 468    except:
 469        obj["y"] = 3
 470    else:
 471        obj["z"] = 4
 472    return 7
 473""", level)
 474        obj = {}
 475        self.assertEquals(7, catch(obj))
 476        self.assertEquals({"x": 2, "z": 4}, obj)
 477
 478    @at_each_optimization_level
 479    def test_else_skipped_on_catch(self, level):
 480        catch = compile_for_llvm("catch", """
 481def catch(obj):
 482    try:
 483        a = a
 484    except:
 485        obj["y"] = 3
 486    else:
 487        obj["z"] = 4
 488    return 7
 489""", level)
 490        obj = {}
 491        self.assertEquals(7, catch(obj))
 492        self.assertEquals({"y": 3}, obj)
 493
 494    @at_each_optimization_level
 495    def test_raise_from_except(self, level):
 496        catch = compile_for_llvm("catch", """
 497def catch(obj):
 498    try:
 499        raise ZeroDivisionError
 500    except:
 501        a = a
 502    obj["x"] = 2
 503""", level)
 504        obj = {}
 505        self.assertRaises(UnboundLocalError, catch, obj)
 506        self.assertEquals({}, obj)
 507
 508    @at_each_optimization_level
 509    def test_nested_except(self, level):
 510        catch = compile_for_llvm("catch", """
 511def catch(obj):
 512    try:
 513        try:
 514            1 / 0
 515        except:
 516            obj["x"] = 2
 517            a = a
 518    except:
 519        obj["y"] = 3
 520""", level)
 521        obj = {}
 522        self.assertEquals(None, catch(obj))
 523        self.assertEquals({"x": 2, "y": 3}, obj)
 524
 525    @at_each_optimization_level
 526    def test_nested_except_skipped_on_fallthrough(self, level):
 527        catch = compile_for_llvm("catch", """
 528def catch(obj):
 529    try:
 530        try:
 531            raise ZeroDivisionError
 532        except:
 533            obj["x"] = 2
 534    except:
 535        obj["y"] = 3
 536""", level)
 537        obj = {}
 538        self.assertEquals(None, catch(obj))
 539        self.assertEquals({"x": 2}, obj)
 540
 541    @at_each_optimization_level
 542    def test_nested_finally_doesnt_block_catch(self, level):
 543        # Raise from the try.
 544        catch = compile_for_llvm("catch", """
 545def catch(obj):
 546    try:
 547        try:
 548            1 / 0
 549        finally:
 550            obj["x"] = 2
 551    except:
 552        obj["y"] = 3
 553""", level)
 554        obj = {}
 555        self.assertEquals(None, catch(obj))
 556        self.assertEquals({"x": 2, "y": 3}, obj)
 557
 558        # And raise from the finally.
 559        catch = compile_for_llvm("catch", """
 560def catch(obj):
 561    try:
 562        try:
 563            obj["x"] = 2
 564        finally:
 565            raise ZeroDivisionError
 566    except:
 567        obj["y"] = 3
 568""", level)
 569        obj = {}
 570        self.assertEquals(None, catch(obj))
 571        self.assertEquals({"x": 2, "y": 3}, obj)
 572
 573    @at_each_optimization_level
 574    def test_nested_except_goes_through_finally(self, level):
 575        # Raise from the try.
 576        catch = compile_for_llvm("catch", """
 577def catch(obj):
 578    try:
 579        try:
 580            1 / 0
 581        except:
 582            obj["x"] = 2
 583    finally:
 584        obj["y"] = 3
 585""", level)
 586        obj = {}
 587        self.assertEquals(None, catch(obj))
 588        self.assertEquals({"x": 2, "y": 3}, obj)
 589
 590        # And raise from the except.
 591        catch = compile_for_llvm("catch", """
 592def catch(obj):
 593    try:
 594        try:
 595            raise UnboundLocalError
 596        except:
 597            1 / 0
 598    finally:
 599        obj["y"] = 3
 600""", level)
 601        obj = {}
 602        self.assertRaises(ZeroDivisionError, catch, obj)
 603        self.assertEquals({"y": 3}, obj)
 604
 605    @at_each_optimization_level
 606    def test_finally_in_finally(self, level):
 607        catch = compile_for_llvm("catch", """
 608def catch(obj):
 609    try:
 610        raise ZeroDivisionError
 611    finally:
 612        try:
 613            a = a
 614        finally:
 615            obj["x"] = 2
 616""", level)
 617        obj = {}
 618        self.assertRaises(UnboundLocalError, catch, obj)
 619        self.assertEquals({"x": 2}, obj)
 620
 621    @at_each_optimization_level
 622    def test_subexception_caught_in_finally(self, level):
 623        catch = compile_for_llvm("catch", """
 624def catch(obj):
 625    try:
 626        1 / 0
 627    finally:
 628        try:
 629            a = a
 630        except:
 631            obj["x"] = 2
 632""", level)
 633        obj = {}
 634        self.assertRaises(ZeroDivisionError, catch, obj)
 635        self.assertEquals({"x": 2}, obj)
 636
 637    @at_each_optimization_level
 638    def test_delete_fast(self, level):
 639        delit = compile_for_llvm('delit', """
 640def delit(x):
 641    y = 2
 642    z = 3
 643    del y
 644    del x
 645    return z
 646""", level)
 647        self.assertEquals(delit(1), 3)
 648
 649        useit = compile_for_llvm('useit', """
 650def useit(x):
 651    del x
 652    return x
 653""", level)
 654        self.assertRaises(UnboundLocalError, useit, 1)
 655
 656        misuseit = compile_for_llvm('misuseit', 'def misuseit(x): del y',
 657                                    level)
 658        self.assertRaises(UnboundLocalError, misuseit, 1)
 659
 660        reuseit = compile_for_llvm('reuseit', """
 661def reuseit(x):
 662    del x
 663    x = 3
 664    return x
 665""", level)
 666        self.assertEquals(reuseit(1), 3)
 667
 668    @at_each_optimization_level
 669    def test_call_function(self, level):
 670        f1 = compile_for_llvm("f1", "def f1(x): return x()", level)
 671        self.assertEquals(f1(lambda: 5), 5)
 672        def raise_exc():
 673            raise ValueError
 674        self.assertRaises(ValueError, f1, raise_exc)
 675
 676        f2 = compile_for_llvm("f2", "def f2(x, y, z): return x(y, 2, z)",
 677                              level)
 678        self.assertEquals(f2(lambda *args: args, 1, 3), (1, 2, 3))
 679
 680        f3 = compile_for_llvm("f3", "def f3(x, y, z): return x(y(z()))",
 681                              level)
 682        self.assertEquals(f3(lambda x: x+1, lambda x: x+2, lambda: 0), 3)
 683
 684    @at_each_optimization_level
 685    def test_load_global(self, level):
 686        our_globals = dict(globals())  # Isolate the test's global effects.
 687        testvalue = 'test global value'
 688        loadglobal = compile_for_llvm('loadglobal',
 689                                      'def loadglobal(): return testvalue',
 690                                      level, our_globals)
 691        our_globals['testvalue'] = testvalue
 692        self.assertEquals(loadglobal(), testvalue)
 693
 694        loadbuiltin = compile_for_llvm('loadbuiltin',
 695                                       'def loadbuiltin(): return str',
 696                                       level)
 697        self.assertEquals(loadbuiltin(), str)
 698
 699        nosuchglobal = compile_for_llvm('nosuchglobal', '''
 700def nosuchglobal():
 701    return there_better_be_no_such_global
 702''', level)
 703        self.assertRaises(NameError, nosuchglobal)
 704
 705    @at_each_optimization_level
 706    def test_store_global(self, level):
 707        our_globals = dict(globals())  # Isolate the test's global effects.
 708        setglobal = compile_for_llvm('setglobal', '''
 709def setglobal(x):
 710    global _test_global
 711    _test_global = x
 712''', level, our_globals)
 713        testvalue = "test global value"
 714        self.assertTrue('_test_global' not in our_globals)
 715        setglobal(testvalue)
 716        self.assertContains('_test_global', our_globals)
 717        self.assertEquals(our_globals['_test_global'], testvalue)
 718
 719    @at_each_optimization_level
 720    def test_delete_global(self, level):
 721        our_globals = dict(globals())  # Isolate the test's global effects.
 722        delglobal = compile_for_llvm('delglobal', '''
 723def delglobal():
 724    global _test_global
 725    del _test_global
 726''', level, our_globals)
 727        our_globals['_test_global'] = 'test global value'
 728        self.assertContains('_test_global', our_globals)
 729        delglobal()
 730        self.assertTrue('_test_global' not in our_globals)
 731
 732    @at_each_optimization_level
 733    def test_load_name(self, level):
 734        our_globals = dict(globals())  # Isolate the test's global effects.
 735        testvalue = 'test name value'
 736        loadlocal = compile_for_llvm('loadlocal', '''
 737def loadlocal():
 738    exec 'testvalue = "Hello"'
 739    return testvalue
 740''', level, our_globals)
 741        our_globals['testvalue'] = testvalue
 742        self.assertEquals(loadlocal(), 'Hello')
 743
 744        our_globals = dict(globals())
 745        loadglobal = compile_for_llvm('loadglobal', '''
 746def loadglobal():
 747    exec ''
 748    return testvalue
 749''', level, our_globals)
 750        our_globals['testvalue'] = testvalue
 751        self.assertEquals(loadglobal(), testvalue)
 752
 753        loadbuiltin = compile_for_llvm('loadbuiltin', '''
 754def loadbuiltin():
 755    exec ''
 756    return str
 757''', level)
 758        self.assertEquals(loadbuiltin(), str)
 759
 760        nosuchname = compile_for_llvm('nosuchname', '''
 761def nosuchname():
 762    exec ''
 763    return there_better_be_no_such_name
 764''', level)
 765        self.assertRaises(NameError, nosuchname)
 766
 767    @at_each_optimization_level
 768    def test_store_name(self, level):
 769        set_local = compile('a = 3', '<string>', 'exec')
 770        if level is not None:
 771            set_local.co_optimization = level
 772            set_local.co_use_jit = True
 773        exec set_local
 774        self.assertEquals(a, 3)
 775
 776    @at_each_optimization_level
 777    def test_delete_name(self, level):
 778        do_del = compile('del a', '<string>', 'exec')
 779        if level is not None:
 780            do_del.co_optimization = level
 781            do_del.co_use_jit = True
 782        exec 'a = 3'
 783        self.assertEquals(a, 3)
 784        exec do_del
 785        try:
 786            a
 787        except NameError:
 788            pass
 789        else:
 790            self.fail('Expected "a" to be deleted')
 791
 792        try:
 793            exec compile('del nonexistent', '<string>', 'exec')
 794        except NameError, e:
 795            self.assertEquals(e.args, ('name \'nonexistent\' is not defined',))
 796        else:
 797            self.fail('Expected not to find "nonexistent"')
 798
 799    @at_each_optimization_level
 800    def test_simple_if_stmt(self, level):
 801        simple_if = compile_for_llvm("simple_if", """
 802def simple_if(x):
 803    if x:
 804        return "true"
 805""", level)
 806        self.assertEquals(simple_if(True), "true")
 807        self.assertEquals(simple_if(False), None)
 808
 809        simple_if_else = compile_for_llvm("simple_if_else", """
 810def simple_if_else(x):
 811    if x:
 812        return "true"
 813    else:
 814        return "false"
 815""", level)
 816        self.assertEquals(simple_if_else("not false"), "true")
 817        self.assertEquals(simple_if_else(""), "false")
 818
 819    @at_each_optimization_level
 820    def test_if_stmt_exceptions(self, level):
 821        if_exception = compile_for_llvm("if_exception", """
 822def if_exception(x):
 823    if x:
 824        return 1
 825""", level)
 826        class Unboolable(object):
 827            def __nonzero__(self):
 828                raise RuntimeError
 829        self.assertRaises(RuntimeError, if_exception, Unboolable())
 830
 831    @at_each_optimization_level
 832    def test_complex_if(self, level):
 833        complex_if = compile_for_llvm("complex_if", """
 834def complex_if(x, y, z):
 835    if x:
 836        if y:
 837            return 1
 838        else:
 839            if z:
 840                return 2
 841            return 1 / 0
 842    else:
 843        return 3
 844""", level)
 845        self.assertEquals(complex_if(True, True, False), 1)
 846        self.assertEquals(complex_if(True, False, True), 2)
 847        self.assertEquals(complex_if(False, True, True), 3)
 848        self.assertRaises(ZeroDivisionError, complex_if, True, False, False)
 849
 850    # Asserts aren't compiled when -O is passed.
 851    if sys.flags.optimize < 1:
 852        @at_each_optimization_level
 853        def test_assert(self, level):
 854            f = compile_for_llvm("f", "def f(x): assert x", level)
 855            self.assertEquals(f(1), None)
 856            self.assertRaises(AssertionError, f, 0)
 857
 858    @at_each_optimization_level
 859    def test_and(self, level):
 860        and1 = compile_for_llvm("and1",
 861                                "def and1(x, y): return x and y", level)
 862        self.assertEquals(and1("x", "y"), "y")
 863        self.assertEquals(and1((), "y"), ())
 864        self.assertEquals(and1((), ""), ())
 865
 866        and2 = compile_for_llvm("and2",
 867                                "def and2(x, y): return x+1 and y+1",
 868                                level)
 869        self.assertEquals(and2(-1, "5"), 0)
 870        self.assertRaises(TypeError, and2, "5", 5)
 871        self.assertRaises(TypeError, and2,  5, "5")
 872
 873    @at_each_optimization_level
 874    def test_or(self, level):
 875        or1 = compile_for_llvm("or1", "def or1(x, y): return x or y", level)
 876        self.assertEquals(or1("x", "y"), "x")
 877        self.assertEquals(or1((), "y"), "y")
 878        self.assertEquals(or1((), ""), "")
 879
 880        or2 = compile_for_llvm("or2",
 881                               "def or2(x, y): return x+1 or y+1", level)
 882        self.assertEquals(or2(5, "5"), 6)
 883        self.assertRaises(TypeError, or2, "5", 5)
 884        self.assertRaises(TypeError, or2, -1, "5")
 885
 886    @at_each_optimization_level
 887    def test_complex_or(self, level):
 888        complex_or = compile_for_llvm('complex_or', '''
 889def complex_or(a, b, c):
 890    return a or b or c
 891''', level)
 892        self.assertEquals(complex_or(1, 2, 0), 1)
 893        self.assertEquals(complex_or(1, 2, 3), 1)
 894        self.assertEquals(complex_or(3, 0, 0), 3)
 895        self.assertEquals(complex_or(0, 3, 0), 3)
 896        self.assertEquals(complex_or(0, 0, 1), 1)
 897        self.assertEquals(complex_or(0, 0, 0), 0)
 898
 899        complex_or_and = compile_for_llvm('complex_or_and', '''
 900def complex_or_and(a, b, c):
 901    return a or b and c
 902''', level)
 903        self.assertEquals(complex_or_and(3, 0, 0), 3)
 904        self.assertEquals(complex_or_and("", 3, 0), 0)
 905        self.assertEquals(complex_or_and("", 0, 1), 0)
 906        self.assertEquals(complex_or_and(0, 3, 1), 1)
 907
 908    @at_each_optimization_level
 909    def test_complex_and(self, level):
 910        complex_and = compile_for_llvm('complex_and', '''
 911def complex_and(a, b, c):
 912    return a and b and c
 913''', level)
 914        self.assertEquals(complex_and(3, 0, ""), 0)
 915        self.assertEquals(complex_and(3, 2, 0), 0)
 916        self.assertEquals(complex_and(3, 2, 1), 1)
 917        self.assertEquals(complex_and(0, 3, 2), 0)
 918        self.assertEquals(complex_and(3, 0, 2), 0)
 919
 920        complex_and_or = compile_for_llvm('complex_and_or', '''
 921def complex_and_or(a, b, c):
 922    return a and b or c
 923''', level)
 924        self.assertEquals(complex_and_or(3, "", 0), 0)
 925        self.assertEquals(complex_and_or(1, 3, 0), 3)
 926        self.assertEquals(complex_and_or(1, 3, 2), 3)
 927        self.assertEquals(complex_and_or(0, 3, 1), 1)
 928
 929    @at_each_optimization_level
 930    def test_break(self, level):
 931        break_one = compile_for_llvm("break_one", """
 932def break_one(x):
 933    for y in [1, 2]:
 934        x["break"] = y
 935        break
 936        x["post break"] = y
 937    else:
 938        x["else"] = True
 939    return x
 940""", level)
 941        self.assertEqual(break_one({}), {"break": 1})
 942
 943        nested = compile_for_llvm("nested", """
 944def nested(x):
 945    for y in [1, 2]:
 946        for z in [3, 4]:
 947            x["break"] = z
 948            break
 949            x["post break"] = z
 950        else:
 951            x["inner else"] = True
 952        x["outer"] = y
 953    else:
 954        x["else"] = True
 955    return x
 956""", level)
 957        self.assertEqual(nested({}), {"break": 3, "outer": 2, "else": True})
 958
 959    @at_each_optimization_level
 960    def test_continue(self, level):
 961        # CONTINUE_LOOP is only used inside a try/except block. Otherwise,
 962        # the continue statement is lowered to a JUMP_ABSOLUTE.
 963        continue_one = compile_for_llvm("continue_one", """
 964def continue_one(x):
 965    for y in [1, 2]:
 966        if y:
 967            x["continue"] = y
 968            try:
 969                continue
 970            except:
 971                pass
 972            finally:
 973                x["finally"] = y
 974        1 / 0
 975    else:
 976        x["else"] = True
 977    return x
 978""", level)
 979        self.assertEqual(continue_one({}), {"continue": 2, "else": True,
 980                                            "finally": 2})
 981
 982        nested = compile_for_llvm("nested", """
 983def nested(x):
 984    for y in [1, 2]:
 985        for z in [3, 4]:
 986            if z:
 987                x["continue"] = z
 988                try:
 989                    continue
 990                except:
 991                    pass
 992            1 / 0
 993        else:
 994            x["inner else"] = True
 995        x["outer"] = y
 996    else:
 997        x["else"] = True
 998    return x
 999""", level)
1000        self.assertEqual(nested({}), {"continue": 4, "outer": 2,
1001                                      "inner else": True, "else": True})
1002
1003    @at_each_optimization_level
1004    def test_load_attr(self, level):
1005        load_attr = compile_for_llvm('load_attr',
1006                                     'def load_attr(o): return o.attr',
1007                                     level)
1008        load_attr.attr = 1
1009        self.assertEquals(load_attr(load_attr), 1)
1010        self.assertRaises(AttributeError, load_attr, object())
1011
1012    @at_each_optimization_level
1013    def test_store_attr(self, level):
1014        store_attr = compile_for_llvm('store_attr',
1015                                      'def store_attr(o): o.attr = 2',
1016                                      level)
1017        store_attr(store_attr)
1018        self.assertEquals(store_attr.attr, 2)
1019        self.assertRaises(AttributeError, store_attr, object())
1020
1021    @at_each_optimization_level
1022    def test_delete_attr(self, level):
1023        delete_attr = compile_for_llvm('delete_attr',
1024                                       'def delete_attr(o): del o.attr',
1025                                       level)
1026        delete_attr.attr = 3
1027        delete_attr(delete_attr)
1028        self.assertFalse(hasattr(delete_attr, 'attr'))
1029        self.assertRaises(AttributeError, delete_attr, object())
1030
1031    @at_each_optimization_level
1032    def test_call_varargs(self, level):
1033        f1 = compile_for_llvm("f1", "def f1(x, args): return x(*args)",
1034                              level)
1035        def receiver1(a, b):
1036            return a, b
1037        self.assertEquals(f1(receiver1, (1, 2)), (1, 2))
1038        self.assertRaises(TypeError, f1, receiver1, None)
1039        self.assertRaises(TypeError, f1, None, (1, 2))
1040
1041        f2 = compile_for_llvm("f2",
1042                              "def f2(x, args): return x(1, 2, *args)",
1043                              level)
1044        def receiver2(a, *args):
1045            return a, args
1046        self.assertEquals(f2(receiver2, (3, 4, 5)), (1, (2, 3, 4, 5)))
1047
1048    @at_each_optimization_level
1049    def test_call_kwargs(self, level):
1050        f = compile_for_llvm("f",
1051                             "def f(x, kwargs): return x(a=1, **kwargs)",
1052                             level)
1053        def receiver(**kwargs):
1054            return kwargs
1055        self.assertEquals(f(receiver, {'b': 2, 'c': 3}),
1056                          {'a': 1, 'b': 2, 'c': 3})
1057
1058    @at_each_optimization_level
1059    def test_call_args_kwargs(self, level):
1060        f = compile_for_llvm("f", """
1061def f(x, args, kwargs):
1062    return x(1, d=4, *args, **kwargs)
1063""", level)
1064        def receiver(*args, **kwargs):
1065            return args, kwargs
1066        self.assertEquals(f(receiver, (2, 3), {'e': 5, 'f': 6}),
1067                          ((1, 2, 3), {'d': 4, 'e': 5, 'f': 6}))
1068
1069    @at_each_optimization_level
1070    def test_varargs_func(self, level):
1071        f = compile_for_llvm("f", """
1072def f(*args):
1073    return zip(*args)
1074""", level)
1075        self.assertEqual(f([1], [2]), [(1, 2)])
1076
1077    @at_each_optimization_level
1078    def test_kwargs_func(self, level):
1079        f = compile_for_llvm("f", """
1080def f(**kwargs):
1081    return dict(**kwargs)
1082""", level)
1083        self.assertEqual(f(a=3), {"a": 3})
1084
1085    @at_each_optimization_level
1086    def test_build_slice(self, level):
1087        class Sliceable(object):
1088            def __getitem__(self, item):
1089                return item
1090        # Test BUILD_SLICE_TWO; make sure we didn't swap arguments.
1091        slice_two = compile_for_llvm('slice_two',
1092                                      'def slice_two(o): return o[1:2:]',
1093                                      level)
1094        self.assertEquals(slice_two(Sliceable()), slice(1, 2, None))
1095        # Test BUILD_SLICE_THREE.
1096        slice_three = compile_for_llvm('slice_three',
1097                                     'def slice_three(o): return o[1:2:3]',
1098                                     level)
1099        self.assertEquals(slice_three(Sliceable()), slice(1, 2, 3))
1100        # No way to make BUILD_SLICE_* raise exceptions.
1101
1102    @at_each_optimization_level
1103    def test_with(self, level):
1104        class SimpleCM(object):
1105            def __enter__(self):
1106                self.enter = True
1107
1108            def __exit__(self, *exc_info):
1109                self.exit = True
1110
1111        with_simple = compile_for_llvm('with_simple', '''
1112def with_simple(self, x):
1113    with x:
1114        self.assertEqual(x.__dict__, {"enter": True})
1115    self.assertEqual(x.__dict__, {"enter": True, "exit": True})
1116''', level)
1117        with_simple(self, SimpleCM())
1118
1119        with_raise = compile_for_llvm('with_raise', '''
1120def with_raise(self, x):
1121    with x:
1122        self.assertEqual(x.__dict__, {"enter": True})
1123        raise ArithmeticError
1124''', level)
1125        x = SimpleCM()
1126        self.assertRaises(ArithmeticError, with_raise, self, x)
1127        self.assertEqual(x.__dict__, {'enter': True, 'exit': True})
1128
1129        with_return = compile_for_llvm('with_return', '''
1130def with_return(self, x):
1131    with x:
1132        self.assertEqual(x.__dict__, {"enter": True})
1133        return 55
1134''', level)
1135        x = SimpleCM()
1136        self.assertEqual(with_return(self, x), 55)
1137        self.assertEqual(x.__dict__, {'enter': True, 'exit': True})
1138
1139        class SwallowingCM(object):
1140            def __enter__(self):
1141                self.enter = True
1142
1143            def __exit__(self, *exc_info):
1144                self.exit = True
1145                return True  # Swallow the raised exception
1146
1147        with_swallow = compile_for_llvm('with_swallow', '''
1148def with_swallow(self, x):
1149    with x:
1150        self.assertEqual(x.__dict__, {"enter": True})
1151        raise ArithmeticError
1152    return 55
1153''', level)
1154        x = SwallowingCM()
1155        self.assertEqual(with_swallow(self, x), 55)
1156        self.assertEqual(x.__dict__, {'enter': True, 'exit': True})
1157
1158        class BustedExitCM(object):
1159            def __enter__(self):
1160                self.enter = True
1161
1162            def __exit__(self, *exc_info):
1163                self.exit = True
1164                class A(object):
1165                    def __nonzero__(self):
1166                        raise ArithmeticError
1167                return A()  # Test error paths in WITH_CLEANUP
1168
1169        with_ignored_bad_exit = compile_for_llvm('with_ignored_bad_exit', '''
1170def with_ignored_bad_exit(self, x):
1171    with x:
1172        self.assertEqual(x.__dict__, {"enter": True})
1173    return 55
1174''', level)
1175        x = BustedExitCM()
1176        self.assertEqual(with_ignored_bad_exit(self, x), 55)
1177        self.assertEqual(x.__dict__, {'enter': True, 'exit': True})
1178
1179        with_bad_exit = compile_for_llvm('with_bad_exit', '''
1180def with_bad_exit(self, x):
1181    with x:
1182        self.assertEqual(x.__dict__, {"enter": True})
1183        raise KeyError
1184    return 55
1185''', level)
1186        x = BustedExitCM()
1187        self.assertRaises(ArithmeticError, with_bad_exit, self, x)
1188        self.assertEqual(x.__dict__, {'enter': True, 'exit': True})
1189
1190        class RaisingCM(object):
1191            def __enter__(self):
1192                self.enter = True
1193
1194            def __exit__(self, *exc_info):
1195                self.exit = True
1196                raise ArithmeticError
1197
1198        with_error = compile_for_llvm('with_error', '''
1199def with_error(self, x):
1200    with x:
1201        return 55
1202''', level)
1203        x = RaisingCM()
1204        self.assertRaises(ArithmeticError, with_error, self, x)
1205        self.assertEqual(x.__dict__, {'enter': True, 'exit': True})
1206
1207        class NestedCM(object):
1208            def __init__(self):
1209                self.enter = 0
1210                self.exit = 0
1211
1212            def __enter__(self):
1213                self.enter += 1
1214
1215            def __exit__(self, *exc_info):
1216                self.exit += 1
1217
1218        with_yield = compile_for_llvm('with_yield', '''
1219def with_yield(self, x):
1220    with x:
1221        self.assertEqual(x.__dict__, {"enter": 1, "exit": 0})
1222        yield 7
1223        self.assertEqual(x.__dict__, {"enter": 1, "exit": 0})
1224        yield 8
1225    self.assertEqual(x.__dict__, {"enter": 1, "exit": 1})
1226''', level)
1227        x = NestedCM()
1228        self.assertEqual(list(with_yield(self, x)), [7, 8])
1229
1230        with_nested = compile_for_llvm('with_nested', '''
1231def with_nested(self, x):
1232    with x:
1233        self.assertEqual(x.__dict__, {"enter": 1, "exit": 0})
1234        with x:
1235            self.assertEqual(x.__dict__, {"enter": 2, "exit": 0})
1236        self.assertEqual(x.__dict__, {"enter": 2, "exit": 1})
1237    self.assertEqual(x.__dict__, {"enter": 2, "exit": 2})
1238''', level)
1239        x = NestedCM()
1240        with_nested(self, x)
1241
1242    @at_each_optimization_level
1243    def test_raise(self, level):
1244        raise_onearg = compile_for_llvm('raise_onearg', '''
1245def raise_onearg(x):
1246    raise x
1247''', level)
1248        self.assertRaises(OpExc, raise_onearg, OpExc);
1249
1250        raise_twoargs = compile_for_llvm('raise_twoargs', '''
1251def raise_twoargs(x, y):
1252    raise x, y
1253''', level)
1254        self.assertRaisesWithArgs(OpExc, ('twoarg',),
1255                                  raise_twoargs, OpExc, OpExc('twoarg'));
1256
1257    @at_each_optimization_level
1258    def test_reraise(self, level):
1259        raise_noargs = compile_for_llvm('raise_noargs', '''
1260def raise_noargs():
1261    raise
1262''', level)
1263        exc = OpExc('exc')
1264        def setup_traceback(e):
1265            raise e
1266        try:
1267            setup_traceback(exc)
1268        except OpExc:
1269            # orig_tb and exc re-used for raise_threeargs.
1270            orig_tb = sys.exc_info()[2]
1271            try:
1272                raise_noargs()
1273            except OpExc, e:
1274                new_tb = sys.exc_info()[2]
1275                # Test that we got the right exception and the right
1276                # traceback. Test both equality and identity for more
1277                # convenient error displays when things aren't as expected.
1278                self.assertEquals(e, exc)
1279                self.assertTrue(e is exc)
1280                self.assertEquals(new_tb.tb_next, orig_tb)
1281                self.assertTrue(new_tb.tb_next is orig_tb)
1282            else:
1283                self.fail('expected OpExc exception')
1284        else:
1285            self.fail('expected OpExc exception')
1286
1287        raise_threeargs = compile_for_llvm('raise_threeargs', '''
1288def raise_threeargs(x, y, z):
1289    raise x, y, z
1290''', level)
1291        # Explicit version of the no-args raise.
1292        try:
1293            # Re-using exc and orig_tb from raise_noargs.
1294            raise_threeargs(OpExc, exc, orig_tb)
1295        except OpExc, e:
1296            new_tb = sys.exc_info()[2]
1297            self.assertEquals(e, exc)
1298            self.assertTrue(e is exc)
1299            self.assertEquals(new_tb.tb_next, orig_tb)
1300            self.assertTrue(new_tb.tb_next is orig_tb)
1301        else:
1302            self.fail('expected OpExc exception')
1303
1304    @at_each_optimization_level
1305    def test_complex_reraise(self, level):
1306        reraise = compile_for_llvm('reraise', '''
1307def reraise(raiser, exctype):
1308    try:
1309        raiser()
1310    except:
1311        try:
1312            raise
1313        except exctype:
1314            return "inner"
1315        return "middle"
1316    return "outer"
1317''', level)
1318        def raiser():
1319            raise ZeroDivisionError
1320        self.assertEquals(reraise(raiser, ZeroDivisionError),
1321                          "inner")
1322        self.assertRaises(ZeroDivisionError, reraise, raiser, TypeError)
1323
1324    @at_each_optimization_level
1325    def test_simple_yield(self, level):
1326        generator = compile_for_llvm("generator", """
1327def generator():
1328    yield 1
1329    yield 2
1330    yield 3
1331""", level)
1332        g = generator()
1333        self.assertEquals(1, g.next())
1334        self.assertEquals(2, g.next())
1335        self.assertEquals(3, g.next())
1336        self.assertRaises(StopIteration, g.next)
1337
1338    @at_each_optimization_level
1339    def test_yield_in_loop(self, level):
1340        generator = compile_for_llvm("generator", """
1341def generator(x):
1342    for i in x:
1343        yield i
1344""", level)
1345        g = generator([1, 2, 3, 4])
1346        self.assertEquals([1, 2, 3, 4], list(g))
1347
1348        cross_product = compile_for_llvm("cross_product", """
1349def cross_product(x, y):
1350    for i in x:
1351        for j in y:
1352            yield (i, j)
1353""", level)
1354        g = cross_product([1, 2], [3, 4])
1355        self.assertEquals([(1,3), (1,4), (2,3), (2,4)], list(g))
1356
1357    @at_each_optimization_level
1358    def test_yield_saves_block_stack(self, level):
1359        generator = compile_for_llvm("generator", """
1360def generator(x):
1361    yield "starting"
1362    for i in x:
1363        try:
1364            try:
1365                1 / i
1366                yield ("survived", i)
1367            finally:
1368                yield ("finally", i)
1369        except ZeroDivisionError:
1370            yield "caught exception"
1371    yield "done looping"
1372""", level)
1373        self.assertEquals(list(generator([0, 1, 2])),
1374                          ["starting",
1375                           ("finally", 0),
1376                           "caught exception",
1377                           ("survived", 1),
1378                           ("finally", 1),
1379                           ("survived", 2),
1380                           ("finally", 2),
1381                           "done looping"])
1382
1383    @at_each_optimization_level
1384    def test_generator_send(self, level):
1385        generator = compile_for_llvm("generator", """
1386def generator():
1387    yield (yield 1)
1388""", level)
1389        g = generator()
1390        self.assertEquals(1, g.next())
1391        self.assertEquals("Hello world", g.send("Hello world"))
1392        self.assertRaises(StopIteration, g.send, 3)
1393
1394    @at_each_optimization_level
1395    def test_generator_throw(self, level):
1396        generator = compile_for_llvm("generator", """
1397def generator(obj):
1398    try:
1399        yield "starting"
1400    except ArithmeticError:
1401        obj["caught"] = 1
1402    finally:
1403        obj["finally"] = 1
1404    yield "done"
1405""", level)
1406        obj = {}
1407        g = generator(obj)
1408        self.assertEquals("starting", g.next())
1409        self.assertEquals("done", g.throw(ArithmeticError))
1410        self.assertEquals(None, g.close())
1411        self.assertEquals({"caught": 1, "finally": 1}, obj)
1412
1413        obj = {}
1414        g = generator(obj)
1415        self.assertEquals("starting", g.next())
1416        self.assertRaises(UnboundLocalError, g.throw, UnboundLocalError)
1417        self.assertRaises(StopIteration, g.next)
1418        self.assertEquals({"finally": 1}, obj)
1419
1420    # Getting this to work under -Xjit=always is a pain in the ass, and not
1421    # worth the effort IMHO.
1422    if _llvm.get_jit_control() != "always":
1423        def test_toggle_generator(self):
1424            # Toggling between native code and the interpreter between yields
1425            # used to cause crashes because f_lasti doesn't get translated
1426            # between the scheme used for LLVM and the scheme used for the
1427            # interpreter.  Currently, due to our generator pseudo
1428            # on-stack-replacement, these assignments take effect on generator
1429            # reentry.
1430            def generator():
1431                yield 1
1432                generator.func_code.co_use_jit = True
1433                yield 2
1434                generator.func_code.co_use_jit = False
1435                yield 3
1436            self.assertEqual(list(generator()), [1, 2, 3])
1437
1438    @at_each_optimization_level
1439    def test_closure(self, level):
1440        make_closure = compile_for_llvm('make_closure', '''
1441def make_closure(a, level):
1442    b = 5
1443    c = 3
1444    def inner(d, e=5):
1445        c = d + 1
1446        return a, b, c, d, e
1447    if level is not None:
1448        inner.__code__.co_use_jit = True
1449        inner.__code__.co_optimization = level
1450    b = 2
1451    return inner
1452''', level)
1453        inner = make_closure(1, level)
1454        self.assertEquals(inner(4), (1, 2, 5, 4, 5))
1455        self.assertRaises(TypeError, inner, "5")
1456
1457    @at_each_optimization_level
1458    def test_closure_unbound_freevar(self, level):
1459        unbound_freevar = compile_for_llvm('unbound_freevar', '''
1460def unbound_freevar(level):
1461    if 0:
1462        b = 2
1463    def inner():
1464        return b
1465    if level is not None:
1466        inner.__code__.co_use_jit = True
1467        inner.__code__.co_optimization = level
1468    return inner
1469''', level)
1470        inner = unbound_freevar(level)
1471        self.assertRaisesWithArgs(NameError,
1472            ("free variable 'b' referenced before "
1473             "assignment in enclosing scope",), inner)
1474
1475    @at_each_optimization_level
1476    def test_closure_unbound_local(self, level):
1477        unbound_local = compile_for_llvm('unbound_local', '''
1478def unbound_local(level):
1479    def inner():
1480        if 0:
1481            b = 3
1482        return b
1483    if level is not None:
1484        inner.__code__.co_use_jit = True
1485        inner.__code__.co_optimization = level
1486    return inner
1487''', level)
1488        inner = unbound_local(level)
1489        self.assertRaisesWithArgs(UnboundLocalError,
1490            ("local variable 'b' referenced before assignment",), inner)
1491
1492    @at_each_optimization_level
1493    def test_ends_with_unconditional_jump(self, level):
1494        foo = compile_for_llvm('foo', '''
1495from opcode import opmap
1496from types import CodeType, FunctionType
1497foo_bytecode = [
1498    opmap["JUMP_FORWARD"],  4, 0,  #  0  JUMP_FORWARD   4 (to 7)
1499    opmap["LOAD_CONST"],    0, 0,  #  3  LOAD_CONST     0 (1)
1500    opmap["RETURN_VALUE"],         #  6  RETURN_VALUE
1501    opmap["JUMP_ABSOLUTE"], 3, 0,  #  7  JUMP_ABSOLUTE  3
1502]
1503foo_code = CodeType(0, 0, 1, 0, "".join(chr(x) for x in foo_bytecode),
1504                    (1,), (), (), "<string>", "foo", 1, "")
1505foo = FunctionType(foo_code, globals())
1506''', level)
1507        self.assertEquals(1, foo())
1508
1509
1510class LoopExceptionInteractionTests(LlvmTestCase):
1511    @at_each_optimization_level
1512    def test_except_through_loop_caught(self, level):
1513        nested = compile_for_llvm('nested', '''
1514def nested(lst, obj):
1515    try:
1516        for x in lst:
1517            raise UnboundLocalError
1518    except:
1519        obj["x"] = 2
1520    # Make sure the block stack is ok.
1521    try:
1522        for x in lst:
1523            return x
1524    finally:
1525        obj["y"] = 3
1526''', level)
1527        obj = {}
1528        self.assertEquals(1, nested([1,2,3], obj))
1529        self.assertEquals({"x": 2, "y": 3}, obj)
1530
1531    @at_each_optimization_level
1532    def test_except_in_loop(self, level):
1533        nested = compile_for_llvm('nested', '''
1534def nested(lst, obj):
1535    try:
1536        for x in lst:
1537            try:
1538                a = a
1539            except ZeroDivisionError:
1540                obj["x"] = 2
1541    except UnboundLocalError:
1542        obj["z"] = 4
1543    # Make sure the block stack is ok.
1544    try:
1545        for x in lst:
1546            return x
1547    finally:
1548        obj["y"] = 3
1549''', level)
1550        obj = {}
1551        self.assertEquals(1, nested([1,2,3], obj))
1552        self.assertEquals({"z": 4, "y": 3}, obj)
1553
1554    @at_each_optimization_level
1555    def test_except_through_loop_finally(self, level):
1556        nested = compile_for_llvm('nested', '''
1557def nested(lst, obj):
1558    try:
1559        for x in lst:
1560            a = a
1561    finally:
1562        obj["x"] = 2
1563''', level)
1564        obj = {}
1565        self.assertRaises(UnboundLocalError, nested, [1,2,3], obj)
1566        self.assertEquals({"x": 2}, obj)
1567
1568    @at_each_optimization_level
1569    def test_break_in_try(self, level):
1570        break_one = compile_for_llvm("break_one", """
1571def break_one(x):
1572    for y in [1, 2]:
1573        try:
1574            x["break"] = y
1575            break
1576            x["post break"] = y
1577        except ZeroDivisionError:
1578            x["except"] = 77
1579        finally:
1580            x["finally"] = y
1581    else:
1582        x["else"] = True
1583
1584    # Make sure the block stack is ok.
1585    try:
1586        1 / 0
1587    except ZeroDivisionError:
1588        x["except"] = ZeroDivisionError
1589    return x
1590""", level)
1591        self.assertEqual(break_one({}), {"break": 1, "finally": 1,
1592                                         "except": ZeroDivisionError})
1593
1594
1595def cause_bail_on_next_line():
1596    sys.settrace(lambda *args: None)
1597
1598
1599class BailoutTests(ExtraAssertsTestCase):
1600    @at_each_optimization_level
1601    def test_bail_inside_loop(self, level):
1602        # We had a bug where the block stack in the compiled version
1603        # of the below function used contiguous small integers to
1604        # identify block handlers.  When we bailed out to the
1605        # interpreter, it expected an handler's identifier to be the
1606        # index of the opcode that started the code for the handler.
1607        # This mismatch caused a crash.
1608        loop = compile_for_llvm("loop", """
1609def loop():
1610    for i in [1, 2]:
1611        # Use try/finally to get "break" to emit a BREAK_LOOP opcode
1612        # instead of just jumping out of the loop.
1613        try:
1614            cause_bail_on_next_line()
1615            break
1616        finally:
1617            pass
1618    return i
1619""", level)
1620        orig_trace = sys.gettrace()
1621        try:
1622            self.assertEquals(loop(), 1)
1623        finally:
1624            sys.settrace(orig_trace)
1625
1626    def test_use_correct_unwind_reason_when_bailing(self):
1627 

Large files files are truncated, but you can click here to view the full file