⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dt_parser.c

📁 Sun Solaris 10 中的 DTrace 组件的源代码。请参看: http://www.sun.com/software/solaris/observability.jsp
💻 C
📖 第 1 页 / 共 5 页
字号:
		bzero(&idn, sizeof (dt_node_t));		idp = dt_idhash_lookup(dhp, dsp->ds_ident);		if (idp != NULL)			(void) dt_ident_cook(&idn, idp, NULL);		/*		 * Cache some attributes of the decl to make the rest of this		 * code simpler: if the decl is an array which is subscripted		 * by a type rather than an integer, then it's an associative		 * array (assc).  We then expect to match either DT_IDENT_ARRAY		 * for associative arrays or DT_IDENT_SCALAR for anything else.		 */		assc = ddp->dd_kind == CTF_K_ARRAY &&		    ddp->dd_node->dn_kind == DT_NODE_TYPE;		idkind = assc ? DT_IDENT_ARRAY : DT_IDENT_SCALAR;		if (assc) {			if (class == DT_DC_THIS) {				xyerror(D_DECL_LOCASSC, "associative arrays "				    "may not be declared as local variables:"				    " %s\n", dsp->ds_ident);			}			if (dt_decl_type(ddp->dd_next, &dtt) != 0)				longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);		}		if (idp != NULL && (idp->di_kind != idkind ||		    ctf_type_cmp(dtt.dtt_ctfp, dtt.dtt_type,		    idn.dn_ctfp, idn.dn_type) != 0)) {			xyerror(D_DECL_IDRED, "identifier redeclared: %s\n"			    "\t current: %s %s\n\tprevious: %s %s\n",			    dsp->ds_ident, dt_idkind_name(idkind),			    dt_type_name(dtt.dtt_ctfp,			    dtt.dtt_type, n1, sizeof (n1)),			    dt_idkind_name(idp->di_kind),			    dt_node_type_name(&idn, n2, sizeof (n2)));		} else if (idp != NULL && assc) {			const dt_idsig_t *isp = idp->di_data;			dt_node_t *dnp = ddp->dd_node;			int argc = 0;			for (; dnp != NULL; dnp = dnp->dn_list, argc++) {				const dt_node_t *pnp = &isp->dis_args[argc];				if (ctf_type_cmp(dnp->dn_ctfp, dnp->dn_type,				    pnp->dn_ctfp, pnp->dn_type) == 0)					continue;				xyerror(D_DECL_IDRED,				    "identifier redeclared: %s\n"				    "\t current: %s, key #%d of type %s\n"				    "\tprevious: %s, key #%d of type %s\n",				    dsp->ds_ident,				    dt_idkind_name(idkind), argc + 1,				    dt_node_type_name(dnp, n1, sizeof (n1)),				    dt_idkind_name(idp->di_kind), argc + 1,				    dt_node_type_name(pnp, n2, sizeof (n2)));			}			if (isp->dis_argc != argc) {				xyerror(D_DECL_IDRED,				    "identifier redeclared: %s\n"				    "\t current: %s of %s, tuple length %d\n"				    "\tprevious: %s of %s, tuple length %d\n",				    dsp->ds_ident, dt_idkind_name(idkind),				    dt_type_name(dtt.dtt_ctfp, dtt.dtt_type,				    n1, sizeof (n1)), argc,				    dt_idkind_name(idp->di_kind),				    dt_node_type_name(&idn, n2, sizeof (n2)),				    isp->dis_argc);			}		} else if (idp == NULL) {			type = ctf_type_resolve(dtt.dtt_ctfp, dtt.dtt_type);			kind = ctf_type_kind(dtt.dtt_ctfp, type);			switch (kind) {			case CTF_K_INTEGER:				if (ctf_type_encoding(dtt.dtt_ctfp, type,				    &cte) == 0 && IS_VOID(cte)) {					xyerror(D_DECL_VOIDOBJ, "cannot have "					    "void object: %s\n", dsp->ds_ident);				}				break;			case CTF_K_STRUCT:			case CTF_K_UNION:				if (ctf_type_size(dtt.dtt_ctfp, type) != 0)					break; /* proceed to declaring */				/*FALLTHRU*/			case CTF_K_FORWARD:				xyerror(D_DECL_INCOMPLETE,				    "incomplete struct/union/enum %s: %s\n",				    dt_type_name(dtt.dtt_ctfp, dtt.dtt_type,				    n1, sizeof (n1)), dsp->ds_ident);				/*NOTREACHED*/			}			if ((kind == CTF_K_STRUCT || kind == CTF_K_UNION ||			    kind == CTF_K_ARRAY) && class == DT_DC_THIS) {				xyerror(D_VAR_UNSUP, "clause-local variable"				    " cannot be used with struct/union/array"				    " type: %s\n", dsp->ds_ident);			}			if (dt_idhash_nextid(dhp, &id) == -1) {				xyerror(D_ID_OFLOW, "cannot create %s: limit "				    "on number of %s variables exceeded\n",				    dsp->ds_ident, dt_idhash_name(dhp));			}			dt_dprintf("declare %s %s variable %s, id=%u\n",			    dt_idhash_name(dhp), dt_idkind_name(idkind),			    dsp->ds_ident, id);			idp = dt_idhash_insert(dhp, dsp->ds_ident, idkind,			    idflags | DT_IDFLG_WRITE | DT_IDFLG_DECL, id,			    _dtrace_defattr, 0, assc ? &dt_idops_assc :			    &dt_idops_thaw, NULL, dtp->dt_gen);			if (idp == NULL)				longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);			dt_ident_type_assign(idp, dtt.dtt_ctfp, dtt.dtt_type);			/*			 * If we are declaring an associative array, use our			 * fake parse node to cook the new assoc identifier.			 * This will force the ident code to instantiate the			 * array type signature corresponding to the list of			 * types pointed to by ddp->dd_node.  We also reset			 * the identifier's attributes based upon the result.			 */			if (assc) {				idp->di_attr =				    dt_ident_cook(&idn, idp, &ddp->dd_node);			}		}	}	} /* end of switch */	free(dsp->ds_ident);	dsp->ds_ident = NULL;	return (NULL);}dt_node_t *dt_node_func(dt_node_t *dnp, dt_node_t *args){	dt_ident_t *idp;	if (dnp->dn_kind != DT_NODE_IDENT) {		xyerror(D_FUNC_IDENT,		    "function designator is not of function type\n");	}	idp = dt_idhash_lookup(yypcb->pcb_hdl->dt_globals, dnp->dn_string);	if (idp == NULL) {		xyerror(D_FUNC_UNDEF,		    "undefined function name: %s\n", dnp->dn_string);	}	if (idp->di_kind != DT_IDENT_FUNC &&	    idp->di_kind != DT_IDENT_AGGFUNC &&	    idp->di_kind != DT_IDENT_ACTFUNC) {		xyerror(D_FUNC_IDKIND, "%s '%s' may not be referenced as a "		    "function\n", dt_idkind_name(idp->di_kind), idp->di_name);	}	free(dnp->dn_string);	dnp->dn_string = NULL;	dnp->dn_kind = DT_NODE_FUNC;	dnp->dn_flags &= ~DT_NF_COOKED;	dnp->dn_ident = idp;	dnp->dn_args = args;	dnp->dn_list = NULL;	return (dnp);}/* * The offsetof() function is special because it takes a type name as an * argument.  It does not actually construct its own node; after looking up the * structure or union offset, we just return an integer node with the offset. */dt_node_t *dt_node_offsetof(dt_decl_t *ddp, char *s){	dtrace_typeinfo_t dtt;	dt_node_t dn;	char *name;	int err;	ctf_membinfo_t ctm;	ctf_id_t type;	uint_t kind;	name = alloca(strlen(s) + 1);	(void) strcpy(name, s);	free(s);	err = dt_decl_type(ddp, &dtt);	dt_decl_free(ddp);	if (err != 0)		longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);	type = ctf_type_resolve(dtt.dtt_ctfp, dtt.dtt_type);	kind = ctf_type_kind(dtt.dtt_ctfp, type);	if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) {		xyerror(D_OFFSETOF_TYPE,		    "offsetof operand must be a struct or union type\n");	}	if (ctf_member_info(dtt.dtt_ctfp, type, name, &ctm) == CTF_ERR) {		xyerror(D_UNKNOWN, "failed to determine offset of %s: %s\n",		    name, ctf_errmsg(ctf_errno(dtt.dtt_ctfp)));	}	bzero(&dn, sizeof (dn));	dt_node_type_assign(&dn, dtt.dtt_ctfp, ctm.ctm_type);	if (dn.dn_flags & DT_NF_BITFIELD) {		xyerror(D_OFFSETOF_BITFIELD,		    "cannot take offset of a bit-field: %s\n", name);	}	return (dt_node_int(ctm.ctm_offset / NBBY));}dt_node_t *dt_node_op1(int op, dt_node_t *cp){	dt_node_t *dnp;	if (cp->dn_kind == DT_NODE_INT) {		switch (op) {		case DT_TOK_INEG:			/*			 * If we're negating an unsigned integer, zero out any			 * extra top bits to truncate the value to the size of			 * the effective type determined by dt_node_int().			 */			cp->dn_value = -cp->dn_value;			if (!(cp->dn_flags & DT_NF_SIGNED)) {				cp->dn_value &= ~0ULL >>				    (64 - dt_node_type_size(cp) * NBBY);			}			/*FALLTHRU*/		case DT_TOK_IPOS:			return (cp);		case DT_TOK_BNEG:			cp->dn_value = ~cp->dn_value;			return (cp);		case DT_TOK_LNEG:			cp->dn_value = !cp->dn_value;			return (cp);		}	}	/*	 * If sizeof is applied to a type_name or string constant, we can	 * transform 'cp' into an integer constant in the node construction	 * pass so that it can then be used for arithmetic in this pass.	 */	if (op == DT_TOK_SIZEOF &&	    (cp->dn_kind == DT_NODE_STRING || cp->dn_kind == DT_NODE_TYPE)) {		dtrace_hdl_t *dtp = yypcb->pcb_hdl;		size_t size = dt_node_type_size(cp);		if (size == 0) {			xyerror(D_SIZEOF_TYPE, "cannot apply sizeof to an "			    "operand of unknown size\n");		}		dt_node_type_assign(cp, dtp->dt_ddefs->dm_ctfp,		    ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t"));		cp->dn_kind = DT_NODE_INT;		cp->dn_op = DT_TOK_INT;		cp->dn_value = size;		return (cp);	}	dnp = dt_node_alloc(DT_NODE_OP1);	assert(op <= USHRT_MAX);	dnp->dn_op = (ushort_t)op;	dnp->dn_child = cp;	return (dnp);}dt_node_t *dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp){	dtrace_hdl_t *dtp = yypcb->pcb_hdl;	dt_node_t *dnp;	/*	 * First we check for operations that are illegal -- namely those that	 * might result in integer division by zero, and abort if one is found.	 */	if (rp->dn_kind == DT_NODE_INT && rp->dn_value == 0 &&	    (op == DT_TOK_MOD || op == DT_TOK_DIV ||	    op == DT_TOK_MOD_EQ || op == DT_TOK_DIV_EQ))		xyerror(D_DIV_ZERO, "expression contains division by zero\n");	/*	 * If both children are immediate values, we can just perform inline	 * calculation and return a new immediate node with the result.	 */	if (lp->dn_kind == DT_NODE_INT && rp->dn_kind == DT_NODE_INT) {		uintmax_t l = lp->dn_value;		uintmax_t r = rp->dn_value;		dnp = dt_node_int(0); /* allocate new integer node for result */		switch (op) {		case DT_TOK_LOR:			dnp->dn_value = l || r;			dt_node_type_assign(dnp,			    DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));			break;		case DT_TOK_LXOR:			dnp->dn_value = (l != 0) ^ (r != 0);			dt_node_type_assign(dnp,			    DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));			break;		case DT_TOK_LAND:			dnp->dn_value = l && r;			dt_node_type_assign(dnp,			    DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));			break;		case DT_TOK_BOR:			dnp->dn_value = l | r;			dt_node_promote(lp, rp, dnp);			break;		case DT_TOK_XOR:			dnp->dn_value = l ^ r;			dt_node_promote(lp, rp, dnp);			break;		case DT_TOK_BAND:			dnp->dn_value = l & r;			dt_node_promote(lp, rp, dnp);			break;		case DT_TOK_EQU:			dnp->dn_value = l == r;			dt_node_type_assign(dnp,			    DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));			break;		case DT_TOK_NEQ:			dnp->dn_value = l != r;			dt_node_type_assign(dnp,			    DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));			break;		case DT_TOK_LT:			dt_node_promote(lp, rp, dnp);			if (dnp->dn_flags & DT_NF_SIGNED)				dnp->dn_value = (intmax_t)l < (intmax_t)r;			else				dnp->dn_value = l < r;			dt_node_type_assign(dnp,			    DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));			break;		case DT_TOK_LE:			dt_node_promote(lp, rp, dnp);			if (dnp->dn_flags & DT_NF_SIGNED)				dnp->dn_value = (intmax_t)l <= (intmax_t)r;			else				dnp->dn_value = l <= r;			dt_node_type_assign(dnp,			    DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));			break;		case DT_TOK_GT:			dt_node_promote(lp, rp, dnp);			if (dnp->dn_flags & DT_NF_SIGNED)				dnp->dn_value = (intmax_t)l > (intmax_t)r;			else				dnp->dn_value = l > r;			dt_node_type_assign(dnp,			    DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));			break;		case DT_TOK_GE:			dt_node_promote(lp, rp, dnp);			if (dnp->dn_flags & DT_NF_SIGNED)				dnp->dn_value = (intmax_t)l >= (intmax_t)r;			else				dnp->dn_value = l >= r;			dt_node_type_assign(dnp,			    DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));			break;		case DT_TOK_LSH:			dnp->dn_value = l << r;			dt_node_type_propagate(lp, dnp);			dt_node_attr_assign(rp,			    dt_attr_min(lp->dn_attr, rp->dn_attr));			break;		case DT_TOK_RSH:			dnp->dn_value = l >> r;			dt_node_type_propagate(lp, dnp);			dt_node_attr_assign(rp,			    dt_attr_min(lp->dn_attr, rp->dn_attr));			break;		case DT_TOK_ADD:			dnp->dn_value = l + r;			dt_node_promote(lp, rp, dnp);			break;		case DT_TOK_SUB:			dnp->dn_value = l - r;			dt_node_promote(lp, rp, dnp);			break;		case DT_TOK_MUL:			dnp->dn_value = l * r;			dt_node_promote(lp, rp, dnp);			break;		case DT_TOK_DIV:			dt_node_promote(lp, rp, dnp);			if (dnp->dn_flags & DT_NF_SIGNED)				dnp->dn_value = (intmax_t)l / (intmax_t)r;			else				dnp->dn_value = l / r;			break;		case DT_TOK_MOD:			dt_node_promote(lp, rp, dnp);			if (dnp->dn_flags & DT_NF_SIGNED)				dnp->dn_value = (intmax_t)l % (intmax_t)r;			else				dnp->dn_value = l % r;			break;		default:			dt_node_free(dnp);			dnp = NULL;		}		if (dnp != NULL) {			dt_node_free(lp);			dt_node_free(rp);			return (dnp);		}	}	/*	 * If an integer constant is being cast to another integer type, we can	 * perform the cast as part of integer constant folding in this pass.	 * We must take action when the integer is being cast to a smaller type	 * or if it is changing signed-ness.  If so, we first shift rp's bits	 * bits high (losing excess bits if narrowing) and then shift them down	 * with either a logical shift (unsigned) or arithmetic shift (signed).	 */	if (op == DT_TOK_LPAR && rp->dn_kind == DT_NODE_INT &&	    dt_node_is_integer(lp)) {		size_t srcsize = dt_node_type_size(rp);		size_t dstsize = dt_node_type_size(lp);		if ((dstsize < srcsize) || ((lp->dn_flags & DT_NF_SIGNED) ^		    (rp->dn_flags & DT_NF_SIGNED))) {			int n = dstsize < srcsize ?			    (sizeof (uint64_t) * NBBY - dstsize * NBBY) :			    (sizeof (uint64_t) * NBBY - srcsize * NBBY);			rp->dn_value <<= n;			if (lp->dn_flags & DT_NF_SIGNED)				rp->dn_value = (intmax_t)rp->dn_value >> n;			else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -