Attachment #586591: v1.1 for bug #715359

View | Details | Raw Unified | Return to bug 715359
Collapse All | Expand All

(-)a/js/src/frontend/BytecodeEmitter.cpp (+2 lines)
Line     Link Here 
 Lines 7228-7243   frontend::EmitTree(JSContext *cx, Byteco Link Here 
7228
      case PNK_ADD:
7228
      case PNK_ADD:
7229
      case PNK_SUB:
7229
      case PNK_SUB:
7230
      case PNK_BITOR:
7230
      case PNK_BITOR:
7231
      case PNK_BITXOR:
7231
      case PNK_BITXOR:
7232
      case PNK_BITAND:
7232
      case PNK_BITAND:
7233
      case PNK_STRICTEQ:
7233
      case PNK_STRICTEQ:
7234
      case PNK_EQ:
7234
      case PNK_EQ:
7235
      case PNK_STRICTNE:
7235
      case PNK_STRICTNE:
7236
      case PNK_IS:
7237
      case PNK_ISNT:
7236
      case PNK_NE:
7238
      case PNK_NE:
7237
      case PNK_LT:
7239
      case PNK_LT:
7238
      case PNK_LE:
7240
      case PNK_LE:
7239
      case PNK_GT:
7241
      case PNK_GT:
7240
      case PNK_GE:
7242
      case PNK_GE:
7241
      case PNK_IN:
7243
      case PNK_IN:
7242
      case PNK_INSTANCEOF:
7244
      case PNK_INSTANCEOF:
7243
      case PNK_LSH:
7245
      case PNK_LSH:
(-)a/js/src/frontend/ParseNode.h (+4 lines)
Line     Link Here 
 Lines 161-176   enum ParseNodeKind { Link Here 
161
     */
161
     */
162
162
163
    /* Equality operators. */
163
    /* Equality operators. */
164
    PNK_STRICTEQ,
164
    PNK_STRICTEQ,
165
    PNK_EQ,
165
    PNK_EQ,
166
    PNK_STRICTNE,
166
    PNK_STRICTNE,
167
    PNK_NE,
167
    PNK_NE,
168
168
169
    /* Harmony is/isnt */
170
    PNK_IS,
171
    PNK_ISNT,
172
169
    /* Unary operators. */
173
    /* Unary operators. */
170
    PNK_TYPEOF,
174
    PNK_TYPEOF,
171
    PNK_VOID,
175
    PNK_VOID,
172
    PNK_NOT,
176
    PNK_NOT,
173
    PNK_BITNOT,
177
    PNK_BITNOT,
174
178
175
    /* Relational operators (< <= > >=). */
179
    /* Relational operators (< <= > >=). */
176
    PNK_LT,
180
    PNK_LT,
(-)a/js/src/frontend/Parser.cpp (-34 / +69 lines)
Line     Link Here 
 Lines 1863-1879   Parser::statements() Link Here 
1863
    pn->pn_pos.end = tokenStream.currentToken().pos.end;
1863
    pn->pn_pos.end = tokenStream.currentToken().pos.end;
1864
    return pn;
1864
    return pn;
1865
}
1865
}
1866
1866
1867
ParseNode *
1867
ParseNode *
1868
Parser::condition()
1868
Parser::condition()
1869
{
1869
{
1870
    MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_COND);
1870
    MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_COND);
1871
    ParseNode *pn = parenExpr();
1871
    bool isGenerator = false;
1872
    ParseNode *pn = parenExpr(isGenerator);
1872
    if (!pn)
1873
    if (!pn)
1873
        return NULL;
1874
        return NULL;
1874
    MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_COND);
1875
    MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_COND);
1875
1876
1876
    /* Check for (a = b) and warn about possible (a == b) mistype. */
1877
    /* Check for (a = b) and warn about possible (a == b) mistype. */
1877
    JS_ASSERT_IF(pn->isKind(PNK_ASSIGN), pn->isOp(JSOP_NOP));
1878
    JS_ASSERT_IF(pn->isKind(PNK_ASSIGN), pn->isOp(JSOP_NOP));
