]>
git.saurik.com Git - apple/javascriptcore.git/blob - runtime/PropertyDescriptor.cpp
236a8e5aeec176757815072751d4eae48fc7a286
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 JSObject
* PropertyDescriptor::getterObject() const
89 ASSERT(isAccessorDescriptor() && getterPresent());
90 return m_getter
.isObject() ? asObject(m_getter
) : 0;
93 JSObject
* PropertyDescriptor::setterObject() const
95 ASSERT(isAccessorDescriptor() && setterPresent());
96 return m_setter
.isObject() ? asObject(m_setter
) : 0;
99 void PropertyDescriptor::setDescriptor(JSValue value
, unsigned attributes
)
102 ASSERT(value
.isGetterSetter() == !!(attributes
& Accessor
));
104 m_attributes
= attributes
;
105 if (value
.isGetterSetter()) {
106 m_attributes
&= ~ReadOnly
; // FIXME: we should be able to ASSERT this!
108 GetterSetter
* accessor
= asGetterSetter(value
);
109 m_getter
= accessor
->getter() ? accessor
->getter() : jsUndefined();
110 m_setter
= accessor
->setter() ? accessor
->setter() : jsUndefined();
111 m_seenAttributes
= EnumerablePresent
| ConfigurablePresent
;
114 m_seenAttributes
= EnumerablePresent
| ConfigurablePresent
| WritablePresent
;
118 void PropertyDescriptor::setAccessorDescriptor(GetterSetter
* accessor
, unsigned attributes
)
120 ASSERT(attributes
& Accessor
);
121 attributes
&= ~ReadOnly
; // FIXME: we should be able to ASSERT this!
123 m_attributes
= attributes
;
124 m_getter
= accessor
->getter() ? accessor
->getter() : jsUndefined();
125 m_setter
= accessor
->setter() ? accessor
->setter() : jsUndefined();
126 m_seenAttributes
= EnumerablePresent
| ConfigurablePresent
;
129 void PropertyDescriptor::setWritable(bool writable
)
132 m_attributes
&= ~ReadOnly
;
134 m_attributes
|= ReadOnly
;
135 m_seenAttributes
|= WritablePresent
;
138 void PropertyDescriptor::setEnumerable(bool enumerable
)
141 m_attributes
&= ~DontEnum
;
143 m_attributes
|= DontEnum
;
144 m_seenAttributes
|= EnumerablePresent
;
147 void PropertyDescriptor::setConfigurable(bool configurable
)
150 m_attributes
&= ~DontDelete
;
152 m_attributes
|= DontDelete
;
153 m_seenAttributes
|= ConfigurablePresent
;
156 void PropertyDescriptor::setSetter(JSValue setter
)
159 m_attributes
|= Accessor
;
160 m_attributes
&= ~ReadOnly
;
163 void PropertyDescriptor::setGetter(JSValue getter
)
166 m_attributes
|= Accessor
;
167 m_attributes
&= ~ReadOnly
;
171 bool sameValue(ExecState
* exec
, JSValue a
, JSValue b
)
174 return JSValue::strictEqual(exec
, a
, b
);
177 double x
= a
.asNumber();
178 double y
= b
.asNumber();
181 return bitwise_cast
<uint64_t>(x
) == bitwise_cast
<uint64_t>(y
);
184 bool PropertyDescriptor::equalTo(ExecState
* exec
, const PropertyDescriptor
& other
) const
186 if (!other
.m_value
== m_value
||
187 !other
.m_getter
== m_getter
||
188 !other
.m_setter
== m_setter
)
190 return (!m_value
|| sameValue(exec
, other
.m_value
, m_value
))
191 && (!m_getter
|| JSValue::strictEqual(exec
, other
.m_getter
, m_getter
))
192 && (!m_setter
|| JSValue::strictEqual(exec
, other
.m_setter
, m_setter
))
193 && attributesEqual(other
);
196 bool PropertyDescriptor::attributesEqual(const PropertyDescriptor
& other
) const
198 unsigned mismatch
= other
.m_attributes
^ m_attributes
;
199 unsigned sharedSeen
= other
.m_seenAttributes
& m_seenAttributes
;
200 if (sharedSeen
& WritablePresent
&& mismatch
& ReadOnly
)
202 if (sharedSeen
& ConfigurablePresent
&& mismatch
& DontDelete
)
204 if (sharedSeen
& EnumerablePresent
&& mismatch
& DontEnum
)
209 unsigned PropertyDescriptor::attributesOverridingCurrent(const PropertyDescriptor
& current
) const
211 unsigned currentAttributes
= current
.m_attributes
;
212 if (isDataDescriptor() && current
.isAccessorDescriptor())
213 currentAttributes
|= ReadOnly
;
214 unsigned overrideMask
= 0;
215 if (writablePresent())
216 overrideMask
|= ReadOnly
;
217 if (enumerablePresent())
218 overrideMask
|= DontEnum
;
219 if (configurablePresent())
220 overrideMask
|= DontDelete
;
221 if (isAccessorDescriptor())
222 overrideMask
|= Accessor
;
223 return (m_attributes
& overrideMask
) | (currentAttributes
& ~overrideMask
);