jsscope.h

来自「一个基于alice开发的机器人」· C头文件 代码 · 共 387 行 · 第 1/2 页

H
387
字号
 * scope members as if it were non-null and minimal-length.  Until a property
 * is added that crosses the threshold of 6 or more entries for hashing, or
 * until a "middle delete" occurs, we use linear search from scope->lastProp
 * to find a given id, and save on the space overhead of a hash table.
 */

struct JSScope {
    JSObjectMap     map;                /* base class state */
    JSObject        *object;            /* object that owns this scope */
    uint16          flags;              /* flags, see below */
    int16           hashShift;          /* multiplicative hash shift */
    uint32          entryCount;         /* number of entries in table */
    uint32          removedCount;       /* removed entry sentinels in table */
    JSScopeProperty **table;            /* table of ptrs to shared tree nodes */
    JSScopeProperty *lastProp;          /* pointer to last property added */
#ifdef JS_THREADSAFE
    JSContext       *ownercx;           /* creating context, NULL if shared */
    JSThinLock      lock;               /* binary semaphore protecting scope */
    union {                             /* union lockful and lock-free state: */
        jsrefcount  count;              /* lock entry count for reentrancy */
        JSScope     *link;              /* next link in rt->scopeSharingTodo */
    } u;
#ifdef DEBUG
    const char      *file[4];           /* file where lock was (re-)taken */
    unsigned int    line[4];            /* line where lock was (re-)taken */
#endif
#endif
};

#define OBJ_SCOPE(obj)                  ((JSScope *)(obj)->map)

/* By definition, hashShift = JS_DHASH_BITS - log2(capacity). */
#define SCOPE_CAPACITY(scope)           JS_BIT(JS_DHASH_BITS-(scope)->hashShift)

/* Scope flags and some macros to hide them from other files than jsscope.c. */
#define SCOPE_MIDDLE_DELETE             0x0001
#define SCOPE_SEALED                    0x0002

#define SCOPE_HAD_MIDDLE_DELETE(scope)  ((scope)->flags & SCOPE_MIDDLE_DELETE)
#define SCOPE_SET_MIDDLE_DELETE(scope)  ((scope)->flags |= SCOPE_MIDDLE_DELETE)
#define SCOPE_CLR_MIDDLE_DELETE(scope)  ((scope)->flags &= ~SCOPE_MIDDLE_DELETE)

#define SCOPE_IS_SEALED(scope)          ((scope)->flags & SCOPE_SEALED)
#define SCOPE_SET_SEALED(scope)         ((scope)->flags |= SCOPE_SEALED)
#if 0
/*
 * Don't define this, it can't be done safely because JS_LOCK_OBJ will avoid
 * taking the lock if the object owns its scope and the scope is sealed.
 */
#define SCOPE_CLR_SEALED(scope)         ((scope)->flags &= ~SCOPE_SEALED)
#endif

/*
 * A little information hiding for scope->lastProp, in case it ever becomes
 * a tagged pointer again.
 */
#define SCOPE_LAST_PROP(scope)          ((scope)->lastProp)
#define SCOPE_REMOVE_LAST_PROP(scope)   ((scope)->lastProp =                  \
                                         (scope)->lastProp->parent)

struct JSScopeProperty {
    jsid            id;                 /* int-tagged jsval/untagged JSAtom* */
    JSPropertyOp    getter;             /* getter and setter hooks or objects */
    JSPropertyOp    setter;
    uint32          slot;               /* index in obj->slots vector */
    uint8           attrs;              /* attributes, see jsapi.h JSPROP_* */
    uint8           flags;              /* flags, see below for defines */
    int16           shortid;            /* tinyid, or local arg/var index */
    JSScopeProperty *parent;            /* parent node, reverse for..in order */
    JSScopeProperty *kids;              /* null, single child, or a tagged ptr
                                           to many-kids data structure */
};

/* JSScopeProperty pointer tag bit indicating a collision. */
#define SPROP_COLLISION                 ((jsuword)1)
#define SPROP_REMOVED                   ((JSScopeProperty *) SPROP_COLLISION)

/* Macros to get and set sprop pointer values and collision flags. */
#define SPROP_IS_FREE(sprop)            ((sprop) == NULL)
#define SPROP_IS_REMOVED(sprop)         ((sprop) == SPROP_REMOVED)
#define SPROP_IS_LIVE(sprop)            ((sprop) > SPROP_REMOVED)
#define SPROP_FLAG_COLLISION(spp,sprop) (*(spp) = (JSScopeProperty *)         \
                                         ((jsuword)(sprop) | SPROP_COLLISION))
#define SPROP_HAD_COLLISION(sprop)      ((jsuword)(sprop) & SPROP_COLLISION)
#define SPROP_FETCH(spp)                SPROP_CLEAR_COLLISION(*(spp))

#define SPROP_CLEAR_COLLISION(sprop)                                          \
    ((JSScopeProperty *) ((jsuword)(sprop) & ~SPROP_COLLISION))

