From 843d04553164edfbb6ab5417a2e6e41035398bbf Mon Sep 17 00:00:00 2001 From: "mrbkap%gmail.com" Date: Tue, 26 Jul 2005 20:43:09 +0000 Subject: [PATCH] bug 301692: E4X toString quotes the returned XML string. r+a=shaver git-svn-id: svn://10.0.0.236/trunk@176633 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js/src/jsemit.c | 21 ++++++++++++++++++- mozilla/js/src/jsinterp.c | 4 ++++ mozilla/js/src/jsopcode.c | 42 ++++++++++++++++++++++++++++++++----- mozilla/js/src/jsopcode.tbl | 6 ++++++ 4 files changed, 67 insertions(+), 6 deletions(-) diff --git a/mozilla/js/src/jsemit.c b/mozilla/js/src/jsemit.c index 5ddfada1560..84d8817e3cd 100644 --- a/mozilla/js/src/jsemit.c +++ b/mozilla/js/src/jsemit.c @@ -2818,7 +2818,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn) intN noteIndex; JSSrcNoteType noteType; jsbytecode *pc; - JSOp op; + JSOp op, nextop; uint32 argc; int stackDummy; @@ -4709,7 +4709,17 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn) } JS_ASSERT(pn->pn_type == TOK_XMLLIST || pn->pn_count != 0); + nextop = pn->pn_head->pn_type; + if (nextop != TOK_XMLPTAGC && + nextop != TOK_XMLSTAGO && + nextop != TOK_XMLETAGO && /* XXX can this happen? */ + js_Emit1(cx, cg, JSOP_STARTXML) < 0) { + return JS_FALSE; + } + for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) { + if (pn2->pn_type == TOK_LC && js_Emit1(cx, cg, JSOP_JSEXPR) < 0) + return JS_FALSE; if (!js_EmitTree(cx, cg, pn2)) return JS_FALSE; if (pn2 != pn->pn_head && js_Emit1(cx, cg, JSOP_ADD) < 0) @@ -4746,6 +4756,9 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn) { uint32 i; + if (js_Emit1(cx, cg, JSOP_STARTXML) < 0) + return JS_FALSE; + ale = js_IndexAtom(cx, (pn->pn_type == TOK_XMLETAGO) ? cx->runtime->atomState.etagoAtom @@ -4757,12 +4770,18 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn) JS_ASSERT(pn->pn_count != 0); pn2 = pn->pn_head; + if (pn2->pn_type == TOK_LC && js_Emit1(cx, cg, JSOP_JSEXPR) < 0) + return JS_FALSE; if (!js_EmitTree(cx, cg, pn2)) return JS_FALSE; if (js_Emit1(cx, cg, JSOP_ADD) < 0) return JS_FALSE; for (pn2 = pn2->pn_next, i = 0; pn2; pn2 = pn2->pn_next, i++) { + if (pn2->pn_type == TOK_LC) { + if (!js_Emit1(cx, cg, JSOP_JSEXPR) < 0) + return JS_FALSE; + } if (!js_EmitTree(cx, cg, pn2)) return JS_FALSE; if ((i & 1) && pn2->pn_type == TOK_LC) { diff --git a/mozilla/js/src/jsinterp.c b/mozilla/js/src/jsinterp.c index 5a357355eb4..68704266f9b 100644 --- a/mozilla/js/src/jsinterp.c +++ b/mozilla/js/src/jsinterp.c @@ -5063,6 +5063,10 @@ js_Interpret(JSContext *cx, jsbytecode *pc, jsval *result) *result = POP_OPND(); goto out; + case JSOP_STARTXML: + case JSOP_JSEXPR: + break; + case JSOP_TOXML: rval = FETCH_OPND(-1); SAVE_SP(fp); diff --git a/mozilla/js/src/jsopcode.c b/mozilla/js/src/jsopcode.c index 4302574817e..224a0111fcf 100644 --- a/mozilla/js/src/jsopcode.c +++ b/mozilla/js/src/jsopcode.c @@ -841,6 +841,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb) JSFunction *fun; JSString *str; JSBool ok; + JSBool inXML; jsval val; static const char catch_cookie[] = "/*CATCH*/"; static const char with_cookie[] = "/*WITH*/"; @@ -898,6 +899,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb) op = JSOP_NOP; sn = NULL; rval = NULL; + inXML = JS_FALSE; while (pc < endpc) { lastop = op; @@ -925,9 +927,13 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb) if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) { /* Print only the right operand of the assignment-op. */ todo = SprintPut(&ss->sprinter, rval, strlen(rval)); - } else { + } else if (!inXML) { todo = Sprint(&ss->sprinter, "%s %s %s", lval, cs->token, rval); + } else { + /* In XML, just concatenate the two operands. */ + JS_ASSERT(op == JSOP_ADD); + todo = Sprint(&ss->sprinter, "%s%s", lval, rval); } break; @@ -2039,8 +2045,17 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb) END_LITOPX_CASE BEGIN_LITOPX_CASE(JSOP_STRING) - rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), - (jschar)'"'); + if (!inXML) { + rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), + (jschar)'"'); + } else { + /* Don't quote strings in XML mode. */ + JSString *str = ATOM_TO_STRING(atom); + todo = SprintPut(&ss->sprinter, + js_GetStringBytes(str), + JSSTRING_LENGTH(str)); + break; + } if (!rval) return JS_FALSE; todo = STR2OFF(&ss->sprinter, rval); @@ -2461,6 +2476,12 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb) #endif /* JS_HAS_DEBUGGER_KEYWORD */ #if JS_HAS_XML_SUPPORT + case JSOP_STARTXML: + case JSOP_JSEXPR: + inXML = op == JSOP_STARTXML; + todo = -2; + break; + case JSOP_DEFXMLNS: rval = POP_STR(); js_printf(jp, "\t%s %s %s %s;\n", @@ -2498,6 +2519,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb) break; case JSOP_TOATTRVAL: + todo = -2; break; case JSOP_ADDATTRNAME: @@ -2524,11 +2546,21 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb) lval = POP_STR(); goto do_setlval; - case JSOP_XMLNAME: - case JSOP_XMLTAGEXPR: case JSOP_XMLELTEXPR: + case JSOP_XMLTAGEXPR: + saveop = op; + op = JSOP_NOP; + todo = Sprint(&ss->sprinter, "{%s}", POP_STR()); + op = saveop; + inXML = JS_TRUE; /* we're done with the tag. */ + break; + case JSOP_TOXML: case JSOP_TOXMLLIST: + inXML = JS_FALSE; + /* fall through */ + + case JSOP_XMLNAME: case JSOP_FOREACH: case JSOP_FILTER: /* Conversion and prefix ops do nothing in the decompiler. */ diff --git a/mozilla/js/src/jsopcode.tbl b/mozilla/js/src/jsopcode.tbl index 549077bd27e..ac6002b07b9 100644 --- a/mozilla/js/src/jsopcode.tbl +++ b/mozilla/js/src/jsopcode.tbl @@ -385,3 +385,9 @@ OPDEF(JSOP_UINT24, 188,"uint24", NULL, 4, 0, 1, 12, JOF_UINT24 OPDEF(JSOP_LITERAL, 189,"literal", NULL, 4, 0, 1, 12, JOF_UINT24) OPDEF(JSOP_FINDNAME, 190,"findname", NULL, 4, 0, 2, 0, JOF_UINT24) OPDEF(JSOP_LITOPX, 191,"litopx", NULL, 5, 0, 0, 12, JOF_LITOPX) + +/* + * Opcodes to help the decompiler deal with XML. + */ +OPDEF(JSOP_STARTXML, 192,"startxml", NULL, 1, 0, 0, 0, JOF_BYTE) +OPDEF(JSOP_JSEXPR, 193,"jsepxr", NULL, 1, 0, 0, 0, JOF_BYTE)