mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 622321 - While { x: 1, x: 1 } is a syntax error only in strict mode, any other name collision between property assignments in an object literal is a syntax error regardless whether the literal is in strict mode code or not. r=dmandelin
--HG-- extra : rebase_source : 04493a7d56924ab968d5524b8bee57ecde37068a
This commit is contained in:
parent
2d4d55374d
commit
4b88bf7958
@ -35,8 +35,6 @@
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
var safebrowsing = {
|
||||
appContext: null,
|
||||
|
||||
startup: function() {
|
||||
setTimeout(function() {
|
||||
safebrowsing.deferredStartup();
|
||||
|
@ -8423,13 +8423,15 @@ Parser::primaryExpr(TokenKind tt, JSBool afterDot)
|
||||
JSParseNode *pnval;
|
||||
|
||||
/*
|
||||
* A map from property names we've seen thus far to bit masks.
|
||||
* (We use ALE_INDEX/ALE_SET_INDEX). An atom's mask includes
|
||||
* JSPROP_SETTER if we've seen a setter for it, JSPROP_GETTER
|
||||
* if we've seen as getter, and both of those if we've just
|
||||
* seen an ordinary value.
|
||||
* A map from property names we've seen thus far to a mask of property
|
||||
* assignment types, stored and retrieved with ALE_SET_INDEX/ALE_INDEX.
|
||||
*/
|
||||
JSAutoAtomList seen(tc->parser);
|
||||
enum AssignmentType {
|
||||
GET = 0x1,
|
||||
SET = 0x2,
|
||||
VALUE = 0x4 | GET | SET
|
||||
};
|
||||
|
||||
pn = ListNode::create(tc);
|
||||
if (!pn)
|
||||
@ -8448,16 +8450,8 @@ Parser::primaryExpr(TokenKind tt, JSBool afterDot)
|
||||
if (!pn3)
|
||||
return NULL;
|
||||
pn3->pn_dval = tokenStream.currentToken().t_dval;
|
||||
if (tc->needStrictChecks()) {
|
||||
/*
|
||||
* Use string-valued atoms for detecting duplicate
|
||||
* properties so that 1 and "1" properly collide.
|
||||
*/
|
||||
if (!js_ValueToAtom(context, DoubleValue(pn3->pn_dval), &atom))
|
||||
return NULL;
|
||||
} else {
|
||||
atom = NULL; /* for the compiler */
|
||||
}
|
||||
if (!js_ValueToAtom(context, DoubleValue(pn3->pn_dval), &atom))
|
||||
return NULL;
|
||||
break;
|
||||
case TOK_NAME:
|
||||
{
|
||||
@ -8480,16 +8474,8 @@ Parser::primaryExpr(TokenKind tt, JSBool afterDot)
|
||||
if (!pn3)
|
||||
return NULL;
|
||||
pn3->pn_dval = tokenStream.currentToken().t_dval;
|
||||
if (tc->needStrictChecks()) {
|
||||
/*
|
||||
* Use string-valued atoms for detecting duplicate
|
||||
* properties so that 1 and "1" properly collide.
|
||||
*/
|
||||
if (!js_ValueToAtom(context, DoubleValue(pn3->pn_dval), &atom))
|
||||
return NULL;
|
||||
} else {
|
||||
atom = NULL; /* for the compiler */
|
||||
}
|
||||
if (!js_ValueToAtom(context, DoubleValue(pn3->pn_dval), &atom))
|
||||
return NULL;
|
||||
} else {
|
||||
tokenStream.ungetToken();
|
||||
goto property_name;
|
||||
@ -8553,40 +8539,49 @@ Parser::primaryExpr(TokenKind tt, JSBool afterDot)
|
||||
pn->append(pn2);
|
||||
|
||||
/*
|
||||
* In strict mode code, check for duplicate property names. Treat
|
||||
* getters and setters as distinct attributes of each property. A
|
||||
* plain old value conflicts with a getter or a setter.
|
||||
* Check for duplicate property names. Duplicate data properties
|
||||
* only conflict in strict mode. Duplicate getter or duplicate
|
||||
* setter halves always conflict. A data property conflicts with
|
||||
* any part of an accessor property.
|
||||
*/
|
||||
if (tc->needStrictChecks()) {
|
||||
unsigned attributesMask;
|
||||
if (op == JSOP_INITPROP) {
|
||||
attributesMask = JSPROP_GETTER | JSPROP_SETTER;
|
||||
} else if (op == JSOP_GETTER) {
|
||||
attributesMask = JSPROP_GETTER;
|
||||
} else if (op == JSOP_SETTER) {
|
||||
attributesMask = JSPROP_SETTER;
|
||||
} else {
|
||||
JS_NOT_REACHED("bad opcode in object initializer");
|
||||
attributesMask = 0;
|
||||
}
|
||||
AssignmentType assignType;
|
||||
if (op == JSOP_INITPROP) {
|
||||
assignType = VALUE;
|
||||
} else if (op == JSOP_GETTER) {
|
||||
assignType = GET;
|
||||
} else if (op == JSOP_SETTER) {
|
||||
assignType = SET;
|
||||
} else {
|
||||
JS_NOT_REACHED("bad opcode in object initializer");
|
||||
assignType = VALUE; /* try to error early */
|
||||
}
|
||||
|
||||
JSAtomListElement *ale = seen.lookup(atom);
|
||||
if (ale) {
|
||||
if (ALE_INDEX(ale) & attributesMask) {
|
||||
JSAutoByteString name;
|
||||
if (!js_AtomToPrintableString(context, atom, &name) ||
|
||||
!ReportStrictModeError(context, &tokenStream, tc, NULL,
|
||||
JSMSG_DUPLICATE_PROPERTY, name.ptr())) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
ALE_SET_INDEX(ale, attributesMask | ALE_INDEX(ale));
|
||||
} else {
|
||||
ale = seen.add(tc->parser, atom);
|
||||
if (!ale)
|
||||
if (JSAtomListElement *ale = seen.lookup(atom)) {
|
||||
AssignmentType oldAssignType = AssignmentType(ALE_INDEX(ale));
|
||||
if ((oldAssignType & assignType) &&
|
||||
(oldAssignType != VALUE || assignType != VALUE || tc->needStrictChecks()))
|
||||
{
|
||||
JSAutoByteString name;
|
||||
if (!js_AtomToPrintableString(context, atom, &name))
|
||||
return NULL;
|
||||
ALE_SET_INDEX(ale, attributesMask);
|
||||
|
||||
uintN flags = (oldAssignType == VALUE &&
|
||||
assignType == VALUE &&
|
||||
!tc->inStrictMode())
|
||||
? JSREPORT_WARNING
|
||||
: JSREPORT_ERROR;
|
||||
if (!ReportCompileErrorNumber(context, &tokenStream, NULL, flags,
|
||||
JSMSG_DUPLICATE_PROPERTY, name.ptr()))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
ALE_SET_INDEX(ale, assignType | oldAssignType);
|
||||
} else {
|
||||
ale = seen.add(tc->parser, atom);
|
||||
if (!ale)
|
||||
return NULL;
|
||||
ALE_SET_INDEX(ale, assignType);
|
||||
}
|
||||
|
||||
tt = tokenStream.getToken();
|
||||
|
@ -94,22 +94,42 @@ assertEq(testLenientAndStrict('({a:1, b:1, c:1, d:1, e:1, f:1, g:1, h:1, i:1, j:
|
||||
* appropriate.
|
||||
*/
|
||||
assertEq(testLenientAndStrict('({get x() {}, x:1})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
assertEq(testLenientAndStrict('({x:1, get x() {}})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
assertEq(testLenientAndStrict('({set x(q) {}, x:1})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
assertEq(testLenientAndStrict('({x:1, set x(q) {}})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
assertEq(testLenientAndStrict('({1:1, set 1(q) {}})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
assertEq(testLenientAndStrict('({set 1(q) {}, 1:1})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
assertEq(testLenientAndStrict('({"1":1, set 1(q) {}})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
assertEq(testLenientAndStrict('({set 1(q) {}, "1":1})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
@ -124,17 +144,22 @@ assertEq(testLenientAndStrict('({set x(q) {}, get x() {}})',
|
||||
true);
|
||||
|
||||
assertEq(testLenientAndStrict('({get x() {}, set x(q) {}, x:1})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
assertEq(testLenientAndStrict('({set x(q) {}, get x() {}, x:1})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
assertEq(testLenientAndStrict('({get x() {}, get x() {}})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
assertEq(testLenientAndStrict('({set x() {}, set x() {}})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user