/[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 373 by siliconforks, Mon Oct 27 20:36:44 2008 UTC revision 389 by siliconforks, Thu Oct 30 17:53:07 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:  
     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 493  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      instrument_expression(node->pn_left, f);      output_expression(node->pn_left, f, parenthesize_object_literals);
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 528  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 551  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 570  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 608  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 639  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 */
627        switch (node->pn_expr->pn_type) {
628        case TOK_NUMBER:
629          Stream_write_char(f, '(');
630          output_expression(node->pn_expr, f, false);
631          Stream_write_char(f, ')');
632          break;
633        default:
634          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'
639      contains illegal characters, we have to use the subscript syntax instead of      contains illegal characters, we have to use the subscript syntax instead of
640      the dot syntax.      the dot syntax.
641      */      */
     instrument_expression(node->pn_expr, f);  
642      assert(ATOM_IS_STRING(node->pn_atom));      assert(ATOM_IS_STRING(node->pn_atom));
643      {      {
644        JSString * s = ATOM_TO_STRING(node->pn_atom);        JSString * s = ATOM_TO_STRING(node->pn_atom);
# Line 676  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 692  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 701  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 720  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          if (p->pn_right->pn_type != TOK_FUNCTION) {          if (p->pn_right->pn_type != TOK_FUNCTION) {
719            fatal_source(file_id, p->pn_pos.begin.lineno, "expected function");            fatal_source(file_id, p->pn_pos.begin.lineno, "expected function");
720          }          }
721          instrument_function(p->pn_right, f, 0, FUNCTION_GETTER_OR_SETTER);          instrument_function(p->pn_right, f, 0, FUNCTION_GETTER_OR_SETTER);
722          break;          break;
723        default:        default:
724          instrument_expression(p->pn_left, f);          output_expression(p->pn_left, f, false);
725          Stream_write_string(f, ": ");          Stream_write_string(f, ": ");
726          instrument_expression(p->pn_right, f);          output_expression(p->pn_right, f, false);
727          break;          break;
728        }        }
729      }      }
730      Stream_write_char(f, '}');      Stream_write_char(f, '}');
731        if (parenthesize_object_literals) {
732          Stream_write_char(f, ')');
733        }
734      break;      break;
735    case TOK_RP:    case TOK_RP:
736      Stream_write_char(f, '(');      Stream_write_char(f, '(');
737      instrument_expression(node->pn_kid, f);      output_expression(node->pn_kid, f, false);
738      Stream_write_char(f, ')');      Stream_write_char(f, ')');
739      break;      break;
740    case TOK_NAME:    case TOK_NAME:
741      print_string_atom(node->pn_atom, f);      print_string_atom(node->pn_atom, f);
742        if (node->pn_expr != NULL) {
743          Stream_write_string(f, " = ");
744          output_expression(node->pn_expr, f, false);
745        }
746      break;      break;
747    case TOK_STRING:    case TOK_STRING:
748      print_quoted_string_atom(node->pn_atom, f);      print_quoted_string_atom(node->pn_atom, f);
# Line 765  Line 766 
766      if (node->pn_dval == 0.0) {      if (node->pn_dval == 0.0) {
767        Stream_write_string(f, "0");        Stream_write_string(f, "0");
768      }      }
769        else if (node->pn_dval == INFINITY) {
770          Stream_write_string(f, "Number.POSITIVE_INFINITY");
771        }
772        else if (node->pn_dval == -INFINITY) {
773          Stream_write_string(f, "Number.NEGATIVE_INFINITY");
774        }
775        else if (node->pn_dval == NAN) {
776          Stream_write_string(f, "Number.NaN");
777        }
778      else {      else {
779        Stream_printf(f, "%.15g", node->pn_dval);        Stream_printf(f, "%.15g", node->pn_dval);
780      }      }
# Line 789  Line 799 
799      }      }
800      break;      break;
801    case TOK_INSTANCEOF:    case TOK_INSTANCEOF:
802      instrument_expression(node->pn_left, f);      output_expression(node->pn_left, f, parenthesize_object_literals);
803      Stream_write_string(f, " instanceof ");      Stream_write_string(f, " instanceof ");
804      instrument_expression(node->pn_right, f);      output_expression(node->pn_right, f, false);
805      break;      break;
806    case TOK_IN:    case TOK_IN:
807      instrument_expression(node->pn_left, f);      output_expression(node->pn_left, f, false);
808      Stream_write_string(f, " in ");      Stream_write_string(f, " in ");
809      instrument_expression(node->pn_right, f);      output_expression(node->pn_right, f, false);
810      break;      break;
811    case TOK_LEXICALSCOPE:    case TOK_LEXICALSCOPE:
812      assert(node->pn_arity == PN_NAME);      assert(node->pn_arity == PN_NAME);
# Line 807  Line 817 
817      assert(node->pn_expr->pn_left->pn_arity == PN_LIST);      assert(node->pn_expr->pn_left->pn_arity == PN_LIST);
818      instrument_declarations(node->pn_expr->pn_left, f);      instrument_declarations(node->pn_expr->pn_left, f);
819      Stream_write_string(f, ") ");      Stream_write_string(f, ") ");
820      instrument_expression(node->pn_expr->pn_right, f);      output_expression(node->pn_expr->pn_right, f, true);
821      break;      break;
822    case TOK_YIELD:    case TOK_YIELD:
823      assert(node->pn_arity == PN_UNARY);      assert(node->pn_arity == PN_UNARY);
824      Stream_write_string(f, "yield");      Stream_write_string(f, "yield");
825      if (node->pn_kid != NULL) {      if (node->pn_kid != NULL) {
826        Stream_write_char(f, ' ');        Stream_write_char(f, ' ');
827        instrument_expression(node->pn_kid, f);        output_expression(node->pn_kid, f, true);
828      }      }
829      break;      break;
830    case TOK_ARRAYCOMP:    case TOK_ARRAYCOMP:
# Line 856  Line 866 
866    switch (node->pn_type) {    switch (node->pn_type) {
867    case TOK_FUNCTION:    case TOK_FUNCTION:
868      instrument_function(node, f, indent, FUNCTION_NORMAL);      instrument_function(node, f, indent, FUNCTION_NORMAL);
869        Stream_write_char(f, '\n');
870      break;      break;
871    case TOK_LC:    case TOK_LC:
872      assert(node->pn_arity == PN_LIST);      assert(node->pn_arity == PN_LIST);
# Line 886  Line 897 
897    
898      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
899      Stream_write_string(f, "if (");      Stream_write_string(f, "if (");
900      instrument_expression(node->pn_kid1, f);      output_expression(node->pn_kid1, f, false);
901      Stream_write_string(f, ") {\n");      Stream_write_string(f, ") {\n");
902      if (is_jscoverage_if && node->pn_kid3) {      if (is_jscoverage_if && node->pn_kid3) {
903        uint16_t else_start = node->pn_kid3->pn_pos.begin.lineno;        uint16_t else_start = node->pn_kid3->pn_pos.begin.lineno;
# Line 923  Line 934 
934      assert(node->pn_arity == PN_BINARY);      assert(node->pn_arity == PN_BINARY);
935      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
936      Stream_write_string(f, "switch (");      Stream_write_string(f, "switch (");
937      instrument_expression(node->pn_left, f);      output_expression(node->pn_left, f, false);
938      Stream_write_string(f, ") {\n");      Stream_write_string(f, ") {\n");
939      {      {
940        JSParseNode * list = node->pn_right;        JSParseNode * list = node->pn_right;
# Line 935  Line 946 
946          switch (p->pn_type) {          switch (p->pn_type) {
947          case TOK_CASE:          case TOK_CASE:
948            Stream_write_string(f, "case ");            Stream_write_string(f, "case ");
949            instrument_expression(p->pn_left, f);            output_expression(p->pn_left, f, false);
950            Stream_write_string(f, ":\n");            Stream_write_string(f, ":\n");
951            break;            break;
952          case TOK_DEFAULT:          case TOK_DEFAULT:
# Line 959  Line 970 
970      assert(node->pn_arity == PN_BINARY);      assert(node->pn_arity == PN_BINARY);
971      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
972      Stream_write_string(f, "while (");      Stream_write_string(f, "while (");
973      instrument_expression(node->pn_left, f);      output_expression(node->pn_left, f, false);
974      Stream_write_string(f, ") {\n");      Stream_write_string(f, ") {\n");
975      instrument_statement(node->pn_right, f, indent + 2, false);      instrument_statement(node->pn_right, f, indent + 2, false);
976      Stream_write_string(f, "}\n");      Stream_write_string(f, "}\n");
# Line 972  Line 983 
983      Stream_write_string(f, "}\n");      Stream_write_string(f, "}\n");
984      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
985      Stream_write_string(f, "while (");      Stream_write_string(f, "while (");
986      instrument_expression(node->pn_right, f);      output_expression(node->pn_right, f, false);
987      Stream_write_string(f, ");\n");      Stream_write_string(f, ");\n");
988      break;      break;
989    case TOK_FOR:    case TOK_FOR:
# Line 989  Line 1000 
1000        assert(node->pn_left->pn_arity == PN_TERNARY);        assert(node->pn_left->pn_arity == PN_TERNARY);
1001        Stream_write_string(f, "for (");        Stream_write_string(f, "for (");
1002        if (node->pn_left->pn_kid1) {        if (node->pn_left->pn_kid1) {
1003          instrument_expression(node->pn_left->pn_kid1, f);          output_expression(node->pn_left->pn_kid1, f, false);
1004        }        }
1005        Stream_write_string(f, ";");        Stream_write_string(f, ";");
1006        if (node->pn_left->pn_kid2) {        if (node->pn_left->pn_kid2) {
1007          Stream_write_char(f, ' ');          Stream_write_char(f, ' ');
1008          instrument_expression(node->pn_left->pn_kid2, f);          output_expression(node->pn_left->pn_kid2, f, false);
1009        }        }
1010        Stream_write_string(f, ";");        Stream_write_string(f, ";");
1011        if (node->pn_left->pn_kid3) {        if (node->pn_left->pn_kid3) {
1012          Stream_write_char(f, ' ');          Stream_write_char(f, ' ');
1013          instrument_expression(node->pn_left->pn_kid3, f);          output_expression(node->pn_left->pn_kid3, f, false);
1014        }        }
1015        Stream_write_char(f, ')');        Stream_write_char(f, ')');
1016        break;        break;
# Line 1015  Line 1026 
1026      assert(node->pn_arity == PN_UNARY);      assert(node->pn_arity == PN_UNARY);
1027      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
1028      Stream_write_string(f, "throw ");      Stream_write_string(f, "throw ");
1029      instrument_expression(node->pn_u.unary.kid, f);      output_expression(node->pn_u.unary.kid, f, false);
1030      Stream_write_string(f, ";\n");      Stream_write_string(f, ";\n");
1031      break;      break;
1032    case TOK_TRY:    case TOK_TRY:
# Line 1032  Line 1043 
1043          assert(catch->pn_type == TOK_CATCH);          assert(catch->pn_type == TOK_CATCH);
1044          Stream_printf(f, "%*s", indent, "");          Stream_printf(f, "%*s", indent, "");
1045          Stream_write_string(f, "catch (");          Stream_write_string(f, "catch (");
1046          /* 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);  
1047          if (catch->pn_kid2) {          if (catch->pn_kid2) {
1048            Stream_write_string(f, " if ");            Stream_write_string(f, " if ");
1049            instrument_expression(catch->pn_kid2, f);            output_expression(catch->pn_kid2, f, false);
1050          }          }
1051          Stream_write_string(f, ") {\n");          Stream_write_string(f, ") {\n");
1052          instrument_statement(catch->pn_kid3, f, indent + 2, false);          instrument_statement(catch->pn_kid3, f, indent + 2, false);
# Line 1075  Line 1081 
1081      assert(node->pn_arity == PN_BINARY);      assert(node->pn_arity == PN_BINARY);
1082      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
1083      Stream_write_string(f, "with (");      Stream_write_string(f, "with (");
1084      instrument_expression(node->pn_left, f);      output_expression(node->pn_left, f, false);
1085      Stream_write_string(f, ") {\n");      Stream_write_string(f, ") {\n");
1086      instrument_statement(node->pn_right, f, indent + 2, false);      instrument_statement(node->pn_right, f, indent + 2, false);
1087      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
# Line 1083  Line 1089 
1089      break;      break;
1090    case TOK_VAR:    case TOK_VAR:
1091      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
1092      instrument_expression(node, f);      output_expression(node, f, false);
1093      Stream_write_string(f, ";\n");      Stream_write_string(f, ";\n");
1094      break;      break;
1095    case TOK_RETURN:    case TOK_RETURN:
# Line 1092  Line 1098 
1098      Stream_write_string(f, "return");      Stream_write_string(f, "return");
1099      if (node->pn_kid != NULL) {      if (node->pn_kid != NULL) {
1100        Stream_write_char(f, ' ');        Stream_write_char(f, ' ');
1101        instrument_expression(node->pn_kid, f);        output_expression(node->pn_kid, f, true);
1102      }      }
1103      Stream_write_string(f, ";\n");      Stream_write_string(f, ";\n");
1104      break;      break;
# Line 1100  Line 1106 
1106      assert(node->pn_arity == PN_UNARY);      assert(node->pn_arity == PN_UNARY);
1107      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
1108      if (node->pn_kid != NULL) {      if (node->pn_kid != NULL) {
1109        instrument_expression(node->pn_kid, f);        output_expression(node->pn_kid, f, true);
1110      }      }
1111      Stream_write_string(f, ";\n");      Stream_write_string(f, ";\n");
1112      break;      break;
1113    case TOK_COLON:    case TOK_COLON:
1114      {
1115      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 ...  
     */  
1116      Stream_printf(f, "%*s", indent < 2? 0: indent - 2, "");      Stream_printf(f, "%*s", indent < 2? 0: indent - 2, "");
1117      print_string_atom(node->pn_atom, f);      print_string_atom(node->pn_atom, f);
1118      Stream_write_string(f, ":\n");      Stream_write_string(f, ":\n");
1119      /*      JSParseNode * labelled = node->pn_expr;
1120      ... use output_statement instead of instrument_statement.      if (labelled->pn_type == TOK_LEXICALSCOPE) {
1121      */        labelled = labelled->pn_expr;
1122      output_statement(node->pn_expr, f, indent, false);      }
1123        if (labelled->pn_type == TOK_LC) {
1124          /* labelled block */
1125          Stream_printf(f, "%*s", indent, "");
1126          Stream_write_string(f, "{\n");
1127          instrument_statement(labelled, f, indent + 2, false);
1128          Stream_printf(f, "%*s", indent, "");
1129          Stream_write_string(f, "}\n");
1130        }
1131        else {
1132          /*
1133          This one is tricky: can't output instrumentation between the label and the
1134          statement it's supposed to label, so use output_statement instead of
1135          instrument_statement.
1136          */
1137          output_statement(labelled, f, indent, false);
1138        }
1139      break;      break;
1140      }
1141    case TOK_LEXICALSCOPE:    case TOK_LEXICALSCOPE:
1142      /* let statement */      /* let statement */
1143      assert(node->pn_arity == PN_NAME);      assert(node->pn_arity == PN_NAME);
# Line 1160  Line 1180 
1180      case PN_LIST:      case PN_LIST:
1181        /* let definition */        /* let definition */
1182        Stream_printf(f, "%*s", indent, "");        Stream_printf(f, "%*s", indent, "");
1183        instrument_expression(node, f);        output_expression(node, f, false);
1184        Stream_write_string(f, ";\n");        Stream_write_string(f, ";\n");
1185        break;        break;
1186      default:      default:

Legend:
Removed from v.373  
changed lines
  Added in v.389

  ViewVC Help
Powered by ViewVC 1.1.24