Fix broken left-associativity and constant folding for + chains involving some string terms (196290, r=shaver by telepathy).
git-svn-id: svn://10.0.0.236/trunk@139787 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
c3c549beae
commit
7cc2d1c1ff
@ -237,14 +237,41 @@ NewBinary(JSContext *cx, JSTokenType tt,
|
||||
left->pn_arity = PN_LIST;
|
||||
PN_INIT_LIST_1(left, pn1);
|
||||
PN_APPEND(left, pn2);
|
||||
left->pn_strcat = (tt == TOK_PLUS &&
|
||||
(pn1->pn_type == TOK_STRING ||
|
||||
pn2->pn_type == TOK_STRING));
|
||||
left->pn_extra = 0;
|
||||
if (tt == TOK_PLUS) {
|
||||
if (pn1->pn_type == TOK_STRING)
|
||||
left->pn_extra |= PNX_STRCAT;
|
||||
else if (pn1->pn_type != TOK_NUMBER)
|
||||
left->pn_extra |= PNX_CANTFOLD;
|
||||
if (pn2->pn_type == TOK_STRING)
|
||||
left->pn_extra |= PNX_STRCAT;
|
||||
else if (pn2->pn_type != TOK_NUMBER)
|
||||
left->pn_extra |= PNX_CANTFOLD;
|
||||
}
|
||||
}
|
||||
PN_APPEND(left, right);
|
||||
left->pn_pos.end = right->pn_pos.end;
|
||||
if (tt == TOK_PLUS && right->pn_type == TOK_STRING)
|
||||
left->pn_strcat = JS_TRUE;
|
||||
if (tt == TOK_PLUS) {
|
||||
if (right->pn_type == TOK_STRING)
|
||||
left->pn_extra |= PNX_STRCAT;
|
||||
else if (right->pn_type != TOK_NUMBER)
|
||||
left->pn_extra |= PNX_CANTFOLD;
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fold constant addition immediately, to conserve node space and, what's
|
||||
* more, so js_FoldConstants never sees mixed addition and concatenation
|
||||
* operations with more than one leading non-string operand in a PN_LIST
|
||||
* generated for expressions such as 1 + 2 + "pt" (which should evaluate
|
||||
* to "3pt", not "12pt").
|
||||
*/
|
||||
if (tt == TOK_PLUS &&
|
||||
left->pn_type == TOK_NUMBER &&
|
||||
right->pn_type == TOK_NUMBER) {
|
||||
left->pn_dval += right->pn_dval;
|
||||
RecycleTree(right, tc);
|
||||
return left;
|
||||
}
|
||||
|
||||
@ -3314,9 +3341,15 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc)
|
||||
jschar *chars;
|
||||
JSString *str, *str2;
|
||||
|
||||
/* Any one string literal operand means this is a concatenation. */
|
||||
/*
|
||||
* Any string literal term with all others number or string means
|
||||
* this is a concatenation. If any term is not a string or number
|
||||
* literal, we can't fold.
|
||||
*/
|
||||
JS_ASSERT(pn->pn_count > 2);
|
||||
if (!pn->pn_strcat)
|
||||
if (pn->pn_extra & PNX_CANTFOLD)
|
||||
return JS_TRUE;
|
||||
if (pn->pn_extra != PNX_STRCAT)
|
||||
goto do_binary_op;
|
||||
|
||||
/* Ok, we're concatenating: convert non-string constant operands. */
|
||||
|
||||
@ -128,11 +128,14 @@ JS_BEGIN_EXTERN_C
|
||||
* TOK_SHOP binary pn_left: left-assoc SH expr, pn_right: ADD expr
|
||||
* pn_op: JSOP_LSH, JSOP_RSH, JSOP_URSH
|
||||
* TOK_PLUS, binary pn_left: left-assoc ADD expr, pn_right: MUL expr
|
||||
* pn_strcat: if a left-associated binary TOK_PLUS
|
||||
* pn_extra: if a left-associated binary TOK_PLUS
|
||||
* tree has been flattened into a list (see above
|
||||
* under <Expressions>), pn_strcat will be true if
|
||||
* at least one list element is a string literal
|
||||
* (TOK_STRING), and false otherwise.
|
||||
* under <Expressions>), pn_extra will contain
|
||||
* PNX_STRCAT if at least one list element is a
|
||||
* string literal (TOK_STRING); if such a list has
|
||||
* any non-string, non-number term, pn_extra will
|
||||
* contain PNX_CANTFOLD.
|
||||
* pn_
|
||||
* TOK_MINUS pn_op: JSOP_ADD, JSOP_SUB
|
||||
* TOK_STAR, binary pn_left: left-assoc MUL expr, pn_right: UNARY expr
|
||||
* TOK_DIVOP pn_op: JSOP_MUL, JSOP_DIV, JSOP_MOD
|
||||
@ -198,7 +201,7 @@ struct JSParseNode {
|
||||
JSParseNode *head; /* first node in list */
|
||||
JSParseNode **tail; /* ptr to ptr to last node in list */
|
||||
uint32 count; /* number of nodes in list */
|
||||
JSBool extra; /* extra comma flag for [1,2,,] */
|
||||
uint32 extra; /* extra comma flag for [1,2,,] */
|
||||
} list;
|
||||
struct { /* ternary: if, for(;;), ?: */
|
||||
JSParseNode *kid1; /* condition, discriminant, etc. */
|
||||
@ -233,7 +236,6 @@ struct JSParseNode {
|
||||
#define pn_tail pn_u.list.tail
|
||||
#define pn_count pn_u.list.count
|
||||
#define pn_extra pn_u.list.extra
|
||||
#define pn_strcat pn_u.list.extra
|
||||
#define pn_kid1 pn_u.ternary.kid1
|
||||
#define pn_kid2 pn_u.ternary.kid2
|
||||
#define pn_kid3 pn_u.ternary.kid3
|
||||
@ -248,6 +250,10 @@ struct JSParseNode {
|
||||
#define pn_attrs pn_u.name.attrs
|
||||
#define pn_dval pn_u.dval
|
||||
|
||||
/* PN_LIST pn_extra flags. */
|
||||
#define PNX_STRCAT 0x1 /* TOK_PLUS list has string term */
|
||||
#define PNX_CANTFOLD 0x2 /* TOK_PLUS list has unfoldable term */
|
||||
|
||||
/*
|
||||
* Move pn2 into pn, preserving pn->pn_pos and pn->pn_offset and handing off
|
||||
* any kids in pn2->pn_u, by clearing pn2.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user