Back out 88145df4191a, 42408569a696, and 2108d51be2e7 (Bug 719841, Bug 678086, and Bug 695922) for tp crashes on a CLOSED TREE
authorPhil Ringnalda <philringnalda@gmail.com>
Fri, 27 Jan 2012 14:22:10 -0800
changeset 86847 117f2280bd374a99b6344a0641ac16281d9f1aa4
parent 86846 8df0708b2fe3b06158d0a820a9b3e16e0c5e2c73
child 86848 e50a68c31b0000230a353abbb34d7be6f4322d1b
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs719841, 678086, 695922
milestone12.0a1
backs out88145df4191a6b4d29f552c2f0e5f05c21545cc2
Back out 88145df4191a, 42408569a696, and 2108d51be2e7 (Bug 719841, Bug 678086, and Bug 695922) for tp crashes on a CLOSED TREE
js/src/frontend/Parser.cpp
js/src/frontend/TokenStream.h
js/src/jit-test/tests/debug/Debugger-getNewestFrame-03.js
js/src/jsinfer.cpp
js/src/jsinferinlines.h
js/src/jsinterp.cpp
js/src/jsobj.cpp
js/src/vm/Debugger.cpp
js/src/vm/Debugger.h
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -1289,17 +1289,18 @@ Parser::functionArguments(TreeContext &f
                 ParseNode *rhs =
                     NameNode::create(PNK_NAME, context->runtime->atomState.emptyAtom, &funtc);
                 if (!rhs)
                     return false;
                 rhs->setOp(JSOP_GETARG);
                 rhs->pn_cookie.set(funtc.staticLevel, slot);
                 rhs->pn_dflags |= PND_BOUND;
 
-                ParseNode *item = new_<BinaryNode>(PNK_ASSIGN, JSOP_NOP, lhs->pn_pos, lhs, rhs);
+                ParseNode *item =
+                    ParseNode::newBinaryOrAppend(PNK_ASSIGN, JSOP_NOP, lhs, rhs, &funtc);
                 if (!item)
                     return false;
                 if (!list) {
                     list = ListNode::create(PNK_VAR, &funtc);
                     if (!list)
                         return false;
                     list->makeEmpty();
                     *listp = list;
@@ -6904,17 +6905,16 @@ Parser::primaryExpr(TokenKind tt, JSBool
         if (!pn)
             return NULL;
         pn->setOp(JSOP_NEWINIT);
         pn->makeEmpty();
 
         for (;;) {
             JSAtom *atom;
             TokenKind ltok = tokenStream.getToken(TSF_KEYWORD_IS_NAME);
-            TokenPtr begin = tokenStream.currentToken().pos.begin;
             switch (ltok) {
               case TOK_NUMBER:
                 pn3 = NullaryNode::create(PNK_NUMBER, tc);
                 if (!pn3)
                     return NULL;
                 pn3->pn_dval = tokenStream.currentToken().number();
                 if (!js_ValueToAtom(context, DoubleValue(pn3->pn_dval), &atom))
                     return NULL;
@@ -6971,20 +6971,17 @@ Parser::primaryExpr(TokenKind tt, JSBool
                         pn3->pn_atom = atom;
                         break;
                     }
 
                     pn->pn_xflags |= PNX_NONCONST;
 
                     /* NB: Getter function in { get x(){} } is unnamed. */
                     pn2 = functionDef(NULL, op == JSOP_GETTER ? Getter : Setter, Expression);
-                    if (!pn2)
-                        return NULL;
-                    TokenPos pos = {begin, pn2->pn_pos.end};
-                    pn2 = new_<BinaryNode>(PNK_COLON, op, pos, pn3, pn2);
+                    pn2 = ParseNode::newBinaryOrAppend(PNK_COLON, op, pn3, pn2, tc);
                     goto skip;
                 }
               case TOK_STRING: {
                 atom = tokenStream.currentToken().atom();
                 uint32_t index;
                 if (atom->isIndex(&index)) {
                     pn3 = NullaryNode::create(PNK_NUMBER, tc);
                     if (!pn3)
@@ -7036,20 +7033,17 @@ Parser::primaryExpr(TokenKind tt, JSBool
                 ((NameNode *)pnval)->initCommon(tc);
             }
 #endif
             else {
                 reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_COLON_AFTER_ID);
                 return NULL;
             }
 
-            {
-                TokenPos pos = {begin, pnval->pn_pos.end};
-                pn2 = new_<BinaryNode>(PNK_COLON, op, pos, pn3, pnval);
-            }
+            pn2 = ParseNode::newBinaryOrAppend(PNK_COLON, op, pn3, pnval, tc);
           skip:
             if (!pn2)
                 return NULL;
             pn->append(pn2);
 
             /*
              * Check for duplicate property names.  Duplicate data properties
              * only conflict in strict mode.  Duplicate getter or duplicate
--- a/js/src/frontend/TokenStream.h
+++ b/js/src/frontend/TokenStream.h
@@ -257,26 +257,28 @@ struct TokenPtr {
     }
 };
 
 struct TokenPos {
     TokenPtr          begin;          /* first character and line of token */
     TokenPtr          end;            /* index 1 past last char, last line */
 
     static TokenPos make(const TokenPtr &begin, const TokenPtr &end) {
-        JS_ASSERT(begin <= end);
+        // Assertions temporarily disabled by jorendorff. See bug 695922.
+        //JS_ASSERT(begin <= end);
         TokenPos pos = {begin, end};
         return pos;
     }
 
     /* Return a TokenPos that covers left, right, and anything in between. */
     static TokenPos box(const TokenPos &left, const TokenPos &right) {
-        JS_ASSERT(left.begin <= left.end);
-        JS_ASSERT(left.end <= right.begin);
-        JS_ASSERT(right.begin <= right.end);
+        // Assertions temporarily disabled by jorendorff. See bug 695922.
+        //JS_ASSERT(left.begin <= left.end);
+        //JS_ASSERT(left.end <= right.begin);
+        //JS_ASSERT(right.begin <= right.end);
         TokenPos pos = {left.begin, right.end};
         return pos;
     }
 
     bool operator==(const TokenPos& bpos) const {
         return begin == bpos.begin && end == bpos.end;
     }
 
deleted file mode 100644
--- a/js/src/jit-test/tests/debug/Debugger-getNewestFrame-03.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Debugger.prototype.getNewestFrame() ignores dummy frames.
-// See bug 678086.
-
-var g = newGlobal('new-compartment');
-g.f = function () { return dbg.getNewestFrame(); };
-var dbg = new Debugger;
-var gw = dbg.addDebuggee(g);
-var fw = gw.getOwnPropertyDescriptor("f").value;
-assertEq(fw.call().return, null);
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -5664,19 +5664,16 @@ JSObject::splicePrototype(JSContext *cx,
     /*
      * For singleton types representing only a single JSObject, the proto
      * can be rearranged as needed without destroying type information for
      * the old or new types. Note that type constraints propagating properties
      * from the old prototype are not removed.
      */
     JS_ASSERT_IF(cx->typeInferenceEnabled(), hasSingletonType());
 
-    /* Inner objects may not appear on prototype chains. */
-    JS_ASSERT_IF(proto, !proto->getClass()->ext.outerObject);
-
     /*
      * Force type instantiation when splicing lazy types. This may fail,
      * in which case inference will be disabled for the compartment.
      */
     TypeObject *type = getType(cx);
     TypeObject *protoType = NULL;
     if (proto) {
         protoType = proto->getType(cx);
--- a/js/src/jsinferinlines.h
+++ b/js/src/jsinferinlines.h
@@ -1154,19 +1154,16 @@ TypeCallsite::TypeCallsite(JSContext *cx
 /////////////////////////////////////////////////////////////////////
 // TypeObject
 /////////////////////////////////////////////////////////////////////
 
 inline TypeObject::TypeObject(JSObject *proto, bool function, bool unknown)
 {
     PodZero(this);
 
-    /* Inner objects may not appear on prototype chains. */
-    JS_ASSERT_IF(proto, !proto->getClass()->ext.outerObject);
-
     this->proto = proto;
 
     if (function)
         flags |= OBJECT_FLAG_FUNCTION;
     if (unknown)
         flags |= OBJECT_FLAG_UNKNOWN_MASK;
 
     InferSpew(ISpewOps, "newObject: %s", TypeObjectString(this));
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1009,16 +1009,20 @@ EnterWith(JSContext *cx, jsint stackInde
             return JS_FALSE;
         sp[-1].setObject(*obj);
     }
 
     JSObject *parent = GetScopeChain(cx, fp);
     if (!parent)
         return JS_FALSE;
 
+    OBJ_TO_INNER_OBJECT(cx, obj);
+    if (!obj)
+        return JS_FALSE;
+
     JSObject *withobj = WithObject::create(cx, fp, *obj, *parent,
                                            sp + stackIndex - fp->base());
     if (!withobj)
         return JS_FALSE;
 
     fp->setScopeChainNoCallObj(*withobj);
     return JS_TRUE;
 }
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -181,25 +181,36 @@ obj_setProto(JSContext *cx, JSObject *ob
 
     /* ECMAScript 5 8.6.2 forbids changing [[Prototype]] if not [[Extensible]]. */
     if (!obj->isExtensible()) {
         obj->reportNotExtensible(cx);
         return false;
     }
 
     if (!vp->isObjectOrNull())
-        return true;
+        return JS_TRUE;
 
     JSObject *pobj = vp->toObjectOrNull();
+    if (pobj) {
+        /*
+         * Innerize pobj here to avoid sticking unwanted properties on the
+         * outer object. This ensures that any with statements only grant
+         * access to the inner object.
+         */
+        OBJ_TO_INNER_OBJECT(cx, pobj);
+        if (!pobj)
+            return JS_FALSE;
+    }
+
     uintN attrs;
     id = ATOM_TO_JSID(cx->runtime->atomState.protoAtom);
     if (!CheckAccess(cx, obj, id, JSAccessMode(JSACC_PROTO|JSACC_WRITE), vp, &attrs))
-        return false;
-
-    return SetProto(cx, obj, pobj, true);
+        return JS_FALSE;
+
+    return SetProto(cx, obj, pobj, JS_TRUE);
 }
 
 #else  /* !JS_HAS_OBJ_PROTO_PROP */
 
 #define object_props NULL
 
 #endif /* !JS_HAS_OBJ_PROTO_PROP */
 
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -2555,17 +2555,17 @@ DebuggerFrame_getThis(JSContext *cx, uin
 }
 
 static JSBool
 DebuggerFrame_getOlder(JSContext *cx, uintN argc, Value *vp)
 {
     THIS_FRAME(cx, argc, vp, "get this", args, thisobj, thisfp);
     Debugger *dbg = Debugger::fromChildJSObject(thisobj);
     for (StackFrame *fp = thisfp->prev(); fp; fp = fp->prev()) {
-        if (dbg->observesFrame(fp))
+        if (!fp->isDummyFrame() && dbg->observesFrame(fp))
             return dbg->getScriptFrame(cx, fp, vp);
     }
     args.rval().setNull();
     return true;
 }
 
 Class DebuggerArguments_class = {
     "Arguments", JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGARGUMENTS_COUNT),
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -478,17 +478,17 @@ bool
 Debugger::observesGlobal(GlobalObject *global) const
 {
     return debuggees.has(global);
 }
 
 bool
 Debugger::observesFrame(StackFrame *fp) const
 {
-    return !fp->isDummyFrame() && observesGlobal(&fp->scopeChain().global());
+    return observesGlobal(&fp->scopeChain().global());
 }
 
 JSTrapStatus
 Debugger::onEnterFrame(JSContext *cx, Value *vp)
 {
     if (cx->compartment->getDebuggees().empty())
         return JSTRAP_CONTINUE;
     return slowPathOnEnterFrame(cx, vp);