X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/9dae56ea45a0f5f8136a5c93d6f3a7f99399ca73..cb9aa2694aba0ae4f946ed34b8e0f6c99c1cfe44:/runtime/JSActivation.h diff --git a/runtime/JSActivation.h b/runtime/JSActivation.h index 5e82bdc..55c5ade 100644 --- a/runtime/JSActivation.h +++ b/runtime/JSActivation.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2009, 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,7 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -30,68 +30,178 @@ #define JSActivation_h #include "CodeBlock.h" +#include "CopiedSpaceInlines.h" #include "JSVariableObject.h" -#include "RegisterFile.h" -#include "SymbolTable.h" #include "Nodes.h" +#include "SymbolTable.h" namespace JSC { - class Arguments; - class Register; +class Register; - class JSActivation : public JSVariableObject { - typedef JSVariableObject Base; - public: - JSActivation(CallFrame*, PassRefPtr); - virtual ~JSActivation(); - - virtual void mark(); - - virtual bool isDynamicScope() const; - - virtual bool isActivationObject() const { return true; } - - virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); - - virtual void put(ExecState*, const Identifier&, JSValuePtr, PutPropertySlot&); - - virtual void putWithAttributes(ExecState*, const Identifier&, JSValuePtr, unsigned attributes); - virtual bool deleteProperty(ExecState*, const Identifier& propertyName); - - virtual JSObject* toThisObject(ExecState*) const; +class JSActivation : public JSVariableObject { +private: + JSActivation(VM&, CallFrame*, Register*, SymbolTable*); + +public: + typedef JSVariableObject Base; - void copyRegisters(Arguments* arguments); + static JSActivation* create(VM& vm, CallFrame* callFrame, Register* registers, CodeBlock* codeBlock) + { + SymbolTable* symbolTable = codeBlock->symbolTable(); + ASSERT(codeBlock->codeType() == FunctionCode); + JSActivation* activation = new ( + NotNull, + allocateCell( + vm.heap, + allocationSize(symbolTable) + ) + ) JSActivation(vm, callFrame, registers, symbolTable); + activation->finishCreation(vm); + return activation; + } - virtual const ClassInfo* classInfo() const { return &info; } - static const ClassInfo info; + static JSActivation* create(VM& vm, CallFrame* callFrame, CodeBlock* codeBlock) + { + return create(vm, callFrame, callFrame->registers() + codeBlock->framePointerOffsetToGetActivationRegisters(), codeBlock); + } - static PassRefPtr createStructure(JSValuePtr proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); } + static void visitChildren(JSCell*, SlotVisitor&); - private: - struct JSActivationData : public JSVariableObjectData { - JSActivationData(PassRefPtr functionBody, Register* registers) - : JSVariableObjectData(&functionBody->generatedBytecode().symbolTable(), registers) - , functionBody(functionBody) - { - } + static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); + static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); - RefPtr functionBody; - }; - - static JSValuePtr argumentsGetter(ExecState*, const Identifier&, const PropertySlot&); - NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter(); + static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); - JSActivationData* d() const { return static_cast(JSVariableObject::d); } - }; + static bool deleteProperty(JSCell*, ExecState*, PropertyName); - JSActivation* asActivation(JSValuePtr); + static JSValue toThis(JSCell*, ExecState*, ECMAMode); - inline JSActivation* asActivation(JSValuePtr value) - { - ASSERT(asObject(value)->inherits(&JSActivation::info)); - return static_cast(asObject(value)); - } + void tearOff(VM&); + + DECLARE_INFO; + + static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(ActivationObjectType, StructureFlags), info()); } + + WriteBarrierBase& registerAt(int) const; + bool isValidIndex(int) const; + bool isValid(const SymbolTableEntry&) const; + bool isTornOff(); + int registersOffset(); + static int registersOffset(SymbolTable*); + +protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags; + +private: + bool symbolTableGet(PropertyName, PropertySlot&); + bool symbolTableGet(PropertyName, PropertyDescriptor&); + bool symbolTableGet(PropertyName, PropertySlot&, bool& slotIsWriteable); + bool symbolTablePut(ExecState*, PropertyName, JSValue, bool shouldThrow); + bool symbolTablePutWithAttributes(VM&, PropertyName, JSValue, unsigned attributes); + + static EncodedJSValue argumentsGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName); + + static size_t allocationSize(SymbolTable*); + static size_t storageOffset(); + + WriteBarrier* storage(); // captureCount() number of registers. +}; + +extern int activationCount; +extern int allTheThingsCount; + +inline JSActivation::JSActivation(VM& vm, CallFrame* callFrame, Register* registers, SymbolTable* symbolTable) + : Base( + vm, + callFrame->lexicalGlobalObject()->activationStructure(), + registers, + callFrame->scope(), + symbolTable) +{ + WriteBarrier* storage = this->storage(); + size_t captureCount = symbolTable->captureCount(); + for (size_t i = 0; i < captureCount; ++i) + new (NotNull, &storage[i]) WriteBarrier; +} + +JSActivation* asActivation(JSValue); + +inline JSActivation* asActivation(JSValue value) +{ + ASSERT(asObject(value)->inherits(JSActivation::info())); + return jsCast(asObject(value)); +} + +ALWAYS_INLINE JSActivation* Register::activation() const +{ + return asActivation(jsValue()); +} + +inline int JSActivation::registersOffset(SymbolTable* symbolTable) +{ + return storageOffset() + ((symbolTable->captureCount() - symbolTable->captureStart() - 1) * sizeof(WriteBarrier)); +} + +inline void JSActivation::tearOff(VM& vm) +{ + ASSERT(!isTornOff()); + + WriteBarrierBase* dst = reinterpret_cast_ptr*>( + reinterpret_cast(this) + registersOffset(symbolTable())); + WriteBarrierBase* src = m_registers; + + int captureEnd = symbolTable()->captureEnd(); + for (int i = symbolTable()->captureStart(); i > captureEnd; --i) + dst[i].set(vm, this, src[i].get()); + + m_registers = dst; + ASSERT(isTornOff()); +} + +inline bool JSActivation::isTornOff() +{ + return m_registers == reinterpret_cast_ptr*>( + reinterpret_cast(this) + registersOffset(symbolTable())); +} + +inline size_t JSActivation::storageOffset() +{ + return WTF::roundUpToMultipleOf)>(sizeof(JSActivation)); +} + +inline WriteBarrier* JSActivation::storage() +{ + return reinterpret_cast_ptr*>( + reinterpret_cast(this) + storageOffset()); +} + +inline size_t JSActivation::allocationSize(SymbolTable* symbolTable) +{ + size_t objectSizeInBytes = WTF::roundUpToMultipleOf)>(sizeof(JSActivation)); + size_t storageSizeInBytes = symbolTable->captureCount() * sizeof(WriteBarrier); + return objectSizeInBytes + storageSizeInBytes; +} + +inline bool JSActivation::isValidIndex(int index) const +{ + if (index > symbolTable()->captureStart()) + return false; + if (index <= symbolTable()->captureEnd()) + return false; + return true; +} + +inline bool JSActivation::isValid(const SymbolTableEntry& entry) const +{ + return isValidIndex(entry.getIndex()); +} + +inline WriteBarrierBase& JSActivation::registerAt(int index) const +{ + ASSERT(isValidIndex(index)); + return Base::registerAt(index); +} } // namespace JSC