Revision: 8068
Author:   l...@chromium.org
Date:     Thu May 26 00:35:09 2011
Log:      Make RegExp objects not callable.

Review URL: http://codereview.chromium.org/6930006
http://code.google.com/p/v8/source/detail?r=8068

Deleted:
 /branches/bleeding_edge/test/mjsunit/override-eval-with-non-function.js
Modified:
 /branches/bleeding_edge/src/execution.cc
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/test/mjsunit/json.js
 /branches/bleeding_edge/test/mjsunit/number-string-index-call.js
 /branches/bleeding_edge/test/mjsunit/regexp-call-as-function.js
 /branches/bleeding_edge/test/mjsunit/regress/regress-603.js
 /branches/bleeding_edge/test/mjsunit/regress/regress-752.js
 /branches/bleeding_edge/test/mjsunit/typeof.js
 /branches/bleeding_edge/test/mozilla/mozilla.status
 /branches/bleeding_edge/test/sputnik/sputnik.status

=======================================
--- /branches/bleeding_edge/test/mjsunit/override-eval-with-non-function.js Fri Apr 15 04:35:36 2011
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2011 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.
-
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
-
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
-}
-
-test();
=======================================
--- /branches/bleeding_edge/src/execution.cc    Mon May 16 09:33:58 2011
+++ /branches/bleeding_edge/src/execution.cc    Thu May 26 00:35:09 2011
@@ -209,23 +209,6 @@

   // If you return a function from here, it will be called when an
   // attempt is made to call the given object as a function.
-
-  // Regular expressions can be called as functions in both Firefox
-  // and Safari so we allow it too.
-  if (object->IsJSRegExp()) {
-    Handle<String> exec = factory->exec_symbol();
- // TODO(lrn): Bug 617. We should use the default function here, not the
-    // one on the RegExp object.
-    Object* exec_function;
-    { MaybeObject* maybe_exec_function = object->GetProperty(*exec);
- // This can lose an exception, but the alternative is to put a failure
-      // object in a handle, which is not GC safe.
-      if (!maybe_exec_function->ToObject(&exec_function)) {
-        return factory->undefined_value();
-      }
-    }
-    return Handle<Object>(exec_function);
-  }

   // Objects created through the API can have an instance-call handler
   // that should be used when calling the object as a function.
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue May 24 07:01:36 2011 +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Thu May 26 00:35:09 2011
@@ -4281,17 +4281,13 @@

   } else if (type_name->Equals(heap()->function_symbol())) {
     __ JumpIfSmi(input, false_label);
-    __ CmpObjectType(input, JS_FUNCTION_TYPE, input);
-    __ j(equal, true_label);
-    // Regular expressions => 'function' (they are callable).
-    __ CmpInstanceType(input, JS_REGEXP_TYPE);
-    final_branch_condition = equal;
+    __ CmpObjectType(input, FIRST_FUNCTION_CLASS_TYPE, input);
+    final_branch_condition = above_equal;

   } else if (type_name->Equals(heap()->object_symbol())) {
     __ JumpIfSmi(input, false_label);
     __ cmp(input, factory()->null_value());
     __ j(equal, true_label);
-    // Regular expressions => 'function', not 'object'.
     __ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, input);
     __ j(below, false_label);
     __ CmpInstanceType(input, FIRST_FUNCTION_CLASS_TYPE);
=======================================
--- /branches/bleeding_edge/src/objects.h       Wed May 25 01:37:38 2011
+++ /branches/bleeding_edge/src/objects.h       Thu May 26 00:35:09 2011
@@ -562,9 +562,9 @@
   JS_GLOBAL_PROXY_TYPE,
   JS_ARRAY_TYPE,

-  JS_REGEXP_TYPE,  // LAST_JS_OBJECT_TYPE, FIRST_FUNCTION_CLASS_TYPE
-
-  JS_FUNCTION_TYPE,
+  JS_REGEXP_TYPE,  // LAST_JS_OBJECT_TYPE
+
+  JS_FUNCTION_TYPE,  // FIRST_FUNCTION_CLASS_TYPE

   // Pseudo-types
   FIRST_TYPE = 0x0,
@@ -583,7 +583,7 @@
   LAST_JS_OBJECT_TYPE = JS_REGEXP_TYPE,
   // RegExp objects have [[Class]] "function" because they are callable.
// All types from this type and above are objects with [[Class]] "function".
-  FIRST_FUNCTION_CLASS_TYPE = JS_REGEXP_TYPE
+  FIRST_FUNCTION_CLASS_TYPE = JS_FUNCTION_TYPE
 };

 static const int kExternalArrayTypeCount = LAST_EXTERNAL_ARRAY_TYPE -
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Tue May 24 07:01:36 2011
+++ /branches/bleeding_edge/src/runtime.cc      Thu May 26 00:35:09 2011
@@ -4637,7 +4637,7 @@
       }
       ASSERT(heap_obj->IsUndefined());
       return isolate->heap()->undefined_symbol();
