/[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 240 by siliconforks, Fri Oct 3 23:51:32 2008 UTC revision 317 by siliconforks, Tue Oct 14 01:28:46 2008 UTC
# Line 27  Line 27 
27    
28  #include <jsapi.h>  #include <jsapi.h>
29  #include <jsatom.h>  #include <jsatom.h>
30    #include <jsexn.h>
31  #include <jsfun.h>  #include <jsfun.h>
32  #include <jsinterp.h>  #include <jsinterp.h>
33  #include <jsparse.h>  #include <jsparse.h>
# Line 88  Line 89 
89    JS_DestroyRuntime(runtime);    JS_DestroyRuntime(runtime);
90  }  }
91    
92    static void print_javascript(const jschar * characters, size_t num_characters, Stream * f) {
93      for (size_t i = 0; i < num_characters; i++) {
94        jschar c = characters[i];
95        /*
96        XXX does not handle no-break space, other unicode "space separator"
97        */
98        switch (c) {
99        case 0x9:
100        case 0xB:
101        case 0xC:
102          Stream_write_char(f, c);
103          break;
104        default:
105          if (32 <= c && c <= 126) {
106            Stream_write_char(f, c);
107          }
108          else {
109            Stream_printf(f, "\\u%04x", c);
110          }
111          break;
112        }
113      }
114    }
115    
116  static void print_string(JSString * s, Stream * f) {  static void print_string(JSString * s, Stream * f) {
117    size_t length = JSSTRING_LENGTH(s);    size_t length = JSSTRING_LENGTH(s);
118    jschar * characters = JSSTRING_CHARS(s);    jschar * characters = JSSTRING_CHARS(s);
# Line 122  Line 147 
147        case 0xa:        case 0xa:
148          Stream_write_string(f, "\\n");          Stream_write_string(f, "\\n");
149          break;          break;
150          /* IE doesn't support this */
151          /*
152        case 0xb:        case 0xb:
153          Stream_write_string(f, "\\v");          Stream_write_string(f, "\\v");
154          break;          break;
155          */
156        case 0xc:        case 0xc:
157          Stream_write_string(f, "\\f");          Stream_write_string(f, "\\f");
158          break;          break;
# Line 515  Line 543 
543        /* check whether this is a getter or setter */        /* check whether this is a getter or setter */
544        switch (p->pn_op) {        switch (p->pn_op) {
545        case JSOP_GETTER:        case JSOP_GETTER:
         Stream_write_string(f, "get ");  
         instrument_expression(p->pn_left, f);  
         instrument_function(p->pn_right, f, 0, FUNCTION_GETTER_OR_SETTER);  
         break;  
546        case JSOP_SETTER:        case JSOP_SETTER:
547          Stream_write_string(f, "set ");          if (p->pn_op == JSOP_GETTER) {
548              Stream_write_string(f, "get ");
549            }
550            else {
551              Stream_write_string(f, "set ");
552            }
553          instrument_expression(p->pn_left, f);          instrument_expression(p->pn_left, f);
554            if (p->pn_right->pn_type != TOK_FUNCTION) {
555              fatal("parse error: expected function");
556            }
557          instrument_function(p->pn_right, f, 0, FUNCTION_GETTER_OR_SETTER);          instrument_function(p->pn_right, f, 0, FUNCTION_GETTER_OR_SETTER);
558          break;          break;
559        default:        default:
# Line 966  Line 998 
998    return true;    return true;
999  }  }
1000    
1001    static void error_reporter(JSContext * context, const char * message, JSErrorReport * report) {
1002      fprintf(stderr, "jscoverage: parse error: line %u: %s\n", report->lineno, message);
1003    }
1004    
1005  void jscoverage_instrument_js(const char * id, const uint16_t * characters, size_t num_characters, Stream * output) {  void jscoverage_instrument_js(const char * id, const uint16_t * characters, size_t num_characters, Stream * output) {
1006    file_id = id;    file_id = id;
1007    
# Line 976  Line 1012 
1012    }    }
1013    
1014    /* parse the javascript */    /* parse the javascript */
1015      JSErrorReporter old_error_reporter = JS_SetErrorReporter(context, error_reporter);
1016    JSParseNode * node = js_ParseTokenStream(context, global, token_stream);    JSParseNode * node = js_ParseTokenStream(context, global, token_stream);
1017    if (node == NULL) {    if (node == NULL) {
1018        js_ReportUncaughtException(context);
1019      fatal("parse error in file: %s", file_id);      fatal("parse error in file: %s", file_id);
1020    }    }
1021      JS_SetErrorReporter(context, old_error_reporter);
1022    num_lines = node->pn_pos.end.lineno;    num_lines = node->pn_pos.end.lineno;
1023    lines = xmalloc(num_lines);    lines = xmalloc(num_lines);
1024    for (unsigned int i = 0; i < num_lines; i++) {    for (unsigned int i = 0; i < num_lines; i++) {
# Line 1090  Line 1129 
1129    /* conditionals */    /* conditionals */
1130    for (struct IfDirective * if_directive = if_directives; if_directive != NULL; if_directive = if_directive->next) {    for (struct IfDirective * if_directive = if_directives; if_directive != NULL; if_directive = if_directive->next) {
1131      Stream_write_string(output, "if (!(");      Stream_write_string(output, "if (!(");
1132      for (const jschar * p = if_directive->condition_start; p < if_directive->condition_end; p++) {      print_javascript(if_directive->condition_start, if_directive->condition_end - if_directive->condition_start, output);
       jschar c = *p;  
       if (c == '\t' || (32 <= c && c <= 126)) {  
         Stream_write_char(output, c);  
       }  
       else {  
         Stream_printf(output, "\\u%04x", c);  
       }  
     }  
1133      Stream_write_string(output, ")) {\n");      Stream_write_string(output, ")) {\n");
1134      Stream_printf(output, "  _$jscoverage['%s'].conditionals[%d] = %d;\n", file_id, if_directive->start_line, if_directive->end_line);      Stream_printf(output, "  _$jscoverage['%s'].conditionals[%d] = %d;\n", file_id, if_directive->start_line, if_directive->end_line);
1135      Stream_write_string(output, "}\n");      Stream_write_string(output, "}\n");
# Line 1149  Line 1180 
1180            /* line feed (new line) */            /* line feed (new line) */
1181            done = true;            done = true;
1182            break;            break;
1183            /* IE doesn't support this */
1184            /*
1185          case 0xb:          case 0xb:
           /* vertical tab */  
1186            Stream_write_string(output, "\\v");            Stream_write_string(output, "\\v");
1187            break;            break;
1188            */
1189          case 0xc:          case 0xc:
1190            /* form feed */            /* form feed */
1191            Stream_write_string(output, "\\f");            Stream_write_string(output, "\\f");
# Line 1207  Line 1240 
1240            /* line feed (new line) */            /* line feed (new line) */
1241            done = true;            done = true;
1242            break;            break;
1243            /* IE doesn't support this */
1244            /*
1245          case 0xb:          case 0xb:
           /* vertical tab */  
1246            Stream_write_string(output, "\\v");            Stream_write_string(output, "\\v");
1247            break;            break;
1248            */
1249          case 0xc:          case 0xc:
1250            /* form feed */            /* form feed */
1251            Stream_write_string(output, "\\f");            Stream_write_string(output, "\\f");
# Line 1456  Line 1491 
1491        file_coverage->id = id;        file_coverage->id = id;
1492        file_coverage->num_coverage_lines = array->pn_count;        file_coverage->num_coverage_lines = array->pn_count;
1493        file_coverage->coverage_lines = xnew(int, array->pn_count);        file_coverage->coverage_lines = xnew(int, array->pn_count);
1494        if (source == NULL) {        file_coverage->source_lines = NULL;
         file_coverage->source_lines = NULL;  
       }  
       else {  
         file_coverage->num_source_lines = source->pn_count;  
         file_coverage->source_lines = xnew(char *, source->pn_count);  
         uint32 i = 0;  
         for (JSParseNode * element = source->pn_head; element != NULL; element = element->pn_next, i++) {  
           if (element->pn_type != TOK_STRING) {  
             return -1;  
           }  
           file_coverage->source_lines[i] = xstrdup(JS_GetStringBytes(ATOM_TO_STRING(element->pn_atom)));  
         }  
         assert(i == source->pn_count);  
       }  
1495    
1496        /* set coverage for all lines */        /* set coverage for all lines */
1497        uint32 i = 0;        uint32 i = 0;
# Line 1520  Line 1541 
1541          }          }
1542        }        }
1543        assert(i == array->pn_count);        assert(i == array->pn_count);
1544        }
1545    
1546        /* if this JSON file has source, use it */      /* if this JSON file has source, use it */
1547        if (file_coverage->source_lines == NULL && source != NULL) {      if (file_coverage->source_lines == NULL && source != NULL) {
1548          file_coverage->num_source_lines = source->pn_count;        file_coverage->num_source_lines = source->pn_count;
1549          file_coverage->source_lines = xnew(char *, source->pn_count);        file_coverage->source_lines = xnew(char *, source->pn_count);
1550          uint32 i = 0;        uint32 i = 0;
1551          for (JSParseNode * element = source->pn_head; element != NULL; element = element->pn_next, i++) {        for (JSParseNode * element = source->pn_head; element != NULL; element = element->pn_next, i++) {
1552            if (element->pn_type != TOK_STRING) {          if (element->pn_type != TOK_STRING) {
1553              return -1;            return -1;
           }  
           file_coverage->source_lines[i] = xstrdup(JS_GetStringBytes(ATOM_TO_STRING(element->pn_atom)));  
1554          }          }
1555          assert(i == source->pn_count);          file_coverage->source_lines[i] = xstrdup(JS_GetStringBytes(ATOM_TO_STRING(element->pn_atom)));
1556        }        }
1557          assert(i == source->pn_count);
1558      }      }
1559    }    }
1560    

Legend:
Removed from v.240  
changed lines
  Added in v.317

  ViewVC Help
Powered by ViewVC 1.1.24