1878
    if (pn->isKind(PNK_ASSIGN) &&
1879
    if (pn->isKind(PNK_ASSIGN) &&
1879
        !pn->isInParens() &&
1880
        !pn->isInParens() &&
 Lines 3019-3035   Parser::switchStatement() Link Here 
3019
{
3020
{
3020
    JS_ASSERT(tc->parser->tokenStream.currentToken().type == TOK_SWITCH);
3021
    JS_ASSERT(tc->parser->tokenStream.currentToken().type == TOK_SWITCH);
3021
    ParseNode *pn = BinaryNode::create(PNK_SWITCH, tc);
3022
    ParseNode *pn = BinaryNode::create(PNK_SWITCH, tc);
3022
    if (!pn)
3023
    if (!pn)
3023
        return NULL;
3024
        return NULL;
3024
    MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_SWITCH);
3025
    MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_SWITCH);
3025
3026
3026
    /* pn1 points to the switch's discriminant. */
3027
    /* pn1 points to the switch's discriminant. */
3027
    ParseNode *pn1 = parenExpr();
3028
    bool isGenerator = false;
3029
    ParseNode *pn1 = parenExpr(isGenerator);
3028
    if (!pn1)
3030
    if (!pn1)
3029
        return NULL;
3031
        return NULL;
3030
3032
3031
    MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_SWITCH);
3033
    MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_SWITCH);
3032
    MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_SWITCH);
3034
    MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_SWITCH);
3033
3035
3034
    /*
3036
    /*
3035
     * NB: we must push stmtInfo before calling GenerateBlockIdForStmtNode
3037
     * NB: we must push stmtInfo before calling GenerateBlockIdForStmtNode
 Lines 3677-3693   Parser::withStatement() Link Here 
3677
        reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_STRICT_CODE_WITH);
3679
        reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_STRICT_CODE_WITH);
3678
        return NULL;
3680
        return NULL;
3679
    }
3681
    }
3680
3682
3681
    ParseNode *pn = BinaryNode::create(PNK_WITH, tc);
3683
    ParseNode *pn = BinaryNode::create(PNK_WITH, tc);
3682
    if (!pn)
3684
    if (!pn)
3683
        return NULL;
3685
        return NULL;
3684
    MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_WITH);
3686
    MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_WITH);
3685
    ParseNode *pn2 = parenExpr();
3687
    bool isGenerator = false;
3688
    ParseNode *pn2 = parenExpr(isGenerator);
3686
    if (!pn2)
3689
    if (!pn2)
3687
        return NULL;
3690
        return NULL;
3688
    MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_WITH);
3691
    MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_WITH);
3689
    pn->pn_left = pn2;
3692
    pn->pn_left = pn2;
3690
3693
3691
    ParseNode *oldWith = tc->innermostWith;
3694
    ParseNode *oldWith = tc->innermostWith;
3692
    tc->innermostWith = pn;
3695
    tc->innermostWith = pn;
3693
3696
 Lines 4568-4593   EqualityTokenToParseNodeKind(const Token Link Here 
4568
      case TOK_STRICTNE:
4571
      case TOK_STRICTNE:
4569
        return PNK_STRICTNE;
4572
        return PNK_STRICTNE;
4570
      default:
4573
      default:
4571
        JS_ASSERT(token.type == TOK_NE);
4574
        JS_ASSERT(token.type == TOK_NE);
4572
        return PNK_NE;
4575
        return PNK_NE;
4573
    }
4576
    }
4574
}
4577
}
4575
4578
4579
bool
4580
TokenIsHarmonyEquality(const Token &token, JSContext *cx)
4581
{
4582
    if (token.type != TOK_NAME)
4583
        return false;
4584
    if (token.name() == cx->runtime->atomState.isAtom)
4585
        return true;
4586
    if (token.name() == cx->runtime->atomState.isntAtom)
4587
        return true;
4588
    return false;
4589
}
4590
4576
BEGIN_EXPR_PARSER(eqExpr1)
4591
BEGIN_EXPR_PARSER(eqExpr1)
4577
{
4592
{
4578
    ParseNode *left = relExpr1i();
4593
    ParseNode *left = relExpr1i();
4579
    while (left && tokenStream.isCurrentTokenEquality()) {
4594
    while (left) {
4580
        ParseNodeKind kind = EqualityTokenToParseNodeKind(tokenStream.currentToken());
4595
        if (TokenIsHarmonyEquality(tokenStream.currentToken(), context)) {
4581
        JSOp op = tokenStream.currentToken().t_op;
4596
            /* Is defined as [no LineTerminator here]. */
4582
        ParseNode *right = relExpr1n();
4597
            if (left->pn_pos.end.lineno < tokenStream.currentToken().pos.begin.lineno) {
4583
        if (!right)
4598
                reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_NEW_LINE_BEFORE_IS);
4584
            return NULL;
4599
                return NULL;
4585
        left = tc->parser->new_<BinaryNode>(kind, op, left, right);
4600
            }
4601
4602
            JSOp op;
4603
            ParseNodeKind kind;
4604
            if (tokenStream.currentToken().name() == context->runtime->atomState.isAtom) {
4605
                op = JSOP_IS;
4606
                kind = PNK_IS;
4607
            } else {
4608
                op = JSOP_ISNT;
4609
                kind = PNK_ISNT;
4610
            }
