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

📄 lookup.h

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 H
字号:
/* *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org) *  Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * *  This library is free software; you can redistribute it and/or *  modify it under the terms of the GNU Lesser General Public *  License as published by the Free Software Foundation; either *  version 2 of the License, or (at your option) any later version. * *  This library is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *  Lesser General Public License for more details. * *  You should have received a copy of the GNU Lesser General Public *  License along with this library; if not, write to the Free Software *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA * */#ifndef Lookup_h#define Lookup_h#include "CallFrame.h"#include "Identifier.h"#include "JSFunction.h"#include "JSGlobalObject.h"#include "JSObject.h"#include "PropertySlot.h"#include <stdio.h>#include <wtf/Assertions.h>// Set ENABLE_PERFECT_HASH_SIZE to 0 to save memory at the// cost of speed.  Test your platform as results may vary.#define ENABLE_PERFECT_HASH_SIZE 1namespace JSC {    // Hash table generated by the create_hash_table script.    struct HashTableValue {        const char* key; // property name        unsigned char attributes; // JSObject attributes        intptr_t value1;        intptr_t value2;    };    // FIXME: There is no reason this get function can't be simpler.    // ie. typedef JSValuePtr (*GetFunction)(ExecState*, JSObject* baseObject)    typedef PropertySlot::GetValueFunc GetFunction;    typedef void (*PutFunction)(ExecState*, JSObject* baseObject, JSValuePtr value);    class HashEntry {    public:        void initialize(UString::Rep* key, unsigned char attributes, intptr_t v1, intptr_t v2)        {            m_key = key;            m_attributes = attributes;            m_u.store.value1 = v1;            m_u.store.value2 = v2;#if !ENABLE(PERFECT_HASH_SIZE)            m_next = 0;#endif        }        void setKey(UString::Rep* key) { m_key = key; }        UString::Rep* key() const { return m_key; }        unsigned char attributes() const { return m_attributes; }        NativeFunction function() const { ASSERT(m_attributes & Function); return m_u.function.functionValue; }        unsigned char functionLength() const { ASSERT(m_attributes & Function); return static_cast<unsigned char>(m_u.function.length); }        GetFunction propertyGetter() const { ASSERT(!(m_attributes & Function)); return m_u.property.get; }        PutFunction propertyPutter() const { ASSERT(!(m_attributes & Function)); return m_u.property.put; }        intptr_t lexerValue() const { ASSERT(!m_attributes); return m_u.lexer.value; }#if !ENABLE(PERFECT_HASH_SIZE)        void setNext(HashEntry *next) { m_next = next; }        HashEntry* next() const { return m_next; }#endif    private:        UString::Rep* m_key;        unsigned char m_attributes; // JSObject attributes        union {            struct {                intptr_t value1;                intptr_t value2;            } store;            struct {                NativeFunction functionValue;                intptr_t length; // number of arguments for function            } function;            struct {                GetFunction get;                PutFunction put;            } property;            struct {                intptr_t value;                intptr_t unused;            } lexer;        } m_u;#if !ENABLE(PERFECT_HASH_SIZE)        HashEntry* m_next;#endif    };    struct HashTable {#if ENABLE(PERFECT_HASH_SIZE)        int hashSizeMask; // Precomputed size for the hash table (minus 1).#else        int compactSize;        int compactHashSizeMask;#endif        const HashTableValue* values; // Fixed values generated by script.        mutable const HashEntry* table; // Table allocated at runtime.        ALWAYS_INLINE void initializeIfNeeded(JSGlobalData* globalData) const        {            if (!table)                createTable(globalData);        }        ALWAYS_INLINE void initializeIfNeeded(ExecState* exec) const        {            if (!table)                createTable(&exec->globalData());        }        void deleteTable() const;        // Find an entry in the table, and return the entry.        ALWAYS_INLINE const HashEntry* entry(JSGlobalData* globalData, const Identifier& identifier) const        {            initializeIfNeeded(globalData);            return entry(identifier);        }        ALWAYS_INLINE const HashEntry* entry(ExecState* exec, const Identifier& identifier) const        {            initializeIfNeeded(exec);            return entry(identifier);        }    private:        ALWAYS_INLINE const HashEntry* entry(const Identifier& identifier) const        {#if ENABLE(PERFECT_HASH_SIZE)            ASSERT(table);            const HashEntry* entry = &table[identifier.ustring().rep()->computedHash() & hashSizeMask];            if (entry->key() != identifier.ustring().rep())                return 0;            return entry;#else            ASSERT(table);            const HashEntry* entry = &table[identifier.ustring().rep()->computedHash() & compactHashSizeMask];            if (!entry->key())                return 0;            do {                if (entry->key() == identifier.ustring().rep())                    return entry;                entry = entry->next();            } while (entry);            return 0;#endif        }        // Convert the hash table keys to identifiers.        void createTable(JSGlobalData*) const;    };    void setUpStaticFunctionSlot(ExecState*, const HashEntry*, JSObject* thisObject, const Identifier& propertyName, PropertySlot&);    /**     * This method does it all (looking in the hashtable, checking for function     * overrides, creating the function or retrieving from cache, calling     * getValueProperty in case of a non-function property, forwarding to parent if     * unknown property).     */    template <class ThisImp, class ParentImp>    inline bool getStaticPropertySlot(ExecState* exec, const HashTable* table, ThisImp* thisObj, const Identifier& propertyName, PropertySlot& slot)    {        const HashEntry* entry = table->entry(exec, propertyName);        if (!entry) // not found, forward to parent            return thisObj->ParentImp::getOwnPropertySlot(exec, propertyName, slot);        if (entry->attributes() & Function)            setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot);        else            slot.setCustom(thisObj, entry->propertyGetter());        return true;    }    /**     * Simplified version of getStaticPropertySlot in case there are only functions.     * Using this instead of getStaticPropertySlot allows 'this' to avoid implementing     * a dummy getValueProperty.     */    template <class ParentImp>    inline bool getStaticFunctionSlot(ExecState* exec, const HashTable* table, JSObject* thisObj, const Identifier& propertyName, PropertySlot& slot)    {        if (static_cast<ParentImp*>(thisObj)->ParentImp::getOwnPropertySlot(exec, propertyName, slot))            return true;        const HashEntry* entry = table->entry(exec, propertyName);        if (!entry)            return false;        setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot);        return true;    }    /**     * Simplified version of getStaticPropertySlot in case there are no functions, only "values".     * Using this instead of getStaticPropertySlot removes the need for a FuncImp class.     */    template <class ThisImp, class ParentImp>    inline bool getStaticValueSlot(ExecState* exec, const HashTable* table, ThisImp* thisObj, const Identifier& propertyName, PropertySlot& slot)    {        const HashEntry* entry = table->entry(exec, propertyName);        if (!entry) // not found, forward to parent            return thisObj->ParentImp::getOwnPropertySlot(exec, propertyName, slot);        ASSERT(!(entry->attributes() & Function));        slot.setCustom(thisObj, entry->propertyGetter());        return true;    }    /**     * This one is for "put".     * It looks up a hash entry for the property to be set.  If an entry     * is found it sets the value and returns true, else it returns false.     */    template <class ThisImp>    inline bool lookupPut(ExecState* exec, const Identifier& propertyName, JSValuePtr value, const HashTable* table, ThisImp* thisObj)    {        const HashEntry* entry = table->entry(exec, propertyName);        if (!entry)            return false;        if (entry->attributes() & Function) // function: put as override property            thisObj->putDirect(propertyName, value);        else if (!(entry->attributes() & ReadOnly))            entry->propertyPutter()(exec, thisObj, value);        return true;    }    /**     * This one is for "put".     * It calls lookupPut<ThisImp>() to set the value.  If that call     * returns false (meaning no entry in the hash table was found),     * then it calls put() on the ParentImp class.     */    template <class ThisImp, class ParentImp>    inline void lookupPut(ExecState* exec, const Identifier& propertyName, JSValuePtr value, const HashTable* table, ThisImp* thisObj, PutPropertySlot& slot)    {        if (!lookupPut<ThisImp>(exec, propertyName, value, table, thisObj))            thisObj->ParentImp::put(exec, propertyName, value, slot); // not found: forward to parent    }} // namespace JSC#endif // Lookup_h

⌨️ 快捷键说明

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