Reviewers: Lasse Reichstein, Description: Made the Error prototype into an error. Allow \c at the end of regexps. Throw a type error when calling regexp methods on non-regexps.
Please review this at http://codereview.chromium.org/42007 Affected files: M src/messages.js M src/parser.cc M src/regexp-delay.js M test/cctest/test-regexp.cc Index: src/messages.js diff --git a/src/messages.js b/src/messages.js index 1af7c0abee89e54536b7be0c9e51285b209796c7..d6de768e5bed2f7b4947f613637f5f821e279b7e 100644 --- a/src/messages.js +++ b/src/messages.js @@ -628,8 +628,17 @@ function DefineError(f) { %SetProperty(global, name, f, DONT_ENUM); this['$' + name] = f; // Configure the error function. - // prototype of 'Error' must be as default: new Object(). - if (name != 'Error') %FunctionSetPrototype(f, new $Error()); + if (name == 'Error') { + // The prototype of the Error object must itself be an error. + // However, it can't be an instance of the Error object because + // it hasn't been properly configured yet. Instead we create a + // special not-a-true-error-but-close-enough object. + function ErrorPrototype() {} + %FunctionSetInstanceClassName(ErrorPrototype, 'Error'); + %FunctionSetPrototype(f, new ErrorPrototype()); + } else { + %FunctionSetPrototype(f, new $Error()); + } %FunctionSetInstanceClassName(f, 'Error'); %SetProperty(f.prototype, 'constructor', f, DONT_ENUM); f.prototype.name = name; Index: src/parser.cc diff --git a/src/parser.cc b/src/parser.cc index 43fd012f0c4fd9b8a8c4470629d7ce3da7628bc4..12f1781a76e9c2d10a0bb0f277f85c1ec5a1189b 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -4177,10 +4177,8 @@ bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) { STATIC_CHECK(('a' ^ 'A') == 0x20); uc32 RegExpParser::ParseControlLetterEscape() { - if (!has_more()) { - ReportError(CStrVector("\\c at end of pattern")); - return '\0'; - } + if (!has_more()) + return 'c'; uc32 letter = current() & ~(0x20); // Collapse upper and lower case letters. if (letter < 'A' || 'Z' < letter) { // Non-spec error-correction: "\c" followed by non-control letter is Index: src/regexp-delay.js diff --git a/src/regexp-delay.js b/src/regexp-delay.js index 66f23b00f182ebf60767d70b1b9068c38162954e..39fae34200739fce8515b2c5fda249a061e6f13d 100644 --- a/src/regexp-delay.js +++ b/src/regexp-delay.js @@ -160,6 +160,9 @@ function DoRegExpExecGlobal(regexp, string) { function RegExpExec(string) { + if (!IS_REGEXP(this)) { + throw MakeTypeError('method_called_on_incompatible', ['RegExp.prototype.exec', this]); + } if (%_ArgumentsLength() == 0) { if (IS_UNDEFINED(regExpInput)) { throw MakeError('no_input_to_regexp', [this]); Index: test/cctest/test-regexp.cc diff --git a/test/cctest/test-regexp.cc b/test/cctest/test-regexp.cc index 5945fe7d991b693e30f42310fbd125918b57635e..ed2e9ab21e720f02e020eb37ac6b5208303abf82 100644 --- a/test/cctest/test-regexp.cc +++ b/test/cctest/test-regexp.cc @@ -214,6 +214,7 @@ TEST(Parser) { CHECK_PARSE_EQ("\\x34", "'\x34'"); CHECK_PARSE_EQ("\\x60", "'\x60'"); CHECK_PARSE_EQ("\\x3z", "'x3z'"); + CHECK_PARSE_EQ("\\c", "'c'"); CHECK_PARSE_EQ("\\u0034", "'\x34'"); CHECK_PARSE_EQ("\\u003z", "'u003z'"); CHECK_PARSE_EQ("foo[z]*", "(: 'foo' (# 0 - g [z]))"); @@ -363,8 +364,6 @@ TEST(Errors) { const char* kUnterminatedCharacterClass = "Unterminated character class"; ExpectError("[", kUnterminatedCharacterClass); ExpectError("[a-", kUnterminatedCharacterClass); - const char* kEndControl = "\\c at end of pattern"; - ExpectError("\\c", kEndControl); const char* kNothingToRepeat = "Nothing to repeat"; ExpectError("*", kNothingToRepeat); ExpectError("?", kNothingToRepeat); --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list v8-dev@googlegroups.com http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---