4611
4612
            ParseNode *right = relExpr1n();
4613
            if (!right)
4614
                return NULL;
4615
            left = tc->parser->new_<BinaryNode>(kind, op, left, right);
4616
        } else if (tokenStream.isCurrentTokenEquality()) {
4617
            ParseNodeKind kind = EqualityTokenToParseNodeKind(tokenStream.currentToken());
4618
            JSOp op = tokenStream.currentToken().t_op;
4619
            ParseNode *right = relExpr1n();
4620
            if (!right)
4621
                return NULL;
4622
            left = tc->parser->new_<BinaryNode>(kind, op, left, right);
4623
        } else {
4624
            break;
4625
        }
4586
    }
4626
    }
4587
    return left;
4627
    return left;
4588
}
4628
}
4589
END_EXPR_PARSER(eqExpr1)
4629
END_EXPR_PARSER(eqExpr1)
4590
4630
4591
BEGIN_EXPR_PARSER(bitAndExpr1)
4631
BEGIN_EXPR_PARSER(bitAndExpr1)
4592
{
4632
{
4593
    ParseNode *pn = eqExpr1i();
4633
    ParseNode *pn = eqExpr1i();
 Lines 7157-7180   Parser::primaryExpr(TokenKind tt, JSBool Link Here 
7157
        if (!pn)
7197
        if (!pn)
7158
            return NULL;
7198
            return NULL;
7159
        break;
7199
        break;
7160
      }
7200
      }
7161
#endif /* JS_HAS_SHARP_VARS */
7201
#endif /* JS_HAS_SHARP_VARS */
7162
7202
7163
      case TOK_LP:
7203
      case TOK_LP:
7164
      {
7204
      {
7165
        JSBool genexp;
7205
        bool isGenerator = false;
7166
7206
        pn = parenExpr(isGenerator);
7167
        pn = parenExpr(&genexp);
7168
        if (!pn)
7207
        if (!pn)
7169
            return NULL;
7208
            return NULL;
7170
        pn->setInParens(true);
7209
        pn->setInParens(true);
7171
        if (!genexp)
7210
7211
        if (!isGenerator)
7172
            MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_IN_PAREN);
7212
            MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_IN_PAREN);
7213
7214
        pn->pn_pos.end = tokenStream.currentToken().pos.end;
7173
        break;
7215
        break;
7174
      }
7216
      }
7175
7217
7176
      case TOK_STRING:
7218
      case TOK_STRING:
7177
        pn = atomNode(PNK_STRING, JSOP_STRING);
7219
        pn = atomNode(PNK_STRING, JSOP_STRING);
7178
        if (!pn)
7220
        if (!pn)
7179
            return NULL;
7221
            return NULL;
7180
        break;
7222
        break;
 Lines 7278-7334   Parser::primaryExpr(TokenKind tt, JSBool Link Here 
7278
      default:
7320
      default:
7279
        reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_SYNTAX_ERROR);
7321
        reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_SYNTAX_ERROR);
7280
        return NULL;
7322
        return NULL;
7281
    }
7323
    }
7282
    return pn;
7324
    return pn;
