[BlackBerry][ARM] Fix cast-align warnings in JavaScriptCore
[WebKit-https.git] / Source / JavaScriptCore / runtime / JSActivation.h
1 /*
2  * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
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.
16  *
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.
27  */
28  
29 #ifndef JSActivation_h
30 #define JSActivation_h
31
32 #include "CodeBlock.h"
33 #include "CopiedSpaceInlines.h"
34 #include "JSVariableObject.h"
35 #include "Nodes.h"
36 #include "SymbolTable.h"
37
38 namespace JSC {
39
40     class Register;
41     
42     class JSActivation : public JSVariableObject {
43     private:
44         JSActivation(JSGlobalData& globalData, CallFrame*, SharedSymbolTable*);
45     
46     public:
47         typedef JSVariableObject Base;
48
49         static JSActivation* create(JSGlobalData& globalData, CallFrame* callFrame, CodeBlock* codeBlock)
50         {
51             SharedSymbolTable* symbolTable = codeBlock->symbolTable();
52             JSActivation* activation = new (
53                 NotNull,
54                 allocateCell<JSActivation>(
55                     globalData.heap,
56                     allocationSize(symbolTable)
57                 )
58             ) JSActivation(globalData, callFrame, symbolTable);
59             activation->finishCreation(globalData);
60             return activation;
61         }
62
63         static void visitChildren(JSCell*, SlotVisitor&);
64
65         bool isDynamicScope(bool& requiresDynamicChecks) const;
66
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&);
70
71         static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
72
73         static void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes);
74         static bool deleteProperty(JSCell*, ExecState*, PropertyName);
75
76         static JSObject* toThisObject(JSCell*, ExecState*);
77
78         void tearOff(JSGlobalData&);
79         
80         static const ClassInfo s_info;
81
82         static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(ActivationObjectType, StructureFlags), &s_info); }
83
84         WriteBarrierBase<Unknown>& registerAt(int) const;
85         bool isValidIndex(int) const;
86         bool isValid(const SymbolTableEntry&) const;
87         bool isTornOff();
88         int registersOffset();
89         static int registersOffset(SharedSymbolTable*);
90
91     protected:
92         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags;
93
94     private:
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(JSGlobalData&, PropertyName, JSValue, unsigned attributes);
100
101         static JSValue argumentsGetter(ExecState*, JSValue, PropertyName);
102         NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
103
104         static size_t allocationSize(SharedSymbolTable*);
105         static size_t storageOffset();
106
107         WriteBarrier<Unknown>* storage(); // captureCount() number of registers.
108     };
109
110     extern int activationCount;
111     extern int allTheThingsCount;
112
113     inline JSActivation::JSActivation(JSGlobalData& globalData, CallFrame* callFrame, SharedSymbolTable* symbolTable)
114         : Base(
115             globalData,
116             callFrame->lexicalGlobalObject()->activationStructure(),
117             callFrame->registers(),
118             callFrame->scope(),
119             symbolTable
120         )
121     {
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>;
126     }
127
128     JSActivation* asActivation(JSValue);
129
130     inline JSActivation* asActivation(JSValue value)
131     {
132         ASSERT(asObject(value)->inherits(&JSActivation::s_info));
133         return jsCast<JSActivation*>(asObject(value));
134     }
135     
136     ALWAYS_INLINE JSActivation* Register::activation() const
137     {
138         return asActivation(jsValue());
139     }
140
141     inline bool JSActivation::isDynamicScope(bool& requiresDynamicChecks) const
142     {
143         requiresDynamicChecks = symbolTable()->usesNonStrictEval();
144         return false;
145     }
146
147     inline int JSActivation::registersOffset(SharedSymbolTable* symbolTable)
148     {
149         return storageOffset() - (symbolTable->captureStart() * sizeof(WriteBarrier<Unknown>));
150     }
151
152     inline void JSActivation::tearOff(JSGlobalData& globalData)
153     {
154         ASSERT(!isTornOff());
155
156         WriteBarrierBase<Unknown>* dst = reinterpret_cast_ptr<WriteBarrierBase<Unknown>*>(
157             reinterpret_cast<char*>(this) + registersOffset(symbolTable()));
158         WriteBarrierBase<Unknown>* src = m_registers;
159
160         int captureEnd = symbolTable()->captureEnd();
161         for (int i = symbolTable()->captureStart(); i < captureEnd; ++i)
162             dst[i].set(globalData, this, src[i].get());
163
164         m_registers = dst;
165         ASSERT(isTornOff());
166     }
167
168     inline bool JSActivation::isTornOff()
169     {
170         return m_registers == reinterpret_cast_ptr<WriteBarrierBase<Unknown>*>(
171             reinterpret_cast<char*>(this) + registersOffset(symbolTable()));
172     }
173
174     inline size_t JSActivation::storageOffset()
175     {
176         return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSActivation));
177     }
178
179     inline WriteBarrier<Unknown>* JSActivation::storage()
180     {
181         return reinterpret_cast_ptr<WriteBarrier<Unknown>*>(
182             reinterpret_cast<char*>(this) + storageOffset());
183     }
184
185     inline size_t JSActivation::allocationSize(SharedSymbolTable* symbolTable)
186     {
187         size_t objectSizeInBytes = WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSActivation));
188         size_t storageSizeInBytes = symbolTable->captureCount() * sizeof(WriteBarrier<Unknown>);
189         return objectSizeInBytes + storageSizeInBytes;
190     }
191
192     inline bool JSActivation::isValidIndex(int index) const
193     {
194         if (index < symbolTable()->captureStart())
195             return false;
196         if (index >= symbolTable()->captureEnd())
197             return false;
198         return true;
199     }
200
201     inline bool JSActivation::isValid(const SymbolTableEntry& entry) const
202     {
203         return isValidIndex(entry.getIndex());
204     }
205
206     inline WriteBarrierBase<Unknown>& JSActivation::registerAt(int index) const
207     {
208         ASSERT(isValidIndex(index));
209         return Base::registerAt(index);
210     }
211
212 } // namespace JSC
213
214 #endif // JSActivation_h