52 |
struct IfDirective * next; |
struct IfDirective * next; |
53 |
}; |
}; |
54 |
|
|
55 |
|
bool jscoverage_mozilla = false; |
56 |
|
|
57 |
static bool * exclusive_directives = NULL; |
static bool * exclusive_directives = NULL; |
58 |
|
|
59 |
static JSRuntime * runtime = NULL; |
static JSRuntime * runtime = NULL; |
279 |
Stream_write_char(f, ')'); |
Stream_write_char(f, ')'); |
280 |
} |
} |
281 |
|
|
282 |
|
static void output_array_comprehension_or_generator_expression(JSParseNode * node, Stream * f) { |
283 |
|
assert(node->pn_type == TOK_LEXICALSCOPE); |
284 |
|
assert(node->pn_arity == PN_NAME); |
285 |
|
JSParseNode * for_node = node->pn_expr; |
286 |
|
assert(for_node->pn_type == TOK_FOR); |
287 |
|
assert(for_node->pn_arity == PN_BINARY); |
288 |
|
JSParseNode * p = for_node; |
289 |
|
while (p->pn_type == TOK_FOR) { |
290 |
|
p = p->pn_right; |
291 |
|
} |
292 |
|
JSParseNode * if_node = NULL; |
293 |
|
if (p->pn_type == TOK_IF) { |
294 |
|
if_node = p; |
295 |
|
assert(if_node->pn_arity == PN_TERNARY); |
296 |
|
p = if_node->pn_kid2; |
297 |
|
} |
298 |
|
assert(p->pn_arity == PN_UNARY); |
299 |
|
p = p->pn_kid; |
300 |
|
if (p->pn_type == TOK_YIELD) { |
301 |
|
/* for generator expressions */ |
302 |
|
p = p->pn_kid; |
303 |
|
} |
304 |
|
|
305 |
|
instrument_expression(p, f); |
306 |
|
p = for_node; |
307 |
|
while (p->pn_type == TOK_FOR) { |
308 |
|
Stream_write_char(f, ' '); |
309 |
|
output_for_in(p, f); |
310 |
|
p = p->pn_right; |
311 |
|
} |
312 |
|
if (if_node) { |
313 |
|
Stream_write_string(f, " if ("); |
314 |
|
instrument_expression(if_node->pn_kid1, f); |
315 |
|
Stream_write_char(f, ')'); |
316 |
|
} |
317 |
|
} |
318 |
|
|
319 |
static void instrument_function(JSParseNode * node, Stream * f, int indent, enum FunctionType type) { |
static void instrument_function(JSParseNode * node, Stream * f, int indent, enum FunctionType type) { |
320 |
assert(node->pn_type == TOK_FUNCTION); |
assert(node->pn_type == TOK_FUNCTION); |
321 |
assert(node->pn_arity == PN_FUNC); |
assert(node->pn_arity == PN_FUNC); |
385 |
|
|
386 |
if (function_node->pn_flags & TCF_GENEXP_LAMBDA) { |
if (function_node->pn_flags & TCF_GENEXP_LAMBDA) { |
387 |
/* it's a generator expression */ |
/* it's a generator expression */ |
|
JSParseNode * lexical_scope_node = function_node->pn_body; |
|
|
assert(lexical_scope_node->pn_type == TOK_LEXICALSCOPE); |
|
|
assert(lexical_scope_node->pn_arity == PN_NAME); |
|
|
JSParseNode * for_node = lexical_scope_node->pn_body; |
|
|
assert(for_node->pn_type == TOK_FOR); |
|
|
assert(for_node->pn_arity == PN_BINARY); |
|
|
JSParseNode * if_node = NULL; |
|
|
JSParseNode * semi_node; |
|
|
switch (for_node->pn_right->pn_type) { |
|
|
case TOK_SEMI: |
|
|
semi_node = for_node->pn_right; |
|
|
break; |
|
|
case TOK_IF: |
|
|
if_node = for_node->pn_right; |
|
|
assert(if_node->pn_arity == PN_TERNARY); |
|
|
semi_node = if_node->pn_kid2; |
|
|
assert(semi_node->pn_type == TOK_SEMI); |
|
|
break; |
|
|
default: |
|
|
abort(); |
|
|
break; |
|
|
} |
|
|
assert(semi_node->pn_arity == PN_UNARY); |
|
|
JSParseNode * yield_node = semi_node->pn_kid; |
|
|
assert(yield_node->pn_type == TOK_YIELD); |
|
388 |
Stream_write_char(f, '('); |
Stream_write_char(f, '('); |
389 |
instrument_expression(yield_node->pn_kid, f); |
output_array_comprehension_or_generator_expression(function_node->pn_body, f); |
|
Stream_write_char(f, ' '); |
|
|
output_for_in(for_node, f); |
|
|
if (if_node) { |
|
|
Stream_write_string(f, " if ("); |
|
|
instrument_expression(if_node->pn_kid1, f); |
|
|
Stream_write_char(f, ')'); |
|
|
} |
|
390 |
Stream_write_char(f, ')'); |
Stream_write_char(f, ')'); |
391 |
return; |
return; |
392 |
} |
} |
789 |
abort(); |
abort(); |
790 |
break; |
break; |
791 |
} |
} |
|
assert(block_node->pn_type == TOK_LEXICALSCOPE); |
|
|
assert(block_node->pn_arity == PN_NAME); |
|
|
JSParseNode * for_node = block_node->pn_expr; |
|
|
assert(for_node->pn_type == TOK_FOR); |
|
|
assert(for_node->pn_arity == PN_BINARY); |
|
|
JSParseNode * if_node = NULL; |
|
|
JSParseNode * push_node; |
|
|
switch (for_node->pn_right->pn_type) { |
|
|
case TOK_ARRAYPUSH: |
|
|
push_node = for_node->pn_right; |
|
|
assert(push_node->pn_arity == PN_UNARY); |
|
|
break; |
|
|
case TOK_IF: |
|
|
if_node = for_node->pn_right; |
|
|
assert(if_node->pn_arity == PN_TERNARY); |
|
|
push_node = if_node->pn_kid2; |
|
|
break; |
|
|
default: |
|
|
abort(); |
|
|
break; |
|
|
} |
|
792 |
Stream_write_char(f, '['); |
Stream_write_char(f, '['); |
793 |
instrument_expression(push_node->pn_kid, f); |
output_array_comprehension_or_generator_expression(block_node, f); |
|
Stream_write_char(f, ' '); |
|
|
output_for_in(for_node, f); |
|
|
if (if_node) { |
|
|
Stream_write_string(f, " if ("); |
|
|
instrument_expression(if_node->pn_kid1, f); |
|
|
Stream_write_char(f, ')'); |
|
|
} |
|
794 |
Stream_write_char(f, ']'); |
Stream_write_char(f, ']'); |
795 |
} |
} |
796 |
break; |
break; |
1294 |
|
|
1295 |
/* write line number info to the output */ |
/* write line number info to the output */ |
1296 |
Stream_write_string(output, "/* automatically generated by JSCoverage - do not edit */\n"); |
Stream_write_string(output, "/* automatically generated by JSCoverage - do not edit */\n"); |
1297 |
Stream_write_string(output, "if (! top._$jscoverage) {\n top._$jscoverage = {};\n}\n"); |
if (jscoverage_mozilla) { |
1298 |
Stream_write_string(output, "var _$jscoverage = top._$jscoverage;\n"); |
Stream_write_string(output, "try {\n"); |
1299 |
|
Stream_write_string(output, " Components.utils.import('resource://gre/modules/jscoverage.jsm');\n"); |
1300 |
|
Stream_printf(output, " dump('%s: successfully imported jscoverage module\\n');\n", id); |
1301 |
|
Stream_write_string(output, "}\n"); |
1302 |
|
Stream_write_string(output, "catch (e) {\n"); |
1303 |
|
Stream_write_string(output, " _$jscoverage = {};\n"); |
1304 |
|
Stream_printf(output, " dump('%s: failed to import jscoverage module - coverage not available for this file\\n');\n", id); |
1305 |
|
Stream_write_string(output, "}\n"); |
1306 |
|
} |
1307 |
|
else { |
1308 |
|
Stream_write_string(output, "if (! top._$jscoverage) {\n top._$jscoverage = {};\n}\n"); |
1309 |
|
Stream_write_string(output, "var _$jscoverage = top._$jscoverage;\n"); |
1310 |
|
} |
1311 |
Stream_printf(output, "if (! _$jscoverage['%s']) {\n", file_id); |
Stream_printf(output, "if (! _$jscoverage['%s']) {\n", file_id); |
1312 |
Stream_printf(output, " _$jscoverage['%s'] = [];\n", file_id); |
Stream_printf(output, " _$jscoverage['%s'] = [];\n", file_id); |
1313 |
for (int i = 0; i < num_lines; i++) { |
for (int i = 0; i < num_lines; i++) { |