1// -*- mode: c++; c-basic-offset: 4 -*-
2/*
3 * Copyright (C) 2008 Apple Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#ifndef JSTypeInfo_h
28#define JSTypeInfo_h
29
30// This file would be called TypeInfo.h, but that conflicts with <typeinfo.h>
31// in the STL on systems without case-sensitive file systems.
32
33#include "JSType.h"
34
35namespace JSC {
36
37    class LLIntOffsetsExtractor;
38
39    static const unsigned MasqueradesAsUndefined = 1; // WebCore uses MasqueradesAsUndefined to make document.all undetectable.
40    static const unsigned ImplementsHasInstance = 1 << 1;
41    static const unsigned OverridesHasInstance = 1 << 2;
42    static const unsigned ImplementsDefaultHasInstance = 1 << 3;
43    static const unsigned IsEnvironmentRecord = 1 << 4;
44    static const unsigned OverridesGetOwnPropertySlot = 1 << 5;
45    static const unsigned InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero = 1 << 6;
46    static const unsigned OverridesVisitChildren = 1 << 7;
47
48    static const unsigned OverridesGetPropertyNames = 1 << 8;
49    static const unsigned ProhibitsPropertyCaching = 1 << 9;
50    static const unsigned HasImpureGetOwnPropertySlot = 1 << 10;
51    static const unsigned NewImpurePropertyFiresWatchpoints = 1 << 11;
52    static const unsigned StructureIsImmortal = 1 << 12;
53
54    class TypeInfo {
55    public:
56        typedef uint8_t InlineTypeFlags;
57        typedef uint8_t OutOfLineTypeFlags;
58
59        TypeInfo(JSType type, unsigned flags = 0)
60            : TypeInfo(type, flags & 0xff, flags >> 8)
61        {
62        }
63
64        TypeInfo(JSType type, InlineTypeFlags inlineTypeFlags, OutOfLineTypeFlags outOfLineTypeFlags)
65            : m_type(type)
66            , m_flags(inlineTypeFlags)
67            , m_flags2(outOfLineTypeFlags)
68        {
69            ASSERT(m_type >= CompoundType || !(isSetOnFlags1(OverridesVisitChildren)));
70            // No object that doesn't ImplementsHasInstance should override it!
71            ASSERT((m_flags & (ImplementsHasInstance | OverridesHasInstance)) != OverridesHasInstance);
72            // ImplementsDefaultHasInstance means (ImplementsHasInstance & !OverridesHasInstance)
73            if ((m_flags & (ImplementsHasInstance | OverridesHasInstance)) == ImplementsHasInstance)
74                m_flags |= ImplementsDefaultHasInstance;
75        }
76
77        JSType type() const { return static_cast<JSType>(m_type); }
78        bool isObject() const { return isObject(type()); }
79        static bool isObject(JSType type) { return type >= ObjectType; }
80        bool isFinalObject() const { return type() == FinalObjectType; }
81        bool isNumberObject() const { return type() == NumberObjectType; }
82        bool isName() const { return type() == NameInstanceType; }
83
84        unsigned flags() const { return (static_cast<unsigned>(m_flags2) << 8) | static_cast<unsigned>(m_flags); }
85        bool masqueradesAsUndefined() const { return isSetOnFlags1(MasqueradesAsUndefined); }
86        bool implementsHasInstance() const { return isSetOnFlags1(ImplementsHasInstance); }
87        bool isEnvironmentRecord() const { return isSetOnFlags1(IsEnvironmentRecord); }
88        bool overridesHasInstance() const { return isSetOnFlags1(OverridesHasInstance); }
89        bool implementsDefaultHasInstance() const { return isSetOnFlags1(ImplementsDefaultHasInstance); }
90        bool overridesGetOwnPropertySlot() const { return overridesGetOwnPropertySlot(inlineTypeFlags()); }
91        static bool overridesGetOwnPropertySlot(InlineTypeFlags flags) { return flags & OverridesGetOwnPropertySlot; }
92        bool interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero() const { return isSetOnFlags1(InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero); }
93        bool overridesVisitChildren() const { return isSetOnFlags1(OverridesVisitChildren); }
94        bool overridesGetPropertyNames() const { return isSetOnFlags2(OverridesGetPropertyNames); }
95        bool prohibitsPropertyCaching() const { return isSetOnFlags2(ProhibitsPropertyCaching); }
96        bool hasImpureGetOwnPropertySlot() const { return isSetOnFlags2(HasImpureGetOwnPropertySlot); }
97        bool newImpurePropertyFiresWatchpoints() const { return isSetOnFlags2(NewImpurePropertyFiresWatchpoints); }
98        bool structureIsImmortal() const { return isSetOnFlags2(StructureIsImmortal); }
99
100        static ptrdiff_t flagsOffset()
101        {
102            return OBJECT_OFFSETOF(TypeInfo, m_flags);
103        }
104
105        static ptrdiff_t typeOffset()
106        {
107            return OBJECT_OFFSETOF(TypeInfo, m_type);
108        }
109
110        InlineTypeFlags inlineTypeFlags() const { return m_flags; }
111        OutOfLineTypeFlags outOfLineTypeFlags() const { return m_flags2; }
112
113    private:
114        friend class LLIntOffsetsExtractor;
115
116        bool isSetOnFlags1(unsigned flag) const { ASSERT(flag <= (1 << 7)); return m_flags & flag; }
117        bool isSetOnFlags2(unsigned flag) const { ASSERT(flag >= (1 << 8)); return m_flags2 & (flag >> 8); }
118
119        unsigned char m_type;
120        unsigned char m_flags;
121        unsigned char m_flags2;
122    };
123
124}
125
126#endif // JSTypeInfo_h
127