• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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