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

Diff of /trunk/instrument-js.cpp

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

trunk/instrument-js.c revision 387 by siliconforks, Thu Oct 30 03:14:12 2008 UTC trunk/instrument-js.cpp revision 399 by siliconforks, Tue Dec 9 03:37:47 2008 UTC
# Line 1  Line 1 
1  /*  /*
2      instrument-js.c - JavaScript instrumentation routines      instrument-js.cpp - JavaScript instrumentation routines
3      Copyright (C) 2007, 2008 siliconforks.com      Copyright (C) 2007, 2008 siliconforks.com
4    
5      This program is free software; you can redistribute it and/or modify      This program is free software; you can redistribute it and/or modify
# 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 366  Line 367 
367      if (param == NULL) {      if (param == NULL) {
368        destructuring = true;        destructuring = true;
369        JSParseNode * expression = NULL;        JSParseNode * expression = NULL;
370        assert(node->pn_body->pn_type == TOK_LC || node->pn_body->pn_type == TOK_BODY);        assert(node->pn_body->pn_type == TOK_LC || node->pn_body->pn_type == TOK_SEQ);
371        JSParseNode * semi = node->pn_body->pn_head;        JSParseNode * semi = node->pn_body->pn_head;
372        assert(semi->pn_type == TOK_SEMI);        assert(semi->pn_type == TOK_SEMI);
373        JSParseNode * comma = semi->pn_kid;        JSParseNode * comma = semi->pn_kid;
# Line 393  Line 394 
394    /* function body */    /* function body */
395    if (function->flags & JSFUN_EXPR_CLOSURE) {    if (function->flags & JSFUN_EXPR_CLOSURE) {
396      /* expression closure - use output_statement instead of instrument_statement */      /* expression closure - use output_statement instead of instrument_statement */
397      if (node->pn_body->pn_type == TOK_BODY) {      if (node->pn_body->pn_type == TOK_SEQ) {
398        assert(node->pn_body->pn_arity == PN_LIST);        assert(node->pn_body->pn_arity == PN_LIST);
399        assert(node->pn_body->pn_count == 2);        assert(node->pn_body->pn_count == 2);
400        output_statement(node->pn_body->pn_head->pn_next, f, indent + 2, false);        output_statement(node->pn_body->pn_head->pn_next, f, indent + 2, false);
# Line 714  Line 715 
715            Stream_write_string(f, "set ");            Stream_write_string(f, "set ");
716          }          }
717          output_expression(p->pn_left, f, false);          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          }          }
# Line 763  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 985  Line 1001 
1001        assert(node->pn_left->pn_arity == PN_BINARY);        assert(node->pn_left->pn_arity == PN_BINARY);
1002        output_for_in(node, f);        output_for_in(node, f);
1003        break;        break;
1004      case TOK_RESERVED:      case TOK_FORHEAD:
1005        /* for (;;) */        /* for (;;) */
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 (");
# Line 1029  Line 1045 
1045        assert(node->pn_kid2->pn_type == TOK_RESERVED);        assert(node->pn_kid2->pn_type == TOK_RESERVED);
1046        for (JSParseNode * scope = node->pn_kid2->pn_head; scope != NULL; scope = scope->pn_next) {        for (JSParseNode * scope = node->pn_kid2->pn_head; scope != NULL; scope = scope->pn_next) {
1047          assert(scope->pn_type == TOK_LEXICALSCOPE);          assert(scope->pn_type == TOK_LEXICALSCOPE);
1048          JSParseNode * catch = scope->pn_expr;          JSParseNode * catch_node = scope->pn_expr;
1049          assert(catch->pn_type == TOK_CATCH);          assert(catch_node->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          output_expression(catch->pn_kid1, f, false);          output_expression(catch_node->pn_kid1, f, false);
1053          if (catch->pn_kid2) {          if (catch_node->pn_kid2) {
1054            Stream_write_string(f, " if ");            Stream_write_string(f, " if ");
1055            output_expression(catch->pn_kid2, f, false);            output_expression(catch_node->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_node->pn_kid3, f, indent + 2, false);
1059          Stream_printf(f, "%*s", indent, "");          Stream_printf(f, "%*s", indent, "");
1060          Stream_write_string(f, "}\n");          Stream_write_string(f, "}\n");
1061        }        }
# Line 1060  Line 1076 
1076      assert(node->pn_arity == PN_NAME || node->pn_arity == PN_NULLARY);      assert(node->pn_arity == PN_NAME || node->pn_arity == PN_NULLARY);
1077      Stream_printf(f, "%*s", indent, "");      Stream_printf(f, "%*s", indent, "");
1078      Stream_write_string(f, node->pn_type == TOK_BREAK? "break": "continue");      Stream_write_string(f, node->pn_type == TOK_BREAK? "break": "continue");
1079      JSAtom * atom = node->pn_u.name.atom;      if (node->pn_atom != NULL) {
     if (atom != NULL) {  
1080        Stream_write_char(f, ' ');        Stream_write_char(f, ' ');
1081        print_string_atom(node->pn_atom, f);        print_string_atom(node->pn_atom, f);
1082      }      }
# Line 1263  Line 1278 
1278    }    }
1279    JS_SetErrorReporter(context, old_error_reporter);    JS_SetErrorReporter(context, old_error_reporter);
1280    num_lines = node->pn_pos.end.lineno;    num_lines = node->pn_pos.end.lineno;
1281    lines = xmalloc(num_lines);    lines = (char *) xmalloc(num_lines);
1282    for (unsigned int i = 0; i < num_lines; i++) {    for (unsigned int i = 0; i < num_lines; i++) {
1283      lines[i] = 0;      lines[i] = 0;
1284    }    }
# Line 1576  Line 1591 
1591  };  };
1592    
1593  static int compare_strings(const void * p1, const void * p2) {  static int compare_strings(const void * p1, const void * p2) {
1594    return strcmp(p1, p2) == 0;    return strcmp((const char *) p1, (const char *) p2) == 0;
1595  }  }
1596    
1597  Coverage * Coverage_new(void) {  Coverage * Coverage_new(void) {
1598    Coverage * result = xmalloc(sizeof(Coverage));    Coverage * result = (Coverage *) xmalloc(sizeof(Coverage));
1599    result->coverage_table = JS_NewHashTable(1024, JS_HashString, compare_strings, NULL, NULL, NULL);    result->coverage_table = JS_NewHashTable(1024, JS_HashString, compare_strings, NULL, NULL, NULL);
1600    if (result->coverage_table == NULL) {    if (result->coverage_table == NULL) {
1601      fatal("cannot create hash table");      fatal("cannot create hash table");
# Line 1615  Line 1630 
1630  };  };
1631    
1632  static intN enumerator(JSHashEntry * entry, intN i, void * arg) {  static intN enumerator(JSHashEntry * entry, intN i, void * arg) {
1633    struct EnumeratorArg * enumerator_arg = arg;    struct EnumeratorArg * enumerator_arg = (struct EnumeratorArg *) arg;
1634    enumerator_arg->f(entry->value, i, enumerator_arg->p);    enumerator_arg->f((FileCoverage *) entry->value, i, enumerator_arg->p);
1635    return 0;    return 0;
1636  }  }
1637    
# Line 1649  Line 1664 
1664    }    }
1665    JSParseNode * root = js_ParseScript(context, global, &parse_context);    JSParseNode * root = js_ParseScript(context, global, &parse_context);
1666    free(parenthesized_json);    free(parenthesized_json);
1667    
1668      JSParseNode * semi = NULL;
1669      JSParseNode * object = NULL;
1670    
1671    if (root == NULL) {    if (root == NULL) {
1672      result = -1;      result = -1;
1673      goto done;      goto done;
# Line 1659  Line 1678 
1678      result = -1;      result = -1;
1679      goto done;      goto done;
1680    }    }
1681    JSParseNode * semi = root->pn_u.list.head;    semi = root->pn_u.list.head;
1682    
1683    /* the list must be TOK_SEMI and it must contain only one element */    /* the list must be TOK_SEMI and it must contain only one element */
1684    if (semi->pn_type != TOK_SEMI || semi->pn_next != NULL) {    if (semi->pn_type != TOK_SEMI || semi->pn_next != NULL) {
1685      result = -1;      result = -1;
1686      goto done;      goto done;
1687    }    }
1688    JSParseNode * parenthesized = semi->pn_kid;    object = semi->pn_kid;
   
   /* this must be a parenthesized expression */  
   if (parenthesized->pn_type != TOK_RP) {  
     result = -1;  
     goto done;  
   }  
   JSParseNode * object = parenthesized->pn_kid;  