#define SPROP_STORE_PRESERVING_COLLISION(spp, sprop)                          \
    (*(spp) = (JSScopeProperty *) ((jsuword)(sprop)                           \
                                   | SPROP_HAD_COLLISION(*(spp))))

/* Bits stored in sprop->flags. */
#define SPROP_MARK                      0x01
#define SPROP_IS_DUPLICATE              0x02
#define SPROP_IS_ALIAS                  0x04
#define SPROP_HAS_SHORTID               0x08

/*
 * If SPROP_HAS_SHORTID is set in sprop->flags, we use sprop->shortid rather
 * than id when calling sprop's getter or setter.
 */
#define SPROP_USERID(sprop)                                                   \
    (((sprop)->flags & SPROP_HAS_SHORTID) ? INT_TO_JSVAL((sprop)->shortid)    \
                                          : ID_TO_VALUE((sprop)->id))

#define SPROP_INVALID_SLOT              0xffffffff

#define SPROP_HAS_VALID_SLOT(sprop, scope)                                    \
    ((sprop)->slot < (scope)->map.freeslot)

#define SPROP_CALL_GETTER(cx,sprop,getter,obj,obj2,vp)                        \
    (!(getter) ||                                                             \
     (getter)(cx, OBJ_THIS_OBJECT(cx,obj), SPROP_USERID(sprop), vp))
#define SPROP_CALL_SETTER(cx,sprop,setter,obj,obj2,vp)                        \
    (!(setter) ||                                                             \
     (setter)(cx, OBJ_THIS_OBJECT(cx,obj), SPROP_USERID(sprop), vp))

#define SPROP_GET(cx,sprop,obj,obj2,vp)                                       \
    (((sprop)->attrs & JSPROP_GETTER)                                         \
     ? js_InternalGetOrSet(cx, obj, (sprop)->id,                              \
                           OBJECT_TO_JSVAL((sprop)->getter), JSACC_READ,      \
                           0, 0, vp)                                          \
     : SPROP_CALL_GETTER(cx, sprop, (sprop)->getter, obj, obj2, vp))

#define SPROP_SET(cx,sprop,obj,obj2,vp)                                       \
    (((sprop)->attrs & JSPROP_SETTER)                                         \
     ? js_InternalGetOrSet(cx, obj, (sprop)->id,                              \
                           OBJECT_TO_JSVAL((sprop)->setter), JSACC_WRITE,     \
                           1, vp, vp)                                         \
     : ((sprop)->attrs & JSPROP_GETTER)                                       \
     ? (JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                    \
                             JSMSG_GETTER_ONLY, NULL), JS_FALSE)              \
     : SPROP_CALL_SETTER(cx, sprop, (sprop)->setter, obj, obj2, vp))

/* Macro for common expression to test for shared permanent attributes. */
#define SPROP_IS_SHARED_PERMANENT(sprop)                                      \
    ((~(sprop)->attrs & (JSPROP_SHARED | JSPROP_PERMANENT)) == 0)

extern JSScope *
js_GetMutableScope(JSContext *cx, JSObject *obj);

extern JSScope *
js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *clasp,
            JSObject *obj);

extern void
js_DestroyScope(JSContext *cx, JSScope *scope);

#define ID_TO_VALUE(id) (((id) & JSVAL_INT) ? id : ATOM_KEY((JSAtom *)(id)))
#define HASH_ID(id)     (((id) & JSVAL_INT)                                   \
                         ? (jsatomid) JSVAL_TO_INT(id)                        \
                         : ((JSAtom *)id)->number)

extern JS_FRIEND_API(JSScopeProperty **)
js_SearchScope(JSScope *scope, jsid id, JSBool adding);

#define SCOPE_GET_PROPERTY(scope, id)                                         \
    SPROP_FETCH(js_SearchScope(scope, id, JS_FALSE))

#define SCOPE_HAS_PROPERTY(scope, sprop)                                      \
    (SCOPE_GET_PROPERTY(scope, (sprop)->id) == (sprop))

extern JSScopeProperty *
js_AddScopeProperty(JSContext *cx, JSScope *scope, jsid id,
                    JSPropertyOp getter, JSPropertyOp setter, uint32 slot,
                    uintN attrs, uintN flags, intN shortid);

extern JSScopeProperty *
js_ChangeScopePropertyAttrs(JSContext *cx, JSScope *scope,
                            JSScopeProperty *sprop, uintN attrs, uintN mask,
                            JSPropertyOp getter, JSPropertyOp setter);

extern JSBool
js_RemoveScopeProperty(JSContext *cx, JSScope *scope, jsid id);

extern void
js_ClearScope(JSContext *cx, JSScope *scope);

#define MARK_SCOPE_PROPERTY(sprop)      ((sprop)->flags |= SPROP_MARK)

extern void
js_SweepScopeProperties(JSRuntime *rt);

extern JSBool
js_InitPropertyTree(JSRuntime *rt);

extern void
js_FinishPropertyTree(JSRuntime *rt);

#endif /* jsscope_h___ */

⌨️ 快捷键说明

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