cinap_lenrekadd hg and python4bb9e2215 years agoHistory
4570 lines · 109.1 KB · C
RawDownload
	    return 0;    }    else {	/* Discard result from context.__enter__() */	ADDOP(c, POP_TOP);    }     /* Start the try block */    ADDOP_JREL(c, SETUP_FINALLY, finally);     compiler_use_next_block(c, block);    if (!compiler_push_fblock(c, FINALLY_TRY, block)) {	return 0;    }     if (s->v.With.optional_vars) {	/* Bind saved result of context.__enter__() to VAR */	if (!compiler_nameop(c, tmpvalue, Load) ||	    !compiler_nameop(c, tmpvalue, Del))	  return 0;	VISIT(c, expr, s->v.With.optional_vars);    }     /* BLOCK code */    VISIT_SEQ(c, stmt, s->v.With.body);     /* End of try block; start the finally block */    ADDOP(c, POP_BLOCK);    compiler_pop_fblock(c, FINALLY_TRY, block);     ADDOP_O(c, LOAD_CONST, Py_None, consts);    compiler_use_next_block(c, finally);    if (!compiler_push_fblock(c, FINALLY_END, finally))	return 0;     /* Finally block starts; push tmpexit and issue our magic opcode. */    if (!compiler_nameop(c, tmpexit, Load) ||	!compiler_nameop(c, tmpexit, Del))	return 0;    ADDOP(c, WITH_CLEANUP);     /* Finally block ends. */    ADDOP(c, END_FINALLY);    compiler_pop_fblock(c, FINALLY_END, finally);    return 1;} static intcompiler_visit_expr(struct compiler *c, expr_ty e){	int i, n;     /* If expr e has a different line number than the last expr/stmt,       set a new line number for the next instruction.       */	if (e->lineno > c->u->u_lineno) {		c->u->u_lineno = e->lineno;		c->u->u_lineno_set = false;	}	switch (e->kind) {	case BoolOp_kind:		return compiler_boolop(c, e);	case BinOp_kind:		VISIT(c, expr, e->v.BinOp.left);		VISIT(c, expr, e->v.BinOp.right);		ADDOP(c, binop(c, e->v.BinOp.op));		break;	case UnaryOp_kind:		VISIT(c, expr, e->v.UnaryOp.operand);		ADDOP(c, unaryop(e->v.UnaryOp.op));		break;	case Lambda_kind:		return compiler_lambda(c, e);	case IfExp_kind:		return compiler_ifexp(c, e);	case Dict_kind:		/* XXX get rid of arg? */		ADDOP_I(c, BUILD_MAP, 0);		n = asdl_seq_LEN(e->v.Dict.values);		/* We must arrange things just right for STORE_SUBSCR.		   It wants the stack to look like (value) (dict) (key) */		for (i = 0; i < n; i++) {			ADDOP(c, DUP_TOP);			VISIT(c, expr,                                 (expr_ty)asdl_seq_GET(e->v.Dict.values, i));			ADDOP(c, ROT_TWO);			VISIT(c, expr,                                 (expr_ty)asdl_seq_GET(e->v.Dict.keys, i));			ADDOP(c, STORE_SUBSCR);		}		break;	case ListComp_kind:		return compiler_listcomp(c, e);	case GeneratorExp_kind:		return compiler_genexp(c, e);	case Yield_kind:		if (c->u->u_ste->ste_type != FunctionBlock)			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) {			VISIT(c, expr, e->v.Yield.value);		}		else {			ADDOP_O(c, LOAD_CONST, Py_None, consts);		}		ADDOP(c, YIELD_VALUE);		break;	case Compare_kind:		return compiler_compare(c, e);	case Call_kind:		return compiler_call(c, e);	case Repr_kind:		VISIT(c, expr, e->v.Repr.value);		ADDOP(c, UNARY_CONVERT);		break;	case Num_kind:		ADDOP_O(c, LOAD_CONST, e->v.Num.n, consts);		break;	case Str_kind:		ADDOP_O(c, LOAD_CONST, e->v.Str.s, consts);		break;	/* The following exprs can be assignment targets. */	case Attribute_kind:		if (e->v.Attribute.ctx != AugStore)			VISIT(c, expr, e->v.Attribute.value);		switch (e->v.Attribute.ctx) {		case AugLoad:			ADDOP(c, DUP_TOP);			/* Fall through to load */		case Load:			ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names);			break;		case AugStore:			ADDOP(c, ROT_TWO);			/* Fall through to save */		case Store:			ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names);			break;		case Del:			ADDOP_NAME(c, DELETE_ATTR, e->v.Attribute.attr, names);			break;		case Param:		default:			PyErr_SetString(PyExc_SystemError,					"param invalid in attribute expression");			return 0;		}		break;	case Subscript_kind:		switch (e->v.Subscript.ctx) {		case AugLoad:			VISIT(c, expr, e->v.Subscript.value);			VISIT_SLICE(c, e->v.Subscript.slice, AugLoad);			break;		case Load:			VISIT(c, expr, e->v.Subscript.value);			VISIT_SLICE(c, e->v.Subscript.slice, Load);			break;		case AugStore:			VISIT_SLICE(c, e->v.Subscript.slice, AugStore);			break;		case Store:			VISIT(c, expr, e->v.Subscript.value);			VISIT_SLICE(c, e->v.Subscript.slice, Store);			break;		case Del:			VISIT(c, expr, e->v.Subscript.value);			VISIT_SLICE(c, e->v.Subscript.slice, Del);			break;		case Param:		default:			PyErr_SetString(PyExc_SystemError,				"param invalid in subscript expression");			return 0;		}		break;	case Name_kind:		return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx);	/* child nodes of List and Tuple will have expr_context set */	case List_kind:		return compiler_list(c, e);	case Tuple_kind:		return compiler_tuple(c, e);	}	return 1;} static intcompiler_augassign(struct compiler *c, stmt_ty s){	expr_ty e = s->v.AugAssign.target;	expr_ty auge; 	assert(s->kind == AugAssign_kind); 	switch (e->kind) {	case Attribute_kind:		auge = Attribute(e->v.Attribute.value, e->v.Attribute.attr,				 AugLoad, e->lineno, e->col_offset, c->c_arena);		if (auge == NULL)		    return 0;		VISIT(c, expr, auge);		VISIT(c, expr, s->v.AugAssign.value);		ADDOP(c, inplace_binop(c, s->v.AugAssign.op));		auge->v.Attribute.ctx = AugStore;		VISIT(c, expr, auge);		break;	case Subscript_kind:		auge = Subscript(e->v.Subscript.value, e->v.Subscript.slice,				 AugLoad, e->lineno, e->col_offset, c->c_arena);		if (auge == NULL)		    return 0;		VISIT(c, expr, auge);		VISIT(c, expr, s->v.AugAssign.value);		ADDOP(c, inplace_binop(c, s->v.AugAssign.op));		auge->v.Subscript.ctx = AugStore;		VISIT(c, expr, auge);		break;	case Name_kind:		if (!compiler_nameop(c, e->v.Name.id, Load))		    return 0;		VISIT(c, expr, s->v.AugAssign.value);		ADDOP(c, inplace_binop(c, s->v.AugAssign.op));		return compiler_nameop(c, e->v.Name.id, Store);	default:		PyErr_Format(PyExc_SystemError, 			"invalid node type (%d) for augmented assignment",			e->kind);		return 0;	}	return 1;} static intcompiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b){	struct fblockinfo *f;	if (c->u->u_nfblocks >= CO_MAXBLOCKS) {		PyErr_SetString(PyExc_SystemError,				"too many statically nested blocks");		return 0;	}	f = &c->u->u_fblock[c->u->u_nfblocks++];	f->fb_type = t;	f->fb_block = b;	return 1;} static voidcompiler_pop_fblock(struct compiler *c, enum fblocktype t, basicblock *b){	struct compiler_unit *u = c->u;	assert(u->u_nfblocks > 0);	u->u_nfblocks--;	assert(u->u_fblock[u->u_nfblocks].fb_type == t);	assert(u->u_fblock[u->u_nfblocks].fb_block == b);} static intcompiler_in_loop(struct compiler *c) {        int i;        struct compiler_unit *u = c->u;        for (i = 0; i < u->u_nfblocks; ++i) {                if (u->u_fblock[i].fb_type == LOOP)                        return 1;        }        return 0;}/* Raises a SyntaxError and returns 0.   If something goes wrong, a different exception may be raised.*/ static intcompiler_error(struct compiler *c, const char *errstr){	PyObject *loc;	PyObject *u = NULL, *v = NULL; 	loc = PyErr_ProgramText(c->c_filename, c->u->u_lineno);	if (!loc) {		Py_INCREF(Py_None);		loc = Py_None;	}	u = Py_BuildValue("(ziOO)", c->c_filename, c->u->u_lineno,			  Py_None, loc);	if (!u)		goto exit;	v = Py_BuildValue("(zO)", errstr, u);	if (!v)		goto exit;	PyErr_SetObject(PyExc_SyntaxError, v); exit:	Py_DECREF(loc);	Py_XDECREF(u);	Py_XDECREF(v);	return 0;} static intcompiler_handle_subscr(struct compiler *c, const char *kind, 		       expr_context_ty ctx) {	int op = 0; 	/* XXX this code is duplicated */	switch (ctx) {		case AugLoad: /* fall through to Load */		case Load:    op = BINARY_SUBSCR; break;		case AugStore:/* fall through to Store */		case Store:   op = STORE_SUBSCR; break;		case Del:     op = DELETE_SUBSCR; break;		case Param:			PyErr_Format(PyExc_SystemError, 				     "invalid %s kind %d in subscript\n", 				     kind, ctx);			return 0;	}	if (ctx == AugLoad) {		ADDOP_I(c, DUP_TOPX, 2);	}	else if (ctx == AugStore) {		ADDOP(c, ROT_THREE);	}	ADDOP(c, op);	return 1;} static intcompiler_slice(struct compiler *c, slice_ty s, expr_context_ty ctx){	int n = 2;	assert(s->kind == Slice_kind); 	/* only handles the cases where BUILD_SLICE is emitted */	if (s->v.Slice.lower) {		VISIT(c, expr, s->v.Slice.lower);	}	else {		ADDOP_O(c, LOAD_CONST, Py_None, consts);	}			if (s->v.Slice.upper) {		VISIT(c, expr, s->v.Slice.upper);	}	else {		ADDOP_O(c, LOAD_CONST, Py_None, consts);	} 	if (s->v.Slice.step) {		n++;		VISIT(c, expr, s->v.Slice.step);	}	ADDOP_I(c, BUILD_SLICE, n);	return 1;} static intcompiler_simple_slice(struct compiler *c, slice_ty s, expr_context_ty ctx){	int op = 0, slice_offset = 0, stack_count = 0; 	assert(s->v.Slice.step == NULL);	if (s->v.Slice.lower) {		slice_offset++;		stack_count++;		if (ctx != AugStore) 			VISIT(c, expr, s->v.Slice.lower);	}	if (s->v.Slice.upper) {		slice_offset += 2;		stack_count++;		if (ctx != AugStore) 			VISIT(c, expr, s->v.Slice.upper);	} 	if (ctx == AugLoad) {		switch (stack_count) {		case 0: ADDOP(c, DUP_TOP); break;		case 1: ADDOP_I(c, DUP_TOPX, 2); break;		case 2: ADDOP_I(c, DUP_TOPX, 3); break;		}	}	else if (ctx == AugStore) {		switch (stack_count) {		case 0: ADDOP(c, ROT_TWO); break;		case 1: ADDOP(c, ROT_THREE); break;		case 2: ADDOP(c, ROT_FOUR); break;		}	} 	switch (ctx) {	case AugLoad: /* fall through to Load */	case Load: op = SLICE; break;	case AugStore:/* fall through to Store */	case Store: op = STORE_SLICE; break;	case Del: op = DELETE_SLICE; break;	case Param:	default:		PyErr_SetString(PyExc_SystemError,				"param invalid in simple slice");		return 0;	} 	ADDOP(c, op + slice_offset);	return 1;} static intcompiler_visit_nested_slice(struct compiler *c, slice_ty s, 			    expr_context_ty ctx){	switch (s->kind) {	case Ellipsis_kind:		ADDOP_O(c, LOAD_CONST, Py_Ellipsis, consts);		break;	case Slice_kind:		return compiler_slice(c, s, ctx);	case Index_kind:		VISIT(c, expr, s->v.Index.value);		break;	case ExtSlice_kind:	default:		PyErr_SetString(PyExc_SystemError,				"extended slice invalid in nested slice");		return 0;	}	return 1;}  static intcompiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx){	char * kindname = NULL;	switch (s->kind) {	case Index_kind:		kindname = "index";		if (ctx != AugStore) {			VISIT(c, expr, s->v.Index.value);		}		break;	case Ellipsis_kind:		kindname = "ellipsis";		if (ctx != AugStore) {			ADDOP_O(c, LOAD_CONST, Py_Ellipsis, consts);		}		break;	case Slice_kind:		kindname = "slice";		if (!s->v.Slice.step) 			return compiler_simple_slice(c, s, ctx);		if (ctx != AugStore) {			if (!compiler_slice(c, s, ctx))				return 0;		}		break;	case ExtSlice_kind:		kindname = "extended slice";		if (ctx != AugStore) {			int i, n = asdl_seq_LEN(s->v.ExtSlice.dims);			for (i = 0; i < n; i++) {				slice_ty sub = (slice_ty)asdl_seq_GET(                                        s->v.ExtSlice.dims, i);				if (!compiler_visit_nested_slice(c, sub, ctx))					return 0;			}			ADDOP_I(c, BUILD_TUPLE, n);		}		break;	default:		PyErr_Format(PyExc_SystemError,			     "invalid subscript kind %d", s->kind);		return 0;	}	return compiler_handle_subscr(c, kindname, ctx);} /* do depth-first search of basic block graph, starting with block.   post records the block indices in post-order.    XXX must handle implicit jumps from one block to next*/ static voiddfs(struct compiler *c, basicblock *b, struct assembler *a){	int i;	struct instr *instr = NULL; 	if (b->b_seen)		return;	b->b_seen = 1;	if (b->b_next != NULL)

Lines 3501–4000 of 4570. Previous lines