Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(689)

Unified Diff: src/js/regexp.js

Issue 2310903002: Revert of [regexp] Remove dead code (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/js/regexp.js
diff --git a/src/js/regexp.js b/src/js/regexp.js
index b9d0f50b244345c52e73e1cb33fdbe09d7c3c6f6..584d4cdf41bdbe58c76cb3bd9ee22249f34f494a 100644
--- a/src/js/regexp.js
+++ b/src/js/regexp.js
@@ -162,6 +162,46 @@
%FunctionRemovePrototype(RegExpSubclassExecJS);
+// Legacy implementation of RegExp.prototype.exec
+function RegExpExecJS(string) {
+ if (!IS_REGEXP(this)) {
+ throw %make_type_error(kIncompatibleMethodReceiver,
+ 'RegExp.prototype.exec', this);
+ }
+
+ string = TO_STRING(string);
+ var lastIndex = this.lastIndex;
+
+ // Conversion is required by the ES2015 specification (RegExpBuiltinExec
+ // algorithm, step 4) even if the value is discarded for non-global RegExps.
+ var i = TO_LENGTH(lastIndex);
+
+ var updateLastIndex = REGEXP_GLOBAL(this) || REGEXP_STICKY(this);
+ if (updateLastIndex) {
+ if (i < 0 || i > string.length) {
+ this.lastIndex = 0;
+ return null;
+ }
+ } else {
+ i = 0;
+ }
+
+ // matchIndices is either null or the RegExpLastMatchInfo array.
+ var matchIndices = %_RegExpExec(this, string, i, RegExpLastMatchInfo);
+
+ if (IS_NULL(matchIndices)) {
+ this.lastIndex = 0;
+ return null;
+ }
+
+ // Successful match.
+ if (updateLastIndex) {
+ this.lastIndex = RegExpLastMatchInfo[CAPTURE1];
+ }
+ RETURN_NEW_RESULT_FROM_MATCH_INFO(matchIndices, string);
+}
+
+
// ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S )
// Also takes an optional exec method in case our caller
// has already fetched exec.
@@ -176,9 +216,68 @@
}
return result;
}
- return %_Call(RegExpSubclassExecJS, regexp, string);
+ return %_Call(RegExpExecJS, regexp, string);
}
%SetForceInlineFlag(RegExpSubclassExec);
+
+
+// One-element cache for the simplified test regexp.
+var regexp_key;
+var regexp_val;
+
+// Legacy implementation of RegExp.prototype.test
+// Section 15.10.6.3 doesn't actually make sense, but the intention seems to be
+// that test is defined in terms of String.prototype.exec. However, it probably
+// means the original value of String.prototype.exec, which is what everybody
+// else implements.
+function RegExpTest(string) {
+ if (!IS_REGEXP(this)) {
+ throw %make_type_error(kIncompatibleMethodReceiver,
+ 'RegExp.prototype.test', this);
+ }
+ string = TO_STRING(string);
+
+ var lastIndex = this.lastIndex;
+
+ // Conversion is required by the ES2015 specification (RegExpBuiltinExec
+ // algorithm, step 4) even if the value is discarded for non-global RegExps.
+ var i = TO_LENGTH(lastIndex);
+
+ if (REGEXP_GLOBAL(this) || REGEXP_STICKY(this)) {
+ if (i < 0 || i > string.length) {
+ this.lastIndex = 0;
+ return false;
+ }
+ // matchIndices is either null or the RegExpLastMatchInfo array.
+ var matchIndices = %_RegExpExec(this, string, i, RegExpLastMatchInfo);
+ if (IS_NULL(matchIndices)) {
+ this.lastIndex = 0;
+ return false;
+ }
+ this.lastIndex = RegExpLastMatchInfo[CAPTURE1];
+ return true;
+ } else {
+ // Non-global, non-sticky regexp.
+ // Remove irrelevant preceeding '.*' in a test regexp. The expression
+ // checks whether this.source starts with '.*' and that the third char is
+ // not a '?'. But see https://code.google.com/p/v8/issues/detail?id=3560
+ var regexp = this;
+ var source = REGEXP_SOURCE(regexp);
+ if (source.length >= 3 &&
+ %_StringCharCodeAt(source, 0) == 46 && // '.'
+ %_StringCharCodeAt(source, 1) == 42 && // '*'
+ %_StringCharCodeAt(source, 2) != 63) { // '?'
+ regexp = TrimRegExp(regexp);
+ }
+ // matchIndices is either null or the RegExpLastMatchInfo array.
+ var matchIndices = %_RegExpExec(regexp, string, 0, RegExpLastMatchInfo);
+ if (IS_NULL(matchIndices)) {
+ this.lastIndex = 0;
+ return false;
+ }
+ return true;
+ }
+}
// ES#sec-regexp.prototype.test RegExp.prototype.test ( S )
@@ -192,6 +291,18 @@
return !IS_NULL(match);
}
%FunctionRemovePrototype(RegExpSubclassTest);
+
+function TrimRegExp(regexp) {
+ if (regexp_key !== regexp) {
+ regexp_key = regexp;
+ regexp_val =
+ new GlobalRegExp(
+ %_SubString(REGEXP_SOURCE(regexp), 2, REGEXP_SOURCE(regexp).length),
+ (REGEXP_IGNORE_CASE(regexp) ? REGEXP_MULTILINE(regexp) ? "im" : "i"
+ : REGEXP_MULTILINE(regexp) ? "m" : ""));
+ }
+ return regexp_val;
+}
function AtSurrogatePair(subject, index) {
@@ -816,7 +927,10 @@
to.InternalRegExpMatch = InternalRegExpMatch;
to.InternalRegExpReplace = InternalRegExpReplace;
to.IsRegExp = IsRegExp;
+ to.RegExpExec = DoRegExpExec;
to.RegExpInitialize = RegExpInitialize;
+ to.RegExpLastMatchInfo = RegExpLastMatchInfo;
+ to.RegExpTest = RegExpTest;
});
})
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698