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

📄 jsscope.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 5 页
字号:
                        }                        spvec = spp2;                        memmove(spvec + i, spvec, SCOPE_TABLE_NBYTES(splen));                        splen += i;                    }                    spvec[--i] = sprop;                } while ((sprop = sprop->parent) != NULL);                JS_ASSERT(i == 0);                /*                 * Now loop forward through spvec, forking the property tree                 * whenever we see a "parent gap" due to deletions from scope.                 * NB: sprop is null on first entry to the loop body.                 */                do {                    if (spvec[i]->parent == sprop) {                        sprop = spvec[i];                    } else {                        sprop = GetPropertyTreeChild(cx, sprop, spvec[i]);                        if (!sprop) {                            JS_free(cx, spvec);                            goto fail_overwrite;                        }                        spp2 = js_SearchScope(scope, sprop->id, JS_FALSE);                        JS_ASSERT(SPROP_FETCH(spp2) == spvec[i]);                        SPROP_STORE_PRESERVING_COLLISION(spp2, sprop);                    }                } while (++i < splen);                JS_free(cx, spvec);                /*                 * Now sprop points to the last property in scope, where the                 * ancestor line from sprop to the root is dense w.r.t. scope:                 * it contains no nodes not mapped by scope->table, apart from                 * any stinking ECMA-mandated duplicate formal parameters.                 */                scope->lastProp = sprop;                CHECK_ANCESTOR_LINE(scope, JS_FALSE);                JS_RUNTIME_METER(cx->runtime, middleDeleteFixups);            }            SCOPE_CLR_MIDDLE_DELETE(scope);        }        /*         * Aliases share another property's slot, passed in the |slot| param.         * Shared properties have no slot.  Unshared properties that do not         * alias another property's slot get one here, but may lose it due to         * a JS_ClearScope call.         */        if (!(flags & SPROP_IS_ALIAS)) {            if (attrs & JSPROP_SHARED) {                slot = SPROP_INVALID_SLOT;            } else {                /*                 * We may have set slot from a nearly-matching sprop, above.                 * If so, we're overwriting that nearly-matching sprop, so we                 * can reuse its slot -- we don't need to allocate a new one.                 * Callers should therefore pass SPROP_INVALID_SLOT for all                 * non-alias, unshared property adds.                 */                if (slot != SPROP_INVALID_SLOT)                    JS_ASSERT(overwriting);                else if (!js_AllocSlot(cx, scope->object, &slot))                    goto fail_overwrite;            }        }        /*         * Check for a watchpoint on a deleted property; if one exists, change         * setter to js_watch_set.         * XXXbe this could get expensive with lots of watchpoints...         */        if (!JS_CLIST_IS_EMPTY(&cx->runtime->watchPointList) &&            js_FindWatchPoint(cx->runtime, scope, id)) {            JS_PUSH_TEMP_ROOT_SPROP(cx, overwriting, &tvr);            setter = js_WrapWatchedSetter(cx, id, attrs, setter);            JS_POP_TEMP_ROOT(cx, &tvr);            if (!setter)                goto fail_overwrite;        }        /* Find or create a property tree node labeled by our arguments. */        child.id = id;        child.getter = getter;        child.setter = setter;        child.slot = slot;        child.attrs = attrs;        child.flags = flags;        child.shortid = shortid;        sprop = GetPropertyTreeChild(cx, scope->lastProp, &child);        if (!sprop)            goto fail_overwrite;        /* Store the tree node pointer in the table entry for id. */        if (scope->table)            SPROP_STORE_PRESERVING_COLLISION(spp, sprop);        scope->entryCount++;        scope->lastProp = sprop;        CHECK_ANCESTOR_LINE(scope, JS_FALSE);        if (!overwriting) {            JS_RUNTIME_METER(cx->runtime, liveScopeProps);            JS_RUNTIME_METER(cx->runtime, totalScopeProps);        }        /*         * If we reach the hashing threshold, try to allocate scope->table.         * If we can't (a rare event, preceded by swapping to death on most         * modern OSes), stick with linear search rather than whining about         * this little set-back.  Therefore we must test !scope->table and         * scope->entryCount >= SCOPE_HASH_THRESHOLD, not merely whether the         * entry count just reached the threshold.         */        if (!scope->table && scope->entryCount >= SCOPE_HASH_THRESHOLD)            (void) CreateScopeTable(cx, scope, JS_FALSE);    }    METER(adds);    return sprop;fail_overwrite:    if (overwriting) {        /*         * We may or may not have forked overwriting out of scope's ancestor         * line, so we must check (the alternative is to set a flag above, but         * that hurts the common, non-error case).  If we did fork overwriting         * out, we'll add it back at scope->lastProp.  This means enumeration         * order can change due to a failure to overwrite an id.         * XXXbe very minor incompatibility         */        for (sprop = SCOPE_LAST_PROP(scope); ; sprop = sprop->parent) {            if (!sprop) {                sprop = SCOPE_LAST_PROP(scope);                if (overwriting->parent == sprop) {                    scope->lastProp = overwriting;                } else {                    sprop = GetPropertyTreeChild(cx, sprop, overwriting);                    if (sprop) {                        JS_ASSERT(sprop != overwriting);                        scope->lastProp = sprop;                    }                    overwriting = sprop;                }                break;            }            if (sprop == overwriting)                break;        }        if (overwriting) {            if (scope->table)                SPROP_STORE_PRESERVING_COLLISION(spp, overwriting);            scope->entryCount++;        }        CHECK_ANCESTOR_LINE(scope, JS_TRUE);    }    METER(addFailures);    return NULL;}JSScopeProperty *js_ChangeScopePropertyAttrs(JSContext *cx, JSScope *scope,                            JSScopeProperty *sprop, uintN attrs, uintN mask,                            JSPropertyOp getter, JSPropertyOp setter){    JSScopeProperty child, *newsprop, **spp;    CHECK_ANCESTOR_LINE(scope, JS_TRUE);    /* Allow only shared (slot-less) => unshared (slot-full) transition. */    attrs |= sprop->attrs & mask;    JS_ASSERT(!((attrs ^ sprop->attrs) & JSPROP_SHARED) ||              !(attrs & JSPROP_SHARED));    if (getter == JS_PropertyStub)        getter = NULL;    if (setter == JS_PropertyStub)        setter = NULL;    if (sprop->attrs == attrs &&        sprop->getter == getter &&        sprop->setter == setter) {        return sprop;    }    child.id = sprop->id;    child.getter = getter;    child.setter = setter;    child.slot = sprop->slot;    child.attrs = attrs;    child.flags = sprop->flags;    child.shortid = sprop->shortid;    if (SCOPE_LAST_PROP(scope) == sprop) {        /*         * Optimize the case where the last property added to scope is changed         * to have a different attrs, getter, or setter.  In the last property         * case, we need not fork the property tree.  But since we do not call         * js_AddScopeProperty, we may need to allocate a new slot directly.         */        if ((sprop->attrs & JSPROP_SHARED) && !(attrs & JSPROP_SHARED)) {            JS_ASSERT(child.slot == SPROP_INVALID_SLOT);            if (!js_AllocSlot(cx, scope->object, &child.slot))                return NULL;        }        newsprop = GetPropertyTreeChild(cx, sprop->parent, &child);        if (newsprop) {            spp = js_SearchScope(scope, sprop->id, JS_FALSE);            JS_ASSERT(SPROP_FETCH(spp) == sprop);            if (scope->table)                SPROP_STORE_PRESERVING_COLLISION(spp, newsprop);            scope->lastProp = newsprop;            CHECK_ANCESTOR_LINE(scope, JS_TRUE);        }    } else {        /*         * Let js_AddScopeProperty handle this |overwriting| case, including         * the conservation of sprop->slot (if it's valid).  We must not call         * js_RemoveScopeProperty here, it will free a valid sprop->slot and         * js_AddScopeProperty won't re-allocate it.         */        newsprop = js_AddScopeProperty(cx, scope, child.id,                                       child.getter, child.setter, child.slot,                                       child.attrs, child.flags, child.shortid);    }#ifdef DUMP_SCOPE_STATS    if (!newsprop)        METER(changeFailures);#endif    return newsprop;}JSBooljs_RemoveScopeProperty(JSContext *cx, JSScope *scope, jsid id){    JSScopeProperty **spp, *stored, *sprop;    uint32 size;    JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, scope));    CHECK_ANCESTOR_LINE(scope, JS_TRUE);    if (SCOPE_IS_SEALED(scope)) {        ReportReadOnlyScope(cx, scope);        return JS_FALSE;    }    METER(removes);    spp = js_SearchScope(scope, id, JS_FALSE);    stored = *spp;    sprop = SPROP_CLEAR_COLLISION(stored);    if (!sprop) {        METER(uselessRemoves);        return JS_TRUE;    }    /* Convert from a list to a hash so we can handle "middle deletes". */    if (!scope->table && sprop != scope->lastProp) {        if (!CreateScopeTable(cx, scope, JS_TRUE))            return JS_FALSE;        spp = js_SearchScope(scope, id, JS_FALSE);        stored = *spp;        sprop = SPROP_CLEAR_COLLISION(stored);    }    /* First, if sprop is unshared and not cleared, free its slot number. */    if (SPROP_HAS_VALID_SLOT(sprop, scope)) {        js_FreeSlot(cx, scope->object, sprop->slot);        JS_ATOMIC_INCREMENT(&cx->runtime->propertyRemovals);    }    /* Next, remove id by setting its entry to a removed or free sentinel. */    if (SPROP_HAD_COLLISION(stored)) {        JS_ASSERT(scope->table);        *spp = SPROP_REMOVED;        scope->removedCount++;    } else {        METER(removeFrees);        if (scope->table)            *spp = NULL;    }    scope->entryCount--;    JS_RUNTIME_UNMETER(cx->runtime, liveScopeProps);    /* Update scope->lastProp directly, or set its deferred update flag. */    if (sprop == SCOPE_LAST_PROP(scope)) {        do {            SCOPE_REMOVE_LAST_PROP(scope);            if (!SCOPE_HAD_MIDDLE_DELETE(scope))                break;            sprop = SCOPE_LAST_PROP(scope);        } while (sprop && !SCOPE_HAS_PROPERTY(scope, sprop));    } else if (!SCOPE_HAD_MIDDLE_DELETE(scope)) {        SCOPE_SET_MIDDLE_DELETE(scope);    }    CHECK_ANCESTOR_LINE(scope, JS_TRUE);    /* Last, consider shrinking scope's table if its load factor is <= .25. */    size = SCOPE_CAPACITY(scope);    if (size > MIN_SCOPE_SIZE && scope->entryCount <= size >> 2) {        METER(shrinks);        (void) ChangeScope(cx, scope, -1);    }    return JS_TRUE;}voidjs_ClearScope(JSContext *cx, JSScope *scope){    CHECK_ANCESTOR_LINE(scope, JS_TRUE);#ifdef DEBUG    JS_LOCK_RUNTIME_VOID(cx->runtime,                         cx->runtime->liveScopeProps -= scope->entryCount);#endif    if (scope->table)        free(scope->table);    SCOPE_CLR_MIDDLE_DELETE(scope);    InitMinimalScope(scope);    JS_ATOMIC_INCREMENT(&cx->runtime->propertyRemovals);}voidjs_MarkId(JSContext *cx, jsid id){    if (JSID_IS_ATOM(id))        GC_MARK_ATOM(cx, JSID_TO_ATOM(id));    else if (JSID_IS_OBJECT(id))        GC_MARK(cx, JSID_TO_OBJECT(id), "id");    else        JS_ASSERT(JSID_IS_INT(id));}#if defined GC_MARK_DEBUG || defined DUMP_SCOPE_STATS# include "jsprf.h"#endifvoidjs_MarkScopeProperty(JSContext *cx, JSScopeProperty *sprop){    sprop->flags |= SPROP_MARK;    MARK_ID(cx, sprop->id);#if JS_HAS_GETTER_SETTER    if (sprop->attrs & (JSPROP_GETTER | JSPROP_SETTER)) {#ifdef GC_MARK_DEBUG        char buf[64];        char buf2[11];        const char *id;        if (JSID_IS_ATOM(sprop->id)) {            JSAtom *atom = JSID_TO_ATOM(sprop->id);            id = (atom && ATOM_IS_STRING(atom))

⌨️ 快捷键说明

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