Kaydet (Commit) f733a013 authored tarafından Neal Norwitz's avatar Neal Norwitz

Update comments, remove commented out code.

Move assembler structure next to assembler code to make it easier to
move it to a separate file.
üst 7a4e8044
...@@ -6,9 +6,10 @@ ...@@ -6,9 +6,10 @@
* object: * object:
* 1. Checks for future statements. See future.c * 1. Checks for future statements. See future.c
* 2. Builds a symbol table. See symtable.c. * 2. Builds a symbol table. See symtable.c.
* 3. Generate code for basic blocks. See compiler_mod() in this file. * 3. Generate code for basic blocks. See compiler_mod() in this file.
* 4. Assemble the basic blocks into final code. See assemble() in * 4. Assemble the basic blocks into final code. See assemble() in
* this file. * this file.
* 5. Optimize the byte code (peephole optimizations). See peephole.c
* *
* Note that compiler_mod() suggests module, but the module ast type * Note that compiler_mod() suggests module, but the module ast type
* (mod_ty) has cases for expressions and interactive statements. * (mod_ty) has cases for expressions and interactive statements.
...@@ -16,7 +17,8 @@ ...@@ -16,7 +17,8 @@
* CAUTION: The VISIT_* macros abort the current function when they * CAUTION: The VISIT_* macros abort the current function when they
* encounter a problem. So don't invoke them when there is memory * encounter a problem. So don't invoke them when there is memory
* which needs to be released. Code blocks are OK, as the compiler * which needs to be released. Code blocks are OK, as the compiler
* structure takes care of releasing those. * structure takes care of releasing those. Use the arena to manage
* objects.
*/ */
#include "Python.h" #include "Python.h"
...@@ -32,16 +34,6 @@ ...@@ -32,16 +34,6 @@
int Py_OptimizeFlag = 0; int Py_OptimizeFlag = 0;
/*
ISSUES:
opcode_stack_effect() function should be reviewed since stack depth bugs
could be really hard to find later.
Dead code is being generated (i.e. after unconditional jumps).
XXX(nnorwitz): not sure this is still true
*/
#define DEFAULT_BLOCK_SIZE 16 #define DEFAULT_BLOCK_SIZE 16
#define DEFAULT_BLOCKS 8 #define DEFAULT_BLOCKS 8
#define DEFAULT_CODE_SIZE 128 #define DEFAULT_CODE_SIZE 128
...@@ -115,11 +107,11 @@ struct compiler_unit { ...@@ -115,11 +107,11 @@ struct compiler_unit {
PyObject *u_private; /* for private name mangling */ PyObject *u_private; /* for private name mangling */
int u_argcount; /* number of arguments for block */ int u_argcount; /* number of arguments for block */
/* Pointer to the most recently allocated block. By following b_list /* Pointer to the most recently allocated block. By following b_list
members, you can reach all early allocated blocks. */ members, you can reach all early allocated blocks. */
basicblock *u_blocks; basicblock *u_blocks;
basicblock *u_curblock; /* pointer to current block */ basicblock *u_curblock; /* pointer to current block */
int u_tmpname; /* temporary variables for list comps */ int u_tmpname; /* temporary variables for list comps */
int u_nfblocks; int u_nfblocks;
struct fblockinfo u_fblock[CO_MAXBLOCKS]; struct fblockinfo u_fblock[CO_MAXBLOCKS];
...@@ -152,17 +144,6 @@ struct compiler { ...@@ -152,17 +144,6 @@ struct compiler {
PyArena *c_arena; /* pointer to memory allocation arena */ PyArena *c_arena; /* pointer to memory allocation arena */
}; };
struct assembler {
PyObject *a_bytecode; /* string containing bytecode */
int a_offset; /* offset into bytecode */
int a_nblocks; /* number of reachable blocks */
basicblock **a_postorder; /* list of blocks in dfs postorder */
PyObject *a_lnotab; /* string containing lnotab */
int a_lnotab_off; /* offset into lnotab */
int a_lineno; /* last lineno of emitted instruction */
int a_lineno_off; /* bytecode offset of last lineno */
};
static int compiler_enter_scope(struct compiler *, identifier, void *, int); static int compiler_enter_scope(struct compiler *, identifier, void *, int);
static void compiler_free(struct compiler *); static void compiler_free(struct compiler *);
static basicblock *compiler_new_block(struct compiler *); static basicblock *compiler_new_block(struct compiler *);
...@@ -396,47 +377,6 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset) ...@@ -396,47 +377,6 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset)
return dest; return dest;
} }
/*
Leave this debugging code for just a little longer.
static void
compiler_display_symbols(PyObject *name, PyObject *symbols)
{
PyObject *key, *value;
int flags;
Py_ssize_t pos = 0;
fprintf(stderr, "block %s\n", PyString_AS_STRING(name));
while (PyDict_Next(symbols, &pos, &key, &value)) {
flags = PyInt_AsLong(value);
fprintf(stderr, "var %s:", PyString_AS_STRING(key));
if (flags & DEF_GLOBAL)
fprintf(stderr, " declared_global");
if (flags & DEF_LOCAL)
fprintf(stderr, " local");
if (flags & DEF_PARAM)
fprintf(stderr, " param");
if (flags & DEF_STAR)
fprintf(stderr, " stararg");
if (flags & DEF_DOUBLESTAR)
fprintf(stderr, " starstar");
if (flags & DEF_INTUPLE)
fprintf(stderr, " tuple");
if (flags & DEF_FREE)
fprintf(stderr, " free");
if (flags & DEF_FREE_GLOBAL)
fprintf(stderr, " global");
if (flags & DEF_FREE_CLASS)
fprintf(stderr, " free/class");
if (flags & DEF_IMPORT)
fprintf(stderr, " import");
fprintf(stderr, "\n");
}
fprintf(stderr, "\n");
}
*/
static void static void
compiler_unit_check(struct compiler_unit *u) compiler_unit_check(struct compiler_unit *u)
{ {
...@@ -610,7 +550,7 @@ compiler_new_block(struct compiler *c) ...@@ -610,7 +550,7 @@ compiler_new_block(struct compiler *c)
return NULL; return NULL;
} }
memset((void *)b, 0, sizeof(basicblock)); memset((void *)b, 0, sizeof(basicblock));
/* Extend the singly linked list of blocks with new block. */ /* Extend the singly linked list of blocks with new block. */
b->b_list = u->u_blocks; b->b_list = u->u_blocks;
u->u_blocks = b; u->u_blocks = b;
return b; return b;
...@@ -649,7 +589,7 @@ compiler_use_next_block(struct compiler *c, basicblock *block) ...@@ -649,7 +589,7 @@ compiler_use_next_block(struct compiler *c, basicblock *block)
/* Returns the offset of the next instruction in the current block's /* Returns the offset of the next instruction in the current block's
b_instr array. Resizes the b_instr as necessary. b_instr array. Resizes the b_instr as necessary.
Returns -1 on failure. Returns -1 on failure.
*/ */
static int static int
compiler_next_instr(struct compiler *c, basicblock *b) compiler_next_instr(struct compiler *c, basicblock *b)
...@@ -693,7 +633,7 @@ compiler_next_instr(struct compiler *c, basicblock *b) ...@@ -693,7 +633,7 @@ compiler_next_instr(struct compiler *c, basicblock *b)
already been set. If it has been set, the call has no effect. already been set. If it has been set, the call has no effect.
Every time a new node is b Every time a new node is b
*/ */
static void static void
compiler_set_lineno(struct compiler *c, int off) compiler_set_lineno(struct compiler *c, int off)
...@@ -1055,8 +995,8 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) ...@@ -1055,8 +995,8 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)
from the current block to the new block. from the current block to the new block.
*/ */
/* XXX The returns inside these macros make it impossible to decref /* The returns inside these macros make it impossible to decref objects
objects created in the local function. created in the local function. Local objects should use the arena.
*/ */
...@@ -2060,7 +2000,7 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) ...@@ -2060,7 +2000,7 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)
{ {
int i, n; int i, n;
/* Always assign a lineno to the next instruction for a stmt. */ /* Always assign a lineno to the next instruction for a stmt. */
c->u->u_lineno = s->lineno; c->u->u_lineno = s->lineno;
c->u->u_lineno_set = false; c->u->u_lineno_set = false;
...@@ -2519,7 +2459,6 @@ compiler_compare(struct compiler *c, expr_ty e) ...@@ -2519,7 +2459,6 @@ compiler_compare(struct compiler *c, expr_ty e)
} }
return 1; return 1;
} }
#undef CMPCAST
static int static int
compiler_call(struct compiler *c, expr_ty e) compiler_call(struct compiler *c, expr_ty e)
...@@ -2933,9 +2872,9 @@ compiler_visit_expr(struct compiler *c, expr_ty e) ...@@ -2933,9 +2872,9 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
{ {
int i, n; int i, n;
/* If expr e has a different line number than the last expr/stmt, /* If expr e has a different line number than the last expr/stmt,
set a new line number for the next instruction. set a new line number for the next instruction.
*/ */
if (e->lineno > c->u->u_lineno) { if (e->lineno > c->u->u_lineno) {
c->u->u_lineno = e->lineno; c->u->u_lineno = e->lineno;
c->u->u_lineno_set = false; c->u->u_lineno_set = false;
...@@ -2979,14 +2918,6 @@ compiler_visit_expr(struct compiler *c, expr_ty e) ...@@ -2979,14 +2918,6 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
case Yield_kind: case Yield_kind:
if (c->u->u_ste->ste_type != FunctionBlock) if (c->u->u_ste->ste_type != FunctionBlock)
return compiler_error(c, "'yield' outside function"); return compiler_error(c, "'yield' outside function");
/*
for (i = 0; i < c->u->u_nfblocks; i++) {
if (c->u->u_fblock[i].fb_type == FINALLY_TRY)
return compiler_error(
c, "'yield' not allowed in a 'try' "
"block with a 'finally' clause");
}
*/
if (e->v.Yield.value) { if (e->v.Yield.value) {
VISIT(c, expr, e->v.Yield.value); VISIT(c, expr, e->v.Yield.value);
} }
...@@ -3317,7 +3248,6 @@ compiler_visit_nested_slice(struct compiler *c, slice_ty s, ...@@ -3317,7 +3248,6 @@ compiler_visit_nested_slice(struct compiler *c, slice_ty s,
return 1; return 1;
} }
static int static int
compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx) compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
{ {
...@@ -3365,12 +3295,26 @@ compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx) ...@@ -3365,12 +3295,26 @@ compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
return compiler_handle_subscr(c, kindname, ctx); return compiler_handle_subscr(c, kindname, ctx);
} }
/* End of the compiler section, beginning of the assembler section */
/* do depth-first search of basic block graph, starting with block. /* do depth-first search of basic block graph, starting with block.
post records the block indices in post-order. post records the block indices in post-order.
XXX must handle implicit jumps from one block to next XXX must handle implicit jumps from one block to next
*/ */
struct assembler {
PyObject *a_bytecode; /* string containing bytecode */
int a_offset; /* offset into bytecode */
int a_nblocks; /* number of reachable blocks */
basicblock **a_postorder; /* list of blocks in dfs postorder */
PyObject *a_lnotab; /* string containing lnotab */
int a_lnotab_off; /* offset into lnotab */
int a_lineno; /* last lineno of emitted instruction */
int a_lineno_off; /* bytecode offset of last lineno */
};
static void static void
dfs(struct compiler *c, basicblock *b, struct assembler *a) dfs(struct compiler *c, basicblock *b, struct assembler *a)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment