JS_XDRRegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *idp) { uintN numclasses, maxclasses; JSClass **registry; numclasses = xdr->numclasses; maxclasses = xdr->maxclasses; if (numclasses == maxclasses) { maxclasses = (maxclasses == 0) ? CLASS_REGISTRY_MIN : maxclasses << 1; registry = (JSClass **) JS_realloc(xdr->cx, xdr->registry, maxclasses * sizeof(JSClass *)); if (!registry) return JS_FALSE; xdr->registry = registry; xdr->maxclasses = maxclasses; } else { JS_ASSERT(numclasses && numclasses < maxclasses); registry = xdr->registry; } registry[numclasses] = clasp; if (xdr->reghash) { JSRegHashEntry *entry = (JSRegHashEntry *) JS_DHashTableOperate(xdr->reghash, clasp->name, JS_DHASH_ADD); if (!entry) { JS_ReportOutOfMemory(xdr->cx); return JS_FALSE; } entry->name = clasp->name; entry->index = numclasses; } *idp = CLASS_INDEX_TO_ID(numclasses); xdr->numclasses = ++numclasses; return JS_TRUE; }
JS_XDRFindClassIdByName(JSXDRState *xdr, const char *name) { uintN i, numclasses; numclasses = xdr->numclasses; if (numclasses >= 10) { JSRegHashEntry *entry; /* Bootstrap reghash from registry on first overpopulated Find. */ if (!xdr->reghash) { xdr->reghash = JS_NewDHashTable(JS_DHashGetStubOps(), NULL, sizeof(JSRegHashEntry), JS_DHASH_DEFAULT_CAPACITY(numclasses)); if (xdr->reghash) { for (i = 0; i < numclasses; i++) { JSClass *clasp = xdr->registry[i]; entry = (JSRegHashEntry *) JS_DHashTableOperate((JSDHashTable *) xdr->reghash, clasp->name, JS_DHASH_ADD); entry->name = clasp->name; entry->index = i; } } } /* If we managed to create reghash, use it for O(1) Find. */ if (xdr->reghash) { entry = (JSRegHashEntry *) JS_DHashTableOperate((JSDHashTable *) xdr->reghash, name, JS_DHASH_LOOKUP); if (JS_DHASH_ENTRY_IS_BUSY(&entry->hdr)) return CLASS_INDEX_TO_ID(entry->index); } } /* Only a few classes, or we couldn't malloc reghash: use linear search. */ for (i = 0; i < numclasses; i++) { if (!strcmp(name, xdr->registry[i]->name)) return CLASS_INDEX_TO_ID(i); } return 0; }