/[jscoverage]/trunk/instrument-js.cpp
ViewVC logotype

Diff of /trunk/instrument-js.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 375 by siliconforks, Tue Oct 28 05:30:01 2008 UTC revision 392 by siliconforks, Thu Oct 30 17:54:24 2008 UTC
# Line 22  Line 22 
22  #include "instrument-js.h"  #include "instrument-js.h"
23    
24  #include <assert.h>  #include <assert.h>
25    #include <math.h>
26  #include <stdlib.h>  #include <stdlib.h>
27  #include <string.h>  #include <string.h>
28    
# Line 267  Line 268 
268    }    }
269  }  }
270    
271  static void instrument_expression(JSParseNode * node, Stream * f);  static void output_expression(JSParseNode * node, Stream * f, bool parenthesize_object_literals);
272  static void instrument_statement(JSParseNode * node, Stream * f, int indent, bool is_jscoverage_if);  static void instrument_statement(JSParseNode * node, Stream * f, int indent, bool is_jscoverage_if);
273  static void output_statement(JSParseNode * node, Stream * f, int indent, bool is_jscoverage_if);  static void output_statement(JSParseNode * node, Stream * f, int indent, bool is_jscoverage_if);
274    
# Line 284  Line 285 
285      Stream_write_string(f, "each ");      Stream_write_string(f, "each ");
286    }    }
287    Stream_write_char(f, '(');    Stream_write_char(f, '(');
288    instrument_expression(node->pn_left, f);    output_expression(node->pn_left, f, false);
289    Stream_write_char(f, ')');    Stream_write_char(f, ')');
290  }  }
291    
# Line 311  Line 312 
312      p = p->pn_kid;      p = p->pn_kid;
313    }    }
314    
315    instrument_expression(p, f);    output_expression(p, f, false);
316    p = for_node;    p = for_node;
317    while (p->pn_type == TOK_FOR) {    while (p->pn_type == TOK_FOR) {
318      Stream_write_char(f, ' ');      Stream_write_char(f, ' ');
# Line 320  Line 321 
321    }    }
322    if (if_node) {    if (if_node) {
323      Stream_write_string(f, " if (");      Stream_write_string(f, " if (");
324      instrument_expression(if_node->pn_kid1, f);      output_expression(if_node->pn_kid1, f, false);
325      Stream_write_char(f, ')');      Stream_write_char(f, ')');
326    }    }
327  }  }
# Line 381  Line 382 
382          }          }
383        }        }
384        assert(expression != NULL);        assert(expression != NULL);
385        instrument_expression(expression, f);        output_expression(expression, f, false);
386      }      }
387      else {      else {
388        print_string_atom(param, f);        print_string_atom(param, f);
# Line 414  Line 415 
415      }      }
416    }    }
417    
418    Stream_write_string(f, "}\n");    Stream_write_char(f, '}');
419  }  }
420    
421  static void instrument_function_call(JSParseNode * node, Stream * f) {  static void instrument_function_call(JSParseNode * node, Stream * f) {
# Line 433  Line 434 
434        Stream_write_char(f, ')');        Stream_write_char(f, ')');
435        return;        return;
436      }      }
     else {  
       Stream_write_char(f, '(');  
       instrument_expression(function_node, f);  
       Stream_write_char(f, ')');  
     }  
   }  
   else {  
     instrument_expression(function_node, f);  
437    }    }
438      output_expression(function_node, f, false);
439    Stream_write_char(f, '(');    Stream_write_char(f, '(');
440    for (struct JSParseNode * p = function_node->pn_next; p != NULL; p = p->pn_next) {    for (struct JSParseNode * p = function_node->pn_next; p != NULL; p = p->pn_next) {
441      if (p != node->pn_head->pn_next) {      if (p != node->pn_head->pn_next) {
442        Stream_write_string(f, ", ");        Stream_write_string(f, ", ");
443      }      }
444      instrument_expression(p, f);      output_expression(p, f, false);
445    }    }
446    Stream_write_char(f, ')');    Stream_write_char(f, ')');
447  }  }
# Line 455  Line 449 
449  static void instrument_declarations(JSParseNode * list, Stream * f) {  static void instrument_declarations(JSParseNode * list, Stream * f) {
450    assert(list->pn_arity == PN_LIST);    assert(list->pn_arity == PN_LIST);
451    for (JSParseNode * p = list->pn_head; p != NULL; p = p->pn_next) {    for (JSParseNode * p = list->pn_head; p != NULL; p = p->pn_next) {
452      switch (p->pn_type) {      if (p != list->pn_head) {
453      case TOK_NAME:        Stream_write_string(f, ", ");
       assert(p->pn_arity == PN_NAME);  
       if (p != list->pn_head) {  
         Stream_write_string(f, ", ");  
       }  
       print_string_atom(p->pn_atom, f);  
       if (p->pn_expr != NULL) {  
         Stream_write_string(f, " = ");  
         instrument_expression(p->pn_expr, f);  
       }  
       break;  
     case TOK_ASSIGN:  
       /* destructuring */  
       instrument_expression(p->pn_left, f);  
       Stream_write_string(f, " = ");  
       instrument_expression(p->pn_right, f);  
       break;  
     case TOK_RB:  
     case TOK_RC:  
       /* destructuring */  
       instrument_expression(p, f);  
       break;  
     default:  
       abort();  
       break;  
454      }      }
455        output_expression(p, f, false);
456    }    }
457  }  }
458    
# Line 498  Line 469 
469  TOK_INSTANCEOF  binary  TOK_INSTANCEOF  binary
470  TOK_IN          binary  TOK_IN          binary
471  */  */
472  static void instrument_expression(JSParseNode * node, Stream * f) {  static void output_expression(JSParseNode * node, Stream * f, bool parenthesize_object_literals) {
473    switch (node->pn_type) {    switch (node->pn_type) {
474    case TOK_FUNCTION:    case TOK_FUNCTION:
475        Stream_write_char(f, '(');
476      instrument_function(node, f, 0, FUNCTION_NORMAL);      instrument_function(node, f, 0, FUNCTION_NORMAL);
477        Stream_write_char(f, ')');
478      break;      break;
479    case TOK_COMMA:    case TOK_COMMA:
480      for (struct JSParseNode * p = node->pn_head; p != NULL; p = p->pn_next) {      for (struct JSParseNode * p = node->pn_head; p != NULL; p = p->pn_next) {
481        if (p != node->pn_head) {        if (p != node->pn_head) {
482          Stream_write_string(f, ", ");          Stream_write_string(f, ", ");
483        }        }
484        instrument_expression(p, f);        output_expression(p, f, parenthesize_object_literals);
485      }      }
486      break;      break;
487    case TOK_ASSIGN:    case TOK_ASSIGN:
488      if (node->pn_left->pn_type == TOK_RC) {      output_expression(node->pn_left, f, parenthesize_object_literals);
       /* destructuring assignment with object literal must be in parentheses */  
       Stream_write_char(f, '(');  
       instrument_expression(node->pn_left, f);  
       Stream_write_char(f, ')');  
     }  
     else {  
       instrument_expression(node->pn_left, f);  
     }  
489      Stream_write_char(f, ' ');      Stream_write_char(f, ' ');
490      switch (node->pn_op) {      switch (node->pn_op) {
491      case JSOP_ADD:      case JSOP_ADD:
# Line 541  Line 506 
506        break;        break;
507      }      }
508      Stream_write_string(f, "= ");      Stream_write_string(f, "= ");
509      instrument_expression(node->pn_right, f);      output_expression(node->pn_right, f, false);
510      break;      break;
511    case TOK_HOOK:    case TOK_HOOK:
512      instrument_expression(node->pn_kid1, f);      output_expression(node->pn_kid1, f, parenthesize_object_literals);
513      Stream_write_string(f, "? ");      Stream_write_string(f, "? ");
514      instrument_expression(node->pn_kid2, f);      output_expression(node->pn_kid2, f, false);
515      Stream_write_string(f, ": ");      Stream_write_string(f, ": ");
516      instrument_expression(node->pn_kid3, f);      output_expression(node->pn_kid3, f, false);
517      break;      break;
518    case TOK_OR:    case TOK_OR:
519    case TOK_AND:    case TOK_AND:
# Line 564  Line 529 
529    case TOK_DIVOP:    case TOK_DIVOP:
530      switch (node->pn_arity) {      switch (node->pn_arity) {
531      case PN_BINARY:      case PN_BINARY:
532        instrument_expression(node->pn_left, f);        output_expression(node->pn_left, f, parenthesize_object_literals);
533        Stream_printf(f, " %s ", get_op(node->pn_op));        Stream_printf(f, " %s ", get_op(node->pn_op));
534        instrument_expression(node->pn_right, f);        output_expression(node->pn_right, f, false);
535        break;        break;
536      case PN_LIST:      case PN_LIST:
537        for (struct JSParseNode * p = node->pn_head; p != NULL; p = p->pn_next) {        for (struct JSParseNode * p = node->pn_head; p != NULL; p = p->pn_next) {
538          if (p != node->pn_head) {          if (p == node->pn_head) {
539              output_expression(p, f, parenthesize_object_literals);
540            }
541            else {
542            Stream_printf(f, " %s ", get_op(node->pn_op));            Stream_printf(f, " %s ", get_op(node->pn_op));
543              output_expression(p, f, false);
544          }          }
         instrument_expression(p, f);  
545        }        }
546        break;        break;
547      default:      default:
# Line 583  Line 551 
551    case TOK_UNARYOP:    case TOK_UNARYOP:
552      switch (node->pn_op) {      switch (node->pn_op) {
553      case JSOP_NEG:      case JSOP_NEG:
554        Stream_write_char(f, '-');        Stream_write_string(f, "- ");
555        instrument_expression(node->pn_kid, f);        output_expression(node->pn_kid, f, false);
556        break;        break;
557      case JSOP_POS:      case JSOP_POS:
558        Stream_write_char(f, '+');        Stream_write_string(f, "+ ");
559        instrument_expression(node->pn_kid, f);        output_expression(node->pn_kid, f, false);
560        break;        break;
561      case JSOP_NOT:      case JSOP_NOT:
562        Stream_write_char(f, '!');        Stream_write_string(f, "! ");
563        instrument_expression(node->pn_kid, f);        output_expression(node->pn_kid, f, false);
564        break;        break;
565      case JSOP_BITNOT:      case JSOP_BITNOT:
566        Stream_write_char(f, '~');        Stream_write_string(f, "~ ");
567        instrument_expression(node->pn_kid, f);        output_expression(node->pn_kid, f, false);
568        break;        break;
569      case JSOP_TYPEOF:      case JSOP_TYPEOF:
570        Stream_write_string(f, "typeof ");        Stream_write_string(f, "typeof ");
571        instrument_expression(node->pn_kid, f);        output_expression(node->pn_kid, f, false);
572        break;        break;
573      case JSOP_VOID:      case JSOP_VOID:
574        Stream_write_string(f, "void ");        Stream_write_string(f, "void ");
575        instrument_expression(node->pn_kid, f);        output_expression(node->pn_kid, f, false);
576        break;        break;
577      default:      default:
578        fatal_source(file_id, node->pn_pos.begin.lineno, "unknown operator (%d)", node->pn_op);        fatal_source(file_id, node->pn_pos.begin.lineno, "unknown operator (%d)", node->pn_op);
# Line 621  Line 589 
589      case JSOP_INCPROP:      case JSOP_INCPROP:
590      case JSOP_INCELEM:      case JSOP_INCELEM:
591        Stream_write_string(f, "++");        Stream_write_string(f, "++");
592        instrument_expression(node->pn_kid, f);        output_expression(node->pn_kid, f, false);
593        break;        break;
594      case JSOP_DECNAME:      case JSOP_DECNAME:
595      case JSOP_DECPROP:      case JSOP_DECPROP:
596      case JSOP_DECELEM:      case JSOP_DECELEM:
597        Stream_write_string(f, "--");        Stream_write_string(f, "--");
598        instrument_expression(node->pn_kid, f);        output_expression(node->pn_kid, f, false);
599        break;        break;
600      case JSOP_NAMEINC:      case JSOP_NAMEINC:
601      case JSOP_PROPINC:      case JSOP_PROPINC:
602      case JSOP_ELEMINC:      case JSOP_ELEMINC:
603        instrument_expression(node->pn_kid, f);        output_expression(node->pn_kid, f, parenthesize_object_literals);
604        Stream_write_string(f, "++");        Stream_write_string(f, "++");
605        break;        break;
606      case JSOP_NAMEDEC:      case JSOP_NAMEDEC:
607      case JSOP_PROPDEC:      case JSOP_PROPDEC:
608      case JSOP_ELEMDEC:      case JSOP_ELEMDEC:
609        instrument_expression(node->pn_kid, f);        output_expression(node->pn_kid, f, parenthesize_object_literals);
610        Stream_write_string(f, "--");        Stream_write_string(f, "--");
611        break;        break;
612      default:      default:
# Line 652  Line 620 
620      break;      break;
621    case TOK_DELETE:    case TOK_DELETE:
622      Stream_write_string(f, "delete ");      Stream_write_string(f, "delete ");
623      instrument_expression(node->pn_kid, f);      output_expression(node->pn_kid, f, false);
624      break;      break;
625    case TOK_DOT:    case TOK_DOT:
626      /* numeric literals must be parenthesized */      /* numeric literals must be parenthesized */
627      if (node->pn_expr->pn_type == TOK_NUMBER) {      switch (node->pn_expr->pn_type) {
628        case TOK_NUMBER:
629        Stream_write_char(f, '(');        Stream_write_char(f, '(');
630        instrument_expression(node->pn_expr, f);        output_expression(node->pn_expr, f, false);
631        Stream_write_char(f, ')');        Stream_write_char(f, ')');
632      }        break;
633      else {      default:
634        instrument_expression(node->pn_expr, f);        output_expression(node->pn_expr, f, true);
635          break;
636      }      }
637      /*      /*
638      This may have originally been x['foo-bar'].  Because the string 'foo-bar'      This may have originally been x['foo-bar'].  Because the string 'foo-bar'
# Line 697  Line 667 
667      }      }
668      break;      break;
669    case TOK_LB:    case TOK_LB:
670      instrument_expression(node->pn_left, f);      output_expression(node->pn_left, f, false);
671      Stream_write_char(f, '[');      Stream_write_char(f, '[');
672      instrument_expression(node->pn_right, f);      output_expression(node->pn_right, f, false);
673      Stream_write_char(f, ']');      Stream_write_char(f, ']');
674      break;      break;
675    case TOK_LP:    case TOK_LP:
# Line 713  Line 683 
683        }        }
684        /* TOK_COMMA is a special case: a hole in the array */        /* TOK_COMMA is a special case: a hole in the array */
685        if (p->pn_type != TOK_COMMA) {        if (p->pn_type != TOK_COMMA) {
686          instrument_expression(p, f);          output_expression(p, f, false);
687        }        }
688      }      }
689      if (node->pn_extra == PNX_ENDCOMMA) {      if (node->pn_extra == PNX_ENDCOMMA) {
# Line 722  Line 692 
692      Stream_write_char(f, ']');      Stream_write_char(f, ']');
693      break;      break;
694    case TOK_RC:    case TOK_RC:
695        if (parenthesize_object_literals) {
696          Stream_write_char(f, '(');
697        }
698      Stream_write_char(f, '{');      Stream_write_char(f, '{');
699      for (struct JSParseNode * p = node->pn_head; p != NULL; p = p->pn_next) {      for (struct JSParseNode * p = node->pn_head; p != NULL; p = p->pn_next) {
700        if (p->pn_type != TOK_COLON) {        if (p->pn_type != TOK_COLON) {
# Line 741  Line 714 
714          else {          else {
715            Stream_write_string(f, "set ");            Stream_write_string(f, "set ");
716          }          }
717          instrument_expression(p->pn_left, f);          output_expression(p->pn_left, f, false);
718            Stream_write_char(f, ' ');
719          if (p->pn_right->pn_type != TOK_FUNCTION) {          if (p->pn_right->pn_type != TOK_FUNCTION) {
720            fatal_source(file_id, p->pn_pos.begin.lineno, "expected function");            fatal_source(file_id, p->pn_pos.begin.lineno, "expected function");
721          }          }
722          instrument_function(p->pn_right, f, 0, FUNCTION_GETTER_OR_SETTER);          instrument_function(p->pn_right, f, 0, FUNCTION_GETTER_OR_SETTER);
723          break;          break;
724        default:        default:
725          instrument_expression(p->pn_left, f);          output_expression(p->pn_left, f, false);
726          Stream_write_string(f, ": ");          Stream_write_string(f, ": ");
727          instrument_expression(p->pn_right, f);          output_expression(p->pn_right, f, false);
728          break;          break;
729        }        }
730      }      }
731      Stream_write_char(f, '}');      Stream_write_char(f, '}');
732        if (parenthesize_object_literals) {
733          Stream_write_char(f, ')');
734        }
735      break;      break;
736    case TOK_RP:    case TOK_RP:
737      Stream_write_char(f, '(');      Stream_write_char(f, '(');
738      instrument_expression(node->pn_kid, f);      output_expression(node->pn_kid, f, false);
739      Stream_write_char(f, ')');      Stream_write_char(f, ')');
740      break;      break;
741    case TOK_NAME:    case TOK_NAME:
742      print_string_atom(node->pn_atom, f);      print_string_atom(node->pn_atom, f);
743        if (node->pn_expr != NULL) {
744          Stream_write_string(f, " = ");
745          output_expression(node->pn_expr, f, false);
746        }
747      break;      break;
748    case TOK_STRING:    case TOK_STRING:
749      print_quoted_string_atom(node->pn_atom, f);      print_quoted_string_atom(node->pn_atom, f);
# Line 784  Line 765 
765      To keep the output simple, special-case zero.      To keep the output simple, special-case zero.
766      */      */
767      if (node->pn_dval == 0.0) {      if (node->pn_dval == 0.0) {
768        Stream_write_string(f, "0");        if (signbit(node->pn_dval)) {
769            Stream_write_string(f, "-0");
770          }
771          else {
772            Stream_write_string(f, "0");
773          }
774        }
775        else if (node->pn_dval == INFINITY) {
776          Stream_write_string(f, "Number.POSITIVE_INFINITY");
777        }
778        else if (node->pn_dval == -INFINITY) {
779          Stream_write_string(f, "Number.NEGATIVE_INFINITY");
780        }
781        else if (isnan(node->pn_dval)) {
782          Stream_write_string(f, "Number.NaN");
783      }      }
784      else {      else {
785        Stream_printf(f, "%.15g", node->pn_dval);        Stream_printf(f, "%.15g", node->pn_dval);
# Line 810  Line 805 
805      }      }
806      break;      break;
807    case TOK_INSTANCEOF:    case TOK_INSTANCEOF:
808      instrument_expression(node->pn_left, f);      output_expression(node->pn_left, f, parenthesize_object_literals);
809      Stream_write_string(f, " instanceof ");      Stream_write_string(f, " instanceof ");
810      instrument_expression(node->pn_right, f);      output_expression(node->pn_right, f, false);
811      break;      break;
812    case TOK_IN:    case TOK_IN:
813      instrument_expression(node->pn_left, f);      output_expression(node->pn_left, f, false);
814      Stream_write_string(f, " in ");      Stream_write_string(f, " in ");
815      instrument_expression(node->pn_right, f);      output_expression(node->pn_right, f, false);
816      break;      break;
817    case TOK_LEXICALSCOPE:    case TOK_LEXICALSCOPE:
818      assert(node->pn_arity == PN_NAME);      assert(node->pn_arity == PN_NAME);
# Line 828  Line 823 
823      assert(node->pn_expr->pn_left->pn_arity == PN_LIST);      assert(node->pn_expr->pn_left->pn_arity == PN_LIST);
824      instrument_declarations(node->pn_expr->pn_left, f);      instrument_declarations(node->pn_expr->pn_left, f);
825      Stream_write_string(f, ") ");      Stream_write_string(f, ") ");
826      instrument_expression(node->pn_expr->pn_right, f);      output_expression(node->pn_expr->pn_right, f, true);
827      break;      break;
828    case TOK_YIELD:    case TOK_YIELD:
829      assert(node->pn_arity == PN_UNARY);      assert(node->pn_arity == PN_UNARY);
830      Stream_write_string(f, "yield");      Stream_write_string(f, "yield");
831      if (node->pn_kid != NULL) {      if (node->pn_kid != NULL) {
832        Stream_write_char(f, ' ');        Stream_write_char(f, ' ');
833        instrument_expression(node->pn_kid, f);        output_expression(node->pn_kid, f, true);
834      }      }
835      break;      break;
836    case TOK_ARRAYCOMP:    case TOK_ARRAYCOMP:
# Line 877  Line 872 
872    switch (node->pn_type) {    switch (node->pn_type) {
873    case TOK_FUNCTION:    case TOK_FUNCTION:
874      instrument_function(node, f, indent, FUNCTION_NORMAL);      instrument_function(node, f, indent, FUNCTION_NORMAL);
875        Stream_write_char(f, '\n');
876      break;      break;
877    case TOK_LC:    case TOK_LC:
878      assert(node->pn_arity == PN_LIST);      assert(node->pn_arity == PN_LIST);
# Line 907  Line 903 
903    
904      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
905      Stream_write_string(f, "if (");      Stream_write_string(f, "if (");
906      instrument_expression(node->pn_kid1, f);      output_expression(node->pn_kid1, f, false);
907      Stream_write_string(f, ") {\n");      Stream_write_string(f, ") {\n");
908      if (is_jscoverage_if && node->pn_kid3) {      if (is_jscoverage_if && node->pn_kid3) {
909        uint16_t else_start = node->pn_kid3->pn_pos.begin.lineno;        uint16_t else_start = node->pn_kid3->pn_pos.begin.lineno;
# Line 944  Line 940 
940      assert(node->pn_arity == PN_BINARY);      assert(node->pn_arity == PN_BINARY);
941      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
942      Stream_write_string(f, "switch (");      Stream_write_string(f, "switch (");
943      instrument_expression(node->pn_left, f);      output_expression(node->pn_left, f, false);
944      Stream_write_string(f, ") {\n");      Stream_write_string(f, ") {\n");
945      {      {
946        JSParseNode * list = node->pn_right;        JSParseNode * list = node->pn_right;
# Line 956  Line 952 
952          switch (p->pn_type) {          switch (p->pn_type) {
953          case TOK_CASE:          case TOK_CASE:
954            Stream_write_string(f, "case ");            Stream_write_string(f, "case ");
955            instrument_expression(p->pn_left, f);            output_expression(p->pn_left, f, false);
956            Stream_write_string(f, ":\n");            Stream_write_string(f, ":\n");
957            break;            break;
958          case TOK_DEFAULT:          case TOK_DEFAULT:
# Line 980  Line 976 
976      assert(node->pn_arity == PN_BINARY);      assert(node->pn_arity == PN_BINARY);
977      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
978      Stream_write_string(f, "while (");      Stream_write_string(f, "while (");
979      instrument_expression(node->pn_left, f);      output_expression(node->pn_left, f, false);
980      Stream_write_string(f, ") {\n");      Stream_write_string(f, ") {\n");
981      instrument_statement(node->pn_right, f, indent + 2, false);      instrument_statement(node->pn_right, f, indent + 2, false);
982      Stream_write_string(f, "}\n");      Stream_write_string(f, "}\n");
# Line 993  Line 989 
989      Stream_write_string(f, "}\n");      Stream_write_string(f, "}\n");
990      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
991      Stream_write_string(f, "while (");      Stream_write_string(f, "while (");
992      instrument_expression(node->pn_right, f);      output_expression(node->pn_right, f, false);
993      Stream_write_string(f, ");\n");      Stream_write_string(f, ");\n");
994      break;      break;
995    case TOK_FOR:    case TOK_FOR:
# Line 1010  Line 1006 
1006        assert(node->pn_left->pn_arity == PN_TERNARY);        assert(node->pn_left->pn_arity == PN_TERNARY);
1007        Stream_write_string(f, "for (");        Stream_write_string(f, "for (");
1008        if (node->pn_left->pn_kid1) {        if (node->pn_left->pn_kid1) {
1009          instrument_expression(node->pn_left->pn_kid1, f);          output_expression(node->pn_left->pn_kid1, f, false);
1010        }        }
1011        Stream_write_string(f, ";");        Stream_write_string(f, ";");
1012        if (node->pn_left->pn_kid2) {        if (node->pn_left->pn_kid2) {
1013          Stream_write_char(f, ' ');          Stream_write_char(f, ' ');
1014          instrument_expression(node->pn_left->pn_kid2, f);          output_expression(node->pn_left->pn_kid2, f, false);
1015        }        }
1016        Stream_write_string(f, ";");        Stream_write_string(f, ";");
1017        if (node->pn_left->pn_kid3) {        if (node->pn_left->pn_kid3) {
1018          Stream_write_char(f, ' ');          Stream_write_char(f, ' ');
1019          instrument_expression(node->pn_left->pn_kid3, f);          output_expression(node->pn_left->pn_kid3, f, false);
1020        }        }
1021        Stream_write_char(f, ')');        Stream_write_char(f, ')');
1022        break;        break;
# Line 1036  Line 1032 
1032      assert(node->pn_arity == PN_UNARY);      assert(node->pn_arity == PN_UNARY);
1033      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
1034      Stream_write_string(f, "throw ");      Stream_write_string(f, "throw ");
1035      instrument_expression(node->pn_u.unary.kid, f);      output_expression(node->pn_u.unary.kid, f, false);
1036      Stream_write_string(f, ";\n");      Stream_write_string(f, ";\n");
1037      break;      break;
1038    case TOK_TRY:    case TOK_TRY:
# Line 1053  Line 1049 
1049          assert(catch->pn_type == TOK_CATCH);          assert(catch->pn_type == TOK_CATCH);
1050          Stream_printf(f, "%*s", indent, "");          Stream_printf(f, "%*s", indent, "");
1051          Stream_write_string(f, "catch (");          Stream_write_string(f, "catch (");
1052          /* this may not be a name - destructuring assignment */          output_expression(catch->pn_kid1, f, false);
         /*  
         assert(catch->pn_kid1->pn_arity == PN_NAME);  
         print_string_atom(catch->pn_kid1->pn_atom, f);  
         */  
         instrument_expression(catch->pn_kid1, f);  
1053          if (catch->pn_kid2) {          if (catch->pn_kid2) {
1054            Stream_write_string(f, " if ");            Stream_write_string(f, " if ");
1055            instrument_expression(catch->pn_kid2, f);            output_expression(catch->pn_kid2, f, false);
1056          }          }
1057          Stream_write_string(f, ") {\n");          Stream_write_string(f, ") {\n");
1058          instrument_statement(catch->pn_kid3, f, indent + 2, false);          instrument_statement(catch->pn_kid3, f, indent + 2, false);
# Line 1096  Line 1087 
1087      assert(node->pn_arity == PN_BINARY);      assert(node->pn_arity == PN_BINARY);
1088      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
1089      Stream_write_string(f, "with (");      Stream_write_string(f, "with (");
1090      instrument_expression(node->pn_left, f);      output_expression(node->pn_left, f, false);
1091      Stream_write_string(f, ") {\n");      Stream_write_string(f, ") {\n");
1092      instrument_statement(node->pn_right, f, indent + 2, false);      instrument_statement(node->pn_right, f, indent + 2, false);
1093      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
# Line 1104  Line 1095 
1095      break;      break;
1096    case TOK_VAR:    case TOK_VAR:
1097      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
1098      instrument_expression(node, f);      output_expression(node, f, false);
1099      Stream_write_string(f, ";\n");      Stream_write_string(f, ";\n");
1100      break;      break;
1101    case TOK_RETURN:    case TOK_RETURN:
# Line 1113  Line 1104 
1104      Stream_write_string(f, "return");      Stream_write_string(f, "return");
1105      if (node->pn_kid != NULL) {      if (node->pn_kid != NULL) {
1106        Stream_write_char(f, ' ');        Stream_write_char(f, ' ');
1107        instrument_expression(node->pn_kid, f);        output_expression(node->pn_kid, f, true);
1108      }      }
1109      Stream_write_string(f, ";\n");      Stream_write_string(f, ";\n");
1110      break;      break;
# Line 1121  Line 1112 
1112      assert(node->pn_arity == PN_UNARY);      assert(node->pn_arity == PN_UNARY);
1113      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
1114      if (node->pn_kid != NULL) {      if (node->pn_kid != NULL) {
1115        instrument_expression(node->pn_kid, f);        output_expression(node->pn_kid, f, true);
1116      }      }
1117      Stream_write_string(f, ";\n");      Stream_write_string(f, ";\n");
1118      break;      break;
1119    case TOK_COLON:    case TOK_COLON:
1120      {
1121      assert(node->pn_arity == PN_NAME);      assert(node->pn_arity == PN_NAME);
     /*  
     This one is tricky: can't output instrumentation between the label and the  
     statement it's supposed to label ...  
     */  
1122      Stream_printf(f, "%*s", indent < 2? 0: indent - 2, "");      Stream_printf(f, "%*s", indent < 2? 0: indent - 2, "");
1123      print_string_atom(node->pn_atom, f);      print_string_atom(node->pn_atom, f);
1124      Stream_write_string(f, ":\n");      Stream_write_string(f, ":\n");
1125      /*      JSParseNode * labelled = node->pn_expr;
1126      ... use output_statement instead of instrument_statement.      if (labelled->pn_type == TOK_LEXICALSCOPE) {
1127      */        labelled = labelled->pn_expr;
1128      output_statement(node->pn_expr, f, indent, false);      }
1129        if (labelled->pn_type == TOK_LC) {
1130          /* labelled block */
1131          Stream_printf(f, "%*s", indent, "");
1132          Stream_write_string(f, "{\n");
1133          instrument_statement(labelled, f, indent + 2, false);
1134          Stream_printf(f, "%*s", indent, "");
1135          Stream_write_string(f, "}\n");
1136        }
1137        else {
1138          /*
1139          This one is tricky: can't output instrumentation between the label and the
1140          statement it's supposed to label, so use output_statement instead of
1141          instrument_statement.
1142          */
1143          output_statement(labelled, f, indent, false);
1144        }
1145      break;      break;
1146      }
1147    case TOK_LEXICALSCOPE:    case TOK_LEXICALSCOPE:
1148      /* let statement */      /* let statement */
1149      assert(node->pn_arity == PN_NAME);      assert(node->pn_arity == PN_NAME);
# Line 1181  Line 1186 
1186      case PN_LIST:      case PN_LIST:
1187        /* let definition */        /* let definition */
1188        Stream_printf(f, "%*s", indent, "");        Stream_printf(f, "%*s", indent, "");
1189        instrument_expression(node, f);        output_expression(node, f, false);
1190        Stream_write_string(f, ";\n");        Stream_write_string(f, ";\n");
1191        break;        break;
1192      default:      default:

Legend:
Removed from v.375  
changed lines
  Added in v.392

  ViewVC Help
Powered by ViewVC 1.1.24