7283
}
7325
}
7284
7326
7285
ParseNode *
7327
ParseNode *
7286
Parser::parenExpr(JSBool *genexp)
7328
Parser::parenExpr(bool &isGenerator)
7287
{
7329
{
7288
    TokenPtr begin;
7289
    ParseNode *pn;
7290
7291
    JS_ASSERT(tokenStream.currentToken().type == TOK_LP);
7330
    JS_ASSERT(tokenStream.currentToken().type == TOK_LP);
7292
    begin = tokenStream.currentToken().pos.begin;
7331
    TokenPtr begin = tokenStream.currentToken().pos.begin;
7293
7332
    
7294
    if (genexp)
7295
        *genexp = JS_FALSE;
7296
7297
    GenexpGuard guard(tc);
7333
    GenexpGuard guard(tc);
7298
7334
    ParseNode *pn = bracketedExpr();
7299
    pn = bracketedExpr();
7300
    if (!pn)
7335
    if (!pn)
7301
        return NULL;
7336
        return NULL;
7302
    guard.endBody();
7337
    guard.endBody();
7303
7338
7304
#if JS_HAS_GENERATOR_EXPRS
7339
#if JS_HAS_GENERATOR_EXPRS
7305
    if (tokenStream.matchToken(TOK_FOR)) {
7340
    if (tokenStream.matchToken(TOK_FOR)) {
7306
        if (!guard.checkValidBody(pn))
7341
        if (!guard.checkValidBody(pn))
7307
            return NULL;
7342
            return NULL;
7343
7308
        JS_ASSERT(!pn->isKind(PNK_YIELD));
7344
        JS_ASSERT(!pn->isKind(PNK_YIELD));
7345
7309
        if (pn->isKind(PNK_COMMA) && !pn->isInParens()) {
7346
        if (pn->isKind(PNK_COMMA) && !pn->isInParens()) {
7310
            reportErrorNumber(pn->last(), JSREPORT_ERROR, JSMSG_BAD_GENERATOR_SYNTAX,
7347
            reportErrorNumber(pn->last(), JSREPORT_ERROR, JSMSG_BAD_GENERATOR_SYNTAX,
7311
                              js_generator_str);
7348
                              js_generator_str);
7312
            return NULL;
7349
            return NULL;
7313
        }
7350
        }
7314
        pn = generatorExpr(pn);
7351
        pn = generatorExpr(pn);
7315
        if (!pn)
7352
        if (!pn)
7316
            return NULL;
7353
            return NULL;
7354
7317
        pn->pn_pos.begin = begin;
7355
        pn->pn_pos.begin = begin;
7318
        if (genexp) {
7356
7319
            if (tokenStream.getToken() != TOK_RP) {
7357
        if (tokenStream.getToken() != TOK_RP) {
7320
                reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_BAD_GENERATOR_SYNTAX,
7358
            reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_BAD_GENERATOR_SYNTAX, js_generator_str);
7321
                                  js_generator_str);
7359
            return NULL;
7322
                return NULL;
7323
            }
7324
            pn->pn_pos.end = tokenStream.currentToken().pos.end;
7325
            *genexp = JS_TRUE;
7326
        }
7360
        }
7361
7362
        isGenerator = true;
7327
    } else
7363
    } else
7328
#endif /* JS_HAS_GENERATOR_EXPRS */
7364
#endif /* JS_HAS_GENERATOR_EXPRS */
7329
7330
    if (!guard.maybeNoteGenerator(pn))
7365
    if (!guard.maybeNoteGenerator(pn))
7331
        return NULL;
7366
        return NULL;
7332
7367
7333
    return pn;
7368
    return pn;
7334
}
7369
}
(-)a/js/src/frontend/Parser.h (-1 / +1 lines)
Line     Link Here 
 Lines 230-246   struct Parser : private AutoGCRooter Link Here 
230
    ParseNode *shiftExpr1n();
230
    ParseNode *shiftExpr1n();
231
    ParseNode *addExpr1i();
231
    ParseNode *addExpr1i();
232
    ParseNode *addExpr1n();
232
    ParseNode *addExpr1n();
233
    ParseNode *mulExpr1i();
233
    ParseNode *mulExpr1i();
234
    ParseNode *mulExpr1n();
234
    ParseNode *mulExpr1n();
235
    ParseNode *unaryExpr();
235
    ParseNode *unaryExpr();
236
    ParseNode *memberExpr(JSBool allowCallSyntax);
236
    ParseNode *memberExpr(JSBool allowCallSyntax);
237
    ParseNode *primaryExpr(TokenKind tt, JSBool afterDot);
237
    ParseNode *primaryExpr(TokenKind tt, JSBool afterDot);
238
    ParseNode *parenExpr(JSBool *genexp = NULL);
238
    ParseNode *parenExpr(bool &isGenerator);
239
239
240
    /*
240
    /*
241
     * Additional JS parsers.
241
     * Additional JS parsers.
242
     */
242
     */
243
    enum FunctionType { Getter, Setter, Normal };
243
    enum FunctionType { Getter, Setter, Normal };
244
    bool functionArguments(TreeContext &funtc, FunctionBox *funbox, ParseNode **list);
244
    bool functionArguments(TreeContext &funtc, FunctionBox *funbox, ParseNode **list);
245
245
246
    ParseNode *functionDef(PropertyName *name, FunctionType type, FunctionSyntaxKind kind);
246
    ParseNode *functionDef(PropertyName *name, FunctionType type, FunctionSyntaxKind kind);
