]>
Commit | Line | Data |
---|---|---|
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 "JSVariableObject.h" | |
34 | #include "SymbolTable.h" | |
35 | #include "Nodes.h" | |
36 | ||
37 | namespace JSC { | |
38 | ||
39 | class Arguments; | |
40 | class Register; | |
41 | ||
42 | class JSActivation : public JSVariableObject { | |
43 | private: | |
44 | JSActivation(CallFrame*, FunctionExecutable*); | |
45 | ||
46 | public: | |
47 | typedef JSVariableObject Base; | |
48 | ||
49 | static JSActivation* create(JSGlobalData& globalData, CallFrame* callFrame, FunctionExecutable* funcExec) | |
50 | { | |
51 | JSActivation* activation = new (NotNull, allocateCell<JSActivation>(globalData.heap)) JSActivation(callFrame, funcExec); | |
52 | activation->finishCreation(callFrame); | |
53 | return activation; | |
54 | } | |
55 | ||
56 | static void finalize(JSCell*); | |
57 | ||
58 | static void visitChildren(JSCell*, SlotVisitor&); | |
59 | ||
60 | bool isDynamicScope(bool& requiresDynamicChecks) const; | |
61 | ||
62 | static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier&, PropertySlot&); | |
63 | static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); | |
64 | ||
65 | static void put(JSCell*, ExecState*, const Identifier&, JSValue, PutPropertySlot&); | |
66 | ||
67 | static void putDirectVirtual(JSObject*, ExecState*, const Identifier&, JSValue, unsigned attributes); | |
68 | static bool deleteProperty(JSCell*, ExecState*, const Identifier& propertyName); | |
69 | ||
70 | static JSObject* toThisObject(JSCell*, ExecState*); | |
71 | ||
72 | void tearOff(JSGlobalData&); | |
73 | ||
74 | static const ClassInfo s_info; | |
75 | ||
76 | static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(ActivationObjectType, StructureFlags), &s_info); } | |
77 | ||
78 | bool isValidScopedLookup(int index) { return index < m_numCapturedVars; } | |
79 | ||
80 | protected: | |
81 | void finishCreation(CallFrame*); | |
82 | static const unsigned StructureFlags = IsEnvironmentRecord | OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags; | |
83 | ||
84 | private: | |
85 | bool symbolTableGet(const Identifier&, PropertySlot&); | |
86 | bool symbolTableGet(const Identifier&, PropertyDescriptor&); | |
87 | bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable); | |
88 | bool symbolTablePut(ExecState*, const Identifier&, JSValue, bool shouldThrow); | |
89 | bool symbolTablePutWithAttributes(JSGlobalData&, const Identifier&, JSValue, unsigned attributes); | |
90 | ||
91 | static JSValue argumentsGetter(ExecState*, JSValue, const Identifier&); | |
92 | NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter(); | |
93 | ||
94 | int m_numCapturedArgs; | |
95 | int m_numCapturedVars : 30; | |
96 | bool m_isTornOff : 1; | |
97 | bool m_requiresDynamicChecks : 1; | |
98 | int m_argumentsRegister; | |
99 | }; | |
100 | ||
101 | JSActivation* asActivation(JSValue); | |
102 | ||
103 | inline JSActivation* asActivation(JSValue value) | |
104 | { | |
105 | ASSERT(asObject(value)->inherits(&JSActivation::s_info)); | |
106 | return jsCast<JSActivation*>(asObject(value)); | |
107 | } | |
108 | ||
109 | ALWAYS_INLINE JSActivation* Register::activation() const | |
110 | { | |
111 | return asActivation(jsValue()); | |
112 | } | |
113 | ||
114 | inline bool JSActivation::isDynamicScope(bool& requiresDynamicChecks) const | |
115 | { | |
116 | requiresDynamicChecks = m_requiresDynamicChecks; | |
117 | return false; | |
118 | } | |
119 | ||
120 | inline void JSActivation::tearOff(JSGlobalData& globalData) | |
121 | { | |
122 | ASSERT(!m_registerArray); | |
123 | ASSERT(m_numCapturedVars + m_numCapturedArgs); | |
124 | ||
125 | int registerOffset = CallFrame::offsetFor(m_numCapturedArgs + 1); | |
126 | size_t registerArraySize = registerOffset + m_numCapturedVars; | |
127 | ||
128 | OwnArrayPtr<WriteBarrier<Unknown> > registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[registerArraySize]); | |
129 | WriteBarrier<Unknown>* registers = registerArray.get() + registerOffset; | |
130 | ||
131 | int from = CallFrame::argumentOffset(m_numCapturedArgs - 1); | |
132 | int to = m_numCapturedVars; | |
133 | for (int i = from; i < to; ++i) | |
134 | registers[i].set(globalData, this, m_registers[i].get()); | |
135 | ||
136 | setRegisters(registers, registerArray.release()); | |
137 | m_isTornOff = true; | |
138 | } | |
139 | ||
140 | } // namespace JSC | |
141 | ||
142 | #endif // JSActivation_h |