diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-06-18 14:10:49 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2015-06-18 13:53:24 +0000 |
commit | 813fbf95af77a531c57a8c497345ad2c61d475b3 (patch) | |
tree | 821b2c8de8365f21b6c9ba17a236fb3006a1d506 /chromium/v8/src/regexp.js | |
parent | af6588f8d723931a298c995fa97259bb7f7deb55 (diff) | |
download | qtwebengine-chromium-813fbf95af77a531c57a8c497345ad2c61d475b3.tar.gz |
BASELINE: Update chromium to 44.0.2403.47
Change-Id: Ie056fedba95cf5e5c76b30c4b2c80fca4764aa2f
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Diffstat (limited to 'chromium/v8/src/regexp.js')
-rw-r--r-- | chromium/v8/src/regexp.js | 380 |
1 files changed, 175 insertions, 205 deletions
diff --git a/chromium/v8/src/regexp.js b/chromium/v8/src/regexp.js index 0f3dbb630e8..3ac59872029 100644 --- a/chromium/v8/src/regexp.js +++ b/chromium/v8/src/regexp.js @@ -2,12 +2,38 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file relies on the fact that the following declaration has been made -// in runtime.js: -// var $Object = global.Object; -// var $Array = global.Array; +var $regexpExec; +var $regexpExecNoTests; +var $regexpLastMatchInfo; +var $regexpLastMatchInfoOverride; +var harmony_regexps = false; +var harmony_unicode_regexps = false; -var $RegExp = global.RegExp; +(function(global, shared, exports) { + +%CheckIsBootstrapping(); + +var GlobalRegExp = global.RegExp; + +// Property of the builtins object for recording the result of the last +// regexp match. The property $regexpLastMatchInfo includes the matchIndices +// array of the last successful regexp match (an array of start/end index +// pairs for the match and all the captured substrings), the invariant is +// that there are at least two capture indeces. The array also contains +// the subject string for the last successful match. +$regexpLastMatchInfo = new InternalPackedArray( + 2, // REGEXP_NUMBER_OF_CAPTURES + "", // Last subject. + UNDEFINED, // Last input - settable with RegExpSetInput. + 0, // REGEXP_FIRST_CAPTURE + 0 + 0 // REGEXP_FIRST_CAPTURE + 1 +); + +// Override last match info with an array of actual substrings. +// Used internally by replace regexp with function. +// The array has the format of an "apply" argument for a replacement +// function. +$regexpLastMatchInfoOverride = null; // ------------------------------------------------------------------- @@ -22,54 +48,17 @@ function DoConstructRegExp(object, pattern, flags) { flags = (pattern.global ? 'g' : '') + (pattern.ignoreCase ? 'i' : '') + (pattern.multiline ? 'm' : ''); + if (harmony_unicode_regexps) + flags += (pattern.unicode ? 'u' : ''); if (harmony_regexps) flags += (pattern.sticky ? 'y' : ''); pattern = pattern.source; } - pattern = IS_UNDEFINED(pattern) ? '' : ToString(pattern); - flags = IS_UNDEFINED(flags) ? '' : ToString(flags); - - var global = false; - var ignoreCase = false; - var multiline = false; - var sticky = false; - for (var i = 0; i < flags.length; i++) { - var c = %_CallFunction(flags, i, StringCharAt); - switch (c) { - case 'g': - if (global) { - throw MakeSyntaxError("invalid_regexp_flags", [flags]); - } - global = true; - break; - case 'i': - if (ignoreCase) { - throw MakeSyntaxError("invalid_regexp_flags", [flags]); - } - ignoreCase = true; - break; - case 'm': - if (multiline) { - throw MakeSyntaxError("invalid_regexp_flags", [flags]); - } - multiline = true; - break; - case 'y': - if (!harmony_regexps || sticky) { - throw MakeSyntaxError("invalid_regexp_flags", [flags]); - } - sticky = true; - break; - default: - throw MakeSyntaxError("invalid_regexp_flags", [flags]); - } - } - - %RegExpInitializeObject(object, pattern, global, ignoreCase, multiline, sticky); + pattern = IS_UNDEFINED(pattern) ? '' : $toString(pattern); + flags = IS_UNDEFINED(flags) ? '' : $toString(flags); - // Call internal function to compile the pattern. - %RegExpCompile(object, pattern, flags); + %RegExpInitializeAndCompile(object, pattern, flags); } @@ -81,7 +70,7 @@ function RegExpConstructor(pattern, flags) { if (IS_REGEXP(pattern) && IS_UNDEFINED(flags)) { return pattern; } - return new $RegExp(pattern, flags); + return new GlobalRegExp(pattern, flags); } } @@ -97,10 +86,10 @@ function RegExpCompileJS(pattern, flags) { // RegExp.prototype.compile and in the constructor, where they are // the empty string. For compatibility with JSC, we match their // behavior. - if (this == $RegExp.prototype) { + if (this == GlobalRegExp.prototype) { // We don't allow recompiling RegExp.prototype. - throw MakeTypeError('incompatible_method_receiver', - ['RegExp.prototype.compile', this]); + throw MakeTypeError(kIncompatibleMethodReceiver, + 'RegExp.prototype.compile', this); } if (IS_UNDEFINED(pattern) && %_ArgumentsLength() != 0) { DoConstructRegExp(this, 'undefined', flags); @@ -111,8 +100,8 @@ function RegExpCompileJS(pattern, flags) { function DoRegExpExec(regexp, string, index) { - var result = %_RegExpExec(regexp, string, index, lastMatchInfo); - if (result !== null) lastMatchInfoOverride = null; + var result = %_RegExpExec(regexp, string, index, $regexpLastMatchInfo); + if (result !== null) $regexpLastMatchInfoOverride = null; return result; } @@ -145,9 +134,9 @@ endmacro function RegExpExecNoTests(regexp, string, start) { // Must be called with RegExp, string and positive integer as arguments. - var matchInfo = %_RegExpExec(regexp, string, start, lastMatchInfo); + var matchInfo = %_RegExpExec(regexp, string, start, $regexpLastMatchInfo); if (matchInfo !== null) { - lastMatchInfoOverride = null; + $regexpLastMatchInfoOverride = null; RETURN_NEW_RESULT_FROM_MATCH_INFO(matchInfo, string); } regexp.lastIndex = 0; @@ -155,10 +144,10 @@ function RegExpExecNoTests(regexp, string, start) { } -function RegExpExec(string) { +function RegExpExecJS(string) { if (!IS_REGEXP(this)) { - throw MakeTypeError('incompatible_method_receiver', - ['RegExp.prototype.exec', this]); + throw MakeTypeError(kIncompatibleMethodReceiver, + 'RegExp.prototype.exec', this); } string = TO_STRING_INLINE(string); @@ -178,8 +167,8 @@ function RegExpExec(string) { i = 0; } - // matchIndices is either null or the lastMatchInfo array. - var matchIndices = %_RegExpExec(this, string, i, lastMatchInfo); + // matchIndices is either null or the $regexpLastMatchInfo array. + var matchIndices = %_RegExpExec(this, string, i, $regexpLastMatchInfo); if (IS_NULL(matchIndices)) { this.lastIndex = 0; @@ -187,9 +176,9 @@ function RegExpExec(string) { } // Successful match. - lastMatchInfoOverride = null; + $regexpLastMatchInfoOverride = null; if (updateLastIndex) { - this.lastIndex = lastMatchInfo[CAPTURE1]; + this.lastIndex = $regexpLastMatchInfo[CAPTURE1]; } RETURN_NEW_RESULT_FROM_MATCH_INFO(matchIndices, string); } @@ -205,8 +194,8 @@ var regexp_val; // else implements. function RegExpTest(string) { if (!IS_REGEXP(this)) { - throw MakeTypeError('incompatible_method_receiver', - ['RegExp.prototype.test', this]); + throw MakeTypeError(kIncompatibleMethodReceiver, + 'RegExp.prototype.test', this); } string = TO_STRING_INLINE(string); @@ -221,14 +210,14 @@ function RegExpTest(string) { this.lastIndex = 0; return false; } - // matchIndices is either null or the lastMatchInfo array. - var matchIndices = %_RegExpExec(this, string, i, lastMatchInfo); + // matchIndices is either null or the $regexpLastMatchInfo array. + var matchIndices = %_RegExpExec(this, string, i, $regexpLastMatchInfo); if (IS_NULL(matchIndices)) { this.lastIndex = 0; return false; } - lastMatchInfoOverride = null; - this.lastIndex = lastMatchInfo[CAPTURE1]; + $regexpLastMatchInfoOverride = null; + this.lastIndex = $regexpLastMatchInfo[CAPTURE1]; return true; } else { // Non-global, non-sticky regexp. @@ -242,13 +231,13 @@ function RegExpTest(string) { %_StringCharCodeAt(regexp.source, 2) != 63) { // '?' regexp = TrimRegExp(regexp); } - // matchIndices is either null or the lastMatchInfo array. - var matchIndices = %_RegExpExec(regexp, string, 0, lastMatchInfo); + // matchIndices is either null or the $regexpLastMatchInfo array. + var matchIndices = %_RegExpExec(regexp, string, 0, $regexpLastMatchInfo); if (IS_NULL(matchIndices)) { this.lastIndex = 0; return false; } - lastMatchInfoOverride = null; + $regexpLastMatchInfoOverride = null; return true; } } @@ -257,9 +246,9 @@ function TrimRegExp(regexp) { if (!%_ObjectEquals(regexp_key, regexp)) { regexp_key = regexp; regexp_val = - new $RegExp(%_SubString(regexp.source, 2, regexp.source.length), - (regexp.ignoreCase ? regexp.multiline ? "im" : "i" - : regexp.multiline ? "m" : "")); + new GlobalRegExp(%_SubString(regexp.source, 2, regexp.source.length), + (regexp.ignoreCase ? regexp.multiline ? "im" : "i" + : regexp.multiline ? "m" : "")); } return regexp_val; } @@ -267,13 +256,14 @@ function TrimRegExp(regexp) { function RegExpToString() { if (!IS_REGEXP(this)) { - throw MakeTypeError('incompatible_method_receiver', - ['RegExp.prototype.toString', this]); + throw MakeTypeError(kIncompatibleMethodReceiver, + 'RegExp.prototype.toString', this); } var result = '/' + this.source + '/'; if (this.global) result += 'g'; if (this.ignoreCase) result += 'i'; if (this.multiline) result += 'm'; + if (harmony_unicode_regexps && this.unicode) result += 'u'; if (harmony_regexps && this.sticky) result += 'y'; return result; } @@ -284,30 +274,30 @@ function RegExpToString() { // on the captures array of the last successful match and the subject string // of the last successful match. function RegExpGetLastMatch() { - if (lastMatchInfoOverride !== null) { - return OVERRIDE_MATCH(lastMatchInfoOverride); + if ($regexpLastMatchInfoOverride !== null) { + return OVERRIDE_MATCH($regexpLastMatchInfoOverride); } - var regExpSubject = LAST_SUBJECT(lastMatchInfo); + var regExpSubject = LAST_SUBJECT($regexpLastMatchInfo); return %_SubString(regExpSubject, - lastMatchInfo[CAPTURE0], - lastMatchInfo[CAPTURE1]); + $regexpLastMatchInfo[CAPTURE0], + $regexpLastMatchInfo[CAPTURE1]); } function RegExpGetLastParen() { - if (lastMatchInfoOverride) { - var override = lastMatchInfoOverride; + if ($regexpLastMatchInfoOverride) { + var override = $regexpLastMatchInfoOverride; if (override.length <= 3) return ''; return override[override.length - 3]; } - var length = NUMBER_OF_CAPTURES(lastMatchInfo); + var length = NUMBER_OF_CAPTURES($regexpLastMatchInfo); if (length <= 2) return ''; // There were no captures. // We match the SpiderMonkey behavior: return the substring defined by the // last pair (after the first pair) of elements of the capture array even if // it is empty. - var regExpSubject = LAST_SUBJECT(lastMatchInfo); - var start = lastMatchInfo[CAPTURE(length - 2)]; - var end = lastMatchInfo[CAPTURE(length - 1)]; + var regExpSubject = LAST_SUBJECT($regexpLastMatchInfo); + var start = $regexpLastMatchInfo[CAPTURE(length - 2)]; + var end = $regexpLastMatchInfo[CAPTURE(length - 1)]; if (start != -1 && end != -1) { return %_SubString(regExpSubject, start, end); } @@ -318,11 +308,11 @@ function RegExpGetLastParen() { function RegExpGetLeftContext() { var start_index; var subject; - if (!lastMatchInfoOverride) { - start_index = lastMatchInfo[CAPTURE0]; - subject = LAST_SUBJECT(lastMatchInfo); + if (!$regexpLastMatchInfoOverride) { + start_index = $regexpLastMatchInfo[CAPTURE0]; + subject = LAST_SUBJECT($regexpLastMatchInfo); } else { - var override = lastMatchInfoOverride; + var override = $regexpLastMatchInfoOverride; start_index = OVERRIDE_POS(override); subject = OVERRIDE_SUBJECT(override); } @@ -333,11 +323,11 @@ function RegExpGetLeftContext() { function RegExpGetRightContext() { var start_index; var subject; - if (!lastMatchInfoOverride) { - start_index = lastMatchInfo[CAPTURE1]; - subject = LAST_SUBJECT(lastMatchInfo); + if (!$regexpLastMatchInfoOverride) { + start_index = $regexpLastMatchInfo[CAPTURE1]; + subject = LAST_SUBJECT($regexpLastMatchInfo); } else { - var override = lastMatchInfoOverride; + var override = $regexpLastMatchInfoOverride; subject = OVERRIDE_SUBJECT(override); var match = OVERRIDE_MATCH(override); start_index = OVERRIDE_POS(override) + match.length; @@ -350,126 +340,106 @@ function RegExpGetRightContext() { // successful match, or ''. The function RegExpMakeCaptureGetter will be // called with indices from 1 to 9. function RegExpMakeCaptureGetter(n) { - return function() { - if (lastMatchInfoOverride) { - if (n < lastMatchInfoOverride.length - 2) { - return OVERRIDE_CAPTURE(lastMatchInfoOverride, n); + return function foo() { + if ($regexpLastMatchInfoOverride) { + if (n < $regexpLastMatchInfoOverride.length - 2) { + return OVERRIDE_CAPTURE($regexpLastMatchInfoOverride, n); } return ''; } var index = n * 2; - if (index >= NUMBER_OF_CAPTURES(lastMatchInfo)) return ''; - var matchStart = lastMatchInfo[CAPTURE(index)]; - var matchEnd = lastMatchInfo[CAPTURE(index + 1)]; + if (index >= NUMBER_OF_CAPTURES($regexpLastMatchInfo)) return ''; + var matchStart = $regexpLastMatchInfo[CAPTURE(index)]; + var matchEnd = $regexpLastMatchInfo[CAPTURE(index + 1)]; if (matchStart == -1 || matchEnd == -1) return ''; - return %_SubString(LAST_SUBJECT(lastMatchInfo), matchStart, matchEnd); + return %_SubString(LAST_SUBJECT($regexpLastMatchInfo), matchStart, matchEnd); }; } - -// Property of the builtins object for recording the result of the last -// regexp match. The property lastMatchInfo includes the matchIndices -// array of the last successful regexp match (an array of start/end index -// pairs for the match and all the captured substrings), the invariant is -// that there are at least two capture indeces. The array also contains -// the subject string for the last successful match. -var lastMatchInfo = new InternalPackedArray( - 2, // REGEXP_NUMBER_OF_CAPTURES - "", // Last subject. - UNDEFINED, // Last input - settable with RegExpSetInput. - 0, // REGEXP_FIRST_CAPTURE + 0 - 0 // REGEXP_FIRST_CAPTURE + 1 -); - -// Override last match info with an array of actual substrings. -// Used internally by replace regexp with function. -// The array has the format of an "apply" argument for a replacement -// function. -var lastMatchInfoOverride = null; - // ------------------------------------------------------------------- -function SetUpRegExp() { - %CheckIsBootstrapping(); - %FunctionSetInstanceClassName($RegExp, 'RegExp'); - %AddNamedProperty($RegExp.prototype, 'constructor', $RegExp, DONT_ENUM); - %SetCode($RegExp, RegExpConstructor); - - InstallFunctions($RegExp.prototype, DONT_ENUM, $Array( - "exec", RegExpExec, - "test", RegExpTest, - "toString", RegExpToString, - "compile", RegExpCompileJS - )); - - // The length of compile is 1 in SpiderMonkey. - %FunctionSetLength($RegExp.prototype.compile, 1); - - // The properties `input` and `$_` are aliases for each other. When this - // value is set the value it is set to is coerced to a string. - // Getter and setter for the input. - var RegExpGetInput = function() { - var regExpInput = LAST_INPUT(lastMatchInfo); - return IS_UNDEFINED(regExpInput) ? "" : regExpInput; - }; - var RegExpSetInput = function(string) { - LAST_INPUT(lastMatchInfo) = ToString(string); - }; - - %OptimizeObjectForAddingMultipleProperties($RegExp, 22); - %DefineAccessorPropertyUnchecked($RegExp, 'input', RegExpGetInput, - RegExpSetInput, DONT_DELETE); - %DefineAccessorPropertyUnchecked($RegExp, '$_', RegExpGetInput, - RegExpSetInput, DONT_ENUM | DONT_DELETE); - - // The properties multiline and $* are aliases for each other. When this - // value is set in SpiderMonkey, the value it is set to is coerced to a - // boolean. We mimic that behavior with a slight difference: in SpiderMonkey - // the value of the expression 'RegExp.multiline = null' (for instance) is the - // boolean false (i.e., the value after coercion), while in V8 it is the value - // null (i.e., the value before coercion). - - // Getter and setter for multiline. - var multiline = false; - var RegExpGetMultiline = function() { return multiline; }; - var RegExpSetMultiline = function(flag) { multiline = flag ? true : false; }; - - %DefineAccessorPropertyUnchecked($RegExp, 'multiline', RegExpGetMultiline, - RegExpSetMultiline, DONT_DELETE); - %DefineAccessorPropertyUnchecked($RegExp, '$*', RegExpGetMultiline, - RegExpSetMultiline, - DONT_ENUM | DONT_DELETE); - - - var NoOpSetter = function(ignored) {}; - - - // Static properties set by a successful match. - %DefineAccessorPropertyUnchecked($RegExp, 'lastMatch', RegExpGetLastMatch, - NoOpSetter, DONT_DELETE); - %DefineAccessorPropertyUnchecked($RegExp, '$&', RegExpGetLastMatch, - NoOpSetter, DONT_ENUM | DONT_DELETE); - %DefineAccessorPropertyUnchecked($RegExp, 'lastParen', RegExpGetLastParen, - NoOpSetter, DONT_DELETE); - %DefineAccessorPropertyUnchecked($RegExp, '$+', RegExpGetLastParen, - NoOpSetter, DONT_ENUM | DONT_DELETE); - %DefineAccessorPropertyUnchecked($RegExp, 'leftContext', - RegExpGetLeftContext, NoOpSetter, +%FunctionSetInstanceClassName(GlobalRegExp, 'RegExp'); +%AddNamedProperty( + GlobalRegExp.prototype, 'constructor', GlobalRegExp, DONT_ENUM); +%SetCode(GlobalRegExp, RegExpConstructor); + +$installFunctions(GlobalRegExp.prototype, DONT_ENUM, [ + "exec", RegExpExecJS, + "test", RegExpTest, + "toString", RegExpToString, + "compile", RegExpCompileJS +]); + +// The length of compile is 1 in SpiderMonkey. +%FunctionSetLength(GlobalRegExp.prototype.compile, 1); + +// The properties `input` and `$_` are aliases for each other. When this +// value is set the value it is set to is coerced to a string. +// Getter and setter for the input. +var RegExpGetInput = function() { + var regExpInput = LAST_INPUT($regexpLastMatchInfo); + return IS_UNDEFINED(regExpInput) ? "" : regExpInput; +}; +var RegExpSetInput = function(string) { + LAST_INPUT($regexpLastMatchInfo) = $toString(string); +}; + +%OptimizeObjectForAddingMultipleProperties(GlobalRegExp, 22); +%DefineAccessorPropertyUnchecked(GlobalRegExp, 'input', RegExpGetInput, + RegExpSetInput, DONT_DELETE); +%DefineAccessorPropertyUnchecked(GlobalRegExp, '$_', RegExpGetInput, + RegExpSetInput, DONT_ENUM | DONT_DELETE); + +// The properties multiline and $* are aliases for each other. When this +// value is set in SpiderMonkey, the value it is set to is coerced to a +// boolean. We mimic that behavior with a slight difference: in SpiderMonkey +// the value of the expression 'RegExp.multiline = null' (for instance) is the +// boolean false (i.e., the value after coercion), while in V8 it is the value +// null (i.e., the value before coercion). + +// Getter and setter for multiline. +var multiline = false; +var RegExpGetMultiline = function() { return multiline; }; +var RegExpSetMultiline = function(flag) { multiline = flag ? true : false; }; + +%DefineAccessorPropertyUnchecked(GlobalRegExp, 'multiline', RegExpGetMultiline, + RegExpSetMultiline, DONT_DELETE); +%DefineAccessorPropertyUnchecked(GlobalRegExp, '$*', RegExpGetMultiline, + RegExpSetMultiline, + DONT_ENUM | DONT_DELETE); + + +var NoOpSetter = function(ignored) {}; + + +// Static properties set by a successful match. +%DefineAccessorPropertyUnchecked(GlobalRegExp, 'lastMatch', RegExpGetLastMatch, + NoOpSetter, DONT_DELETE); +%DefineAccessorPropertyUnchecked(GlobalRegExp, '$&', RegExpGetLastMatch, + NoOpSetter, DONT_ENUM | DONT_DELETE); +%DefineAccessorPropertyUnchecked(GlobalRegExp, 'lastParen', RegExpGetLastParen, + NoOpSetter, DONT_DELETE); +%DefineAccessorPropertyUnchecked(GlobalRegExp, '$+', RegExpGetLastParen, + NoOpSetter, DONT_ENUM | DONT_DELETE); +%DefineAccessorPropertyUnchecked(GlobalRegExp, 'leftContext', + RegExpGetLeftContext, NoOpSetter, + DONT_DELETE); +%DefineAccessorPropertyUnchecked(GlobalRegExp, '$`', RegExpGetLeftContext, + NoOpSetter, DONT_ENUM | DONT_DELETE); +%DefineAccessorPropertyUnchecked(GlobalRegExp, 'rightContext', + RegExpGetRightContext, NoOpSetter, + DONT_DELETE); +%DefineAccessorPropertyUnchecked(GlobalRegExp, "$'", RegExpGetRightContext, + NoOpSetter, DONT_ENUM | DONT_DELETE); + +for (var i = 1; i < 10; ++i) { + %DefineAccessorPropertyUnchecked(GlobalRegExp, '$' + i, + RegExpMakeCaptureGetter(i), NoOpSetter, DONT_DELETE); - %DefineAccessorPropertyUnchecked($RegExp, '$`', RegExpGetLeftContext, - NoOpSetter, DONT_ENUM | DONT_DELETE); - %DefineAccessorPropertyUnchecked($RegExp, 'rightContext', - RegExpGetRightContext, NoOpSetter, - DONT_DELETE); - %DefineAccessorPropertyUnchecked($RegExp, "$'", RegExpGetRightContext, - NoOpSetter, DONT_ENUM | DONT_DELETE); - - for (var i = 1; i < 10; ++i) { - %DefineAccessorPropertyUnchecked($RegExp, '$' + i, - RegExpMakeCaptureGetter(i), NoOpSetter, - DONT_DELETE); - } - %ToFastProperties($RegExp); } +%ToFastProperties(GlobalRegExp); + +$regexpExecNoTests = RegExpExecNoTests; +$regexpExec = DoRegExpExec; -SetUpRegExp(); +}) |