Changeset 109008 in webkit
- Timestamp:
- Feb 27, 2012 10:29:04 AM (12 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r109001 r109008 1 2012-02-27 Gavin Barraclough <barraclough@apple.com> 2 3 RegExp lastIndex should behave as a regular property 4 https://bugs.webkit.org/show_bug.cgi?id=79446 5 6 Reviewed by Sam Weinig. 7 8 lastIndex should be a regular data descriptor, with the attributes configurable:false, 9 enumerable:false, writable:true. As such, it should be possible to reconfigure writable 10 as false. If the lastIndex property is reconfigured to be read-only, we should respect 11 this correctly. 12 13 * fast/regex/lastIndex-expected.txt: Added. 14 * fast/regex/lastIndex.html: Added. 15 * fast/regex/script-tests/lastIndex.js: Added. 16 - Added test cases for correct handling of lastIndex. 17 1 18 2012-02-27 Adrienne Walker <enne@google.com> 2 19 -
trunk/Source/JavaScriptCore/ChangeLog
r109007 r109008 1 2012-02-27 Gavin Barraclough <barraclough@apple.com> 2 3 RegExp lastIndex should behave as a regular property 4 https://bugs.webkit.org/show_bug.cgi?id=79446 5 6 Reviewed by Sam Weinig. 7 8 lastIndex should be a regular data descriptor, with the attributes configurable:false, 9 enumerable:false, writable:true. As such, it should be possible to reconfigure writable 10 as false. If the lastIndex property is reconfigured to be read-only, we should respect 11 this correctly. 12 13 * runtime/CommonIdentifiers.h: 14 - Removed some unused identifiers, added lastIndex. 15 * runtime/RegExpObject.cpp: 16 (JSC::RegExpObject::getOwnPropertySlot): 17 - lastIndex is no longer a static value, provided specific handling. 18 (JSC::RegExpObject::getOwnPropertyDescriptor): 19 - lastIndex is no longer a static value, provided specific handling. 20 (JSC::RegExpObject::deleteProperty): 21 - lastIndex is no longer a static value, provided specific handling. 22 (JSC::RegExpObject::getOwnPropertyNames): 23 - lastIndex is no longer a static value, provided specific handling. 24 (JSC::RegExpObject::getPropertyNames): 25 - lastIndex is no longer a static value, provided specific handling. 26 (JSC::reject): 27 - helper function for defineOwnProperty. 28 (JSC::RegExpObject::defineOwnProperty): 29 - lastIndex is no longer a static value, provided specific handling. 30 (JSC::RegExpObject::put): 31 - lastIndex is no longer a static value, provided specific handling. 32 (JSC::RegExpObject::match): 33 - Pass setLastIndex an ExecState, so it can throw if read-only. 34 * runtime/RegExpObject.h: 35 (JSC::RegExpObject::setLastIndex): 36 - Pass setLastIndex an ExecState, so it can throw if read-only. 37 (RegExpObjectData): 38 - Added lastIndexIsWritable. 39 * runtime/RegExpPrototype.cpp: 40 (JSC::regExpProtoFuncCompile): 41 - Pass setLastIndex an ExecState, so it can throw if read-only. 42 1 43 2012-02-27 Gavin Barraclough <barraclough@apple.com> 2 44 -
trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h
r108112 r109008 28 28 // ways without repeating the list. 29 29 #define JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(macro) \ 30 macro(__defineGetter__) \31 macro(__defineSetter__) \32 macro(__lookupGetter__) \33 macro(__lookupSetter__) \34 30 macro(apply) \ 35 31 macro(arguments) \ … … 53 49 macro(isArray) \ 54 50 macro(isPrototypeOf) \ 51 macro(lastIndex) \ 55 52 macro(length) \ 56 53 macro(message) \ -
trunk/Source/JavaScriptCore/runtime/RegExpObject.cpp
r105698 r109008 41 41 static JSValue regExpObjectMultiline(ExecState*, JSValue, const Identifier&); 42 42 static JSValue regExpObjectSource(ExecState*, JSValue, const Identifier&); 43 static JSValue regExpObjectLastIndex(ExecState*, JSValue, const Identifier&);44 static void setRegExpObjectLastIndex(ExecState*, JSObject*, JSValue);45 43 46 44 } // namespace JSC … … 60 58 multiline regExpObjectMultiline DontDelete|ReadOnly|DontEnum 61 59 source regExpObjectSource DontDelete|ReadOnly|DontEnum 62 lastIndex regExpObjectLastIndex DontDelete|DontEnum63 60 @end 64 61 */ … … 96 93 bool RegExpObject::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot) 97 94 { 95 if (propertyName == exec->propertyNames().lastIndex) { 96 RegExpObject* regExp = asRegExpObject(cell); 97 slot.setValue(regExp, regExp->getLastIndex()); 98 return true; 99 } 98 100 return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), jsCast<RegExpObject*>(cell), propertyName, slot); 99 101 } … … 101 103 bool RegExpObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 102 104 { 105 if (propertyName == exec->propertyNames().lastIndex) { 106 RegExpObject* regExp = asRegExpObject(object); 107 descriptor.setDescriptor(regExp->getLastIndex(), regExp->d->lastIndexIsWritable ? DontDelete | DontEnum : DontDelete | DontEnum | ReadOnly); 108 return true; 109 } 103 110 return getStaticValueDescriptor<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), jsCast<RegExpObject*>(object), propertyName, descriptor); 111 } 112 113 bool RegExpObject::deleteProperty(JSCell* cell, ExecState* exec, const Identifier& propertyName) 114 { 115 if (propertyName == exec->propertyNames().lastIndex) 116 return false; 117 return Base::deleteProperty(cell, exec, propertyName); 118 } 119 120 void RegExpObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) 121 { 122 if (mode == IncludeDontEnumProperties) 123 propertyNames.add(exec->propertyNames().lastIndex); 124 Base::getOwnPropertyNames(object, exec, propertyNames, mode); 125 } 126 127 void RegExpObject::getPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) 128 { 129 if (mode == IncludeDontEnumProperties) 130 propertyNames.add(exec->propertyNames().lastIndex); 131 Base::getPropertyNames(object, exec, propertyNames, mode); 132 } 133 134 static bool reject(ExecState* exec, bool throwException, const char* message) 135 { 136 if (throwException) 137 throwTypeError(exec, message); 138 return false; 139 } 140 141 bool RegExpObject::defineOwnProperty(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool shouldThrow) 142 { 143 if (propertyName == exec->propertyNames().lastIndex) { 144 RegExpObject* regExp = asRegExpObject(object); 145 if (descriptor.configurablePresent() && descriptor.configurable()) 146 return reject(exec, shouldThrow, "Attempting to change configurable attribute of unconfigurable property."); 147 if (descriptor.enumerablePresent() && descriptor.enumerable()) 148 return reject(exec, shouldThrow, "Attempting to change enumerable attribute of unconfigurable property."); 149 if (descriptor.isAccessorDescriptor()) 150 return reject(exec, shouldThrow, "Attempting to change access mechanism for an unconfigurable property."); 151 if (!regExp->d->lastIndexIsWritable) { 152 if (descriptor.writablePresent() && descriptor.writable()) 153 return reject(exec, shouldThrow, "Attempting to change writable attribute of unconfigurable property."); 154 if (!sameValue(exec, regExp->getLastIndex(), descriptor.value())) 155 return reject(exec, shouldThrow, "Attempting to change value of a readonly property."); 156 return true; 157 } 158 if (descriptor.writablePresent() && !descriptor.writable()) 159 regExp->d->lastIndexIsWritable = false; 160 if (descriptor.value()) 161 regExp->setLastIndex(exec, descriptor.value(), false); 162 return true; 163 } 164 165 return Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow); 104 166 } 105 167 … … 201 263 } 202 264 203 JSValue regExpObjectLastIndex(ExecState*, JSValue slotBase, const Identifier&)204 {205 return asRegExpObject(slotBase)->getLastIndex();206 }207 208 265 void RegExpObject::put(JSCell* cell, ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 209 266 { 267 if (propertyName == exec->propertyNames().lastIndex) { 268 asRegExpObject(cell)->setLastIndex(exec, value, slot.isStrictMode()); 269 return; 270 } 210 271 lookupPut<RegExpObject, JSObject>(exec, propertyName, value, ExecState::regExpTable(exec), jsCast<RegExpObject*>(cell), slot); 211 }212 213 void setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValue value)214 {215 asRegExpObject(baseObject)->setLastIndex(exec->globalData(), value);216 272 } 217 273 … … 246 302 lastIndex = jsLastIndex.asUInt32(); 247 303 if (lastIndex > input.length()) { 248 setLastIndex( 0);304 setLastIndex(exec, 0); 249 305 return false; 250 306 } … … 252 308 double doubleLastIndex = jsLastIndex.toInteger(exec); 253 309 if (doubleLastIndex < 0 || doubleLastIndex > input.length()) { 254 setLastIndex( 0);310 setLastIndex(exec, 0); 255 311 return false; 256 312 } … … 262 318 regExpConstructor->performMatch(*globalData, d->regExp.get(), input, lastIndex, position, length); 263 319 if (position < 0) { 264 setLastIndex( 0);320 setLastIndex(exec, 0); 265 321 return false; 266 322 } 267 323 268 setLastIndex( position + length);324 setLastIndex(exec, position + length); 269 325 return true; 270 326 } -
trunk/Source/JavaScriptCore/runtime/RegExpObject.h
r104900 r109008 48 48 RegExp* regExp() const { return d->regExp.get(); } 49 49 50 void setLastIndex( size_t lastIndex)50 void setLastIndex(ExecState* exec, size_t lastIndex) 51 51 { 52 52 d->lastIndex.setWithoutWriteBarrier(jsNumber(lastIndex)); 53 if (LIKELY(d->lastIndexIsWritable)) 54 d->lastIndex.setWithoutWriteBarrier(jsNumber(lastIndex)); 55 else 56 throwTypeError(exec, StrictModeReadonlyPropertyWriteError); 53 57 } 54 void setLastIndex( JSGlobalData& globalData, JSValue lastIndex)58 void setLastIndex(ExecState* exec, JSValue lastIndex, bool shouldThrow) 55 59 { 56 d->lastIndex.set(globalData, this, lastIndex); 60 if (LIKELY(d->lastIndexIsWritable)) 61 d->lastIndex.set(exec->globalData(), this, lastIndex); 62 else if (shouldThrow) 63 throwTypeError(exec, StrictModeReadonlyPropertyWriteError); 57 64 } 58 65 JSValue getLastIndex() const … … 84 91 static void visitChildren(JSCell*, SlotVisitor&); 85 92 93 JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, const Identifier& propertyName); 94 JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 95 JS_EXPORT_PRIVATE static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 96 JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, const Identifier& propertyName, PropertyDescriptor&, bool shouldThrow); 97 86 98 private: 87 99 bool match(ExecState*); … … 92 104 RegExpObjectData(JSGlobalData& globalData, RegExpObject* owner, RegExp* regExp) 93 105 : regExp(globalData, owner, regExp) 106 , lastIndexIsWritable(true) 94 107 { 95 108 lastIndex.setWithoutWriteBarrier(jsNumber(0)); … … 98 111 WriteBarrier<RegExp> regExp; 99 112 WriteBarrier<Unknown> lastIndex; 113 bool lastIndexIsWritable; 100 114 }; 101 115 #if COMPILER(MSVC) -
trunk/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
r105698 r109008 130 130 131 131 asRegExpObject(thisValue)->setRegExp(exec->globalData(), regExp); 132 asRegExpObject(thisValue)->setLastIndex( 0);132 asRegExpObject(thisValue)->setLastIndex(exec, 0); 133 133 return JSValue::encode(jsUndefined()); 134 134 }
Note: See TracChangeset
for help on using the changeset viewer.