• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
symbolTable()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 
registerAt(int index)57         WriteBarrier<Unknown>& registerAt(int index) const { return m_registers[index]; }
58 
addressOfRegisters()59         WriteBarrier<Unknown>* const * addressOfRegisters() const { return &m_registers; }
60 
createStructure(JSGlobalData & globalData,JSValue prototype)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 
JSVariableObject(JSGlobalData & globalData,Structure * structure,SymbolTable * symbolTable,Register * registers)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 
symbolTableGet(const Identifier & propertyName,PropertySlot & slot)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 
symbolTableGet(const Identifier & propertyName,PropertySlot & slot,bool & slotIsWriteable)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 
symbolTablePut(JSGlobalData & globalData,const Identifier & propertyName,JSValue value)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 
symbolTablePutWithAttributes(JSGlobalData & globalData,const Identifier & propertyName,JSValue value,unsigned attributes)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 
copyRegisterArray(JSGlobalData & globalData,WriteBarrier<Unknown> * src,size_t count,size_t callframeStarts)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 
setRegisters(WriteBarrier<Unknown> * registers,PassOwnArrayPtr<WriteBarrier<Unknown>> registerArray)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