Skip to content

Handle boxing of cell variables in the bytecode. #41

Closed
@markshannon

Description

@markshannon

This is a refinement of #37, and occurred to me when discussing https://bugs.python.org/issue43693
Rather than simply tacking the cells on to the end of locals, why not interleave them?
Arguments that escape could then be left in their "natural" position.
Doing so would simplify frame creation code a lot, as it wouldn't need to know about cell variables at all.

Example:

def f(a):
    def g():
           return a
    return g

When creating the frame for f, frame creation code (e.g. _PyEval_MakeFrameVector) has to know about cell variables, free variables and which cell variables are arguments. That could all be handled in the compiler.

Currently the bytecode for f above is:

  2           0 LOAD_CLOSURE             0 (a)
              2 BUILD_TUPLE              1
              4 LOAD_CONST               1 (<code object g at 0x7f8075837c60, file "<stdin>", line 2>)
              6 LOAD_CONST               2 ('f.<locals>.g')
              8 MAKE_FUNCTION            8 (closure)
             10 STORE_FAST               1 (g)

  4          12 LOAD_FAST                1 (g)
             14 RETURN_VALUE

The compiler knows that a escapes f, so why not use that knowledge?
By boxing a in the bytecode, closures and normal functions can be treated the same at runtime.
We only need to add one extra instruction in this case:

  2           0 MAKE_CELL                0 (a)
              2 LOAD_CLOSURE             0 (a)
              4 BUILD_TUPLE              1
              6 LOAD_CONST               1 (<code object g at 0x7f8075837c60, file "<stdin>", line 2>)
              8 LOAD_CONST               2 ('f.<locals>.g')
             10 MAKE_FUNCTION            8 (closure)
             12 STORE_FAST               1 (g)

  4          12 LOAD_FAST                1 (g)
             14 RETURN_VALUE

(The code for g is unchanged)

Metadata

Metadata

Labels

3.11Things we intend to do for 3.11

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions