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
-~----------~----~----~----~------~----~------~--~---

Reply via email to