js_free_symbol(void *priv, PRHashEntry *he, uintN flag) { JSContext *cx; JSSymbol *sym, **sp; JSProperty *prop; cx = priv; PR_ASSERT(JS_IS_LOCKED(cx)); sym = (JSSymbol *)he; prop = sym->entry.value; if (prop) { sym->entry.value = NULL; prop = js_DropProperty(cx, prop); if (prop) { for (sp = &prop->symbols; *sp; sp = &(*sp)->next) { if (*sp == sym) { *sp = sym->next; if (!*sp) break; } } sym->next = NULL; } } if (flag == HT_FREE_ENTRY) { if (!JSVAL_IS_INT(sym_id(sym))) JS_LOCK_VOID(cx, js_DropAtom(cx, sym_atom(sym))); JS_free(cx, he); } }
static JSBool FindConstructor(JSContext *cx, JSClass *clasp, jsval *vp) { JSAtom *atom; JSObject *obj, *tmp; JSBool ok; PR_ASSERT(JS_IS_LOCKED(cx)); /* XXX pre-atomize in JS_InitClass! */ atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0); if (!atom) return JS_FALSE; if (cx->fp && (tmp = cx->fp->scopeChain)) { /* Find the topmost object in the scope chain. */ do { obj = tmp; tmp = OBJ_GET_PARENT(obj); } while (tmp); } else { obj = cx->globalObject; if (!obj) { *vp = JSVAL_VOID; return JS_TRUE; } } ok = (js_GetProperty(cx, obj, (jsval)atom, vp) != NULL); js_DropAtom(cx, atom); return JS_TRUE; }
js_FreeAtomMap(JSContext *cx, JSAtomMap *map) { uintN i; if (map->vector) { for (i = 0; i < map->length; i++) js_DropAtom(cx, map->vector[i]); free(map->vector); map->vector = NULL; } map->length = 0; }
void js_DropUnmappedAtoms(JSContext *cx, JSAtomList *al) { JSAtom *atom, *next; for (atom = al->list; atom; atom = next) { atom->flags &= ~ATOM_INDEXED; next = ATOM_NEXT(atom); ATOM_SET_NEXT(atom, NULL); js_DropAtom(cx, atom); } al->list = NULL; al->count = 0; }
static JSBool obj_watch(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { JSFunction *fun; jsval userid, symid, propid, value; JSAtom *atom; JSRuntime *rt; JSBool ok; JSProperty *prop; JSPropertyOp getter, setter; JSClass *clasp; fun = JS_ValueToFunction(cx, argv[1]); if (!fun) return JS_FALSE; argv[1] = OBJECT_TO_JSVAL(fun->object); /* * Lock the world while we look in obj. Be sure to return via goto out * on error, so we unlock. */ rt = cx->runtime; JS_LOCK_RUNTIME(rt); /* Compute the unique int/atom symbol id needed by js_LookupProperty. */ userid = argv[0]; if (JSVAL_IS_INT(userid)) { symid = userid; atom = NULL; } else { atom = js_ValueToStringAtom(cx, userid); if (!atom) { ok = JS_FALSE; goto out; } symid = (jsval)atom; } ok = js_LookupProperty(cx, obj, symid, &obj, &prop); if (atom) js_DropAtom(cx, atom); if (!ok) goto out; /* Set propid from the property, in case it has a tinyid. */ if (prop) { propid = prop->id; getter = prop->getter; setter = prop->setter; value = prop->object->slots[prop->slot]; } else { propid = userid; clasp = obj->map->clasp; getter = clasp->getProperty; setter = clasp->setProperty; value = JSVAL_VOID; } /* * Security policy is implemented in getters and setters, so we have to * call get and set here to let the JS API client check for a watchpoint * that crosses a trust boundary. * XXX assumes get and set are idempotent, should use a clasp->watch hook */ ok = getter(cx, obj, propid, &value) && setter(cx, obj, propid, &value); if (!ok) goto out; /* Finally, call into jsdbgapi.c to set the watchpoint on userid. */ ok = JS_SetWatchPoint(cx, obj, userid, obj_watch_handler, fun->object); out: JS_UNLOCK_RUNTIME(rt); return ok; }