694081db5f17784a54a48e085bad6e13d89f09c8
[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()) {
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()) {
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     return static_cast<const JSObject*>(this)->toPrimitive(exec, preferredType);
142 }
143
144 bool JSCell::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value) const
145 {
146     if (isString())
147         return static_cast<const JSString*>(this)->getPrimitiveNumber(exec, number, value);
148     return static_cast<const JSObject*>(this)->getPrimitiveNumber(exec, number, value);
149 }
150
151 double JSCell::toNumber(ExecState* exec) const
152
153     if (isString())
154         return static_cast<const JSString*>(this)->toNumber(exec);
155     return static_cast<const JSObject*>(this)->toNumber(exec);
156 }
157
158 JSObject* JSCell::toObject(ExecState* exec, JSGlobalObject* globalObject) const
159 {
160     if (isString())
161         return static_cast<const JSString*>(this)->toObject(exec, globalObject);
162     ASSERT(isObject());
163     return jsCast<JSObject*>(const_cast<JSCell*>(this));
164 }
165
166 void slowValidateCell(JSCell* cell)
167 {
168     ASSERT_GC_OBJECT_LOOKS_VALID(cell);
169 }
170
171 JSValue JSCell::defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType)
172 {
173     RELEASE_ASSERT_NOT_REACHED();
174     return jsUndefined();
175 }
176
177 bool JSCell::getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&)
178 {
179     RELEASE_ASSERT_NOT_REACHED();
180     return false;
181 }
182
183 bool JSCell::getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned, PropertySlot&)
184 {
185     RELEASE_ASSERT_NOT_REACHED();
186     return false;
187 }
188
189 void JSCell::getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
190 {
191     RELEASE_ASSERT_NOT_REACHED();
192 }
193
194 void JSCell::getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
195 {
196     RELEASE_ASSERT_NOT_REACHED();
197 }
198
199 String JSCell::className(const JSObject*)
200 {
201     RELEASE_ASSERT_NOT_REACHED();
202     return String();
203 }
204
205 const char* JSCell::className() const
206 {
207     return classInfo()->className;
208 }
209
210 void JSCell::getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
211 {
212     RELEASE_ASSERT_NOT_REACHED();
213 }
214
215 bool JSCell::customHasInstance(JSObject*, ExecState*, JSValue)
216 {
217     RELEASE_ASSERT_NOT_REACHED();
218     return false;
219 }
220
221 bool JSCell::defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool)
222 {
223     RELEASE_ASSERT_NOT_REACHED();
224     return false;
225 }
226
227 ArrayBuffer* JSCell::slowDownAndWasteMemory(JSArrayBufferView*)
228 {
229     RELEASE_ASSERT_NOT_REACHED();
230     return 0;
231 }
232
233 PassRefPtr<ArrayBufferView> JSCell::getTypedArrayImpl(JSArrayBufferView*)
234 {
235     RELEASE_ASSERT_NOT_REACHED();
236     return 0;
237 }
238
239 uint32_t JSCell::getEnumerableLength(ExecState*, JSObject*)
240 {
241     RELEASE_ASSERT_NOT_REACHED();
242     return 0;
243 }
244
245 void JSCell::getStructurePropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
246 {
247     RELEASE_ASSERT_NOT_REACHED();
248 }
249
250 void JSCell::getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
251 {
252     RELEASE_ASSERT_NOT_REACHED();
253 }
254
255 } // namespace JSC