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

Unified Diff: src/regexp-delay.js

Issue 1094014: Merge the partial_snapshots branch back into bleeding_edge. For... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 9 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
Index: src/regexp-delay.js
===================================================================
--- src/regexp-delay.js (revision 4215)
+++ src/regexp-delay.js (working copy)
@@ -1,497 +0,0 @@
-// Copyright 2006-2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "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 THE COPYRIGHT
-// OWNER 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.
-
-// Expect $Object = global.Object;
-// Expect $Array = global.Array;
-
-const $RegExp = global.RegExp;
-
-// A recursive descent parser for Patterns according to the grammar of
-// ECMA-262 15.10.1, with deviations noted below.
-function DoConstructRegExp(object, pattern, flags, isConstructorCall) {
- // RegExp : Called as constructor; see ECMA-262, section 15.10.4.
- if (IS_REGEXP(pattern)) {
- if (!IS_UNDEFINED(flags)) {
- throw MakeTypeError('regexp_flags', []);
- }
- flags = (pattern.global ? 'g' : '')
- + (pattern.ignoreCase ? 'i' : '')
- + (pattern.multiline ? 'm' : '');
- pattern = pattern.source;
- }
-
- pattern = IS_UNDEFINED(pattern) ? '' : ToString(pattern);
- flags = IS_UNDEFINED(flags) ? '' : ToString(flags);
-
- var global = false;
- var ignoreCase = false;
- var multiline = false;
-
- for (var i = 0; i < flags.length; i++) {
- var c = StringCharAt.call(flags, i);
- switch (c) {
- case 'g':
- // Allow duplicate flags to be consistent with JSC and others.
- global = true;
- break;
- case 'i':
- ignoreCase = true;
- break;
- case 'm':
- multiline = true;
- break;
- default:
- // Ignore flags that have no meaning to be consistent with
- // JSC.
- break;
- }
- }
-
- if (isConstructorCall) {
- // ECMA-262, section 15.10.7.1.
- %SetProperty(object, 'source', pattern,
- DONT_DELETE | READ_ONLY | DONT_ENUM);
-
- // ECMA-262, section 15.10.7.2.
- %SetProperty(object, 'global', global, DONT_DELETE | READ_ONLY | DONT_ENUM);
-
- // ECMA-262, section 15.10.7.3.
- %SetProperty(object, 'ignoreCase', ignoreCase,
- DONT_DELETE | READ_ONLY | DONT_ENUM);
-
- // ECMA-262, section 15.10.7.4.
- %SetProperty(object, 'multiline', multiline,
- DONT_DELETE | READ_ONLY | DONT_ENUM);
-
- // ECMA-262, section 15.10.7.5.
- %SetProperty(object, 'lastIndex', 0, DONT_DELETE | DONT_ENUM);
- } else { // RegExp is being recompiled via RegExp.prototype.compile.
- %IgnoreAttributesAndSetProperty(object, 'source', pattern);
- %IgnoreAttributesAndSetProperty(object, 'global', global);
- %IgnoreAttributesAndSetProperty(object, 'ignoreCase', ignoreCase);
- %IgnoreAttributesAndSetProperty(object, 'multiline', multiline);
- %IgnoreAttributesAndSetProperty(object, 'lastIndex', 0);
- regExpCache.type = 'none';
- }
-
- // Call internal function to compile the pattern.
- %RegExpCompile(object, pattern, flags);
-}
-
-
-function RegExpConstructor(pattern, flags) {
- if (%_IsConstructCall()) {
- DoConstructRegExp(this, pattern, flags, true);
- } else {
- // RegExp : Called as function; see ECMA-262, section 15.10.3.1.
- if (IS_REGEXP(pattern) && IS_UNDEFINED(flags)) {
- return pattern;
- }
- return new $RegExp(pattern, flags);
- }
-}
-
-
-// Deprecated RegExp.prototype.compile method. We behave like the constructor
-// were called again. In SpiderMonkey, this method returns the regexp object.
-// In JSC, it returns undefined. For compatibility with JSC, we match their
-// behavior.
-function CompileRegExp(pattern, flags) {
- // Both JSC and SpiderMonkey treat a missing pattern argument as the
- // empty subject string, and an actual undefined value passed as the
- // pattern as the string 'undefined'. Note that JSC is inconsistent
- // here, treating undefined values differently in
- // RegExp.prototype.compile and in the constructor, where they are
- // the empty string. For compatibility with JSC, we match their
- // behavior.
- if (IS_UNDEFINED(pattern) && %_ArgumentsLength() != 0) {
- DoConstructRegExp(this, 'undefined', flags, false);
- } else {
- DoConstructRegExp(this, pattern, flags, false);
- }
-}
-
-
-function DoRegExpExec(regexp, string, index) {
- return %_RegExpExec(regexp, string, index, lastMatchInfo);
-}
-
-
-function RegExpCache() {
- this.type = 'none';
- this.regExp = 0;
- this.subject = 0;
- this.replaceString = 0;
- this.lastIndex = 0;
- this.answer = 0;
-}
-
-
-var regExpCache = new RegExpCache();
-
-
-function CloneRegexpAnswer(array) {
- var len = array.length;
- var answer = new $Array(len);
- for (var i = 0; i < len; i++) {
- answer[i] = array[i];
- }
- answer.index = array.index;
- answer.input = array.input;
- return answer;
-}
-
-
-function RegExpExec(string) {
- if (!IS_REGEXP(this)) {
- throw MakeTypeError('incompatible_method_receiver',
- ['RegExp.prototype.exec', this]);
- }
-
- var cache = regExpCache;
-
- if (%_ObjectEquals(cache.type, 'exec') &&
- %_ObjectEquals(cache.lastIndex, this.lastIndex) &&
- %_ObjectEquals(cache.regExp, this) &&
- %_ObjectEquals(cache.subject, string)) {
- var last = cache.answer;
- if (last == null) {
- return last;
- } else {
- return CloneRegexpAnswer(last);
- }
- }
-
- if (%_ArgumentsLength() == 0) {
- var regExpInput = LAST_INPUT(lastMatchInfo);
- if (IS_UNDEFINED(regExpInput)) {
- throw MakeError('no_input_to_regexp', [this]);
- }
- string = regExpInput;
- }
- var s;
- if (IS_STRING(string)) {
- s = string;
- } else {
- s = ToString(string);
- }
- var lastIndex = this.lastIndex;
-
- var i = this.global ? TO_INTEGER(lastIndex) : 0;
-
- if (i < 0 || i > s.length) {
- this.lastIndex = 0;
- return null;
- }
-
- %_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, s, lastIndex]);
- // matchIndices is either null or the lastMatchInfo array.
- var matchIndices = %_RegExpExec(this, s, i, lastMatchInfo);
-
- if (matchIndices == null) {
- if (this.global) this.lastIndex = 0;
- cache.lastIndex = lastIndex;
- cache.regExp = this;
- cache.subject = s;
- cache.answer = matchIndices; // Null.
- cache.type = 'exec';
- return matchIndices; // No match.
- }
-
- var numResults = NUMBER_OF_CAPTURES(lastMatchInfo) >> 1;
- var result;
- if (numResults === 1) {
- var matchStart = lastMatchInfo[CAPTURE(0)];
- var matchEnd = lastMatchInfo[CAPTURE(1)];
- result = [SubString(s, matchStart, matchEnd)];
- } else {
- result = new $Array(numResults);
- for (var i = 0; i < numResults; i++) {
- var matchStart = lastMatchInfo[CAPTURE(i << 1)];
- var matchEnd = lastMatchInfo[CAPTURE((i << 1) + 1)];
- if (matchStart != -1 && matchEnd != -1) {
- result[i] = SubString(s, matchStart, matchEnd);
- } else {
- // Make sure the element is present. Avoid reading the undefined
- // property from the global object since this may change.
- result[i] = void 0;
- }
- }
- }
-
- result.index = lastMatchInfo[CAPTURE0];
- result.input = s;
- if (this.global) {
- this.lastIndex = lastMatchInfo[CAPTURE1];
- return result;
- } else {
- cache.regExp = this;
- cache.subject = s;
- cache.lastIndex = lastIndex;
- cache.answer = result;
- cache.type = 'exec';
- return CloneRegexpAnswer(result);
- }
-}
-
-
-// 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 MakeTypeError('incompatible_method_receiver',
- ['RegExp.prototype.test', this]);
- }
- if (%_ArgumentsLength() == 0) {
- var regExpInput = LAST_INPUT(lastMatchInfo);
- if (IS_UNDEFINED(regExpInput)) {
- throw MakeError('no_input_to_regexp', [this]);
- }
- string = regExpInput;
- }
- var s;
- if (IS_STRING(string)) {
- s = string;
- } else {
- s = ToString(string);
- }
-
- var lastIndex = this.lastIndex;
-
- var cache = regExpCache;
-
- if (%_ObjectEquals(cache.type, 'test') &&
- %_ObjectEquals(cache.regExp, this) &&
- %_ObjectEquals(cache.subject, string) &&
- %_ObjectEquals(cache.lastIndex, lastIndex)) {
- return cache.answer;
- }
-
- var length = s.length;
- var i = this.global ? TO_INTEGER(lastIndex) : 0;
-
- cache.type = 'test';
- cache.regExp = this;
- cache.subject = s;
- cache.lastIndex = i;
-
- if (i < 0 || i > s.length) {
- this.lastIndex = 0;
- cache.answer = false;
- return false;
- }
-
- %_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, s, lastIndex]);
- // matchIndices is either null or the lastMatchInfo array.
- var matchIndices = %_RegExpExec(this, s, i, lastMatchInfo);
-
- if (matchIndices == null) {
- if (this.global) this.lastIndex = 0;
- cache.answer = false;
- return false;
- }
-
- if (this.global) this.lastIndex = lastMatchInfo[CAPTURE1];
- cache.answer = true;
- return true;
-}
-
-
-function RegExpToString() {
- // If this.source is an empty string, output /(?:)/.
- // http://bugzilla.mozilla.org/show_bug.cgi?id=225550
- // ecma_2/RegExp/properties-001.js.
- var src = this.source ? this.source : '(?:)';
- var result = '/' + src + '/';
- if (this.global)
- result += 'g';
- if (this.ignoreCase)
- result += 'i';
- if (this.multiline)
- result += 'm';
- return result;
-}
-
-
-// Getters for the static properties lastMatch, lastParen, leftContext, and
-// rightContext of the RegExp constructor. The properties are computed based
-// on the captures array of the last successful match and the subject string
-// of the last successful match.
-function RegExpGetLastMatch() {
- var regExpSubject = LAST_SUBJECT(lastMatchInfo);
- return SubString(regExpSubject,
- lastMatchInfo[CAPTURE0],
- lastMatchInfo[CAPTURE1]);
-}
-
-
-function RegExpGetLastParen() {
- var length = NUMBER_OF_CAPTURES(lastMatchInfo);
- 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)];
- if (start != -1 && end != -1) {
- return SubString(regExpSubject, start, end);
- }
- return "";
-}
-
-
-function RegExpGetLeftContext() {
- return SubString(LAST_SUBJECT(lastMatchInfo),
- 0,
- lastMatchInfo[CAPTURE0]);
-}
-
-
-function RegExpGetRightContext() {
- var subject = LAST_SUBJECT(lastMatchInfo);
- return SubString(subject,
- lastMatchInfo[CAPTURE1],
- subject.length);
-}
-
-
-// The properties $1..$9 are the first nine capturing substrings of the last
-// successful match, or ''. The function RegExpMakeCaptureGetter will be
-// called with indices from 1 to 9.
-function RegExpMakeCaptureGetter(n) {
- return function() {
- var index = n * 2;
- if (index >= NUMBER_OF_CAPTURES(lastMatchInfo)) return '';
- var matchStart = lastMatchInfo[CAPTURE(index)];
- var matchEnd = lastMatchInfo[CAPTURE(index + 1)];
- if (matchStart == -1 || matchEnd == -1) return '';
- return SubString(LAST_SUBJECT(lastMatchInfo), 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 = [
- 2, // REGEXP_NUMBER_OF_CAPTURES
- "", // Last subject.
- void 0, // Last input - settable with RegExpSetInput.
- 0, // REGEXP_FIRST_CAPTURE + 0
- 0, // REGEXP_FIRST_CAPTURE + 1
-];
-
-// -------------------------------------------------------------------
-
-function SetupRegExp() {
- %FunctionSetInstanceClassName($RegExp, 'RegExp');
- %FunctionSetPrototype($RegExp, new $Object());
- %SetProperty($RegExp.prototype, 'constructor', $RegExp, DONT_ENUM);
- %SetCode($RegExp, RegExpConstructor);
-
- InstallFunctions($RegExp.prototype, DONT_ENUM, $Array(
- "exec", RegExpExec,
- "test", RegExpTest,
- "toString", RegExpToString,
- "compile", CompileRegExp
- ));
-
- // The length of compile is 1 in SpiderMonkey.
- %FunctionSetLength($RegExp.prototype.compile, 1);
-
- // The properties input, $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.
- function RegExpGetInput() {
- var regExpInput = LAST_INPUT(lastMatchInfo);
- return IS_UNDEFINED(regExpInput) ? "" : regExpInput;
- }
- function RegExpSetInput(string) {
- regExpCache.type = 'none';
- LAST_INPUT(lastMatchInfo) = ToString(string);
- };
-
- %DefineAccessor($RegExp, 'input', GETTER, RegExpGetInput, DONT_DELETE);
- %DefineAccessor($RegExp, 'input', SETTER, RegExpSetInput, DONT_DELETE);
- %DefineAccessor($RegExp, '$_', GETTER, RegExpGetInput, DONT_ENUM | DONT_DELETE);
- %DefineAccessor($RegExp, '$_', SETTER, RegExpSetInput, DONT_ENUM | DONT_DELETE);
- %DefineAccessor($RegExp, '$input', GETTER, RegExpGetInput, DONT_ENUM | DONT_DELETE);
- %DefineAccessor($RegExp, '$input', SETTER, 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 (ie, the value after coercion), while in V8 it is the value
- // null (ie, the value before coercion).
-
- // Getter and setter for multiline.
- var multiline = false;
- function RegExpGetMultiline() { return multiline; };
- function RegExpSetMultiline(flag) { multiline = flag ? true : false; };
-
- %DefineAccessor($RegExp, 'multiline', GETTER, RegExpGetMultiline, DONT_DELETE);
- %DefineAccessor($RegExp, 'multiline', SETTER, RegExpSetMultiline, DONT_DELETE);
- %DefineAccessor($RegExp, '$*', GETTER, RegExpGetMultiline, DONT_ENUM | DONT_DELETE);
- %DefineAccessor($RegExp, '$*', SETTER, RegExpSetMultiline, DONT_ENUM | DONT_DELETE);
-
-
- function NoOpSetter(ignored) {}
-
-
- // Static properties set by a successful match.
- %DefineAccessor($RegExp, 'lastMatch', GETTER, RegExpGetLastMatch, DONT_DELETE);
- %DefineAccessor($RegExp, 'lastMatch', SETTER, NoOpSetter, DONT_DELETE);
- %DefineAccessor($RegExp, '$&', GETTER, RegExpGetLastMatch, DONT_ENUM | DONT_DELETE);
- %DefineAccessor($RegExp, '$&', SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE);
- %DefineAccessor($RegExp, 'lastParen', GETTER, RegExpGetLastParen, DONT_DELETE);
- %DefineAccessor($RegExp, 'lastParen', SETTER, NoOpSetter, DONT_DELETE);
- %DefineAccessor($RegExp, '$+', GETTER, RegExpGetLastParen, DONT_ENUM | DONT_DELETE);
- %DefineAccessor($RegExp, '$+', SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE);
- %DefineAccessor($RegExp, 'leftContext', GETTER, RegExpGetLeftContext, DONT_DELETE);
- %DefineAccessor($RegExp, 'leftContext', SETTER, NoOpSetter, DONT_DELETE);
- %DefineAccessor($RegExp, '$`', GETTER, RegExpGetLeftContext, DONT_ENUM | DONT_DELETE);
- %DefineAccessor($RegExp, '$`', SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE);
- %DefineAccessor($RegExp, 'rightContext', GETTER, RegExpGetRightContext, DONT_DELETE);
- %DefineAccessor($RegExp, 'rightContext', SETTER, NoOpSetter, DONT_DELETE);
- %DefineAccessor($RegExp, "$'", GETTER, RegExpGetRightContext, DONT_ENUM | DONT_DELETE);
- %DefineAccessor($RegExp, "$'", SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE);
-
- for (var i = 1; i < 10; ++i) {
- %DefineAccessor($RegExp, '$' + i, GETTER, RegExpMakeCaptureGetter(i), DONT_DELETE);
- %DefineAccessor($RegExp, '$' + i, SETTER, NoOpSetter, DONT_DELETE);
- }
-}
-
-
-SetupRegExp();

Powered by Google App Engine
This is Rietveld 408576698