diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-09-14 16:29:47 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-09-14 16:29:47 +0200 |
commit | d0424a769059c84ae20beb3c217812792ea6726b (patch) | |
tree | 6f94a5c3db8c52c6694ee56498542a6c35417350 /Source/JavaScriptCore/runtime/JSActivation.h | |
parent | 88a04ac016f57c2d78e714682445dff2e7db4ade (diff) | |
download | qtwebkit-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.h | 156 |
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 |