diff --git a/mozilla/js/src/js.c b/mozilla/js/src/js.c index 08834537fc2..9ee1fa4ba11 100644 --- a/mozilla/js/src/js.c +++ b/mozilla/js/src/js.c @@ -976,7 +976,7 @@ DumpScope(JSContext *cx, JSObject *obj, JSHashEnumerator dump, FILE *fp) int i; fprintf(fp, "\n%s scope contents:\n", OBJ_GET_CLASS(cx, obj)->name); - scope = (JSScope *)obj->map; + scope = OBJ_SCOPE(obj); if (!MAP_IS_NATIVE(&scope->map)) return; if (scope->ops == &js_list_scope_ops) { diff --git a/mozilla/js/src/jsapi.c b/mozilla/js/src/jsapi.c index 7a5fcdf5e19..121c4ab6e76 100644 --- a/mozilla/js/src/jsapi.c +++ b/mozilla/js/src/jsapi.c @@ -1661,7 +1661,7 @@ JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name, if (!atom) { ok = JS_FALSE; } else { - scope = (JSScope *) obj->map; + scope = OBJ_SCOPE(obj); ok = (scope->ops->add(cx, scope, (jsid)atom, (JSScopeProperty *)prop) != NULL); } @@ -2006,7 +2006,7 @@ JS_AliasElement(JSContext *cx, JSObject *obj, const char *name, jsint alias) numBuf, name, OBJ_GET_CLASS(cx, obj2)->name); return JS_FALSE; } - scope = (JSScope *) obj->map; + scope = OBJ_SCOPE(obj); ok = (scope->ops->add(cx, scope, INT_TO_JSVAL(alias), (JSScopeProperty *)prop) != NULL); @@ -2506,11 +2506,16 @@ JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj, funAtom = NULL; goto out; } - funAtom = js_Atomize(cx, name, strlen(name), 0); - if (!funAtom) { - fun = NULL; - goto out; + if (!name) { + funAtom = NULL; + } else { + funAtom = js_Atomize(cx, name, strlen(name), 0); + if (!funAtom) { + fun = NULL; + goto out; + } } +/* XXXbe new-function, bind name only on success */ fun = js_DefineFunction(cx, obj, funAtom, NULL, nargs, 0); if (!fun) goto out; diff --git a/mozilla/js/src/jsdbgapi.c b/mozilla/js/src/jsdbgapi.c index a479242e6cc..82368a9d202 100644 --- a/mozilla/js/src/jsdbgapi.c +++ b/mozilla/js/src/jsdbgapi.c @@ -251,9 +251,9 @@ DropWatchPoint(JSContext *cx, JSWatchPoint *wp) { if (--wp->nrefs != 0) return; - wp->sprop->setter = wp->setter; + SPROP_SETTER(wp->sprop, wp->object) = wp->setter; JS_LOCK_OBJ_VOID(cx, wp->object, - js_DropScopeProperty(cx, (JSScope *)wp->object->map, + js_DropScopeProperty(cx, OBJ_SCOPE(wp->object), wp->sprop)); JS_REMOVE_LINK(&wp->links); js_RemoveRoot(cx->runtime, &wp->closure); @@ -319,7 +319,7 @@ js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp) } symid = (jsid)atom; } - scope = (JSScope *) obj->map; + scope = OBJ_SCOPE(obj); JS_ASSERT(scope->props); ok = LOCKED_OBJ_GET_CLASS(obj)->addProperty(cx, obj, sprop->id, &value); @@ -409,8 +409,8 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval id, return JS_FALSE; } } - getter = sprop->getter; - setter = sprop->setter; + getter = SPROP_GETTER(sprop, pobj); + setter = SPROP_SETTER(sprop, pobj); attrs = sprop->attrs; OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop); @@ -434,9 +434,9 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval id, JS_APPEND_LINK(&wp->links, &rt->watchPointList); wp->object = obj; wp->userid = id; - wp->sprop = js_HoldScopeProperty(cx, (JSScope *)obj->map, sprop); - wp->setter = sprop->setter; - sprop->setter = js_watch_set; + wp->sprop = js_HoldScopeProperty(cx, OBJ_SCOPE(obj), sprop); + wp->setter = SPROP_SETTER(sprop, obj); + SPROP_SETTER(sprop, obj) = js_watch_set; wp->nrefs = 1; } wp->handler = handler; @@ -732,7 +732,7 @@ JS_PropertyIterator(JSObject *obj, JSScopeProperty **iteratorp) JSScope *scope; sprop = *iteratorp; - scope = (JSScope *) obj->map; + scope = OBJ_SCOPE(obj); sprop = (sprop == NULL) ? scope->props : sprop->next; *iteratorp = sprop; return sprop; @@ -743,23 +743,25 @@ JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, JSPropertyDesc *pd) { JSSymbol *sym; + JSPropertyOp getter; sym = sprop->symbols; pd->id = sym ? js_IdToValue(sym_id(sym)) : JSVAL_VOID; if (!sym || !js_GetProperty(cx, obj, sym_id(sym), &pd->value)) pd->value = OBJ_GET_SLOT(cx, obj, sprop->slot); + getter = SPROP_GETTER(sprop, obj); pd->flags = ((sprop->attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0) | ((sprop->attrs & JSPROP_READONLY) ? JSPD_READONLY : 0) | ((sprop->attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0) #if JS_HAS_CALL_OBJECT - | ((sprop->getter == js_GetCallVariable) ? JSPD_VARIABLE : 0) + | ((getter == js_GetCallVariable) ? JSPD_VARIABLE : 0) #endif /* JS_HAS_CALL_OBJECT */ - | ((sprop->getter == js_GetArgument) ? JSPD_ARGUMENT : 0) - | ((sprop->getter == js_GetLocalVariable) ? JSPD_VARIABLE : 0); + | ((getter == js_GetArgument) ? JSPD_ARGUMENT : 0) + | ((getter == js_GetLocalVariable) ? JSPD_VARIABLE : 0); #if JS_HAS_CALL_OBJECT /* for Call Object 'real' getter isn't passed in to us */ if (OBJ_GET_CLASS(cx, obj) == &js_CallClass && - sprop->getter == js_CallClass.getProperty) { + getter == js_CallClass.getProperty) { pd->flags |= JSPD_ARGUMENT; } #endif /* JS_HAS_CALL_OBJECT */ @@ -795,10 +797,9 @@ JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda) return JS_FALSE; /* have no props, or object's scope has not mutated from that of proto */ - scope = (JSScope *)obj->map; + scope = OBJ_SCOPE(obj); if (!scope->props || - (OBJ_GET_PROTO(cx,obj) && - scope == (JSScope *)(OBJ_GET_PROTO(cx,obj)->map))) { + (OBJ_GET_PROTO(cx,obj) && scope == OBJ_SCOPE(OBJ_GET_PROTO(cx,obj)))) { pda->length = 0; pda->array = NULL; return JS_TRUE; diff --git a/mozilla/js/src/jsfun.c b/mozilla/js/src/jsfun.c index e1c6b40e9a0..d8adb97fd45 100644 --- a/mozilla/js/src/jsfun.c +++ b/mozilla/js/src/jsfun.c @@ -469,9 +469,9 @@ call_enumerate(JSContext *cx, JSObject *obj) return JS_TRUE; /* Reflect actual args for formal parameters, and all local variables. */ - scope = (JSScope *)fun->object->map; + scope = OBJ_SCOPE(fun->object); for (sprop = scope->props; sprop; sprop = sprop->next) { - getter = sprop->getter; + getter = SPROP_GETTER_SCOPE(sprop, scope); if (getter != js_GetArgument && getter != js_GetLocalVariable) continue; @@ -518,7 +518,7 @@ call_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, } if (sprop) { - getter = sprop->getter; + getter = SPROP_GETTER(sprop, obj2); propid = sprop->id; symid = (jsid) sym_atom(sprop->symbols); OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop); @@ -804,7 +804,7 @@ fun_enumProperty(JSContext *cx, JSObject *obj) */ JS_LOCK_OBJ(cx, obj); - scope = (JSScope *) obj->map; + scope = OBJ_SCOPE(obj); for (sprop = scope->props; sprop; sprop = sprop->next) { jsval id = sprop->id; if (!JSVAL_IS_INT(id)) { @@ -1023,13 +1023,15 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp) /* do arguments and local vars */ if (fun->object) { if (xdr->mode == JSXDR_ENCODE) { - JSScope *scope = (JSScope *) fun->object->map; + JSScope *scope = OBJ_SCOPE(fun->object); for (sprop = scope->props; sprop; sprop = sprop->next) { - if (sprop->getter == js_GetArgument) { + JSPropertyOp getter = SPROP_GETTER_SCOPE(sprop, scope); + + if (getter == js_GetArgument) { type = JSXDR_FUNARG; JS_ASSERT(nargs++ <= fun->nargs); - } else if (sprop->getter == js_GetLocalVariable) { + } else if (getter == js_GetLocalVariable) { type = JSXDR_FUNVAR; JS_ASSERT(nvars++ <= fun->nvars); } else { @@ -1535,7 +1537,7 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) } if (sprop && obj2 == obj) { #ifdef CHECK_ARGUMENT_HIDING - JS_ASSERT(sprop->getter == js_GetArgument); + JS_ASSERT(SPROP_GETTER(sprop, obj) == js_GetArgument); OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop); JS_ReportErrorNumber(cx, JSREPORT_WARNING, JSMSG_SAME_FORMAL, ATOM_BYTES(atom)); diff --git a/mozilla/js/src/jsgc.c b/mozilla/js/src/jsgc.c index 3e465a06266..95d3c3785df 100644 --- a/mozilla/js/src/jsgc.c +++ b/mozilla/js/src/jsgc.c @@ -502,7 +502,7 @@ gc_mark(JSRuntime *rt, void *thing) obj = thing; vp = obj->slots; if (vp) { - scope = OBJ_IS_NATIVE(obj) ? (JSScope *) obj->map : NULL; + scope = OBJ_IS_NATIVE(obj) ? OBJ_SCOPE(obj) : NULL; if (scope) { clasp = JSVAL_TO_PRIVATE(obj->slots[JSSLOT_CLASS]); @@ -550,7 +550,8 @@ gc_mark(JSRuntime *rt, void *thing) id, js_getter_str); #endif GC_MARK(rt, - JSVAL_TO_GCTHING((jsval)sprop->getter), + JSVAL_TO_GCTHING((jsval) + SPROP_GETTER_SCOPE(sprop, scope)), buf, prev); } @@ -560,7 +561,8 @@ gc_mark(JSRuntime *rt, void *thing) id, js_setter_str); #endif GC_MARK(rt, - JSVAL_TO_GCTHING((jsval)sprop->setter), + JSVAL_TO_GCTHING((jsval) + SPROP_SETTER_SCOPE(sprop, scope)), buf, prev); } diff --git a/mozilla/js/src/jslock.c b/mozilla/js/src/jslock.c index a0c4416db96..56c46f16d59 100644 --- a/mozilla/js/src/jslock.c +++ b/mozilla/js/src/jslock.c @@ -70,11 +70,11 @@ js_UnlockGlobal(void *id) } #define ReadWord(W) (W) -#define AtomicAddBody(P,I)\ - jsword n;\ - do {\ - n = ReadWord(*(P));\ - } while (!js_CompareAndSwap(P, n, n + I)); +#define AtomicAddBody(P,I) \ + jsword n; \ + do { \ + n = ReadWord(*(P)); \ + } while (!js_CompareAndSwap(P, n, n + I)) /* Exclude Alpha NT. */ #if defined(_WIN32) && defined(_M_IX86) && !defined(NSPR_LOCK) @@ -112,10 +112,10 @@ static PRLock *_counter_lock; #define UsingCounterLock 1 #undef AtomicAddBody -#define AtomicAddBody(P,I) \ - PR_Lock(_counter_lock);\ - *(P) += I;\ - PR_Unlock(_counter_lock); +#define AtomicAddBody(P,I) \ + PR_Lock(_counter_lock); \ + *(P) += I; \ + PR_Unlock(_counter_lock) #endif /* !ULTRA_SPARC */ @@ -182,10 +182,10 @@ static PRLock *_counter_lock; #define UsingCounterLock 1 #undef AtomicAddBody -#define AtomicAddBody(P,I) \ - PR_Lock(_counter_lock);\ - *(P) += I;\ - PR_Unlock(_counter_lock); +#define AtomicAddBody(P,I) \ + PR_Lock(_counter_lock); \ + *(P) += I; \ + PR_Unlock(_counter_lock) static PRLock *_compare_and_swap_lock; #define UsingCompareAndSwapLock 1 @@ -219,25 +219,25 @@ js_CurrentThreadId() } void -js_NewLock(JSThinLock *p) +js_NewLock(JSThinLock *tl) { #ifdef NSPR_LOCK - p->owner = 0; - p->fat = (JSFatLock*)JS_NEW_LOCK(); + tl->owner = 0; + tl->fat = (JSFatLock*)JS_NEW_LOCK(); #else - memset(p, 0, sizeof(JSThinLock)); + memset(tl, 0, sizeof(JSThinLock)); #endif } void -js_DestroyLock(JSThinLock *p) +js_DestroyLock(JSThinLock *tl) { #ifdef NSPR_LOCK - p->owner = 0xdeadbeef; - JS_DESTROY_LOCK(((JSLock*)p->fat)); + tl->owner = 0xdeadbeef; + JS_DESTROY_LOCK(((JSLock*)tl->fat)); #else - JS_ASSERT(p->owner == 0); - JS_ASSERT(p->fat == NULL); + JS_ASSERT(tl->owner == 0); + JS_ASSERT(tl->fat == NULL); #endif } @@ -248,27 +248,27 @@ js_GetSlotWhileLocked(JSContext *cx, JSObject *obj, uint32 slot) { jsval v; #ifndef NSPR_LOCK - JSScope *scp = (JSScope *)obj->map; - JSThinLock *p = &scp->lock; + JSScope *scope = OBJ_SCOPE(obj); + JSThinLock *tl = &scope->lock; jsword me = cx->thread; #endif JS_ASSERT(obj->slots && slot < obj->map->freeslot); #ifndef NSPR_LOCK JS_ASSERT(me == CurrentThreadId()); - if (js_CompareAndSwap(&p->owner, 0, me)) { - if (scp == (JSScope *)obj->map) { + if (js_CompareAndSwap(&tl->owner, 0, me)) { + if (scope == OBJ_SCOPE(obj)) { v = obj->slots[slot]; - if (!js_CompareAndSwap(&p->owner, me, 0)) { - scp->count = 1; + if (!js_CompareAndSwap(&tl->owner, me, 0)) { + scope->count = 1; js_UnlockObj(cx,obj); } return v; } - if (!js_CompareAndSwap(&p->owner, me, 0)) - js_Dequeue(p); + if (!js_CompareAndSwap(&tl->owner, me, 0)) + js_Dequeue(tl); } - else if (Thin_RemoveWait(ReadWord(p->owner)) == me) { + else if (Thin_RemoveWait(ReadWord(tl->owner)) == me) { return obj->slots[slot]; } #endif @@ -282,27 +282,27 @@ JS_INLINE void js_SetSlotWhileLocked(JSContext *cx, JSObject *obj, uint32 slot, jsval v) { #ifndef NSPR_LOCK - JSScope *scp = (JSScope *)obj->map; - JSThinLock *p = &scp->lock; + JSScope *scope = OBJ_SCOPE(obj); + JSThinLock *tl = &scope->lock; jsword me = cx->thread; #endif JS_ASSERT(obj->slots && slot < obj->map->freeslot); #ifndef NSPR_LOCK JS_ASSERT(me == CurrentThreadId()); - if (js_CompareAndSwap(&p->owner, 0, me)) { - if (scp == (JSScope *)obj->map) { + if (js_CompareAndSwap(&tl->owner, 0, me)) { + if (scope == OBJ_SCOPE(obj)) { obj->slots[slot] = v; - if (!js_CompareAndSwap(&p->owner, me, 0)) { - scp->count = 1; + if (!js_CompareAndSwap(&tl->owner, me, 0)) { + scope->count = 1; js_UnlockObj(cx,obj); } return; } - if (!js_CompareAndSwap(&p->owner, me, 0)) - js_Dequeue(p); + if (!js_CompareAndSwap(&tl->owner, me, 0)) + js_Dequeue(tl); } - else if (Thin_RemoveWait(ReadWord(p->owner)) == me) { + else if (Thin_RemoveWait(ReadWord(tl->owner)) == me) { obj->slots[slot] = v; return; } @@ -316,7 +316,7 @@ static JSFatLock * mallocFatlock() { JSFatLock *fl = (JSFatLock *)malloc(sizeof(JSFatLock)); /* for now */ - JS_ASSERT(fl); + if (!fl) return NULL; fl->susp = 0; fl->next = NULL; fl->prev = NULL; @@ -338,13 +338,13 @@ listOfFatlocks(int l) { JSFatLock *m; JSFatLock *m0; - int i; + int i; JS_ASSERT(l>0); m0 = m = mallocFatlock(); for (i=1; inext = mallocFatlock(); - m = m->next; + m->next = mallocFatlock(); + m = m->next; } return m0; } @@ -364,25 +364,25 @@ static JSFatLockTable* _fl_tables; static JSFatLock * allocateFatlock(void *id) { - JSFatLock *m; + JSFatLock *m; - int i = ((int)id/4)%_nr_of_globals; - if (_fl_tables[i].free == NULL) { -#ifdef DEBUG - printf("Ran out of fat locks!\n"); -#endif - _fl_tables[i].free = listOfFatlocks(10); - } - m = _fl_tables[i].free; - _fl_tables[i].free = m->next; - _fl_tables[i].free->prev = NULL; - m->susp = 0; - m->next = _fl_tables[i].taken; - m->prev = NULL; - if (_fl_tables[i].taken != NULL) - _fl_tables[i].taken->prev = m; - _fl_tables[i].taken = m; - return m; + int i = ((int)id/4)%_nr_of_globals; + if (_fl_tables[i].free == NULL) { + #ifdef DEBUG + printf("Ran out of fat locks!\n"); + #endif + _fl_tables[i].free = listOfFatlocks(10); + } + m = _fl_tables[i].free; + _fl_tables[i].free = m->next; + _fl_tables[i].free->prev = NULL; + m->susp = 0; + m->next = _fl_tables[i].taken; + m->prev = NULL; + if (_fl_tables[i].taken != NULL) + _fl_tables[i].taken->prev = m; + _fl_tables[i].taken = m; + return m; } static void @@ -508,93 +508,93 @@ js_InitContextForLocking(JSContext *cx) (ii) fl->susp >= 0 */ static int -js_SuspendThread(JSThinLock *p) +js_SuspendThread(JSThinLock *tl) { JSFatLock *fl; JSStatus stat; - - if (p->fat == NULL) - fl = p->fat = allocateFatlock(p); + + if (tl->fat == NULL) + fl = tl->fat = allocateFatlock(tl); else - fl = p->fat; + fl = tl->fat; JS_ASSERT(fl->susp >= 0); fl->susp++; PR_Lock(fl->slock); - js_UnlockGlobal(p); + js_UnlockGlobal(tl); stat = (JSStatus)PR_WaitCondVar(fl->svar,PR_INTERVAL_NO_TIMEOUT); JS_ASSERT(stat != JS_FAILURE); PR_Unlock(fl->slock); - js_LockGlobal(p); + js_LockGlobal(tl); fl->susp--; if (fl->susp == 0) { - deallocateFatlock(fl,p); - p->fat = NULL; + deallocateFatlock(fl,tl); + tl->fat = NULL; } - return p->fat == NULL; + return tl->fat == NULL; } -/* (i) global lock is held +/* (i) global lock is held (ii) fl->susp > 0 */ static void -js_ResumeThread(JSThinLock *p) +js_ResumeThread(JSThinLock *tl) { - JSFatLock *fl = p->fat; + JSFatLock *fl = tl->fat; JSStatus stat; JS_ASSERT(fl != NULL); JS_ASSERT(fl->susp > 0); PR_Lock(fl->slock); - js_UnlockGlobal(p); + js_UnlockGlobal(tl); stat = (JSStatus)PR_NotifyCondVar(fl->svar); JS_ASSERT(stat != JS_FAILURE); PR_Unlock(fl->slock); } static void -js_Enqueue(JSThinLock *p, jsword me) +js_Enqueue(JSThinLock *tl, jsword me) { jsword o, n; - js_LockGlobal(p); + js_LockGlobal(tl); while (1) { - o = ReadWord(p->owner); + o = ReadWord(tl->owner); n = Thin_SetWait(o); - if (o != 0 && js_CompareAndSwap(&p->owner,o,n)) { - if (js_SuspendThread(p)) + if (o != 0 && js_CompareAndSwap(&tl->owner,o,n)) { + if (js_SuspendThread(tl)) me = Thin_RemoveWait(me); else me = Thin_SetWait(me); } - else if (js_CompareAndSwap(&p->owner,0,me)) { - js_UnlockGlobal(p); + else if (js_CompareAndSwap(&tl->owner,0,me)) { + js_UnlockGlobal(tl); return; } } } static void -js_Dequeue(JSThinLock *p) +js_Dequeue(JSThinLock *tl) { int o; - js_LockGlobal(p); - o = ReadWord(p->owner); + js_LockGlobal(tl); + o = ReadWord(tl->owner); JS_ASSERT(Thin_GetWait(o) != 0); - JS_ASSERT(p->fat != NULL); - if (!js_CompareAndSwap(&p->owner,o,0)) /* release it */ + JS_ASSERT(tl->fat != NULL); + if (!js_CompareAndSwap(&tl->owner,o,0)) /* release it */ JS_ASSERT(0); - js_ResumeThread(p); + js_ResumeThread(tl); } JS_INLINE void -js_Lock(JSThinLock *p, jsword me) +js_Lock(JSThinLock *tl, jsword me) { JS_ASSERT(me == CurrentThreadId()); - if (js_CompareAndSwap(&p->owner, 0, me)) + if (js_CompareAndSwap(&tl->owner, 0, me)) return; - if (Thin_RemoveWait(ReadWord(p->owner)) != me) - js_Enqueue(p, me); + if (Thin_RemoveWait(ReadWord(tl->owner)) != me) + js_Enqueue(tl, me); #ifdef DEBUG else JS_ASSERT(0); @@ -602,13 +602,13 @@ js_Lock(JSThinLock *p, jsword me) } JS_INLINE void -js_Unlock(JSThinLock *p, jsword me) +js_Unlock(JSThinLock *tl, jsword me) { JS_ASSERT(me == CurrentThreadId()); - if (js_CompareAndSwap(&p->owner, me, 0)) + if (js_CompareAndSwap(&tl->owner, me, 0)) return; - if (Thin_RemoveWait(ReadWord(p->owner)) == me) - js_Dequeue(p); + if (Thin_RemoveWait(ReadWord(tl->owner)) == me) + js_Dequeue(tl); #ifdef DEBUG else JS_ASSERT(0); @@ -619,35 +619,35 @@ void js_LockRuntime(JSRuntime *rt) { jsword me = CurrentThreadId(); - JSThinLock *p; + JSThinLock *tl; JS_ASSERT(Thin_RemoveWait(ReadWord(rt->rtLock.owner)) != me); - p = &rt->rtLock; - JS_LOCK0(p,me); + tl = &rt->rtLock; + JS_LOCK0(tl,me); } void js_UnlockRuntime(JSRuntime *rt) { jsword me = CurrentThreadId(); - JSThinLock *p; + JSThinLock *tl; JS_ASSERT(Thin_RemoveWait(ReadWord(rt->rtLock.owner)) == me); - p = &rt->rtLock; - JS_UNLOCK0(p,me); + tl = &rt->rtLock; + JS_UNLOCK0(tl,me); } static JS_INLINE void js_LockScope1(JSContext *cx, JSScope *scope, jsword me) { - JSThinLock *p; + JSThinLock *tl; if (Thin_RemoveWait(ReadWord(scope->lock.owner)) == me) { JS_ASSERT(scope->count > 0); scope->count++; } else { - p = &scope->lock; - JS_LOCK0(p,me); + tl = &scope->lock; + JS_LOCK0(tl,me); JS_ASSERT(scope->count == 0); scope->count = 1; } @@ -664,7 +664,7 @@ void js_UnlockScope(JSContext *cx, JSScope *scope) { jsword me = cx->thread; - JSThinLock *p; + JSThinLock *tl; JS_ASSERT(scope->count > 0); if (Thin_RemoveWait(ReadWord(scope->lock.owner)) != me) { @@ -672,8 +672,8 @@ js_UnlockScope(JSContext *cx, JSScope *scope) return; } if (--scope->count == 0) { - p = &scope->lock; - JS_UNLOCK0(p,me); + tl = &scope->lock; + JS_UNLOCK0(tl,me); } } @@ -681,30 +681,32 @@ void js_TransferScopeLock(JSContext *cx, JSScope *oldscope, JSScope *newscope) { jsword me; - JSThinLock *p; + JSThinLock *tl; JS_ASSERT(JS_IS_SCOPE_LOCKED(newscope)); + /* * If the last reference to oldscope went away, newscope needs no lock * state update. */ - if (!oldscope) { + if (!oldscope) return; - } JS_ASSERT(JS_IS_SCOPE_LOCKED(oldscope)); + /* * Transfer oldscope's entry count to newscope, as it will be unlocked * now via JS_UNLOCK_OBJ(cx,obj) calls made while we unwind the C stack * from the current point (under js_GetMutableScope). */ newscope->count = oldscope->count; + /* * Reset oldscope's lock state so that it is completely unlocked. */ oldscope->count = 0; - p = &oldscope->lock; + tl = &oldscope->lock; me = cx->thread; - JS_UNLOCK0(p,me); + JS_UNLOCK0(tl,me); } void @@ -714,22 +716,22 @@ js_LockObj(JSContext *cx, JSObject *obj) jsword me = cx->thread; JS_ASSERT(me == CurrentThreadId()); for (;;) { - scope = (JSScope *) obj->map; - js_LockScope1(cx, scope, me); + scope = OBJ_SCOPE(obj); + js_LockScope1(cx, scope, me); - /* If obj still has this scope, we're done. */ - if (scope == (JSScope *) obj->map) - return; + /* If obj still has this scope, we're done. */ + if (scope == OBJ_SCOPE(obj)) + return; - /* Lost a race with a mutator; retry with obj's new scope. */ - js_UnlockScope(cx, scope); + /* Lost a race with a mutator; retry with obj's new scope. */ + js_UnlockScope(cx, scope); } } void js_UnlockObj(JSContext *cx, JSObject *obj) { - js_UnlockScope(cx, (JSScope *) obj->map); + js_UnlockScope(cx, OBJ_SCOPE(obj)); } #ifdef DEBUG @@ -742,9 +744,10 @@ js_IsRuntimeLocked(JSRuntime *rt) JSBool js_IsObjLocked(JSObject *obj) { - JSObjectMap *map = obj->map; + JSScope *scope = OBJ_SCOPE(obj); - return MAP_IS_NATIVE(map) && CurrentThreadId() == Thin_RemoveWait(ReadWord(((JSScope *)map)->lock.owner)); + return MAP_IS_NATIVE(&scope->map) && + CurrentThreadId() == Thin_RemoveWait(ReadWord(scope->lock.owner)); } JSBool diff --git a/mozilla/js/src/jslock.h b/mozilla/js/src/jslock.h index 79b30631910..05f66e1f6bb 100644 --- a/mozilla/js/src/jslock.h +++ b/mozilla/js/src/jslock.h @@ -87,7 +87,7 @@ typedef struct JSFatLockTable { #include "jsscope.h" #define _SET_OBJ_INFO(obj,f,l) \ - _SET_SCOPE_INFO(((JSScope*)obj->map),f,l) + _SET_SCOPE_INFO(OBJ_SCOPE(obj),f,l) #define _SET_SCOPE_INFO(scope,f,l) \ (JS_ASSERT(scope->count > 0 && scope->count <= 4), \ diff --git a/mozilla/js/src/jsobj.c b/mozilla/js/src/jsobj.c index 1ed69e0bfd3..3bef3ee37a1 100644 --- a/mozilla/js/src/jsobj.c +++ b/mozilla/js/src/jsobj.c @@ -249,7 +249,7 @@ MarkSharpObjects(JSContext *cx, JSObject *obj, JSIdArray **idap) (attrs & (JSPROP_GETTER | JSPROP_SETTER))) { val = JSVAL_NULL; if (attrs & JSPROP_GETTER) - val = (jsval) ((JSScopeProperty *)prop)->getter; + val = (jsval)SPROP_GETTER((JSScopeProperty*)prop, obj2); if (attrs & JSPROP_SETTER) { if (val != JSVAL_NULL) { /* Mark the getter here, then set val to setter. */ @@ -257,7 +257,7 @@ MarkSharpObjects(JSContext *cx, JSObject *obj, JSIdArray **idap) NULL) != NULL); } - val = (jsval) ((JSScopeProperty *)prop)->setter; + val = (jsval)SPROP_SETTER((JSScopeProperty*)prop, obj2); } } else { ok = OBJ_GET_PROPERTY(cx, obj, id, &val); @@ -486,13 +486,15 @@ js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, (attrs & (JSPROP_GETTER | JSPROP_SETTER))) { valcnt = 0; if (attrs & JSPROP_GETTER) { - val[valcnt] = (jsval) ((JSScopeProperty *)prop)->getter; + val[valcnt] = (jsval) + SPROP_GETTER((JSScopeProperty *)prop, obj2); gsop[valcnt] = ATOM_TO_STRING(cx->runtime->atomState.getterAtom); valcnt++; } if (attrs & JSPROP_SETTER) { - val[valcnt] = (jsval) ((JSScopeProperty *)prop)->setter; + val[valcnt] = (jsval) + SPROP_SETTER((JSScopeProperty *)prop, obj2); gsop[valcnt] = ATOM_TO_STRING(cx->runtime->atomState.setterAtom); valcnt++; @@ -1516,9 +1518,9 @@ js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, (sprop->attrs & (JSPROP_GETTER | JSPROP_SETTER))) { sprop->attrs |= attrs; if (attrs & JSPROP_GETTER) - sprop->getter = getter; + SPROP_GETTER(sprop, pobj) = getter; else - sprop->setter = setter; + SPROP_SETTER(sprop, pobj) = setter; if (propp) *propp = (JSProperty *) sprop; #ifdef JS_THREADSAFE @@ -1610,7 +1612,7 @@ js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, for (;;) { JS_LOCK_OBJ(cx, obj); _SET_OBJ_INFO(obj, file, line); - scope = (JSScope *)obj->map; + scope = OBJ_SCOPE(obj); if (scope == prevscope) goto skip; sym = scope->ops->lookup(cx, scope, id, hash); @@ -1635,7 +1637,7 @@ js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, JS_LOCK_OBJ(cx, obj); _SET_OBJ_INFO(obj, file, line); if (obj2) { - scope = (JSScope *)obj2->map; + scope = OBJ_SCOPE(obj2); if (MAP_IS_NATIVE(&scope->map)) sym = scope->ops->lookup(cx, scope, id, hash); } @@ -1645,14 +1647,14 @@ js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, return JS_FALSE; JS_LOCK_OBJ(cx, obj); _SET_OBJ_INFO(obj, file, line); - scope = (JSScope *)obj->map; + scope = OBJ_SCOPE(obj); if (MAP_IS_NATIVE(&scope->map)) sym = scope->ops->lookup(cx, scope, id, hash); } } } if (sym && (sprop = sym_property(sym)) != NULL) { - JS_ASSERT((JSScope *)obj->map == scope); + JS_ASSERT(OBJ_SCOPE(obj) == scope); *objp = scope->object; /* XXXbe hide in jsscope.[ch] */ #ifdef JS_THREADSAFE js_HoldScopeProperty(cx, scope, sprop); @@ -1924,7 +1926,7 @@ js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp) JS_UNLOCK_OBJ(cx, obj); while (proto) { JS_LOCK_OBJ(cx, proto); - protoscope = (JSScope *)proto->map; + protoscope = OBJ_SCOPE(proto); if (MAP_IS_NATIVE(&protoscope->map)) { protosym = protoscope->ops->lookup(cx, protoscope, id, hash); if (protosym) { @@ -1952,8 +1954,8 @@ js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp) #endif /* JS_HAS_GETTER_SETTER */ protoid = protosprop->id; - protogetter = protosprop->getter; - protosetter = protosprop->setter; + protogetter = SPROP_GETTER_SCOPE(protosprop,protoscope); + protosetter = SPROP_SETTER_SCOPE(protosprop,protoscope); JS_UNLOCK_OBJ(cx, proto); break; } @@ -2191,7 +2193,7 @@ js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval) } GC_POKE(cx, LOCKED_OBJ_GET_SLOT(obj, sprop->slot)); - scope = (JSScope *)obj->map; + scope = OBJ_SCOPE(obj); /* * Purge cache only if prop is not about to be destroyed (since @@ -2203,7 +2205,7 @@ js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval) } #if JS_HAS_OBJ_WATCHPOINT - if (sprop->setter == js_watch_set) { + if (SPROP_SETTER_SCOPE(sprop, scope) == js_watch_set) { /* * Keep the symbol around with null value in case of re-set. * The watchpoint will hold the "deleted" property until it @@ -2381,7 +2383,7 @@ js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, * deleted during the iteration. */ JS_LOCK_OBJ(cx, obj); - scope = (JSScope *) obj->map; + scope = OBJ_SCOPE(obj); /* * If this object shares a scope with its prototype, don't enumerate @@ -2389,7 +2391,7 @@ js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, * when the prototype object is enumerated. */ proto_obj = OBJ_GET_PROTO(cx, obj); - if (proto_obj && (scope == (JSScope *)proto_obj->map)) { + if (proto_obj && scope == OBJ_SCOPE(proto_obj)) { ida = js_NewIdArray(cx, 0); if (!ida) { JS_UNLOCK_OBJ(cx, obj); @@ -2553,7 +2555,7 @@ js_IsDelegate(JSContext *cx, JSObject *obj, jsval v, JSBool *bp) void js_DropProperty(JSContext *cx, JSObject *obj, JSProperty *prop) { - js_DropScopeProperty(cx, (JSScope *)obj->map, (JSScopeProperty *)prop); + js_DropScopeProperty(cx, OBJ_SCOPE(obj), (JSScopeProperty *)prop); JS_UNLOCK_OBJ(cx, obj); } #endif diff --git a/mozilla/js/src/jsobj.h b/mozilla/js/src/jsobj.h index 924c09229e0..30c90c54aef 100644 --- a/mozilla/js/src/jsobj.h +++ b/mozilla/js/src/jsobj.h @@ -165,8 +165,8 @@ struct JSObject { extern JS_FRIEND_DATA(JSObjectOps) js_ObjectOps; extern JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps; -extern JSClass js_ObjectClass; -extern JSClass js_WithClass; +extern JSClass js_ObjectClass; +extern JSClass js_WithClass; struct JSSharpObjectMap { jsrefcount depth; diff --git a/mozilla/js/src/jsopcode.c b/mozilla/js/src/jsopcode.c index 6289f8780e0..785ea1904d7 100644 --- a/mozilla/js/src/jsopcode.c +++ b/mozilla/js/src/jsopcode.c @@ -451,7 +451,7 @@ js_NewPrinter(JSContext *cx, const char *name, uintN indent, JSBool pretty) if (fp && fp->scopeChain) { obj = fp->scopeChain; map = obj->map; - if (map->ops == &js_ObjectOps) { + if (MAP_IS_NATIVE(map)) { if (OBJ_GET_CLASS(cx, obj) == &js_CallClass) { obj = fp->fun ? fp->fun->object : NULL; if (obj) @@ -747,7 +747,7 @@ GetSlotAtom(JSScope *scope, JSPropertyOp getter, uintN slot) if (!scope) return NULL; for (sprop = scope->props; sprop; sprop = sprop->next) { - if (sprop->getter != getter) + if (SPROP_GETTER_SCOPE(sprop, scope) != getter) continue; if ((uintN)JSVAL_TO_INT(sprop->id) == slot) return sym_atom(sprop->symbols); @@ -2128,7 +2128,7 @@ js_DecompileFunctionBody(JSPrinter *jp, JSFunction *fun) js_printf(jp, native_code_str); return JS_TRUE; } - scope = fun->object ? (JSScope *)fun->object->map : NULL; + scope = fun->object ? OBJ_SCOPE(fun->object) : NULL; save = jp->scope; jp->scope = scope; ok = js_DecompileCode(jp, script, script->code, (uintN)script->length); @@ -2171,10 +2171,10 @@ js_DecompileFunction(JSPrinter *jp, JSFunction *fun) for (i = 0; ; i++) { jsid id; atom = NULL; - scope = (JSScope *)fun->object->map; + scope = OBJ_SCOPE(fun->object); for (sprop = scope->props; sprop; sprop = snext) { snext = sprop->next; - if (sprop->getter != js_GetArgument) + if (SPROP_GETTER_SCOPE(sprop, scope) != js_GetArgument) continue; if (JSVAL_IS_INT(sprop->id) && JSVAL_TO_INT(sprop->id) == i) { atom = sym_atom(sprop->symbols); diff --git a/mozilla/js/src/jsparse.c b/mozilla/js/src/jsparse.c index 661469d2ccd..ebf9373f9fd 100644 --- a/mozilla/js/src/jsparse.c +++ b/mozilla/js/src/jsparse.c @@ -110,21 +110,18 @@ static JSMemberParser MemberExpr; static JSParser PrimaryExpr; /* - * Insist that the next token be of type tt, or report err and throw or fail. + * Insist that the next token be of type tt, or report errno and return null. * NB: this macro uses cx and ts from its lexical environment. */ -#define MUST_MATCH_TOKEN_THROW(tt, errno, throw) \ +#define MUST_MATCH_TOKEN(tt, errno) \ JS_BEGIN_MACRO \ if (js_GetToken(cx, ts) != tt) { \ js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR, errno); \ - throw; \ + return NULL; \ } \ JS_END_MACRO -#define MUST_MATCH_TOKEN(tt, errno) \ - MUST_MATCH_TOKEN_THROW(tt, errno, return NULL) - /* * Allocate a JSParseNode from cx's temporary arena. @@ -447,9 +444,12 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, JSParseNode *pn, *pn2; JSOp op; JSAtom *funAtom, *argAtom; - JSObject *parent; JSFunction *fun, *outerFun; - JSBool ok, named; + JSObject *parent; + JSPropertyOp getter, setter; + uintN attrs; + JSBool named; + jsval fval; JSObject *pobj; JSScopeProperty *sprop; JSTreeContext funtc; @@ -471,74 +471,55 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, if (!parent) return NULL; + /* Set up for ultimate OBJ_DEFINE_PROPERTY call, if not anonymous. */ + named = !lambda && funAtom && !InWithStatement(tc); + getter = setter = NULL; + attrs = JSPROP_ENUMERATE; + + fun = js_NewFunction(cx, NULL, NULL, 0, 0, parent, funAtom); + if (!fun) + return NULL; + #if JS_HAS_GETTER_SETTER if (op != JSOP_NOP) { - JSPropertyOp getter, setter; - uintN attr; + uintN gsattr; - fun = js_NewFunction(cx, NULL, NULL, 0, 0, parent, funAtom); - if (!fun) - return NULL; if (op == JSOP_GETTER) { getter = (JSPropertyOp) fun->object; - setter = NULL; - attr = JSPROP_GETTER; + gsattr = JSPROP_GETTER; } else { - getter = NULL; setter = (JSPropertyOp) fun->object; - attr = JSPROP_SETTER; + gsattr = JSPROP_SETTER; } - fun->flags |= attr; + fun->flags |= gsattr; + attrs |= gsattr; - if (!lambda && funAtom && !InWithStatement(tc)) { - if (!OBJ_DEFINE_PROPERTY(cx, parent, (jsid)funAtom, JSVAL_VOID, - getter, setter, attr | JSPROP_ENUMERATE, - NULL)) { - return NULL; - } - } - } else -#endif -#if JS_HAS_LEXICAL_CLOSURE - if (lambda || !funAtom || InWithStatement(tc)) { - /* Don't name the function if enclosed by a with statement or equiv. */ - fun = js_NewFunction(cx, NULL, NULL, 0, 0, cx->fp->scopeChain, - funAtom); - named = JS_FALSE; + fval = JSVAL_VOID; } else #endif { - /* Don't add the function to it's parent until the parse succeeds. */ - fun = js_NewFunction(cx, NULL, NULL, 0, 0, parent, funAtom); - named = (fun != NULL); - } - if (!fun) { - ok = JS_FALSE; - goto out; + fval = OBJECT_TO_JSVAL(fun->object); } /* Now parse formal argument list and compute fun->nargs. */ - MUST_MATCH_TOKEN_THROW(TOK_LP, JSMSG_PAREN_BEFORE_FORMAL, - ok = JS_FALSE; goto out); + MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_FORMAL); if (!js_MatchToken(cx, ts, TOK_RP)) { do { - MUST_MATCH_TOKEN_THROW(TOK_NAME, JSMSG_MISSING_FORMAL, - ok = JS_FALSE; goto out); + MUST_MATCH_TOKEN(TOK_NAME, JSMSG_MISSING_FORMAL); argAtom = CURRENT_TOKEN(ts).t_atom; pobj = NULL; - ok = js_LookupProperty(cx, fun->object, (jsid)argAtom, &pobj, - (JSProperty **)&sprop); - if (!ok) - goto out; + if (!js_LookupProperty(cx, fun->object, (jsid)argAtom, &pobj, + (JSProperty **)&sprop)) { + return NULL; + } if (sprop && pobj == fun->object) { - if (sprop->getter == js_GetArgument) { + if (SPROP_GETTER(sprop, pobj) == js_GetArgument) { #ifdef CHECK_ARGUMENT_HIDING OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop); js_ReportCompileErrorNumber(cx, ts, JSREPORT_WARNING, JSMSG_DUPLICATE_FORMAL, ATOM_BYTES(argAtom)); - ok = JS_FALSE; - goto out; + return NULL; #else /* * A duplicate parameter name. We create a dummy symbol @@ -549,13 +530,13 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, jsid oldArgId = (jsid) sprop->id; OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop); sprop = NULL; - ok = js_DefineProperty(cx, fun->object, + if (!js_DefineProperty(cx, fun->object, oldArgId, JSVAL_VOID, js_GetArgument, js_SetArgument, JSPROP_ENUMERATE | JSPROP_PERMANENT, - (JSProperty **)&sprop); - if (!ok) - goto out; + (JSProperty **)&sprop)) { + return NULL; + } sprop->id = (jsid) argAtom; #endif } @@ -564,35 +545,30 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop); sprop = NULL; } - ok = js_DefineProperty(cx, fun->object, + if (!js_DefineProperty(cx, fun->object, (jsid)argAtom, JSVAL_VOID, js_GetArgument, js_SetArgument, JSPROP_ENUMERATE | JSPROP_PERMANENT, - (JSProperty **)&sprop); - if (!ok) - goto out; + (JSProperty **)&sprop)) { + return NULL; + } JS_ASSERT(sprop); sprop->id = INT_TO_JSVAL(fun->nargs++); OBJ_DROP_PROPERTY(cx, fun->object, (JSProperty *)sprop); } while (js_MatchToken(cx, ts, TOK_COMMA)); - MUST_MATCH_TOKEN_THROW(TOK_RP, JSMSG_PAREN_AFTER_FORMAL, - ok = JS_FALSE; goto out); + MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_FORMAL); } - MUST_MATCH_TOKEN_THROW(TOK_LC, JSMSG_CURLY_BEFORE_BODY, - ok = JS_FALSE; goto out); + MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_BODY); pn->pn_pos.begin = CURRENT_TOKEN(ts).pos.begin; TREE_CONTEXT_INIT(&funtc); pn2 = FunctionBody(cx, ts, fun, &funtc); - if (!pn2) { - ok = JS_FALSE; - goto out; - } + if (!pn2) + return NULL; - MUST_MATCH_TOKEN_THROW(TOK_RC, JSMSG_CURLY_AFTER_BODY, - ok = JS_FALSE; goto out); + MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_BODY); pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end; pn->pn_fun = fun; @@ -608,15 +584,10 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, #endif pn->pn_op = JSOP_NOP; - ok = JS_TRUE; - if (named) - if (!OBJ_DEFINE_PROPERTY(cx, parent, (jsid)funAtom, OBJECT_TO_JSVAL(fun->object), - NULL, NULL, JSPROP_ENUMERATE, NULL)) { - return NULL; - } -out: - if (!ok) { - return NULL; + if (named && + !OBJ_DEFINE_PROPERTY(cx, parent, (jsid)funAtom, fval, getter, setter, + attrs, NULL)) { + return NULL; } return pn; } @@ -1085,8 +1056,8 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) /* * We can be sure that if it's a for/in loop, there's still an 'in' * keyword here, even if Javascript recognizes it as an operator, - * because we've excluded it from parsing by setting the - * TCF_IN_FOR_INIT flag on the JSTreeContext argument. + * because we've excluded it from being parsed in RelExpr by setting + * the TCF_IN_FOR_INIT flag in our JSTreeContext. */ if (pn1 && js_MatchToken(cx, ts, TOK_IN)) { stmtInfo.type = STMT_FOR_IN_LOOP; @@ -1589,8 +1560,9 @@ Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) if (pobj == obj && OBJ_IS_NATIVE(pobj) && (sprop = (JSScopeProperty *)prop) != NULL) { - if (sprop->getter == js_GetArgument) { - currentGetter = sprop->getter; + if (SPROP_GETTER(sprop, pobj) == js_GetArgument) { + currentGetter = js_GetArgument; + currentSetter = js_SetArgument; #ifdef CHECK_ARGUMENT_HIDING js_ReportCompileErrorNumber(cx, ts, JSREPORT_WARNING, JSMSG_VAR_HIDES_ARG, @@ -1604,11 +1576,11 @@ Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) if (fun) { /* Not an argument, must be a redeclared local var. */ if (clasp == &js_FunctionClass) { - JS_ASSERT(sprop->getter == js_GetLocalVariable); + JS_ASSERT(SPROP_GETTER(sprop,pobj) == js_GetLocalVariable); JS_ASSERT(JSVAL_IS_INT(sprop->id) && JSVAL_TO_INT(sprop->id) < fun->nvars); } else if (clasp == &js_CallClass) { - if (sprop->getter == js_GetCallVariable) { + if (SPROP_GETTER(sprop, pobj) == js_GetCallVariable) { /* * Referencing a variable introduced by a var * statement in the enclosing function. Check @@ -1622,16 +1594,16 @@ Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) * don't use the special getters and setters * since we can't allocate a slot in the frame. */ - currentGetter = sprop->getter; - currentSetter = sprop->setter; + currentGetter = SPROP_GETTER(sprop, pobj); + currentSetter = SPROP_SETTER(sprop, pobj); } } } else { /* Global var: (re-)set id a la js_DefineProperty. */ sprop->id = ATOM_KEY(atom); } - sprop->getter = currentGetter; - sprop->setter = currentSetter; + SPROP_GETTER(sprop, pobj) = currentGetter; + SPROP_SETTER(sprop, pobj) = currentSetter; sprop->attrs |= JSPROP_ENUMERATE | JSPROP_PERMANENT; sprop->attrs &= ~JSPROP_READONLY; } @@ -1684,8 +1656,9 @@ Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) } } - if (ok && fun && (clasp == &js_FunctionClass || - clasp == &js_CallClass) && + if (ok && + fun && + (clasp == &js_FunctionClass || clasp == &js_CallClass) && !InWithStatement(tc)) { /* Depending on the value of the getter, change the @@ -1764,11 +1737,13 @@ LookupArgOrVar(JSContext *cx, JSAtom *atom, JSTreeContext *tc, return JS_FALSE; *slotp = -1; if (sprop) { - if (sprop->getter == js_GetArgument) { + JSPropertyOp getter = SPROP_GETTER(sprop, pobj); + + if (getter == js_GetArgument) { *opp = JSOP_GETARG; *slotp = JSVAL_TO_INT(sprop->id); - } else if (sprop->getter == js_GetLocalVariable || - sprop->getter == js_GetCallVariable) + } else if (getter == js_GetLocalVariable || + getter == js_GetCallVariable) { *opp = JSOP_GETVAR; *slotp = JSVAL_TO_INT(sprop->id); @@ -1966,7 +1941,7 @@ RelExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) (js_MatchToken(cx, ts, TOK_RELOP) #if JS_HAS_IN_OPERATOR /* - * Only recognize the 'in' token as an operator if we're not + * Recognize the 'in' token as an operator only if we're not * currently in the init expr of a for loop. */ || (inForInitFlag == 0 && js_MatchToken(cx, ts, TOK_IN)) diff --git a/mozilla/js/src/jsscope.c b/mozilla/js/src/jsscope.c index 112c4335602..1e8ac190d2c 100644 --- a/mozilla/js/src/jsscope.c +++ b/mozilla/js/src/jsscope.c @@ -367,7 +367,7 @@ js_GetMutableScope(JSContext *cx, JSObject *obj) { JSScope *scope, *newscope; - scope = (JSScope *) obj->map; + scope = OBJ_SCOPE(obj); JS_ASSERT(JS_IS_SCOPE_LOCKED(scope)); if (scope->object == obj) return scope; diff --git a/mozilla/js/src/jsscope.h b/mozilla/js/src/jsscope.h index fcb640178a2..9c84c56796b 100644 --- a/mozilla/js/src/jsscope.h +++ b/mozilla/js/src/jsscope.h @@ -43,6 +43,7 @@ #include "jsprvtd.h" #include "jspubtd.h" +#ifndef JS_DOUBLE_HASHING struct JSScopeOps { JSSymbol * (*lookup)(JSContext *cx, JSScope *scope, jsid id, JSHashNumber hash); @@ -51,16 +52,24 @@ struct JSScopeOps { JSBool (*remove)(JSContext *cx, JSScope *scope, jsid id); void (*clear)(JSContext *cx, JSScope *scope); }; +#endif struct JSScope { JSObjectMap map; /* base class state */ JSObject *object; /* object that owns this scope */ JSScopeProperty *props; /* property list in definition order */ JSScopeProperty **proptail; /* pointer to pointer to last prop */ +#ifdef JS_DOUBLE_HASHING + uint32 tableLength; + JSScopeProperty *table; + uint32 gsTableLength; /* number of entries in gsTable */ + JSPropertyOp gsTable[1]; /* actually, gsTableLength ops */ +#else JSScopeOps *ops; /* virtual operations */ void *data; /* private data specific to ops */ +#endif #ifdef JS_THREADSAFE - JSThinLock lock; /* binary semaphore protecting scope */ + JSThinLock lock; /* binary semaphore protecting scope */ int32 count; /* entry count for reentrancy */ #ifdef DEBUG const char *file[4]; /* file where lock was (re-)taken */ @@ -69,6 +78,27 @@ struct JSScope { #endif }; +#define OBJ_SCOPE(obj) ((JSScope *)(obj)->map) +#define SPROP_GETTER(sprop,obj) SPROP_GETTER_SCOPE(sprop, OBJ_SCOPE(obj)) +#define SPROP_SETTER(sprop,obj) SPROP_SETTER_SCOPE(sprop, OBJ_SCOPE(obj)) + +#ifdef JS_DOUBLE_HASHING + +struct JSScopeProperty { + jsid id; + uint32 slot; /* index in obj->slots vector */ + uint8 attrs; /* attributes, see jsapi.h JSPROP_ */ + uint8 getterIndex; /* getter and setter method indexes */ + uint8 setterIndex; /* in JSScope.gsTable[] */ + uint8 reserved; + JSScopeProperty *next; /* singly-linked list linkage */ +}; + +#define SPROP_GETTER_SCOPE(sprop,scope) ((scope)->gsTable[(sprop)->getterIndex]) +#define SPROP_SETTER_SCOPE(sprop,scope) ((scope)->gsTable[(sprop)->setterIndex]) + +#else /* !JS_DOUBLE_HASHING */ + struct JSSymbol { JSHashEntry entry; /* base class state */ JSScope *scope; /* pointer to owning scope */ @@ -92,21 +122,28 @@ struct JSScopeProperty { JSScopeProperty **prevp; }; +#define SPROP_GETTER_SCOPE(sprop,scope) ((sprop)->getter) +#define SPROP_SETTER_SCOPE(sprop,scope) ((sprop)->setter) + +#endif /* !JS_DOUBLE_HASHING */ + /* * These macros are designed to decouple getter and setter from sprop, by * passing obj2 (in whose scope sprop lives, and in whose scope getter and - * setter might be stored apart from sprop -- say in scope->opTable[i] for + * setter might be stored apart from sprop -- say in scope->gsTable[i] for * a compressed getter or setter index i that is stored in sprop). */ #define SPROP_GET(cx,sprop,obj,obj2,vp) \ (((sprop)->attrs & JSPROP_GETTER) \ - ? js_InternalCall(cx, obj, OBJECT_TO_JSVAL(sprop->getter), 0, 0, vp) \ - : (sprop)->getter(cx, OBJ_THIS_OBJECT(cx,obj), sprop->id, vp)) + ? js_InternalCall(cx, obj, OBJECT_TO_JSVAL(SPROP_GETTER(sprop,obj2)), \ + 0, 0, vp) \ + : SPROP_GETTER(sprop,obj2)(cx, OBJ_THIS_OBJECT(cx,obj), sprop->id, vp)) #define SPROP_SET(cx,sprop,obj,obj2,vp) \ (((sprop)->attrs & JSPROP_SETTER) \ - ? js_InternalCall(cx, obj, OBJECT_TO_JSVAL(sprop->setter), 1, vp, vp) \ - : (sprop)->setter(cx, OBJ_THIS_OBJECT(cx,obj), sprop->id, vp)) + ? js_InternalCall(cx, obj, OBJECT_TO_JSVAL(SPROP_SETTER(sprop,obj2)), \ + 1, vp, vp) \ + : SPROP_SETTER(sprop,obj2)(cx, OBJ_THIS_OBJECT(cx,obj), sprop->id, vp)) extern JSScope * js_GetMutableScope(JSContext *cx, JSObject *obj);