return -1; case DELETE_FAST: return 0; case RAISE_VARARGS: return -oparg;#define NARGS(o) (((o) % 256) + 2*((o) / 256)) case CALL_FUNCTION: return -NARGS(oparg); case CALL_FUNCTION_VAR: case CALL_FUNCTION_KW: return -NARGS(oparg)-1; case CALL_FUNCTION_VAR_KW: return -NARGS(oparg)-2;#undef NARGS case MAKE_FUNCTION: return -oparg; case BUILD_SLICE: if (oparg == 3) return -2; else return -1; case MAKE_CLOSURE: return -oparg; case LOAD_CLOSURE: return 1; case LOAD_DEREF: return 1; case STORE_DEREF: return -1; default: fprintf(stderr, "opcode = %d\n", opcode); Py_FatalError("opcode_stack_effect()"); } return 0; /* not reachable */} /* Add an opcode with no argument. Returns 0 on failure, 1 on success.*/ static intcompiler_addop(struct compiler *c, int opcode){ basicblock *b; struct instr *i; int off; off = compiler_next_instr(c, c->u->u_curblock); if (off < 0) return 0; b = c->u->u_curblock; i = &b->b_instr[off]; i->i_opcode = opcode; i->i_hasarg = 0; if (opcode == RETURN_VALUE) b->b_return = 1; compiler_set_lineno(c, off); return 1;} static intcompiler_add_o(struct compiler *c, PyObject *dict, PyObject *o){ PyObject *t, *v; Py_ssize_t arg; /* necessary to make sure types aren't coerced (e.g., int and long) */ t = PyTuple_Pack(2, o, o->ob_type); if (t == NULL) return -1; v = PyDict_GetItem(dict, t); if (!v) { arg = PyDict_Size(dict); v = PyInt_FromLong(arg); if (!v) { Py_DECREF(t); return -1; } if (PyDict_SetItem(dict, t, v) < 0) { Py_DECREF(t); Py_DECREF(v); return -1; } Py_DECREF(v); } else arg = PyInt_AsLong(v); Py_DECREF(t); return arg;} static intcompiler_addop_o(struct compiler *c, int opcode, PyObject *dict, PyObject *o){ int arg = compiler_add_o(c, dict, o); if (arg < 0) return 0; return compiler_addop_i(c, opcode, arg);} static intcompiler_addop_name(struct compiler *c, int opcode, PyObject *dict, PyObject *o){ int arg; PyObject *mangled = _Py_Mangle(c->u->u_private, o); if (!mangled) return 0; arg = compiler_add_o(c, dict, mangled); Py_DECREF(mangled); if (arg < 0) return 0; return compiler_addop_i(c, opcode, arg);} /* Add an opcode with an integer argument. Returns 0 on failure, 1 on success.*/ static intcompiler_addop_i(struct compiler *c, int opcode, int oparg){ struct instr *i; int off; off = compiler_next_instr(c, c->u->u_curblock); if (off < 0) return 0; i = &c->u->u_curblock->b_instr[off]; i->i_opcode = opcode; i->i_oparg = oparg; i->i_hasarg = 1; compiler_set_lineno(c, off); return 1;} static intcompiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute){ struct instr *i; int off; assert(b != NULL); off = compiler_next_instr(c, c->u->u_curblock); if (off < 0) return 0; i = &c->u->u_curblock->b_instr[off]; i->i_opcode = opcode; i->i_target = b; i->i_hasarg = 1; if (absolute) i->i_jabs = 1; else i->i_jrel = 1; compiler_set_lineno(c, off); return 1;} /* The distinction between NEW_BLOCK and NEXT_BLOCK is subtle. (I'd like to find better names.) NEW_BLOCK() creates a new block and sets it as the current block. NEXT_BLOCK() also creates an implicit jump from the current block to the new block.*/ /* XXX The returns inside these macros make it impossible to decref objects created in the local function.*/ #define NEW_BLOCK(C) { \ if (compiler_use_new_block((C)) == NULL) \ return 0; \} #define NEXT_BLOCK(C) { \ if (compiler_next_block((C)) == NULL) \ return 0; \} #define ADDOP(C, OP) { \ if (!compiler_addop((C), (OP))) \ return 0; \} #define ADDOP_IN_SCOPE(C, OP) { \ if (!compiler_addop((C), (OP))) { \ compiler_exit_scope(c); \ return 0; \ } \} #define ADDOP_O(C, OP, O, TYPE) { \ if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) \ return 0; \} #define ADDOP_NAME(C, OP, O, TYPE) { \ if (!compiler_addop_name((C), (OP), (C)->u->u_ ## TYPE, (O))) \ return 0; \} #define ADDOP_I(C, OP, O) { \ if (!compiler_addop_i((C), (OP), (O))) \ return 0; \} #define ADDOP_JABS(C, OP, O) { \ if (!compiler_addop_j((C), (OP), (O), 1)) \ return 0; \} #define ADDOP_JREL(C, OP, O) { \ if (!compiler_addop_j((C), (OP), (O), 0)) \ return 0; \} /* VISIT and VISIT_SEQ takes an ASDL type as their second argument. They use the ASDL name to synthesize the name of the C type and the visit function.*/ #define VISIT(C, TYPE, V) {\ if (!compiler_visit_ ## TYPE((C), (V))) \ return 0; \} #define VISIT_IN_SCOPE(C, TYPE, V) {\ if (!compiler_visit_ ## TYPE((C), (V))) { \ compiler_exit_scope(c); \ return 0; \ } \} #define VISIT_SLICE(C, V, CTX) {\ if (!compiler_visit_slice((C), (V), (CTX))) \ return 0; \} #define VISIT_SEQ(C, TYPE, SEQ) { \ int _i; \ asdl_seq *seq = (SEQ); /* avoid variable capture */ \ for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \ if (!compiler_visit_ ## TYPE((C), elt)) \ return 0; \ } \} #define VISIT_SEQ_IN_SCOPE(C, TYPE, SEQ) { \ int _i; \ asdl_seq *seq = (SEQ); /* avoid variable capture */ \ for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \ if (!compiler_visit_ ## TYPE((C), elt)) { \ compiler_exit_scope(c); \ return 0; \ } \ } \} static intcompiler_isdocstring(stmt_ty s){ if (s->kind != Expr_kind) return 0; return s->v.Expr.value->kind == Str_kind;} /* Compile a sequence of statements, checking for a docstring. */ static intcompiler_body(struct compiler *c, asdl_seq *stmts){ int i = 0; stmt_ty st; if (!asdl_seq_LEN(stmts)) return 1; st = (stmt_ty)asdl_seq_GET(stmts, 0); if (compiler_isdocstring(st)) { i = 1; VISIT(c, expr, st->v.Expr.value); if (!compiler_nameop(c, __doc__, Store)) return 0; } for (; i < asdl_seq_LEN(stmts); i++) VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i)); return 1;} static PyCodeObject *compiler_mod(struct compiler *c, mod_ty mod){ PyCodeObject *co; int addNone = 1; static PyObject *module; if (!module) { module = PyString_FromString("<module>"); if (!module) return NULL; } /* Use 0 for firstlineno initially, will fixup in assemble(). */ if (!compiler_enter_scope(c, module, mod, 0)) return NULL; switch (mod->kind) { case Module_kind: if (!compiler_body(c, mod->v.Module.body)) { compiler_exit_scope(c); return 0; } break; case Interactive_kind: c->c_interactive = 1; VISIT_SEQ_IN_SCOPE(c, stmt, mod->v.Interactive.body); break; case Expression_kind: VISIT_IN_SCOPE(c, expr, mod->v.Expression.body); addNone = 0; break; case Suite_kind: PyErr_SetString(PyExc_SystemError, "suite should not be possible"); return 0; default: PyErr_Format(PyExc_SystemError, "module kind %d should not be possible", mod->kind); return 0; } co = assemble(c, addNone); compiler_exit_scope(c); return co;} /* The test for LOCAL must come before the test for FREE in order to handle classes where name is both local and free. The local var is a method and the free var is a free var referenced within a method.*/ static intget_ref_type(struct compiler *c, PyObject *name){ int scope = PyST_GetScope(c->u->u_ste, name); if (scope == 0) { char buf[350]; PyOS_snprintf(buf, sizeof(buf), "unknown scope for %.100s in %.100s(%s) in %s\n" "symbols: %s\nlocals: %s\nglobals: %s\n", PyString_AS_STRING(name), PyString_AS_STRING(c->u->u_name), PyObject_REPR(c->u->u_ste->ste_id), c->c_filename, PyObject_REPR(c->u->u_ste->ste_symbols), PyObject_REPR(c->u->u_varnames), PyObject_REPR(c->u->u_names) ); Py_FatalError(buf); } return scope;} static intcompiler_lookup_arg(PyObject *dict, PyObject *name){ PyObject *k, *v; k = PyTuple_Pack(2, name, name->ob_type); if (k == NULL) return -1; v = PyDict_GetItem(dict, k); Py_DECREF(k); if (v == NULL) return -1; return PyInt_AS_LONG(v);} static intcompiler_make_closure(struct compiler *c, PyCodeObject *co, int args){ int i, free = PyCode_GetNumFree(co); if (free == 0) { ADDOP_O(c, LOAD_CONST, (PyObject*)co, consts); ADDOP_I(c, MAKE_FUNCTION, args); return 1; } for (i = 0; i < free; ++i) { /* Bypass com_addop_varname because it will generate LOAD_DEREF but LOAD_CLOSURE is needed. */ PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); int arg, reftype; /* Special case: If a class contains a method with a free variable that has the same name as a method, the name will be considered free *and* local in the class. It should be handled by the closure, as well as by the normal name loookup logic. */ reftype = get_ref_type(c, name); if (reftype == CELL) arg = compiler_lookup_arg(c->u->u_cellvars, name); else /* (reftype == FREE) */ arg = compiler_lookup_arg(c->u->u_freevars, name); if (arg == -1) { printf("lookup %s in %s %d %d\n" "freevars of %s: %s\n", PyObject_REPR(name), PyString_AS_STRING(c->u->u_name), reftype, arg, PyString_AS_STRING(co->co_name), PyObject_REPR(co->co_freevars)); Py_FatalError("compiler_make_closure()"); } ADDOP_I(c, LOAD_CLOSURE, arg); } ADDOP_I(c, BUILD_TUPLE, free); ADDOP_O(c, LOAD_CONST, (PyObject*)co, consts); ADDOP_I(c, MAKE_CLOSURE, args); return 1;} static intcompiler_decorators(struct compiler *c, asdl_seq* decos){ int i; if (!decos) return 1; for (i = 0; i < asdl_seq_LEN(decos); i++) { VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i)); } return 1;} static intcompiler_arguments(struct compiler *c, arguments_ty args){ int i; int n = asdl_seq_LEN(args->args); /* Correctly handle nested argument lists */ for (i = 0; i < n; i++) { expr_ty arg = (expr_ty)asdl_seq_GET(args->args, i); if (arg->kind == Tuple_kind) { PyObject *id = PyString_FromFormat(".%d", i); if (id == NULL) { return 0; } if (!compiler_nameop(c, id, Load)) { Py_DECREF(id); return 0; } Py_DECREF(id); VISIT(c, expr, arg); } } return 1;} static intcompiler_function(struct compiler *c, stmt_ty s){ PyCodeObject *co; PyObject *first_const = Py_None; arguments_ty args = s->v.FunctionDef.args; asdl_seq* decos = s->v.FunctionDef.decorators; stmt_ty st; int i, n, docstring; assert(s->kind == FunctionDef_kind); if (!compiler_decorators(c, decos)) return 0; if (args->defaults) VISIT_SEQ(c, expr, args->defaults); if (!compiler_enter_scope(c, s->v.FunctionDef.name, (void *)s, s->lineno)) return 0; st = (stmt_ty)asdl_seq_GET(s->v.FunctionDef.body, 0); docstring = compiler_isdocstring(st); if (docstring) first_const = st->v.Expr.value->v.Str.s; if (compiler_add_o(c, c->u->u_consts, first_const) < 0) { compiler_exit_scope(c); return 0; } /* unpack nested arguments */ compiler_arguments(c, args); c->u->u_argcount = asdl_seq_LEN(args->args); n = asdl_seq_LEN(s->v.FunctionDef.body); /* if there was a docstring, we need to skip the first statement */ for (i = docstring; i < n; i++) { st = (stmt_ty)asdl_seq_GET(s->v.FunctionDef.body, i); VISIT_IN_SCOPE(c, stmt, st);Lines 1501–2000 of 4570. Previous lines Load more
return -1; case DELETE_FAST: return 0; case RAISE_VARARGS: return -oparg; #define NARGS(o) (((o) % 256) + 2*((o) / 256)) case CALL_FUNCTION: return -NARGS(oparg); case CALL_FUNCTION_VAR: case CALL_FUNCTION_KW: return -NARGS(oparg)-1; case CALL_FUNCTION_VAR_KW: return -NARGS(oparg)-2; #undef NARGS case MAKE_FUNCTION: return -oparg; case BUILD_SLICE: if (oparg == 3) return -2; else return -1; case MAKE_CLOSURE: return -oparg; case LOAD_CLOSURE: return 1; case LOAD_DEREF: return 1; case STORE_DEREF: return -1; default: fprintf(stderr, "opcode = %d\n", opcode); Py_FatalError("opcode_stack_effect()"); } return 0; /* not reachable */ } /* Add an opcode with no argument. Returns 0 on failure, 1 on success. */ static int compiler_addop(struct compiler *c, int opcode) { basicblock *b; struct instr *i; int off; off = compiler_next_instr(c, c->u->u_curblock); if (off < 0) return 0; b = c->u->u_curblock; i = &b->b_instr[off]; i->i_opcode = opcode; i->i_hasarg = 0; if (opcode == RETURN_VALUE) b->b_return = 1; compiler_set_lineno(c, off); return 1; } static int compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o) { PyObject *t, *v; Py_ssize_t arg; /* necessary to make sure types aren't coerced (e.g., int and long) */ t = PyTuple_Pack(2, o, o->ob_type); if (t == NULL) return -1; v = PyDict_GetItem(dict, t); if (!v) { arg = PyDict_Size(dict); v = PyInt_FromLong(arg); if (!v) { Py_DECREF(t); return -1; } if (PyDict_SetItem(dict, t, v) < 0) { Py_DECREF(t); Py_DECREF(v); return -1; } Py_DECREF(v); } else arg = PyInt_AsLong(v); Py_DECREF(t); return arg; } static int compiler_addop_o(struct compiler *c, int opcode, PyObject *dict, PyObject *o) { int arg = compiler_add_o(c, dict, o); if (arg < 0) return 0; return compiler_addop_i(c, opcode, arg); } static int compiler_addop_name(struct compiler *c, int opcode, PyObject *dict, PyObject *o) { int arg; PyObject *mangled = _Py_Mangle(c->u->u_private, o); if (!mangled) return 0; arg = compiler_add_o(c, dict, mangled); Py_DECREF(mangled); if (arg < 0) return 0; return compiler_addop_i(c, opcode, arg); } /* Add an opcode with an integer argument. Returns 0 on failure, 1 on success. */ static int compiler_addop_i(struct compiler *c, int opcode, int oparg) { struct instr *i; int off; off = compiler_next_instr(c, c->u->u_curblock); if (off < 0) return 0; i = &c->u->u_curblock->b_instr[off]; i->i_opcode = opcode; i->i_oparg = oparg; i->i_hasarg = 1; compiler_set_lineno(c, off); return 1; } static int compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) { struct instr *i; int off; assert(b != NULL); off = compiler_next_instr(c, c->u->u_curblock); if (off < 0) return 0; i = &c->u->u_curblock->b_instr[off]; i->i_opcode = opcode; i->i_target = b; i->i_hasarg = 1; if (absolute) i->i_jabs = 1; else i->i_jrel = 1; compiler_set_lineno(c, off); return 1; } /* The distinction between NEW_BLOCK and NEXT_BLOCK is subtle. (I'd like to find better names.) NEW_BLOCK() creates a new block and sets it as the current block. NEXT_BLOCK() also creates an implicit jump from the current block to the new block. */ /* XXX The returns inside these macros make it impossible to decref objects created in the local function. */ #define NEW_BLOCK(C) { \ if (compiler_use_new_block((C)) == NULL) \ return 0; \ } #define NEXT_BLOCK(C) { \ if (compiler_next_block((C)) == NULL) \ return 0; \ } #define ADDOP(C, OP) { \ if (!compiler_addop((C), (OP))) \ return 0; \ } #define ADDOP_IN_SCOPE(C, OP) { \ if (!compiler_addop((C), (OP))) { \ compiler_exit_scope(c); \ return 0; \ } \ } #define ADDOP_O(C, OP, O, TYPE) { \ if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) \ return 0; \ } #define ADDOP_NAME(C, OP, O, TYPE) { \ if (!compiler_addop_name((C), (OP), (C)->u->u_ ## TYPE, (O))) \ return 0; \ } #define ADDOP_I(C, OP, O) { \ if (!compiler_addop_i((C), (OP), (O))) \ return 0; \ } #define ADDOP_JABS(C, OP, O) { \ if (!compiler_addop_j((C), (OP), (O), 1)) \ return 0; \ } #define ADDOP_JREL(C, OP, O) { \ if (!compiler_addop_j((C), (OP), (O), 0)) \ return 0; \ } /* VISIT and VISIT_SEQ takes an ASDL type as their second argument. They use the ASDL name to synthesize the name of the C type and the visit function. */ #define VISIT(C, TYPE, V) {\ if (!compiler_visit_ ## TYPE((C), (V))) \ return 0; \ } #define VISIT_IN_SCOPE(C, TYPE, V) {\ if (!compiler_visit_ ## TYPE((C), (V))) { \ compiler_exit_scope(c); \ return 0; \ } \ } #define VISIT_SLICE(C, V, CTX) {\ if (!compiler_visit_slice((C), (V), (CTX))) \ return 0; \ } #define VISIT_SEQ(C, TYPE, SEQ) { \ int _i; \ asdl_seq *seq = (SEQ); /* avoid variable capture */ \ for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \ if (!compiler_visit_ ## TYPE((C), elt)) \ return 0; \ } \ } #define VISIT_SEQ_IN_SCOPE(C, TYPE, SEQ) { \ int _i; \ asdl_seq *seq = (SEQ); /* avoid variable capture */ \ for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \ if (!compiler_visit_ ## TYPE((C), elt)) { \ compiler_exit_scope(c); \ return 0; \ } \ } \ } static int compiler_isdocstring(stmt_ty s) { if (s->kind != Expr_kind) return 0; return s->v.Expr.value->kind == Str_kind; } /* Compile a sequence of statements, checking for a docstring. */ static int compiler_body(struct compiler *c, asdl_seq *stmts) { int i = 0; stmt_ty st; if (!asdl_seq_LEN(stmts)) return 1; st = (stmt_ty)asdl_seq_GET(stmts, 0); if (compiler_isdocstring(st)) { i = 1; VISIT(c, expr, st->v.Expr.value); if (!compiler_nameop(c, __doc__, Store)) return 0; } for (; i < asdl_seq_LEN(stmts); i++) VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i)); return 1; } static PyCodeObject * compiler_mod(struct compiler *c, mod_ty mod) { PyCodeObject *co; int addNone = 1; static PyObject *module; if (!module) { module = PyString_FromString("<module>"); if (!module) return NULL; } /* Use 0 for firstlineno initially, will fixup in assemble(). */ if (!compiler_enter_scope(c, module, mod, 0)) return NULL; switch (mod->kind) { case Module_kind: if (!compiler_body(c, mod->v.Module.body)) { compiler_exit_scope(c); return 0; } break; case Interactive_kind: c->c_interactive = 1; VISIT_SEQ_IN_SCOPE(c, stmt, mod->v.Interactive.body); break; case Expression_kind: VISIT_IN_SCOPE(c, expr, mod->v.Expression.body); addNone = 0; break; case Suite_kind: PyErr_SetString(PyExc_SystemError, "suite should not be possible"); return 0; default: PyErr_Format(PyExc_SystemError, "module kind %d should not be possible", mod->kind); return 0; } co = assemble(c, addNone); compiler_exit_scope(c); return co; } /* The test for LOCAL must come before the test for FREE in order to handle classes where name is both local and free. The local var is a method and the free var is a free var referenced within a method. */ static int get_ref_type(struct compiler *c, PyObject *name) { int scope = PyST_GetScope(c->u->u_ste, name); if (scope == 0) { char buf[350]; PyOS_snprintf(buf, sizeof(buf), "unknown scope for %.100s in %.100s(%s) in %s\n" "symbols: %s\nlocals: %s\nglobals: %s\n", PyString_AS_STRING(name), PyString_AS_STRING(c->u->u_name), PyObject_REPR(c->u->u_ste->ste_id), c->c_filename, PyObject_REPR(c->u->u_ste->ste_symbols), PyObject_REPR(c->u->u_varnames), PyObject_REPR(c->u->u_names) ); Py_FatalError(buf); } return scope; } static int compiler_lookup_arg(PyObject *dict, PyObject *name) { PyObject *k, *v; k = PyTuple_Pack(2, name, name->ob_type); if (k == NULL) return -1; v = PyDict_GetItem(dict, k); Py_DECREF(k); if (v == NULL) return -1; return PyInt_AS_LONG(v); } static int compiler_make_closure(struct compiler *c, PyCodeObject *co, int args) { int i, free = PyCode_GetNumFree(co); if (free == 0) { ADDOP_O(c, LOAD_CONST, (PyObject*)co, consts); ADDOP_I(c, MAKE_FUNCTION, args); return 1; } for (i = 0; i < free; ++i) { /* Bypass com_addop_varname because it will generate LOAD_DEREF but LOAD_CLOSURE is needed. */ PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); int arg, reftype; /* Special case: If a class contains a method with a free variable that has the same name as a method, the name will be considered free *and* local in the class. It should be handled by the closure, as well as by the normal name loookup logic. */ reftype = get_ref_type(c, name); if (reftype == CELL) arg = compiler_lookup_arg(c->u->u_cellvars, name); else /* (reftype == FREE) */ arg = compiler_lookup_arg(c->u->u_freevars, name); if (arg == -1) { printf("lookup %s in %s %d %d\n" "freevars of %s: %s\n", PyObject_REPR(name), PyString_AS_STRING(c->u->u_name), reftype, arg, PyString_AS_STRING(co->co_name), PyObject_REPR(co->co_freevars)); Py_FatalError("compiler_make_closure()"); } ADDOP_I(c, LOAD_CLOSURE, arg); } ADDOP_I(c, BUILD_TUPLE, free); ADDOP_O(c, LOAD_CONST, (PyObject*)co, consts); ADDOP_I(c, MAKE_CLOSURE, args); return 1; } static int compiler_decorators(struct compiler *c, asdl_seq* decos) { int i; if (!decos) return 1; for (i = 0; i < asdl_seq_LEN(decos); i++) { VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i)); } return 1; } static int compiler_arguments(struct compiler *c, arguments_ty args) { int i; int n = asdl_seq_LEN(args->args); /* Correctly handle nested argument lists */ for (i = 0; i < n; i++) { expr_ty arg = (expr_ty)asdl_seq_GET(args->args, i); if (arg->kind == Tuple_kind) { PyObject *id = PyString_FromFormat(".%d", i); if (id == NULL) { return 0; } if (!compiler_nameop(c, id, Load)) { Py_DECREF(id); return 0; } Py_DECREF(id); VISIT(c, expr, arg); } } return 1; } static int compiler_function(struct compiler *c, stmt_ty s) { PyCodeObject *co; PyObject *first_const = Py_None; arguments_ty args = s->v.FunctionDef.args; asdl_seq* decos = s->v.FunctionDef.decorators; stmt_ty st; int i, n, docstring; assert(s->kind == FunctionDef_kind); if (!compiler_decorators(c, decos)) return 0; if (args->defaults) VISIT_SEQ(c, expr, args->defaults); if (!compiler_enter_scope(c, s->v.FunctionDef.name, (void *)s, s->lineno)) return 0; st = (stmt_ty)asdl_seq_GET(s->v.FunctionDef.body, 0); docstring = compiler_isdocstring(st); if (docstring) first_const = st->v.Expr.value->v.Str.s; if (compiler_add_o(c, c->u->u_consts, first_const) < 0) { compiler_exit_scope(c); return 0; } /* unpack nested arguments */ compiler_arguments(c, args); c->u->u_argcount = asdl_seq_LEN(args->args); n = asdl_seq_LEN(s->v.FunctionDef.body); /* if there was a docstring, we need to skip the first statement */ for (i = docstring; i < n; i++) { st = (stmt_ty)asdl_seq_GET(s->v.FunctionDef.body, i); VISIT_IN_SCOPE(c, stmt, st);