static KidsHash * HashChildren(Shape *kid1, Shape *kid2) { void *mem = js_malloc(sizeof(KidsHash)); if (!mem) return NULL; KidsHash *hash = new (mem) KidsHash(); if (!hash->init(2)) { js_free(hash); return NULL; } KidsHash::AddPtr addPtr = hash->lookupForAdd(kid1); JS_ALWAYS_TRUE(hash->add(addPtr, kid1)); addPtr = hash->lookupForAdd(kid2); JS_ASSERT(!addPtr.found()); JS_ALWAYS_TRUE(hash->add(addPtr, kid2)); return hash; }
bool PropertyTree::insertChild(JSContext *cx, Shape *parent, Shape *child) { JS_ASSERT(!parent->inDictionary()); JS_ASSERT(!child->parent); JS_ASSERT(!child->inDictionary()); JS_ASSERT(!JSID_IS_VOID(parent->id)); JS_ASSERT(!JSID_IS_VOID(child->id)); JS_ASSERT(cx->compartment == compartment); JS_ASSERT(child->compartment == parent->compartment); KidsPointer *kidp = &parent->kids; if (kidp->isNull()) { child->setParent(parent); kidp->setShape(child); return true; } if (kidp->isShape()) { Shape *shape = kidp->toShape(); JS_ASSERT(shape != child); JS_ASSERT(!shape->matches(child)); KidsHash *hash = HashChildren(shape, child); if (!hash) { JS_ReportOutOfMemory(cx); return false; } kidp->setHash(hash); child->setParent(parent); return true; } KidsHash *hash = kidp->toHash(); KidsHash::AddPtr addPtr = hash->lookupForAdd(child); JS_ASSERT(!addPtr.found()); if (!hash->add(addPtr, child)) { JS_ReportOutOfMemory(cx); return false; } child->setParent(parent); return true; }