Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2007, 2008 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 JSVariableObject_h
     30 #define JSVariableObject_h
     31 
     32 #include "JSObject.h"
     33 #include "Register.h"
     34 #include "SymbolTable.h"
     35 #include "UnusedParam.h"
     36 #include <wtf/OwnArrayPtr.h>
     37 #include <wtf/UnusedParam.h>
     38 
     39 namespace JSC {
     40 
     41     class Register;
     42 
     43     class JSVariableObject : public JSNonFinalObject {
     44         friend class JIT;
     45 
     46     public:
     47         SymbolTable& symbolTable() const { return *m_symbolTable; }
     48 
     49         virtual void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes) = 0;
     50 
     51         virtual bool deleteProperty(ExecState*, const Identifier&);
     52         virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
     53 
     54         virtual bool isVariableObject() const;
     55         virtual bool isDynamicScope(bool& requiresDynamicChecks) const = 0;
     56 
     57         WriteBarrier<Unknown>& registerAt(int index) const { return m_registers[index]; }
     58 
     59         WriteBarrier<Unknown>* const * addressOfRegisters() const { return &m_registers; }
     60 
     61         static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
     62         {
     63             return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
     64         }
     65 
     66     protected:
     67         static const unsigned StructureFlags = OverridesGetPropertyNames | JSObject::StructureFlags;
     68 
     69         JSVariableObject(JSGlobalData& globalData, Structure* structure, SymbolTable* symbolTable, Register* registers)
     70             : JSNonFinalObject(globalData, structure)
     71             , m_symbolTable(symbolTable)
     72             , m_registers(reinterpret_cast<WriteBarrier<Unknown>*>(registers))
     73         {
     74             ASSERT(m_symbolTable);
     75             COMPILE_ASSERT(sizeof(WriteBarrier<Unknown>) == sizeof(Register), Register_should_be_same_size_as_WriteBarrier);
     76         }
     77 
     78         PassOwnArrayPtr<WriteBarrier<Unknown> > copyRegisterArray(JSGlobalData&, WriteBarrier<Unknown>* src, size_t count, size_t callframeStarts);
     79         void setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray);
     80 
     81         bool symbolTableGet(const Identifier&, PropertySlot&);
     82         bool symbolTableGet(const Identifier&, PropertyDescriptor&);
     83         bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable);
     84         bool symbolTablePut(JSGlobalData&, const Identifier&, JSValue);
     85         bool symbolTablePutWithAttributes(JSGlobalData&, const Identifier&, JSValue, unsigned attributes);
     86 
     87         SymbolTable* m_symbolTable; // Maps name -> offset from "r" in register file.
     88         WriteBarrier<Unknown>* m_registers; // "r" in the register file.
     89         OwnArrayPtr<WriteBarrier<Unknown> > m_registerArray; // Independent copy of registers, used when a variable object copies its registers out of the register file.
     90     };
     91 
     92     inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot)
     93     {
     94         SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
     95         if (!entry.isNull()) {
     96             slot.setValue(registerAt(entry.getIndex()).get());
     97             return true;
     98         }
     99         return false;
    100     }
    101 
    102     inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
    103     {
    104         SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
    105         if (!entry.isNull()) {
    106             slot.setValue(registerAt(entry.getIndex()).get());
    107             slotIsWriteable = !entry.isReadOnly();
    108             return true;
    109         }
    110         return false;
    111     }
    112 
    113     inline bool JSVariableObject::symbolTablePut(JSGlobalData& globalData, const Identifier& propertyName, JSValue value)
    114     {
    115         ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
    116 
    117         SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
    118         if (entry.isNull())
    119             return false;
    120         if (entry.isReadOnly())
    121             return true;
    122         registerAt(entry.getIndex()).set(globalData, this, value);
    123         return true;
    124     }
    125 
    126     inline bool JSVariableObject::symbolTablePutWithAttributes(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes)
    127     {
    128         ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
    129 
    130         SymbolTable::iterator iter = symbolTable().find(propertyName.impl());
    131         if (iter == symbolTable().end())
    132             return false;
    133         SymbolTableEntry& entry = iter->second;
    134         ASSERT(!entry.isNull());
    135         entry.setAttributes(attributes);
    136         registerAt(entry.getIndex()).set(globalData, this, value);
    137         return true;
    138     }
    139 
    140     inline PassOwnArrayPtr<WriteBarrier<Unknown> > JSVariableObject::copyRegisterArray(JSGlobalData& globalData, WriteBarrier<Unknown>* src, size_t count, size_t callframeStarts)
    141     {
    142         OwnArrayPtr<WriteBarrier<Unknown> > registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[count]);
    143         for (size_t i = 0; i < callframeStarts; i++)
    144             registerArray[i].set(globalData, this, src[i].get());
    145         for (size_t i = callframeStarts + RegisterFile::CallFrameHeaderSize; i < count; i++)
    146             registerArray[i].set(globalData, this, src[i].get());
    147 
    148         return registerArray.release();
    149     }
    150 
    151     inline void JSVariableObject::setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray)
    152     {
    153         ASSERT(registerArray != m_registerArray);
    154         m_registerArray = registerArray;
    155         m_registers = registers;
    156     }
    157 
    158 } // namespace JSC
    159 
    160 #endif // JSVariableObject_h
    161