Heap Snapshot should include different Edge types and data (Property, Index, Variable)
[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 size_t JSCell::estimatedSizeInBytes() const
55 {
56     return methodTable()->estimatedSize(const_cast<JSCell*>(this));
57 }
58
59 size_t JSCell::estimatedSize(JSCell* cell)
60 {
61     return MarkedBlock::blockFor(cell)->cellSize();
62 }
63
64 void JSCell::copyBackingStore(JSCell*, CopyVisitor&, CopyToken)
65 {
66 }
67
68 void JSCell::heapSnapshot(JSCell*, HeapSnapshotBuilder&)
69 {
70 }
71
72 bool JSCell::getString(ExecState* exec, String& stringValue) const
73 {
74     if (!isString())
75         return false;
76     stringValue = static_cast<const JSString*>(this)->value(exec);
77     return true;
78 }
79
80 String JSCell::getString(ExecState* exec) const
81 {
82     return isString() ? static_cast<const JSString*>(this)->value(exec) : String();
83 }
84
85 JSObject* JSCell::getObject()
86 {
87     return isObject() ? asObject(this) : 0;
88 }
89
90 const JSObject* JSCell::getObject() const
91 {
92     return isObject() ? static_cast<const JSObject*>(this) : 0;
93 }
94
95 CallType JSCell::getCallData(JSCell*, CallData& callData)
96 {
97     callData.js.functionExecutable = 0;
98     callData.js.scope = 0;
99     callData.native.function = 0;
100     return CallType::None;
101 }
102
103 ConstructType JSCell::getConstructData(JSCell*, ConstructData& constructData)
104 {
105     constructData.js.functionExecutable = 0;
106     constructData.js.scope = 0;
107     constructData.native.function = 0;
108     return ConstructType::None;
109 }
110
111 void JSCell::put(JSCell* cell, ExecState* exec, PropertyName identifier, JSValue value, PutPropertySlot& slot)
112 {
113     if (cell->isString() || cell->isSymbol()) {
114         JSValue(cell).putToPrimitive(exec, identifier, value, slot);
115         return;
116     }
117     JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject());
118     thisObject->methodTable(exec->vm())->put(thisObject, exec, identifier, value, slot);
119 }
120
121 void JSCell::putByIndex(JSCell* cell, ExecState* exec, unsigned identifier, JSValue value, bool shouldThrow)
122 {
123     if (cell->isString() || cell->isSymbol()) {
124         PutPropertySlot slot(cell, shouldThrow);
125         JSValue(cell).putToPrimitive(exec, Identifier::from(exec, identifier), value, slot);
126         return;
127     }
128     JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject());
129     thisObject->methodTable(exec->vm())->putByIndex(thisObject, exec, identifier, value, shouldThrow);
130 }
131
132 bool JSCell::deleteProperty(JSCell* cell, ExecState* exec, PropertyName identifier)
133 {
134     JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject());
135     return thisObject->methodTable(exec->vm())->deleteProperty(thisObject, exec, identifier);
136 }
137
138 bool JSCell::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned identifier)
139 {
140     JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject());
141     return thisObject->methodTable(exec->vm())->deletePropertyByIndex(thisObject, exec, identifier);
142 }
143
144 JSValue JSCell::toThis(JSCell* cell, ExecState* exec, ECMAMode ecmaMode)
145 {
146     if (ecmaMode == StrictMode)
147         return cell;
148     return cell->toObject(exec, exec->lexicalGlobalObject());
149 }
150
151 JSValue JSCell::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
152 {
153     if (isString())
154         return static_cast<const JSString*>(this)->toPrimitive(exec, preferredType);
155     if (isSymbol())
156         return static_cast<const Symbol*>(this)->toPrimitive(exec, preferredType);
157     return static_cast<const JSObject*>(this)->toPrimitive(exec, preferredType);
158 }
159
160 bool JSCell::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value) const
161 {
162     if (isString())
163         return static_cast<const JSString*>(this)->getPrimitiveNumber(exec, number, value);
164     if (isSymbol())
165         return static_cast<const Symbol*>(this)->getPrimitiveNumber(exec, number, value);
166     return static_cast<const JSObject*>(this)->getPrimitiveNumber(exec, number, value);
167 }
168
169 double JSCell::toNumber(ExecState* exec) const
170
171     if (isString())
172         return static_cast<const JSString*>(this)->toNumber(exec);
173     if (isSymbol())
174         return static_cast<const Symbol*>(this)->toNumber(exec);
175     return static_cast<const JSObject*>(this)->toNumber(exec);
176 }
177
178 JSObject* JSCell::toObject(ExecState* exec, JSGlobalObject* globalObject) const
179 {
180     if (isString())
181         return static_cast<const JSString*>(this)->toObject(exec, globalObject);
182     if (isSymbol())
183         return static_cast<const Symbol*>(this)->toObject(exec, globalObject);
184     ASSERT(isObject());
185     return jsCast<JSObject*>(const_cast<JSCell*>(this));
186 }
187
188 void slowValidateCell(JSCell* cell)
189 {
190     ASSERT_GC_OBJECT_LOOKS_VALID(cell);
191 }
192
193 JSValue JSCell::defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType)
194 {
195     RELEASE_ASSERT_NOT_REACHED();
196     return jsUndefined();
197 }
198
199 bool JSCell::getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&)
200 {
201     RELEASE_ASSERT_NOT_REACHED();
202     return false;
203 }
204
205 bool JSCell::getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned, PropertySlot&)
206 {
207     RELEASE_ASSERT_NOT_REACHED();
208     return false;
209 }
210
211 void JSCell::getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
212 {
213     RELEASE_ASSERT_NOT_REACHED();
214 }
215
216 void JSCell::getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
217 {
218     RELEASE_ASSERT_NOT_REACHED();
219 }
220
221 String JSCell::className(const JSObject*)
222 {
223     RELEASE_ASSERT_NOT_REACHED();
224     return String();
225 }
226
227 const char* JSCell::className() const
228 {
229     return classInfo()->className;
230 }
231
232 void JSCell::getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
233 {
234     RELEASE_ASSERT_NOT_REACHED();
235 }
236
237 bool JSCell::customHasInstance(JSObject*, ExecState*, JSValue)
238 {
239     RELEASE_ASSERT_NOT_REACHED();
240     return false;
241 }
242
243 bool JSCell::defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool)
244 {
245     RELEASE_ASSERT_NOT_REACHED();
246     return false;
247 }
248
249 ArrayBuffer* JSCell::slowDownAndWasteMemory(JSArrayBufferView*)
250 {
251     RELEASE_ASSERT_NOT_REACHED();
252     return 0;
253 }
254
255 PassRefPtr<ArrayBufferView> JSCell::getTypedArrayImpl(JSArrayBufferView*)
256 {
257     RELEASE_ASSERT_NOT_REACHED();
258     return 0;
259 }
260
261 uint32_t JSCell::getEnumerableLength(ExecState*, JSObject*)
262 {
263     RELEASE_ASSERT_NOT_REACHED();
264     return 0;
265 }
266
267 void JSCell::getStructurePropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
268 {
269     RELEASE_ASSERT_NOT_REACHED();
270 }
271
272 void JSCell::getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
273 {
274     RELEASE_ASSERT_NOT_REACHED();
275 }
276
277 bool JSCell::preventExtensions(JSObject*, ExecState*)
278 {
279     RELEASE_ASSERT_NOT_REACHED();
280 }
281
282 bool JSCell::isExtensible(JSObject*, ExecState*)
283 {
284     RELEASE_ASSERT_NOT_REACHED();
285 }
286
287 bool JSCell::setPrototype(JSObject*, ExecState*, JSValue, bool)
288 {
289     RELEASE_ASSERT_NOT_REACHED();
290 }
291
292 JSValue JSCell::getPrototype(JSObject*, ExecState*)
293 {
294     RELEASE_ASSERT_NOT_REACHED();
295 }
296
297 } // namespace JSC