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

📄 dt_parser.c

📁 Sun Solaris 10 中的 DTrace 组件的源代码。请参看: http://www.sun.com/software/solaris/observability.jsp
💻 C
📖 第 1 页 / 共 5 页
字号:
				rp->dn_value = rp->dn_value >> n;		}		dt_node_type_propagate(lp, rp);		dt_node_attr_assign(rp, dt_attr_min(lp->dn_attr, rp->dn_attr));		dt_node_free(lp);		return (rp);	}	/*	 * If no immediate optimizations are available, create an new OP2 node	 * and glue the left and right children into place and return.	 */	dnp = dt_node_alloc(DT_NODE_OP2);	assert(op <= USHRT_MAX);	dnp->dn_op = (ushort_t)op;	dnp->dn_left = lp;	dnp->dn_right = rp;	return (dnp);}dt_node_t *dt_node_op3(dt_node_t *expr, dt_node_t *lp, dt_node_t *rp){	dt_node_t *dnp;	if (expr->dn_kind == DT_NODE_INT)		return (expr->dn_value != 0 ? lp : rp);	dnp = dt_node_alloc(DT_NODE_OP3);	dnp->dn_op = DT_TOK_QUESTION;	dnp->dn_expr = expr;	dnp->dn_left = lp;	dnp->dn_right = rp;	return (dnp);}dt_node_t *dt_node_statement(dt_node_t *expr){	dt_node_t *dnp;	if (expr->dn_kind == DT_NODE_AGG)		return (expr);	if (expr->dn_kind == DT_NODE_FUNC &&	    expr->dn_ident->di_kind == DT_IDENT_ACTFUNC)		dnp = dt_node_alloc(DT_NODE_DFUNC);	else		dnp = dt_node_alloc(DT_NODE_DEXPR);	dnp->dn_expr = expr;	return (dnp);}dt_node_t *dt_node_pdesc_by_name(char *spec){	dtrace_hdl_t *dtp = yypcb->pcb_hdl;	dt_node_t *dnp;	if (spec == NULL)		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);	dnp = dt_node_alloc(DT_NODE_PDESC);	dnp->dn_spec = spec;	dnp->dn_desc = malloc(sizeof (dtrace_probedesc_t));	if (dnp->dn_desc == NULL)		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);	if (dtrace_xstr2desc(dtp, yypcb->pcb_pspec, dnp->dn_spec,	    yypcb->pcb_sargc, yypcb->pcb_sargv, dnp->dn_desc) != 0) {		xyerror(D_PDESC_INVAL, "invalid probe description \"%s\": %s\n",		    dnp->dn_spec, dtrace_errmsg(dtp, dtrace_errno(dtp)));	}	free(dnp->dn_spec);	dnp->dn_spec = NULL;	return (dnp);}dt_node_t *dt_node_pdesc_by_id(uintmax_t id){	static const char *const names[] = {		"providers", "modules", "functions"	};	dtrace_hdl_t *dtp = yypcb->pcb_hdl;	dt_node_t *dnp = dt_node_alloc(DT_NODE_PDESC);	if ((dnp->dn_desc = malloc(sizeof (dtrace_probedesc_t))) == NULL)		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);	if (id > UINT_MAX) {		xyerror(D_PDESC_INVAL, "identifier %llu exceeds maximum "		    "probe id\n", (u_longlong_t)id);	}	if (yypcb->pcb_pspec != DTRACE_PROBESPEC_NAME) {		xyerror(D_PDESC_INVAL, "probe identifier %llu not permitted "		    "when specifying %s\n", (u_longlong_t)id,		    names[yypcb->pcb_pspec]);	}	if (dtrace_id2desc(dtp, (dtrace_id_t)id, dnp->dn_desc) != 0) {		xyerror(D_PDESC_INVAL, "invalid probe identifier %llu: %s\n",		    (u_longlong_t)id, dtrace_errmsg(dtp, dtrace_errno(dtp)));	}	return (dnp);}dt_node_t *dt_node_clause(dt_node_t *pdescs, dt_node_t *pred, dt_node_t *acts){	dt_node_t *dnp = dt_node_alloc(DT_NODE_CLAUSE);	dnp->dn_pdescs = pdescs;	dnp->dn_pred = pred;	dnp->dn_acts = acts;	yybegin(YYS_CLAUSE);	return (dnp);}dt_node_t *dt_node_inline(dt_decl_t *ddp, char *name, dt_node_t *expr){	dtrace_hdl_t *dtp = yypcb->pcb_hdl;	dtrace_typeinfo_t dtt;	dtrace_attribute_t attr;	int err;	dt_idnode_t *inp;	dt_ident_t *idp;	dt_node_t *dnp;	err = dt_decl_type(ddp, &dtt);	dt_decl_free(ddp);	if (err != 0)		longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);	/*	 * Unlike most constructors, we need to explicitly cook the right-hand	 * side of the inline definition immediately to prevent recursion.  If	 * the right-hand side uses the inline itself, the cook will fail.	 */	expr = dt_node_cook(expr, DT_IDFLG_REF);	attr = dt_attr_min(_dtrace_defattr, expr->dn_attr);	if ((idp = dt_idhash_lookup(dtp->dt_globals, name)) != NULL) {		free(name);		xyerror(D_DECL_IDRED, "identifier redefined: %s\n\t current: "		    "inline definition\n\tprevious: %s %s\n",		    idp->di_name, dt_idkind_name(idp->di_kind),		    (idp->di_flags & DT_IDFLG_INLINE) ? "inline" : "");	}	dt_dprintf("create inline definition %s\n", name);	idp = dt_idhash_insert(dtp->dt_globals, name, DT_IDENT_SCALAR,	    DT_IDFLG_INLINE | DT_IDFLG_REF, 0, attr, 0,	    &dt_idops_inline, NULL, dtp->dt_gen);	free(name);	if (idp == NULL)		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);	if ((inp = malloc(sizeof (dt_idnode_t))) == NULL)		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);	inp->din_list = yypcb->pcb_list;	inp->din_root = expr;	yybegin(YYS_CLAUSE);	idp->di_data = inp;	if (dt_node_is_dynamic(expr)) {		dt_ident_t *rdp = dt_ident_resolve(expr->dn_ident);		idp->di_kind = rdp->di_kind;		idp->di_flags |= (rdp->di_flags &		    (DT_IDFLG_WRITE | DT_IDFLG_USER | DT_IDFLG_PRIM));		idp->di_ctfp = expr->dn_ctfp;		idp->di_type = expr->dn_type;	} else {		if (expr->dn_kind == DT_NODE_VAR ||		    expr->dn_kind == DT_NODE_SYM) {			idp->di_flags |= (expr->dn_ident->di_flags &			    (DT_IDFLG_WRITE | DT_IDFLG_USER | DT_IDFLG_PRIM));		}		idp->di_ctfp = dtt.dtt_ctfp;		idp->di_type = dtt.dtt_type;	}	dnp = dt_node_alloc(DT_NODE_INLINE);	dnp->dn_ident = idp;	dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type);	dt_node_attr_assign(dnp, _dtrace_defattr);	dnp->dn_flags &= ~DT_NF_COOKED;	return (dt_node_cook(dnp, DT_IDFLG_REF));}dt_node_t *dt_node_member(dt_decl_t *ddp, char *name, dt_node_t *expr){	dtrace_typeinfo_t dtt;	dt_node_t *dnp;	int err;	if (ddp != NULL) {		err = dt_decl_type(ddp, &dtt);		dt_decl_free(ddp);		if (err != 0)			longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);	}	dnp = dt_node_alloc(DT_NODE_MEMBER);	dnp->dn_membname = name;	dnp->dn_membexpr = expr;	if (ddp != NULL)		dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type);	return (dnp);}dt_node_t *dt_node_xlator(dt_decl_t *ddp, dt_decl_t *sdp, char *name, dt_node_t *members){	dtrace_hdl_t *dtp = yypcb->pcb_hdl;	dtrace_typeinfo_t src, dst;	dt_node_t sn, dn;	dt_xlator_t *dxp;	dt_node_t *dnp;	int edst, esrc;	char n1[DT_TYPE_NAMELEN];	char n2[DT_TYPE_NAMELEN];	edst = dt_decl_type(ddp, &dst);	dt_decl_free(ddp);	esrc = dt_decl_type(sdp, &src);	dt_decl_free(sdp);	if (edst != 0 || esrc != 0) {		free(name);		longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);	}	bzero(&sn, sizeof (sn));	dt_node_type_assign(&sn, src.dtt_ctfp, src.dtt_type);	bzero(&dn, sizeof (dn));	dt_node_type_assign(&dn, dst.dtt_ctfp, dst.dtt_type);	if (dt_xlator_lookup(dtp, &sn, &dn, DT_XLATE_EXACT) != NULL) {		xyerror(D_XLATE_REDECL,		    "translator from %s to %s has already been declared\n",		    dt_node_type_name(&sn, n1, sizeof (n1)),		    dt_node_type_name(&dn, n2, sizeof (n2)));	}	dxp = dt_xlator_create(dtp, &src, &dst, name, members, yypcb->pcb_list);	yybegin(YYS_CLAUSE);	free(name);	if (dxp == NULL)		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);	dnp = dt_node_alloc(DT_NODE_XLATOR);	dnp->dn_xlator = dxp;	dnp->dn_members = members;	return (dt_node_cook(dnp, DT_IDFLG_REF));}/* * Examine the list of formal parameters 'flist' and determine if the formal * name fnp->dn_string is defined in this list (B_TRUE) or not (B_FALSE). * If 'fnp' is in 'flist', do not search beyond 'fnp' itself in 'flist'. */static intdt_node_probe_protoform(dt_node_t *fnp, dt_node_t *flist){	dt_node_t *dnp;	for (dnp = flist; dnp != fnp && dnp != NULL; dnp = dnp->dn_list) {		if (dnp->dn_string != NULL &&		    strcmp(dnp->dn_string, fnp->dn_string) == 0)			return (B_TRUE);	}	return (B_FALSE);}/* * Common code for parsing a probe definition's prototype 'plist', of which * there can be two: one for native arguments at the probe site and one for * translated arguments presented to DTrace consumers.  If 'defined' is TRUE, * we demand that every formal parameter have a name and be present in 'flist'. * If 'defined' is false, we require that named parameters not be in 'flist'. */static intdt_node_probe_prototype(const char *pname, const char *desc,    dt_node_t *plist, dt_node_t *flist, int defined){	char n[DT_TYPE_NAMELEN];	dt_node_t *dnp;	int i = 0, v = 0;	for (dnp = plist; dnp != NULL; dnp = dnp->dn_list, i++) {		if (dt_node_is_dynamic(dnp)) {			xyerror(D_DECL_FUNCTYPE, "%s type may not be "			    "used in probe %s %s prototype: param #%d\n",			    dt_node_type_name(dnp, n, sizeof (n)),			    pname, desc, i + 1);		}		if (dnp->dn_type == CTF_ERR) {			xyerror(D_DECL_FUNCTYPE, "probe %s %s prototype may "			    "not use variable argument list\n", pname, desc);		}		if (dnp->dn_string != NULL &&		    dt_node_probe_protoform(dnp, flist) != defined) {			xyerror(D_DECL_PARMNAME, "formal parameter %s is %s "			    "defined in probe %s %s prototype: param #%d\n",			    dnp->dn_string, defined ? "not" : "already",			    pname, desc, i + 1);		}		if (dt_node_is_void(dnp))			v++; /* count number of void parameters for below */		else if (dnp->dn_string == NULL && defined == B_TRUE) {			xyerror(D_DECL_PARMNAME, "probe %s formal %s "			    "parameter lacks name: param #%d\n",			    pname, desc, i + 1);		}	}	if (v != 0 && plist->dn_list != NULL) {		xyerror(D_DECL_FUNCVOID, "void must be sole parameter in "		    "probe %s %s prototype\n", pname, desc);	}	if (i > UINT8_MAX) {		xyerror(D_PROV_PRARGLEN, "probe %s %s prototype exceeds %u "		    "parameters: %d params used\n", pname, desc, UINT8_MAX, i);	}	return (v ? 0 : i); /* return zero if sole parameter is 'void' */}dt_node_t *dt_node_probe(char *s, dt_node_t *nargs, dt_node_t *xargs){	dtrace_hdl_t *dtp = yypcb->pcb_hdl;	int nargc, xargc;	dt_node_t *dnp;	char *name;	name = alloca(strlen(s) + 1);	(void) strcpy(name, s);	(void) strhyphenate(name);	free(s);	if (strchr(name, '`') != NULL) {		xyerror(D_PROV_BADNAME, "probe name may not "		    "contain scoping operator: %s\n", name);	}	if (strlen(name) >= DTRACE_NAMELEN) {		xyerror(D_PROV_BADNAME, "probe name may not exceed %d "		    "characters: %s\n", DTRACE_NAMELEN - 1, name);	}	dnp = dt_node_alloc(DT_NODE_PROBE);	dnp->dn_ident = dt_ident_create(name, DT_IDENT_PROBE, 0, 0,	    _dtrace_defattr, 0, &dt_idops_probe, (void *)CTF_ERR, dtp->dt_gen);	nargc = dt_node_probe_prototype(name, "input", nargs, nargs, B_FALSE);	xargc = dt_node_probe_prototype(name, "output", xargs, nargs, B_TRUE);	if (dnp->dn_ident == NULL || (dnp->dn_ident->di_data =	    dt_probe_create(dnp->dn_ident, nargs, nargc, xargs, xargc)) == NULL)		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);	return (dnp);}dt_node_t *dt_node_provider(char *name, dt_node_t *probes){	dtrace_hdl_t *dtp = yypcb->pcb_hdl;	dt_node_t *dnp, *pnp;	dt_provider_t *pvp;	dnp = dt_node_alloc(DT_NODE_PROVIDER);	dnp->dn_string = name;	dnp->dn_list = probes;	if (!(dtp->dt_cflags & DTRACE_C_PRDEFS))		dnerror(dnp, D_PROV_NODEFS, "unexpected provider definition\n");	if (dt_provider_lookup(dtp, name) != NULL)		dnerror(dnp, D_PROV_EXISTS, "provider redeclared: %s\n", name);	if (strchr(name, '`') != NULL) {		dnerror(dnp, D_PROV_BADNAME, "provider name may not "		    "contain scoping operator: %s\n", name);	}	if (strlen(name) >= DTRACE_PROVNAMELEN) {		dnerror(dnp, D_PROV_BADNAME, "provider name may not exceed %d "		    "characters: %s\n", DTRACE_PROVNAMELEN - 1, name);	}	if ((pvp = dt_provider_create(dtp, dnp->dn_string)) == NULL)		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);	/*	 * Store all parse nodes created since we consumed the DT_KEY_PROVIDER	 * token with the provider and then restore our lexing state to CLAUSE.	 */	pvp->pv_nodes = yypcb->pcb_list;	yybegin(YYS_CLAUSE);	for (pnp = probes; pnp != NULL; pnp = pnp->dn_list) {		if (dt_idhash_lookup(pvp->pv_probes, pnp->dn_ident->di_name)) {			dnerror(pnp, D_PROV_PREXISTS,			    "probe redeclared: %s\n", pnp->dn_ident->di_name);		}		dt_idhash_xinsert(pvp->pv_probes, pnp->dn_ident);		pnp->dn_ident = NULL; /* ident is now in idhash */	}	return (dt_node_cook(dnp, DT_IDFLG_REF));}dt_node_t *dt_node_program(dt_node_t *lnp){	dt_node_t *dnp = dt_node_alloc(DT_NODE_PROG);	dnp->dn_list = lnp;	return (dnp);}/* * This function provides the underlying implementation of cooking an * identifier given its node, a hash of dynamic identifiers, an identifier * kind, and a boolean flag indicating whether we are allowed to instantiate * a new identifier if the string is not found.  This function is either * called from dt_cook_ident(), below, or directly by the various cooking * routines that are allowed to instantiate identifiers (e.g. op2 TOK_ASGN). */static voiddt_xcook_i

⌨️ 快捷键说明

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