2009-10-05 John Abd-El-Malek <jam@chromium.org>
authorabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 Oct 2009 04:55:14 +0000 (04:55 +0000)
committerabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 Oct 2009 04:55:14 +0000 (04:55 +0000)
        Reviewed by Adam Barth.

        Fix reliablity bot crash in DateExtension.
        https://bugs.webkit.org/show_bug.cgi?id=30033

        There were a few problems using the weak persistent pointers because no one else had a
        handle to them.  The new approach stores them as a hidden value on the Date constructor.

        * bindings/v8/DateExtension.cpp:
        (WebCore::DateExtension::setAllowSleep):
        (WebCore::DateExtension::GetNativeFunction):
        (WebCore::DateExtension::Setup):
        (WebCore::DateExtension::OnSleepDetected):
        * bindings/v8/DateExtension.h:
        * bindings/v8/V8HiddenPropertyName.cpp:
        (WebCore::V8HiddenPropertyName::sleepFunction):
        * bindings/v8/V8HiddenPropertyName.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@49148 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/bindings/v8/DateExtension.cpp
WebCore/bindings/v8/DateExtension.h
WebCore/bindings/v8/V8HiddenPropertyName.h

index 3918c79b20de1eb187fb55e6830d9cb1a3813a19..9ccde15c1a04a46ef39a0af9fa0c1ee2cf6caafb 100644 (file)
@@ -1,3 +1,23 @@
+2009-10-05  John Abd-El-Malek  <jam@chromium.org>
+
+        Reviewed by Adam Barth.
+
+        Fix reliablity bot crash in DateExtension.
+        https://bugs.webkit.org/show_bug.cgi?id=30033
+
+        There were a few problems using the weak persistent pointers because no one else had a
+        handle to them.  The new approach stores them as a hidden value on the Date constructor.
+
+        * bindings/v8/DateExtension.cpp:
+        (WebCore::DateExtension::setAllowSleep):
+        (WebCore::DateExtension::GetNativeFunction):
+        (WebCore::DateExtension::Setup):
+        (WebCore::DateExtension::OnSleepDetected):
+        * bindings/v8/DateExtension.h:
+        * bindings/v8/V8HiddenPropertyName.cpp:
+        (WebCore::V8HiddenPropertyName::sleepFunction):
+        * bindings/v8/V8HiddenPropertyName.h:
+
 2009-10-05  Stephanie Lewis  <slewis@apple.com>
 
         Reviewed by Dan Bernstein.
index 9e256954299f825de68568871a3ff533e7d0a31b..778a15abc5c91b72aff165b0ea76af5b5d359a17 100644 (file)
@@ -32,6 +32,7 @@
 #include "DateExtension.h"
 
 #include "V8Proxy.h"
