• Kevin Modzelewski's avatar
    Implement closures · ddabda9a
    Kevin Modzelewski authored
    Implementation is pretty straightforward for now:
    - find all names that get accessed from a nested function
    - if any, create a closure object at function entry
    - any time we set a name accessed from a nested function,
      update its value in the closure
    - when evaluating a functiondef that needs a closure, attach
      the created closure to the created function object.
    
    Closures are currently passed as an extra argument before any
    python-level args, which I'm not convinced is the right strategy.
    It's works out fine but it feels messy to say that functions
    can have different C-level calling conventions.
    It felt worse to include the closure as part of the python-level arg
    passing.
    Maybe it should be passed after all the other arguments?
    
    Closures are currently just simple objects, on which we set and get
    Python-level attributes.  The performance (which I haven't tested)
    relies on attribute access being made fast through the hidden-class
    inline caches.
    
    There are a number of ways that this could be improved:
    - be smarter about when we create the closure object, or when we
      update it.
    - not create empty pass-through closures
    - give the closures a pre-defined shape, since we know at irgen-time
      what names can get set.  could probably avoid the inline cache
      machinery and also have better code.
    ddabda9a
closure_test.py 840 Bytes