Changeset 198554 in webkit
- Timestamp:
- Mar 22, 2016 2:42:06 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r198551 r198554 1 2016-03-22 Michael Saboff <msaboff@apple.com> 2 3 [ES6] Implement RegExp.prototype[@@match] 4 https://bugs.webkit.org/show_bug.cgi?id=155711 5 6 Reviewed by Filip Pizlo. 7 8 Updated tests for exception string changes and added Symbol.match. 9 10 * js/Object-getOwnPropertyNames-expected.txt: 11 * js/dom/string-prototype-properties-expected.txt: 12 * js/script-tests/Object-getOwnPropertyNames.js: 13 * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.10_String.prototype.match/S15.5.4.10_A1_T3-expected.txt: 14 1 15 2016-03-22 Daniel Bates <dabates@apple.com> 2 16 -
trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt
r198447 r198554 62 62 PASS getSortedOwnPropertyNames(Math) is ['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','clz32','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc'] 63 63 PASS getSortedOwnPropertyNames(JSON) is ['parse', 'stringify'] 64 PASS getSortedOwnPropertyNames(Symbol) is ['for', 'hasInstance', 'iterator', 'keyFor', 'length', ' name', 'prototype', 'search', 'species', 'toPrimitive', 'toStringTag', 'unscopables']64 PASS getSortedOwnPropertyNames(Symbol) is ['for', 'hasInstance', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'search', 'species', 'toPrimitive', 'toStringTag', 'unscopables'] 65 65 PASS getSortedOwnPropertyNames(Symbol.prototype) is ['constructor', 'toString', 'valueOf'] 66 66 PASS getSortedOwnPropertyNames(Map) is ['length', 'name', 'prototype'] -
trunk/LayoutTests/js/dom/string-prototype-properties-expected.txt
r198171 r198554 11 11 PASS String.prototype.indexOf.call(undefined, '2') threw exception TypeError: Type error. 12 12 PASS String.prototype.lastIndexOf.call(undefined, '2') threw exception TypeError: Type error. 13 PASS String.prototype.match.call(undefined, /2+/) threw exception TypeError: Type error.13 PASS String.prototype.match.call(undefined, /2+/) threw exception TypeError: String.prototype.match requires that |this| not be undefined. 14 14 PASS String.prototype.replace.call(undefined, /2+/, '-') threw exception TypeError: Type error. 15 15 PASS String.prototype.search.call(undefined, '4') threw exception TypeError: String.prototype.search requires that |this| not be undefined. -
trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js
r198447 r198554 71 71 "Math": "['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','clz32','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc']", 72 72 "JSON": "['parse', 'stringify']", 73 "Symbol": "['for', 'hasInstance', 'iterator', 'keyFor', 'length', ' name', 'prototype', 'search', 'species', 'toPrimitive', 'toStringTag', 'unscopables']",73 "Symbol": "['for', 'hasInstance', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'search', 'species', 'toPrimitive', 'toStringTag', 'unscopables']", 74 74 "Symbol.prototype": "['constructor', 'toString', 'valueOf']", 75 75 "Map": "['length', 'name', 'prototype']", -
trunk/LayoutTests/sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.10_String.prototype.match/S15.5.4.10_A1_T3-expected.txt
r153221 r198554 1 1 S15.5.4.10_A1_T3 2 2 3 FAIL TypeError: Type error3 FAIL TypeError: String.prototype.match requires that |this| not be undefined 4 4 5 5 TEST COMPLETE -
trunk/Source/JavaScriptCore/CMakeLists.txt
r198364 r198554 1220 1220 ${JAVASCRIPTCORE_DIR}/builtins/PromisePrototype.js 1221 1221 ${JAVASCRIPTCORE_DIR}/builtins/ReflectObject.js 1222 ${JAVASCRIPTCORE_DIR}/builtins/RegExpPrototype.js 1222 1223 ${JAVASCRIPTCORE_DIR}/builtins/SetPrototype.js 1223 1224 ${JAVASCRIPTCORE_DIR}/builtins/StringConstructor.js -
trunk/Source/JavaScriptCore/ChangeLog
r198531 r198554 1 2016-03-22 Michael Saboff <msaboff@apple.com> 2 3 [ES6] Implement RegExp.prototype[@@match] 4 https://bugs.webkit.org/show_bug.cgi?id=155711 5 6 Reviewed by Filip Pizlo. 7 8 Implemented ES6 spec for String.prototype.match and RegExp.prototype[@@match]. 9 Implemented both as builtins, with String.prototype.match calling 10 RegExp.prototype[@@match]. 11 12 For performance reasons, RegExp.prototype[@@match] has a C++ fast path when 13 RegExp.prototype.exec has not been overridden. This fast path, 14 RegExpObject::matchGlobal, was taken from the prior StringPrototype::match. 15 It only handles global matches. 16 17 Added new test, stress/regexp-match.js. 18 19 Updated various tests for changes exception string and now passing ES6 behavior. 20 21 * CMakeLists.txt: 22 * DerivedSources.make: 23 * JavaScriptCore.xcodeproj/project.pbxproj: 24 Added builtins/RegExpPrototype.js and eliminated RegExpPrototype.lut.h. 25 26 * builtins/RegExpPrototype.js: Added. 27 (match.advanceStringIndexUnicode): Helper. 28 (match): Implements RegExp.prototype[@@match]. 29 * builtins/StringPrototype.js: 30 (match): Implements String.prototype.match. 31 32 * bytecode/BytecodeIntrinsicRegistry.cpp: 33 (JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry): 34 (JSC::BytecodeIntrinsicRegistry::lookup): 35 * bytecode/BytecodeIntrinsicRegistry.h: 36 * runtime/CommonIdentifiers.h: 37 Added Symbol.match and builtins @match and @exec. 38 39 * runtime/RegExpObject.cpp: 40 * runtime/RegExpObject.h: 41 * runtime/RegExpObjectInlines.h: 42 (JSC::RegExpObject::matchGlobal): Added. 43 (JSC::RegExpObject::advanceStringUnicode): Added helper. 44 45 * runtime/RegExpPrototype.cpp: 46 * runtime/RegExpPrototype.h: 47 (JSC::RegExpPrototype::RegExpPrototype): 48 (JSC::RegExpPrototype::finishCreation): 49 (JSC::RegExpPrototype::visitChildren): 50 (JSC::regExpProtoFuncMatchPrivate): 51 (JSC::RegExpPrototype::getOwnPropertySlot): Deleted. 52 (JSC::RegExpPrototype::create): 53 Restructured to create properties explicitly due to having two names for native regExpProtoFuncExec. 54 55 * runtime/StringPrototype.cpp: 56 (JSC::StringPrototype::finishCreation): 57 Made match a builtin. 58 Removed unused declaration of stringProtoFuncSearch() since it was made a builtin. 59 60 * tests/es6.yaml: 61 * tests/stress/regexp-match.js: Added. 62 (shouldBe): 63 (shouldThrow): 64 (errorKey.toString): 65 (primitive.of.primitives.shouldThrow): 66 (testRegExpMatch): 67 (testMatch): 68 (testBoth): 69 (alwaysUnmatch): 70 1 71 2016-03-22 Caitlin Potter <caitp@igalia.com> 2 72 -
trunk/Source/JavaScriptCore/DerivedSources.make
r197781 r198554 100 100 $(JavaScriptCore)/builtins/PromisePrototype.js \ 101 101 $(JavaScriptCore)/builtins/ReflectObject.js \ 102 $(JavaScriptCore)/builtins/RegExpPrototype.js \ 102 103 $(JavaScriptCore)/builtins/SetPrototype.js \ 103 104 $(JavaScriptCore)/builtins/StringConstructor.js \ … … 148 149 ReflectObject.lut.h \ 149 150 RegExpConstructor.lut.h \ 150 RegExpPrototype.lut.h \151 151 SetPrototype.lut.h \ 152 152 StringConstructor.lut.h \ -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r198364 r198554 1465 1465 996B73221BDA08EF00331B84 /* ObjectConstructor.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 996B730E1BD9FA2C00331B84 /* ObjectConstructor.lut.h */; }; 1466 1466 996B73231BDA08EF00331B84 /* ReflectObject.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 996B730F1BD9FA2C00331B84 /* ReflectObject.lut.h */; }; 1467 996B73241BDA08EF00331B84 /* RegExpPrototype.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 996B73101BD9FA2C00331B84 /* RegExpPrototype.lut.h */; };1468 1467 996B73251BDA08EF00331B84 /* StringConstructor.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 996B73111BD9FA2C00331B84 /* StringConstructor.lut.h */; }; 1469 1468 996B73261BDA08EF00331B84 /* StringIteratorPrototype.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 996B73121BD9FA2C00331B84 /* StringIteratorPrototype.lut.h */; }; … … 3356 3355 6546F51F1A32A59C006F07D5 /* NullGetterFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = NullGetterFunction.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; 3357 3356 6546F5201A32A59C006F07D5 /* NullGetterFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NullGetterFunction.h; sourceTree = "<group>"; }; 3357 654788421C937D2C000781A0 /* RegExpPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = RegExpPrototype.js; sourceTree = "<group>"; }; 3358 3358 65525FC31A6DD3B3007B5495 /* NullSetterFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NullSetterFunction.cpp; sourceTree = "<group>"; }; 3359 3359 65525FC41A6DD3B3007B5495 /* NullSetterFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NullSetterFunction.h; sourceTree = "<group>"; }; … … 3670 3670 996B730E1BD9FA2C00331B84 /* ObjectConstructor.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectConstructor.lut.h; sourceTree = "<group>"; }; 3671 3671 996B730F1BD9FA2C00331B84 /* ReflectObject.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReflectObject.lut.h; sourceTree = "<group>"; }; 3672 996B73101BD9FA2C00331B84 /* RegExpPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpPrototype.lut.h; sourceTree = "<group>"; };3673 3672 996B73111BD9FA2C00331B84 /* StringConstructor.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringConstructor.lut.h; sourceTree = "<group>"; }; 3674 3673 996B73121BD9FA2C00331B84 /* StringIteratorPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringIteratorPrototype.lut.h; sourceTree = "<group>"; }; … … 5371 5370 BCD202D50E170708002C7E82 /* RegExpConstructor.lut.h */, 5372 5371 A718F61A11754A21002465A7 /* RegExpJitTables.h */, 5373 996B73101BD9FA2C00331B84 /* RegExpPrototype.lut.h */,5374 5372 7035587F1C418458004BD7BF /* SetPrototype.lut.h */, 5375 5373 996B73111BD9FA2C00331B84 /* StringConstructor.lut.h */, … … 6844 6842 7CF9BC5E1B65D9B1009DB1EF /* PromiseConstructor.js */, 6845 6843 7CF9BC5F1B65D9B1009DB1EF /* ReflectObject.js */, 6844 654788421C937D2C000781A0 /* RegExpPrototype.js */, 6846 6845 7035587D1C418419004BD7BF /* SetPrototype.js */, 6847 6846 7CF9BC601B65D9B1009DB1EF /* StringConstructor.js */, … … 7898 7897 BC18C45B0E16F5CD00B34460 /* RegExpObject.h in Headers */, 7899 7898 BCD202C40E1706A7002C7E82 /* RegExpPrototype.h in Headers */, 7900 996B73241BDA08EF00331B84 /* RegExpPrototype.lut.h in Headers */,7901 7899 BC18C45D0E16F5CD00B34460 /* Register.h in Headers */, 7902 7900 969A072B0ED1CE6900F1F681 /* RegisterID.h in Headers */, -
trunk/Source/JavaScriptCore/builtins/StringPrototype.js
r198171 r198554 27 27 // @conditional=ENABLE(INTL) 28 28 29 function match(regexp) 30 { 31 "use strict"; 32 33 if (this == null) { 34 if (this === null) 35 throw new @TypeError("String.prototype.match requires that |this| not be null"); 36 throw new @TypeError("String.prototype.match requires that |this| not be undefined"); 37 } 38 39 if (regexp != null) { 40 var matcher = regexp[@symbolMatch]; 41 if (matcher !== @undefined) 42 return matcher.@call(regexp, this); 43 } 44 45 let thisString = @toString(this); 46 let createdRegExp = new @RegExp(regexp, @undefined); 47 return createdRegExp[@symbolMatch](thisString); 48 } 49 29 50 function search(regexp) 30 51 { -
trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp
r196950 r198554 52 52 m_promiseStateRejected.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Status::Rejected))); 53 53 m_symbolIterator.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->iteratorSymbol.impl()))); 54 m_symbolMatch.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->matchSymbol.impl()))); 54 55 m_symbolSearch.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->searchSymbol.impl()))); 55 56 m_symbolSpecies.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->speciesSymbol.impl()))); -
trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h
r196950 r198554 54 54 macro(promiseStateRejected) \ 55 55 macro(symbolIterator) \ 56 macro(symbolMatch) \ 56 57 macro(symbolSearch) \ 57 58 macro(symbolSpecies) -
trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h
r198192 r198554 275 275 #define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL_NOT_IMPLEMENTED_YET(macro)\ 276 276 macro(isConcatSpreadable) \ 277 macro(match) \278 277 macro(replace) \ 279 macro(split) \278 macro(split) 280 279 281 280 #define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(macro) \ 282 281 macro(hasInstance) \ 283 282 macro(iterator) \ 283 macro(match) \ 284 284 macro(search) \ 285 285 macro(species) \ … … 353 353 macro(Float32Array) \ 354 354 macro(Float64Array) \ 355 macro(exec) \ 355 356 macro(generator) \ 356 357 macro(generatorNext) \ -
trunk/Source/JavaScriptCore/runtime/RegExpObject.cpp
r198270 r198554 170 170 } 171 171 172 JSValue RegExpObject::matchGlobal(ExecState* exec, JSGlobalObject* globalObject, JSString* string) 173 { 174 RegExp* regExp = this->regExp(); 175 176 ASSERT(regExp->global()); 177 178 VM* vm = &globalObject->vm(); 179 180 setLastIndex(exec, 0); 181 if (exec->hadException()) 182 return jsUndefined(); 183 184 String s = string->value(exec); 185 RegExpConstructor* regExpConstructor = globalObject->regExpConstructor(); 186 MatchResult result = regExpConstructor->performMatch(*vm, regExp, string, s, 0); 187 188 // return array of matches 189 MarkedArgumentBuffer list; 190 // We defend ourselves from crazy. 191 const size_t maximumReasonableMatchSize = 1000000000; 192 193 if (regExp->unicode()) { 194 while (result) { 195 if (list.size() > maximumReasonableMatchSize) { 196 throwOutOfMemoryError(exec); 197 return jsUndefined(); 198 } 199 200 size_t end = result.end; 201 size_t length = end - result.start; 202 list.append(jsSubstring(exec, s, result.start, length)); 203 if (!length) 204 end = advanceStringUnicode(s, length, end); 205 result = regExpConstructor->performMatch(*vm, regExp, string, s, end); 206 } 207 } else { 208 while (result) { 209 if (list.size() > maximumReasonableMatchSize) { 210 throwOutOfMemoryError(exec); 211 return jsUndefined(); 212 } 213 214 size_t end = result.end; 215 size_t length = end - result.start; 216 list.append(jsSubstring(exec, s, result.start, length)); 217 if (!length) 218 ++end; 219 result = regExpConstructor->performMatch(*vm, regExp, string, s, end); 220 } 221 } 222 223 if (list.isEmpty()) { 224 // if there are no matches at all, it's important to return 225 // Null instead of an empty array, because this matches 226 // other browsers and because Null is a false value. 227 return jsNull(); 228 } 229 230 return constructArray(exec, static_cast<ArrayAllocationProfile*>(0), list); 231 } 232 172 233 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/RegExpObject.h
r198023 r198554 71 71 JSValue exec(ExecState*, JSGlobalObject*, JSString*); 72 72 JSValue execInline(ExecState*, JSGlobalObject*, JSString*); 73 MatchResult match(ExecState*, JSGlobalObject*, JSString*); 74 JSValue matchGlobal(ExecState*, JSGlobalObject*, JSString*); 73 75 74 76 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); … … 103 105 JS_EXPORT_PRIVATE static void getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 104 106 JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow); 107 unsigned advanceStringUnicode(String, unsigned, unsigned); 105 108 106 109 private: 107 MatchResult match(ExecState*, JSGlobalObject*, JSString*);108 110 MatchResult matchInline(ExecState*, JSGlobalObject*, JSString*); 109 111 -
trunk/Source/JavaScriptCore/runtime/RegExpObjectInlines.h
r197869 r198554 109 109 } 110 110 111 unsigned RegExpObject::advanceStringUnicode(String s, unsigned length, unsigned currentIndex) 112 { 113 if (currentIndex + 1 >= length) 114 return currentIndex + 1; 115 116 UChar first = s[currentIndex]; 117 if (first < 0xD800 || first > 0xDBFF) 118 return currentIndex + 1; 119 120 UChar second = s[currentIndex]; 121 if (second < 0xDC00 || second > 0xDFFF) 122 return currentIndex + 1; 123 124 return currentIndex + 2; 125 } 126 111 127 } // namespace JSC 112 128 -
trunk/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
r198447 r198554 23 23 24 24 #include "ArrayPrototype.h" 25 #include "BuiltinNames.h" 25 26 #include "Error.h" 26 27 #include "JSArray.h" 28 #include "JSCBuiltins.h" 27 29 #include "JSCJSValue.h" 28 30 #include "JSFunction.h" … … 37 39 #include "RegExpCache.h" 38 40 #include "RegExpConstructor.h" 41 #include "RegExpMatchesArray.h" 39 42 #include "StringRecursionChecker.h" 40 43 … … 43 46 static EncodedJSValue JSC_HOST_CALL regExpProtoFuncTest(ExecState*); 44 47 static EncodedJSValue JSC_HOST_CALL regExpProtoFuncExec(ExecState*); 48 static EncodedJSValue JSC_HOST_CALL regExpProtoFuncMatchPrivate(ExecState*); 45 49 static EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState*); 46 50 static EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState*); … … 54 58 static EncodedJSValue JSC_HOST_CALL regExpProtoGetterFlags(ExecState*); 55 59 56 } 57 58 #include "RegExpPrototype.lut.h" 59 60 namespace JSC { 61 62 const ClassInfo RegExpPrototype::s_info = { "Object", &Base::s_info, ®ExpPrototypeTable, CREATE_METHOD_TABLE(RegExpPrototype) }; 63 64 /* Source for RegExpPrototype.lut.h 65 @begin regExpPrototypeTable 66 compile regExpProtoFuncCompile DontEnum|Function 2 67 exec regExpProtoFuncExec DontEnum|Function 1 68 test regExpProtoFuncTest DontEnum|Function 1 69 toString regExpProtoFuncToString DontEnum|Function 0 70 global regExpProtoGetterGlobal DontEnum|Accessor 71 ignoreCase regExpProtoGetterIgnoreCase DontEnum|Accessor 72 multiline regExpProtoGetterMultiline DontEnum|Accessor 73 sticky regExpProtoGetterSticky DontEnum|Accessor 74 unicode regExpProtoGetterUnicode DontEnum|Accessor 75 source regExpProtoGetterSource DontEnum|Accessor 76 flags regExpProtoGetterFlags DontEnum|Accessor 77 @end 78 */ 60 const ClassInfo RegExpPrototype::s_info = { "Object", &Base::s_info, 0, CREATE_METHOD_TABLE(RegExpPrototype) }; 79 61 80 62 RegExpPrototype::RegExpPrototype(VM& vm, Structure* structure) … … 87 69 Base::finishCreation(vm); 88 70 ASSERT(inherits(info())); 89 JSC_NATIVE_FUNCTION(vm.propertyNames->searchSymbol, regExpProtoFuncSearch, DontEnum, 1); 71 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->compile, regExpProtoFuncCompile, DontEnum, 2); 72 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->test, regExpProtoFuncTest, DontEnum, 1); 73 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->toString, regExpProtoFuncToString, DontEnum, 0); 74 JSC_NATIVE_GETTER(vm.propertyNames->global, regExpProtoGetterGlobal, DontEnum | Accessor); 75 JSC_NATIVE_GETTER(vm.propertyNames->ignoreCase, regExpProtoGetterIgnoreCase, DontEnum | Accessor); 76 JSC_NATIVE_GETTER(vm.propertyNames->multiline, regExpProtoGetterMultiline, DontEnum | Accessor); 77 JSC_NATIVE_GETTER(vm.propertyNames->sticky, regExpProtoGetterSticky, DontEnum | Accessor); 78 JSC_NATIVE_GETTER(vm.propertyNames->unicode, regExpProtoGetterUnicode, DontEnum | Accessor); 79 JSC_NATIVE_GETTER(vm.propertyNames->source, regExpProtoGetterSource, DontEnum | Accessor); 80 JSC_NATIVE_GETTER(vm.propertyNames->flags, regExpProtoGetterFlags, DontEnum | Accessor); 81 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().matchPrivateName(), regExpProtoFuncMatchPrivate, DontEnum | DontDelete | ReadOnly, 1); 82 JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->matchSymbol, regExpPrototypeMatchCodeGenerator, DontEnum); 83 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->searchSymbol, regExpProtoFuncSearch, DontEnum, 1); 84 85 JSFunction* execFunction = JSFunction::create(vm, globalObject, 1, vm.propertyNames->exec.string(), regExpProtoFuncExec, RegExpExecIntrinsic); 86 putDirectWithoutTransition(vm, vm.propertyNames->execPrivateName, execFunction, DontEnum | DontDelete | ReadOnly); 87 putDirectWithoutTransition(vm, vm.propertyNames->exec, execFunction, DontEnum); 90 88 91 89 m_emptyRegExp.set(vm, this, RegExp::create(vm, "", NoFlags)); 92 }93 94 bool RegExpPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)95 {96 return getStaticFunctionSlot<Base>(exec, regExpPrototypeTable, jsCast<RegExpPrototype*>(object), propertyName, slot);97 90 } 98 91 … … 128 121 return JSValue::encode(jsUndefined()); 129 122 return JSValue::encode(asRegExpObject(thisValue)->exec(exec, exec->lexicalGlobalObject(), string)); 123 } 124 125 EncodedJSValue JSC_HOST_CALL regExpProtoFuncMatchPrivate(ExecState* exec) 126 { 127 JSValue thisValue = exec->thisValue(); 128 if (!thisValue.inherits(RegExpObject::info())) 129 return throwVMTypeError(exec); 130 JSString* string = exec->argument(0).toStringOrNull(exec); 131 if (!string) 132 return JSValue::encode(jsUndefined()); 133 return JSValue::encode(asRegExpObject(thisValue)->matchGlobal(exec, exec->lexicalGlobalObject(), string)); 130 134 } 131 135 -
trunk/Source/JavaScriptCore/runtime/RegExpPrototype.h
r198447 r198554 30 30 public: 31 31 typedef JSNonFinalObject Base; 32 static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;32 static const unsigned StructureFlags = Base::StructureFlags; 33 33 34 34 static RegExpPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure) … … 55 55 private: 56 56 void finishCreation(VM&, JSGlobalObject*); 57 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);58 57 59 58 WriteBarrier<RegExp> m_emptyRegExp; -
trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp
r198364 r198554 67 67 EncodedJSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState*); 68 68 EncodedJSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState*); 69 EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState*);70 69 EncodedJSValue JSC_HOST_CALL stringProtoFuncRepeat(ExecState*); 71 70 EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState*); 72 EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState*);73 71 EncodedJSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState*); 74 72 EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState*); … … 112 110 /* Source for StringConstructor.lut.h 113 111 @begin stringPrototypeTable 112 match JSBuiltin DontEnum|Function 1 114 113 search JSBuiltin DontEnum|Function 1 115 114 @end … … 135 134 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("indexOf", stringProtoFuncIndexOf, DontEnum, 1); 136 135 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("lastIndexOf", stringProtoFuncLastIndexOf, DontEnum, 1); 137 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("match", stringProtoFuncMatch, DontEnum, 1);138 136 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("repeat", stringProtoFuncRepeat, DontEnum, 1); 139 137 JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION("replace", stringProtoFuncReplace, DontEnum, 2, StringPrototypeReplaceIntrinsic); … … 1031 1029 } 1032 1030 1033 EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec)1034 {1035 JSValue thisValue = exec->thisValue();1036 if (!checkObjectCoercible(thisValue))1037 return throwVMTypeError(exec);1038 JSString* string = thisValue.toString(exec);1039 String s = string->value(exec);1040 JSGlobalObject* globalObject = exec->lexicalGlobalObject();1041 VM* vm = &globalObject->vm();1042 1043 JSValue a0 = exec->argument(0);1044 1045 RegExp* regExp;1046 unsigned startOffset = 0;1047 bool global = false;1048 bool sticky = false;1049 RegExpObject* regExpObject = nullptr;1050 if (a0.inherits(RegExpObject::info())) {1051 regExpObject = asRegExpObject(a0);1052 regExp = regExpObject->regExp();1053 if ((global = regExp->global())) {1054 // ES6 21.2.5.6 step 6.b.1055 regExpObject->setLastIndex(exec, 0);1056 if (exec->hadException())1057 return JSValue::encode(jsUndefined());1058 }1059 sticky = regExp->sticky();1060 if (!global && sticky) {1061 JSValue jsLastIndex = regExpObject->getLastIndex();1062 unsigned lastIndex;1063 if (LIKELY(jsLastIndex.isUInt32())) {1064 lastIndex = jsLastIndex.asUInt32();1065 if (lastIndex > s.length()) {1066 regExpObject->setLastIndex(exec, 0);1067 return JSValue::encode(jsUndefined());1068 }1069 } else {1070 double doubleLastIndex = jsLastIndex.toInteger(exec);1071 if (doubleLastIndex < 0 || doubleLastIndex > s.length()) {1072 regExpObject->setLastIndex(exec, 0);1073 return JSValue::encode(jsUndefined());1074 }1075 lastIndex = static_cast<unsigned>(doubleLastIndex);1076 }1077 1078 startOffset = lastIndex;1079 }1080 } else {1081 /*1082 * ECMA 15.5.4.12 String.prototype.search (regexp)1083 * If regexp is not an object whose [[Class]] property is "RegExp", it is1084 * replaced with the result of the expression new RegExp(regexp).1085 * Per ECMA 15.10.4.1, if a0 is undefined substitute the empty string.1086 */1087 String patternString = emptyString();1088 if (!a0.isUndefined()) {1089 patternString = a0.toString(exec)->value(exec);1090 if (exec->hadException())1091 return JSValue::encode(jsUndefined());1092 }1093 regExp = RegExp::create(exec->vm(), patternString, NoFlags);1094 if (!regExp->isValid())1095 return throwVMError(exec, createSyntaxError(exec, regExp->errorMessage()));1096 }1097 RegExpConstructor* regExpConstructor = globalObject->regExpConstructor();1098 MatchResult result = regExpConstructor->performMatch(*vm, regExp, string, s, startOffset);1099 // case without 'g' flag is handled like RegExp.prototype.exec1100 if (!global) {1101 if (sticky)1102 regExpObject->setLastIndex(exec, result ? result.end : 0);1103 1104 return JSValue::encode(result ? createRegExpMatchesArray(exec, globalObject, string, regExp, result.start) : jsNull());1105 }1106 1107 // return array of matches1108 MarkedArgumentBuffer list;1109 while (result) {1110 // We defend ourselves from crazy.1111 const size_t maximumReasonableMatchSize = 1000000000;1112 if (list.size() > maximumReasonableMatchSize) {1113 throwOutOfMemoryError(exec);1114 return JSValue::encode(jsUndefined());1115 }1116 1117 size_t end = result.end;1118 size_t length = end - result.start;1119 list.append(jsSubstring(exec, s, result.start, length));1120 if (!length)1121 ++end;1122 result = regExpConstructor->performMatch(*vm, regExp, string, s, end);1123 }1124 if (list.isEmpty()) {1125 // if there are no matches at all, it's important to return1126 // Null instead of an empty array, because this matches1127 // other browsers and because Null is a false value.1128 return JSValue::encode(jsNull());1129 }1130 1131 return JSValue::encode(constructArray(exec, static_cast<ArrayAllocationProfile*>(0), list));1132 }1133 1134 1031 EncodedJSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState* exec) 1135 1032 { -
trunk/Source/JavaScriptCore/tests/es6.yaml
r198531 r198554 1008 1008 cmd: runES6 :fail 1009 1009 - path: es6/Proxy_internal_get_calls_String.prototype.match.js 1010 cmd: runES6 : fail1010 cmd: runES6 :normal 1011 1011 - path: es6/Proxy_internal_get_calls_String.prototype.replace.js 1012 1012 cmd: runES6 :fail … … 1084 1084 cmd: runES6 :normal 1085 1085 - path: es6/RegExp.prototype_properties_RegExp.prototype[Symbol.match].js 1086 cmd: runES6 : fail1086 cmd: runES6 :normal 1087 1087 - path: es6/RegExp.prototype_properties_RegExp.prototype[Symbol.replace].js 1088 1088 cmd: runES6 :fail … … 1194 1194 cmd: runES6 :fail 1195 1195 - path: es6/well-known_symbols_Symbol.match.js 1196 cmd: runES6 : fail1196 cmd: runES6 :normal 1197 1197 - path: es6/well-known_symbols_Symbol.replace.js 1198 1198 cmd: runES6 :fail
Note: See TracChangeset
for help on using the changeset viewer.