/[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 293 by siliconforks, Sun Oct 12 16:41:57 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 515  Line 540 
540        /* check whether this is a getter or setter */        /* check whether this is a getter or setter */
541        switch (p->pn_op) {        switch (p->pn_op) {
542        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;  
543        case JSOP_SETTER:        case JSOP_SETTER:
544          Stream_write_string(f, "set ");          if (p->pn_op == JSOP_GETTER) {
545              Stream_write_string(f, "get ");
546            }
547            else {
548              Stream_write_string(f, "set ");
549            }
550          instrument_expression(p->pn_left, f);          instrument_expression(p->pn_left, f);
551            if (p->pn_right->pn_type != TOK_FUNCTION) {
552              fatal("parse error: expected function");
553            }
554          instrument_function(p->pn_right, f, 0, FUNCTION_GETTER_OR_SETTER);          instrument_function(p->pn_right, f, 0, FUNCTION_GETTER_OR_SETTER);
555          break;          break;
556        default:        default:
# Line 966  Line 995 
995    return true;    return true;
996  }  }
997    
998    static void error_reporter(JSContext * context, const char * message, JSErrorReport * report) {
999      fprintf(stderr, "jscoverage: parse error: line %u: %s\n", report->lineno, message);
1000    }
1001    
1002  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) {
1003    file_id = id;    file_id = id;
1004    
# Line 976  Line 1009 
1009    }    }
1010    
1011    /* parse the javascript */    /* parse the javascript */
1012      JSErrorReporter old_error_reporter = JS_SetErrorReporter(context, error_reporter);
1013    JSParseNode * node = js_ParseTokenStream(context, global, token_stream);    JSParseNode * node = js_ParseTokenStream(context, global, token_stream);
1014    if (node == NULL) {    if (node == NULL) {
1015        js_ReportUncaughtException(context);
1016      fatal("parse error in file: %s", file_id);      fatal("parse error in file: %s", file_id);
1017    }    }
1018      JS_SetErrorReporter(context, old_error_reporter);
1019    num_lines = node->pn_pos.end.lineno;    num_lines = node->pn_pos.end.lineno;
1020    lines = xmalloc(num_lines);    lines = xmalloc(num_lines);
1021    for (unsigned int i = 0; i < num_lines; i++) {    for (unsigned int i = 0; i < num_lines; i++) {
# Line 1090  Line 1126 
1126    /* conditionals */    /* conditionals */
1127    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) {
1128      Stream_write_string(output, "if (!(");      Stream_write_string(output, "if (!(");
1129      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);  
       }  
     }  
1130      Stream_write_string(output, ")) {\n");      Stream_write_string(output, ")) {\n");
1131      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);
1132      Stream_write_string(output, "}\n");      Stream_write_string(output, "}\n");
# Line 1456  Line 1484 
1484        file_coverage->id = id;        file_coverage->id = id;
1485        file_coverage->num_coverage_lines = array->pn_count;        file_coverage->num_coverage_lines = array->pn_count;
1486        file_coverage->coverage_lines = xnew(int, array->pn_count);        file_coverage->coverage_lines = xnew(int, array->pn_count);
1487        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);  
       }  
1488    
1489        /* set coverage for all lines */        /* set coverage for all lines */
1490        uint32 i = 0;        uint32 i = 0;
# Line 1520  Line 1534 
1534          }          }
1535        }        }
1536        assert(i == array->pn_count);        assert(i == array->pn_count);
1537        }
1538    
1539        /* if this JSON file has source, use it */      /* if this JSON file has source, use it */
1540        if (file_coverage->source_lines == NULL && source != NULL) {      if (file_coverage->source_lines == NULL && source != NULL) {
1541          file_coverage->num_source_lines = source->pn_count;        file_coverage->num_source_lines = source->pn_count;
1542          file_coverage->source_lines = xnew(char *, source->pn_count);        file_coverage->source_lines = xnew(char *, source->pn_count);
1543          uint32 i = 0;        uint32 i = 0;
1544          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++) {
1545            if (element->pn_type != TOK_STRING) {          if (element->pn_type != TOK_STRING) {
1546              return -1;            return -1;
           }  
           file_coverage->source_lines[i] = xstrdup(JS_GetStringBytes(ATOM_TO_STRING(element->pn_atom)));  
1547          }          }
1548          assert(i == source->pn_count);          file_coverage->source_lines[i] = xstrdup(JS_GetStringBytes(ATOM_TO_STRING(element->pn_atom)));
1549        }        }
1550          assert(i == source->pn_count);
1551      }      }
1552    }    }
1553    

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

  ViewVC Help
Powered by ViewVC 1.1.24