-    case JS_FUNCTION_TYPE: case JS_REGEXP_TYPE:
+    case JS_FUNCTION_TYPE:
       return isolate->heap()->function_symbol();
     default:
       // For any kind of object not handled above, the spec rule for
=======================================
--- /branches/bleeding_edge/test/mjsunit/json.js        Tue Feb  8 03:38:15 2011
+++ /branches/bleeding_edge/test/mjsunit/json.js        Thu May 26 00:35:09 2011
@@ -67,7 +67,7 @@
           valueOf: "not callable",
           toString: "not callable either",
           toISOString: function() { return 42; }};
-assertThrows("d4.toJSON()", TypeError);  // ToPrimitive throws.
+assertThrows("d4.toJSON()", TypeError);  // ToPrimitive throws.

 var d5 = {toJSON: Date.prototype.toJSON,
           valueOf: "not callable",
@@ -196,9 +196,6 @@
 TestInvalid('"Unterminated string\\"');
 TestInvalid('"Unterminated string\\\\\\"');

-// JavaScript RegExp literals not valid in JSON.
-TestInvalid('/true/');
-
 // Test bad JSON that would be good JavaScript (ES5).
 TestInvalid("{true:42}");
 TestInvalid("{false:42}");
@@ -382,7 +379,7 @@
 reJSON.toJSON = function() { return "has toJSON"; };

 assertEquals(
-    '[37,null,1,"foo","37","true",null,"has toJSON",null,"has toJSON"]',
+    '[37,null,1,"foo","37","true",null,"has toJSON",{},"has toJSON"]',
     JSON.stringify([num37, numFoo, numTrue,
                     strFoo, str37, strTrue,
                     func, funcJSON, re, reJSON]));
@@ -397,6 +394,9 @@
 var counter = { get toJSON() { getCount++;
                                return function() { callCount++;
                                                    return 42; }; } };
+
+// RegExps are not callable, so they are stringified as objects.
+assertEquals('{}', JSON.stringify(/regexp/));
 assertEquals('42', JSON.stringify(counter));
 assertEquals(1, getCount);
 assertEquals(1, callCount);
@@ -419,9 +419,9 @@
 // We don't currently allow plain properties called __proto__ in JSON
 // objects in JSON.parse. Instead we read them as we would JS object
 // literals. If we change that, this test should change with it.
-//
-// Parse a non-object value as __proto__. This must not create a
-// __proto__ property different from the original, and should not
+//
+// Parse a non-object value as __proto__. This must not create a
+// __proto__ property different from the original, and should not
 // change the original.
 var o = JSON.parse('{"__proto__":5}');
 assertEquals(Object.prototype, o.__proto__);  // __proto__ isn't changed.
=======================================
--- /branches/bleeding_edge/test/mjsunit/number-string-index-call.js Fri Apr 15 04:35:36 2011 +++ /branches/bleeding_edge/test/mjsunit/number-string-index-call.js Thu May 26 00:35:09 2011
@@ -25,8 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-// Flags: --call_regexp
-var callbacks = [ function() { return 'foo'; }, "nonobject", /abc/ ];
+var callbacks = [ function() {return 'foo'}, "nonobject", /abc/ ];
 assertEquals('foo', callbacks['0']());
 assertThrows("callbacks['1']()");
-assertEquals(['abc'], callbacks['2']("abcdefg"));
+assertThrows("callbacks['2']('abcdefg')");
=======================================
--- /branches/bleeding_edge/test/mjsunit/regexp-call-as-function.js Tue Dec 7 03:01:02 2010 +++ /branches/bleeding_edge/test/mjsunit/regexp-call-as-function.js Thu May 26 00:35:09 2011
@@ -33,4 +33,4 @@
 var subject = "xyzabcde";
 var expected = 'abc,b,c';
 assertEquals(expected, String(regexp.exec(subject)));
-assertEquals(expected, String(regexp(subject)));
+assertThrows(function(){ regexp(subject); });
=======================================
--- /branches/bleeding_edge/test/mjsunit/regress/regress-603.js Tue Dec 7 03:01:02 2010 +++ /branches/bleeding_edge/test/mjsunit/regress/regress-603.js Thu May 26 00:35:09 2011
@@ -29,21 +29,36 @@
 // not mess up the stack.
 // http://code.google.com/p/v8/issues/detail?id=603

-function test0() {
-  var re = /b../;
+var re = /b../;
+assertThrows(function() {
   return re('abcdefghijklm') + 'z';
-}
-assertEquals('bcdz', test0());
+});

 var re1 = /c../;
 re1.call = Function.prototype.call;
-var test1 = re1.call(null, 'abcdefghijklm') + 'z';
-assertEquals('cdez', test1);
+assertThrows(function() {
+  re1.call(null, 'abcdefghijklm') + 'z';
+});

 var re2 = /d../;
-var test2 = Function.prototype.call.call(re2, null, 'abcdefghijklm') + 'z';
-assertEquals('defz', test2);
+assertThrows(function() {
+  Function.prototype.call.call(re2, null, 'abcdefghijklm') + 'z';
+});

 var re3 = /e../;
-var test3 = Function.prototype.call.apply(re3, [null, 'abcdefghijklm']) + 'z';
-assertEquals('efgz', test3);
+assertThrows(function() {
+  Function.prototype.call.apply(
+      re3, [null, 'abcdefghijklm']) + 'z';
+});
+
+var re4 = /f../;
+assertThrows(function() {
+  Function.prototype.apply.call(
+      re4, null, ['abcdefghijklm']) + 'z';
+});
+
+var re5 = /g../;
+assertThrows(function() {
+  Function.prototype.apply.apply(
+      re4, [null, ['abcdefghijklm']]) + 'z';
+});
=======================================
--- /branches/bleeding_edge/test/mjsunit/regress/regress-752.js Tue Dec 7 03:01:02 2010 +++ /branches/bleeding_edge/test/mjsunit/regress/regress-752.js Thu May 26 00:35:09 2011
@@ -33,4 +33,4 @@
   return value === 42 ? new Boolean(false) : value;
 }

