1// -*- mode: c++; c-basic-offset: 4 -*-
2/*
3 * Copyright (C) 2008, 2015 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
37class LLIntOffsetsExtractor;
38
39static const unsigned MasqueradesAsUndefined = 1; // WebCore uses MasqueradesAsUndefined to make document.all undetectable.
40static const unsigned ImplementsDefaultHasInstance = 1 << 1;
41static const unsigned TypeOfShouldCallGetCallData = 1 << 2; // Need this flag if you override getCallData() and you want typeof to use this to determine if it should say "function". Currently we always set this flag when we override getCallData().
42static const unsigned OverridesGetOwnPropertySlot = 1 << 3;
43static const unsigned InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero = 1 << 4;
44static const unsigned StructureIsImmortal = 1 << 5;
45// There are two free bits at the end of the InlineTypeFlags.
46
47static const unsigned ImplementsHasInstance = 1 << 8;
48static const unsigned OverridesGetPropertyNames = 1 << 9;
49static const unsigned ProhibitsPropertyCaching = 1 << 10;
50static const unsigned GetOwnPropertySlotIsImpure = 1 << 11;
51static const unsigned NewImpurePropertyFiresWatchpoints = 1 << 12;
52static const unsigned IsEnvironmentRecord = 1 << 13;
53static const unsigned GetOwnPropertySlotIsImpureForPropertyAbsence = 1 << 14;
54
55class TypeInfo {
56public:
57 typedef uint8_t InlineTypeFlags;
58 typedef uint8_t OutOfLineTypeFlags;
59
60 TypeInfo(JSType type, unsigned flags = 0)
61 : TypeInfo(type, flags & 0xff, flags >> 8)
62 {
63 }
64
65 TypeInfo(JSType type, InlineTypeFlags inlineTypeFlags, OutOfLineTypeFlags outOfLineTypeFlags)
66 : m_type(type)
67 , m_flags(inlineTypeFlags)
68 , m_flags2(outOfLineTypeFlags)
69 {
70 }
71
72 JSType type() const { return static_cast<JSType>(m_type); }
73 bool isObject() const { return isObject(type()); }
74 static bool isObject(JSType type) { return type >= ObjectType; }
75 bool isFinalObject() const { return type() == FinalObjectType; }
76 bool isNumberObject() const { return type() == NumberObjectType; }
77
78 unsigned flags() const { return (static_cast<unsigned>(m_flags2) << 8) | static_cast<unsigned>(m_flags); }
79 bool masqueradesAsUndefined() const { return isSetOnFlags1(MasqueradesAsUndefined); }
80 bool implementsHasInstance() const { return isSetOnFlags2(ImplementsHasInstance); }
81 bool implementsDefaultHasInstance() const { return isSetOnFlags1(ImplementsDefaultHasInstance); }
82 bool typeOfShouldCallGetCallData() const { return isSetOnFlags1(TypeOfShouldCallGetCallData); }
83 bool overridesGetOwnPropertySlot() const { return overridesGetOwnPropertySlot(inlineTypeFlags()); }
84 static bool overridesGetOwnPropertySlot(InlineTypeFlags flags) { return flags & OverridesGetOwnPropertySlot; }
85 bool interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero() const { return isSetOnFlags1(InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero); }
86 bool structureIsImmortal() const { return isSetOnFlags1(StructureIsImmortal); }
87 bool overridesGetPropertyNames() const { return isSetOnFlags2(OverridesGetPropertyNames); }
88 bool prohibitsPropertyCaching() const { return isSetOnFlags2(ProhibitsPropertyCaching); }
89 bool getOwnPropertySlotIsImpure() const { return isSetOnFlags2(GetOwnPropertySlotIsImpure); }
90 bool getOwnPropertySlotIsImpureForPropertyAbsence() const { return isSetOnFlags2(GetOwnPropertySlotIsImpureForPropertyAbsence); }
91 bool newImpurePropertyFiresWatchpoints() const { return isSetOnFlags2(NewImpurePropertyFiresWatchpoints); }
92 bool isEnvironmentRecord() const { return isSetOnFlags2(IsEnvironmentRecord); }
93
94 static ptrdiff_t flagsOffset()
95 {
96 return OBJECT_OFFSETOF(TypeInfo, m_flags);
97 }
98
99 static ptrdiff_t typeOffset()
100 {
101 return OBJECT_OFFSETOF(TypeInfo, m_type);
102 }
103
104 InlineTypeFlags inlineTypeFlags() const { return m_flags; }
105 OutOfLineTypeFlags outOfLineTypeFlags() const { return m_flags2; }
106
107private:
108 friend class LLIntOffsetsExtractor;
109
110 bool isSetOnFlags1(unsigned flag) const { ASSERT(flag <= (1 << 7)); return m_flags & flag; }
111 bool isSetOnFlags2(unsigned flag) const { ASSERT(flag >= (1 << 8)); return m_flags2 & (flag >> 8); }
112
113 unsigned char m_type;
114 unsigned char m_flags;
115 unsigned char m_flags2;
116};
117
118}
119
120#endif // JSTypeInfo_h
121