tizen beta release
[framework/web/webkit-efl.git] / Source / JavaScriptCore / runtime / PropertyDescriptor.cpp
1 /*
2  * Copyright (C) 2009 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
27 #include "config.h"
28
29 #include "PropertyDescriptor.h"
30
31 #include "GetterSetter.h"
32 #include "JSObject.h"
33 #include "Operations.h"
34
35 namespace JSC {
36 unsigned PropertyDescriptor::defaultAttributes = (DontDelete << 1) - 1;
37
38 bool PropertyDescriptor::writable() const
39 {
40     ASSERT(!isAccessorDescriptor());
41     return !(m_attributes & ReadOnly);
42 }
43
44 bool PropertyDescriptor::enumerable() const
45 {
46     return !(m_attributes & DontEnum);
47 }
48
49 bool PropertyDescriptor::configurable() const
50 {
51     return !(m_attributes & DontDelete);
52 }
53
54 bool PropertyDescriptor::isDataDescriptor() const
55 {
56     return m_value || (m_seenAttributes & WritablePresent);
57 }
58
59 bool PropertyDescriptor::isGenericDescriptor() const
60 {
61     return !isAccessorDescriptor() && !isDataDescriptor();
62 }
63
64 bool PropertyDescriptor::isAccessorDescriptor() const
65 {
66     return m_getter || m_setter;
67 }
68
69 void PropertyDescriptor::setUndefined()
70 {
71     m_value = jsUndefined();
72     m_attributes = ReadOnly | DontDelete | DontEnum;
73 }
74
75 JSValue PropertyDescriptor::getter() const
76 {
77     ASSERT(isAccessorDescriptor());
78     return m_getter;
79 }
80
81 JSValue PropertyDescriptor::setter() const
82 {
83     ASSERT(isAccessorDescriptor());
84     return m_setter;
85 }
86
87 void PropertyDescriptor::setDescriptor(JSValue value, unsigned attributes)
88 {
89     ASSERT(value);
90     m_attributes = attributes;
91     if (value.isGetterSetter()) {
92         GetterSetter* accessor = asGetterSetter(value);
93
94         m_getter = accessor->getter();
95         if (m_getter)
96             m_attributes |= Getter;
97
98         m_setter = accessor->setter();
99         if (m_setter)
100             m_attributes |= Setter;
101
102         ASSERT(m_getter || m_setter);
103         m_seenAttributes = EnumerablePresent | ConfigurablePresent;
104         m_attributes &= ~ReadOnly;
105     } else {
106         m_value = value;
107         m_seenAttributes = EnumerablePresent | ConfigurablePresent | WritablePresent;
108     }
109 }
110
111 void PropertyDescriptor::setAccessorDescriptor(JSValue getter, JSValue setter, unsigned attributes)
112 {
113     ASSERT(attributes & (Getter | Setter));
114     ASSERT(getter || setter);
115     m_attributes = attributes;
116     m_getter = getter;
117     m_setter = setter;
118     m_attributes &= ~ReadOnly;
119     m_seenAttributes = EnumerablePresent | ConfigurablePresent;
120 }
121
122 void PropertyDescriptor::setWritable(bool writable)
123 {
124     if (writable)
125         m_attributes &= ~ReadOnly;
126     else
127         m_attributes |= ReadOnly;
128     m_seenAttributes |= WritablePresent;
129 }
130
131 void PropertyDescriptor::setEnumerable(bool enumerable)
132 {
133     if (enumerable)
134         m_attributes &= ~DontEnum;
135     else
136         m_attributes |= DontEnum;
137     m_seenAttributes |= EnumerablePresent;
138 }
139
140 void PropertyDescriptor::setConfigurable(bool configurable)
141 {
142     if (configurable)
143         m_attributes &= ~DontDelete;
144     else
145         m_attributes |= DontDelete;
146     m_seenAttributes |= ConfigurablePresent;
147 }
148
149 void PropertyDescriptor::setSetter(JSValue setter)
150 {
151     m_setter = setter;
152     m_attributes |= Setter;
153     m_attributes &= ~ReadOnly;
154 }
155
156 void PropertyDescriptor::setGetter(JSValue getter)
157 {
158     m_getter = getter;
159     m_attributes |= Getter;
160     m_attributes &= ~ReadOnly;
161 }
162
163 bool PropertyDescriptor::equalTo(ExecState* exec, const PropertyDescriptor& other) const
164 {
165     if (!other.m_value == m_value ||
166         !other.m_getter == m_getter ||
167         !other.m_setter == m_setter)
168         return false;
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);
173 }
174
175 bool PropertyDescriptor::attributesEqual(const PropertyDescriptor& other) const
176 {
177     unsigned mismatch = other.m_attributes ^ m_attributes;
178     unsigned sharedSeen = other.m_seenAttributes & m_seenAttributes;
179     if (sharedSeen & WritablePresent && mismatch & ReadOnly)
180         return false;
181     if (sharedSeen & ConfigurablePresent && mismatch & DontDelete)
182         return false;
183     if (sharedSeen & EnumerablePresent && mismatch & DontEnum)
184         return false;
185     return true;
186 }
187
188 unsigned PropertyDescriptor::attributesWithOverride(const PropertyDescriptor& other) const
189 {
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;
200 }
201
202 }