Fix second half of issue 1151, the first change (r6765) only fixed FunctionGetPrototy...
authorricow@chromium.org <ricow@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 22 Feb 2011 12:27:36 +0000 (12:27 +0000)
committerricow@chromium.org <ricow@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 22 Feb 2011 12:27:36 +0000 (12:27 +0000)
Review URL: http://codereview.chromium.org/6548008

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6893 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/accessors.cc
test/mjsunit/regress/regress-1151.js

index f6d1daf..1826425 100644 (file)
@@ -446,8 +446,15 @@ MaybeObject* Accessors::FunctionGetPrototype(Object* object, void*) {
   bool found_it = false;
   JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it);
   if (!found_it) return Heap::undefined_value();
+  while (!function->should_have_prototype()) {
+    found_it = false;
+    function = FindInPrototypeChain<JSFunction>(object->GetPrototype(),
+                                                &found_it);
+    // There has to be one because we hit the getter.
+    ASSERT(found_it);
+  }
+
   if (!function->has_prototype()) {
-    if (!function->should_have_prototype()) return Heap::undefined_value();
     Object* prototype;
     { MaybeObject* maybe_prototype = Heap::AllocateFunctionPrototype(function);
       if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype;
@@ -467,6 +474,13 @@ MaybeObject* Accessors::FunctionSetPrototype(JSObject* object,
   bool found_it = false;
   JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it);
   if (!found_it) return Heap::undefined_value();
+  if (!function->should_have_prototype()) {
+    // Since we hit this accessor, object will have no prototype property.
+    return object->SetLocalPropertyIgnoreAttributes(Heap::prototype_symbol(),
+                                                    value,
+                                                    NONE);
+  }
+
   if (function->has_initial_map()) {
     // If the function has allocated the initial map
     // replace it with a copy containing the new prototype.
index d36126e..8d0bca9 100644 (file)
 
 __defineSetter__.__proto__ = function() {};
 __defineSetter__['prototype']
+
+eval.__proto__ = function () { };
+eval['prototype'] = {};
+
+// Test that we are compatible with Safari on prototypes set locally and
+// on the actual prototype set using __proto__ on objects that has the
+// should_have_prototype set to false.
+function f() { return 42; }
+f.prototype = 43;
+__defineGetter__.__proto__ = f;
+
+// Regression test for not returning undefined.
+assertEquals(__defineGetter__.prototype, 43);
+
+// Regression test for not crashing.
+__defineGetter__.prototype = "foo";
+assertEquals(__defineGetter__.prototype, "foo");