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