1689    
1690    /* this must be an object literal */    /* this must be an object literal */
1691    if (object->pn_type != TOK_RC) {    if (object->pn_type != TOK_RC) {
# Line 1757  Line 1769 
1769      }      }
1770    
1771      /* look up the file in the coverage table */      /* look up the file in the coverage table */
1772      FileCoverage * file_coverage = JS_HashTableLookup(coverage->coverage_table, id_bytes);      FileCoverage * file_coverage = (FileCoverage *) JS_HashTableLookup(coverage->coverage_table, id_bytes);
1773      if (file_coverage == NULL) {      if (file_coverage == NULL) {
1774        /* not there: create a new one */        /* not there: create a new one */
1775        char * id = xstrdup(id_bytes);        char * id = xstrdup(id_bytes);
1776        file_coverage = xmalloc(sizeof(FileCoverage));        file_coverage = (FileCoverage *) xmalloc(sizeof(FileCoverage));
1777        file_coverage->id = id;        file_coverage->id = id;
1778        file_coverage->num_coverage_lines = array->pn_count;        file_coverage->num_coverage_lines = array->pn_count;
1779        file_coverage->coverage_lines = xnew(int, array->pn_count);        file_coverage->coverage_lines = xnew(int, array->pn_count);
# Line 1785  Line 1797 
1797    
1798        /* add to the hash table */        /* add to the hash table */
1799        JS_HashTableAdd(coverage->coverage_table, id, file_coverage);        JS_HashTableAdd(coverage->coverage_table, id, file_coverage);
1800        struct FileCoverageList * coverage_list = xmalloc(sizeof(struct FileCoverageList));        struct FileCoverageList * coverage_list = (FileCoverageList *) xmalloc(sizeof(struct FileCoverageList));
1801        coverage_list->file_coverage = file_coverage;        coverage_list->file_coverage = file_coverage;
1802        coverage_list->next = coverage->coverage_list;        coverage_list->next = coverage->coverage_list;
1803        coverage->coverage_list = coverage_list;        coverage->coverage_list = coverage_list;

Legend:
Removed from v.387  
changed lines
  Added in v.399

  ViewVC Help
Powered by ViewVC 1.1.24