summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/JSActivation.h
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-09-14 16:29:47 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-09-14 16:29:47 +0200
commitd0424a769059c84ae20beb3c217812792ea6726b (patch)
tree6f94a5c3db8c52c6694ee56498542a6c35417350 /Source/JavaScriptCore/runtime/JSActivation.h
parent88a04ac016f57c2d78e714682445dff2e7db4ade (diff)
downloadqtwebkit-d0424a769059c84ae20beb3c217812792ea6726b.tar.gz
Imported WebKit commit 37c5e5041d39a14ea0d429a77ebd352e4bd26516 (http://svn.webkit.org/repository/webkit/trunk@128608)
New snapshot that enables WebKit2 build on Windows (still some bugs) and allows for WebKit to be built with qmake && make
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSActivation.h')
-rw-r--r--Source/JavaScriptCore/runtime/JSActivation.h156
1 files changed, 105 insertions, 51 deletions
diff --git a/Source/JavaScriptCore/runtime/JSActivation.h b/Source/JavaScriptCore/runtime/JSActivation.h
index 3abe5f54b..df59c3d94 100644
--- a/Source/JavaScriptCore/runtime/JSActivation.h
+++ b/Source/JavaScriptCore/runtime/JSActivation.h
@@ -37,20 +37,26 @@
namespace JSC {
- class Arguments;
class Register;
class JSActivation : public JSVariableObject {
private:
- JSActivation(CallFrame*, FunctionExecutable*);
+ JSActivation(JSGlobalData& globalData, CallFrame*, SharedSymbolTable*, size_t storageSize);
public:
typedef JSVariableObject Base;
- static JSActivation* create(JSGlobalData& globalData, CallFrame* callFrame, FunctionExecutable* funcExec)
+ static JSActivation* create(JSGlobalData& globalData, CallFrame* callFrame, FunctionExecutable* functionExecutable)
{
- JSActivation* activation = new (NotNull, allocateCell<JSActivation>(globalData.heap)) JSActivation(callFrame, funcExec);
- activation->finishCreation(callFrame, funcExec);
+ size_t storageSize = JSActivation::storageSize(callFrame, functionExecutable->symbolTable());
+ JSActivation* activation = new (
+ NotNull,
+ allocateCell<JSActivation>(
+ globalData.heap,
+ allocationSize(storageSize)
+ )
+ ) JSActivation(globalData, callFrame, functionExecutable->symbolTable(), storageSize);
+ activation->finishCreation(globalData);
return activation;
}
@@ -59,7 +65,7 @@ namespace JSC {
bool isDynamicScope(bool& requiresDynamicChecks) const;
static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
- static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+ static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
JS_EXPORT_PRIVATE static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
@@ -75,10 +81,10 @@ namespace JSC {
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(ActivationObjectType, StructureFlags), &s_info); }
- bool isValidScopedLookup(int index) { return index < m_numCapturedVars; }
+ bool isValid(const SymbolTableEntry&);
+ bool isTornOff();
protected:
- void finishCreation(CallFrame*, FunctionExecutable*);
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags;
private:
@@ -91,18 +97,32 @@ namespace JSC {
static JSValue argumentsGetter(ExecState*, JSValue, PropertyName);
NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
- size_t registerOffset();
- size_t registerArraySize();
- size_t registerArraySizeInBytes();
+ static size_t allocationSize(size_t storageSize);
+ static size_t storageSize(CallFrame*, SharedSymbolTable*);
+ static int captureStart(CallFrame*, SharedSymbolTable*);
- StorageBarrier m_registerArray; // Independent copy of registers, used when a variable object copies its registers out of the register file.
- int m_numCapturedArgs;
- int m_numCapturedVars : 30;
- bool m_isTornOff : 1;
- bool m_requiresDynamicChecks : 1;
- int m_argumentsRegister;
+ int registerOffset();
+ size_t storageSize();
+ WriteBarrier<Unknown>* storage(); // storageSize() number of registers.
};
+ extern int activationCount;
+ extern int allTheThingsCount;
+
+ inline JSActivation::JSActivation(JSGlobalData& globalData, CallFrame* callFrame, SharedSymbolTable* symbolTable, size_t storageSize)
+ : Base(
+ globalData,
+ callFrame->lexicalGlobalObject()->activationStructure(),
+ callFrame->registers(),
+ callFrame->scope(),
+ symbolTable
+ )
+ {
+ WriteBarrier<Unknown>* storage = this->storage();
+ for (size_t i = 0; i < storageSize; ++i)
+ new(&storage[i]) WriteBarrier<Unknown>;
+ }
+
JSActivation* asActivation(JSValue);
inline JSActivation* asActivation(JSValue value)
@@ -118,55 +138,89 @@ namespace JSC {
inline bool JSActivation::isDynamicScope(bool& requiresDynamicChecks) const
{
- requiresDynamicChecks = m_requiresDynamicChecks;
+ requiresDynamicChecks = symbolTable()->usesNonStrictEval();
return false;
}
- inline size_t JSActivation::registerOffset()
+ inline int JSActivation::captureStart(CallFrame* callFrame, SharedSymbolTable* symbolTable)
{
- if (!m_numCapturedArgs)
- return 0;
+ if (symbolTable->captureMode() == SharedSymbolTable::AllOfTheThings)
+ return -CallFrame::offsetFor(std::max<size_t>(callFrame->argumentCountIncludingThis(), symbolTable->parameterCountIncludingThis()));
+ return symbolTable->captureStart();
+ }
- size_t capturedArgumentCountIncludingThis = m_numCapturedArgs + 1;
- return CallFrame::offsetFor(capturedArgumentCountIncludingThis);
+ inline size_t JSActivation::storageSize(CallFrame* callFrame, SharedSymbolTable* symbolTable)
+ {
+ return symbolTable->captureEnd() - captureStart(callFrame, symbolTable);
}
- inline size_t JSActivation::registerArraySize()
+ inline int JSActivation::registerOffset()
{
- return registerOffset() + m_numCapturedVars;
+ return -captureStart(CallFrame::create(reinterpret_cast<Register*>(m_registers)), symbolTable());
}
- inline size_t JSActivation::registerArraySizeInBytes()
+ inline size_t JSActivation::storageSize()
{
- return registerArraySize() * sizeof(WriteBarrierBase<Unknown>);
+ return storageSize(CallFrame::create(reinterpret_cast<Register*>(m_registers)), symbolTable());
}
inline void JSActivation::tearOff(JSGlobalData& globalData)
{
- ASSERT(!m_registerArray);
- ASSERT(m_numCapturedVars + m_numCapturedArgs);
-
- void* allocation = 0;
- if (!globalData.heap.tryAllocateStorage(registerArraySizeInBytes(), &allocation))
- CRASH();
- PropertyStorage registerArray = static_cast<PropertyStorage>(allocation);
- PropertyStorage registers = registerArray + registerOffset();
-
- // arguments
- int from = CallFrame::argumentOffset(m_numCapturedArgs - 1);
- int to = CallFrame::thisArgumentOffset(); // Skip 'this' because it's not lexically accessible.
- for (int i = from; i < to; ++i)
- registers[i].set(globalData, this, m_registers[i].get());
-
- // vars
- from = 0;
- to = m_numCapturedVars;
- for (int i = from; i < to; ++i)
- registers[i].set(globalData, this, m_registers[i].get());
-
- m_registerArray.set(globalData, this, registerArray);
- m_registers = registers;
- m_isTornOff = true;
+ ASSERT(!isTornOff());
+
+ int registerOffset = this->registerOffset();
+ WriteBarrierBase<Unknown>* dst = storage() + registerOffset;
+ WriteBarrierBase<Unknown>* src = m_registers;
+
+ if (symbolTable()->captureMode() == SharedSymbolTable::AllOfTheThings) {
+ int from = -registerOffset;
+ int to = CallFrame::thisArgumentOffset(); // Skip 'this' because it's not lexically accessible.
+ for (int i = from; i < to; ++i)
+ dst[i].set(globalData, this, src[i].get());
+
+ dst[RegisterFile::ArgumentCount].set(globalData, this, JSValue(
+ CallFrame::create(reinterpret_cast<Register*>(src))->argumentCountIncludingThis()));
+
+ int captureEnd = symbolTable()->captureEnd();
+ for (int i = 0; i < captureEnd; ++i)
+ dst[i].set(globalData, this, src[i].get());
+ } else {
+ int captureEnd = symbolTable()->captureEnd();
+ for (int i = symbolTable()->captureStart(); i < captureEnd; ++i)
+ dst[i].set(globalData, this, src[i].get());
+ }
+
+ m_registers = dst;
+ ASSERT(isTornOff());
+ }
+
+ inline bool JSActivation::isTornOff()
+ {
+ return m_registers == storage() + registerOffset();
+ }
+
+ inline WriteBarrier<Unknown>* JSActivation::storage()
+ {
+ return reinterpret_cast<WriteBarrier<Unknown>*>(
+ reinterpret_cast<char*>(this) +
+ WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSActivation))
+ );
+ }
+
+ inline size_t JSActivation::allocationSize(size_t storageSize)
+ {
+ size_t objectSizeInBytes = WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSActivation));
+ size_t storageSizeInBytes = storageSize * sizeof(WriteBarrier<Unknown>);
+ return objectSizeInBytes + storageSizeInBytes;
+ }
+
+ inline bool JSActivation::isValid(const SymbolTableEntry& entry)
+ {
+ if (entry.getIndex() < captureStart(CallFrame::create(reinterpret_cast<Register*>(m_registers)), symbolTable()))
+ return false;
+ if (entry.getIndex() >= symbolTable()->captureEnd())
+ return false;
+ return true;
}
} // namespace JSC