]> git.saurik.com Git - apple/javascriptcore.git/blame - runtime/JSSymbolTableObject.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / runtime / JSSymbolTableObject.h
CommitLineData
93a37866 1/*
ed1e77d3 2 * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
93a37866
A
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.
81345200 13 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
93a37866
A
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 "JSScope.h"
33#include "PropertyDescriptor.h"
34#include "SymbolTable.h"
ed1e77d3 35#include "VariableWriteFireDetail.h"
93a37866
A
36
37namespace JSC {
38
ed1e77d3
A
39class JSSymbolTableObject;
40
93a37866
A
41class JSSymbolTableObject : public JSScope {
42public:
43 typedef JSScope Base;
ed1e77d3 44 static const unsigned StructureFlags = Base::StructureFlags | IsEnvironmentRecord | OverridesGetPropertyNames;
93a37866 45
81345200 46 SymbolTable* symbolTable() const { return m_symbolTable.get(); }
93a37866
A
47
48 JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
49 JS_EXPORT_PRIVATE static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
50
ed1e77d3
A
51 static ptrdiff_t offsetOfSymbolTable() { return OBJECT_OFFSETOF(JSSymbolTableObject, m_symbolTable); }
52
93a37866 53protected:
ed1e77d3
A
54 JSSymbolTableObject(VM& vm, Structure* structure, JSScope* scope)
55 : Base(vm, structure, scope)
56 {
57 }
93a37866 58
ed1e77d3 59 JSSymbolTableObject(VM& vm, Structure* structure, JSScope* scope, SymbolTable* symbolTable)
93a37866
A
60 : Base(vm, structure, scope)
61 {
ed1e77d3
A
62 ASSERT(symbolTable);
63 setSymbolTable(vm, symbolTable);
93a37866 64 }
ed1e77d3
A
65
66 void setSymbolTable(VM& vm, SymbolTable* symbolTable)
93a37866 67 {
ed1e77d3
A
68 ASSERT(!m_symbolTable);
69 symbolTable->singletonScope()->notifyWrite(vm, this, "Allocated a scope");
70 m_symbolTable.set(vm, this, symbolTable);
93a37866 71 }
ed1e77d3 72
93a37866 73 static void visitChildren(JSCell*, SlotVisitor&);
ed1e77d3
A
74
75private:
81345200 76 WriteBarrier<SymbolTable> m_symbolTable;
93a37866
A
77};
78
79template<typename SymbolTableObjectType>
80inline bool symbolTableGet(
81 SymbolTableObjectType* object, PropertyName propertyName, PropertySlot& slot)
82{
83 SymbolTable& symbolTable = *object->symbolTable();
81345200
A
84 ConcurrentJITLocker locker(symbolTable.m_lock);
85 SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.uid());
86 if (iter == symbolTable.end(locker))
93a37866
A
87 return false;
88 SymbolTableEntry::Fast entry = iter->value;
89 ASSERT(!entry.isNull());
ed1e77d3 90 slot.setValue(object, entry.getAttributes() | DontDelete, object->variableAt(entry.scopeOffset()).get());
93a37866
A
91 return true;
92}
93
94template<typename SymbolTableObjectType>
95inline bool symbolTableGet(
96 SymbolTableObjectType* object, PropertyName propertyName, PropertyDescriptor& descriptor)
97{
98 SymbolTable& symbolTable = *object->symbolTable();
81345200
A
99 ConcurrentJITLocker locker(symbolTable.m_lock);
100 SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.uid());
101 if (iter == symbolTable.end(locker))
93a37866
A
102 return false;
103 SymbolTableEntry::Fast entry = iter->value;
104 ASSERT(!entry.isNull());
105 descriptor.setDescriptor(
ed1e77d3 106 object->variableAt(entry.scopeOffset()).get(), entry.getAttributes() | DontDelete);
93a37866
A
107 return true;
108}
109
110template<typename SymbolTableObjectType>
111inline bool symbolTableGet(
112 SymbolTableObjectType* object, PropertyName propertyName, PropertySlot& slot,
113 bool& slotIsWriteable)
114{
115 SymbolTable& symbolTable = *object->symbolTable();
81345200
A
116 ConcurrentJITLocker locker(symbolTable.m_lock);
117 SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.uid());
118 if (iter == symbolTable.end(locker))
93a37866
A
119 return false;
120 SymbolTableEntry::Fast entry = iter->value;
121 ASSERT(!entry.isNull());
ed1e77d3 122 slot.setValue(object, entry.getAttributes() | DontDelete, object->variableAt(entry.scopeOffset()).get());
93a37866
A
123 slotIsWriteable = !entry.isReadOnly();
124 return true;
125}
126
127template<typename SymbolTableObjectType>
128inline bool symbolTablePut(
129 SymbolTableObjectType* object, ExecState* exec, PropertyName propertyName, JSValue value,
130 bool shouldThrow)
131{
132 VM& vm = exec->vm();
133 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object));
134
81345200 135 WriteBarrierBase<Unknown>* reg;
ed1e77d3 136 WatchpointSet* set;
81345200
A
137 {
138 SymbolTable& symbolTable = *object->symbolTable();
139 // FIXME: This is very suspicious. We shouldn't need a GC-safe lock here.
140 // https://bugs.webkit.org/show_bug.cgi?id=134601
141 GCSafeConcurrentJITLocker locker(symbolTable.m_lock, exec->vm().heap);
142 SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.uid());
143 if (iter == symbolTable.end(locker))
144 return false;
145 bool wasFat;
146 SymbolTableEntry::Fast fastEntry = iter->value.getFast(wasFat);
147 ASSERT(!fastEntry.isNull());
148 if (fastEntry.isReadOnly()) {
149 if (shouldThrow)
150 throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
151 return true;
152 }
ed1e77d3
A
153 set = iter->value.watchpointSet();
154 reg = &object->variableAt(fastEntry.scopeOffset());
93a37866 155 }
81345200
A
156 // I'd prefer we not hold lock while executing barriers, since I prefer to reserve
157 // the right for barriers to be able to trigger GC. And I don't want to hold VM
158 // locks while GC'ing.
159 reg->set(vm, object, value);
ed1e77d3
A
160 if (set)
161 VariableWriteFireDetail::touch(set, object, propertyName);
93a37866
A
162 return true;
163}
164
165template<typename SymbolTableObjectType>
166inline bool symbolTablePutWithAttributes(
167 SymbolTableObjectType* object, VM& vm, PropertyName propertyName,
168 JSValue value, unsigned attributes)
169{
170 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object));
81345200
A
171
172 WriteBarrierBase<Unknown>* reg;
ed1e77d3 173 WatchpointSet* set;
81345200
A
174 {
175 SymbolTable& symbolTable = *object->symbolTable();
176 ConcurrentJITLocker locker(symbolTable.m_lock);
177 SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.uid());
178 if (iter == symbolTable.end(locker))
179 return false;
180 SymbolTableEntry& entry = iter->value;
181 ASSERT(!entry.isNull());
ed1e77d3 182 set = entry.watchpointSet();
81345200 183 entry.setAttributes(attributes);
ed1e77d3 184 reg = &object->variableAt(entry.scopeOffset());
81345200
A
185 }
186 reg->set(vm, object, value);
ed1e77d3
A
187 if (set)
188 VariableWriteFireDetail::touch(set, object, propertyName);
93a37866
A
189 return true;
190}
191
192} // namespace JSC
193
194#endif // JSSymbolTableObject_h
195