⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jsscope.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* Copy only live entries, leaving removed and free ones behind. */    for (oldspp = oldtable; oldsize != 0; oldspp++) {        sprop = SPROP_FETCH(oldspp);        if (sprop) {            spp = js_SearchScope(scope, sprop->id, JS_TRUE);            JS_ASSERT(SPROP_IS_FREE(*spp));            *spp = sprop;        }        oldsize--;    }    /* Finally, free the old table storage. */    JS_free(cx, oldtable);    return JS_TRUE;}/* * Take care to exclude the mark and duplicate bits, in case we're called from * the GC, or we are searching for a property that has not yet been flagged as * a duplicate when making a duplicate formal parameter. */#define SPROP_FLAGS_NOT_MATCHED (SPROP_MARK | SPROP_IS_DUPLICATE)JS_STATIC_DLL_CALLBACK(JSDHashNumber)js_HashScopeProperty(JSDHashTable *table, const void *key){    const JSScopeProperty *sprop = (const JSScopeProperty *)key;    JSDHashNumber hash;    JSPropertyOp gsop;    /* Accumulate from least to most random so the low bits are most random. */    hash = 0;    gsop = sprop->getter;    if (gsop)        hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ (jsword)gsop;    gsop = sprop->setter;    if (gsop)        hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ (jsword)gsop;    hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4)           ^ (sprop->flags & ~SPROP_FLAGS_NOT_MATCHED);    hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->attrs;    hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->shortid;    hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->slot;    hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->id;    return hash;}#define SPROP_MATCH(sprop, child)                                             \    SPROP_MATCH_PARAMS(sprop, (child)->id, (child)->getter, (child)->setter,  \                       (child)->slot, (child)->attrs, (child)->flags,         \                       (child)->shortid)#define SPROP_MATCH_PARAMS(sprop, aid, agetter, asetter, aslot, aattrs,       \                           aflags, ashortid)                                  \    ((sprop)->id == (aid) &&                                                  \     SPROP_MATCH_PARAMS_AFTER_ID(sprop, agetter, asetter, aslot, aattrs,      \                                 aflags, ashortid))#define SPROP_MATCH_PARAMS_AFTER_ID(sprop, agetter, asetter, aslot, aattrs,   \                                    aflags, ashortid)                         \    ((sprop)->getter == (agetter) &&                                          \     (sprop)->setter == (asetter) &&                                          \     (sprop)->slot == (aslot) &&                                              \     (sprop)->attrs == (aattrs) &&                                            \     (((sprop)->flags ^ (aflags)) & ~SPROP_FLAGS_NOT_MATCHED) == 0 &&         \     (sprop)->shortid == (ashortid))JS_STATIC_DLL_CALLBACK(JSBool)js_MatchScopeProperty(JSDHashTable *table,                      const JSDHashEntryHdr *hdr,                      const void *key){    const JSPropertyTreeEntry *entry = (const JSPropertyTreeEntry *)hdr;    const JSScopeProperty *sprop = entry->child;    const JSScopeProperty *kprop = (const JSScopeProperty *)key;    return SPROP_MATCH(sprop, kprop);}static const JSDHashTableOps PropertyTreeHashOps = {    JS_DHashAllocTable,    JS_DHashFreeTable,    JS_DHashGetKeyStub,    js_HashScopeProperty,    js_MatchScopeProperty,    JS_DHashMoveEntryStub,    JS_DHashClearEntryStub,    JS_DHashFinalizeStub,    NULL};/* * A property tree node on rt->propertyFreeList overlays the following prefix * struct on JSScopeProperty. */typedef struct FreeNode {    jsid                id;    JSScopeProperty     *next;    JSScopeProperty     **prevp;} FreeNode;#define FREENODE(sprop) ((FreeNode *) (sprop))#define FREENODE_INSERT(list, sprop)                                          \    JS_BEGIN_MACRO                                                            \        FREENODE(sprop)->next = (list);                                       \        FREENODE(sprop)->prevp = &(list);                                     \        if (list)                                                             \            FREENODE(list)->prevp = &FREENODE(sprop)->next;                   \        (list) = (sprop);                                                     \    JS_END_MACRO#define FREENODE_REMOVE(sprop)                                                \    JS_BEGIN_MACRO                                                            \        *FREENODE(sprop)->prevp = FREENODE(sprop)->next;                      \        if (FREENODE(sprop)->next)                                            \            FREENODE(FREENODE(sprop)->next)->prevp = FREENODE(sprop)->prevp;  \    JS_END_MACRO/* NB: Called with the runtime lock held. */static JSScopeProperty *NewScopeProperty(JSRuntime *rt){    JSScopeProperty *sprop;    sprop = rt->propertyFreeList;    if (sprop) {        FREENODE_REMOVE(sprop);    } else {        JS_ARENA_ALLOCATE_CAST(sprop, JSScopeProperty *,                               &rt->propertyArenaPool,                               sizeof(JSScopeProperty));        if (!sprop)            return NULL;    }    JS_RUNTIME_METER(rt, livePropTreeNodes);    JS_RUNTIME_METER(rt, totalPropTreeNodes);    return sprop;}#define CHUNKY_KIDS_TAG         ((jsuword)1)#define KIDS_IS_CHUNKY(kids)    ((jsuword)(kids) & CHUNKY_KIDS_TAG)#define KIDS_TO_CHUNK(kids)     ((PropTreeKidsChunk *)                        \                                 ((jsuword)(kids) & ~CHUNKY_KIDS_TAG))#define CHUNK_TO_KIDS(chunk)    ((JSScopeProperty *)                          \                                 ((jsuword)(chunk) | CHUNKY_KIDS_TAG))#define MAX_KIDS_PER_CHUNK      10typedef struct PropTreeKidsChunk PropTreeKidsChunk;struct PropTreeKidsChunk {    JSScopeProperty     *kids[MAX_KIDS_PER_CHUNK];    PropTreeKidsChunk   *next;};static PropTreeKidsChunk *NewPropTreeKidsChunk(JSRuntime *rt){    PropTreeKidsChunk *chunk;    chunk = calloc(1, sizeof *chunk);    if (!chunk)        return NULL;    JS_ASSERT(((jsuword)chunk & CHUNKY_KIDS_TAG) == 0);    JS_RUNTIME_METER(rt, propTreeKidsChunks);    return chunk;}static voidDestroyPropTreeKidsChunk(JSRuntime *rt, PropTreeKidsChunk *chunk){    JS_RUNTIME_UNMETER(rt, propTreeKidsChunks);    free(chunk);}/* NB: Called with the runtime lock held. */static JSBoolInsertPropertyTreeChild(JSRuntime *rt, JSScopeProperty *parent,                        JSScopeProperty *child, PropTreeKidsChunk *sweptChunk){    JSPropertyTreeEntry *entry;    JSScopeProperty **childp, *kids, *sprop;    PropTreeKidsChunk *chunk, **chunkp;    uintN i;    JS_ASSERT(!parent || child->parent != parent);    if (!parent) {        entry = (JSPropertyTreeEntry *)            JS_DHashTableOperate(&rt->propertyTreeHash, child, JS_DHASH_ADD);        if (!entry)            return JS_FALSE;        childp = &entry->child;        sprop = *childp;        if (!sprop) {            *childp = child;        } else {            /*             * A "Duplicate child" case.             *             * We can't do away with child, as at least one live scope entry             * still points at it.  What's more, that scope's lastProp chains             * through an ancestor line to reach child, and js_Enumerate and             * others count on this linkage.  We must leave child out of the             * hash table, and not require it to be there when we eventually             * GC it (see RemovePropertyTreeChild, below).             *             * It is necessary to leave the duplicate child out of the hash             * table to preserve entry uniqueness.  It is safe to leave the             * child out of the hash table (unlike the duplicate child cases             * below), because the child's parent link will be null, which             * can't dangle.             */            JS_ASSERT(sprop != child && SPROP_MATCH(sprop, child));            JS_RUNTIME_METER(rt, duplicatePropTreeNodes);        }    } else {        childp = &parent->kids;        kids = *childp;        if (kids) {            if (KIDS_IS_CHUNKY(kids)) {                chunk = KIDS_TO_CHUNK(kids);                do {                    for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) {                        childp = &chunk->kids[i];                        sprop = *childp;                        if (!sprop)                            goto insert;                        JS_ASSERT(sprop != child);                        if (SPROP_MATCH(sprop, child)) {                            /*                             * Duplicate child, see comment above.  In this                             * case, we must let the duplicate be inserted at                             * this level in the tree, so we keep iterating,                             * looking for an empty slot in which to insert.                             */                            JS_ASSERT(sprop != child);                            JS_RUNTIME_METER(rt, duplicatePropTreeNodes);                        }                    }                    chunkp = &chunk->next;                } while ((chunk = *chunkp) != NULL);                if (sweptChunk) {                    chunk = sweptChunk;                } else {                    chunk = NewPropTreeKidsChunk(rt);                    if (!chunk)                        return JS_FALSE;                }                *chunkp = chunk;                childp = &chunk->kids[0];            } else {                sprop = kids;                JS_ASSERT(sprop != child);                if (SPROP_MATCH(sprop, child)) {                    /*                     * Duplicate child, see comment above.  Once again, we                     * must let duplicates created by deletion pile up in a                     * kids-chunk-list, in order to find them when sweeping                     * and thereby avoid dangling parent pointers.                     */                    JS_RUNTIME_METER(rt, duplicatePropTreeNodes);                }                if (sweptChunk) {                    chunk = sweptChunk;                } else {                    chunk = NewPropTreeKidsChunk(rt);                    if (!chunk)                        return JS_FALSE;                }                parent->kids = CHUNK_TO_KIDS(chunk);                chunk->kids[0] = sprop;                childp = &chunk->kids[1];            }        }    insert:        *childp = child;    }    child->parent = parent;    return JS_TRUE;}/* NB: Called with the runtime lock held. */static PropTreeKidsChunk *RemovePropertyTreeChild(JSRuntime *rt, JSScopeProperty *child){    JSPropertyTreeEntry *entry;    JSScopeProperty *parent, *kids, *kid;    PropTreeKidsChunk *list, *chunk, **chunkp, *lastChunk;    uintN i, j;    parent = child->parent;    if (!parent) {        /*         * Don't remove child if it is not in rt->propertyTreeHash, but only         * matches a root child in the table that has compatible members. See         * the "Duplicate child" comments in InsertPropertyTreeChild, above.         */        entry = (JSPropertyTreeEntry *)            JS_DHashTableOperate(&rt->propertyTreeHash, child, JS_DHASH_LOOKUP);        if (entry->child == child)            JS_DHashTableRawRemove(&rt->propertyTreeHash, &entry->hdr);    } else {        kids = parent->kids;        if (KIDS_IS_CHUNKY(kids)) {            list = chunk = KIDS_TO_CHUNK(kids);            chunkp = &list;            do {                for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) {                    if (chunk->kids[i] == child) {                        lastChunk = chunk;                        if (!lastChunk->next) {                            j = i + 1;                        } else {                            j = 0;                            do {                                chunkp = &lastChunk->next;                                lastChunk = *chunkp;                            } while (lastChunk->next);                        }                        for (; j < MAX_KIDS_PER_CHUNK; j++) {                            if (!lastChunk->kids[j])                                break;                        }                        --j;                        if (chunk != lastChunk || j > i)                            chunk->kids[i] = lastChunk->kids[j];                        lastChunk->kids[j] = NULL;                        if (j == 0) {                            *chunkp = NULL;                            if (!list)                                parent->kids = NULL;                            return lastChunk;                        }                        return NULL;                    }                }                chunkp = &chunk->next;            } while ((chunk = *chunkp) != NULL);        } else {            kid = kids;            if (kid == child)                parent->kids = NULL;        }    }    return NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -