1 | /* |
2 | * Copyright (C) 2016 Apple Inc. All rights reserved. |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions |
6 | * are met: |
7 | * 1. Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. |
9 | * 2. Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
18 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
20 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
21 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
23 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #pragma once |
27 | |
28 | #include <wtf/Optional.h> |
29 | #include <wtf/TriState.h> |
30 | |
31 | namespace JSC { |
32 | |
33 | class DefinePropertyAttributes { |
34 | public: |
35 | static_assert(FalseTriState == 0, "FalseTriState is 0." ); |
36 | static_assert(TrueTriState == 1, "TrueTriState is 1." ); |
37 | static_assert(MixedTriState == 2, "MixedTriState is 2." ); |
38 | |
39 | static const unsigned ConfigurableShift = 0; |
40 | static const unsigned EnumerableShift = 2; |
41 | static const unsigned WritableShift = 4; |
42 | static const unsigned ValueShift = 6; |
43 | static const unsigned GetShift = 7; |
44 | static const unsigned SetShift = 8; |
45 | |
46 | DefinePropertyAttributes() |
47 | : m_attributes( |
48 | (MixedTriState << ConfigurableShift) |
49 | | (MixedTriState << EnumerableShift) |
50 | | (MixedTriState << WritableShift) |
51 | | (0 << ValueShift) |
52 | | (0 << GetShift) |
53 | | (0 << SetShift)) |
54 | { |
55 | } |
56 | |
57 | explicit DefinePropertyAttributes(unsigned attributes) |
58 | : m_attributes(attributes) |
59 | { |
60 | } |
61 | |
62 | unsigned rawRepresentation() const |
63 | { |
64 | return m_attributes; |
65 | } |
66 | |
67 | bool hasValue() const |
68 | { |
69 | return m_attributes & (0b1 << ValueShift); |
70 | } |
71 | |
72 | void setValue() |
73 | { |
74 | m_attributes = m_attributes | (0b1 << ValueShift); |
75 | } |
76 | |
77 | bool hasGet() const |
78 | { |
79 | return m_attributes & (0b1 << GetShift); |
80 | } |
81 | |
82 | void setGet() |
83 | { |
84 | m_attributes = m_attributes | (0b1 << GetShift); |
85 | } |
86 | |
87 | bool hasSet() const |
88 | { |
89 | return m_attributes & (0b1 << SetShift); |
90 | } |
91 | |
92 | void setSet() |
93 | { |
94 | m_attributes = m_attributes | (0b1 << SetShift); |
95 | } |
96 | |
97 | bool hasWritable() const |
98 | { |
99 | return extractTriState(WritableShift) != MixedTriState; |
100 | } |
101 | |
102 | Optional<bool> writable() const |
103 | { |
104 | if (!hasWritable()) |
105 | return WTF::nullopt; |
106 | return extractTriState(WritableShift) == TrueTriState; |
107 | } |
108 | |
109 | bool hasConfigurable() const |
110 | { |
111 | return extractTriState(ConfigurableShift) != MixedTriState; |
112 | } |
113 | |
114 | Optional<bool> configurable() const |
115 | { |
116 | if (!hasConfigurable()) |
117 | return WTF::nullopt; |
118 | return extractTriState(ConfigurableShift) == TrueTriState; |
119 | } |
120 | |
121 | bool hasEnumerable() const |
122 | { |
123 | return extractTriState(EnumerableShift) != MixedTriState; |
124 | } |
125 | |
126 | Optional<bool> enumerable() const |
127 | { |
128 | if (!hasEnumerable()) |
129 | return WTF::nullopt; |
130 | return extractTriState(EnumerableShift) == TrueTriState; |
131 | } |
132 | |
133 | void setWritable(bool value) |
134 | { |
135 | fillWithTriState(value ? TrueTriState : FalseTriState, WritableShift); |
136 | } |
137 | |
138 | void setConfigurable(bool value) |
139 | { |
140 | fillWithTriState(value ? TrueTriState : FalseTriState, ConfigurableShift); |
141 | } |
142 | |
143 | void setEnumerable(bool value) |
144 | { |
145 | fillWithTriState(value ? TrueTriState : FalseTriState, EnumerableShift); |
146 | } |
147 | |
148 | private: |
149 | void fillWithTriState(TriState state, unsigned shift) |
150 | { |
151 | unsigned mask = 0b11 << shift; |
152 | m_attributes = (m_attributes & ~mask) | (state << shift); |
153 | } |
154 | |
155 | TriState (unsigned shift) const |
156 | { |
157 | return static_cast<TriState>((m_attributes >> shift) & 0b11); |
158 | } |
159 | |
160 | unsigned m_attributes; |
161 | }; |
162 | |
163 | |
164 | } // namespace JSC |
165 | |