Implement ES6 Symbol
[WebKit-https.git] / Source / JavaScriptCore / runtime / JSCell.cpp
1 /*
2  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4  *  Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Library General Public
8  *  License as published by the Free Software Foundation; either
9  *  version 2 of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Library General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Library General Public License
17  *  along with this library; see the file COPYING.LIB.  If not, write to
18  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  *  Boston, MA 02110-1301, USA.
20  *
21  */
22
23 #include "config.h"
24 #include "JSCell.h"
25
26 #include "ArrayBufferView.h"
27 #include "JSFunction.h"
28 #include "JSString.h"
29 #include "JSObject.h"
30 #include "NumberObject.h"
31 #include "JSCInlines.h"
32 #include <wtf/MathExtras.h>
33
34 namespace JSC {
35
36 COMPILE_ASSERT(sizeof(JSCell) == sizeof(uint64_t), jscell_is_eight_bytes);
37 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSCell);
38
39 void JSCell::destroy(JSCell* cell)
40 {
41     cell->JSCell::~JSCell();
42 }
43
44 void JSCell::dump(PrintStream& out) const
45 {
46     methodTable()->dumpToStream(this, out);
47 }
48
49 void JSCell::dumpToStream(const JSCell* cell, PrintStream& out)
50 {
51     out.printf("<%p, %s>", cell, cell->className());
52 }
53
54 void JSCell::copyBackingStore(JSCell*, CopyVisitor&, CopyToken)
55 {
56 }
57
58 bool JSCell::getString(ExecState* exec, String& stringValue) const
59 {
60     if (!isString())
61         return false;
62     stringValue = static_cast<const JSString*>(this)->value(exec);
63     return true;
64 }
65
66 String JSCell::getString(ExecState* exec) const
67 {
68     return isString() ? static_cast<const JSString*>(this)->value(exec) : String();
69 }
70
71 JSObject* JSCell::getObject()
72 {
73     return isObject() ? asObject(this) : 0;
74 }
75
76 const JSObject* JSCell::getObject() const
77 {
78     return isObject() ? static_cast<const JSObject*>(this) : 0;
79 }
80
81 CallType JSCell::getCallData(JSCell*, CallData& callData)
82 {
83     callData.js.functionExecutable = 0;
84     callData.js.scope = 0;
85     callData.native.function = 0;
86     return CallTypeNone;
87 }
88
89 ConstructType JSCell::getConstructData(JSCell*, ConstructData& constructData)
90 {
91     constructData.js.functionExecutable = 0;
92     constructData.js.scope = 0;
93     constructData.native.function = 0;
94     return ConstructTypeNone;
95 }
96
97 void JSCell::put(JSCell* cell, ExecState* exec, PropertyName identifier, JSValue value, PutPropertySlot& slot)
98 {
99     if (cell->isString() || cell->isSymbol()) {
100         JSValue(cell).putToPrimitive(exec, identifier, value, slot);
101         return;
102     }
103     JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject());
104     thisObject->methodTable(exec->vm())->put(thisObject, exec, identifier, value, slot);
105 }
106
107 void JSCell::putByIndex(JSCell* cell, ExecState* exec, unsigned identifier, JSValue value, bool shouldThrow)
108 {
109     if (cell->isString() || cell->isSymbol()) {
110         PutPropertySlot slot(cell, shouldThrow);
111         JSValue(cell).putToPrimitive(exec, Identifier::from(exec, identifier), value, slot);
112         return;
113     }
114     JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject());
115     thisObject->methodTable(exec->vm())->putByIndex(thisObject, exec, identifier, value, shouldThrow);
116 }
117
118 bool JSCell::deleteProperty(JSCell* cell, ExecState* exec, PropertyName identifier)
119 {
120     JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject());
121     return thisObject->methodTable(exec->vm())->deleteProperty(thisObject, exec, identifier);
122 }
123
124 bool JSCell::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned identifier)
125 {
126     JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject());
127     return thisObject->methodTable(exec->vm())->deletePropertyByIndex(thisObject, exec, identifier);
128 }
129
130 JSValue JSCell::toThis(JSCell* cell, ExecState* exec, ECMAMode ecmaMode)
131 {
132     if (ecmaMode == StrictMode)
133         return cell;
134     return cell->toObject(exec, exec->lexicalGlobalObject());
135 }
136
137 JSValue JSCell::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
138 {
139     if (isString())
140         return static_cast<const JSString*>(this)->toPrimitive(exec, preferredType);
141     if (isSymbol())
142         return static_cast<const Symbol*>(this)->toPrimitive(exec, preferredType);
143     return static_cast<const JSObject*>(this)->toPrimitive(exec, preferredType);
144 }
145
146 bool JSCell::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value) const
147 {
148     if (isString())
149         return static_cast<const JSString*>(this)->getPrimitiveNumber(exec, number, value);
150     if (isSymbol())
151         return static_cast<const Symbol*>(this)->getPrimitiveNumber(exec, number, value);
152     return static_cast<const JSObject*>(this)->getPrimitiveNumber(exec, number, value);
153 }
154
155 double JSCell::toNumber(ExecState* exec) const
156
157     if (isString())
158         return static_cast<const JSString*>(this)->toNumber(exec);
159     if (isSymbol())
160         return static_cast<const Symbol*>(this)->toNumber(exec);
161     return static_cast<const JSObject*>(this)->toNumber(exec);
162 }
163
164 JSObject* JSCell::toObject(ExecState* exec, JSGlobalObject* globalObject) const
165 {
166     if (isString())
167         return static_cast<const JSString*>(this)->toObject(exec, globalObject);
168     if (isSymbol())
169         return static_cast<const Symbol*>(this)->toObject(exec, globalObject);
170     ASSERT(isObject());
171     return jsCast<JSObject*>(const_cast<JSCell*>(this));
172 }
173
174 void slowValidateCell(JSCell* cell)
175 {
176     ASSERT_GC_OBJECT_LOOKS_VALID(cell);
177 }
178
179 JSValue JSCell::defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType)
180 {
181     RELEASE_ASSERT_NOT_REACHED();
182     return jsUndefined();
183 }
184
185 bool JSCell::getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&)
186 {
187     RELEASE_ASSERT_NOT_REACHED();
188     return false;
189 }
190
191 bool JSCell::getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned, PropertySlot&)
192 {
193     RELEASE_ASSERT_NOT_REACHED();
194     return false;
195 }
196
197 void JSCell::getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
198 {
199     RELEASE_ASSERT_NOT_REACHED();
200 }
201
202 void JSCell::getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
203 {
204     RELEASE_ASSERT_NOT_REACHED();
205 }
206
207 String JSCell::className(const JSObject*)
208 {
209     RELEASE_ASSERT_NOT_REACHED();
210     return String();
211 }
212
213 const char* JSCell::className() const
214 {
215     return classInfo()->className;
216 }
217
218 void JSCell::getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
219 {
220     RELEASE_ASSERT_NOT_REACHED();
221 }
222
223 bool JSCell::customHasInstance(JSObject*, ExecState*, JSValue)
224 {
225     RELEASE_ASSERT_NOT_REACHED();
226     return false;
227 }
228
229 bool JSCell::defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool)
230 {
231     RELEASE_ASSERT_NOT_REACHED();
232     return false;
233 }
234
235 ArrayBuffer* JSCell::slowDownAndWasteMemory(JSArrayBufferView*)
236 {
237     RELEASE_ASSERT_NOT_REACHED();
238     return 0;
239 }
240
241 PassRefPtr<ArrayBufferView> JSCell::getTypedArrayImpl(JSArrayBufferView*)
242 {
243     RELEASE_ASSERT_NOT_REACHED();
244     return 0;
245 }
246
247 uint32_t JSCell::getEnumerableLength(ExecState*, JSObject*)
248 {
249     RELEASE_ASSERT_NOT_REACHED();
250     return 0;
251 }
252
253 void JSCell::getStructurePropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
254 {
255     RELEASE_ASSERT_NOT_REACHED();
256 }
257
258 void JSCell::getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
259 {
260     RELEASE_ASSERT_NOT_REACHED();
261 }
262
263 } // namespace JSC