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 193145 30e6959192dbe46af42b368bdb820934dbe2a30d
parent 193144 98e17f725ba235fcd1fe65e5c640b47e1b788005
child 193146 f7cc3196d216037b9a63c40549a9cddd6ca5256e
push idunknown
push userunknown
push dateunknown
reviewersluke
bugs985687, 975069
milestone31.0a1
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,