2 * Copyright (C) 2008, 2009 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
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #ifndef JSActivation_h
30 #define JSActivation_h
32 #include "CodeBlock.h"
33 #include "CopiedSpaceInlines.h"
34 #include "JSVariableObject.h"
36 #include "SymbolTable.h"
42 class JSActivation
: public JSVariableObject
{
44 JSActivation(VM
& vm
, CallFrame
*, SharedSymbolTable
*);
47 typedef JSVariableObject Base
;
49 static JSActivation
* create(VM
& vm
, CallFrame
* callFrame
, CodeBlock
* codeBlock
)
51 SharedSymbolTable
* symbolTable
= codeBlock
->symbolTable();
52 JSActivation
* activation
= new (
54 allocateCell
<JSActivation
>(
56 allocationSize(symbolTable
)
58 ) JSActivation(vm
, callFrame
, symbolTable
);
59 activation
->finishCreation(vm
);
63 static void visitChildren(JSCell
*, SlotVisitor
&);
65 bool isDynamicScope(bool& requiresDynamicChecks
) const;
67 static bool getOwnPropertySlot(JSCell
*, ExecState
*, PropertyName
, PropertySlot
&);
68 static void getOwnNonIndexPropertyNames(JSObject
*, ExecState
*, PropertyNameArray
&, EnumerationMode
);
69 JS_EXPORT_PRIVATE
static bool getOwnPropertyDescriptor(JSObject
*, ExecState
*, PropertyName
, PropertyDescriptor
&);
71 static void put(JSCell
*, ExecState
*, PropertyName
, JSValue
, PutPropertySlot
&);
73 static void putDirectVirtual(JSObject
*, ExecState
*, PropertyName
, JSValue
, unsigned attributes
);
74 static bool deleteProperty(JSCell
*, ExecState
*, PropertyName
);
76 static JSObject
* toThisObject(JSCell
*, ExecState
*);
80 static const ClassInfo s_info
;
82 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
) { return Structure::create(vm
, globalObject
, proto
, TypeInfo(ActivationObjectType
, StructureFlags
), &s_info
); }
84 WriteBarrierBase
<Unknown
>& registerAt(int) const;
85 bool isValidIndex(int) const;
86 bool isValid(const SymbolTableEntry
&) const;
88 int registersOffset();
89 static int registersOffset(SharedSymbolTable
*);
92 static const unsigned StructureFlags
= OverridesGetOwnPropertySlot
| OverridesVisitChildren
| OverridesGetPropertyNames
| Base::StructureFlags
;
95 bool symbolTableGet(PropertyName
, PropertySlot
&);
96 bool symbolTableGet(PropertyName
, PropertyDescriptor
&);
97 bool symbolTableGet(PropertyName
, PropertySlot
&, bool& slotIsWriteable
);
98 bool symbolTablePut(ExecState
*, PropertyName
, JSValue
, bool shouldThrow
);
99 bool symbolTablePutWithAttributes(VM
&, PropertyName
, JSValue
, unsigned attributes
);
101 static JSValue
argumentsGetter(ExecState
*, JSValue
, PropertyName
);
102 NEVER_INLINE
PropertySlot::GetValueFunc
getArgumentsGetter();
104 static size_t allocationSize(SharedSymbolTable
*);
105 static size_t storageOffset();
107 WriteBarrier
<Unknown
>* storage(); // captureCount() number of registers.
110 extern int activationCount
;
111 extern int allTheThingsCount
;
113 inline JSActivation::JSActivation(VM
& vm
, CallFrame
* callFrame
, SharedSymbolTable
* symbolTable
)
116 callFrame
->lexicalGlobalObject()->activationStructure(),
117 callFrame
->registers(),
122 WriteBarrier
<Unknown
>* storage
= this->storage();
123 size_t captureCount
= symbolTable
->captureCount();
124 for (size_t i
= 0; i
< captureCount
; ++i
)
125 new(&storage
[i
]) WriteBarrier
<Unknown
>;
128 JSActivation
* asActivation(JSValue
);
130 inline JSActivation
* asActivation(JSValue value
)
132 ASSERT(asObject(value
)->inherits(&JSActivation::s_info
));
133 return jsCast
<JSActivation
*>(asObject(value
));
136 ALWAYS_INLINE JSActivation
* Register::activation() const
138 return asActivation(jsValue());
141 inline bool JSActivation::isDynamicScope(bool& requiresDynamicChecks
) const
143 requiresDynamicChecks
= symbolTable()->usesNonStrictEval();
147 inline int JSActivation::registersOffset(SharedSymbolTable
* symbolTable
)
149 return storageOffset() - (symbolTable
->captureStart() * sizeof(WriteBarrier
<Unknown
>));
152 inline void JSActivation::tearOff(VM
& vm
)
154 ASSERT(!isTornOff());
156 WriteBarrierBase
<Unknown
>* dst
= reinterpret_cast_ptr
<WriteBarrierBase
<Unknown
>*>(
157 reinterpret_cast<char*>(this) + registersOffset(symbolTable()));
158 WriteBarrierBase
<Unknown
>* src
= m_registers
;
160 int captureEnd
= symbolTable()->captureEnd();
161 for (int i
= symbolTable()->captureStart(); i
< captureEnd
; ++i
)
162 dst
[i
].set(vm
, this, src
[i
].get());
168 inline bool JSActivation::isTornOff()
170 return m_registers
== reinterpret_cast_ptr
<WriteBarrierBase
<Unknown
>*>(
171 reinterpret_cast<char*>(this) + registersOffset(symbolTable()));
174 inline size_t JSActivation::storageOffset()
176 return WTF::roundUpToMultipleOf
<sizeof(WriteBarrier
<Unknown
>)>(sizeof(JSActivation
));
179 inline WriteBarrier
<Unknown
>* JSActivation::storage()
181 return reinterpret_cast_ptr
<WriteBarrier
<Unknown
>*>(
182 reinterpret_cast<char*>(this) + storageOffset());
185 inline size_t JSActivation::allocationSize(SharedSymbolTable
* symbolTable
)
187 size_t objectSizeInBytes
= WTF::roundUpToMultipleOf
<sizeof(WriteBarrier
<Unknown
>)>(sizeof(JSActivation
));
188 size_t storageSizeInBytes
= symbolTable
->captureCount() * sizeof(WriteBarrier
<Unknown
>);
189 return objectSizeInBytes
+ storageSizeInBytes
;
192 inline bool JSActivation::isValidIndex(int index
) const
194 if (index
< symbolTable()->captureStart())
196 if (index
>= symbolTable()->captureEnd())
201 inline bool JSActivation::isValid(const SymbolTableEntry
& entry
) const
203 return isValidIndex(entry
.getIndex());
206 inline WriteBarrierBase
<Unknown
>& JSActivation::registerAt(int index
) const
208 ASSERT(isValidIndex(index
));
209 return Base::registerAt(index
);
214 #endif // JSActivation_h