Bug 985687 - Remove vestigial tinyid/shortid references, as well as the field in JSPropertySpec. Followup to bug 975069. r=luke
authorJeff Walden <jwalden@mit.edu>
Tue, 11 Mar 2014 12:03:56 -0700
changeset 174641 30e6959192dbe46af42b368bdb820934dbe2a30d
parent 174640 98e17f725ba235fcd1fe65e5c640b47e1b788005
child 174642 f7cc3196d216037b9a63c40549a9cddd6ca5256e
push id41309
push userjwalden@mit.edu
push dateThu, 20 Mar 2014 21:34:15 +0000
treeherdermozilla-inbound@30e6959192db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs985687, 975069
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 985687 - Remove vestigial tinyid/shortid references, as well as the field in JSPropertySpec. Followup to bug 975069. r=luke
dom/bindings/Codegen.py
js/src/frontend/Parser.cpp
js/src/jsapi.h
js/src/shell/js.cpp
js/src/tests/js1_8_5/extensions/mega-let.js
js/src/vm/ScopeObject.cpp
js/src/vm/ScopeObject.h
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1825,17 +1825,17 @@ class AttrDefiner(PropertyDefiner):
                    (accessor, jitinfo)
 
         def specData(attr):
             return (attr.identifier.name, flags(attr), getter(attr),
                     setter(attr))
 
         return self.generatePrefableArray(
             array, name,
-            '  { "%s", 0, %s, %s, %s}',
+            '  { "%s", %s, %s, %s}',
             '  JS_PS_END',
             'JSPropertySpec',
             PropertyDefiner.getControllingCondition, specData, doIdArrays)
 
 class ConstDefiner(PropertyDefiner):
     """
     A class for definining constants on the interface object
     """
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -2688,20 +2688,16 @@ Parser<FullParseHandler>::bindLet(BindDa
     ParseNode *pn = data->pn;
     if (!parser->checkStrictBinding(name, pn))
         return false;
 
     ExclusiveContext *cx = parser->context;
 
     Rooted<StaticBlockObject *> blockObj(cx, data->let.blockObj);
     unsigned index = blockObj->numVariables();
-    if (index >= StaticBlockObject::LOCAL_INDEX_LIMIT) {
-        parser->report(ParseError, false, pn, data->let.overflow);
-        return false;
-    }
 
     /*
      * Assign block-local index to pn->pn_cookie right away, encoding it as an
      * upvar cookie whose skip tells the current static level. The emitter will
      * adjust the node's slot based on its stack depth model -- and, for global
      * and eval code, js::frontend::CompileScript will adjust the slot
      * again to include script->nfixed.
      */
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2390,17 +2390,16 @@ typedef struct JSNativeWrapper {
  */
 struct JSPropertySpec {
     struct SelfHostedWrapper {
         void       *unused;
         const char *funname;
     };
 
     const char                  *name;
-    int8_t                      tinyid;
     uint8_t                     flags;
     union {
         JSPropertyOpWrapper propertyOp;
         SelfHostedWrapper   selfHosted;
     } getter;
     union {
         JSStrictPropertyOpWrapper propertyOp;
         SelfHostedWrapper         selfHosted;
@@ -2444,36 +2443,36 @@ CheckIsCharacterLiteral(const char (&arr
 /*
  * JSPropertySpec uses JSAPI JSPropertyOp and JSStrictPropertyOp in function
  * signatures.  These macros encapsulate the definition of JSNative-backed
  * JSPropertySpecs, performing type-safe casts on the getter/setter functions
  * and adding the necessary property flags to trigger interpretation as
  * JSNatives.
  */
 #define JS_PSG(name, getter, flags) \
-    {name, 0, \
+    {name, \
      uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS), \
      JSOP_WRAPPER(JS_CAST_NATIVE_TO(getter, JSPropertyOp)), \
      JSOP_NULLWRAPPER}
 #define JS_PSGS(name, getter, setter, flags) \
-    {name, 0, \
+    {name, \
      uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS), \
      JSOP_WRAPPER(JS_CAST_NATIVE_TO(getter, JSPropertyOp)), \
      JSOP_WRAPPER(JS_CAST_NATIVE_TO(setter, JSStrictPropertyOp))}
 #define JS_SELF_HOSTED_GET(name, getterName, flags) \
-    {name, 0, \
+    {name, \
      uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER), \
      { nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo *) }, \
      JSOP_NULLWRAPPER }
 #define JS_SELF_HOSTED_GETSET(name, getterName, setterName, flags) \
-    {name, 0, \
+    {name, \
      uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER), \
      { nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo *) },  \
      { nullptr, JS_CAST_STRING_TO(setterName, const JSJitInfo *) } }
-#define JS_PS_END {0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
+#define JS_PS_END { nullptr, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
 
 /*
  * To define a native function, set call to a JSNativeWrapper. To define a
  * self-hosted function, set selfHostedName to the name of a function
  * compiled during JSRuntime::initSelfHosting.
  */
 struct JSFunctionSpec {
     const char      *name;
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -5154,17 +5154,17 @@ static const JSJitInfo doFoo_methodinfo 
     false,    /* isInfallible. False in setters. */
     false,    /* isMovable */
     false,    /* isInSlot */
     false,    /* isTypedMethod */
     0         /* slotIndex */
 };
 
 static const JSPropertySpec dom_props[] = {
-    {"x", 0,
+    {"x",
      JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS,
      { { (JSPropertyOp)dom_genericGetter, &dom_x_getterinfo } },
      { { (JSStrictPropertyOp)dom_genericSetter, &dom_x_setterinfo } }
     },
     JS_PS_END
 };
 
 static const JSFunctionSpec dom_methods[] = {
new file mode 100644
--- /dev/null
+++ b/js/src/tests/js1_8_5/extensions/mega-let.js
@@ -0,0 +1,39 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 999999;
+var summary =
+  "Allow defining more than 2**16 let-variables in a single scope";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+print("Creating binding string...");
+
+var bindings = [];
+var codeStr = "let ";
+for (var i = 0; i < Math.pow(2, 20); i++)
+  bindings.push("x" + i + " = " + i);
+
+var codeStr = "let " + bindings.join(", ") + ";";
+
+print("Binding string created, testing with global eval...");
+
+eval(codeStr);
+
+print("Testing with Function...");
+
+Function(codeStr)();
+
+print("Testing inside a function...");
+
+eval("function q() { " + codeStr + " }; q();");
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
+
+print("Tests complete");
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -679,17 +679,16 @@ StaticBlockObject::create(ExclusiveConte
     return &obj->as<StaticBlockObject>();
 }
 
 /* static */ Shape *
 StaticBlockObject::addVar(ExclusiveContext *cx, Handle<StaticBlockObject*> block, HandleId id,
                           unsigned index, bool *redeclared)
 {
     JS_ASSERT(JSID_IS_ATOM(id));
-    JS_ASSERT(index < LOCAL_INDEX_LIMIT);
 
     *redeclared = false;
 
     /* Inline JSObject::addProperty in order to trap the redefinition case. */
     Shape **spp;
     if (Shape::search(cx, block->lastProperty(), id, &spp, true)) {
         *redeclared = true;
         return nullptr;
@@ -750,29 +749,29 @@ js::XDRStaticBlockObject(XDRState<mode> 
         *objp = obj;
     }
 
     if (!xdr->codeUint32(&count))
         return false;
     if (!xdr->codeUint32(&offset))
         return false;
 
+    /*
+     * XDR the block object's properties. We know that there are 'count'
+     * properties to XDR, stored as id/aliased pairs.  (The empty string as
+     * id indicates an int id.)
+     */
     if (mode == XDR_DECODE) {
         obj->setLocalOffset(offset);
 
-        /*
-         * XDR the block object's properties. We know that there are 'count'
-         * properties to XDR, stored as id/shortid pairs.
-         */
         for (unsigned i = 0; i < count; i++) {
             RootedAtom atom(cx);
             if (!XDRAtom(xdr, &atom))
                 return false;
 
-            /* The empty string indicates an int id. */
             RootedId id(cx, atom != cx->runtime()->emptyString
                             ? AtomToId(atom)
                             : INT_TO_JSID(i));
 
             bool redeclared;
             if (!StaticBlockObject::addVar(cx, obj, id, i, &redeclared)) {
                 JS_ASSERT(!redeclared);
                 return false;
@@ -788,32 +787,27 @@ js::XDRStaticBlockObject(XDRState<mode> 
     } else {
         AutoShapeVector shapes(cx);
         if (!shapes.growBy(count))
             return false;
 
         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(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;
             if (!XDRAtom(xdr, &atom))
                 return false;
 
             uint32_t aliased = obj->isAliased(i);
             if (!xdr->codeUint32(&aliased))
--- a/js/src/vm/ScopeObject.h
+++ b/js/src/vm/ScopeObject.h
@@ -527,24 +527,16 @@ class StaticBlockObject : public BlockOb
         setSlotValue(i, PrivateValue(def));
     }
 
     frontend::Definition *definitionParseNode(unsigned i) {
         Value v = slotValue(i);
         return reinterpret_cast<frontend::Definition *>(v.toPrivate());
     }
 
-    /*
-     * While ScopeCoordinate can generally reference up to 2^24 slots, block objects have an
-     * additional limitation that all slot indices must be storable as uint16_t short-ids in the
-     * associated Shape. If we could remove the block dependencies on shape->shortid, we could
-     * remove INDEX_LIMIT.
-     */
-    static const unsigned LOCAL_INDEX_LIMIT = JS_BIT(16);
-
     static Shape *addVar(ExclusiveContext *cx, Handle<StaticBlockObject*> block, HandleId id,
                          unsigned index, bool *redeclared);
 };
 
 class ClonedBlockObject : public BlockObject
 {
   public:
     static ClonedBlockObject *create(JSContext *cx, Handle<StaticBlockObject *> block,