DFG should be able to set watchpoints on global variables
[WebKit-https.git] / Source / JavaScriptCore / runtime / JSSymbolTableObject.h
1 /*
2  * Copyright (C) 2012 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 JSSymbolTableObject_h
30 #define JSSymbolTableObject_h
31
32 #include "JSObject.h"
33 #include "PropertyDescriptor.h"
34 #include "SymbolTable.h"
35
36 namespace JSC {
37
38 class JSSymbolTableObject : public JSNonFinalObject {
39 public:
40     typedef JSNonFinalObject Base;
41     
42     SymbolTable& symbolTable() const { return *m_symbolTable; }
43     
44     JS_EXPORT_PRIVATE static void destroy(JSCell*);
45     
46     static NO_RETURN_DUE_TO_ASSERT void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes);
47     
48     JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
49     JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
50     
51     bool isDynamicScope(bool& requiresDynamicChecks) const;
52     
53 protected:
54     static const unsigned StructureFlags = OverridesGetPropertyNames | JSNonFinalObject::StructureFlags;
55     
56     JSSymbolTableObject(JSGlobalData& globalData, Structure* structure, SymbolTable* symbolTable)
57         : JSNonFinalObject(globalData, structure)
58         , m_symbolTable(symbolTable)
59     {
60     }
61     
62     void finishCreation(JSGlobalData& globalData)
63     {
64         Base::finishCreation(globalData);
65         ASSERT(m_symbolTable);
66     }
67     
68     SymbolTable* m_symbolTable;
69 };
70
71 template<typename SymbolTableObjectType>
72 inline bool symbolTableGet(
73     SymbolTableObjectType* object, PropertyName propertyName, PropertySlot& slot)
74 {
75     SymbolTable& symbolTable = object->symbolTable();
76     SymbolTable::iterator iter = symbolTable.find(propertyName.publicName());
77     if (iter == symbolTable.end())
78         return false;
79     SymbolTableEntry::Fast entry = iter->second;
80     ASSERT(!entry.isNull());
81     slot.setValue(object->registerAt(entry.getIndex()).get());
82     return true;
83 }
84
85 template<typename SymbolTableObjectType>
86 inline bool symbolTableGet(
87     SymbolTableObjectType* object, PropertyName propertyName, PropertyDescriptor& descriptor)
88 {
89     SymbolTable& symbolTable = object->symbolTable();
90     SymbolTable::iterator iter = symbolTable.find(propertyName.publicName());
91     if (iter == symbolTable.end())
92         return false;
93     SymbolTableEntry::Fast entry = iter->second;
94     ASSERT(!entry.isNull());
95     descriptor.setDescriptor(
96         object->registerAt(entry.getIndex()).get(), entry.getAttributes() | DontDelete);
97     return true;
98 }
99
100 template<typename SymbolTableObjectType>
101 inline bool symbolTableGet(
102     SymbolTableObjectType* object, PropertyName propertyName, PropertySlot& slot,
103     bool& slotIsWriteable)
104 {
105     SymbolTable& symbolTable = object->symbolTable();
106     SymbolTable::iterator iter = symbolTable.find(propertyName.publicName());
107     if (iter == symbolTable.end())
108         return false;
109     SymbolTableEntry::Fast entry = iter->second;
110     ASSERT(!entry.isNull());
111     slot.setValue(object->registerAt(entry.getIndex()).get());
112     slotIsWriteable = !entry.isReadOnly();
113     return true;
114 }
115
116 template<typename SymbolTableObjectType>
117 inline bool symbolTablePut(
118     SymbolTableObjectType* object, ExecState* exec, PropertyName propertyName, JSValue value,
119     bool shouldThrow)
120 {
121     JSGlobalData& globalData = exec->globalData();
122     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object));
123     
124     SymbolTable& symbolTable = object->symbolTable();
125     SymbolTable::iterator iter = symbolTable.find(propertyName.publicName());
126     if (iter == symbolTable.end())
127         return false;
128     bool wasFat;
129     SymbolTableEntry::Fast fastEntry = iter->second.getFast(wasFat);
130     ASSERT(!fastEntry.isNull());
131     if (fastEntry.isReadOnly()) {
132         if (shouldThrow)
133             throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
134         return true;
135     }
136     if (UNLIKELY(wasFat))
137         iter->second.notifyWrite();
138     object->registerAt(fastEntry.getIndex()).set(globalData, object, value);
139     return true;
140 }
141
142 template<typename SymbolTableObjectType>
143 inline bool symbolTablePutWithAttributes(
144     SymbolTableObjectType* object, JSGlobalData& globalData, PropertyName propertyName,
145     JSValue value, unsigned attributes)
146 {
147     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object));
148     
149     SymbolTable::iterator iter = object->symbolTable().find(propertyName.publicName());
150     if (iter == object->symbolTable().end())
151         return false;
152     SymbolTableEntry& entry = iter->second;
153     ASSERT(!entry.isNull());
154     entry.notifyWrite();
155     entry.setAttributes(attributes);
156     object->registerAt(entry.getIndex()).set(globalData, object, value);
157     return true;
158 }
159
160 } // namespace JSC
161
162 #endif // JSSymbolTableObject_h
163