diff --git a/js/src/ds/InlineMap.h b/js/src/ds/InlineMap.h index 27503060711..68ca36fb397 100644 --- a/js/src/ds/InlineMap.h +++ b/js/src/ds/InlineMap.h @@ -89,13 +89,13 @@ class InlineMap { friend class InlineMap; const K &key_; - const V &value_; + V &value_; - Entry(const K &key, const V &value) : key_(key), value_(value) {} + Entry(const K &key, V &value) : key_(key), value_(value) {} public: const K &key() { return key_; } - const V &value() { return value_; } + V &value() { return value_; } }; /* class Entry */ class Ptr diff --git a/js/src/frontend/ParseMaps-inl.h b/js/src/frontend/ParseMaps-inl.h index c371468a8a6..29d18931918 100644 --- a/js/src/frontend/ParseMaps-inl.h +++ b/js/src/frontend/ParseMaps-inl.h @@ -31,10 +31,10 @@ ParseMapPool::acquire() } template <> -inline AtomDOHMap * -ParseMapPool::acquire() +inline AtomDefnListMap * +ParseMapPool::acquire() { - return reinterpret_cast(allocate()); + return reinterpret_cast(allocate()); } inline void * @@ -52,41 +52,31 @@ inline Definition * AtomDecls::lookupFirst(JSAtom *atom) { JS_ASSERT(map); - AtomDOHPtr p = map->lookup(atom); + AtomDefnListPtr p = map->lookup(atom); if (!p) return NULL; - if (p.value().isHeader()) { - /* Just return the head defn. */ - return p.value().header()->defn; - } - return p.value().defn(); + return p.value().front(); } -inline MultiDeclRange +inline DefinitionList::Range AtomDecls::lookupMulti(JSAtom *atom) { JS_ASSERT(map); - AtomDOHPtr p = map->lookup(atom); - if (!p) - return MultiDeclRange((Definition *) NULL); - - DefnOrHeader &doh = p.value(); - if (doh.isHeader()) - return MultiDeclRange(doh.header()); - return MultiDeclRange(doh.defn()); + if (AtomDefnListPtr p = map->lookup(atom)) + return p.value().all(); + return DefinitionList::Range(); } inline bool AtomDecls::addUnique(JSAtom *atom, Definition *defn) { JS_ASSERT(map); - AtomDOHAddPtr p = map->lookupForAdd(atom); - if (p) { - JS_ASSERT(!p.value().isHeader()); - p.value() = DefnOrHeader(defn); - return true; - } - return map->add(p, atom, DefnOrHeader(defn)); + AtomDefnListAddPtr p = map->lookupForAdd(atom); + if (!p) + return map->add(p, atom, DefinitionList(defn)); + JS_ASSERT(!p.value().isMultiple()); + p.value() = DefinitionList(defn); + return true; } template @@ -112,7 +102,7 @@ AtomThingMapPtr::releaseMap(JSContext *cx) inline bool AtomDecls::init() { - map = cx->parseMapPool().acquire(); + map = cx->parseMapPool().acquire(); return map; } diff --git a/js/src/frontend/ParseMaps.cpp b/js/src/frontend/ParseMaps.cpp index 3228fb3f338..773dfbfb29a 100644 --- a/js/src/frontend/ParseMaps.cpp +++ b/js/src/frontend/ParseMaps.cpp @@ -6,6 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "ParseMaps-inl.h" +#include "jscntxt.h" #include "jscompartment.h" using namespace js; @@ -18,13 +19,13 @@ ParseMapPool::checkInvariants() * allocated space for each of the map types. */ JS_STATIC_ASSERT(sizeof(Definition *) == sizeof(jsatomid)); - JS_STATIC_ASSERT(sizeof(Definition *) == sizeof(DefnOrHeader)); + JS_STATIC_ASSERT(sizeof(Definition *) == sizeof(DefinitionList)); JS_STATIC_ASSERT(sizeof(AtomDefnMap::Entry) == sizeof(AtomIndexMap::Entry)); - JS_STATIC_ASSERT(sizeof(AtomDefnMap::Entry) == sizeof(AtomDOHMap::Entry)); - JS_STATIC_ASSERT(sizeof(AtomMapT::Entry) == sizeof(AtomDOHMap::Entry)); + JS_STATIC_ASSERT(sizeof(AtomDefnMap::Entry) == sizeof(AtomDefnListMap::Entry)); + JS_STATIC_ASSERT(sizeof(AtomMapT::Entry) == sizeof(AtomDefnListMap::Entry)); /* Ensure that the HasTable::clear goes quickly via memset. */ JS_STATIC_ASSERT(tl::IsPodType::result); - JS_STATIC_ASSERT(tl::IsPodType::result); + JS_STATIC_ASSERT(tl::IsPodType::result); JS_STATIC_ASSERT(tl::IsPodType::result); } @@ -53,23 +54,67 @@ ParseMapPool::allocateFresh() return (void *) map; } +DefinitionList::Node * +DefinitionList::allocNode(JSContext *cx, Definition *head, Node *tail) +{ + Node *result = cx->tempLifoAlloc().new_(head, tail); + if (!result) + js_ReportOutOfMemory(cx); + return result; +} + +bool +DefinitionList::pushFront(JSContext *cx, Definition *val) +{ + Node *tail; + if (isMultiple()) { + tail = firstNode(); + } else { + tail = allocNode(cx, defn(), NULL); + if (!tail) + return false; + } + + Node *node = allocNode(cx, val, tail); + if (!node) + return false; + *this = DefinitionList(node); + return true; +} + +bool +DefinitionList::pushBack(JSContext *cx, Definition *val) +{ + Node *last; + if (isMultiple()) { + last = firstNode(); + while (last->next) + last = last->next; + } else { + last = allocNode(cx, defn(), NULL); + if (!last) + return false; + } + + Node *node = allocNode(cx, val, NULL); + if (!node) + return false; + last->next = node; + if (!isMultiple()) + *this = DefinitionList(last); + return true; +} + #ifdef DEBUG void AtomDecls::dump() { - for (AtomDOHRange r = map->all(); !r.empty(); r.popFront()) { + for (AtomDefnListRange r = map->all(); !r.empty(); r.popFront()) { fprintf(stderr, "atom: "); js_DumpAtom(r.front().key()); - const DefnOrHeader &doh = r.front().value(); - if (doh.isHeader()) { - AtomDeclNode *node = doh.header(); - do { - fprintf(stderr, " node: %p\n", (void *) node); - fprintf(stderr, " defn: %p\n", (void *) node->defn); - node = node->next; - } while (node); - } else { - fprintf(stderr, " defn: %p\n", (void *) doh.defn()); + const DefinitionList &dlist = r.front().value(); + for (DefinitionList::Range dr = dlist.all(); !dr.empty(); dr.popFront()) { + fprintf(stderr, " defn: %p\n", (void *) dr.front()); } } } @@ -90,74 +135,21 @@ DumpAtomDefnMap(const AtomDefnMapPtr &map) } #endif -AtomDeclNode * -AtomDecls::allocNode(Definition *defn) -{ - AtomDeclNode *p = cx->tempLifoAlloc().new_(defn); - if (!p) { - js_ReportOutOfMemory(cx); - return NULL; - } - return p; -} - bool AtomDecls::addShadow(JSAtom *atom, Definition *defn) { - AtomDeclNode *node = allocNode(defn); - if (!node) - return false; - - AtomDOHAddPtr p = map->lookupForAdd(atom); + AtomDefnListAddPtr p = map->lookupForAdd(atom); if (!p) - return map->add(p, atom, DefnOrHeader(node)); + return map->add(p, atom, DefinitionList(defn)); - AtomDeclNode *toShadow; - if (p.value().isHeader()) { - toShadow = p.value().header(); - } else { - toShadow = allocNode(p.value().defn()); - if (!toShadow) - return false; - } - node->next = toShadow; - p.value() = DefnOrHeader(node); - return true; -} - -AtomDeclNode * -AtomDecls::lastAsNode(DefnOrHeader *doh) -{ - if (doh->isHeader()) { - AtomDeclNode *last = doh->header(); - while (last->next) - last = last->next; - return last; - } - - /* Otherwise, we need to turn the existing defn into a node. */ - AtomDeclNode *node = allocNode(doh->defn()); - if (!node) - return NULL; - *doh = DefnOrHeader(node); - return node; + return p.value().pushFront(cx, defn); } bool AtomDecls::addHoist(JSAtom *atom, Definition *defn) { - AtomDeclNode *node = allocNode(defn); - if (!node) - return false; - - AtomDOHAddPtr p = map->lookupForAdd(atom); - if (p) { - AtomDeclNode *last = lastAsNode(&p.value()); - if (!last) - return false; - last->next = node; - return true; - } - - return map->add(p, atom, DefnOrHeader(node)); + AtomDefnListAddPtr p = map->lookupForAdd(atom); + if (p) + return p.value().pushBack(cx, defn); + return map->add(p, atom, DefinitionList(defn)); } diff --git a/js/src/frontend/ParseMaps.h b/js/src/frontend/ParseMaps.h index 74207aa38d8..dc74c5568ac 100644 --- a/js/src/frontend/ParseMaps.h +++ b/js/src/frontend/ParseMaps.h @@ -18,6 +18,8 @@ namespace js { struct Definition; +typedef InlineMap AtomDefnListMap; + /* * A pool that permits the reuse of the backing storage for the defn, index, or * defn-or-header (multi) maps. @@ -91,7 +93,7 @@ class ParseMapPool recycle((void *) map); } - void release(AtomDOHMap *map) { + void release(AtomDefnListMap *map) { recycle((void *) map); } }; /* ParseMapPool */ @@ -153,59 +155,156 @@ class OwnedAtomThingMapPtr : public AtomThingMapPtrT typedef OwnedAtomThingMapPtr OwnedAtomDefnMapPtr; typedef OwnedAtomThingMapPtr OwnedAtomIndexMapPtr; -/* Node structure for chaining in AtomDecls. */ -struct AtomDeclNode -{ - Definition *defn; - AtomDeclNode *next; - - explicit AtomDeclNode(Definition *defn) - : defn(defn), next(NULL) - {} -}; - /* - * Tagged union of a Definition and an AtomDeclNode, for use in AtomDecl's - * internal map. + * A nonempty list containing one or more pointers to Definitions. + * + * By far the most common case is that the list contains exactly one + * Definition, so the implementation is optimized for that case. + * + * Nodes for the linked list (if any) are allocated from the tempPool of a + * context the caller passes into pushFront and pushBack. This means the + * DefinitionList does not own the memory for the nodes: the JSContext does. + * As a result, DefinitionList is a POD type; it can be safely and cheaply + * copied. */ -class DefnOrHeader +class DefinitionList { + public: + class Range; + + private: + friend class Range; + + /* A node in a linked list of Definitions. */ + struct Node + { + Definition *defn; + Node *next; + + Node(Definition *defn, Node *next) : defn(defn), next(next) {} + }; + union { - Definition *defn; - AtomDeclNode *head; - uintptr_t bits; + Definition *defn; + Node *head; + uintptr_t bits; } u; - public: - DefnOrHeader() { - u.bits = 0; - } - - explicit DefnOrHeader(Definition *defn) { - u.defn = defn; - JS_ASSERT(!isHeader()); - } - - explicit DefnOrHeader(AtomDeclNode *node) { - u.head = node; - u.bits |= 0x1; - JS_ASSERT(isHeader()); - } - - bool isHeader() const { - return u.bits & 0x1; - } - Definition *defn() const { - JS_ASSERT(!isHeader()); + JS_ASSERT(!isMultiple()); return u.defn; } - AtomDeclNode *header() const { - JS_ASSERT(isHeader()); - return (AtomDeclNode *) (u.bits & ~0x1); + Node *firstNode() const { + JS_ASSERT(isMultiple()); + return (Node *) (u.bits & ~0x1); } + static Node * + allocNode(JSContext *cx, Definition *head, Node *tail); + + public: + class Range + { + friend class DefinitionList; + + Node *node; + Definition *defn; + + explicit Range(const DefinitionList &list) { + if (list.isMultiple()) { + node = list.firstNode(); + defn = node->defn; + } else { + node = NULL; + defn = list.defn(); + } + } + + public: + /* An empty Range. */ + Range() : node(NULL), defn(NULL) {} + + void popFront() { + JS_ASSERT(!empty()); + if (!node) { + defn = NULL; + return; + } + node = node->next; + defn = node ? node->defn : NULL; + } + + Definition *front() { + JS_ASSERT(!empty()); + return defn; + } + + bool empty() const { + JS_ASSERT_IF(!defn, !node); + return !defn; + } + }; + + DefinitionList() { + u.bits = 0; + } + + explicit DefinitionList(Definition *defn) { + u.defn = defn; + JS_ASSERT(!isMultiple()); + } + + explicit DefinitionList(Node *node) { + u.head = node; + u.bits |= 0x1; + JS_ASSERT(isMultiple()); + } + + bool isMultiple() const { return (u.bits & 0x1) != 0; } + + Definition *front() { + return isMultiple() ? firstNode()->defn : defn(); + } + + /* + * If there are multiple Definitions in this list, remove the first and + * return true. Otherwise there is exactly one Definition in the list; do + * nothing and return false. + */ + bool popFront() { + if (!isMultiple()) + return false; + + Node *node = firstNode(); + Node *next = node->next; + if (next->next) + *this = DefinitionList(next); + else + *this = DefinitionList(next->defn); + return true; + } + + /* + * Add a definition to the front of this list. + * + * Return true on success. On OOM, report on cx and return false. + */ + bool pushFront(JSContext *cx, Definition *val); + + /* Like pushFront, but add the given val to the end of the list. */ + bool pushBack(JSContext *cx, Definition *val); + + /* Overwrite the first Definition in the list. */ + void setFront(Definition *val) { + if (isMultiple()) + firstNode()->defn = val; + else + *this = DefinitionList(val); + } + + Range all() const { return Range(*this); } + #ifdef DEBUG void dump(); #endif @@ -213,7 +312,7 @@ class DefnOrHeader namespace tl { -template <> struct IsPodType { +template <> struct IsPodType { static const bool result = true; }; @@ -222,7 +321,7 @@ template <> struct IsPodType { /* * Multimap for function-scope atom declarations. * - * Wraps an internal DeclOrHeader map with multi-map functionality. + * Wraps an internal DefinitionList map with multi-map functionality. * * In the common case, no block scoping is used, and atoms have a single * associated definition. In the uncommon (block scoping) case, we map the atom @@ -230,27 +329,17 @@ template <> struct IsPodType { */ class AtomDecls { - /* AtomDeclsIter needs to get at the DOHMap directly. */ + /* AtomDeclsIter needs to get at the DefnListMap directly. */ friend class AtomDeclsIter; JSContext *cx; - AtomDOHMap *map; + AtomDefnListMap *map; AtomDecls(const AtomDecls &other) MOZ_DELETE; void operator=(const AtomDecls &other) MOZ_DELETE; - AtomDeclNode *allocNode(Definition *defn); - - /* - * Fallibly return the value in |doh| as a node. - * Update the defn currently occupying |doh| to a node if necessary. - */ - AtomDeclNode *lastAsNode(DefnOrHeader *doh); - public: - explicit AtomDecls(JSContext *cx) - : cx(cx), map(NULL) - {} + explicit AtomDecls(JSContext *cx) : cx(cx), map(NULL) {} ~AtomDecls(); @@ -264,7 +353,7 @@ class AtomDecls inline Definition *lookupFirst(JSAtom *atom); /* Perform a lookup that can iterate over the definitions associated with |atom|. */ - inline MultiDeclRange lookupMulti(JSAtom *atom); + inline DefinitionList::Range lookupMulti(JSAtom *atom); /* Add-or-update a known-unique definition for |atom|. */ inline bool addUnique(JSAtom *atom, Definition *defn); @@ -274,40 +363,26 @@ class AtomDecls /* Updating the definition for an entry that is known to exist is infallible. */ void updateFirst(JSAtom *atom, Definition *defn) { JS_ASSERT(map); - AtomDOHMap::Ptr p = map->lookup(atom); + AtomDefnListMap::Ptr p = map->lookup(atom); JS_ASSERT(p); - if (p.value().isHeader()) - p.value().header()->defn = defn; - else - p.value() = DefnOrHeader(defn); + p.value().setFront(defn); } /* Remove the node at the head of the chain for |atom|. */ void remove(JSAtom *atom) { JS_ASSERT(map); - AtomDOHMap::Ptr p = map->lookup(atom); + AtomDefnListMap::Ptr p = map->lookup(atom); if (!p) return; - DefnOrHeader &doh = p.value(); - if (!doh.isHeader()) { + DefinitionList &list = p.value(); + if (!list.popFront()) { map->remove(p); return; } - - AtomDeclNode *node = doh.header(); - AtomDeclNode *newHead = node->next; - if (newHead) { - if (newHead->next) - p.value() = DefnOrHeader(newHead); - else - p.value() = DefnOrHeader(newHead->defn); - } else { - map->remove(p); - } } - AtomDOHMap::Range all() { + AtomDefnListMap::Range all() { JS_ASSERT(map); return map->all(); } @@ -317,85 +392,14 @@ class AtomDecls #endif }; -/* - * Lookup state tracker for those situations where the caller wants to traverse - * multiple definitions associated with a single atom. This occurs due to block - * scoping. - */ -class MultiDeclRange -{ - friend class AtomDecls; - - AtomDeclNode *node; - Definition *defn; - - explicit MultiDeclRange(Definition *defn) : node(NULL), defn(defn) {} - explicit MultiDeclRange(AtomDeclNode *node) : node(node), defn(node->defn) {} - - public: - void popFront() { - JS_ASSERT(!empty()); - if (!node) { - defn = NULL; - return; - } - node = node->next; - defn = node ? node->defn : NULL; - } - - Definition *front() { - JS_ASSERT(!empty()); - return defn; - } - - bool empty() const { - JS_ASSERT_IF(!defn, !node); - return !defn; - } -}; - -/* Iterates over all the definitions in an AtomDecls. */ -class AtomDeclsIter -{ - AtomDOHMap::Range r; /* Range over the map. */ - AtomDeclNode *link; /* Optional next node in the current atom's chain. */ - - public: - explicit AtomDeclsIter(AtomDecls *decls) : r(decls->all()), link(NULL) {} - - Definition *next() { - if (link) { - JS_ASSERT(link != link->next); - Definition *result = link->defn; - link = link->next; - JS_ASSERT(result); - return result; - } - - if (r.empty()) - return NULL; - - const DefnOrHeader &doh = r.front().value(); - r.popFront(); - - if (!doh.isHeader()) - return doh.defn(); - - JS_ASSERT(!link); - AtomDeclNode *node = doh.header(); - link = node->next; - return node->defn; - } -}; - typedef AtomDefnMap::Range AtomDefnRange; typedef AtomDefnMap::AddPtr AtomDefnAddPtr; typedef AtomDefnMap::Ptr AtomDefnPtr; typedef AtomIndexMap::AddPtr AtomIndexAddPtr; typedef AtomIndexMap::Ptr AtomIndexPtr; -typedef AtomDOHMap::Ptr AtomDOHPtr; -typedef AtomDOHMap::AddPtr AtomDOHAddPtr; -typedef AtomDOHMap::Range AtomDOHRange; +typedef AtomDefnListMap::Ptr AtomDefnListPtr; +typedef AtomDefnListMap::AddPtr AtomDefnListAddPtr; +typedef AtomDefnListMap::Range AtomDefnListRange; } /* namepsace js */ diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index edd6407da77..63f2aa63511 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -706,13 +706,17 @@ Parser::functionBody(FunctionBodyType type) * might, in the case of calls to eval) be assigned. */ if (tc->sc->inStrictMode()) { - AtomDeclsIter iter(&tc->decls); - while (Definition *dn = iter.next()) { - if (dn->kind() == Definition::ARG && dn->isAssigned()) { - tc->sc->setFunDefinitelyNeedsArgsObj(); - break; + for (AtomDefnListMap::Range r = tc->decls.all(); !r.empty(); r.popFront()) { + DefinitionList &dlist = r.front().value(); + for (DefinitionList::Range dr = dlist.all(); !dr.empty(); dr.popFront()) { + Definition *dn = dr.front(); + if (dn->kind() == Definition::ARG && dn->isAssigned()) { + tc->sc->setFunDefinitelyNeedsArgsObj(); + goto exitLoop; + } } } + exitLoop: ; } break; case ARGUMENT: @@ -1570,14 +1574,18 @@ Parser::functionDef(HandlePropertyName funName, FunctionType type, FunctionSynta * Parser::functionArguments has returned. */ if (prelude) { - AtomDeclsIter iter(&funtc.decls); - while (Definition *apn = iter.next()) { - /* Filter based on pn_op -- see BindDestructuringArg, above. */ - if (!apn->isOp(JSOP_SETLOCAL)) - continue; + for (AtomDefnListMap::Range r = tc->decls.all(); !r.empty(); r.popFront()) { + DefinitionList &dlist = r.front().value(); + for (DefinitionList::Range dr = dlist.all(); !dr.empty(); dr.popFront()) { + Definition *apn = dr.front(); - if (!BindLocalVariable(context, &funtc, apn, VARIABLE)) - return NULL; + /* Filter based on pn_op -- see BindDestructuringArg, above. */ + if (!apn->isOp(JSOP_SETLOCAL)) + continue; + + if (!BindLocalVariable(context, &funtc, apn, VARIABLE)) + return NULL; + } } } #endif @@ -2067,7 +2075,7 @@ OuterLet(TreeContext *tc, StmtInfoTC *stmt, JSAtom *atom) } static bool -BindFunctionLocal(JSContext *cx, BindData *data, MultiDeclRange &mdl, TreeContext *tc) +BindFunctionLocal(JSContext *cx, BindData *data, DefinitionList::Range &defs, TreeContext *tc) { JS_ASSERT(tc->sc->inFunction()); @@ -2093,7 +2101,7 @@ BindFunctionLocal(JSContext *cx, BindData *data, MultiDeclRange &mdl, TreeContex if (kind == ARGUMENT) { JS_ASSERT(tc->sc->inFunction()); - JS_ASSERT(!mdl.empty() && mdl.front()->kind() == Definition::ARG); + JS_ASSERT(!defs.empty() && defs.front()->kind() == Definition::ARG); } else { JS_ASSERT(kind == VARIABLE || kind == CONSTANT); } @@ -2122,11 +2130,11 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser) return true; } - MultiDeclRange mdl = tc->decls.lookupMulti(atom); + DefinitionList::Range defs = tc->decls.lookupMulti(atom); JSOp op = data->op; - if (stmt || !mdl.empty()) { - Definition *dn = mdl.empty() ? NULL : mdl.front(); + if (stmt || !defs.empty()) { + Definition *dn = defs.empty() ? NULL : defs.front(); Definition::Kind dn_kind = dn ? dn->kind() : Definition::VAR; if (dn_kind == Definition::ARG) { @@ -2163,14 +2171,14 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser) } } - if (mdl.empty()) { + if (defs.empty()) { if (!Define(pn, atom, tc)) return false; } else { /* * A var declaration never recreates an existing binding, it restates * it and possibly reinitializes its value. Beware that if pn becomes a - * use of |mdl.defn()|, and if we have an initializer for this var or + * use of |defs.defn()|, and if we have an initializer for this var or * const (typically a const would ;-), then pn must be rewritten into a * PNK_ASSIGN node. See js::Parser::variables, further below. * @@ -2178,7 +2186,7 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser) * There the x definition is hoisted but the x = 2 assignment mutates * the block-local binding of x. */ - Definition *dn = mdl.front(); + Definition *dn = defs.front(); data->fresh = false; @@ -2198,10 +2206,10 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser) /* Find the first non-let binding of this atom. */ while (dn->kind() == Definition::LET) { - mdl.popFront(); - if (mdl.empty()) + defs.popFront(); + if (defs.empty()) break; - dn = mdl.front(); + dn = defs.front(); } if (dn) { @@ -2240,7 +2248,7 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser) pn->pn_dflags |= PND_CONST; if (tc->sc->inFunction()) - return BindFunctionLocal(cx, data, mdl, tc); + return BindFunctionLocal(cx, data, defs, tc); return true; } @@ -2305,11 +2313,11 @@ NoteNameUse(ParseNode *pn, Parser *parser) PropertyName *name = pn->pn_atom->asPropertyName(); StmtInfoTC *stmt = LexicalLookup(parser->tc, name, NULL, (StmtInfoTC *)NULL); - MultiDeclRange mdl = parser->tc->decls.lookupMulti(name); + DefinitionList::Range defs = parser->tc->decls.lookupMulti(name); Definition *dn; - if (!mdl.empty()) { - dn = mdl.front(); + if (!defs.empty()) { + dn = defs.front(); } else { if (AtomDefnAddPtr p = parser->tc->lexdeps->lookupForAdd(name)) { dn = p.value(); diff --git a/js/src/jsprvtd.h b/js/src/jsprvtd.h index b6b1cb168a3..19b5aef3c2b 100644 --- a/js/src/jsprvtd.h +++ b/js/src/jsprvtd.h @@ -174,10 +174,9 @@ struct StackShape; class MultiDeclRange; class ParseMapPool; -class DefnOrHeader; +class DefinitionList; typedef InlineMap AtomDefnMap; typedef InlineMap AtomIndexMap; -typedef InlineMap AtomDOHMap; typedef Vector UpvarCookies; class Breakpoint;