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 34namespace JSC { 35 36COMPILE_ASSERT(sizeof(JSCell) == sizeof(uint64_t), jscell_is_eight_bytes); 37STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSCell); 38 39void JSCell::destroy(JSCell* cell) 40{ 41 cell->JSCell::~JSCell(); 42} 43 44void JSCell::dump(PrintStream& out) const 45{ 46 methodTable()->dumpToStream(this, out); 47} 48 49void JSCell::dumpToStream(const JSCell* cell, PrintStream& out) 50{ 51 out.printf("<%p, %s>", cell, cell->className()); 52} 53 54void JSCell::copyBackingStore(JSCell*, CopyVisitor&, CopyToken) 55{ 56} 57 58bool 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 66String JSCell::getString(ExecState* exec) const 67{ 68 return isString() ? static_cast<const JSString*>(this)->value(exec) : String(); 69} 70 71JSObject* JSCell::getObject() 72{ 73 return isObject() ? asObject(this) : 0; 74} 75 76const JSObject* JSCell::getObject() const 77{ 78 return isObject() ? static_cast<const JSObject*>(this) : 0; 79} 80 81CallType 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 89ConstructType 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 97void 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 107void 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 118bool 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 124bool 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 130JSValue 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 137JSValue 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 144bool 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 151double 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 158JSObject* 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 166void slowValidateCell(JSCell* cell) 167{ 168 ASSERT_GC_OBJECT_LOOKS_VALID(cell); 169} 170 171JSValue JSCell::defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType) 172{ 173 RELEASE_ASSERT_NOT_REACHED(); 174 return jsUndefined(); 175} 176 177bool JSCell::getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&) 178{ 179 RELEASE_ASSERT_NOT_REACHED(); 180 return false; 181} 182 183bool JSCell::getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned, PropertySlot&) 184{ 185 RELEASE_ASSERT_NOT_REACHED(); 186 return false; 187} 188 189void JSCell::getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode) 190{ 191 RELEASE_ASSERT_NOT_REACHED(); 192} 193 194void JSCell::getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode) 195{ 196 RELEASE_ASSERT_NOT_REACHED(); 197} 198 199String JSCell::className(const JSObject*) 200{ 201 RELEASE_ASSERT_NOT_REACHED(); 202 return String(); 203} 204 205const char* JSCell::className() const 206{ 207 return classInfo()->className; 208} 209 210void JSCell::getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode) 211{ 212 RELEASE_ASSERT_NOT_REACHED(); 213} 214 215bool JSCell::customHasInstance(JSObject*, ExecState*, JSValue) 216{ 217 RELEASE_ASSERT_NOT_REACHED(); 218 return false; 219} 220 221bool JSCell::defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool) 222{ 223 RELEASE_ASSERT_NOT_REACHED(); 224 return false; 225} 226 227ArrayBuffer* JSCell::slowDownAndWasteMemory(JSArrayBufferView*) 228{ 229 RELEASE_ASSERT_NOT_REACHED(); 230 return 0; 231} 232 233PassRefPtr<ArrayBufferView> JSCell::getTypedArrayImpl(JSArrayBufferView*) 234{ 235 RELEASE_ASSERT_NOT_REACHED(); 236 return 0; 237} 238 239} // namespace JSC 240