bool WatchpointMap::triggerWatchpoint(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp) { Map::Ptr p = map.lookup(WatchKey(obj, id)); if (!p || p->value().held) return true; AutoEntryHolder holder(cx, map, p); /* Copy the entry, since GC would invalidate p. */ JSWatchPointHandler handler = p->value().handler; RootedObject closure(cx, p->value().closure); /* Determine the property's old value. */ Value old; old.setUndefined(); if (obj->isNative()) { NativeObject* nobj = &obj->as<NativeObject>(); if (Shape* shape = nobj->lookup(cx, id)) { if (shape->hasSlot()) old = nobj->getSlot(shape->slot()); } } // Read barrier to prevent an incorrectly gray closure from escaping the // watchpoint. See the comment before UnmarkGrayChildren in gc/Marking.cpp JS::ExposeObjectToActiveJS(closure); /* Call the handler. */ return handler(cx, obj, id, old, vp.address(), closure); }
JS::ForceLexicalInitialization(JSContext *cx, HandleObject obj) { AssertHeapIsIdle(); CHECK_REQUEST(cx); assertSameCompartment(cx, obj); bool initializedAny = false; NativeObject* nobj = &obj->as<NativeObject>(); for (Shape::Range<NoGC> r(nobj->lastProperty()); !r.empty(); r.popFront()) { Shape* s = &r.front(); Value v = nobj->getSlot(s->slot()); if (s->isDataProperty() && v.isMagic() && v.whyMagic() == JS_UNINITIALIZED_LEXICAL) { nobj->setSlot(s->slot(), UndefinedValue()); initializedAny = true; } } return initializedAny; }