cinap_lenrekadd hg and python4bb9e2215 years agoHistory
4570 lines · 109.1 KB · C
RawDownload
			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