You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
2.9 KiB

36 years ago
36 years ago
36 years ago
PEP 227 implementation The majority of the changes are in the compiler. The mainloop changes primarily to implement the new opcodes and to pass a function's closure to eval_code2(). Frames and functions got new slots to hold the closure. Include/compile.h Add co_freevars and co_cellvars slots to code objects. Update PyCode_New() to take freevars and cellvars as arguments Include/funcobject.h Add func_closure slot to function objects. Add GetClosure()/SetClosure() functions (and corresponding macros) for getting at the closure. Include/frameobject.h PyFrame_New() now takes a closure. Include/opcode.h Add four new opcodes: MAKE_CLOSURE, LOAD_CLOSURE, LOAD_DEREF, STORE_DEREF. Remove comment about old requirement for opcodes to fit in 7 bits. compile.c Implement changes to code objects for co_freevars and co_cellvars. Modify symbol table to use st_cur_name (string object for the name of the current scope) and st_cur_children (list of nested blocks). Also define st_nested, which might more properly be called st_cur_nested. Add several DEF_XXX flags to track def-use information for free variables. New or modified functions of note: com_make_closure(struct compiling *, PyCodeObject *) Emit LOAD_CLOSURE opcodes as needed to pass cells for free variables into nested scope. com_addop_varname(struct compiling *, int, char *) Emits opcodes for LOAD_DEREF and STORE_DEREF. get_ref_type(struct compiling *, char *name) Return NAME_CLOSURE if ref type is FREE or CELL symtable_load_symbols(struct compiling *) Decides what variables are cell or free based on def-use info. Can now raise SyntaxError if nested scopes are mixed with exec or from blah import *. make_scope_info(PyObject *, PyObject *, int, int) Helper functions for symtable scope stack. symtable_update_free_vars(struct symtable *) After a code block has been analyzed, it must check each of its children for free variables that are not defined in the block. If a variable is free in a child and not defined in the parent, then it is defined by block the enclosing the current one or it is a global. This does the right logic. symtable_add_use() is now a macro for symtable_add_def() symtable_assign(struct symtable *, node *) Use goto instead of for (;;) Fixed bug in symtable where name of keyword argument in function call was treated as assignment in the scope of the call site. Ex: def f(): g(a=2) # a was considered a local of f ceval.c eval_code2() now take one more argument, a closure. Implement LOAD_CLOSURE, LOAD_DEREF, STORE_DEREF, MAKE_CLOSURE> Also: When name error occurs for global variable, report that the name was global in the error mesage. Objects/frameobject.c Initialize f_closure to be a tuple containing space for cellvars and freevars. f_closure is NULL if neither are present. Objects/funcobject.c Add support for func_closure. Python/import.c Change the magic number. Python/marshal.c Track changes to code objects.
25 years ago
  1. /* Function object interface */
  2. #ifndef Py_FUNCOBJECT_H
  3. #define Py_FUNCOBJECT_H
  4. #ifdef __cplusplus
  5. extern "C" {
  6. #endif
  7. /* Function objects and code objects should not be confused with each other:
  8. *
  9. * Function objects are created by the execution of the 'def' statement.
  10. * They reference a code object in their func_code attribute, which is a
  11. * purely syntactic object, i.e. nothing more than a compiled version of some
  12. * source code lines. There is one code object per source code "fragment",
  13. * but each code object can be referenced by zero or many function objects
  14. * depending only on how many times the 'def' statement in the source was
  15. * executed so far.
  16. */
  17. typedef struct {
  18. PyObject_HEAD
  19. PyObject *func_code; /* A code object */
  20. PyObject *func_globals; /* A dictionary (other mappings won't do) */
  21. PyObject *func_defaults; /* NULL or a tuple */
  22. PyObject *func_closure; /* NULL or a tuple of cell objects */
  23. PyObject *func_doc; /* The __doc__ attribute, can be anything */
  24. PyObject *func_name; /* The __name__ attribute, a string object */
  25. PyObject *func_dict; /* The __dict__ attribute, a dict or NULL */
  26. PyObject *func_weakreflist; /* List of weak references */
  27. PyObject *func_module; /* The __module__ attribute, can be anything */
  28. /* Invariant:
  29. * func_closure contains the bindings for func_code->co_freevars, so
  30. * PyTuple_Size(func_closure) == PyCode_GetNumFree(func_code)
  31. * (func_closure may be NULL if PyCode_GetNumFree(func_code) == 0).
  32. */
  33. } PyFunctionObject;
  34. PyAPI_DATA(PyTypeObject) PyFunction_Type;
  35. #define PyFunction_Check(op) (Py_TYPE(op) == &PyFunction_Type)
  36. PyAPI_FUNC(PyObject *) PyFunction_New(PyObject *, PyObject *);
  37. PyAPI_FUNC(PyObject *) PyFunction_GetCode(PyObject *);
  38. PyAPI_FUNC(PyObject *) PyFunction_GetGlobals(PyObject *);
  39. PyAPI_FUNC(PyObject *) PyFunction_GetModule(PyObject *);
  40. PyAPI_FUNC(PyObject *) PyFunction_GetDefaults(PyObject *);
  41. PyAPI_FUNC(int) PyFunction_SetDefaults(PyObject *, PyObject *);
  42. PyAPI_FUNC(PyObject *) PyFunction_GetClosure(PyObject *);
  43. PyAPI_FUNC(int) PyFunction_SetClosure(PyObject *, PyObject *);
  44. /* Macros for direct access to these values. Type checks are *not*
  45. done, so use with care. */
  46. #define PyFunction_GET_CODE(func) \
  47. (((PyFunctionObject *)func) -> func_code)
  48. #define PyFunction_GET_GLOBALS(func) \
  49. (((PyFunctionObject *)func) -> func_globals)
  50. #define PyFunction_GET_MODULE(func) \
  51. (((PyFunctionObject *)func) -> func_module)
  52. #define PyFunction_GET_DEFAULTS(func) \
  53. (((PyFunctionObject *)func) -> func_defaults)
  54. #define PyFunction_GET_CLOSURE(func) \
  55. (((PyFunctionObject *)func) -> func_closure)
  56. /* The classmethod and staticmethod types lives here, too */
  57. PyAPI_DATA(PyTypeObject) PyClassMethod_Type;
  58. PyAPI_DATA(PyTypeObject) PyStaticMethod_Type;
  59. PyAPI_FUNC(PyObject *) PyClassMethod_New(PyObject *);
  60. PyAPI_FUNC(PyObject *) PyStaticMethod_New(PyObject *);
  61. #ifdef __cplusplus
  62. }
  63. #endif
  64. #endif /* !Py_FUNCOBJECT_H */