Attachment #585943: WIP 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 7226-7241   frontend::EmitTree(JSContext *cx, Byteco Link Here 
7226
      case PNK_ADD:
7226
      case PNK_ADD:
7227
      case PNK_SUB:
7227
      case PNK_SUB:
7228
      case PNK_BITOR:
7228
      case PNK_BITOR:
7229
      case PNK_BITXOR:
7229
      case PNK_BITXOR:
7230
      case PNK_BITAND:
7230
      case PNK_BITAND:
7231
      case PNK_STRICTEQ:
7231
      case PNK_STRICTEQ:
7232
      case PNK_EQ:
7232
      case PNK_EQ:
7233
      case PNK_STRICTNE:
7233
      case PNK_STRICTNE:
7234
      case PNK_IS:
7235
      case PNK_ISNT:
7234
      case PNK_NE:
7236
      case PNK_NE:
7235
      case PNK_LT:
7237
      case PNK_LT:
7236
      case PNK_LE:
7238
      case PNK_LE:
7237
      case PNK_GT:
7239
      case PNK_GT:
7238
      case PNK_GE:
7240
      case PNK_GE:
7239
      case PNK_IN:
7241
      case PNK_IN:
7240
      case PNK_INSTANCEOF:
7242
      case PNK_INSTANCEOF:
7241
      case PNK_LSH:
7243
      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 (-7 / +45 lines)
Line     Link Here 
 Lines 4568-4593   EqualityTokenToParseNodeKind(const Token Link Here 
4568
      case TOK_STRICTNE:
4568
      case TOK_STRICTNE:
4569
        return PNK_STRICTNE;
4569
        return PNK_STRICTNE;
4570
      default:
4570
      default:
4571
        JS_ASSERT(token.type == TOK_NE);
4571
        JS_ASSERT(token.type == TOK_NE);
4572
        return PNK_NE;
4572
        return PNK_NE;
4573
    }
4573
    }
4574
}
4574
}
4575
4575
4576
bool
4577
TokenIsHarmonyEquality(const Token &token, JSContext *cx)
4578
{
4579
    if (token.type != TOK_NAME)
4580
        return false;
4581
    if (token.name() == cx->runtime->atomState.isAtom)
4582
        return true;
4583
    if (token.name() == cx->runtime->atomState.isntAtom)
4584
        return true;
4585
    return false;
4586
}
4587
4576
BEGIN_EXPR_PARSER(eqExpr1)
4588
BEGIN_EXPR_PARSER(eqExpr1)
4577
{
4589
{
4590
    uintN line = tokenStream.getLineno();
4578
    ParseNode *left = relExpr1i();
4591
    ParseNode *left = relExpr1i();
4579
    while (left && tokenStream.isCurrentTokenEquality()) {
4592
    while (left) {
4580
        ParseNodeKind kind = EqualityTokenToParseNodeKind(tokenStream.currentToken());
4593
        if (TokenIsHarmonyEquality(tokenStream.currentToken(), context)) {
4581
        JSOp op = tokenStream.currentToken().t_op;
4594
            /* Is defined as [no LineTerminator here] */
4582
        ParseNode *right = relExpr1n();
4595
            if (tokenStream.currentToken().pos.end.lineno != line) {
4583
        if (!right)
4596
                reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_NEW_LINE_BEFORE_IN);
4584
            return NULL;
4597
                return NULL;
4585
        left = tc->parser->new_<BinaryNode>(kind, op, left, right);
4598
            }
4599
4600
            JSOp op;
4601
            ParseNodeKind kind;
4602
            if (tokenStream.currentToken().name() == context->runtime->atomState.isAtom) {
4603
                op = JSOP_IS;
4604
                kind = PNK_IS;
4605
            } else {
4606
                op = JSOP_ISNT;
4607
                kind = PNK_ISNT;
4608
            }
4609
4610
            ParseNode *right = relExpr1n();
4611
            if (!right)
4612
                return NULL;
4613
            left = tc->parser->new_<BinaryNode>(kind, op, left, right);
4614
        }
4615
        if (tokenStream.isCurrentTokenEquality()) {
4616
            ParseNodeKind kind = EqualityTokenToParseNodeKind(tokenStream.currentToken());
4617
            JSOp op = tokenStream.currentToken().t_op;
4618
            ParseNode *right = relExpr1n();
4619
            if (!right)
4620
                return NULL;
4621
            left = tc->parser->new_<BinaryNode>(kind, op, left, right);
4622
        }
4623
        break;
4586
    }
4624
    }
4587
    return left;
4625
    return left;
4588
}
4626
}
4589
END_EXPR_PARSER(eqExpr1)
4627
END_EXPR_PARSER(eqExpr1)
4590
4628
4591
BEGIN_EXPR_PARSER(bitAndExpr1)
4629
BEGIN_EXPR_PARSER(bitAndExpr1)
4592
{
4630
{
4593
    ParseNode *pn = eqExpr1i();
4631
    ParseNode *pn = eqExpr1i();
(-)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_IN,     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)

Return to bug 715359