2 * Copyright (C) 2009 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
29 #include "PropertyDescriptor.h"
31 #include "GetterSetter.h"
33 #include "Operations.h"
36 unsigned PropertyDescriptor::defaultAttributes = (DontDelete << 1) - 1;
38 bool PropertyDescriptor::writable() const
40 ASSERT(!isAccessorDescriptor());
41 return !(m_attributes & ReadOnly);
44 bool PropertyDescriptor::enumerable() const
46 return !(m_attributes & DontEnum);
49 bool PropertyDescriptor::configurable() const
51 return !(m_attributes & DontDelete);
54 bool PropertyDescriptor::isDataDescriptor() const
56 return m_value || (m_seenAttributes & WritablePresent);
59 bool PropertyDescriptor::isGenericDescriptor() const
61 return !isAccessorDescriptor() && !isDataDescriptor();
64 bool PropertyDescriptor::isAccessorDescriptor() const
66 return m_getter || m_setter;
69 void PropertyDescriptor::setUndefined()
71 m_value = jsUndefined();
72 m_attributes = ReadOnly | DontDelete | DontEnum;
75 JSValue PropertyDescriptor::getter() const
77 ASSERT(isAccessorDescriptor());
81 JSValue PropertyDescriptor::setter() const
83 ASSERT(isAccessorDescriptor());
87 void PropertyDescriptor::setDescriptor(JSValue value, unsigned attributes)
90 m_attributes = attributes;
91 if (value.isGetterSetter()) {
92 GetterSetter* accessor = asGetterSetter(value);
94 m_getter = accessor->getter();
96 m_attributes |= Getter;
98 m_setter = accessor->setter();
100 m_attributes |= Setter;
102 ASSERT(m_getter || m_setter);
103 m_seenAttributes = EnumerablePresent | ConfigurablePresent;
104 m_attributes &= ~ReadOnly;
107 m_seenAttributes = EnumerablePresent | ConfigurablePresent | WritablePresent;
111 void PropertyDescriptor::setAccessorDescriptor(JSValue getter, JSValue setter, unsigned attributes)
113 ASSERT(attributes & (Getter | Setter));
114 ASSERT(getter || setter);
115 m_attributes = attributes;
118 m_attributes &= ~ReadOnly;
119 m_seenAttributes = EnumerablePresent | ConfigurablePresent;
122 void PropertyDescriptor::setWritable(bool writable)
125 m_attributes &= ~ReadOnly;
127 m_attributes |= ReadOnly;
128 m_seenAttributes |= WritablePresent;
131 void PropertyDescriptor::setEnumerable(bool enumerable)
134 m_attributes &= ~DontEnum;
136 m_attributes |= DontEnum;
137 m_seenAttributes |= EnumerablePresent;
140 void PropertyDescriptor::setConfigurable(bool configurable)
143 m_attributes &= ~DontDelete;
145 m_attributes |= DontDelete;
146 m_seenAttributes |= ConfigurablePresent;
149 void PropertyDescriptor::setSetter(JSValue setter)
152 m_attributes |= Setter;
153 m_attributes &= ~ReadOnly;
156 void PropertyDescriptor::setGetter(JSValue getter)
159 m_attributes |= Getter;
160 m_attributes &= ~ReadOnly;
163 bool PropertyDescriptor::equalTo(ExecState* exec, const PropertyDescriptor& other) const
165 if (!other.m_value == m_value ||
166 !other.m_getter == m_getter ||
167 !other.m_setter == m_setter)
169 return (!m_value || JSValue::strictEqual(exec, other.m_value, m_value)) &&
170 (!m_getter || JSValue::strictEqual(exec, other.m_getter, m_getter)) &&
171 (!m_setter || JSValue::strictEqual(exec, other.m_setter, m_setter)) &&
172 attributesEqual(other);
175 bool PropertyDescriptor::attributesEqual(const PropertyDescriptor& other) const
177 unsigned mismatch = other.m_attributes ^ m_attributes;
178 unsigned sharedSeen = other.m_seenAttributes & m_seenAttributes;
179 if (sharedSeen & WritablePresent && mismatch & ReadOnly)
181 if (sharedSeen & ConfigurablePresent && mismatch & DontDelete)
183 if (sharedSeen & EnumerablePresent && mismatch & DontEnum)
188 unsigned PropertyDescriptor::attributesWithOverride(const PropertyDescriptor& other) const
190 unsigned mismatch = other.m_attributes ^ m_attributes;
191 unsigned sharedSeen = other.m_seenAttributes & m_seenAttributes;
192 unsigned newAttributes = m_attributes & defaultAttributes;
193 if (sharedSeen & WritablePresent && mismatch & ReadOnly)
194 newAttributes ^= ReadOnly;
195 if (sharedSeen & ConfigurablePresent && mismatch & DontDelete)
196 newAttributes ^= DontDelete;
197 if (sharedSeen & EnumerablePresent && mismatch & DontEnum)
198 newAttributes ^= DontEnum;
199 return newAttributes;