Use constexpr instead of const in symbol definitions that are obviously constexpr.
[WebKit-https.git] / Source / JavaScriptCore / runtime / JSTypeInfo.h
1 // -*- mode: c++; c-basic-offset: 4 -*-
2 /*
3  * Copyright (C) 2008-2019 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 #pragma once
28
29 // This file would be called TypeInfo.h, but that conflicts with <typeinfo.h>
30 // in the STL on systems without case-sensitive file systems. 
31
32 #include "JSType.h"
33
34 namespace JSC {
35
36 class LLIntOffsetsExtractor;
37
38 // Inline flags.
39
40 static constexpr unsigned MasqueradesAsUndefined = 1; // WebCore uses MasqueradesAsUndefined to make document.all undetectable.
41 static constexpr unsigned ImplementsDefaultHasInstance = 1 << 1;
42 static constexpr unsigned OverridesGetCallData = 1 << 2; // Need this flag if you implement [[Callable]] interface, which means overriding getCallData. The object may not be callable since getCallData can say it is not callable.
43 static constexpr unsigned OverridesGetOwnPropertySlot = 1 << 3;
44 static constexpr unsigned OverridesToThis = 1 << 4; // If this is false then this returns something other than 'this'. Non-object cells that are visible to JS have this set as do some exotic objects.
45 static constexpr unsigned HasStaticPropertyTable = 1 << 5;
46 static constexpr unsigned TypeInfoPerCellBit = 1 << 7; // Unlike other inline flags, this will only be set on the cell itself and will not be set on the Structure.
47
48 // Out of line flags.
49
50 static constexpr unsigned ImplementsHasInstance = 1 << 8;
51 static constexpr unsigned OverridesGetPropertyNames = 1 << 9;
52 static constexpr unsigned ProhibitsPropertyCaching = 1 << 10;
53 static constexpr unsigned GetOwnPropertySlotIsImpure = 1 << 11;
54 static constexpr unsigned NewImpurePropertyFiresWatchpoints = 1 << 12;
55 static constexpr unsigned IsImmutablePrototypeExoticObject = 1 << 13;
56 static constexpr unsigned GetOwnPropertySlotIsImpureForPropertyAbsence = 1 << 14;
57 static constexpr unsigned InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero = 1 << 15;
58 static constexpr unsigned StructureIsImmortal = 1 << 16;
59 static constexpr unsigned HasPutPropertySecurityCheck = 1 << 17;
60
61 class TypeInfo {
62 public:
63     typedef uint8_t InlineTypeFlags;
64     typedef uint16_t OutOfLineTypeFlags;
65
66     TypeInfo(JSType type, unsigned flags = 0)
67         : TypeInfo(type, flags & 0xff, flags >> 8)
68     {
69         ASSERT(!(flags >> 24));
70     }
71
72     TypeInfo(JSType type, InlineTypeFlags inlineTypeFlags, OutOfLineTypeFlags outOfLineTypeFlags)
73         : m_type(type)
74         , m_flags(inlineTypeFlags)
75         , m_flags2(outOfLineTypeFlags)
76     {
77     }
78
79     JSType type() const { return static_cast<JSType>(m_type); }
80     bool isObject() const { return isObject(type()); }
81     static bool isObject(JSType type) { return type >= ObjectType; }
82     bool isFinalObject() const { return type() == FinalObjectType; }
83     bool isNumberObject() const { return type() == NumberObjectType; }
84
85     unsigned flags() const { return (static_cast<unsigned>(m_flags2) << 8) | static_cast<unsigned>(m_flags); }
86     bool masqueradesAsUndefined() const { return isSetOnFlags1(MasqueradesAsUndefined); }
87     bool implementsHasInstance() const { return isSetOnFlags2(ImplementsHasInstance); }
88     bool implementsDefaultHasInstance() const { return isSetOnFlags1(ImplementsDefaultHasInstance); }
89     bool overridesGetCallData() const { return isSetOnFlags1(OverridesGetCallData); }
90     bool overridesGetOwnPropertySlot() const { return overridesGetOwnPropertySlot(inlineTypeFlags()); }
91     static bool overridesGetOwnPropertySlot(InlineTypeFlags flags) { return flags & OverridesGetOwnPropertySlot; }
92     static bool hasStaticPropertyTable(InlineTypeFlags flags) { return flags & HasStaticPropertyTable; }
93     static bool perCellBit(InlineTypeFlags flags) { return flags & TypeInfoPerCellBit; }
94     bool overridesToThis() const { return isSetOnFlags1(OverridesToThis); }
95     bool structureIsImmortal() const { return isSetOnFlags2(StructureIsImmortal); }
96     bool overridesGetPropertyNames() const { return isSetOnFlags2(OverridesGetPropertyNames); }
97     bool prohibitsPropertyCaching() const { return isSetOnFlags2(ProhibitsPropertyCaching); }
98     bool getOwnPropertySlotIsImpure() const { return isSetOnFlags2(GetOwnPropertySlotIsImpure); }
99     bool getOwnPropertySlotIsImpureForPropertyAbsence() const { return isSetOnFlags2(GetOwnPropertySlotIsImpureForPropertyAbsence); }
100     bool hasPutPropertySecurityCheck() const { return isSetOnFlags2(HasPutPropertySecurityCheck); }
101     bool newImpurePropertyFiresWatchpoints() const { return isSetOnFlags2(NewImpurePropertyFiresWatchpoints); }
102     bool isImmutablePrototypeExoticObject() const { return isSetOnFlags2(IsImmutablePrototypeExoticObject); }
103     bool interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero() const { return isSetOnFlags2(InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero); }
104
105     static bool isArgumentsType(JSType type)
106     {
107         return type == DirectArgumentsType
108             || type == ScopedArgumentsType
109             || type == ClonedArgumentsType;
110     }
111
112     static ptrdiff_t flagsOffset()
113     {
114         return OBJECT_OFFSETOF(TypeInfo, m_flags);
115     }
116
117     static ptrdiff_t typeOffset()
118     {
119         return OBJECT_OFFSETOF(TypeInfo, m_type);
120     }
121
122     // Since the Structure doesn't track TypeInfoPerCellBit, we need to make sure we copy it.
123     static InlineTypeFlags mergeInlineTypeFlags(InlineTypeFlags structureFlags, InlineTypeFlags oldCellFlags)
124     {
125         return structureFlags | (oldCellFlags & static_cast<InlineTypeFlags>(TypeInfoPerCellBit));
126     }
127
128     InlineTypeFlags inlineTypeFlags() const { return m_flags; }
129     OutOfLineTypeFlags outOfLineTypeFlags() const { return m_flags2; }
130
131 private:
132     friend class LLIntOffsetsExtractor;
133
134     bool isSetOnFlags1(unsigned flag) const { ASSERT(flag <= (1 << 7)); return m_flags & flag; }
135     bool isSetOnFlags2(unsigned flag) const { ASSERT(flag >= (1 << 8)); return m_flags2 & (flag >> 8); }
136
137     uint8_t m_type;
138     uint8_t m_flags;
139     uint16_t m_flags2;
140 };
141
142 } // namespace JSC