2 * Copyright (C) 2008, 2009, 2013 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 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
&, CallFrame
*, Register
*, SymbolTable
*);
47 typedef JSVariableObject Base
;
49 static JSActivation
* create(VM
& vm
, CallFrame
* callFrame
, Register
* registers
, CodeBlock
* codeBlock
)
51 SymbolTable
* symbolTable
= codeBlock
->symbolTable();
52 ASSERT(codeBlock
->codeType() == FunctionCode
);
53 JSActivation
* activation
= new (
55 allocateCell
<JSActivation
>(
57 allocationSize(symbolTable
)
59 ) JSActivation(vm
, callFrame
, registers
, symbolTable
);
60 activation
->finishCreation(vm
);
64 static JSActivation
* create(VM
& vm
, CallFrame
* callFrame
, CodeBlock
* codeBlock
)
66 return create(vm
, callFrame
, callFrame
->registers() + codeBlock
->framePointerOffsetToGetActivationRegisters(), codeBlock
);
69 static void visitChildren(JSCell
*, SlotVisitor
&);
71 static bool getOwnPropertySlot(JSObject
*, ExecState
*, PropertyName
, PropertySlot
&);
72 static void getOwnNonIndexPropertyNames(JSObject
*, ExecState
*, PropertyNameArray
&, EnumerationMode
);
74 static void put(JSCell
*, ExecState
*, PropertyName
, JSValue
, PutPropertySlot
&);
76 static bool deleteProperty(JSCell
*, ExecState
*, PropertyName
);
78 static JSValue
toThis(JSCell
*, ExecState
*, ECMAMode
);
84 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
) { return Structure::create(vm
, globalObject
, proto
, TypeInfo(ActivationObjectType
, StructureFlags
), info()); }
86 WriteBarrierBase
<Unknown
>& registerAt(int) const;
87 bool isValidIndex(int) const;
88 bool isValid(const SymbolTableEntry
&) const;
90 int registersOffset();
91 static int registersOffset(SymbolTable
*);
94 static const unsigned StructureFlags
= OverridesGetOwnPropertySlot
| OverridesVisitChildren
| OverridesGetPropertyNames
| Base::StructureFlags
;
97 bool symbolTableGet(PropertyName
, PropertySlot
&);
98 bool symbolTableGet(PropertyName
, PropertyDescriptor
&);
99 bool symbolTableGet(PropertyName
, PropertySlot
&, bool& slotIsWriteable
);
100 bool symbolTablePut(ExecState
*, PropertyName
, JSValue
, bool shouldThrow
);
101 bool symbolTablePutWithAttributes(VM
&, PropertyName
, JSValue
, unsigned attributes
);
103 static EncodedJSValue
argumentsGetter(ExecState
*, JSObject
*, EncodedJSValue
, PropertyName
);
105 static size_t allocationSize(SymbolTable
*);
106 static size_t storageOffset();
108 WriteBarrier
<Unknown
>* storage(); // captureCount() number of registers.
111 extern int activationCount
;
112 extern int allTheThingsCount
;
114 inline JSActivation::JSActivation(VM
& vm
, CallFrame
* callFrame
, Register
* registers
, SymbolTable
* symbolTable
)
117 callFrame
->lexicalGlobalObject()->activationStructure(),
122 WriteBarrier
<Unknown
>* storage
= this->storage();
123 size_t captureCount
= symbolTable
->captureCount();
124 for (size_t i
= 0; i
< captureCount
; ++i
)
125 new (NotNull
, &storage
[i
]) WriteBarrier
<Unknown
>;
128 JSActivation
* asActivation(JSValue
);
130 inline JSActivation
* asActivation(JSValue value
)
132 ASSERT(asObject(value
)->inherits(JSActivation::info()));
133 return jsCast
<JSActivation
*>(asObject(value
));
136 ALWAYS_INLINE JSActivation
* Register::activation() const
138 return asActivation(jsValue());
141 inline int JSActivation::registersOffset(SymbolTable
* symbolTable
)
143 return storageOffset() + ((symbolTable
->captureCount() - symbolTable
->captureStart() - 1) * sizeof(WriteBarrier
<Unknown
>));
146 inline void JSActivation::tearOff(VM
& vm
)
148 ASSERT(!isTornOff());
150 WriteBarrierBase
<Unknown
>* dst
= reinterpret_cast_ptr
<WriteBarrierBase
<Unknown
>*>(
151 reinterpret_cast<char*>(this) + registersOffset(symbolTable()));
152 WriteBarrierBase
<Unknown
>* src
= m_registers
;
154 int captureEnd
= symbolTable()->captureEnd();
155 for (int i
= symbolTable()->captureStart(); i
> captureEnd
; --i
)
156 dst
[i
].set(vm
, this, src
[i
].get());
162 inline bool JSActivation::isTornOff()
164 return m_registers
== reinterpret_cast_ptr
<WriteBarrierBase
<Unknown
>*>(
165 reinterpret_cast<char*>(this) + registersOffset(symbolTable()));
168 inline size_t JSActivation::storageOffset()
170 return WTF::roundUpToMultipleOf
<sizeof(WriteBarrier
<Unknown
>)>(sizeof(JSActivation
));
173 inline WriteBarrier
<Unknown
>* JSActivation::storage()
175 return reinterpret_cast_ptr
<WriteBarrier
<Unknown
>*>(
176 reinterpret_cast<char*>(this) + storageOffset());
179 inline size_t JSActivation::allocationSize(SymbolTable
* symbolTable
)
181 size_t objectSizeInBytes
= WTF::roundUpToMultipleOf
<sizeof(WriteBarrier
<Unknown
>)>(sizeof(JSActivation
));
182 size_t storageSizeInBytes
= symbolTable
->captureCount() * sizeof(WriteBarrier
<Unknown
>);
183 return objectSizeInBytes
+ storageSizeInBytes
;
186 inline bool JSActivation::isValidIndex(int index
) const
188 if (index
> symbolTable()->captureStart())
190 if (index
<= symbolTable()->captureEnd())
195 inline bool JSActivation::isValid(const SymbolTableEntry
& entry
) const
197 return isValidIndex(entry
.getIndex());
200 inline WriteBarrierBase
<Unknown
>& JSActivation::registerAt(int index
) const
202 ASSERT(isValidIndex(index
));
203 return Base::registerAt(index
);
208 #endif // JSActivation_h