Bug 975162 - Remove block object's use of shortids (r=wingo)
authorLuke Wagner <luke@mozilla.com>
Fri, 21 Feb 2014 10:23:57 -0600
changeset 170262 343aac1bb02ead4549e25569dcb2d5623550a13a
parent 170261 879e31a2f667470cacf32ba0cdc2a3b5fa72dd9e
child 170263 a6cf2d7996a4cbd058d53829cec7294331c67b89
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewerswingo
bugs975162
milestone30.0a1
Bug 975162 - Remove block object's use of shortids (r=wingo)
js/src/frontend/Parser.cpp
js/src/jsopcode.cpp
js/src/vm/ScopeObject.cpp
js/src/vm/ScopeObject.h
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -2811,20 +2811,18 @@ LexicalLookup(ContextT *ct, HandleAtom a
 
         // Skip statements that do not introduce a new scope
         if (!stmt->isBlockScope)
             continue;
 
         StaticBlockObject &blockObj = stmt->staticBlock();
         Shape *shape = blockObj.nativeLookup(ct->sc->context, id);
         if (shape) {
-            JS_ASSERT(shape->hasShortID());
-
             if (slotp)
-                *slotp = blockObj.stackDepth() + shape->shortid();
+                *slotp = blockObj.stackDepth() + blockObj.shapeToIndex(*shape);
             return stmt;
         }
     }
 
     if (slotp)
         *slotp = -1;
     return stmt;
 }
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -828,36 +828,38 @@ ToDisassemblySource(JSContext *cx, Handl
             return false;
         bytes->initBytes(source);
         return true;
     }
 
     if (!JSVAL_IS_PRIMITIVE(v)) {
         JSObject *obj = JSVAL_TO_OBJECT(v);
         if (obj->is<BlockObject>()) {
+            Rooted<BlockObject*> block(cx, &obj->as<BlockObject>());
             char *source = JS_sprintf_append(nullptr, "depth %d {",
-                                             obj->as<BlockObject>().stackDepth());
+                                             block->stackDepth());
             if (!source)
                 return false;
 
-            Shape::Range<CanGC> r(cx, obj->lastProperty());
+            Shape::Range<CanGC> r(cx, block->lastProperty());
 
             while (!r.empty()) {
                 Rooted<Shape*> shape(cx, &r.front());
                 JSAtom *atom = JSID_IS_INT(shape->propid())
                                ? cx->names().empty
                                : JSID_TO_ATOM(shape->propid());
 
                 JSAutoByteString bytes;
                 if (!AtomToPrintableString(cx, atom, &bytes))
                     return false;
 
                 r.popFront();
                 source = JS_sprintf_append(source, "%s: %d%s",
-                                           bytes.ptr(), shape->shortid(),
+                                           bytes.ptr(),
+                                           block->shapeToIndex(*shape),
                                            !r.empty() ? ", " : "");
                 if (!source)
                     return false;
             }
 
             source = JS_sprintf_append(source, "}");
             if (!source)
                 return false;
@@ -1644,20 +1646,20 @@ JSAtom *
 ExpressionDecompiler::findLetVar(jsbytecode *pc, uint32_t depth)
 {
     for (JSObject *chain = script->getStaticScope(pc); chain; chain = chain->getParent()) {
         if (!chain->is<StaticBlockObject>())
             continue;
         StaticBlockObject &block = chain->as<StaticBlockObject>();
         uint32_t blockDepth = block.stackDepth();
         uint32_t blockCount = block.slotCount();
-        if (uint32_t(depth - blockDepth) < uint32_t(blockCount)) {
+        if (depth - blockDepth < blockCount) {
             for (Shape::Range<NoGC> r(block.lastProperty()); !r.empty(); r.popFront()) {
                 const Shape &shape = r.front();
-                if (shape.shortid() == int(depth - blockDepth))
+                if (block.shapeToIndex(shape) == depth - blockDepth)
                     return JSID_TO_ATOM(shape.propid());
             }
         }
     }
     return nullptr;
 }
 
 JSAtom *
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -736,18 +736,17 @@ StaticBlockObject::addVar(ExclusiveConte
      * Don't convert this object to dictionary mode so that we can clone the
      * block's shape later.
      */
     uint32_t slot = JSSLOT_FREE(&BlockObject::class_) + index;
     return JSObject::addPropertyInternal<SequentialExecution>(
         cx, block, id,
         /* getter = */ nullptr, /* setter = */ nullptr,
         slot, JSPROP_ENUMERATE | JSPROP_PERMANENT,
-        Shape::HAS_SHORTID, index, spp,
-        /* allowDictionary = */ false);
+        0, 0, spp, /* allowDictionary = */ false);
 }
 
 const Class BlockObject::class_ = {
     "Block",
     JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_RESERVED_SLOTS(BlockObject::RESERVED_SLOTS) |
     JSCLASS_IS_ANONYMOUS,
     JS_PropertyStub,         /* addProperty */
@@ -824,32 +823,30 @@ js::XDRStaticBlockObject(XDRState<mode> 
             JS_ASSERT(aliased == 0 || aliased == 1);
             obj->setAliased(i, !!aliased);
         }
     } else {
         AutoShapeVector shapes(cx);
         if (!shapes.growBy(count))
             return false;
 
-        for (Shape::Range<NoGC> r(obj->lastProperty()); !r.empty(); r.popFront()) {
-            Shape *shape = &r.front();
-            shapes[shape->shortid()] = shape;
-        }
+        for (Shape::Range<NoGC> r(obj->lastProperty()); !r.empty(); r.popFront())
+            shapes[obj->shapeToIndex(r.front())] = &r.front();
 
         /*
          * XDR the block object's properties. We know that there are 'count'
          * properties to XDR, stored as id/shortid pairs.
          */
         RootedShape shape(cx);
         RootedId propid(cx);
         RootedAtom atom(cx);
         for (unsigned i = 0; i < count; i++) {
             shape = shapes[i];
             JS_ASSERT(shape->hasDefaultGetter());
-            JS_ASSERT(unsigned(shape->shortid()) == i);
+            JS_ASSERT(obj->shapeToIndex(*shape) == i);
 
             propid = shape->propid();
             JS_ASSERT(JSID_IS_ATOM(propid) || JSID_IS_INT(propid));
 
             /* The empty string indicates an int id. */
             atom = JSID_IS_ATOM(propid)
                    ? JSID_TO_ATOM(propid)
                    : cx->runtime()->emptyString;
@@ -881,22 +878,23 @@ CloneStaticBlockObject(JSContext *cx, Ha
 
     clone->initEnclosingNestedScope(enclosingScope);
     clone->setStackDepth(srcBlock->stackDepth());
 
     /* Shape::Range is reverse order, so build a list in forward order. */
     AutoShapeVector shapes(cx);
     if (!shapes.growBy(srcBlock->slotCount()))
         return nullptr;
+
     for (Shape::Range<NoGC> r(srcBlock->lastProperty()); !r.empty(); r.popFront())
-        shapes[r.front().shortid()] = &r.front();
+        shapes[srcBlock->shapeToIndex(r.front())] = &r.front();
 
     for (Shape **p = shapes.begin(); p != shapes.end(); ++p) {
         RootedId id(cx, (*p)->propid());
-        unsigned i = (*p)->shortid();
+        unsigned i = srcBlock->shapeToIndex(**p);
 
         bool redeclared;
         if (!StaticBlockObject::addVar(cx, clone, id, i, &redeclared)) {
             JS_ASSERT(!redeclared);
             return nullptr;
         }
 
         clone->setAliased(i, srcBlock->isAliased(i));
@@ -1254,17 +1252,17 @@ class DebugScopeProxy : public BaseProxy
 
         /* Handle unaliased let and catch bindings at block scope. */
         if (scope->is<ClonedBlockObject>()) {
             Rooted<ClonedBlockObject *> block(cx, &scope->as<ClonedBlockObject>());
             Shape *shape = block->lastProperty()->search(cx, id);
             if (!shape)
                 return false;
 
-            unsigned i = shape->shortid();
+            unsigned i = block->shapeToIndex(*shape);
             if (block->staticBlock().isAliased(i))
                 return false;
 
             if (maybeLiveScope) {
                 AbstractFramePtr frame = maybeLiveScope->frame();
                 JSScript *script = frame.script();
                 uint32_t local = block->slotToLocalIndex(script->bindings, shape->slot());
                 if (action == GET)
--- a/js/src/vm/ScopeObject.h
+++ b/js/src/vm/ScopeObject.h
@@ -419,16 +419,26 @@ class BlockObject : public NestedScopeOb
         JS_ASSERT(slot < RESERVED_SLOTS + slotCount());
         return bindings.numVars() + stackDepth() + (slot - RESERVED_SLOTS);
     }
 
     uint32_t localIndexToSlot(const Bindings &bindings, uint32_t i) {
         return RESERVED_SLOTS + (i - (bindings.numVars() + stackDepth()));
     }
 
+    /*
+     * Return the index (in the range [0, slotCount()) corresponding to the
+     * given shape of a block object.
+     */
+    uint32_t shapeToIndex(const Shape &shape) {
+        uint32_t slot = shape.slot();
+        JS_ASSERT(slot - RESERVED_SLOTS < slotCount());
+        return slot - RESERVED_SLOTS;
+    }
+
   protected:
     /* Blocks contain an object slot for each slot i: 0 <= i < slotCount. */
     const Value &slotValue(unsigned i) {
         return getSlotRef(RESERVED_SLOTS + i);
     }
 
     void setSlotValue(unsigned i, const Value &v) {
         setSlot(RESERVED_SLOTS + i, v);