267 |
} |
} |
268 |
} |
} |
269 |
|
|
270 |
static void instrument_expression(JSParseNode * node, Stream * f); |
static void output_expression(JSParseNode * node, Stream * f, bool parenthesize_object_literals); |
271 |
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); |
272 |
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); |
273 |
|
|
284 |
Stream_write_string(f, "each "); |
Stream_write_string(f, "each "); |
285 |
} |
} |
286 |
Stream_write_char(f, '('); |
Stream_write_char(f, '('); |
287 |
instrument_expression(node->pn_left, f); |
output_expression(node->pn_left, f, false); |
288 |
Stream_write_char(f, ')'); |
Stream_write_char(f, ')'); |
289 |
} |
} |
290 |
|
|
311 |
p = p->pn_kid; |
p = p->pn_kid; |
312 |
} |
} |
313 |
|
|
314 |
instrument_expression(p, f); |
output_expression(p, f, false); |
315 |
p = for_node; |
p = for_node; |
316 |
while (p->pn_type == TOK_FOR) { |
while (p->pn_type == TOK_FOR) { |
317 |
Stream_write_char(f, ' '); |
Stream_write_char(f, ' '); |
320 |
} |
} |
321 |
if (if_node) { |
if (if_node) { |
322 |
Stream_write_string(f, " if ("); |
Stream_write_string(f, " if ("); |
323 |
instrument_expression(if_node->pn_kid1, f); |
output_expression(if_node->pn_kid1, f, false); |
324 |
Stream_write_char(f, ')'); |
Stream_write_char(f, ')'); |
325 |
} |
} |
326 |
} |
} |
381 |
} |
} |
382 |
} |
} |
383 |
assert(expression != NULL); |
assert(expression != NULL); |
384 |
instrument_expression(expression, f); |
output_expression(expression, f, false); |
385 |
} |
} |
386 |
else { |
else { |
387 |
print_string_atom(param, f); |
print_string_atom(param, f); |
414 |
} |
} |
415 |
} |
} |
416 |
|
|
417 |
Stream_write_string(f, "}\n"); |
Stream_write_char(f, '}'); |
418 |
} |
} |
419 |
|
|
420 |
static void instrument_function_call(JSParseNode * node, Stream * f) { |
static void instrument_function_call(JSParseNode * node, Stream * f) { |
433 |
Stream_write_char(f, ')'); |
Stream_write_char(f, ')'); |
434 |
return; |
return; |
435 |
} |
} |
|
else { |
|
|
Stream_write_char(f, '('); |
|
|
instrument_expression(function_node, f); |
|
|
Stream_write_char(f, ')'); |
|
|
} |
|
|
} |
|
|
else { |
|
|
instrument_expression(function_node, f); |
|
436 |
} |
} |
437 |
|
output_expression(function_node, f, false); |
438 |
Stream_write_char(f, '('); |
Stream_write_char(f, '('); |
439 |
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) { |
440 |
if (p != node->pn_head->pn_next) { |
if (p != node->pn_head->pn_next) { |
441 |
Stream_write_string(f, ", "); |
Stream_write_string(f, ", "); |
442 |
} |
} |
443 |
instrument_expression(p, f); |
output_expression(p, f, false); |
444 |
} |
} |
445 |
Stream_write_char(f, ')'); |
Stream_write_char(f, ')'); |
446 |
} |
} |
448 |
static void instrument_declarations(JSParseNode * list, Stream * f) { |
static void instrument_declarations(JSParseNode * list, Stream * f) { |
449 |
assert(list->pn_arity == PN_LIST); |
assert(list->pn_arity == PN_LIST); |
450 |
for (JSParseNode * p = list->pn_head; p != NULL; p = p->pn_next) { |
for (JSParseNode * p = list->pn_head; p != NULL; p = p->pn_next) { |
451 |
switch (p->pn_type) { |
if (p != list->pn_head) { |
452 |
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; |
|
453 |
} |
} |
454 |
|
output_expression(p, f, false); |
455 |
} |
} |
456 |
} |
} |
457 |
|
|
468 |
TOK_INSTANCEOF binary |
TOK_INSTANCEOF binary |
469 |
TOK_IN binary |
TOK_IN binary |
470 |
*/ |
*/ |
471 |
static void instrument_expression(JSParseNode * node, Stream * f) { |
static void output_expression(JSParseNode * node, Stream * f, bool parenthesize_object_literals) { |
472 |
switch (node->pn_type) { |
switch (node->pn_type) { |
473 |
case TOK_FUNCTION: |
case TOK_FUNCTION: |
474 |
|
Stream_write_char(f, '('); |
475 |
instrument_function(node, f, 0, FUNCTION_NORMAL); |
instrument_function(node, f, 0, FUNCTION_NORMAL); |
476 |
|
Stream_write_char(f, ')'); |
477 |
break; |
break; |
478 |
case TOK_COMMA: |
case TOK_COMMA: |
479 |
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) { |
480 |
if (p != node->pn_head) { |
if (p != node->pn_head) { |
481 |
Stream_write_string(f, ", "); |
Stream_write_string(f, ", "); |
482 |
} |
} |
483 |
instrument_expression(p, f); |
output_expression(p, f, parenthesize_object_literals); |
484 |
} |
} |
485 |
break; |
break; |
486 |
case TOK_ASSIGN: |
case TOK_ASSIGN: |
487 |
instrument_expression(node->pn_left, f); |
output_expression(node->pn_left, f, parenthesize_object_literals); |
488 |
Stream_write_char(f, ' '); |
Stream_write_char(f, ' '); |
489 |
switch (node->pn_op) { |
switch (node->pn_op) { |
490 |
case JSOP_ADD: |
case JSOP_ADD: |
505 |
break; |
break; |
506 |
} |
} |
507 |
Stream_write_string(f, "= "); |
Stream_write_string(f, "= "); |
508 |
instrument_expression(node->pn_right, f); |
output_expression(node->pn_right, f, false); |
509 |
break; |
break; |
510 |
case TOK_HOOK: |
case TOK_HOOK: |
511 |
instrument_expression(node->pn_kid1, f); |
output_expression(node->pn_kid1, f, parenthesize_object_literals); |
512 |
Stream_write_string(f, "? "); |
Stream_write_string(f, "? "); |
513 |
instrument_expression(node->pn_kid2, f); |
output_expression(node->pn_kid2, f, false); |
514 |
Stream_write_string(f, ": "); |
Stream_write_string(f, ": "); |
515 |
instrument_expression(node->pn_kid3, f); |
output_expression(node->pn_kid3, f, false); |
516 |
break; |
break; |
517 |
case TOK_OR: |
case TOK_OR: |
518 |
case TOK_AND: |
case TOK_AND: |
528 |
case TOK_DIVOP: |
case TOK_DIVOP: |
529 |
switch (node->pn_arity) { |
switch (node->pn_arity) { |
530 |
case PN_BINARY: |
case PN_BINARY: |
531 |
instrument_expression(node->pn_left, f); |
output_expression(node->pn_left, f, parenthesize_object_literals); |
532 |
Stream_printf(f, " %s ", get_op(node->pn_op)); |
Stream_printf(f, " %s ", get_op(node->pn_op)); |
533 |
instrument_expression(node->pn_right, f); |
output_expression(node->pn_right, f, false); |
534 |
break; |
break; |
535 |
case PN_LIST: |
case PN_LIST: |
536 |
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) { |
537 |
if (p != node->pn_head) { |
if (p == node->pn_head) { |
538 |
|
output_expression(p, f, parenthesize_object_literals); |
539 |
|
} |
540 |
|
else { |
541 |
Stream_printf(f, " %s ", get_op(node->pn_op)); |
Stream_printf(f, " %s ", get_op(node->pn_op)); |
542 |
|
output_expression(p, f, false); |
543 |
} |
} |
|
instrument_expression(p, f); |
|
544 |
} |
} |
545 |
break; |
break; |
546 |
default: |
default: |
550 |
case TOK_UNARYOP: |
case TOK_UNARYOP: |
551 |
switch (node->pn_op) { |
switch (node->pn_op) { |
552 |
case JSOP_NEG: |
case JSOP_NEG: |
553 |
Stream_write_char(f, '-'); |
Stream_write_string(f, "- "); |
554 |
instrument_expression(node->pn_kid, f); |
output_expression(node->pn_kid, f, false); |
555 |
break; |
break; |
556 |
case JSOP_POS: |
case JSOP_POS: |
557 |
Stream_write_char(f, '+'); |
Stream_write_string(f, "+ "); |
558 |
instrument_expression(node->pn_kid, f); |
output_expression(node->pn_kid, f, false); |
559 |
break; |
break; |
560 |
case JSOP_NOT: |
case JSOP_NOT: |
561 |
Stream_write_char(f, '!'); |
Stream_write_string(f, "! "); |
562 |
instrument_expression(node->pn_kid, f); |
output_expression(node->pn_kid, f, false); |
563 |
break; |
break; |
564 |
case JSOP_BITNOT: |
case JSOP_BITNOT: |
565 |
Stream_write_char(f, '~'); |
Stream_write_string(f, "~ "); |
566 |
instrument_expression(node->pn_kid, f); |
output_expression(node->pn_kid, f, false); |
567 |
break; |
break; |
568 |
case JSOP_TYPEOF: |
case JSOP_TYPEOF: |
569 |
Stream_write_string(f, "typeof "); |
Stream_write_string(f, "typeof "); |
570 |
instrument_expression(node->pn_kid, f); |
output_expression(node->pn_kid, f, false); |
571 |
break; |
break; |
572 |
case JSOP_VOID: |
case JSOP_VOID: |
573 |
Stream_write_string(f, "void "); |
Stream_write_string(f, "void "); |
574 |
instrument_expression(node->pn_kid, f); |
output_expression(node->pn_kid, f, false); |
575 |
break; |
break; |
576 |
default: |
default: |
577 |
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); |
588 |
case JSOP_INCPROP: |
case JSOP_INCPROP: |
589 |
case JSOP_INCELEM: |
case JSOP_INCELEM: |
590 |
Stream_write_string(f, "++"); |
Stream_write_string(f, "++"); |
591 |
instrument_expression(node->pn_kid, f); |
output_expression(node->pn_kid, f, false); |
592 |
break; |
break; |
593 |
case JSOP_DECNAME: |
case JSOP_DECNAME: |
594 |
case JSOP_DECPROP: |
case JSOP_DECPROP: |
595 |
case JSOP_DECELEM: |
case JSOP_DECELEM: |
596 |
Stream_write_string(f, "--"); |
Stream_write_string(f, "--"); |
597 |
instrument_expression(node->pn_kid, f); |
output_expression(node->pn_kid, f, false); |
598 |
break; |
break; |
599 |
case JSOP_NAMEINC: |
case JSOP_NAMEINC: |
600 |
case JSOP_PROPINC: |
case JSOP_PROPINC: |
601 |
case JSOP_ELEMINC: |
case JSOP_ELEMINC: |
602 |
instrument_expression(node->pn_kid, f); |
output_expression(node->pn_kid, f, parenthesize_object_literals); |
603 |
Stream_write_string(f, "++"); |
Stream_write_string(f, "++"); |
604 |
break; |
break; |
605 |
case JSOP_NAMEDEC: |
case JSOP_NAMEDEC: |
606 |
case JSOP_PROPDEC: |
case JSOP_PROPDEC: |
607 |
case JSOP_ELEMDEC: |
case JSOP_ELEMDEC: |
608 |
instrument_expression(node->pn_kid, f); |
output_expression(node->pn_kid, f, parenthesize_object_literals); |
609 |
Stream_write_string(f, "--"); |
Stream_write_string(f, "--"); |
610 |
break; |
break; |
611 |
default: |
default: |
619 |
break; |
break; |
620 |
case TOK_DELETE: |
case TOK_DELETE: |
621 |
Stream_write_string(f, "delete "); |
Stream_write_string(f, "delete "); |
622 |
instrument_expression(node->pn_kid, f); |
output_expression(node->pn_kid, f, false); |
623 |
break; |
break; |
624 |
case TOK_DOT: |
case TOK_DOT: |
625 |
|
/* numeric literals must be parenthesized */ |
626 |
|
switch (node->pn_expr->pn_type) { |
627 |
|
case TOK_NUMBER: |
628 |
|
Stream_write_char(f, '('); |
629 |
|
output_expression(node->pn_expr, f, false); |
630 |
|
Stream_write_char(f, ')'); |
631 |
|
break; |
632 |
|
default: |
633 |
|
output_expression(node->pn_expr, f, true); |
634 |
|
break; |
635 |
|
} |
636 |
/* |
/* |
637 |
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' |
638 |
contains illegal characters, we have to use the subscript syntax instead of |
contains illegal characters, we have to use the subscript syntax instead of |
639 |
the dot syntax. |
the dot syntax. |
640 |
*/ |
*/ |
|
instrument_expression(node->pn_expr, f); |
|
641 |
assert(ATOM_IS_STRING(node->pn_atom)); |
assert(ATOM_IS_STRING(node->pn_atom)); |
642 |
{ |
{ |
643 |
JSString * s = ATOM_TO_STRING(node->pn_atom); |
JSString * s = ATOM_TO_STRING(node->pn_atom); |
666 |
} |
} |
667 |
break; |
break; |
668 |
case TOK_LB: |
case TOK_LB: |
669 |
instrument_expression(node->pn_left, f); |
output_expression(node->pn_left, f, false); |
670 |
Stream_write_char(f, '['); |
Stream_write_char(f, '['); |
671 |
instrument_expression(node->pn_right, f); |
output_expression(node->pn_right, f, false); |
672 |
Stream_write_char(f, ']'); |
Stream_write_char(f, ']'); |
673 |
break; |
break; |
674 |
case TOK_LP: |
case TOK_LP: |
682 |
} |
} |
683 |
/* TOK_COMMA is a special case: a hole in the array */ |
/* TOK_COMMA is a special case: a hole in the array */ |
684 |
if (p->pn_type != TOK_COMMA) { |
if (p->pn_type != TOK_COMMA) { |
685 |
instrument_expression(p, f); |
output_expression(p, f, false); |
686 |
} |
} |
687 |
} |
} |
688 |
if (node->pn_extra == PNX_ENDCOMMA) { |
if (node->pn_extra == PNX_ENDCOMMA) { |
691 |
Stream_write_char(f, ']'); |
Stream_write_char(f, ']'); |
692 |
break; |
break; |
693 |
case TOK_RC: |
case TOK_RC: |
694 |
|
if (parenthesize_object_literals) { |
695 |
|
Stream_write_char(f, '('); |
696 |
|
} |
697 |
Stream_write_char(f, '{'); |
Stream_write_char(f, '{'); |
698 |
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) { |
699 |
if (p->pn_type != TOK_COLON) { |
if (p->pn_type != TOK_COLON) { |
713 |
else { |
else { |
714 |
Stream_write_string(f, "set "); |
Stream_write_string(f, "set "); |
715 |
} |
} |
716 |
instrument_expression(p->pn_left, f); |
output_expression(p->pn_left, f, false); |
717 |
if (p->pn_right->pn_type != TOK_FUNCTION) { |
if (p->pn_right->pn_type != TOK_FUNCTION) { |
718 |
fatal_source(file_id, p->pn_pos.begin.lineno, "expected function"); |
fatal_source(file_id, p->pn_pos.begin.lineno, "expected function"); |
719 |
} |
} |
720 |
instrument_function(p->pn_right, f, 0, FUNCTION_GETTER_OR_SETTER); |
instrument_function(p->pn_right, f, 0, FUNCTION_GETTER_OR_SETTER); |
721 |
break; |
break; |
722 |
default: |
default: |
723 |
instrument_expression(p->pn_left, f); |
output_expression(p->pn_left, f, false); |
724 |
Stream_write_string(f, ": "); |
Stream_write_string(f, ": "); |
725 |
instrument_expression(p->pn_right, f); |
output_expression(p->pn_right, f, false); |
726 |
break; |
break; |
727 |
} |
} |
728 |
} |
} |
729 |
Stream_write_char(f, '}'); |
Stream_write_char(f, '}'); |
730 |
|
if (parenthesize_object_literals) { |
731 |
|
Stream_write_char(f, ')'); |
732 |
|
} |
733 |
break; |
break; |
734 |
case TOK_RP: |
case TOK_RP: |
735 |
Stream_write_char(f, '('); |
Stream_write_char(f, '('); |
736 |
instrument_expression(node->pn_kid, f); |
output_expression(node->pn_kid, f, false); |
737 |
Stream_write_char(f, ')'); |
Stream_write_char(f, ')'); |
738 |
break; |
break; |
739 |
case TOK_NAME: |
case TOK_NAME: |
740 |
print_string_atom(node->pn_atom, f); |
print_string_atom(node->pn_atom, f); |
741 |
|
if (node->pn_expr != NULL) { |
742 |
|
Stream_write_string(f, " = "); |
743 |
|
output_expression(node->pn_expr, f, false); |
744 |
|
} |
745 |
break; |
break; |
746 |
case TOK_STRING: |
case TOK_STRING: |
747 |
print_quoted_string_atom(node->pn_atom, f); |
print_quoted_string_atom(node->pn_atom, f); |
789 |
} |
} |
790 |
break; |
break; |
791 |
case TOK_INSTANCEOF: |
case TOK_INSTANCEOF: |
792 |
instrument_expression(node->pn_left, f); |
output_expression(node->pn_left, f, parenthesize_object_literals); |
793 |
Stream_write_string(f, " instanceof "); |
Stream_write_string(f, " instanceof "); |
794 |
instrument_expression(node->pn_right, f); |
output_expression(node->pn_right, f, false); |
795 |
break; |
break; |
796 |
case TOK_IN: |
case TOK_IN: |
797 |
instrument_expression(node->pn_left, f); |
output_expression(node->pn_left, f, false); |
798 |
Stream_write_string(f, " in "); |
Stream_write_string(f, " in "); |
799 |
instrument_expression(node->pn_right, f); |
output_expression(node->pn_right, f, false); |
800 |
break; |
break; |
801 |
case TOK_LEXICALSCOPE: |
case TOK_LEXICALSCOPE: |
802 |
assert(node->pn_arity == PN_NAME); |
assert(node->pn_arity == PN_NAME); |
807 |
assert(node->pn_expr->pn_left->pn_arity == PN_LIST); |
assert(node->pn_expr->pn_left->pn_arity == PN_LIST); |
808 |
instrument_declarations(node->pn_expr->pn_left, f); |
instrument_declarations(node->pn_expr->pn_left, f); |
809 |
Stream_write_string(f, ") "); |
Stream_write_string(f, ") "); |
810 |
instrument_expression(node->pn_expr->pn_right, f); |
output_expression(node->pn_expr->pn_right, f, true); |
811 |
break; |
break; |
812 |
case TOK_YIELD: |
case TOK_YIELD: |
813 |
assert(node->pn_arity == PN_UNARY); |
assert(node->pn_arity == PN_UNARY); |
814 |
Stream_write_string(f, "yield"); |
Stream_write_string(f, "yield"); |
815 |
if (node->pn_kid != NULL) { |
if (node->pn_kid != NULL) { |
816 |
Stream_write_char(f, ' '); |
Stream_write_char(f, ' '); |
817 |
instrument_expression(node->pn_kid, f); |
output_expression(node->pn_kid, f, true); |
818 |
} |
} |
819 |
break; |
break; |
820 |
case TOK_ARRAYCOMP: |
case TOK_ARRAYCOMP: |
856 |
switch (node->pn_type) { |
switch (node->pn_type) { |
857 |
case TOK_FUNCTION: |
case TOK_FUNCTION: |
858 |
instrument_function(node, f, indent, FUNCTION_NORMAL); |
instrument_function(node, f, indent, FUNCTION_NORMAL); |
859 |
|
Stream_write_char(f, '\n'); |
860 |
break; |
break; |
861 |
case TOK_LC: |
case TOK_LC: |
862 |
assert(node->pn_arity == PN_LIST); |
assert(node->pn_arity == PN_LIST); |
887 |
|
|
888 |
Stream_printf(f, "%*s", indent, ""); |
Stream_printf(f, "%*s", indent, ""); |
889 |
Stream_write_string(f, "if ("); |
Stream_write_string(f, "if ("); |
890 |
instrument_expression(node->pn_kid1, f); |
output_expression(node->pn_kid1, f, false); |
891 |
Stream_write_string(f, ") {\n"); |
Stream_write_string(f, ") {\n"); |
892 |
if (is_jscoverage_if && node->pn_kid3) { |
if (is_jscoverage_if && node->pn_kid3) { |
893 |
uint16_t else_start = node->pn_kid3->pn_pos.begin.lineno; |
uint16_t else_start = node->pn_kid3->pn_pos.begin.lineno; |
924 |
assert(node->pn_arity == PN_BINARY); |
assert(node->pn_arity == PN_BINARY); |
925 |
Stream_printf(f, "%*s", indent, ""); |
Stream_printf(f, "%*s", indent, ""); |
926 |
Stream_write_string(f, "switch ("); |
Stream_write_string(f, "switch ("); |
927 |
instrument_expression(node->pn_left, f); |
output_expression(node->pn_left, f, false); |
928 |
Stream_write_string(f, ") {\n"); |
Stream_write_string(f, ") {\n"); |
929 |
{ |
{ |
930 |
JSParseNode * list = node->pn_right; |
JSParseNode * list = node->pn_right; |
936 |
switch (p->pn_type) { |
switch (p->pn_type) { |
937 |
case TOK_CASE: |
case TOK_CASE: |
938 |
Stream_write_string(f, "case "); |
Stream_write_string(f, "case "); |
939 |
instrument_expression(p->pn_left, f); |
output_expression(p->pn_left, f, false); |
940 |
Stream_write_string(f, ":\n"); |
Stream_write_string(f, ":\n"); |
941 |
break; |
break; |
942 |
case TOK_DEFAULT: |
case TOK_DEFAULT: |
960 |
assert(node->pn_arity == PN_BINARY); |
assert(node->pn_arity == PN_BINARY); |
961 |
Stream_printf(f, "%*s", indent, ""); |
Stream_printf(f, "%*s", indent, ""); |
962 |
Stream_write_string(f, "while ("); |
Stream_write_string(f, "while ("); |
963 |
instrument_expression(node->pn_left, f); |
output_expression(node->pn_left, f, false); |
964 |
Stream_write_string(f, ") {\n"); |
Stream_write_string(f, ") {\n"); |
965 |
instrument_statement(node->pn_right, f, indent + 2, false); |
instrument_statement(node->pn_right, f, indent + 2, false); |
966 |
Stream_write_string(f, "}\n"); |
Stream_write_string(f, "}\n"); |
973 |
Stream_write_string(f, "}\n"); |
Stream_write_string(f, "}\n"); |
974 |
Stream_printf(f, "%*s", indent, ""); |
Stream_printf(f, "%*s", indent, ""); |
975 |
Stream_write_string(f, "while ("); |
Stream_write_string(f, "while ("); |
976 |
instrument_expression(node->pn_right, f); |
output_expression(node->pn_right, f, false); |
977 |
Stream_write_string(f, ");\n"); |
Stream_write_string(f, ");\n"); |
978 |
break; |
break; |
979 |
case TOK_FOR: |
case TOK_FOR: |
990 |
assert(node->pn_left->pn_arity == PN_TERNARY); |
assert(node->pn_left->pn_arity == PN_TERNARY); |
991 |
Stream_write_string(f, "for ("); |
Stream_write_string(f, "for ("); |
992 |
if (node->pn_left->pn_kid1) { |
if (node->pn_left->pn_kid1) { |
993 |
instrument_expression(node->pn_left->pn_kid1, f); |
output_expression(node->pn_left->pn_kid1, f, false); |
994 |
} |
} |
995 |
Stream_write_string(f, ";"); |
Stream_write_string(f, ";"); |
996 |
if (node->pn_left->pn_kid2) { |
if (node->pn_left->pn_kid2) { |
997 |
Stream_write_char(f, ' '); |
Stream_write_char(f, ' '); |
998 |
instrument_expression(node->pn_left->pn_kid2, f); |
output_expression(node->pn_left->pn_kid2, f, false); |
999 |
} |
} |
1000 |
Stream_write_string(f, ";"); |
Stream_write_string(f, ";"); |
1001 |
if (node->pn_left->pn_kid3) { |
if (node->pn_left->pn_kid3) { |
1002 |
Stream_write_char(f, ' '); |
Stream_write_char(f, ' '); |
1003 |
instrument_expression(node->pn_left->pn_kid3, f); |
output_expression(node->pn_left->pn_kid3, f, false); |
1004 |
} |
} |
1005 |
Stream_write_char(f, ')'); |
Stream_write_char(f, ')'); |
1006 |
break; |
break; |
1016 |
assert(node->pn_arity == PN_UNARY); |
assert(node->pn_arity == PN_UNARY); |
1017 |
Stream_printf(f, "%*s", indent, ""); |
Stream_printf(f, "%*s", indent, ""); |
1018 |
Stream_write_string(f, "throw "); |
Stream_write_string(f, "throw "); |
1019 |
instrument_expression(node->pn_u.unary.kid, f); |
output_expression(node->pn_u.unary.kid, f, false); |
1020 |
Stream_write_string(f, ";\n"); |
Stream_write_string(f, ";\n"); |
1021 |
break; |
break; |
1022 |
case TOK_TRY: |
case TOK_TRY: |
1033 |
assert(catch->pn_type == TOK_CATCH); |
assert(catch->pn_type == TOK_CATCH); |
1034 |
Stream_printf(f, "%*s", indent, ""); |
Stream_printf(f, "%*s", indent, ""); |
1035 |
Stream_write_string(f, "catch ("); |
Stream_write_string(f, "catch ("); |
1036 |
/* 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); |
|
1037 |
if (catch->pn_kid2) { |
if (catch->pn_kid2) { |
1038 |
Stream_write_string(f, " if "); |
Stream_write_string(f, " if "); |
1039 |
instrument_expression(catch->pn_kid2, f); |
output_expression(catch->pn_kid2, f, false); |
1040 |
} |
} |
1041 |
Stream_write_string(f, ") {\n"); |
Stream_write_string(f, ") {\n"); |
1042 |
instrument_statement(catch->pn_kid3, f, indent + 2, false); |
instrument_statement(catch->pn_kid3, f, indent + 2, false); |
1071 |
assert(node->pn_arity == PN_BINARY); |
assert(node->pn_arity == PN_BINARY); |
1072 |
Stream_printf(f, "%*s", indent, ""); |
Stream_printf(f, "%*s", indent, ""); |
1073 |
Stream_write_string(f, "with ("); |
Stream_write_string(f, "with ("); |
1074 |
instrument_expression(node->pn_left, f); |
output_expression(node->pn_left, f, false); |
1075 |
Stream_write_string(f, ") {\n"); |
Stream_write_string(f, ") {\n"); |
1076 |
instrument_statement(node->pn_right, f, indent + 2, false); |
instrument_statement(node->pn_right, f, indent + 2, false); |
1077 |
Stream_printf(f, "%*s", indent, ""); |
Stream_printf(f, "%*s", indent, ""); |
1079 |
break; |
break; |
1080 |
case TOK_VAR: |
case TOK_VAR: |
1081 |
Stream_printf(f, "%*s", indent, ""); |
Stream_printf(f, "%*s", indent, ""); |
1082 |
instrument_expression(node, f); |
output_expression(node, f, false); |
1083 |
Stream_write_string(f, ";\n"); |
Stream_write_string(f, ";\n"); |
1084 |
break; |
break; |
1085 |
case TOK_RETURN: |
case TOK_RETURN: |
1088 |
Stream_write_string(f, "return"); |
Stream_write_string(f, "return"); |
1089 |
if (node->pn_kid != NULL) { |
if (node->pn_kid != NULL) { |
1090 |
Stream_write_char(f, ' '); |
Stream_write_char(f, ' '); |
1091 |
instrument_expression(node->pn_kid, f); |
output_expression(node->pn_kid, f, true); |
1092 |
} |
} |
1093 |
Stream_write_string(f, ";\n"); |
Stream_write_string(f, ";\n"); |
1094 |
break; |
break; |
1096 |
assert(node->pn_arity == PN_UNARY); |
assert(node->pn_arity == PN_UNARY); |
1097 |
Stream_printf(f, "%*s", indent, ""); |
Stream_printf(f, "%*s", indent, ""); |
1098 |
if (node->pn_kid != NULL) { |
if (node->pn_kid != NULL) { |
1099 |
instrument_expression(node->pn_kid, f); |
output_expression(node->pn_kid, f, true); |
1100 |
} |
} |
1101 |
Stream_write_string(f, ";\n"); |
Stream_write_string(f, ";\n"); |
1102 |
break; |
break; |
1103 |
case TOK_COLON: |
case TOK_COLON: |
1104 |
|
{ |
1105 |
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 ... |
|
|
*/ |
|
1106 |
Stream_printf(f, "%*s", indent < 2? 0: indent - 2, ""); |
Stream_printf(f, "%*s", indent < 2? 0: indent - 2, ""); |
1107 |
print_string_atom(node->pn_atom, f); |
print_string_atom(node->pn_atom, f); |
1108 |
Stream_write_string(f, ":\n"); |
Stream_write_string(f, ":\n"); |
1109 |
/* |
JSParseNode * labelled = node->pn_expr; |
1110 |
... use output_statement instead of instrument_statement. |
if (labelled->pn_type == TOK_LEXICALSCOPE) { |
1111 |
*/ |
labelled = labelled->pn_expr; |
1112 |
output_statement(node->pn_expr, f, indent, false); |
} |
1113 |
|
if (labelled->pn_type == TOK_LC) { |
1114 |
|
/* labelled block */ |
1115 |
|
Stream_printf(f, "%*s", indent, ""); |
1116 |
|
Stream_write_string(f, "{\n"); |
1117 |
|
instrument_statement(labelled, f, indent + 2, false); |
1118 |
|
Stream_printf(f, "%*s", indent, ""); |
1119 |
|
Stream_write_string(f, "}\n"); |
1120 |
|
} |
1121 |
|
else { |
1122 |
|
/* |
1123 |
|
This one is tricky: can't output instrumentation between the label and the |
1124 |
|
statement it's supposed to label, so use output_statement instead of |
1125 |
|
instrument_statement. |
1126 |
|
*/ |
1127 |
|
output_statement(labelled, f, indent, false); |
1128 |
|
} |
1129 |
break; |
break; |
1130 |
|
} |
1131 |
case TOK_LEXICALSCOPE: |
case TOK_LEXICALSCOPE: |
1132 |
/* let statement */ |
/* let statement */ |
1133 |
assert(node->pn_arity == PN_NAME); |
assert(node->pn_arity == PN_NAME); |
1170 |
case PN_LIST: |
case PN_LIST: |
1171 |
/* let definition */ |
/* let definition */ |
1172 |
Stream_printf(f, "%*s", indent, ""); |
Stream_printf(f, "%*s", indent, ""); |
1173 |
instrument_expression(node, f); |
output_expression(node, f, false); |
1174 |
Stream_write_string(f, ";\n"); |
Stream_write_string(f, ";\n"); |
1175 |
break; |
break; |
1176 |
default: |
default: |