attr = PyString_FromStringAndSize(src, dot ? dot - src : strlen(src)); if (!attr) return -1; ADDOP_O(c, LOAD_ATTR, attr, names); Py_DECREF(attr); src = dot + 1; } } return compiler_nameop(c, asname, Store);} static intcompiler_import(struct compiler *c, stmt_ty s){ /* The Import node stores a module name like a.b.c as a single string. This is convenient for all cases except import a.b.c as d where we need to parse that string to extract the individual module names. XXX Perhaps change the representation to make this case simpler? */ int i, n = asdl_seq_LEN(s->v.Import.names); for (i = 0; i < n; i++) { alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i); int r; PyObject *level; if (c->c_flags && (c->c_flags->cf_flags & CO_FUTURE_ABSOLUTE_IMPORT)) level = PyInt_FromLong(0); else level = PyInt_FromLong(-1); if (level == NULL) return 0; ADDOP_O(c, LOAD_CONST, level, consts); Py_DECREF(level); ADDOP_O(c, LOAD_CONST, Py_None, consts); ADDOP_NAME(c, IMPORT_NAME, alias->name, names); if (alias->asname) { r = compiler_import_as(c, alias->name, alias->asname); if (!r) return r; } else { identifier tmp = alias->name; const char *base = PyString_AS_STRING(alias->name); char *dot = strchr(base, '.'); if (dot) tmp = PyString_FromStringAndSize(base, dot - base); r = compiler_nameop(c, tmp, Store); if (dot) { Py_DECREF(tmp); } if (!r) return r; } } return 1;} static intcompiler_from_import(struct compiler *c, stmt_ty s){ int i, n = asdl_seq_LEN(s->v.ImportFrom.names); PyObject *names = PyTuple_New(n); PyObject *level; if (!names) return 0; if (s->v.ImportFrom.level == 0 && c->c_flags && !(c->c_flags->cf_flags & CO_FUTURE_ABSOLUTE_IMPORT)) level = PyInt_FromLong(-1); else level = PyInt_FromLong(s->v.ImportFrom.level); if (!level) { Py_DECREF(names); return 0; } /* build up the names */ for (i = 0; i < n; i++) { alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i); Py_INCREF(alias->name); PyTuple_SET_ITEM(names, i, alias->name); } if (s->lineno > c->c_future->ff_lineno) { if (!strcmp(PyString_AS_STRING(s->v.ImportFrom.module), "__future__")) { Py_DECREF(level); Py_DECREF(names); return compiler_error(c, "from __future__ imports must occur " "at the beginning of the file"); } } ADDOP_O(c, LOAD_CONST, level, consts); Py_DECREF(level); ADDOP_O(c, LOAD_CONST, names, consts); Py_DECREF(names); ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names); for (i = 0; i < n; i++) { alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i); identifier store_name; if (i == 0 && *PyString_AS_STRING(alias->name) == '*') { assert(n == 1); ADDOP(c, IMPORT_STAR); return 1; } ADDOP_NAME(c, IMPORT_FROM, alias->name, names); store_name = alias->name; if (alias->asname) store_name = alias->asname; if (!compiler_nameop(c, store_name, Store)) { Py_DECREF(names); return 0; } } /* remove imported module */ ADDOP(c, POP_TOP); return 1;} static intcompiler_assert(struct compiler *c, stmt_ty s){ static PyObject *assertion_error = NULL; basicblock *end; if (Py_OptimizeFlag) return 1; if (assertion_error == NULL) { assertion_error = PyString_FromString("AssertionError"); if (assertion_error == NULL) return 0; } VISIT(c, expr, s->v.Assert.test); end = compiler_new_block(c); if (end == NULL) return 0; ADDOP_JREL(c, JUMP_IF_TRUE, end); ADDOP(c, POP_TOP); ADDOP_O(c, LOAD_GLOBAL, assertion_error, names); if (s->v.Assert.msg) { VISIT(c, expr, s->v.Assert.msg); ADDOP_I(c, RAISE_VARARGS, 2); } else { ADDOP_I(c, RAISE_VARARGS, 1); } compiler_use_next_block(c, end); ADDOP(c, POP_TOP); return 1;} static intcompiler_visit_stmt(struct compiler *c, stmt_ty s){ int i, n; /* Always assign a lineno to the next instruction for a stmt. */ c->u->u_lineno = s->lineno; c->u->u_lineno_set = false; switch (s->kind) { case FunctionDef_kind: return compiler_function(c, s); case ClassDef_kind: return compiler_class(c, s); case Return_kind: if (c->u->u_ste->ste_type != FunctionBlock) return compiler_error(c, "'return' outside function"); if (s->v.Return.value) { VISIT(c, expr, s->v.Return.value); } else ADDOP_O(c, LOAD_CONST, Py_None, consts); ADDOP(c, RETURN_VALUE); break; case Delete_kind: VISIT_SEQ(c, expr, s->v.Delete.targets) break; case Assign_kind: n = asdl_seq_LEN(s->v.Assign.targets); VISIT(c, expr, s->v.Assign.value); for (i = 0; i < n; i++) { if (i < n - 1) ADDOP(c, DUP_TOP); VISIT(c, expr, (expr_ty)asdl_seq_GET(s->v.Assign.targets, i)); } break; case AugAssign_kind: return compiler_augassign(c, s); case Print_kind: return compiler_print(c, s); case For_kind: return compiler_for(c, s); case While_kind: return compiler_while(c, s); case If_kind: return compiler_if(c, s); case Raise_kind: n = 0; if (s->v.Raise.type) { VISIT(c, expr, s->v.Raise.type); n++; if (s->v.Raise.inst) { VISIT(c, expr, s->v.Raise.inst); n++; if (s->v.Raise.tback) { VISIT(c, expr, s->v.Raise.tback); n++; } } } ADDOP_I(c, RAISE_VARARGS, n); break; case TryExcept_kind: return compiler_try_except(c, s); case TryFinally_kind: return compiler_try_finally(c, s); case Assert_kind: return compiler_assert(c, s); case Import_kind: return compiler_import(c, s); case ImportFrom_kind: return compiler_from_import(c, s); case Exec_kind: VISIT(c, expr, s->v.Exec.body); if (s->v.Exec.globals) { VISIT(c, expr, s->v.Exec.globals); if (s->v.Exec.locals) { VISIT(c, expr, s->v.Exec.locals); } else { ADDOP(c, DUP_TOP); } } else { ADDOP_O(c, LOAD_CONST, Py_None, consts); ADDOP(c, DUP_TOP); } ADDOP(c, EXEC_STMT); break; case Global_kind: break; case Expr_kind: if (c->c_interactive && c->c_nestlevel <= 1) { VISIT(c, expr, s->v.Expr.value); ADDOP(c, PRINT_EXPR); } else if (s->v.Expr.value->kind != Str_kind && s->v.Expr.value->kind != Num_kind) { VISIT(c, expr, s->v.Expr.value); ADDOP(c, POP_TOP); } break; case Pass_kind: break; case Break_kind: if (!compiler_in_loop(c)) return compiler_error(c, "'break' outside loop"); ADDOP(c, BREAK_LOOP); break; case Continue_kind: return compiler_continue(c); case With_kind: return compiler_with(c, s); } return 1;} static intunaryop(unaryop_ty op){ switch (op) { case Invert: return UNARY_INVERT; case Not: return UNARY_NOT; case UAdd: return UNARY_POSITIVE; case USub: return UNARY_NEGATIVE; } return 0;} static intbinop(struct compiler *c, operator_ty op){ switch (op) { case Add: return BINARY_ADD; case Sub: return BINARY_SUBTRACT; case Mult: return BINARY_MULTIPLY; case Div: if (c->c_flags && c->c_flags->cf_flags & CO_FUTURE_DIVISION) return BINARY_TRUE_DIVIDE; else return BINARY_DIVIDE; case Mod: return BINARY_MODULO; case Pow: return BINARY_POWER; case LShift: return BINARY_LSHIFT; case RShift: return BINARY_RSHIFT; case BitOr: return BINARY_OR; case BitXor: return BINARY_XOR; case BitAnd: return BINARY_AND; case FloorDiv: return BINARY_FLOOR_DIVIDE; } return 0;} static intcmpop(cmpop_ty op){ switch (op) { case Eq: return PyCmp_EQ; case NotEq: return PyCmp_NE; case Lt: return PyCmp_LT; case LtE: return PyCmp_LE; case Gt: return PyCmp_GT; case GtE: return PyCmp_GE; case Is: return PyCmp_IS; case IsNot: return PyCmp_IS_NOT; case In: return PyCmp_IN; case NotIn: return PyCmp_NOT_IN; } return PyCmp_BAD;} static intinplace_binop(struct compiler *c, operator_ty op){ switch (op) { case Add: return INPLACE_ADD; case Sub: return INPLACE_SUBTRACT; case Mult: return INPLACE_MULTIPLY; case Div: if (c->c_flags && c->c_flags->cf_flags & CO_FUTURE_DIVISION) return INPLACE_TRUE_DIVIDE; else return INPLACE_DIVIDE; case Mod: return INPLACE_MODULO; case Pow: return INPLACE_POWER; case LShift: return INPLACE_LSHIFT; case RShift: return INPLACE_RSHIFT; case BitOr: return INPLACE_OR; case BitXor: return INPLACE_XOR; case BitAnd: return INPLACE_AND; case FloorDiv: return INPLACE_FLOOR_DIVIDE; } PyErr_Format(PyExc_SystemError, "inplace binary op %d should not be possible", op); return 0;} static intcompiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx){ int op, scope, arg; enum { OP_FAST, OP_GLOBAL, OP_DEREF, OP_NAME } optype; PyObject *dict = c->u->u_names; PyObject *mangled; /* XXX AugStore isn't used anywhere! */ /* First check for assignment to __debug__. Param? */ if ((ctx == Store || ctx == AugStore || ctx == Del) && !strcmp(PyString_AS_STRING(name), "__debug__")) { return compiler_error(c, "can not assign to __debug__"); } mangled = _Py_Mangle(c->u->u_private, name); if (!mangled) return 0; op = 0; optype = OP_NAME; scope = PyST_GetScope(c->u->u_ste, mangled); switch (scope) { case FREE: dict = c->u->u_freevars; optype = OP_DEREF; break; case CELL: dict = c->u->u_cellvars; optype = OP_DEREF; break; case LOCAL: if (c->u->u_ste->ste_type == FunctionBlock) optype = OP_FAST; break; case GLOBAL_IMPLICIT: if (c->u->u_ste->ste_type == FunctionBlock && !c->u->u_ste->ste_unoptimized) optype = OP_GLOBAL; break; case GLOBAL_EXPLICIT: optype = OP_GLOBAL; break; default: /* scope can be 0 */ break; } /* XXX Leave assert here, but handle __doc__ and the like better */ assert(scope || PyString_AS_STRING(name)[0] == '_'); switch (optype) { case OP_DEREF: switch (ctx) { case Load: op = LOAD_DEREF; break; case Store: op = STORE_DEREF; break; case AugLoad: case AugStore: break; case Del: PyErr_Format(PyExc_SyntaxError, "can not delete variable '%s' referenced " "in nested scope", PyString_AS_STRING(name)); Py_DECREF(mangled); return 0; case Param: default: PyErr_SetString(PyExc_SystemError, "param invalid for deref variable"); return 0; } break; case OP_FAST: switch (ctx) { case Load: op = LOAD_FAST; break; case Store: op = STORE_FAST; break; case Del: op = DELETE_FAST; break; case AugLoad: case AugStore: break; case Param: default: PyErr_SetString(PyExc_SystemError, "param invalid for local variable"); return 0; } ADDOP_O(c, op, mangled, varnames); Py_DECREF(mangled); return 1; case OP_GLOBAL: switch (ctx) { case Load: op = LOAD_GLOBAL; break; case Store: op = STORE_GLOBAL; break; case Del: op = DELETE_GLOBAL; break; case AugLoad: case AugStore: break; case Param:Lines 2501–3000 of 4570. Previous lines Load more
attr = PyString_FromStringAndSize(src, dot ? dot - src : strlen(src)); if (!attr) return -1; ADDOP_O(c, LOAD_ATTR, attr, names); Py_DECREF(attr); src = dot + 1; } } return compiler_nameop(c, asname, Store); } static int compiler_import(struct compiler *c, stmt_ty s) { /* The Import node stores a module name like a.b.c as a single string. This is convenient for all cases except import a.b.c as d where we need to parse that string to extract the individual module names. XXX Perhaps change the representation to make this case simpler? */ int i, n = asdl_seq_LEN(s->v.Import.names); for (i = 0; i < n; i++) { alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i); int r; PyObject *level; if (c->c_flags && (c->c_flags->cf_flags & CO_FUTURE_ABSOLUTE_IMPORT)) level = PyInt_FromLong(0); else level = PyInt_FromLong(-1); if (level == NULL) return 0; ADDOP_O(c, LOAD_CONST, level, consts); Py_DECREF(level); ADDOP_O(c, LOAD_CONST, Py_None, consts); ADDOP_NAME(c, IMPORT_NAME, alias->name, names); if (alias->asname) { r = compiler_import_as(c, alias->name, alias->asname); if (!r) return r; } else { identifier tmp = alias->name; const char *base = PyString_AS_STRING(alias->name); char *dot = strchr(base, '.'); if (dot) tmp = PyString_FromStringAndSize(base, dot - base); r = compiler_nameop(c, tmp, Store); if (dot) { Py_DECREF(tmp); } if (!r) return r; } } return 1; } static int compiler_from_import(struct compiler *c, stmt_ty s) { int i, n = asdl_seq_LEN(s->v.ImportFrom.names); PyObject *names = PyTuple_New(n); PyObject *level; if (!names) return 0; if (s->v.ImportFrom.level == 0 && c->c_flags && !(c->c_flags->cf_flags & CO_FUTURE_ABSOLUTE_IMPORT)) level = PyInt_FromLong(-1); else level = PyInt_FromLong(s->v.ImportFrom.level); if (!level) { Py_DECREF(names); return 0; } /* build up the names */ for (i = 0; i < n; i++) { alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i); Py_INCREF(alias->name); PyTuple_SET_ITEM(names, i, alias->name); } if (s->lineno > c->c_future->ff_lineno) { if (!strcmp(PyString_AS_STRING(s->v.ImportFrom.module), "__future__")) { Py_DECREF(level); Py_DECREF(names); return compiler_error(c, "from __future__ imports must occur " "at the beginning of the file"); } } ADDOP_O(c, LOAD_CONST, level, consts); Py_DECREF(level); ADDOP_O(c, LOAD_CONST, names, consts); Py_DECREF(names); ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names); for (i = 0; i < n; i++) { alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i); identifier store_name; if (i == 0 && *PyString_AS_STRING(alias->name) == '*') { assert(n == 1); ADDOP(c, IMPORT_STAR); return 1; } ADDOP_NAME(c, IMPORT_FROM, alias->name, names); store_name = alias->name; if (alias->asname) store_name = alias->asname; if (!compiler_nameop(c, store_name, Store)) { Py_DECREF(names); return 0; } } /* remove imported module */ ADDOP(c, POP_TOP); return 1; } static int compiler_assert(struct compiler *c, stmt_ty s) { static PyObject *assertion_error = NULL; basicblock *end; if (Py_OptimizeFlag) return 1; if (assertion_error == NULL) { assertion_error = PyString_FromString("AssertionError"); if (assertion_error == NULL) return 0; } VISIT(c, expr, s->v.Assert.test); end = compiler_new_block(c); if (end == NULL) return 0; ADDOP_JREL(c, JUMP_IF_TRUE, end); ADDOP(c, POP_TOP); ADDOP_O(c, LOAD_GLOBAL, assertion_error, names); if (s->v.Assert.msg) { VISIT(c, expr, s->v.Assert.msg); ADDOP_I(c, RAISE_VARARGS, 2); } else { ADDOP_I(c, RAISE_VARARGS, 1); } compiler_use_next_block(c, end); ADDOP(c, POP_TOP); return 1; } static int compiler_visit_stmt(struct compiler *c, stmt_ty s) { int i, n; /* Always assign a lineno to the next instruction for a stmt. */ c->u->u_lineno = s->lineno; c->u->u_lineno_set = false; switch (s->kind) { case FunctionDef_kind: return compiler_function(c, s); case ClassDef_kind: return compiler_class(c, s); case Return_kind: if (c->u->u_ste->ste_type != FunctionBlock) return compiler_error(c, "'return' outside function"); if (s->v.Return.value) { VISIT(c, expr, s->v.Return.value); } else ADDOP_O(c, LOAD_CONST, Py_None, consts); ADDOP(c, RETURN_VALUE); break; case Delete_kind: VISIT_SEQ(c, expr, s->v.Delete.targets) break; case Assign_kind: n = asdl_seq_LEN(s->v.Assign.targets); VISIT(c, expr, s->v.Assign.value); for (i = 0; i < n; i++) { if (i < n - 1) ADDOP(c, DUP_TOP); VISIT(c, expr, (expr_ty)asdl_seq_GET(s->v.Assign.targets, i)); } break; case AugAssign_kind: return compiler_augassign(c, s); case Print_kind: return compiler_print(c, s); case For_kind: return compiler_for(c, s); case While_kind: return compiler_while(c, s); case If_kind: return compiler_if(c, s); case Raise_kind: n = 0; if (s->v.Raise.type) { VISIT(c, expr, s->v.Raise.type); n++; if (s->v.Raise.inst) { VISIT(c, expr, s->v.Raise.inst); n++; if (s->v.Raise.tback) { VISIT(c, expr, s->v.Raise.tback); n++; } } } ADDOP_I(c, RAISE_VARARGS, n); break; case TryExcept_kind: return compiler_try_except(c, s); case TryFinally_kind: return compiler_try_finally(c, s); case Assert_kind: return compiler_assert(c, s); case Import_kind: return compiler_import(c, s); case ImportFrom_kind: return compiler_from_import(c, s); case Exec_kind: VISIT(c, expr, s->v.Exec.body); if (s->v.Exec.globals) { VISIT(c, expr, s->v.Exec.globals); if (s->v.Exec.locals) { VISIT(c, expr, s->v.Exec.locals); } else { ADDOP(c, DUP_TOP); } } else { ADDOP_O(c, LOAD_CONST, Py_None, consts); ADDOP(c, DUP_TOP); } ADDOP(c, EXEC_STMT); break; case Global_kind: break; case Expr_kind: if (c->c_interactive && c->c_nestlevel <= 1) { VISIT(c, expr, s->v.Expr.value); ADDOP(c, PRINT_EXPR); } else if (s->v.Expr.value->kind != Str_kind && s->v.Expr.value->kind != Num_kind) { VISIT(c, expr, s->v.Expr.value); ADDOP(c, POP_TOP); } break; case Pass_kind: break; case Break_kind: if (!compiler_in_loop(c)) return compiler_error(c, "'break' outside loop"); ADDOP(c, BREAK_LOOP); break; case Continue_kind: return compiler_continue(c); case With_kind: return compiler_with(c, s); } return 1; } static int unaryop(unaryop_ty op) { switch (op) { case Invert: return UNARY_INVERT; case Not: return UNARY_NOT; case UAdd: return UNARY_POSITIVE; case USub: return UNARY_NEGATIVE; } return 0; } static int binop(struct compiler *c, operator_ty op) { switch (op) { case Add: return BINARY_ADD; case Sub: return BINARY_SUBTRACT; case Mult: return BINARY_MULTIPLY; case Div: if (c->c_flags && c->c_flags->cf_flags & CO_FUTURE_DIVISION) return BINARY_TRUE_DIVIDE; else return BINARY_DIVIDE; case Mod: return BINARY_MODULO; case Pow: return BINARY_POWER; case LShift: return BINARY_LSHIFT; case RShift: return BINARY_RSHIFT; case BitOr: return BINARY_OR; case BitXor: return BINARY_XOR; case BitAnd: return BINARY_AND; case FloorDiv: return BINARY_FLOOR_DIVIDE; } return 0; } static int cmpop(cmpop_ty op) { switch (op) { case Eq: return PyCmp_EQ; case NotEq: return PyCmp_NE; case Lt: return PyCmp_LT; case LtE: return PyCmp_LE; case Gt: return PyCmp_GT; case GtE: return PyCmp_GE; case Is: return PyCmp_IS; case IsNot: return PyCmp_IS_NOT; case In: return PyCmp_IN; case NotIn: return PyCmp_NOT_IN; } return PyCmp_BAD; } static int inplace_binop(struct compiler *c, operator_ty op) { switch (op) { case Add: return INPLACE_ADD; case Sub: return INPLACE_SUBTRACT; case Mult: return INPLACE_MULTIPLY; case Div: if (c->c_flags && c->c_flags->cf_flags & CO_FUTURE_DIVISION) return INPLACE_TRUE_DIVIDE; else return INPLACE_DIVIDE; case Mod: return INPLACE_MODULO; case Pow: return INPLACE_POWER; case LShift: return INPLACE_LSHIFT; case RShift: return INPLACE_RSHIFT; case BitOr: return INPLACE_OR; case BitXor: return INPLACE_XOR; case BitAnd: return INPLACE_AND; case FloorDiv: return INPLACE_FLOOR_DIVIDE; } PyErr_Format(PyExc_SystemError, "inplace binary op %d should not be possible", op); return 0; } static int compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) { int op, scope, arg; enum { OP_FAST, OP_GLOBAL, OP_DEREF, OP_NAME } optype; PyObject *dict = c->u->u_names; PyObject *mangled; /* XXX AugStore isn't used anywhere! */ /* First check for assignment to __debug__. Param? */ if ((ctx == Store || ctx == AugStore || ctx == Del) && !strcmp(PyString_AS_STRING(name), "__debug__")) { return compiler_error(c, "can not assign to __debug__"); } mangled = _Py_Mangle(c->u->u_private, name); if (!mangled) return 0; op = 0; optype = OP_NAME; scope = PyST_GetScope(c->u->u_ste, mangled); switch (scope) { case FREE: dict = c->u->u_freevars; optype = OP_DEREF; break; case CELL: dict = c->u->u_cellvars; optype = OP_DEREF; break; case LOCAL: if (c->u->u_ste->ste_type == FunctionBlock) optype = OP_FAST; break; case GLOBAL_IMPLICIT: if (c->u->u_ste->ste_type == FunctionBlock && !c->u->u_ste->ste_unoptimized) optype = OP_GLOBAL; break; case GLOBAL_EXPLICIT: optype = OP_GLOBAL; break; default: /* scope can be 0 */ break; } /* XXX Leave assert here, but handle __doc__ and the like better */ assert(scope || PyString_AS_STRING(name)[0] == '_'); switch (optype) { case OP_DEREF: switch (ctx) { case Load: op = LOAD_DEREF; break; case Store: op = STORE_DEREF; break; case AugLoad: case AugStore: break; case Del: PyErr_Format(PyExc_SyntaxError, "can not delete variable '%s' referenced " "in nested scope", PyString_AS_STRING(name)); Py_DECREF(mangled); return 0; case Param: default: PyErr_SetString(PyExc_SystemError, "param invalid for deref variable"); return 0; } break; case OP_FAST: switch (ctx) { case Load: op = LOAD_FAST; break; case Store: op = STORE_FAST; break; case Del: op = DELETE_FAST; break; case AugLoad: case AugStore: break; case Param: default: PyErr_SetString(PyExc_SystemError, "param invalid for local variable"); return 0; } ADDOP_O(c, op, mangled, varnames); Py_DECREF(mangled); return 1; case OP_GLOBAL: switch (ctx) { case Load: op = LOAD_GLOBAL; break; case Store: op = STORE_GLOBAL; break; case Del: op = DELETE_GLOBAL; break; case AugLoad: case AugStore: break; case Param: