Diff
Modified: trunk/LayoutTests/ChangeLog (198553 => 198554)
--- trunk/LayoutTests/ChangeLog 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/LayoutTests/ChangeLog 2016-03-22 21:42:06 UTC (rev 198554)
@@ -1,3 +1,17 @@
+2016-03-22 Michael Saboff <[email protected]>
+
+ [ES6] Implement RegExp.prototype[@@match]
+ https://bugs.webkit.org/show_bug.cgi?id=155711
+
+ Reviewed by Filip Pizlo.
+
+ Updated tests for exception string changes and added Symbol.match.
+
+ * js/Object-getOwnPropertyNames-expected.txt:
+ * js/dom/string-prototype-properties-expected.txt:
+ * js/script-tests/Object-getOwnPropertyNames.js:
+ * 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:
+
2016-03-22 Daniel Bates <[email protected]>
CSP: Should only execute <script> or apply <style> if its hash appears in all policies
Modified: trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt (198553 => 198554)
--- trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt 2016-03-22 21:42:06 UTC (rev 198554)
@@ -61,7 +61,7 @@
PASS getSortedOwnPropertyNames(Error.prototype) is ['constructor', 'message', 'name', 'toString']
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']
PASS getSortedOwnPropertyNames(JSON) is ['parse', 'stringify']
-PASS getSortedOwnPropertyNames(Symbol) is ['for', 'hasInstance', 'iterator', 'keyFor', 'length', 'name', 'prototype', 'search', 'species', 'toPrimitive', 'toStringTag', 'unscopables']
+PASS getSortedOwnPropertyNames(Symbol) is ['for', 'hasInstance', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'search', 'species', 'toPrimitive', 'toStringTag', 'unscopables']
PASS getSortedOwnPropertyNames(Symbol.prototype) is ['constructor', 'toString', 'valueOf']
PASS getSortedOwnPropertyNames(Map) is ['length', 'name', 'prototype']
PASS getSortedOwnPropertyNames(Map.prototype) is ['clear', 'constructor', 'delete', 'entries', 'forEach', 'get', 'has', 'keys', 'set', 'size', 'values']
Modified: trunk/LayoutTests/js/dom/string-prototype-properties-expected.txt (198553 => 198554)
--- trunk/LayoutTests/js/dom/string-prototype-properties-expected.txt 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/LayoutTests/js/dom/string-prototype-properties-expected.txt 2016-03-22 21:42:06 UTC (rev 198554)
@@ -10,7 +10,7 @@
PASS String.prototype.concat.call(undefined, 'five') threw exception TypeError: Type error.
PASS String.prototype.indexOf.call(undefined, '2') threw exception TypeError: Type error.
PASS String.prototype.lastIndexOf.call(undefined, '2') threw exception TypeError: Type error.
-PASS String.prototype.match.call(undefined, /2+/) threw exception TypeError: Type error.
+PASS String.prototype.match.call(undefined, /2+/) threw exception TypeError: String.prototype.match requires that |this| not be undefined.
PASS String.prototype.replace.call(undefined, /2+/, '-') threw exception TypeError: Type error.
PASS String.prototype.search.call(undefined, '4') threw exception TypeError: String.prototype.search requires that |this| not be undefined.
PASS String.prototype.slice.call(undefined, 1, 3) threw exception TypeError: Type error.
Modified: trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js (198553 => 198554)
--- trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js 2016-03-22 21:42:06 UTC (rev 198554)
@@ -70,7 +70,7 @@
"Error.prototype": "['constructor', 'message', 'name', 'toString']",
"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']",
"JSON": "['parse', 'stringify']",
- "Symbol": "['for', 'hasInstance', 'iterator', 'keyFor', 'length', 'name', 'prototype', 'search', 'species', 'toPrimitive', 'toStringTag', 'unscopables']",
+ "Symbol": "['for', 'hasInstance', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'search', 'species', 'toPrimitive', 'toStringTag', 'unscopables']",
"Symbol.prototype": "['constructor', 'toString', 'valueOf']",
"Map": "['length', 'name', 'prototype']",
"Map.prototype": "['clear', 'constructor', 'delete', 'entries', 'forEach', 'get', 'has', 'keys', 'set', 'size', 'values']",
Modified: 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 (198553 => 198554)
--- 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 2016-03-22 21:31:16 UTC (rev 198553)
+++ 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 2016-03-22 21:42:06 UTC (rev 198554)
@@ -1,6 +1,6 @@
S15.5.4.10_A1_T3
-FAIL TypeError: Type error
+FAIL TypeError: String.prototype.match requires that |this| not be undefined
TEST COMPLETE
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (198553 => 198554)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2016-03-22 21:42:06 UTC (rev 198554)
@@ -1219,6 +1219,7 @@
${_javascript_CORE_DIR}/builtins/PromiseOperations.js
${_javascript_CORE_DIR}/builtins/PromisePrototype.js
${_javascript_CORE_DIR}/builtins/ReflectObject.js
+ ${_javascript_CORE_DIR}/builtins/RegExpPrototype.js
${_javascript_CORE_DIR}/builtins/SetPrototype.js
${_javascript_CORE_DIR}/builtins/StringConstructor.js
${_javascript_CORE_DIR}/builtins/StringIteratorPrototype.js
Modified: trunk/Source/_javascript_Core/ChangeLog (198553 => 198554)
--- trunk/Source/_javascript_Core/ChangeLog 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-03-22 21:42:06 UTC (rev 198554)
@@ -1,3 +1,73 @@
+2016-03-22 Michael Saboff <[email protected]>
+
+ [ES6] Implement RegExp.prototype[@@match]
+ https://bugs.webkit.org/show_bug.cgi?id=155711
+
+ Reviewed by Filip Pizlo.
+
+ Implemented ES6 spec for String.prototype.match and RegExp.prototype[@@match].
+ Implemented both as builtins, with String.prototype.match calling
+ RegExp.prototype[@@match].
+
+ For performance reasons, RegExp.prototype[@@match] has a C++ fast path when
+ RegExp.prototype.exec has not been overridden. This fast path,
+ RegExpObject::matchGlobal, was taken from the prior StringPrototype::match.
+ It only handles global matches.
+
+ Added new test, stress/regexp-match.js.
+
+ Updated various tests for changes exception string and now passing ES6 behavior.
+
+ * CMakeLists.txt:
+ * DerivedSources.make:
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ Added builtins/RegExpPrototype.js and eliminated RegExpPrototype.lut.h.
+
+ * builtins/RegExpPrototype.js: Added.
+ (match.advanceStringIndexUnicode): Helper.
+ (match): Implements RegExp.prototype[@@match].
+ * builtins/StringPrototype.js:
+ (match): Implements String.prototype.match.
+
+ * bytecode/BytecodeIntrinsicRegistry.cpp:
+ (JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
+ (JSC::BytecodeIntrinsicRegistry::lookup):
+ * bytecode/BytecodeIntrinsicRegistry.h:
+ * runtime/CommonIdentifiers.h:
+ Added Symbol.match and builtins @match and @exec.
+
+ * runtime/RegExpObject.cpp:
+ * runtime/RegExpObject.h:
+ * runtime/RegExpObjectInlines.h:
+ (JSC::RegExpObject::matchGlobal): Added.
+ (JSC::RegExpObject::advanceStringUnicode): Added helper.
+
+ * runtime/RegExpPrototype.cpp:
+ * runtime/RegExpPrototype.h:
+ (JSC::RegExpPrototype::RegExpPrototype):
+ (JSC::RegExpPrototype::finishCreation):
+ (JSC::RegExpPrototype::visitChildren):
+ (JSC::regExpProtoFuncMatchPrivate):
+ (JSC::RegExpPrototype::getOwnPropertySlot): Deleted.
+ (JSC::RegExpPrototype::create):
+ Restructured to create properties explicitly due to having two names for native regExpProtoFuncExec.
+
+ * runtime/StringPrototype.cpp:
+ (JSC::StringPrototype::finishCreation):
+ Made match a builtin.
+ Removed unused declaration of stringProtoFuncSearch() since it was made a builtin.
+
+ * tests/es6.yaml:
+ * tests/stress/regexp-match.js: Added.
+ (shouldBe):
+ (shouldThrow):
+ (errorKey.toString):
+ (primitive.of.primitives.shouldThrow):
+ (testRegExpMatch):
+ (testMatch):
+ (testBoth):
+ (alwaysUnmatch):
+
2016-03-22 Caitlin Potter <[email protected]>
[JSC] allow duplicate property names returned from Proxy ownKeys() trap
Modified: trunk/Source/_javascript_Core/DerivedSources.make (198553 => 198554)
--- trunk/Source/_javascript_Core/DerivedSources.make 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/Source/_javascript_Core/DerivedSources.make 2016-03-22 21:42:06 UTC (rev 198554)
@@ -99,6 +99,7 @@
$(_javascript_Core)/builtins/PromiseOperations.js \
$(_javascript_Core)/builtins/PromisePrototype.js \
$(_javascript_Core)/builtins/ReflectObject.js \
+ $(_javascript_Core)/builtins/RegExpPrototype.js \
$(_javascript_Core)/builtins/SetPrototype.js \
$(_javascript_Core)/builtins/StringConstructor.js \
$(_javascript_Core)/builtins/StringIteratorPrototype.js \
@@ -147,7 +148,6 @@
ObjectConstructor.lut.h \
ReflectObject.lut.h \
RegExpConstructor.lut.h \
- RegExpPrototype.lut.h \
SetPrototype.lut.h \
StringConstructor.lut.h \
StringIteratorPrototype.lut.h \
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (198553 => 198554)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2016-03-22 21:42:06 UTC (rev 198554)
@@ -1464,7 +1464,6 @@
996B73211BDA08EF00331B84 /* NumberPrototype.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 996B730D1BD9FA2C00331B84 /* NumberPrototype.lut.h */; };
996B73221BDA08EF00331B84 /* ObjectConstructor.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 996B730E1BD9FA2C00331B84 /* ObjectConstructor.lut.h */; };
996B73231BDA08EF00331B84 /* ReflectObject.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 996B730F1BD9FA2C00331B84 /* ReflectObject.lut.h */; };
- 996B73241BDA08EF00331B84 /* RegExpPrototype.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 996B73101BD9FA2C00331B84 /* RegExpPrototype.lut.h */; };
996B73251BDA08EF00331B84 /* StringConstructor.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 996B73111BD9FA2C00331B84 /* StringConstructor.lut.h */; };
996B73261BDA08EF00331B84 /* StringIteratorPrototype.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 996B73121BD9FA2C00331B84 /* StringIteratorPrototype.lut.h */; };
996B73271BDA08EF00331B84 /* SymbolConstructor.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 996B73131BD9FA2C00331B84 /* SymbolConstructor.lut.h */; };
@@ -3355,6 +3354,7 @@
6540C79F1B82D9CE000F6B79 /* RegisterAtOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterAtOffset.h; sourceTree = "<group>"; };
6546F51F1A32A59C006F07D5 /* NullGetterFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = NullGetterFunction.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
6546F5201A32A59C006F07D5 /* NullGetterFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NullGetterFunction.h; sourceTree = "<group>"; };
+ 654788421C937D2C000781A0 /* RegExpPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = RegExpPrototype.js; sourceTree = "<group>"; };
65525FC31A6DD3B3007B5495 /* NullSetterFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NullSetterFunction.cpp; sourceTree = "<group>"; };
65525FC41A6DD3B3007B5495 /* NullSetterFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NullSetterFunction.h; sourceTree = "<group>"; };
6553A32F17A1F1EE008CF6F3 /* CommonSlowPathsExceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CommonSlowPathsExceptions.cpp; sourceTree = "<group>"; };
@@ -3669,7 +3669,6 @@
996B730D1BD9FA2C00331B84 /* NumberPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NumberPrototype.lut.h; sourceTree = "<group>"; };
996B730E1BD9FA2C00331B84 /* ObjectConstructor.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectConstructor.lut.h; sourceTree = "<group>"; };
996B730F1BD9FA2C00331B84 /* ReflectObject.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReflectObject.lut.h; sourceTree = "<group>"; };
- 996B73101BD9FA2C00331B84 /* RegExpPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpPrototype.lut.h; sourceTree = "<group>"; };
996B73111BD9FA2C00331B84 /* StringConstructor.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringConstructor.lut.h; sourceTree = "<group>"; };
996B73121BD9FA2C00331B84 /* StringIteratorPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringIteratorPrototype.lut.h; sourceTree = "<group>"; };
996B73131BD9FA2C00331B84 /* SymbolConstructor.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolConstructor.lut.h; sourceTree = "<group>"; };
@@ -5370,7 +5369,6 @@
996B730F1BD9FA2C00331B84 /* ReflectObject.lut.h */,
BCD202D50E170708002C7E82 /* RegExpConstructor.lut.h */,
A718F61A11754A21002465A7 /* RegExpJitTables.h */,
- 996B73101BD9FA2C00331B84 /* RegExpPrototype.lut.h */,
7035587F1C418458004BD7BF /* SetPrototype.lut.h */,
996B73111BD9FA2C00331B84 /* StringConstructor.lut.h */,
996B73121BD9FA2C00331B84 /* StringIteratorPrototype.lut.h */,
@@ -6843,6 +6841,7 @@
7CFBAC1C18B535E500D00750 /* PromisePrototype.js */,
7CF9BC5E1B65D9B1009DB1EF /* PromiseConstructor.js */,
7CF9BC5F1B65D9B1009DB1EF /* ReflectObject.js */,
+ 654788421C937D2C000781A0 /* RegExpPrototype.js */,
7035587D1C418419004BD7BF /* SetPrototype.js */,
7CF9BC601B65D9B1009DB1EF /* StringConstructor.js */,
7CF9BC611B65D9B1009DB1EF /* StringIteratorPrototype.js */,
@@ -7897,7 +7896,6 @@
A1712B4111C7B235007A5315 /* RegExpKey.h in Headers */,
BC18C45B0E16F5CD00B34460 /* RegExpObject.h in Headers */,
BCD202C40E1706A7002C7E82 /* RegExpPrototype.h in Headers */,
- 996B73241BDA08EF00331B84 /* RegExpPrototype.lut.h in Headers */,
BC18C45D0E16F5CD00B34460 /* Register.h in Headers */,
969A072B0ED1CE6900F1F681 /* RegisterID.h in Headers */,
623A37EC1B87A7C000754209 /* RegisterMap.h in Headers */,
Added: trunk/Source/_javascript_Core/builtins/RegExpPrototype.js (0 => 198554)
--- trunk/Source/_javascript_Core/builtins/RegExpPrototype.js (rev 0)
+++ trunk/Source/_javascript_Core/builtins/RegExpPrototype.js 2016-03-22 21:42:06 UTC (rev 198554)
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function match(str)
+{
+ "use strict";
+
+ function advanceStringIndexUnicode(string, stringLength, index)
+ {
+ if (index + 1 >= stringLength)
+ return index + 1;
+
+ let first = string.@charCodeAt(index);
+ if (first < 0xD800 || first > 0xDBFF)
+ return index + 1;
+
+ let second = string.@charCodeAt(index + 1);
+ if (second < 0xDC00 || second > 0xDFFF)
+ return index + 1;
+
+ return index + 2;
+ }
+
+ if (!(this instanceof @Object))
+ throw new @TypeError("RegExp.prototype.@@match requires that |this| be an Object");
+
+ let regexp = @Object(this);
+ let stringArg = @toString(str);
+
+ if (!regexp.global)
+ return regexp.exec(stringArg);
+
+ regexp.lastIndex = 0;
+
+ let resultList = [];
+
+ if (regexp.exec !== @RegExp.prototype.@exec && typeof(regexp.exec) === "function") {
+ // Match using the overridden exec.
+ let unicode = regexp.unicode;
+ let stringLength = str.length;
+
+ while (true) {
+ let result = regexp.exec(stringArg);
+
+ if (result === null) {
+ if (resultList.length === 0)
+ return null;
+ return resultList;
+ } else if (!@isObject(result))
+ throw new @TypeError("RegExp.prototype.@@match call to RegExp.exec didn't return null or an object");
+
+ let resultString = @toString(result[0]);
+
+ if (!resultString.length) {
+ if (unicode)
+ regexp.lastIndex = advanceStringIndexUnicode(stringArg, stringLength, regexp.lastIndex);
+ else
+ regexp.lastIndex++;
+ }
+
+ resultList.@push(resultString);
+ }
+ }
+
+ return regexp.@match(stringArg);
+}
+
Modified: trunk/Source/_javascript_Core/builtins/StringPrototype.js (198553 => 198554)
--- trunk/Source/_javascript_Core/builtins/StringPrototype.js 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/Source/_javascript_Core/builtins/StringPrototype.js 2016-03-22 21:42:06 UTC (rev 198554)
@@ -26,6 +26,27 @@
// @conditional=ENABLE(INTL)
+function match(regexp)
+{
+ "use strict";
+
+ if (this == null) {
+ if (this === null)
+ throw new @TypeError("String.prototype.match requires that |this| not be null");
+ throw new @TypeError("String.prototype.match requires that |this| not be undefined");
+ }
+
+ if (regexp != null) {
+ var matcher = regexp[@symbolMatch];
+ if (matcher !== @undefined)
+ return matcher.@call(regexp, this);
+ }
+
+ let thisString = @toString(this);
+ let createdRegExp = new @RegExp(regexp, @undefined);
+ return createdRegExp[@symbolMatch](thisString);
+}
+
function search(regexp)
{
"use strict";
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.cpp (198553 => 198554)
--- trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.cpp 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.cpp 2016-03-22 21:42:06 UTC (rev 198554)
@@ -51,6 +51,7 @@
m_promiseStateFulfilled.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Status::Fulfilled)));
m_promiseStateRejected.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Status::Rejected)));
m_symbolIterator.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->iteratorSymbol.impl())));
+ m_symbolMatch.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->matchSymbol.impl())));
m_symbolSearch.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->searchSymbol.impl())));
m_symbolSpecies.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->speciesSymbol.impl())));
}
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.h (198553 => 198554)
--- trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.h 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.h 2016-03-22 21:42:06 UTC (rev 198554)
@@ -53,6 +53,7 @@
macro(promiseStateFulfilled) \
macro(promiseStateRejected) \
macro(symbolIterator) \
+ macro(symbolMatch) \
macro(symbolSearch) \
macro(symbolSpecies)
Modified: trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h (198553 => 198554)
--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h 2016-03-22 21:42:06 UTC (rev 198554)
@@ -274,13 +274,13 @@
#define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL_NOT_IMPLEMENTED_YET(macro)\
macro(isConcatSpreadable) \
- macro(match) \
macro(replace) \
- macro(split) \
+ macro(split)
#define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(macro) \
macro(hasInstance) \
macro(iterator) \
+ macro(match) \
macro(search) \
macro(species) \
macro(toPrimitive) \
@@ -352,6 +352,7 @@
macro(Uint32Array) \
macro(Float32Array) \
macro(Float64Array) \
+ macro(exec) \
macro(generator) \
macro(generatorNext) \
macro(generatorState) \
Modified: trunk/Source/_javascript_Core/runtime/RegExpObject.cpp (198553 => 198554)
--- trunk/Source/_javascript_Core/runtime/RegExpObject.cpp 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/Source/_javascript_Core/runtime/RegExpObject.cpp 2016-03-22 21:42:06 UTC (rev 198554)
@@ -169,4 +169,65 @@
return matchInline(exec, globalObject, string);
}
+JSValue RegExpObject::matchGlobal(ExecState* exec, JSGlobalObject* globalObject, JSString* string)
+{
+ RegExp* regExp = this->regExp();
+
+ ASSERT(regExp->global());
+
+ VM* vm = &globalObject->vm();
+
+ setLastIndex(exec, 0);
+ if (exec->hadException())
+ return jsUndefined();
+
+ String s = string->value(exec);
+ RegExpConstructor* regExpConstructor = globalObject->regExpConstructor();
+ MatchResult result = regExpConstructor->performMatch(*vm, regExp, string, s, 0);
+
+ // return array of matches
+ MarkedArgumentBuffer list;
+ // We defend ourselves from crazy.
+ const size_t maximumReasonableMatchSize = 1000000000;
+
+ if (regExp->unicode()) {
+ while (result) {
+ if (list.size() > maximumReasonableMatchSize) {
+ throwOutOfMemoryError(exec);
+ return jsUndefined();
+ }
+
+ size_t end = result.end;
+ size_t length = end - result.start;
+ list.append(jsSubstring(exec, s, result.start, length));
+ if (!length)
+ end = advanceStringUnicode(s, length, end);
+ result = regExpConstructor->performMatch(*vm, regExp, string, s, end);
+ }
+ } else {
+ while (result) {
+ if (list.size() > maximumReasonableMatchSize) {
+ throwOutOfMemoryError(exec);
+ return jsUndefined();
+ }
+
+ size_t end = result.end;
+ size_t length = end - result.start;
+ list.append(jsSubstring(exec, s, result.start, length));
+ if (!length)
+ ++end;
+ result = regExpConstructor->performMatch(*vm, regExp, string, s, end);
+ }
+ }
+
+ if (list.isEmpty()) {
+ // if there are no matches at all, it's important to return
+ // Null instead of an empty array, because this matches
+ // other browsers and because Null is a false value.
+ return jsNull();
+ }
+
+ return constructArray(exec, static_cast<ArrayAllocationProfile*>(0), list);
+}
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/RegExpObject.h (198553 => 198554)
--- trunk/Source/_javascript_Core/runtime/RegExpObject.h 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/Source/_javascript_Core/runtime/RegExpObject.h 2016-03-22 21:42:06 UTC (rev 198554)
@@ -70,6 +70,8 @@
bool testInline(ExecState* exec, JSGlobalObject* globalObject, JSString* string) { return !!matchInline(exec, globalObject, string); }
JSValue exec(ExecState*, JSGlobalObject*, JSString*);
JSValue execInline(ExecState*, JSGlobalObject*, JSString*);
+ MatchResult match(ExecState*, JSGlobalObject*, JSString*);
+ JSValue matchGlobal(ExecState*, JSGlobalObject*, JSString*);
static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
static bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
@@ -102,9 +104,9 @@
JS_EXPORT_PRIVATE static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
JS_EXPORT_PRIVATE static void getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
+ unsigned advanceStringUnicode(String, unsigned, unsigned);
private:
- MatchResult match(ExecState*, JSGlobalObject*, JSString*);
MatchResult matchInline(ExecState*, JSGlobalObject*, JSString*);
WriteBarrier<RegExp> m_regExp;
Modified: trunk/Source/_javascript_Core/runtime/RegExpObjectInlines.h (198553 => 198554)
--- trunk/Source/_javascript_Core/runtime/RegExpObjectInlines.h 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/Source/_javascript_Core/runtime/RegExpObjectInlines.h 2016-03-22 21:42:06 UTC (rev 198554)
@@ -108,6 +108,22 @@
return result;
}
+unsigned RegExpObject::advanceStringUnicode(String s, unsigned length, unsigned currentIndex)
+{
+ if (currentIndex + 1 >= length)
+ return currentIndex + 1;
+
+ UChar first = s[currentIndex];
+ if (first < 0xD800 || first > 0xDBFF)
+ return currentIndex + 1;
+
+ UChar second = s[currentIndex];
+ if (second < 0xDC00 || second > 0xDFFF)
+ return currentIndex + 1;
+
+ return currentIndex + 2;
+}
+
} // namespace JSC
#endif // RegExpObjectInlines_h
Modified: trunk/Source/_javascript_Core/runtime/RegExpPrototype.cpp (198553 => 198554)
--- trunk/Source/_javascript_Core/runtime/RegExpPrototype.cpp 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/Source/_javascript_Core/runtime/RegExpPrototype.cpp 2016-03-22 21:42:06 UTC (rev 198554)
@@ -22,8 +22,10 @@
#include "RegExpPrototype.h"
#include "ArrayPrototype.h"
+#include "BuiltinNames.h"
#include "Error.h"
#include "JSArray.h"
+#include "JSCBuiltins.h"
#include "JSCJSValue.h"
#include "JSFunction.h"
#include "JSObject.h"
@@ -36,12 +38,14 @@
#include "RegExp.h"
#include "RegExpCache.h"
#include "RegExpConstructor.h"
+#include "RegExpMatchesArray.h"
#include "StringRecursionChecker.h"
namespace JSC {
static EncodedJSValue JSC_HOST_CALL regExpProtoFuncTest(ExecState*);
static EncodedJSValue JSC_HOST_CALL regExpProtoFuncExec(ExecState*);
+static EncodedJSValue JSC_HOST_CALL regExpProtoFuncMatchPrivate(ExecState*);
static EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState*);
static EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState*);
static EncodedJSValue JSC_HOST_CALL regExpProtoFuncSearch(ExecState*);
@@ -53,30 +57,8 @@
static EncodedJSValue JSC_HOST_CALL regExpProtoGetterSource(ExecState*);
static EncodedJSValue JSC_HOST_CALL regExpProtoGetterFlags(ExecState*);
-}
+const ClassInfo RegExpPrototype::s_info = { "Object", &Base::s_info, 0, CREATE_METHOD_TABLE(RegExpPrototype) };
-#include "RegExpPrototype.lut.h"
-
-namespace JSC {
-
-const ClassInfo RegExpPrototype::s_info = { "Object", &Base::s_info, ®ExpPrototypeTable, CREATE_METHOD_TABLE(RegExpPrototype) };
-
-/* Source for RegExpPrototype.lut.h
-@begin regExpPrototypeTable
- compile regExpProtoFuncCompile DontEnum|Function 2
- exec regExpProtoFuncExec DontEnum|Function 1
- test regExpProtoFuncTest DontEnum|Function 1
- toString regExpProtoFuncToString DontEnum|Function 0
- global regExpProtoGetterGlobal DontEnum|Accessor
- ignoreCase regExpProtoGetterIgnoreCase DontEnum|Accessor
- multiline regExpProtoGetterMultiline DontEnum|Accessor
- sticky regExpProtoGetterSticky DontEnum|Accessor
- unicode regExpProtoGetterUnicode DontEnum|Accessor
- source regExpProtoGetterSource DontEnum|Accessor
- flags regExpProtoGetterFlags DontEnum|Accessor
-@end
-*/
-
RegExpPrototype::RegExpPrototype(VM& vm, Structure* structure)
: JSNonFinalObject(vm, structure)
{
@@ -86,16 +68,27 @@
{
Base::finishCreation(vm);
ASSERT(inherits(info()));
- JSC_NATIVE_FUNCTION(vm.propertyNames->searchSymbol, regExpProtoFuncSearch, DontEnum, 1);
+ JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->compile, regExpProtoFuncCompile, DontEnum, 2);
+ JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->test, regExpProtoFuncTest, DontEnum, 1);
+ JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->toString, regExpProtoFuncToString, DontEnum, 0);
+ JSC_NATIVE_GETTER(vm.propertyNames->global, regExpProtoGetterGlobal, DontEnum | Accessor);
+ JSC_NATIVE_GETTER(vm.propertyNames->ignoreCase, regExpProtoGetterIgnoreCase, DontEnum | Accessor);
+ JSC_NATIVE_GETTER(vm.propertyNames->multiline, regExpProtoGetterMultiline, DontEnum | Accessor);
+ JSC_NATIVE_GETTER(vm.propertyNames->sticky, regExpProtoGetterSticky, DontEnum | Accessor);
+ JSC_NATIVE_GETTER(vm.propertyNames->unicode, regExpProtoGetterUnicode, DontEnum | Accessor);
+ JSC_NATIVE_GETTER(vm.propertyNames->source, regExpProtoGetterSource, DontEnum | Accessor);
+ JSC_NATIVE_GETTER(vm.propertyNames->flags, regExpProtoGetterFlags, DontEnum | Accessor);
+ JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().matchPrivateName(), regExpProtoFuncMatchPrivate, DontEnum | DontDelete | ReadOnly, 1);
+ JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->matchSymbol, regExpPrototypeMatchCodeGenerator, DontEnum);
+ JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->searchSymbol, regExpProtoFuncSearch, DontEnum, 1);
+ JSFunction* execFunction = JSFunction::create(vm, globalObject, 1, vm.propertyNames->exec.string(), regExpProtoFuncExec, RegExpExecIntrinsic);
+ putDirectWithoutTransition(vm, vm.propertyNames->execPrivateName, execFunction, DontEnum | DontDelete | ReadOnly);
+ putDirectWithoutTransition(vm, vm.propertyNames->exec, execFunction, DontEnum);
+
m_emptyRegExp.set(vm, this, RegExp::create(vm, "", NoFlags));
}
-bool RegExpPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
-{
- return getStaticFunctionSlot<Base>(exec, regExpPrototypeTable, jsCast<RegExpPrototype*>(object), propertyName, slot);
-}
-
void RegExpPrototype::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
RegExpPrototype* thisObject = jsCast<RegExpPrototype*>(cell);
@@ -129,6 +122,17 @@
return JSValue::encode(asRegExpObject(thisValue)->exec(exec, exec->lexicalGlobalObject(), string));
}
+EncodedJSValue JSC_HOST_CALL regExpProtoFuncMatchPrivate(ExecState* exec)
+{
+ JSValue thisValue = exec->thisValue();
+ if (!thisValue.inherits(RegExpObject::info()))
+ return throwVMTypeError(exec);
+ JSString* string = exec->argument(0).toStringOrNull(exec);
+ if (!string)
+ return JSValue::encode(jsUndefined());
+ return JSValue::encode(asRegExpObject(thisValue)->matchGlobal(exec, exec->lexicalGlobalObject(), string));
+}
+
EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec)
{
JSValue thisValue = exec->thisValue();
Modified: trunk/Source/_javascript_Core/runtime/RegExpPrototype.h (198553 => 198554)
--- trunk/Source/_javascript_Core/runtime/RegExpPrototype.h 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/Source/_javascript_Core/runtime/RegExpPrototype.h 2016-03-22 21:42:06 UTC (rev 198554)
@@ -29,7 +29,7 @@
class RegExpPrototype : public JSNonFinalObject {
public:
typedef JSNonFinalObject Base;
- static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
+ static const unsigned StructureFlags = Base::StructureFlags;
static RegExpPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
{
@@ -54,7 +54,6 @@
private:
void finishCreation(VM&, JSGlobalObject*);
- static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
WriteBarrier<RegExp> m_emptyRegExp;
};
Modified: trunk/Source/_javascript_Core/runtime/StringPrototype.cpp (198553 => 198554)
--- trunk/Source/_javascript_Core/runtime/StringPrototype.cpp 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/Source/_javascript_Core/runtime/StringPrototype.cpp 2016-03-22 21:42:06 UTC (rev 198554)
@@ -66,10 +66,8 @@
EncodedJSValue JSC_HOST_CALL stringProtoFuncConcat(ExecState*);
EncodedJSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState*);
EncodedJSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState*);
-EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState*);
EncodedJSValue JSC_HOST_CALL stringProtoFuncRepeat(ExecState*);
EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState*);
-EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState*);
EncodedJSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState*);
EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState*);
EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstr(ExecState*);
@@ -111,6 +109,7 @@
/* Source for StringConstructor.lut.h
@begin stringPrototypeTable
+ match JSBuiltin DontEnum|Function 1
search JSBuiltin DontEnum|Function 1
@end
*/
@@ -134,7 +133,6 @@
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("concat", stringProtoFuncConcat, DontEnum, 1);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("indexOf", stringProtoFuncIndexOf, DontEnum, 1);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("lastIndexOf", stringProtoFuncLastIndexOf, DontEnum, 1);
- JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("match", stringProtoFuncMatch, DontEnum, 1);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("repeat", stringProtoFuncRepeat, DontEnum, 1);
JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION("replace", stringProtoFuncReplace, DontEnum, 2, StringPrototypeReplaceIntrinsic);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("slice", stringProtoFuncSlice, DontEnum, 2);
@@ -1030,107 +1028,6 @@
return JSValue::encode(jsNumber(result));
}
-EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec)
-{
- JSValue thisValue = exec->thisValue();
- if (!checkObjectCoercible(thisValue))
- return throwVMTypeError(exec);
- JSString* string = thisValue.toString(exec);
- String s = string->value(exec);
- JSGlobalObject* globalObject = exec->lexicalGlobalObject();
- VM* vm = &globalObject->vm();
-
- JSValue a0 = exec->argument(0);
-
- RegExp* regExp;
- unsigned startOffset = 0;
- bool global = false;
- bool sticky = false;
- RegExpObject* regExpObject = nullptr;
- if (a0.inherits(RegExpObject::info())) {
- regExpObject = asRegExpObject(a0);
- regExp = regExpObject->regExp();
- if ((global = regExp->global())) {
- // ES6 21.2.5.6 step 6.b.
- regExpObject->setLastIndex(exec, 0);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
- }
- sticky = regExp->sticky();
- if (!global && sticky) {
- JSValue jsLastIndex = regExpObject->getLastIndex();
- unsigned lastIndex;
- if (LIKELY(jsLastIndex.isUInt32())) {
- lastIndex = jsLastIndex.asUInt32();
- if (lastIndex > s.length()) {
- regExpObject->setLastIndex(exec, 0);
- return JSValue::encode(jsUndefined());
- }
- } else {
- double doubleLastIndex = jsLastIndex.toInteger(exec);
- if (doubleLastIndex < 0 || doubleLastIndex > s.length()) {
- regExpObject->setLastIndex(exec, 0);
- return JSValue::encode(jsUndefined());
- }
- lastIndex = static_cast<unsigned>(doubleLastIndex);
- }
-
- startOffset = lastIndex;
- }
- } else {
- /*
- * ECMA 15.5.4.12 String.prototype.search (regexp)
- * If regexp is not an object whose [[Class]] property is "RegExp", it is
- * replaced with the result of the _expression_ new RegExp(regexp).
- * Per ECMA 15.10.4.1, if a0 is undefined substitute the empty string.
- */
- String patternString = emptyString();
- if (!a0.isUndefined()) {
- patternString = a0.toString(exec)->value(exec);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
- }
- regExp = RegExp::create(exec->vm(), patternString, NoFlags);
- if (!regExp->isValid())
- return throwVMError(exec, createSyntaxError(exec, regExp->errorMessage()));
- }
- RegExpConstructor* regExpConstructor = globalObject->regExpConstructor();
- MatchResult result = regExpConstructor->performMatch(*vm, regExp, string, s, startOffset);
- // case without 'g' flag is handled like RegExp.prototype.exec
- if (!global) {
- if (sticky)
- regExpObject->setLastIndex(exec, result ? result.end : 0);
-
- return JSValue::encode(result ? createRegExpMatchesArray(exec, globalObject, string, regExp, result.start) : jsNull());
- }
-
- // return array of matches
- MarkedArgumentBuffer list;
- while (result) {
- // We defend ourselves from crazy.
- const size_t maximumReasonableMatchSize = 1000000000;
- if (list.size() > maximumReasonableMatchSize) {
- throwOutOfMemoryError(exec);
- return JSValue::encode(jsUndefined());
- }
-
- size_t end = result.end;
- size_t length = end - result.start;
- list.append(jsSubstring(exec, s, result.start, length));
- if (!length)
- ++end;
- result = regExpConstructor->performMatch(*vm, regExp, string, s, end);
- }
- if (list.isEmpty()) {
- // if there are no matches at all, it's important to return
- // Null instead of an empty array, because this matches
- // other browsers and because Null is a false value.
- return JSValue::encode(jsNull());
- }
-
- return JSValue::encode(constructArray(exec, static_cast<ArrayAllocationProfile*>(0), list));
-}
-
EncodedJSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState* exec)
{
JSValue thisValue = exec->thisValue();
Modified: trunk/Source/_javascript_Core/tests/es6.yaml (198553 => 198554)
--- trunk/Source/_javascript_Core/tests/es6.yaml 2016-03-22 21:31:16 UTC (rev 198553)
+++ trunk/Source/_javascript_Core/tests/es6.yaml 2016-03-22 21:42:06 UTC (rev 198554)
@@ -1007,7 +1007,7 @@
- path: es6/Proxy_internal_get_calls_RegExp_constructor.js
cmd: runES6 :fail
- path: es6/Proxy_internal_get_calls_String.prototype.match.js
- cmd: runES6 :fail
+ cmd: runES6 :normal
- path: es6/Proxy_internal_get_calls_String.prototype.replace.js
cmd: runES6 :fail
- path: es6/Proxy_internal_get_calls_String.prototype.search.js
@@ -1083,7 +1083,7 @@
- path: es6/Reflect_Reflect.set.js
cmd: runES6 :normal
- path: es6/RegExp.prototype_properties_RegExp.prototype[Symbol.match].js
- cmd: runES6 :fail
+ cmd: runES6 :normal
- path: es6/RegExp.prototype_properties_RegExp.prototype[Symbol.replace].js
cmd: runES6 :fail
- path: es6/RegExp.prototype_properties_RegExp.prototype[Symbol.search].js
@@ -1193,7 +1193,7 @@
- path: es6/well-known_symbols_Symbol.isConcatSpreadable.js
cmd: runES6 :fail
- path: es6/well-known_symbols_Symbol.match.js
- cmd: runES6 :fail
+ cmd: runES6 :normal
- path: es6/well-known_symbols_Symbol.replace.js
cmd: runES6 :fail
- path: es6/well-known_symbols_Symbol.search.js
Added: trunk/Source/_javascript_Core/tests/stress/regexp-match.js (0 => 198554)
--- trunk/Source/_javascript_Core/tests/stress/regexp-match.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/regexp-match.js 2016-03-22 21:42:06 UTC (rev 198554)
@@ -0,0 +1,102 @@
+
+function shouldBe(actual, expected) {
+ if (actual !== expected && !(actual !== null && typeof(expected) === "string" && actual.toString() == expected))
+ throw new Error('expected: ' + expected + ', bad value: ' + actual);
+}
+
+function shouldThrow(func, expected) {
+ var error = null;
+ try {
+ func();
+ } catch (e) {
+ error = e;
+ }
+ if (!error)
+ throw new Error('not thrown');
+ shouldBe(String(error), expected);
+}
+
+var errorKey = {
+ toString() {
+ throw new Error('out');
+ }
+};
+var string = 'Cocoa, Cappuccino, Rize, Matcha, Kilimanjaro';
+
+shouldThrow(function () {
+ String.prototype.match.call(null, /Cocoa/);
+}, "TypeError: String.prototype.match requires that |this| not be null");
+
+shouldThrow(function () {
+ String.prototype.match.call(undefined, /Cocoa/);
+}, "TypeError: String.prototype.match requires that |this| not be undefined");
+
+shouldThrow(function () {
+ string.match(errorKey);
+}, "Error: out");
+
+shouldBe('Cocoa'.match(/Cocoa/), "Cocoa");
+
+shouldBe(string.match(/Rize/), "Rize");
+shouldBe(string.match('Rize'), "Rize");
+shouldBe(string.match(/Matcha/), "Matcha");
+shouldBe(string.match('Matcha'), "Matcha");
+
+shouldBe(' undefined'.match(), "");
+shouldBe(' undefined'.match('undefined'), "undefined");
+
+shouldBe((/Cocoa/)[Symbol.match]('Cocoa'), "Cocoa");
+
+var primitives = [
+ '',
+ 'string',
+ 42,
+ Symbol('Cocoa'),
+];
+
+for (var primitive of primitives) {
+ shouldThrow(function () {
+ RegExp.prototype[Symbol.match].call(primitive)
+ }, 'TypeError: RegExp.prototype.@@match requires that |this| be an Object');
+}
+
+shouldThrow(function () {
+ /Cocoa/[Symbol.match](errorKey);
+}, "Error: out");
+
+
+function testRegExpMatch(regexp, string, result, lastIndex) {
+ shouldBe(regexp[Symbol.match](string), result);
+ shouldBe(regexp.lastIndex, lastIndex);
+}
+
+function testMatch(regexp, string, result, lastIndex) {
+ shouldBe(string.match(regexp), result);
+ shouldBe(regexp.lastIndex, lastIndex);
+}
+
+function testBoth(regexp, string, result, lastIndex) {
+ testMatch(regexp, string, result, lastIndex);
+ testRegExpMatch(regexp, string, result, lastIndex);
+}
+
+var cocoa = /Cocoa/;
+cocoa.lastIndex = 20;
+testBoth(cocoa, 'Cocoa', "Cocoa", 20);
+testBoth(cocoa, ' Cocoa', "Cocoa", 20);
+testBoth(cocoa, ' ', null, 20);
+
+var multibyte = /ココア/;
+multibyte.lastIndex = 20;
+testBoth(multibyte, 'ココア', 'ココア', 20);
+testBoth(multibyte, ' Cocoa', null, 20);
+testBoth(multibyte, 'カプチーノ', null, 20);
+
+function alwaysUnmatch(string) {
+ return null;
+}
+
+var regexp = new RegExp('ココア');
+regexp[Symbol.match] = alwaysUnmatch;
+shouldBe(regexp[Symbol.match], alwaysUnmatch);
+testBoth(regexp, 'ココア', null, 0);