Print this page
7085 add support for "if" and "else" statements in dtrace

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libdtrace/common/dt_cc.c
          +++ new/usr/src/lib/libdtrace/common/dt_cc.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
       24 + * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
  24   25   * Copyright (c) 2013, Joyent Inc. All rights reserved.
  25      - * Copyright (c) 2012 by Delphix. All rights reserved.
  26   26   * Copyright 2015 Gary Mills
  27   27   */
  28   28  
  29   29  /*
  30   30   * DTrace D Language Compiler
  31   31   *
  32   32   * The code in this source file implements the main engine for the D language
  33   33   * compiler.  The driver routine for the compiler is dt_compile(), below.  The
  34   34   * compiler operates on either stdio FILEs or in-memory strings as its input
  35   35   * and can produce either dtrace_prog_t structures from a D program or a single
↓ open down ↓ 76 lines elided ↑ open up ↑
 112  112          DIF_TYPE_CTF, CTF_K_INTEGER, 0, 0, 0
 113  113  };
 114  114  
 115  115  static const dtrace_diftype_t dt_int_rtype = {
 116  116          DIF_TYPE_CTF, CTF_K_INTEGER, 0, 0, sizeof (uint64_t)
 117  117  };
 118  118  
 119  119  static void *dt_compile(dtrace_hdl_t *, int, dtrace_probespec_t, void *,
 120  120      uint_t, int, char *const[], FILE *, const char *);
 121  121  
 122      -
 123  122  /*ARGSUSED*/
 124  123  static int
 125  124  dt_idreset(dt_idhash_t *dhp, dt_ident_t *idp, void *ignored)
 126  125  {
 127  126          idp->di_flags &= ~(DT_IDFLG_REF | DT_IDFLG_MOD |
 128  127              DT_IDFLG_DIFR | DT_IDFLG_DIFW);
 129  128          return (0);
 130  129  }
 131  130  
 132  131  /*ARGSUSED*/
↓ open down ↓ 2279 lines elided ↑ open up ↑
2412 2411          if (yypcb->pcb_pragmas != NULL)
2413 2412                  (void) dt_idhash_iter(yypcb->pcb_pragmas, dt_idpragma, NULL);
2414 2413  
2415 2414          if (argc > 1 && !(yypcb->pcb_cflags & DTRACE_C_ARGREF) &&
2416 2415              !(yypcb->pcb_sflagv[argc - 1] & DT_IDFLG_REF)) {
2417 2416                  xyerror(D_MACRO_UNUSED, "extraneous argument '%s' ($%d is "
2418 2417                      "not referenced)\n", yypcb->pcb_sargv[argc - 1], argc - 1);
2419 2418          }
2420 2419  
2421 2420          /*
     2421 +         * Perform sugar transformations (for "if" / "else") and replace the
     2422 +         * existing clause chain with the new one.
     2423 +         */
     2424 +        if (context == DT_CTX_DPROG) {
     2425 +                dt_node_t *dnp, *next_dnp;
     2426 +                dt_node_t *new_list = NULL;
     2427 +
     2428 +                for (dnp = yypcb->pcb_root->dn_list;
     2429 +                    dnp != NULL; dnp = next_dnp) {
     2430 +                        /* remove this node from the list */
     2431 +                        next_dnp = dnp->dn_list;
     2432 +                        dnp->dn_list = NULL;
     2433 +
     2434 +                        if (dnp->dn_kind == DT_NODE_CLAUSE)
     2435 +                                dnp = dt_compile_sugar(dtp, dnp);
     2436 +                        /* append node to the new list */
     2437 +                        new_list = dt_node_link(new_list, dnp);
     2438 +                }
     2439 +                yypcb->pcb_root->dn_list = new_list;
     2440 +        }
     2441 +
     2442 +        /*
2422 2443           * If we have successfully created a parse tree for a D program, loop
2423 2444           * over the clauses and actions and instantiate the corresponding
2424 2445           * libdtrace program.  If we are parsing a D expression, then we
2425 2446           * simply run the code generator and assembler on the resulting tree.
2426 2447           */
2427 2448          switch (context) {
2428 2449          case DT_CTX_DPROG:
2429 2450                  assert(yypcb->pcb_root->dn_kind == DT_NODE_PROG);
2430 2451  
2431 2452                  if ((dnp = yypcb->pcb_root->dn_list) == NULL &&
2432 2453                      !(yypcb->pcb_cflags & DTRACE_C_EMPTY))
2433 2454                          xyerror(D_EMPTY, "empty D program translation unit\n");
2434 2455  
2435 2456                  if ((yypcb->pcb_prog = dt_program_create(dtp)) == NULL)
2436 2457                          longjmp(yypcb->pcb_jmpbuf, dtrace_errno(dtp));
2437 2458  
2438 2459                  for (; dnp != NULL; dnp = dnp->dn_list) {
2439 2460                          switch (dnp->dn_kind) {
2440 2461                          case DT_NODE_CLAUSE:
     2462 +                                if (DT_TREEDUMP_PASS(dtp, 4))
     2463 +                                        dt_printd(dnp, stderr, 0);
2441 2464                                  dt_compile_clause(dtp, dnp);
2442 2465                                  break;
2443 2466                          case DT_NODE_XLATOR:
2444 2467                                  if (dtp->dt_xlatemode == DT_XL_DYNAMIC)
2445 2468                                          dt_compile_xlator(dnp);
2446 2469                                  break;
2447 2470                          case DT_NODE_PROVIDER:
2448 2471                                  (void) dt_node_cook(dnp, DT_IDFLG_REF);
2449 2472                                  break;
2450 2473                          }
↓ open down ↓ 82 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX