The run_mod function is located in file pythonrun.c in line number 1367. It has two important functions bytecode generation and calling the interpreter to execute the bytecode.  The compilation of the bytecode into the Python code object is done in function PyAST_Compile in file Python/compile.c . Let us take a look at the function.

The PyAST_Compile function has two important functions:

  1. Build the symbol table.
    1. This is done in the function PySymtable_Build in line number 285. The function is located in the file Python/symtable.c. The core of the logic is in line number 241 where the asdl sequence is iterated to construct the symbol table in the function symtable_visit_stmt. We can see that an entry is added to the symbol table for a function, class etc… I would urge you to look into this function completely.
    2. Let us examine the structures of the symbol table located in the file Include/symtable.h 
    3. struct symtable {
      const char *st_filename; /* name of file being compiled */
      struct _symtable_entry *st_cur; /* current symbol table entry */
      struct _symtable_entry *st_top; /* module entry */
      PyObject *st_symbols; /* dictionary of symbol table entries */
      PyObject *st_stack; /* stack of namespace info */
      PyObject *st_global; /* borrowed ref to MODULE in st_symbols */
      int st_nblocks; /* number of blocks */
      PyObject *st_private; /* name of current class or NULL */
      PyFutureFeatures *st_future; /* module’s future features */

      typedef struct _symtable_entry {
      PyObject *ste_id; /* int: key in st_symbols */
      PyObject *ste_symbols; /* dict: name to flags */
      PyObject *ste_name; /* string: name of block */
      PyObject *ste_varnames; /* list of variable names */
      PyObject *ste_children; /* list of child ids */
      _Py_block_ty ste_type; /* module, class, or function */
      int ste_unoptimized; /* false if namespace is optimized */
      int ste_nested; /* true if block is nested */
      unsigned ste_free : 1; /* true if block has free variables */
      unsigned ste_child_free : 1; /* true if a child block has free vars,
      including free refs to globals */
      unsigned ste_generator : 1; /* true if namespace is a generator */
      unsigned ste_varargs : 1; /* true if block has varargs */
      unsigned ste_varkeywords : 1; /* true if block has varkeywords */
      unsigned ste_returns_value : 1; /* true if namespace uses return with
      an argument */
      int ste_lineno; /* first line of block */
      int ste_opt_lineno; /* lineno of last exec or import * */
      int ste_tmpname; /* counter for listcomp temp vars */
      struct symtable *ste_table;
      } PySTEntryObject;

      from these two structures we observe that the symbol table is a stack of symbol table entries each constructed from the different types of symbols in the program. I would urge you to debug at this stage and examine the symbol table.

  2. Build the byte code.
    1. This is in the function compiler_mod on line number 292 in compile.c.
    2. Put a breakpoint at this line number.
    3. Enter the function and put a breakpoint on line number 1188.
    4. Which is a call to the function compiler_body.
    5. Enter the function and put a breakpoint on line number 1167 which is a call to the macro VISIT. Open the macro and see that it calls the function compiler_visit_ ## TYPE which in this case is stmt. Open the function compiler_visit_stmt and put a breakpoint on line number 2104 which is a call to the macro ADDOP.
    6. The ADDOP macro calls the function compiler_addop which creates the bytecode instruction for the current asdl sequence.
    7. In this way the code object is constructed.

Let us comeback to the function run_mod in the file pythonrun.c. The next task of this function is to call the interpreter which is done in line number 1376 in function PyEval_EvalCode. This function just calls the main interpreter loop function PyEval_EvalCodeEx which we will look into in the next post.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s