Index: instrument-js.cpp =================================================================== --- instrument-js.cpp (revision 611) +++ instrument-js.cpp (working copy) @@ -140,6 +140,15 @@ } } +static void print_string_unescaped(JSString * s, Stream * f) { + size_t length; + const jschar * characters; + s->getCharsAndLength(characters, length); + for (size_t i = 0; i < length; i++) { + Stream_write_char(f, characters[i]); + } +} + static void print_string(JSString * s, Stream * f) { size_t length; const jschar * characters; @@ -201,6 +210,12 @@ print_string(s, f); } +static void print_string_atom_unescaped(JSAtom * atom, Stream * f) { + assert(ATOM_IS_STRING(atom)); + JSString * s = ATOM_TO_STRING(atom); + print_string_unescaped(s, f); +} + static void print_regex(jsval value, Stream * f) { assert(JSVAL_IS_STRING(value)); JSString * s = JSVAL_TO_STRING(value); @@ -551,15 +566,60 @@ } } +static void output_xmlelem(JSParseNode *node, Stream *f, bool parenthesize_object_literals) { + switch (node->pn_type) { + case TOK_XMLELEM: + assert(node->pn_arity == PN_LIST); + for (struct JSParseNode * p = node->pn_head; p != NULL; p = p->pn_next) { + output_xmlelem(p, f, parenthesize_object_literals); + } + + break; + case TOK_XMLTEXT: + assert(node->pn_arity == PN_NULLARY); + if (node->pn_atom != NULL) { + print_string_atom_unescaped(node->pn_atom, f); + } + break; + // TODO how much of this is really needed? + case TOK_XMLSTAGO: + Stream_write_char(f, '<'); + break; + case TOK_XMLETAGO: + Stream_write_char(f, '<'); + Stream_write_char(f, '/'); + break; + case TOK_XMLPTAGC: + Stream_write_char(f, '/'); + Stream_write_char(f, '>'); + break; + case TOK_XMLTAGC: + Stream_write_char(f, '>'); + break; + + + case TOK_LC: + Stream_write_char(f, '{'); + output_expression(node->pn_kid, f, false); + Stream_write_char(f, '}'); + break; + case TOK_AT: + // TODO here or in output_expression? + Stream_write_char(f, '@'); + output_expression(node->pn_kid, f, false); + break; + + default: + fatal_source(file_id, node->pn_pos.begin.lineno, "unsupported node type (%u)", (unsigned int) node->pn_type); + break; + } +} + + /* See in jsparse.h. TOK_FUNCTION is handled as a statement and as an expression. -TOK_DBLDOT is not handled (XML op). TOK_DEFSHARP and TOK_USESHARP are not handled. -TOK_ANYNAME is not handled (XML op). -TOK_AT is not handled (XML op). -TOK_DBLCOLON is not handled. -TOK_XML* are not handled. There seem to be some undocumented expressions: TOK_INSTANCEOF binary TOK_IN binary @@ -683,6 +743,13 @@ Stream_write_string(f, "void "); output_expression(node->pn_kid, f, false); break; + case JSOP_POPN: + Stream_write_string(f, "POPN!? "); // TODO + output_expression(node->pn_kid, f, false); + break; + case JSOP_XMLNAME: + output_expression(node->pn_kid, f, false); + break; default: fatal_source(file_id, node->pn_pos.begin.lineno, "unknown operator (%u)", (unsigned int) node->pn_op); break; @@ -1009,6 +1076,50 @@ Stream_write_string(f, "let "); instrument_declarations(node, f); break; + case TOK_XMLELEM: + output_xmlelem(node, f, parenthesize_object_literals); + break; + case TOK_AT: + Stream_write_char(f, '@'); + output_expression(node->pn_kid, f, false); + break; + case TOK_DBLCOLON: + if (node->pn_arity == PN_NAME) { + output_expression(node->pn_expr, f, false); + Stream_write_string(f, "::"); + print_string_atom(node->pn_atom, f); + } else if (node->pn_arity == PN_BINARY) { + output_expression(node->pn_left, f, false); + Stream_write_string(f, "::"); + output_expression(node->pn_right, f, false); + } + break; + case TOK_FILTER: + output_expression(node->pn_left, f, false); + Stream_write_string(f, ".("); + output_expression(node->pn_right, f, false); + Stream_write_char(f, ')'); + break; + case TOK_XMLSTAGO: + Stream_write_char(f, '<'); + break; + case TOK_XMLETAGO: + Stream_write_string(f, ""); + break; + case TOK_XMLTAGC: + Stream_write_char(f, '>'); + break; + case TOK_ANYNAME: + print_string_atom(node->pn_atom, f); + break; + case TOK_DBLDOT: + output_expression(node->pn_left, f, false); + Stream_write_string(f, ".."); + output_expression(node->pn_right, f, false); + break; default: fatal_source(file_id, node->pn_pos.begin.lineno, "unsupported node type (%u)", (unsigned int) node->pn_type); } @@ -1115,9 +1226,19 @@ Stream_write_string(f, "}\n"); break; case TOK_CASE: - case TOK_DEFAULT: abort(); break; + case TOK_DEFAULT: + // This could be a statment like "default xml namespace = D" + if (node->pn_arity == PN_UNARY) { + Stream_printf(f, "%*s", indent, ""); + Stream_write_string(f, "default xml namespace = "); + output_expression(node->pn_kid, f, false); + Stream_write_string(f, ";"); + } else { + abort(); + } + break; case TOK_WHILE: assert(node->pn_arity == PN_BINARY); Stream_printf(f, "%*s", indent, "");