2 * Copyright (C) 2012 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef JSCellInlines_h
27 #define JSCellInlines_h
29 #include "CallFrame.h"
34 #include "Structure.h"
38 inline JSCell::JSCell(CreatingEarlyCellTag
)
42 inline JSCell::JSCell(VM
& vm
, Structure
* structure
)
43 : m_structure(vm
, this, structure
)
47 inline void JSCell::finishCreation(VM
& vm
)
49 #if ENABLE(GC_VALIDATION)
50 ASSERT(vm
.isInitializingObject());
51 vm
.setInitializingObjectClass(0);
58 inline void JSCell::finishCreation(VM
& vm
, Structure
* structure
, CreatingEarlyCellTag
)
60 #if ENABLE(GC_VALIDATION)
61 ASSERT(vm
.isInitializingObject());
62 vm
.setInitializingObjectClass(0);
65 m_structure
.setEarlyValue(vm
, this, structure
);
66 // Very first set of allocations won't have a real structure.
67 ASSERT(m_structure
|| !vm
.structureStructure
);
70 inline Structure
* JSCell::structure() const
72 return m_structure
.get();
75 inline void JSCell::visitChildren(JSCell
* cell
, SlotVisitor
& visitor
)
77 MARK_LOG_PARENT(visitor
, cell
);
79 visitor
.append(&cell
->m_structure
);
83 void* allocateCell(Heap
& heap
, size_t size
)
85 ASSERT(size
>= sizeof(T
));
86 #if ENABLE(GC_VALIDATION)
87 ASSERT(!heap
.vm()->isInitializingObject());
88 heap
.vm()->setInitializingObjectClass(&T::s_info
);
91 if (T::needsDestruction
&& T::hasImmortalStructure
)
92 result
= static_cast<JSCell
*>(heap
.allocateWithImmortalStructureDestructor(size
));
93 else if (T::needsDestruction
)
94 result
= static_cast<JSCell
*>(heap
.allocateWithNormalDestructor(size
));
96 result
= static_cast<JSCell
*>(heap
.allocateWithoutDestructor(size
));
97 result
->clearStructure();
102 void* allocateCell(Heap
& heap
)
104 return allocateCell
<T
>(heap
, sizeof(T
));
107 inline bool isZapped(const JSCell
* cell
)
109 return cell
->isZapped();
112 inline bool JSCell::isObject() const
114 return m_structure
->isObject();
117 inline bool JSCell::isString() const
119 return m_structure
->typeInfo().type() == StringType
;
122 inline bool JSCell::isGetterSetter() const
124 return m_structure
->typeInfo().type() == GetterSetterType
;
127 inline bool JSCell::isProxy() const
129 return structure()->typeInfo().type() == ProxyType
;
132 inline bool JSCell::isAPIValueWrapper() const
134 return m_structure
->typeInfo().type() == APIValueWrapperType
;
137 inline void JSCell::setStructure(VM
& vm
, Structure
* structure
)
139 ASSERT(structure
->typeInfo().overridesVisitChildren() == this->structure()->typeInfo().overridesVisitChildren());
140 ASSERT(structure
->classInfo() == m_structure
->classInfo());
142 || m_structure
->transitionWatchpointSetHasBeenInvalidated()
143 || m_structure
.get() == structure
);
144 m_structure
.set(vm
, this, structure
);
147 inline const MethodTable
* JSCell::methodTableForDestruction() const
149 return &classInfo()->methodTable
;
152 inline const MethodTable
* JSCell::methodTable() const
154 if (Structure
* rootStructure
= m_structure
->structure())
155 RELEASE_ASSERT(rootStructure
== rootStructure
->structure());
157 return &classInfo()->methodTable
;
160 inline bool JSCell::inherits(const ClassInfo
* info
) const
162 return classInfo()->isSubClassOf(info
);
165 ALWAYS_INLINE
bool JSCell::fastGetOwnPropertySlot(ExecState
* exec
, PropertyName propertyName
, PropertySlot
& slot
)
167 if (!structure()->typeInfo().overridesGetOwnPropertySlot())
168 return asObject(this)->inlineGetOwnPropertySlot(exec
, propertyName
, slot
);
169 return methodTable()->getOwnPropertySlot(this, exec
, propertyName
, slot
);
172 // Fast call to get a property where we may not yet have converted the string to an
173 // identifier. The first time we perform a property access with a given string, try
174 // performing the property map lookup without forming an identifier. We detect this
175 // case by checking whether the hash has yet been set for this string.
176 ALWAYS_INLINE JSValue
JSCell::fastGetOwnProperty(ExecState
* exec
, const String
& name
)
178 if (!structure()->typeInfo().overridesGetOwnPropertySlot() && !structure()->hasGetterSetterProperties()) {
179 PropertyOffset offset
= name
.impl()->hasHash()
180 ? structure()->get(exec
->vm(), Identifier(exec
, name
))
181 : structure()->get(exec
->vm(), name
);
182 if (offset
!= invalidOffset
)
183 return asObject(this)->locationForOffset(offset
)->get();
188 inline bool JSCell::toBoolean(ExecState
* exec
) const
191 return static_cast<const JSString
*>(this)->toBoolean();
192 return !structure()->masqueradesAsUndefined(exec
->lexicalGlobalObject());
195 inline TriState
JSCell::pureToBoolean() const
198 return static_cast<const JSString
*>(this)->toBoolean() ? TrueTriState
: FalseTriState
;
199 return MixedTriState
;
204 #endif // JSCellInlines_h