From c1c5a09ebd773f1536f0c016a71b94f4aad1a4ea Mon Sep 17 00:00:00 2001 From: "christian.plesner.hansen@gmail.com" Date: Tue, 10 Mar 2009 11:32:19 +0000 Subject: [PATCH] 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. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1473 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/messages.js | 13 +++++++++++-- src/parser.cc | 6 ++---- src/regexp-delay.js | 3 +++ test/cctest/test-regexp.cc | 3 +-- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/messages.js b/src/messages.js index 1af7c0a..d6de768 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; diff --git a/src/parser.cc b/src/parser.cc index 43fd012..12f1781 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 diff --git a/src/regexp-delay.js b/src/regexp-delay.js index 66f23b0..39fae34 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]); diff --git a/test/cctest/test-regexp.cc b/test/cctest/test-regexp.cc index 5945fe7..ed2e9ab 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); -- 2.7.4