| 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 |  | 
| 79 | bool JSCell::getUInt32(uint32_t&) const | 
| 80 | { | 
| 81 |     return false; | 
| 82 | } | 
| 83 |  | 
| 84 | 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 |  | 
| 92 | UString JSCell::getString(ExecState* exec) const | 
| 93 | { | 
| 94 |     return isString() ? static_cast<const JSString*>(this)->value(exec) : UString(); | 
| 95 | } | 
| 96 |  | 
| 97 | JSObject* JSCell::getObject() | 
| 98 | { | 
| 99 |     return isObject() ? asObject(cell: this) : 0; | 
| 100 | } | 
| 101 |  | 
| 102 | const JSObject* JSCell::getObject() const | 
| 103 | { | 
| 104 |     return isObject() ? static_cast<const JSObject*>(this) : 0; | 
| 105 | } | 
| 106 |  | 
| 107 | CallType JSCell::getCallData(CallData&) | 
| 108 | { | 
| 109 |     return CallTypeNone; | 
| 110 | } | 
| 111 |  | 
| 112 | ConstructType JSCell::getConstructData(ConstructData&) | 
| 113 | { | 
| 114 |     return ConstructTypeNone; | 
| 115 | } | 
| 116 |  | 
| 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); | 
| 123 |     slot.setBase(object); | 
| 124 |     if (!object->getPropertySlot(exec, propertyName: identifier, slot)) | 
| 125 |         slot.setUndefined(); | 
| 126 |     return true; | 
| 127 | } | 
| 128 |  | 
| 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); | 
| 135 |     slot.setBase(object); | 
| 136 |     if (!object->getPropertySlot(exec, propertyName: identifier, slot)) | 
| 137 |         slot.setUndefined(); | 
| 138 |     return true; | 
| 139 | } | 
| 140 |  | 
| 141 | void JSCell::put(ExecState* exec, const Identifier& identifier, JSValue value, PutPropertySlot& slot) | 
| 142 | { | 
| 143 |     toObject(exec)->put(exec, propertyName: identifier, value, slot); | 
| 144 | } | 
| 145 |  | 
| 146 | void JSCell::put(ExecState* exec, unsigned identifier, JSValue value) | 
| 147 | { | 
| 148 |     toObject(exec)->put(exec, propertyName: identifier, value); | 
| 149 | } | 
| 150 |  | 
| 151 | bool JSCell::deleteProperty(ExecState* exec, const Identifier& identifier) | 
| 152 | { | 
| 153 |     return toObject(exec)->deleteProperty(exec, propertyName: identifier); | 
| 154 | } | 
| 155 |  | 
| 156 | bool JSCell::deleteProperty(ExecState* exec, unsigned identifier) | 
| 157 | { | 
| 158 |     return toObject(exec)->deleteProperty(exec, propertyName: identifier); | 
| 159 | } | 
| 160 |  | 
| 161 | JSObject* JSCell::toThisObject(ExecState* exec) const | 
| 162 | { | 
| 163 |     return toObject(exec); | 
| 164 | } | 
| 165 |  | 
| 166 | UString JSCell::toThisString(ExecState* exec) const | 
| 167 | { | 
| 168 |     return toThisObject(exec)->toString(exec); | 
| 169 | } | 
| 170 |  | 
| 171 | JSString* JSCell::toThisJSString(ExecState* exec) | 
| 172 | { | 
| 173 |     return jsString(exec, s: toThisString(exec)); | 
| 174 | } | 
| 175 |  | 
| 176 | const ClassInfo* JSCell::classInfo() const | 
| 177 | { | 
| 178 |     return 0; | 
| 179 | } | 
| 180 |  | 
| 181 | JSValue JSCell::getJSNumber() | 
| 182 | { | 
| 183 |     return JSValue(); | 
| 184 | } | 
| 185 |  | 
| 186 | bool JSCell::isGetterSetter() const | 
| 187 | { | 
| 188 |     return false; | 
| 189 | } | 
| 190 |  | 
| 191 | JSValue JSCell::toPrimitive(ExecState*, PreferredPrimitiveType) const | 
| 192 | { | 
| 193 |     ASSERT_NOT_REACHED(); | 
| 194 |     return JSValue(); | 
| 195 | } | 
| 196 |  | 
| 197 | bool JSCell::getPrimitiveNumber(ExecState*, double&, JSValue&) | 
| 198 | { | 
| 199 |     ASSERT_NOT_REACHED(); | 
| 200 |     return false; | 
| 201 | } | 
| 202 |  | 
| 203 | bool JSCell::toBoolean(ExecState*) const | 
| 204 | { | 
| 205 |     ASSERT_NOT_REACHED(); | 
| 206 |     return false; | 
| 207 | } | 
| 208 |  | 
| 209 | double JSCell::toNumber(ExecState*) const | 
| 210 | { | 
| 211 |     ASSERT_NOT_REACHED(); | 
| 212 |     return 0; | 
| 213 | } | 
| 214 |  | 
| 215 | UString JSCell::toString(ExecState*) const | 
| 216 | { | 
| 217 |     ASSERT_NOT_REACHED(); | 
| 218 |     return UString(); | 
| 219 | } | 
| 220 |  | 
| 221 | JSObject* JSCell::toObject(ExecState*) const | 
| 222 | { | 
| 223 |     ASSERT_NOT_REACHED(); | 
| 224 |     return 0; | 
| 225 | } | 
| 226 |  | 
| 227 | } // namespace JSC | 
| 228 |  |