(-)a/js/src/jit-test/tests/harmony/harmony-is.js (+47 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * Any copyright is dedicated to the Public Domain.
3
 * http://creativecommons.org/licenses/publicdomain/
4
 */
5
6
assertEq(1 is 1, true);
7
assertEq(0 is 1, false);
8
9
assertEq(NaN is NaN, true);
10
assertEq(NaN is undefined, false);
11
12
assertEq(Infinity is Infinity, true);
13
assertEq(Infinity is -Infinity, false);
14
15
assertEq(0 is 0, true);
16
assertEq(0 is -0, false);
17
assertEq(-0 is 0, false);
18
19
var obj = {};
20
assertEq(obj is obj, true);
21
22
function throws(code) {
23
    var error;
24
    try {
25
        eval(code);
26
    } catch (e) {
27
        error = e;
28
    }
29
    assertEq(error.name, 'SyntaxError');
30
}
31
32
var is = 0;
33
assertEq(is is 0, true);
34
assertEq(is isnt 0, false);
35
36
throws('0 \n is 1');
37
throws('(0 == 1) \n is 1');
38
39
assertEq((0 == 
40
               1) is true, false);
41
42
assertEq((0 == 0
43
                ) isnt false, true);
44
45
var a;
46
a = (1 is 1) == true;
47
assertEq(a, true);
(-)a/js/src/js.msg (+1 lines)
Line     Link Here 
 Lines 369-376   MSG_DEF(JSMSG_DEBUG_BAD_OFFSET, 28 Link Here 
369
MSG_DEF(JSMSG_DEBUG_BAD_LINE,         283, 0, JSEXN_TYPEERR, "invalid line number")
369
MSG_DEF(JSMSG_DEBUG_BAD_LINE,         283, 0, JSEXN_TYPEERR, "invalid line number")
370
MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGING,    284, 0, JSEXN_ERR, "can't set breakpoint: script global is not a debuggee")
370
MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGING,    284, 0, JSEXN_ERR, "can't set breakpoint: script global is not a debuggee")
371
MSG_DEF(JSMSG_DEBUG_COMPARTMENT_MISMATCH, 285, 2, JSEXN_TYPEERR, "{0}: descriptor .{1} property is an object in a different compartment than the target object")
371
MSG_DEF(JSMSG_DEBUG_COMPARTMENT_MISMATCH, 285, 2, JSEXN_TYPEERR, "{0}: descriptor .{1} property is an object in a different compartment than the target object")
372
MSG_DEF(JSMSG_DEBUG_NOT_SCRIPT_FRAME, 286, 0, JSEXN_ERR, "stack frame is not running JavaScript code")
372
MSG_DEF(JSMSG_DEBUG_NOT_SCRIPT_FRAME, 286, 0, JSEXN_ERR, "stack frame is not running JavaScript code")
373
MSG_DEF(JSMSG_CANT_WATCH_PROP,        287, 0, JSEXN_TYPEERR, "properties whose names are objects can't be watched")
373
MSG_DEF(JSMSG_CANT_WATCH_PROP,        287, 0, JSEXN_TYPEERR, "properties whose names are objects can't be watched")
374
MSG_DEF(JSMSG_CSP_BLOCKED_EVAL,       288, 0, JSEXN_ERR, "call to eval() blocked by CSP")
374
MSG_DEF(JSMSG_CSP_BLOCKED_EVAL,       288, 0, JSEXN_ERR, "call to eval() blocked by CSP")
375
MSG_DEF(JSMSG_DEBUG_NO_SCOPE_OBJECT,  289, 0, JSEXN_TYPEERR, "declarative Environments don't have binding objects")
375
MSG_DEF(JSMSG_DEBUG_NO_SCOPE_OBJECT,  289, 0, JSEXN_TYPEERR, "declarative Environments don't have binding objects")
376
MSG_DEF(JSMSG_EMPTY_CONSEQUENT,       290, 0, JSEXN_SYNTAXERR, "mistyped ; after conditional?")
376
MSG_DEF(JSMSG_EMPTY_CONSEQUENT,       290, 0, JSEXN_SYNTAXERR, "mistyped ; after conditional?")
377
MSG_DEF(JSMSG_NEW_LINE_BEFORE_IS,     291, 0, JSEXN_SYNTAXERR, "new line before 'is' or 'isnt'")
(-)a/js/src/jsatom.cpp (-1 / +4 lines)
Line     Link Here 
 Lines 209-225   const char *const js_common_atom_names[] Link Here 
209
    "keys",                     /* keysAtom                     */
209
    "keys",                     /* keysAtom                     */
210
    "iterate",                  /* iterateAtom                  */
210
    "iterate",                  /* iterateAtom                  */
211
211
212
    "WeakMap",                  /* WeakMapAtom                  */
212
    "WeakMap",                  /* WeakMapAtom                  */
213
213
214
    "byteLength",               /* byteLengthAtom               */
214
    "byteLength",               /* byteLengthAtom               */
215
215
216
    "return",                   /* returnAtom                   */
216
    "return",                   /* returnAtom                   */
217
    "throw"                     /* throwAtom                    */
217
    "throw",                    /* throwAtom                    */
218
219
    "is",                       /* isAtom                       */
220
    "isnt"                      /* isntAtom                     */
