• 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, 2004, 2005, 2006, 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 #ifndef JSObject_h
24 #define JSObject_h
25 
26 #include "ArgList.h"
27 #include "ClassInfo.h"
28 #include "CommonIdentifiers.h"
29 #include "CallFrame.h"
30 #include "JSNumberCell.h"
31 #include "PropertySlot.h"
32 #include "PutPropertySlot.h"
33 #include "ScopeChain.h"
34 #include "Structure.h"
35 
36 namespace JSC {
37 
38     class InternalFunction;
39     class PropertyNameArray;
40     class Structure;
41     struct HashEntry;
42     struct HashTable;
43 
44     // ECMA 262-3 8.6.1
45     // Property attributes
46     enum Attribute {
47         None         = 0,
48         ReadOnly     = 1 << 1,  // property can be only read, not written
49         DontEnum     = 1 << 2,  // property doesn't appear in (for .. in ..)
50         DontDelete   = 1 << 3,  // property can't be deleted
51         Function     = 1 << 4,  // property is a function - only used by static hashtables
52     };
53 
54     typedef JSValuePtr* PropertyStorage;
55 
56     class JSObject : public JSCell {
57         friend class BatchedTransitionOptimizer;
58         friend class JIT;
59         friend class JSCell;
60 
61     public:
62         explicit JSObject(PassRefPtr<Structure>);
63 
64         virtual void mark();
65 
66         // The inline virtual destructor cannot be the first virtual function declared
67         // in the class as it results in the vtable being generated as a weak symbol
68         virtual ~JSObject();
69 
inherits(const ClassInfo * classInfo)70         bool inherits(const ClassInfo* classInfo) const { return JSCell::isObject(classInfo); }
71 
72         JSValuePtr prototype() const;
73         void setPrototype(JSValuePtr prototype);
74 
75         void setStructure(PassRefPtr<Structure>);
76         Structure* inheritorID();
77 
propertyStorage()78         PropertyStorage& propertyStorage() { return m_propertyStorage; }
79 
80         virtual UString className() const;
81 
82         JSValuePtr get(ExecState*, const Identifier& propertyName) const;
83         JSValuePtr get(ExecState*, unsigned propertyName) const;
84 
85         bool getPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
86         bool getPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
87 
88         virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
89         virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
90 
91         virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr value, PutPropertySlot&);
92         virtual void put(ExecState*, unsigned propertyName, JSValuePtr value);
93 
94         virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValuePtr value, unsigned attributes);
95         virtual void putWithAttributes(ExecState*, unsigned propertyName, JSValuePtr value, unsigned attributes);
96 
97         bool propertyIsEnumerable(ExecState*, const Identifier& propertyName) const;
98 
99         bool hasProperty(ExecState*, const Identifier& propertyName) const;
100         bool hasProperty(ExecState*, unsigned propertyName) const;
101         bool hasOwnProperty(ExecState*, const Identifier& propertyName) const;
102 
103         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
104         virtual bool deleteProperty(ExecState*, unsigned propertyName);
105 
106         virtual JSValuePtr defaultValue(ExecState*, PreferredPrimitiveType) const;
107 
108         virtual bool hasInstance(ExecState*, JSValuePtr, JSValuePtr prototypeProperty);
109 
110         virtual void getPropertyNames(ExecState*, PropertyNameArray&);
111 
112         virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
113         virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value);
114         virtual bool toBoolean(ExecState*) const;
115         virtual double toNumber(ExecState*) const;
116         virtual UString toString(ExecState*) const;
117         virtual JSObject* toObject(ExecState*) const;
118 
119         virtual JSObject* toThisObject(ExecState*) const;
120         virtual JSObject* unwrappedObject();
121 
122         virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const;
123 
124         // This get function only looks at the property map.
getDirect(const Identifier & propertyName)125         JSValuePtr getDirect(const Identifier& propertyName) const
126         {
127             size_t offset = m_structure->get(propertyName);
128             return offset != WTF::notFound ? m_propertyStorage[offset] : noValue();
129         }
130 
getDirectLocation(const Identifier & propertyName)131         JSValuePtr* getDirectLocation(const Identifier& propertyName)
132         {
133             size_t offset = m_structure->get(propertyName);
134             return offset != WTF::notFound ? locationForOffset(offset) : 0;
135         }
136 
getDirectLocation(const Identifier & propertyName,unsigned & attributes)137         JSValuePtr* getDirectLocation(const Identifier& propertyName, unsigned& attributes)
138         {
139             size_t offset = m_structure->get(propertyName, attributes);
140             return offset != WTF::notFound ? locationForOffset(offset) : 0;
141         }
142 
offsetForLocation(JSValuePtr * location)143         size_t offsetForLocation(JSValuePtr* location)
144         {
145             return location - m_propertyStorage;
146         }
147 
locationForOffset(size_t offset)148         JSValuePtr* locationForOffset(size_t offset)
149         {
150             return &m_propertyStorage[offset];
151         }
152 
153         void transitionTo(Structure*);
154 
155         void removeDirect(const Identifier& propertyName);
hasCustomProperties()156         bool hasCustomProperties() { return !m_structure->isEmpty(); }
hasGetterSetterProperties()157         bool hasGetterSetterProperties() { return m_structure->hasGetterSetterProperties(); }
158 
159         void putDirect(const Identifier& propertyName, JSValuePtr value, unsigned attr = 0);
160         void putDirect(const Identifier& propertyName, JSValuePtr value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
161         void putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr = 0);
162         void putDirectWithoutTransition(const Identifier& propertyName, JSValuePtr value, unsigned attr = 0);
163         void putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr = 0);
164 
165         // Fast access to known property offsets.
getDirectOffset(size_t offset)166         JSValuePtr getDirectOffset(size_t offset) { return m_propertyStorage[offset]; }
putDirectOffset(size_t offset,JSValuePtr value)167         void putDirectOffset(size_t offset, JSValuePtr value) { m_propertyStorage[offset] = value; }
168 
169         void fillGetterPropertySlot(PropertySlot&, JSValuePtr* location);
170 
171         virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction);
172         virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction);
173         virtual JSValuePtr lookupGetter(ExecState*, const Identifier& propertyName);
174         virtual JSValuePtr lookupSetter(ExecState*, const Identifier& propertyName);
175 
isGlobalObject()176         virtual bool isGlobalObject() const { return false; }
isVariableObject()177         virtual bool isVariableObject() const { return false; }
isActivationObject()178         virtual bool isActivationObject() const { return false; }
isWatchdogException()179         virtual bool isWatchdogException() const { return false; }
isNotAnObjectErrorStub()180         virtual bool isNotAnObjectErrorStub() const { return false; }
181 
182         void allocatePropertyStorage(size_t oldSize, size_t newSize);
183         void allocatePropertyStorageInline(size_t oldSize, size_t newSize);
usingInlineStorage()184         bool usingInlineStorage() const { return m_propertyStorage == m_inlineStorage; }
185 
186         static const size_t inlineStorageCapacity = 2;
187         static const size_t nonInlineBaseStorageCapacity = 16;
188 
createStructure(JSValuePtr prototype)189         static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
190         {
191             return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
192         }
193 
194     protected:
195         bool getOwnPropertySlotForWrite(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
196 
197     private:
198         bool inlineGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
199 
200         const HashEntry* findPropertyHashEntry(ExecState*, const Identifier& propertyName) const;
201         Structure* createInheritorID();
202 
203         RefPtr<Structure> m_inheritorID;
204 
205         PropertyStorage m_propertyStorage;
206         JSValuePtr m_inlineStorage[inlineStorageCapacity];
207     };
208 
209     JSObject* asObject(JSValuePtr);
210 
211     JSObject* constructEmptyObject(ExecState*);
212 
asObject(JSValuePtr value)213 inline JSObject* asObject(JSValuePtr value)
214 {
215     ASSERT(asCell(value)->isObject());
216     return static_cast<JSObject*>(asCell(value));
217 }
218 
JSObject(PassRefPtr<Structure> structure)219 inline JSObject::JSObject(PassRefPtr<Structure> structure)
220     : JSCell(structure.releaseRef()) // ~JSObject balances this ref()
221     , m_propertyStorage(m_inlineStorage)
222 {
223     ASSERT(m_structure);
224     ASSERT(m_structure->propertyStorageCapacity() == inlineStorageCapacity);
225     ASSERT(m_structure->isEmpty());
226     ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype()));
227 }
228 
~JSObject()229 inline JSObject::~JSObject()
230 {
231     ASSERT(m_structure);
232     if (m_propertyStorage != m_inlineStorage)
233         delete [] m_propertyStorage;
234     m_structure->deref();
235 }
236 
prototype()237 inline JSValuePtr JSObject::prototype() const
238 {
239     return m_structure->storedPrototype();
240 }
241 
setPrototype(JSValuePtr prototype)242 inline void JSObject::setPrototype(JSValuePtr prototype)
243 {
244     ASSERT(prototype);
245     RefPtr<Structure> newStructure = Structure::changePrototypeTransition(m_structure, prototype);
246     setStructure(newStructure.release());
247 }
248 
setStructure(PassRefPtr<Structure> structure)249 inline void JSObject::setStructure(PassRefPtr<Structure> structure)
250 {
251     m_structure->deref();
252     m_structure = structure.releaseRef(); // ~JSObject balances this ref()
253 }
254 
inheritorID()255 inline Structure* JSObject::inheritorID()
256 {
257     if (m_inheritorID)
258         return m_inheritorID.get();
259     return createInheritorID();
260 }
261 
isObject(const ClassInfo * info)262 inline bool JSCell::isObject(const ClassInfo* info) const
263 {
264     for (const ClassInfo* ci = classInfo(); ci; ci = ci->parentClass) {
265         if (ci == info)
266             return true;
267     }
268     return false;
269 }
270 
271 // this method is here to be after the inline declaration of JSCell::isObject
isObject(const ClassInfo * classInfo)272 inline bool JSValuePtr::isObject(const ClassInfo* classInfo) const
273 {
274     return isCell() && asCell()->isObject(classInfo);
275 }
276 
inlineGetOwnPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)277 ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
278 {
279     if (JSValuePtr* location = getDirectLocation(propertyName)) {
280         if (m_structure->hasGetterSetterProperties() && location[0].isGetterSetter())
281             fillGetterPropertySlot(slot, location);
282         else
283             slot.setValueSlot(this, location, offsetForLocation(location));
284         return true;
285     }
286 
287     // non-standard Netscape extension
288     if (propertyName == exec->propertyNames().underscoreProto) {
289         slot.setValue(prototype());
290         return true;
291     }
292 
293     return false;
294 }
295 
getOwnPropertySlotForWrite(ExecState * exec,const Identifier & propertyName,PropertySlot & slot,bool & slotIsWriteable)296 ALWAYS_INLINE bool JSObject::getOwnPropertySlotForWrite(ExecState* exec, const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
297 {
298     unsigned attributes;
299     if (JSValuePtr* location = getDirectLocation(propertyName, attributes)) {
300         if (m_structure->hasGetterSetterProperties() && location[0].isGetterSetter()) {
301             slotIsWriteable = false;
302             fillGetterPropertySlot(slot, location);
303         } else {
304             slotIsWriteable = !(attributes & ReadOnly);
305             slot.setValueSlot(this, location, offsetForLocation(location));
306         }
307         return true;
308     }
309 
310     // non-standard Netscape extension
311     if (propertyName == exec->propertyNames().underscoreProto) {
312         slot.setValue(prototype());
313         slotIsWriteable = false;
314         return true;
315     }
316 
317     return false;
318 }
319 
320 // It may seem crazy to inline a function this large, especially a virtual function,
321 // but it makes a big difference to property lookup that derived classes can inline their
322 // base class call to this.
getOwnPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)323 ALWAYS_INLINE bool JSObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
324 {
325     return inlineGetOwnPropertySlot(exec, propertyName, slot);
326 }
327 
fastGetOwnPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)328 ALWAYS_INLINE bool JSCell::fastGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
329 {
330     if (structure()->typeInfo().hasStandardGetOwnPropertySlot())
331         return asObject(this)->inlineGetOwnPropertySlot(exec, propertyName, slot);
332     return getOwnPropertySlot(exec, propertyName, slot);
333 }
334 
335 // It may seem crazy to inline a function this large but it makes a big difference
336 // since this is function very hot in variable lookup
getPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)337 inline bool JSObject::getPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
338 {
339     JSObject* object = this;
340     while (true) {
341         if (object->fastGetOwnPropertySlot(exec, propertyName, slot))
342             return true;
343         JSValuePtr prototype = object->prototype();
344         if (!prototype.isObject())
345             return false;
346         object = asObject(prototype);
347     }
348 }
349 
getPropertySlot(ExecState * exec,unsigned propertyName,PropertySlot & slot)350 inline bool JSObject::getPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
351 {
352     JSObject* object = this;
353     while (true) {
354         if (object->getOwnPropertySlot(exec, propertyName, slot))
355             return true;
356         JSValuePtr prototype = object->prototype();
357         if (!prototype.isObject())
358             return false;
359         object = asObject(prototype);
360     }
361 }
362 
get(ExecState * exec,const Identifier & propertyName)363 inline JSValuePtr JSObject::get(ExecState* exec, const Identifier& propertyName) const
364 {
365     PropertySlot slot(this);
366     if (const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot))
367         return slot.getValue(exec, propertyName);
368 
369     return jsUndefined();
370 }
371 
get(ExecState * exec,unsigned propertyName)372 inline JSValuePtr JSObject::get(ExecState* exec, unsigned propertyName) const
373 {
374     PropertySlot slot(this);
375     if (const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot))
376         return slot.getValue(exec, propertyName);
377 
378     return jsUndefined();
379 }
380 
putDirect(const Identifier & propertyName,JSValuePtr value,unsigned attr)381 inline void JSObject::putDirect(const Identifier& propertyName, JSValuePtr value, unsigned attr)
382 {
383     PutPropertySlot slot;
384     putDirect(propertyName, value, attr, false, slot);
385 }
386 
putDirect(const Identifier & propertyName,JSValuePtr value,unsigned attributes,bool checkReadOnly,PutPropertySlot & slot)387 inline void JSObject::putDirect(const Identifier& propertyName, JSValuePtr value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
388 {
389     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
390 
391     if (m_structure->isDictionary()) {
392         unsigned currentAttributes;
393         size_t offset = m_structure->get(propertyName, currentAttributes);
394         if (offset != WTF::notFound) {
395             if (checkReadOnly && currentAttributes & ReadOnly)
396                 return;
397             m_propertyStorage[offset] = value;
398             slot.setExistingProperty(this, offset);
399             return;
400         }
401 
402         size_t currentCapacity = m_structure->propertyStorageCapacity();
403         offset = m_structure->addPropertyWithoutTransition(propertyName, attributes);
404         if (currentCapacity != m_structure->propertyStorageCapacity())
405             allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
406 
407         ASSERT(offset < m_structure->propertyStorageCapacity());
408         m_propertyStorage[offset] = value;
409         slot.setNewProperty(this, offset);
410         return;
411     }
412 
413     size_t offset;
414     size_t currentCapacity = m_structure->propertyStorageCapacity();
415     if (RefPtr<Structure> structure = Structure::addPropertyTransitionToExistingStructure(m_structure, propertyName, attributes, offset)) {
416         if (currentCapacity != structure->propertyStorageCapacity())
417             allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
418 
419         ASSERT(offset < structure->propertyStorageCapacity());
420         m_propertyStorage[offset] = value;
421         slot.setNewProperty(this, offset);
422         slot.setWasTransition(true);
423         setStructure(structure.release());
424         return;
425     }
426 
427     unsigned currentAttributes;
428     offset = m_structure->get(propertyName, currentAttributes);
429     if (offset != WTF::notFound) {
430         if (checkReadOnly && currentAttributes & ReadOnly)
431             return;
432         m_propertyStorage[offset] = value;
433         slot.setExistingProperty(this, offset);
434         return;
435     }
436 
437     RefPtr<Structure> structure = Structure::addPropertyTransition(m_structure, propertyName, attributes, offset);
438     if (currentCapacity != structure->propertyStorageCapacity())
439         allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
440 
441     ASSERT(offset < structure->propertyStorageCapacity());
442     m_propertyStorage[offset] = value;
443     slot.setNewProperty(this, offset);
444     slot.setWasTransition(true);
445     setStructure(structure.release());
446 }
447 
putDirectWithoutTransition(const Identifier & propertyName,JSValuePtr value,unsigned attributes)448 inline void JSObject::putDirectWithoutTransition(const Identifier& propertyName, JSValuePtr value, unsigned attributes)
449 {
450     size_t currentCapacity = m_structure->propertyStorageCapacity();
451     size_t offset = m_structure->addPropertyWithoutTransition(propertyName, attributes);
452     if (currentCapacity != m_structure->propertyStorageCapacity())
453         allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
454     m_propertyStorage[offset] = value;
455 }
456 
transitionTo(Structure * newStructure)457 inline void JSObject::transitionTo(Structure* newStructure)
458 {
459     if (m_structure->propertyStorageCapacity() != newStructure->propertyStorageCapacity())
460         allocatePropertyStorage(m_structure->propertyStorageCapacity(), newStructure->propertyStorageCapacity());
461     setStructure(newStructure);
462 }
463 
toPrimitive(ExecState * exec,PreferredPrimitiveType preferredType)464 inline JSValuePtr JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
465 {
466     return defaultValue(exec, preferredType);
467 }
468 
get(ExecState * exec,const Identifier & propertyName)469 inline JSValuePtr JSValuePtr::get(ExecState* exec, const Identifier& propertyName) const
470 {
471     PropertySlot slot(asValue());
472     return get(exec, propertyName, slot);
473 }
474 
get(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)475 inline JSValuePtr JSValuePtr::get(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) const
476 {
477     if (UNLIKELY(!isCell())) {
478         JSObject* prototype = JSImmediate::prototype(asValue(), exec);
479         if (!prototype->getPropertySlot(exec, propertyName, slot))
480             return jsUndefined();
481         return slot.getValue(exec, propertyName);
482     }
483     JSCell* cell = asCell();
484     while (true) {
485         if (cell->fastGetOwnPropertySlot(exec, propertyName, slot))
486             return slot.getValue(exec, propertyName);
487         ASSERT(cell->isObject());
488         JSValuePtr prototype = static_cast<JSObject*>(cell)->prototype();
489         if (!prototype.isObject())
490             return jsUndefined();
491         cell = asObject(prototype);
492     }
493 }
494 
get(ExecState * exec,unsigned propertyName)495 inline JSValuePtr JSValuePtr::get(ExecState* exec, unsigned propertyName) const
496 {
497     PropertySlot slot(asValue());
498     return get(exec, propertyName, slot);
499 }
500 
get(ExecState * exec,unsigned propertyName,PropertySlot & slot)501 inline JSValuePtr JSValuePtr::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const
502 {
503     if (UNLIKELY(!isCell())) {
504         JSObject* prototype = JSImmediate::prototype(asValue(), exec);
505         if (!prototype->getPropertySlot(exec, propertyName, slot))
506             return jsUndefined();
507         return slot.getValue(exec, propertyName);
508     }
509     JSCell* cell = const_cast<JSCell*>(asCell());
510     while (true) {
511         if (cell->getOwnPropertySlot(exec, propertyName, slot))
512             return slot.getValue(exec, propertyName);
513         ASSERT(cell->isObject());
514         JSValuePtr prototype = static_cast<JSObject*>(cell)->prototype();
515         if (!prototype.isObject())
516             return jsUndefined();
517         cell = prototype.asCell();
518     }
519 }
520 
put(ExecState * exec,const Identifier & propertyName,JSValuePtr value,PutPropertySlot & slot)521 inline void JSValuePtr::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
522 {
523     if (UNLIKELY(!isCell())) {
524         JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value, slot);
525         return;
526     }
527     asCell()->put(exec, propertyName, value, slot);
528 }
529 
put(ExecState * exec,unsigned propertyName,JSValuePtr value)530 inline void JSValuePtr::put(ExecState* exec, unsigned propertyName, JSValuePtr value)
531 {
532     if (UNLIKELY(!isCell())) {
533         JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value);
534         return;
535     }
536     asCell()->put(exec, propertyName, value);
537 }
538 
allocatePropertyStorageInline(size_t oldSize,size_t newSize)539 ALWAYS_INLINE void JSObject::allocatePropertyStorageInline(size_t oldSize, size_t newSize)
540 {
541     ASSERT(newSize > oldSize);
542 
543     JSValuePtr* oldPropertyStorage = m_propertyStorage;
544     m_propertyStorage = new JSValuePtr[newSize];
545 
546     for (unsigned i = 0; i < oldSize; ++i)
547         m_propertyStorage[i] = oldPropertyStorage[i];
548 
549     if (oldPropertyStorage != m_inlineStorage)
550         delete [] oldPropertyStorage;
551 }
552 
553 } // namespace JSC
554 
555 #endif // JSObject_h
556