+#include "V8HiddenPropertyName.h"
 
 namespace WebCore {
 
@@ -56,9 +57,9 @@ static const char* dateExtensionScript =
     "      Date.prototype.getTime = orig_getTime;"
     "    }"
     "  };"
+    "  native function Setup();"
     "  native function OnSleepDetected();"
-    "  native function GiveEnableSleepDetectionFunction();"
-    "  GiveEnableSleepDetectionFunction(enableSleepDetection);"
+    "  Setup(Date, enableSleepDetection);"
     "})()";
 
 DateExtension::DateExtension() : v8::Extension(dateExtensionName, dateExtensionScript)
@@ -74,57 +75,47 @@ DateExtension* DateExtension::get()
 
 void DateExtension::setAllowSleep(bool allow)
 {
+    v8::Local<v8::Value> result = V8Proxy::retrieve()->context()->Global()->Get(v8::String::New("Date"));
+    if (result.IsEmpty())
+        return;
+
+    v8::Handle<v8::Object> dateObject = v8::Handle<v8::Object>::Cast(result);
+    if (dateObject.IsEmpty())
+        return;
+
+    v8::Local<v8::Value> sleepFunctionHandle = dateObject->GetHiddenValue(V8HiddenPropertyName::sleepFunction());
+    if (sleepFunctionHandle.IsEmpty() || !sleepFunctionHandle->IsFunction())
+        return;
+
     v8::Handle<v8::Value> argv[1];
     argv[0] = v8::String::New(allow ? "false" : "true");
-    for (size_t i = 0; i < callEnableSleepDetectionFunctionPointers.size(); ++i)
-        callEnableSleepDetectionFunctionPointers[i]->Call(v8::Object::New(), 1, argv);
+    v8::Handle<v8::Function>::Cast(sleepFunctionHandle)->Call(v8::Object::New(), 1, argv);
 }
 
 v8::Handle<v8::FunctionTemplate> DateExtension::GetNativeFunction(v8::Handle<v8::String> name)
 {
-    if (name->Equals(v8::String::New("GiveEnableSleepDetectionFunction")))
-        return v8::FunctionTemplate::New(GiveEnableSleepDetectionFunction);
+    if (name->Equals(v8::String::New("Setup")))
+        return v8::FunctionTemplate::New(Setup);
     if (name->Equals(v8::String::New("OnSleepDetected")))
         return v8::FunctionTemplate::New(OnSleepDetected);
 
     return v8::Handle<v8::FunctionTemplate>();
 }
 
-void DateExtension::weakCallback(v8::Persistent<v8::Value> object, void* param)
-{
-    DateExtension* extension = get();
-    for (size_t i = 0; i < extension->callEnableSleepDetectionFunctionPointers.size(); ++i) {
-        if (extension->callEnableSleepDetectionFunctionPointers[i] == object) {
-            object.Dispose();
-            extension->callEnableSleepDetectionFunctionPointers.remove(i);
-            return;
-        }
-    }
-    ASSERT_NOT_REACHED();
-}
-
-v8::Handle<v8::Value> DateExtension::GiveEnableSleepDetectionFunction(const v8::Arguments& args)
+v8::Handle<v8::Value> DateExtension::Setup(const v8::Arguments& args)
 {
-    if (args.Length() != 1 || !args[0]->IsFunction())
+    if (args.Length() != 2 || !args[0]->IsObject() || !args[1]->IsFunction())
         return v8::Undefined();
 
-    // Ideally, we would get the Frame* here and associate it with the function pointer, so that
-    // each time we go into an unload handler we just call that frame's function.  However there's
-    // no way to get the Frame* at this point, so we just store all the function pointers and call
-    // them all each time.
-    DateExtension* extension = get();
-    extension->callEnableSleepDetectionFunctionPointers.append(
-        v8::Persistent<v8::Function>::New(v8::Handle<v8::Function>::Cast(args[0])));
-    extension->callEnableSleepDetectionFunctionPointers.last().MakeWeak(NULL, weakCallback);
+    v8::Handle<v8::Object> dateObject = v8::Handle<v8::Object>::Cast(args[0]);
+    v8::Handle<v8::Function> enableSleepDetectionFunction = v8::Handle<v8::Function>::Cast(args[1]);
+
+    dateObject->SetHiddenValue(V8HiddenPropertyName::sleepFunction(), enableSleepDetectionFunction);
     return v8::Undefined();
 }
 
 v8::Handle<v8::Value> DateExtension::OnSleepDetected(const v8::Arguments&)
 {
-    // After we call TerminateExecution(), we can't call back into JavaScript again, so
-    // reset all the other frames first.
-    get()->setAllowSleep(true);
-
     v8::V8::TerminateExecution();
     return v8::Undefined();
 }
index 6611c5b9cd1553b3343f4bcf5e73a4f04613b206..2bccac40dba039f762a1dd8a696ecf9fb23a9e02 100644 (file)
@@ -33,8 +33,6 @@
 
 #include <v8.h>
 
-#include "Vector.h"
-
 namespace WebCore {
 
 // Prevent "sleep" calls in unload handlers.
@@ -46,12 +44,8 @@ public:
 private:
     DateExtension();
     virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(v8::Handle<v8::String>);
-    static v8::Handle<v8::Value> GiveEnableSleepDetectionFunction(const v8::Arguments&);
+    static v8::Handle<v8::Value> Setup(const v8::Arguments&);
     static v8::Handle<v8::Value> OnSleepDetected(const v8::Arguments&);
-    static void weakCallback(v8::Persistent<v8::Value> object, void* param);
-
-    typedef WTF::Vector<v8::Persistent<v8::Function> > FunctionPointers;
-    FunctionPointers callEnableSleepDetectionFunctionPointers;
 
     static DateExtension* extension;
 };
index 58c01eb513effef9447259274afc2bacc27f6ae6..5ef89cb92fb5af2393a89d58b2abe2bc68c4a7fc 100644 (file)
@@ -40,6 +40,7 @@ namespace WebCore {
     V(isolatedWorld) \
     V(listener) \
     V(attributeListener) \
+    V(sleepFunction) \
     V(toStringString)
 
     class V8HiddenPropertyName {