-assertEquals(JSON.stringify([42], replacer), "[false]");
+assertEquals("[false]", JSON.stringify([42], replacer));
=======================================
--- /branches/bleeding_edge/test/mjsunit/typeof.js      Tue Dec  7 03:31:57 2010
+++ /branches/bleeding_edge/test/mjsunit/typeof.js      Thu May 26 00:35:09 2011
@@ -29,10 +29,10 @@
 // the context of string equality comparisons.

 var r = new RegExp;
-assertEquals('function', typeof r);
-assertTrue(typeof r == 'function');
+assertEquals('object', typeof r);
+assertTrue(typeof r == 'object');
+assertFalse(typeof r == 'function');

 function test(x, y) { return x == y; }
-assertFalse(test('object', typeof r));
-
-assertFalse(typeof r == 'object');
+assertTrue(test('object', typeof r));
+
=======================================
--- /branches/bleeding_edge/test/mozilla/mozilla.status Wed May 4 22:21:30 2011 +++ /branches/bleeding_edge/test/mozilla/mozilla.status Thu May 26 00:35:09 2011
@@ -432,6 +432,14 @@
 js1_2/regexp/string_split: FAIL_OK


+# RegExps are not callable.
+js1_2/regexp/simple_form: FAIL_OK
+js1_2/regexp/regress-6359: FAIL_OK
+js1_2/regexp/regress-9141: FAIL_OK
+js1_5/Regress/regress-224956: FAIL_OK
+js1_5/Regress/regress-325925: FAIL_OK
+ecma_2/RegExp/regress-001: FAIL_OK
+
 # We do not check for bad surrogate pairs when quoting strings.
 js1_5/Regress/regress-315974: FAIL_OK

=======================================
--- /branches/bleeding_edge/test/sputnik/sputnik.status Wed May 4 22:21:30 2011 +++ /branches/bleeding_edge/test/sputnik/sputnik.status Thu May 26 00:35:09 2011
@@ -50,10 +50,6 @@
 S15.10.6.2_A1_T16: FAIL_OK
 S15.10.6.3_A1_T16: FAIL_OK

-# We allow regexps to be called as functions for compatibility reasons.
-S15.10.7_A1_T1: FAIL_OK
-S15.10.7_A1_T2: FAIL_OK
-
 # We are silent in some regexp cases where the spec wants us to give
 # errors, for compatibility.
 S15.10.2.11_A1_T2: FAIL
@@ -244,12 +240,6 @@
 S15.9.5.8_A1_T2: FAIL_OK
 S15.9.5.9_A1_T2: FAIL_OK

-# Regexps have type "function", not "object".
-S11.4.3_A3.6: FAIL_OK
-S15.10.7_A3_T2: FAIL_OK
-S15.10.7_A3_T1: FAIL_OK
-
-
 [ $arch == arm ]

 # BUG(3251225): Tests that timeout with --nocrankshaft.

--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev

Reply via email to