Changeset 128680 in webkit for trunk/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp
- Timestamp:
- Sep 14, 2012, 8:29:04 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp
r128400 r128680 28 28 29 29 #include "ClassInfo.h" 30 #include "SparseArrayValueMapInlineMethods.h" 30 #include "GetterSetter.h" 31 #include "JSObject.h" 32 #include "PropertySlot.h" 33 #include "Reject.h" 34 #include "SlotVisitor.h" 35 #include "Structure.h" 31 36 32 37 namespace JSC { … … 34 39 const ClassInfo SparseArrayValueMap::s_info = { "SparseArrayValueMap", 0, 0, 0, CREATE_METHOD_TABLE(SparseArrayValueMap) }; 35 40 41 SparseArrayValueMap::SparseArrayValueMap(JSGlobalData& globalData) 42 : Base(globalData, globalData.sparseArrayValueMapStructure.get()) 43 , m_flags(Normal) 44 , m_reportedCapacity(0) 45 { 46 } 47 48 SparseArrayValueMap::~SparseArrayValueMap() 49 { 50 } 51 52 void SparseArrayValueMap::finishCreation(JSGlobalData& globalData) 53 { 54 Base::finishCreation(globalData); 55 } 56 57 SparseArrayValueMap* SparseArrayValueMap::create(JSGlobalData& globalData) 58 { 59 SparseArrayValueMap* result = new (NotNull, allocateCell<SparseArrayValueMap>(globalData.heap)) SparseArrayValueMap(globalData); 60 result->finishCreation(globalData); 61 return result; 62 } 63 64 void SparseArrayValueMap::destroy(JSCell* cell) 65 { 66 static_cast<SparseArrayValueMap*>(cell)->SparseArrayValueMap::~SparseArrayValueMap(); 67 } 68 69 Structure* SparseArrayValueMap::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) 70 { 71 return Structure::create(globalData, globalObject, prototype, TypeInfo(CompoundType, StructureFlags), &s_info); 72 } 73 74 SparseArrayValueMap::AddResult SparseArrayValueMap::add(JSObject* array, unsigned i) 75 { 76 SparseArrayEntry entry; 77 entry.setWithoutWriteBarrier(jsUndefined()); 78 79 AddResult result = m_map.add(i, entry); 80 size_t capacity = m_map.capacity(); 81 if (capacity != m_reportedCapacity) { 82 Heap::heap(array)->reportExtraMemoryCost((capacity - m_reportedCapacity) * (sizeof(unsigned) + sizeof(WriteBarrier<Unknown>))); 83 m_reportedCapacity = capacity; 84 } 85 return result; 86 } 87 88 void SparseArrayValueMap::putEntry(ExecState* exec, JSObject* array, unsigned i, JSValue value, bool shouldThrow) 89 { 90 AddResult result = add(array, i); 91 SparseArrayEntry& entry = result.iterator->second; 92 93 // To save a separate find & add, we first always add to the sparse map. 94 // In the uncommon case that this is a new property, and the array is not 95 // extensible, this is not the right thing to have done - so remove again. 96 if (result.isNewEntry && !array->isExtensible()) { 97 remove(result.iterator); 98 if (shouldThrow) 99 throwTypeError(exec, StrictModeReadonlyPropertyWriteError); 100 return; 101 } 102 103 if (!(entry.attributes & Accessor)) { 104 if (entry.attributes & ReadOnly) { 105 if (shouldThrow) 106 throwTypeError(exec, StrictModeReadonlyPropertyWriteError); 107 return; 108 } 109 110 entry.set(exec->globalData(), this, value); 111 return; 112 } 113 114 JSValue accessor = entry.SparseArrayEntry::Base::get(); 115 ASSERT(accessor.isGetterSetter()); 116 JSObject* setter = asGetterSetter(accessor)->setter(); 117 118 if (!setter) { 119 if (shouldThrow) 120 throwTypeError(exec, StrictModeReadonlyPropertyWriteError); 121 return; 122 } 123 124 CallData callData; 125 CallType callType = setter->methodTable()->getCallData(setter, callData); 126 MarkedArgumentBuffer args; 127 args.append(value); 128 call(exec, setter, callType, callData, array, args); 129 } 130 131 bool SparseArrayValueMap::putDirect(ExecState* exec, JSObject* array, unsigned i, JSValue value, unsigned attributes, PutDirectIndexMode mode) 132 { 133 AddResult result = add(array, i); 134 SparseArrayEntry& entry = result.iterator->second; 135 136 // To save a separate find & add, we first always add to the sparse map. 137 // In the uncommon case that this is a new property, and the array is not 138 // extensible, this is not the right thing to have done - so remove again. 139 if (mode != PutDirectIndexLikePutDirect && result.isNewEntry && !array->isExtensible()) { 140 remove(result.iterator); 141 return reject(exec, mode == PutDirectIndexShouldThrow, "Attempting to define property on object that is not extensible."); 142 } 143 144 entry.attributes = attributes; 145 entry.set(exec->globalData(), this, value); 146 return true; 147 } 148 149 void SparseArrayEntry::get(PropertySlot& slot) const 150 { 151 JSValue value = Base::get(); 152 ASSERT(value); 153 154 if (LIKELY(!value.isGetterSetter())) { 155 slot.setValue(value); 156 return; 157 } 158 159 JSObject* getter = asGetterSetter(value)->getter(); 160 if (!getter) { 161 slot.setUndefined(); 162 return; 163 } 164 165 slot.setGetterSlot(getter); 166 } 167 168 void SparseArrayEntry::get(PropertyDescriptor& descriptor) const 169 { 170 descriptor.setDescriptor(Base::get(), attributes); 171 } 172 173 JSValue SparseArrayEntry::get(ExecState* exec, JSObject* array) const 174 { 175 JSValue result = Base::get(); 176 ASSERT(result); 177 178 if (LIKELY(!result.isGetterSetter())) 179 return result; 180 181 JSObject* getter = asGetterSetter(result)->getter(); 182 if (!getter) 183 return jsUndefined(); 184 185 CallData callData; 186 CallType callType = getter->methodTable()->getCallData(getter, callData); 187 return call(exec, getter, callType, callData, array, exec->emptyList()); 188 } 189 190 JSValue SparseArrayEntry::getNonSparseMode() const 191 { 192 ASSERT(!attributes); 193 return Base::get(); 194 } 195 196 void SparseArrayValueMap::visitChildren(JSCell* thisObject, SlotVisitor& visitor) 197 { 198 Base::visitChildren(thisObject, visitor); 199 200 SparseArrayValueMap* thisMap = jsCast<SparseArrayValueMap*>(thisObject); 201 iterator end = thisMap->m_map.end(); 202 for (iterator it = thisMap->m_map.begin(); it != end; ++it) 203 visitor.append(&it->second); 204 } 205 36 206 } // namespace JSC 37 207
Note:
See TracChangeset
for help on using the changeset viewer.