218
};
221
};
219
222
220
void
223
void
221
JSAtomState::checkStaticInvariants()
224
JSAtomState::checkStaticInvariants()
222
{
225
{
223
    /*
226
    /*
224
     * Start and limit offsets for atom pointers in JSAtomState must be aligned
227
     * Start and limit offsets for atom pointers in JSAtomState must be aligned
225
     * on the word boundary.
228
     * on the word boundary.
(-)a/js/src/jsatom.h (+3 lines)
Line     Link Here 
 Lines 358-373   struct JSAtomState Link Here 
358
358
359
    js::PropertyName    *WeakMapAtom;
359
    js::PropertyName    *WeakMapAtom;
360
360
361
    js::PropertyName    *byteLengthAtom;
361
    js::PropertyName    *byteLengthAtom;
362
362
363
    js::PropertyName    *returnAtom;
363
    js::PropertyName    *returnAtom;
364
    js::PropertyName    *throwAtom;
364
    js::PropertyName    *throwAtom;
365
365
366
    js::PropertyName    *isAtom;
367
    js::PropertyName    *isntAtom;
368
366
    /* Less frequently used atoms, pinned lazily by JS_ResolveStandardClass. */
369
    /* Less frequently used atoms, pinned lazily by JS_ResolveStandardClass. */
367
    struct {
370
    struct {
368
        js::PropertyName *XMLListAtom;
371
        js::PropertyName *XMLListAtom;
369
        js::PropertyName *decodeURIAtom;
372
        js::PropertyName *decodeURIAtom;
370
        js::PropertyName *decodeURIComponentAtom;
373
        js::PropertyName *decodeURIComponentAtom;
371
        js::PropertyName *defineGetterAtom;
374
        js::PropertyName *defineGetterAtom;
372
        js::PropertyName *defineSetterAtom;
375
        js::PropertyName *defineSetterAtom;
373
        js::PropertyName *encodeURIAtom;
376
        js::PropertyName *encodeURIAtom;
(-)a/js/src/jsinterp.cpp (+29 lines)
Line     Link Here 
 Lines 2385-2400   END_CASE(JSOP_BITAND) Link Here 
2385
BEGIN_CASE(JSOP_EQ)
2385
BEGIN_CASE(JSOP_EQ)
2386
    EQUALITY_OP(==);
2386
    EQUALITY_OP(==);
2387
END_CASE(JSOP_EQ)
2387
END_CASE(JSOP_EQ)
2388
2388
2389
BEGIN_CASE(JSOP_NE)
2389
BEGIN_CASE(JSOP_NE)
2390
    EQUALITY_OP(!=);
2390
    EQUALITY_OP(!=);
2391
END_CASE(JSOP_NE)
2391
END_CASE(JSOP_NE)
2392
2392
2393
2394
2393
#undef EQUALITY_OP
2395
#undef EQUALITY_OP
2394
2396
2395
#define STRICT_EQUALITY_OP(OP, COND)                                          \
2397
#define STRICT_EQUALITY_OP(OP, COND)                                          \
2396
    JS_BEGIN_MACRO                                                            \
2398
    JS_BEGIN_MACRO                                                            \
2397
        const Value &rref = regs.sp[-1];                                      \
2399
        const Value &rref = regs.sp[-1];                                      \
2398
        const Value &lref = regs.sp[-2];                                      \
2400
        const Value &lref = regs.sp[-2];                                      \
2399
        JSBool equal;                                                         \
2401
        JSBool equal;                                                         \
2400
        if (!StrictlyEqual(cx, lref, rref, &equal))                           \
2402
        if (!StrictlyEqual(cx, lref, rref, &equal))                           \
 Lines 2414-2429   END_CASE(JSOP_STRICTEQ) Link Here 
2414
BEGIN_CASE(JSOP_STRICTNE)
2416
BEGIN_CASE(JSOP_STRICTNE)
2415
{
2417
{
2416
    bool cond;
2418
    bool cond;
2417
    STRICT_EQUALITY_OP(!=, cond);
2419
    STRICT_EQUALITY_OP(!=, cond);
2418
    regs.sp[-1].setBoolean(cond);
2420
    regs.sp[-1].setBoolean(cond);
2419
}
2421
}
2420
END_CASE(JSOP_STRICTNE)
2422
END_CASE(JSOP_STRICTNE)
2421
2423
2424
#define SAME_VALUE_OP(OP, COND)                                               \
2425
    JS_BEGIN_MACRO                                                            \
2426
        const Value &rref = regs.sp[-1];                                      \
2427
        const Value &lref = regs.sp[-2];                                      \
2428
        JSBool equal;                                                         \
2429
        if (!SameValue(cx, lref, rref, &equal))                               \
2430
            goto error;                                                       \
2431
        COND = equal OP JS_TRUE;                                              \
2432
        regs.sp--;                                                            \
2433
    JS_END_MACRO
2434
2435
BEGIN_CASE(JSOP_IS)
2436
{
2437
    bool cond;
2438
    SAME_VALUE_OP(==, cond);
2439
    regs.sp[-1].setBoolean(cond);
2440
}
2441
END_CASE(JSOP_IS)
2442
2443
BEGIN_CASE(JSOP_ISNT)
2444
{
2445
    bool cond;
2446
    SAME_VALUE_OP(!=, cond);
2447
    regs.sp[-1].setBoolean(cond);
2448
}
2449
END_CASE(JSOP_ISNT)
2450
2422
BEGIN_CASE(JSOP_CASE)
2451
BEGIN_CASE(JSOP_CASE)
2423
{
2452
{
2424
    bool cond;
2453
    bool cond;
2425
    STRICT_EQUALITY_OP(==, cond);
2454
    STRICT_EQUALITY_OP(==, cond);
2426
    if (cond) {
2455
    if (cond) {
2427
        regs.sp--;
2456
        regs.sp--;
2428
        len = GET_JUMP_OFFSET(regs.pc);
2457
        len = GET_JUMP_OFFSET(regs.pc);
2429
        BRANCH(len);
2458
        BRANCH(len);
(-)a/js/src/jsopcode.tbl (+3 lines)
Line     Link Here 
 Lines 565-572   OPDEF(JSOP_LAMBDA_FC, 221,"lambda_fc Link Here 
565
 */
565
 */
566
OPDEF(JSOP_SETMETHOD,     222,"setmethod",     NULL,  3,  2,  1,  3,  JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING)
566
OPDEF(JSOP_SETMETHOD,     222,"setmethod",     NULL,  3,  2,  1,  3,  JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING)
567
OPDEF(JSOP_INITMETHOD,    223,"initmethod",    NULL,  3,  2,  1,  3,  JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING)
567
OPDEF(JSOP_INITMETHOD,    223,"initmethod",    NULL,  3,  2,  1,  3,  JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING)
568
568
569
OPDEF(JSOP_SHARPINIT,     224,"sharpinit",     NULL,  3,  0,  0,  0,  JOF_UINT16|JOF_SHARPSLOT)
569
OPDEF(JSOP_SHARPINIT,     224,"sharpinit",     NULL,  3,  0,  0,  0,  JOF_UINT16|JOF_SHARPSLOT)
570
570
571
/* Pop the stack, convert to a jsid (int or string), and push back. */
571
/* Pop the stack, convert to a jsid (int or string), and push back. */
572
OPDEF(JSOP_TOID,          225, "toid",         NULL,  1,  1,  1,  0,  JOF_BYTE)
572
OPDEF(JSOP_TOID,          225, "toid",         NULL,  1,  1,  1,  0,  JOF_BYTE)
573
574
OPDEF(JSOP_IS,            226, "is",           "is",  1,  2,  1,  10,  JOF_BYTE|JOF_LEFTASSOC|JOF_ARITH|JOF_DETECTING)
575
OPDEF(JSOP_ISNT,          227, "isnt",        "isnt", 1,  2,  1,  10,  JOF_BYTE|JOF_LEFTASSOC|JOF_ARITH|JOF_DETECTING)
(-)a/js/src/jsreflect.cpp (+8 lines)
Line     Link Here 
 Lines 85-100   char const *aopNames[] = { Link Here 
85
    "&="    /* AOP_BITAND */
85
    "&="    /* AOP_BITAND */
86
};
86
};
87
87
88
char const *binopNames[] = {
88
char const *binopNames[] = {
89
    "==",         /* BINOP_EQ */
89
    "==",         /* BINOP_EQ */
90
    "!=",         /* BINOP_NE */
90
    "!=",         /* BINOP_NE */
91
    "===",        /* BINOP_STRICTEQ */
91
    "===",        /* BINOP_STRICTEQ */
92
    "!==",        /* BINOP_STRICTNE */
92
    "!==",        /* BINOP_STRICTNE */
93
    "is",         /* BINOP_IS */  
94
    "isnt",       /* BINOP_ISNT */  
93
    "<",          /* BINOP_LT */
95
    "<",          /* BINOP_LT */
94
    "<=",         /* BINOP_LE */
96
    "<=",         /* BINOP_LE */
95
    ">",          /* BINOP_GT */
97
    ">",          /* BINOP_GT */
96
    ">=",         /* BINOP_GE */
98
    ">=",         /* BINOP_GE */
97
    "<<",         /* BINOP_LSH */
99
    "<<",         /* BINOP_LSH */
98
    ">>",         /* BINOP_RSH */
100
    ">>",         /* BINOP_RSH */
99
    ">>>",        /* BINOP_URSH */
101
    ">>>",        /* BINOP_URSH */
100
    "+",          /* BINOP_PLUS */
102
    "+",          /* BINOP_PLUS */
 Lines 1763-1778   ASTSerializer::binop(ParseNodeKind kind, Link Here 
1763
      case PNK_GT:
1765
      case PNK_GT:
1764
        return BINOP_GT;
1766
        return BINOP_GT;
1765
      case PNK_GE:
1767
      case PNK_GE:
1766
        return BINOP_GE;
1768
        return BINOP_GE;
1767
      case PNK_EQ:
1769
      case PNK_EQ:
1768
        return BINOP_EQ;
1770
        return BINOP_EQ;
1769
      case PNK_NE:
1771
      case PNK_NE:
1770
        return BINOP_NE;
1772
        return BINOP_NE;
1773
      case PNK_IS:
1774
        return BINOP_IS;
1775
      case PNK_ISNT:
1776
        return BINOP_ISNT;
1771
      case PNK_STRICTEQ:
1777
      case PNK_STRICTEQ:
1772
        return BINOP_STRICTEQ;
1778
        return BINOP_STRICTEQ;
1773
      case PNK_STRICTNE:
1779
      case PNK_STRICTNE:
1774
        return BINOP_STRICTNE;
1780
        return BINOP_STRICTNE;
1775
      case PNK_ADD:
1781
      case PNK_ADD:
1776
        return BINOP_ADD;
1782
        return BINOP_ADD;
1777
      case PNK_SUB:
1783
      case PNK_SUB:
1778
        return BINOP_SUB;
1784
        return BINOP_SUB;
 Lines 2465-2480   ASTSerializer::expression(ParseNode *pn, Link Here 
2465
      }
2471
      }
2466
2472
2467
      case PNK_ADD:
2473
      case PNK_ADD:
2468
      case PNK_SUB:
2474
      case PNK_SUB:
2469
      case PNK_STRICTEQ:
2475
      case PNK_STRICTEQ:
2470
      case PNK_EQ:
2476
      case PNK_EQ:
2471
      case PNK_STRICTNE:
2477
      case PNK_STRICTNE:
2472
      case PNK_NE:
2478
      case PNK_NE:
2479
      case PNK_IS:
2480
      case PNK_ISNT:
2473
      case PNK_LT:
2481
      case PNK_LT:
2474
      case PNK_LE:
2482
      case PNK_LE:
2475
      case PNK_GT:
2483
      case PNK_GT:
2476
      case PNK_GE:
2484
      case PNK_GE:
2477
      case PNK_LSH:
2485
      case PNK_LSH:
2478
      case PNK_RSH:
2486
      case PNK_RSH:
2479
      case PNK_URSH:
2487
      case PNK_URSH:
2480
      case PNK_STAR:
2488
      case PNK_STAR:
(-)a/js/src/jsreflect.h (+2 lines)
Line     Link Here 
 Lines 71-86   enum AssignmentOperator { Link Here 
71
    AOP_LIMIT
71
    AOP_LIMIT
72
};
72
};
73
73
74
enum BinaryOperator {
74
enum BinaryOperator {
75
    BINOP_ERR = -1,
75
    BINOP_ERR = -1,
76
76
77
    /* eq */
77
    /* eq */
78
    BINOP_EQ = 0, BINOP_NE, BINOP_STRICTEQ, BINOP_STRICTNE,
78
    BINOP_EQ = 0, BINOP_NE, BINOP_STRICTEQ, BINOP_STRICTNE,
79
    /* harmony eq */
80
    BINOP_IS, BINOP_ISNT,
79
    /* rel */
81
    /* rel */
80
    BINOP_LT, BINOP_LE, BINOP_GT, BINOP_GE,
82
    BINOP_LT, BINOP_LE, BINOP_GT, BINOP_GE,
81
    /* shift */
83
    /* shift */
82
    BINOP_LSH, BINOP_RSH, BINOP_URSH,
84
    BINOP_LSH, BINOP_RSH, BINOP_URSH,
83
    /* arithmetic */
85
    /* arithmetic */
84
    BINOP_ADD, BINOP_SUB, BINOP_STAR, BINOP_DIV, BINOP_MOD,
86
    BINOP_ADD, BINOP_SUB, BINOP_STAR, BINOP_DIV, BINOP_MOD,
85
    /* binary */
87
    /* binary */
86
    BINOP_BITOR, BINOP_BITXOR, BINOP_BITAND,
88
    BINOP_BITOR, BINOP_BITXOR, BINOP_BITAND,

Return to bug 715359