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 "JSFunction.h" 27 #include "JSString.h" 28 #include "JSObject.h" 29 #include <wtf/MathExtras.h> 30 31 namespace JSC { 32 33 #if defined NAN && defined INFINITY 34 35 extern const double NaN = NAN; 36 extern const double Inf = INFINITY; 37 38 #else // !(defined NAN && defined INFINITY) 39 40 // The trick is to define the NaN and Inf globals with a different type than the declaration. 41 // This trick works because the mangled name of the globals does not include the type, although 42 // I'm not sure that's guaranteed. There could be alignment issues with this, since arrays of 43 // characters don't necessarily need the same alignment doubles do, but for now it seems to work. 44 // It would be good to figure out a 100% clean way that still avoids code that runs at init time. 45 46 // Note, we have to use union to ensure alignment. Otherwise, NaN_Bytes can start anywhere, 47 // while NaN_double has to be 4-byte aligned for 32-bits. 48 // With -fstrict-aliasing enabled, unions are the only safe way to do type masquerading. 49 50 static const union { 51 struct { 52 unsigned char NaN_Bytes[8]; 53 unsigned char Inf_Bytes[8]; 54 } bytes; 55 56 struct { 57 double NaN_Double; 58 double Inf_Double; 59 } doubles; 60 61 } NaNInf = { { 62 #if CPU(BIG_ENDIAN) 63 { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }, 64 { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } 65 #elif CPU(MIDDLE_ENDIAN) 66 { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 }, 67 { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 } 68 #else 69 { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }, 70 { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } 71 #endif 72 } } ; 73 74 extern const double NaN = NaNInf.doubles.NaN_Double; 75 extern const double Inf = NaNInf.doubles.Inf_Double; 76 77 #endif // !(defined NAN && defined INFINITY) 78 getUInt32(uint32_t &) const79 bool JSCell::getUInt32(uint32_t&) const 80 { 81 return false; 82 } 83 getString(ExecState * exec,UString & stringValue) const84 bool JSCell::getString(ExecState* exec, UString&stringValue) const 85 { 86 if (!isString()) 87 return false; 88 stringValue = static_cast<const JSString*>(this)->value(exec); 89 return true; 90 } 91 getString(ExecState * exec) const92 UString JSCell::getString(ExecState* exec) const 93 { 94 return isString() ? static_cast<const JSString*>(this)->value(exec) : UString(); 95 } 96 getObject()97 JSObject* JSCell::getObject() 98 { 99 return isObject() ? asObject(this) : 0; 100 } 101 getObject() const102 const JSObject* JSCell::getObject() const 103 { 104 return isObject() ? static_cast<const JSObject*>(this) : 0; 105 } 106 getCallData(CallData &)107 CallType JSCell::getCallData(CallData&) 108 { 109 return CallTypeNone; 110 } 111 getConstructData(ConstructData &)112 ConstructType JSCell::getConstructData(ConstructData&) 113 { 114 return ConstructTypeNone; 115 } 116 getOwnPropertySlot(ExecState * exec,const Identifier & identifier,PropertySlot & slot)117 bool JSCell::getOwnPropertySlot(ExecState* exec, const Identifier& identifier, PropertySlot& slot) 118 { 119 // This is not a general purpose implementation of getOwnPropertySlot. 120 // It should only be called by JSValue::get. 121 // It calls getPropertySlot, not getOwnPropertySlot. 122 JSObject* object = toObject(exec, exec->lexicalGlobalObject()); 123 slot.setBase(object); 124 if (!object->getPropertySlot(exec, identifier, slot)) 125 slot.setUndefined(); 126 return true; 127 } 128 getOwnPropertySlot(ExecState * exec,unsigned identifier,PropertySlot & slot)129 bool JSCell::getOwnPropertySlot(ExecState* exec, unsigned identifier, PropertySlot& slot) 130 { 131 // This is not a general purpose implementation of getOwnPropertySlot. 132 // It should only be called by JSValue::get. 133 // It calls getPropertySlot, not getOwnPropertySlot. 134 JSObject* object = toObject(exec, exec->lexicalGlobalObject()); 135 slot.setBase(object); 136 if (!object->getPropertySlot(exec, identifier, slot)) 137 slot.setUndefined(); 138 return true; 139 } 140 put(ExecState * exec,const Identifier & identifier,JSValue value,PutPropertySlot & slot)141 void JSCell::put(ExecState* exec, const Identifier& identifier, JSValue value, PutPropertySlot& slot) 142 { 143 toObject(exec, exec->lexicalGlobalObject())->put(exec, identifier, value, slot); 144 } 145 put(ExecState * exec,unsigned identifier,JSValue value)146 void JSCell::put(ExecState* exec, unsigned identifier, JSValue value) 147 { 148 toObject(exec, exec->lexicalGlobalObject())->put(exec, identifier, value); 149 } 150 deleteProperty(ExecState * exec,const Identifier & identifier)151 bool JSCell::deleteProperty(ExecState* exec, const Identifier& identifier) 152 { 153 return toObject(exec, exec->lexicalGlobalObject())->deleteProperty(exec, identifier); 154 } 155 deleteProperty(ExecState * exec,unsigned identifier)156 bool JSCell::deleteProperty(ExecState* exec, unsigned identifier) 157 { 158 return toObject(exec, exec->lexicalGlobalObject())->deleteProperty(exec, identifier); 159 } 160 toThisObject(ExecState * exec) const161 JSObject* JSCell::toThisObject(ExecState* exec) const 162 { 163 return toObject(exec, exec->lexicalGlobalObject()); 164 } 165 getJSNumber()166 JSValue JSCell::getJSNumber() 167 { 168 return JSValue(); 169 } 170 isGetterSetter() const171 bool JSCell::isGetterSetter() const 172 { 173 return false; 174 } 175 toPrimitive(ExecState *,PreferredPrimitiveType) const176 JSValue JSCell::toPrimitive(ExecState*, PreferredPrimitiveType) const 177 { 178 ASSERT_NOT_REACHED(); 179 return JSValue(); 180 } 181 getPrimitiveNumber(ExecState *,double &,JSValue &)182 bool JSCell::getPrimitiveNumber(ExecState*, double&, JSValue&) 183 { 184 ASSERT_NOT_REACHED(); 185 return false; 186 } 187 toBoolean(ExecState *) const188 bool JSCell::toBoolean(ExecState*) const 189 { 190 ASSERT_NOT_REACHED(); 191 return false; 192 } 193 toNumber(ExecState *) const194 double JSCell::toNumber(ExecState*) const 195 { 196 ASSERT_NOT_REACHED(); 197 return 0; 198 } 199 toString(ExecState *) const200 UString JSCell::toString(ExecState*) const 201 { 202 ASSERT_NOT_REACHED(); 203 return UString(); 204 } 205 toObject(ExecState *,JSGlobalObject *) const206 JSObject* JSCell::toObject(ExecState*, JSGlobalObject*) const 207 { 208 ASSERT_NOT_REACHED(); 209 return 0; 210 } 211 isZombie(const JSCell * cell)212 bool isZombie(const JSCell* cell) 213 { 214 #if ENABLE(JSC_ZOMBIES) 215 return cell && cell->isZombie(); 216 #else 217 UNUSED_PARAM(cell); 218 return false; 219 #endif 220 } 221 222 } // namespace JSC 223