[V8] Get rid of function-level static FunctionTemplates in generated bindings code
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Mar 2013 07:52:32 +0000 (07:52 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Mar 2013 07:52:32 +0000 (07:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=111971

Patch by Marja Hölttä <marja@chromium.org> on 2013-03-12
Reviewed by Kentaro Hara.

In the future we'll create and store function templates for main world
and non-main worlds separately (see bug 111724), having function
templates as static variables inside functions will break the
functionality.

No new tests (updated the bindings test expectations).

* bindings/scripts/CodeGeneratorV8.pm:
(GenerateDomainSafeFunctionGetter):
* bindings/scripts/test/V8/V8TestActiveDOMObject.cpp:
(WebCore::TestActiveDOMObjectV8Internal::postMessageAttrGetter):
* bindings/v8/V8PerIsolateData.cpp:
(WebCore::V8PerIsolateData::V8PerIsolateData):
(WebCore::V8PerIsolateData::privateTemplate):
(WebCore):
* bindings/v8/V8PerIsolateData.h:
(V8PerIsolateData):
* bindings/v8/custom/V8LocationCustom.cpp:
(WebCore::V8Location::reloadAttrGetterCustom):
(WebCore::V8Location::replaceAttrGetterCustom):
(WebCore::V8Location::assignAttrGetterCustom):

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

Source/WebCore/ChangeLog
Source/WebCore/bindings/scripts/CodeGeneratorV8.pm
Source/WebCore/bindings/scripts/test/V8/V8TestActiveDOMObject.cpp
Source/WebCore/bindings/v8/V8PerIsolateData.cpp
Source/WebCore/bindings/v8/V8PerIsolateData.h
Source/WebCore/bindings/v8/custom/V8LocationCustom.cpp

index 62fa726..96d6bc4 100644 (file)
@@ -1,3 +1,32 @@
+2013-03-12  Marja Hölttä  <marja@chromium.org>
+
+        [V8] Get rid of function-level static FunctionTemplates in generated bindings code
+        https://bugs.webkit.org/show_bug.cgi?id=111971
+
+        Reviewed by Kentaro Hara.
+
+        In the future we'll create and store function templates for main world
+        and non-main worlds separately (see bug 111724), having function
+        templates as static variables inside functions will break the
+        functionality.
+
+        No new tests (updated the bindings test expectations).
+
+        * bindings/scripts/CodeGeneratorV8.pm:
+        (GenerateDomainSafeFunctionGetter):
+        * bindings/scripts/test/V8/V8TestActiveDOMObject.cpp:
+        (WebCore::TestActiveDOMObjectV8Internal::postMessageAttrGetter):
+        * bindings/v8/V8PerIsolateData.cpp:
+        (WebCore::V8PerIsolateData::V8PerIsolateData):
+        (WebCore::V8PerIsolateData::privateTemplate):
+        (WebCore):
+        * bindings/v8/V8PerIsolateData.h:
+        (V8PerIsolateData):
+        * bindings/v8/custom/V8LocationCustom.cpp:
+        (WebCore::V8Location::reloadAttrGetterCustom):
+        (WebCore::V8Location::replaceAttrGetterCustom):
+        (WebCore::V8Location::assignAttrGetterCustom):
+
 2013-03-12  Tien-Ren Chen  <trchen@chromium.org>
 
         Need to notify ScrollingCoordinator when frame scrollbars are destroyed
index e38af4d..acc737b 100644 (file)
@@ -786,14 +786,18 @@ sub GenerateDomainSafeFunctionGetter
         $signature = "v8::Local<v8::Signature>()";
     }
 
-    my $newTemplateString = "v8::FunctionTemplate::New(${interfaceName}V8Internal::${funcName}MethodCallback, v8Undefined(), $signature)";
+    my $newTemplateParams = "${interfaceName}V8Internal::${funcName}MethodCallback, v8Undefined(), $signature";
 
     AddToImplIncludes("Frame.h");
     push(@implContentInternals, <<END);
 static v8::Handle<v8::Value> ${funcName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
-    static v8::Persistent<v8::FunctionTemplate> privateTemplate = v8::Persistent<v8::FunctionTemplate>::New(info.GetIsolate(), $newTemplateString);
-    v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(${v8InterfaceName}::GetTemplate(info.GetIsolate(), worldType(info.GetIsolate())));
+    // This is only for getting a unique pointer which we can pass to privateTemplate.
+    static String privateTemplateUniqueKey = "${funcName}PrivateTemplate";
+    WrapperWorldType currentWorldType = worldType(info.GetIsolate());
+    v8::Persistent<v8::FunctionTemplate> privateTemplate = V8PerIsolateData::from(info.GetIsolate())->privateTemplate(currentWorldType, &privateTemplateUniqueKey, $newTemplateParams);
+
+    v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(${v8InterfaceName}::GetTemplate(info.GetIsolate(), currentWorldType));
     if (holder.IsEmpty()) {
         // can only reach here by 'object.__proto__.func', and it should passed
         // domain security check already
@@ -801,7 +805,8 @@ static v8::Handle<v8::Value> ${funcName}AttrGetter(v8::Local<v8::String> name, c
     }
     ${interfaceName}* imp = ${v8InterfaceName}::toNative(holder);
     if (!BindingSecurity::shouldAllowAccessToFrame(BindingState::instance(), imp->frame(), DoNotReportSecurityError)) {
-        static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New(info.GetIsolate(), $newTemplateString);
+        static String sharedTemplateUniqueKey = "${funcName}SharedTemplate";
+        v8::Persistent<v8::FunctionTemplate> sharedTemplate = V8PerIsolateData::from(info.GetIsolate())->privateTemplate(currentWorldType, &sharedTemplateUniqueKey, $newTemplateParams);
         return sharedTemplate->GetFunction();
     }
 
index 78c3fff..9a62cc0 100644 (file)
@@ -128,8 +128,12 @@ static v8::Handle<v8::Value> postMessageMethodCallback(const v8::Arguments& args
 
 static v8::Handle<v8::Value> postMessageAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
-    static v8::Persistent<v8::FunctionTemplate> privateTemplate = v8::Persistent<v8::FunctionTemplate>::New(info.GetIsolate(), v8::FunctionTemplate::New(TestActiveDOMObjectV8Internal::postMessageMethodCallback, v8Undefined(), v8::Signature::New(V8TestActiveDOMObject::GetRawTemplate(info.GetIsolate()))));
-    v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(V8TestActiveDOMObject::GetTemplate(info.GetIsolate(), worldType(info.GetIsolate())));
+    // This is only for getting a unique pointer which we can pass to privateTemplate.
+    static String privateTemplateUniqueKey = "postMessagePrivateTemplate";
+    WrapperWorldType currentWorldType = worldType(info.GetIsolate());
+    v8::Persistent<v8::FunctionTemplate> privateTemplate = V8PerIsolateData::from(info.GetIsolate())->privateTemplate(currentWorldType, &privateTemplateUniqueKey, TestActiveDOMObjectV8Internal::postMessageMethodCallback, v8Undefined(), v8::Signature::New(V8TestActiveDOMObject::GetRawTemplate(info.GetIsolate())));
+
+    v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(V8TestActiveDOMObject::GetTemplate(info.GetIsolate(), currentWorldType));
     if (holder.IsEmpty()) {
         // can only reach here by 'object.__proto__.func', and it should passed
         // domain security check already
@@ -137,7 +141,8 @@ static v8::Handle<v8::Value> postMessageAttrGetter(v8::Local<v8::String> name, c
     }
     TestActiveDOMObject* imp = V8TestActiveDOMObject::toNative(holder);
     if (!BindingSecurity::shouldAllowAccessToFrame(BindingState::instance(), imp->frame(), DoNotReportSecurityError)) {
-        static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New(info.GetIsolate(), v8::FunctionTemplate::New(TestActiveDOMObjectV8Internal::postMessageMethodCallback, v8Undefined(), v8::Signature::New(V8TestActiveDOMObject::GetRawTemplate(info.GetIsolate()))));
+        static String sharedTemplateUniqueKey = "postMessageSharedTemplate";
+        v8::Persistent<v8::FunctionTemplate> sharedTemplate = V8PerIsolateData::from(info.GetIsolate())->privateTemplate(currentWorldType, &sharedTemplateUniqueKey, TestActiveDOMObjectV8Internal::postMessageMethodCallback, v8Undefined(), v8::Signature::New(V8TestActiveDOMObject::GetRawTemplate(info.GetIsolate())));
         return sharedTemplate->GetFunction();
     }
 
index 0100ce6..986ca23 100644 (file)
@@ -44,7 +44,8 @@ template<> struct SequenceMemoryInstrumentationTraits<WebCore::WrapperTypeInfo*>
 namespace WebCore {
 
 V8PerIsolateData::V8PerIsolateData(v8::Isolate* isolate)
-    : m_stringCache(adoptPtr(new StringCache()))
+    : m_isolate(isolate)
+    , m_stringCache(adoptPtr(new StringCache()))
     , m_integerCache(adoptPtr(new IntegerCache()))
     , m_domDataStore(0)
     , m_hiddenPropertyName(adoptPtr(new V8HiddenPropertyName()))
@@ -121,6 +122,17 @@ void V8PerIsolateData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) con
     info.ignoreMember(m_auxiliaryContext);
 }
 
+v8::Persistent<v8::FunctionTemplate> V8PerIsolateData::privateTemplate(WrapperWorldType, void* privatePointer, v8::InvocationCallback callback, v8::Handle<v8::Value> data, v8::Handle<v8::Signature> signature, int length)
+{
+    v8::Persistent<v8::FunctionTemplate> privateTemplate;
+    V8PerIsolateData::TemplateMap::iterator result = m_templates.find(privatePointer);
+    if (result != m_templates.end())
+        return result->value;
+    v8::Persistent<v8::FunctionTemplate> newPrivateTemplate = v8::Persistent<v8::FunctionTemplate>::New(m_isolate, v8::FunctionTemplate::New(callback, data, signature, length));
+    m_templates.add(privatePointer, newPrivateTemplate);
+    return newPrivateTemplate;
+}
+
 #if ENABLE(INSPECTOR)
 void V8PerIsolateData::visitExternalStrings(ExternalStringVisitor* visitor)
 {
index 33cd849..0e7a7f9 100644 (file)
@@ -27,6 +27,7 @@
 #define V8PerIsolateData_h
 
 #include "ScopedPersistent.h"
+#include "WrapperTypeInfo.h"
 #include <v8.h>
 #include <wtf/Forward.h>
 #include <wtf/HashMap.h>
@@ -64,7 +65,7 @@ public:
     }
     static void dispose(v8::Isolate*);
 
-    typedef HashMap<WrapperTypeInfo*, v8::Persistent<v8::FunctionTemplate> > TemplateMap;
+    typedef HashMap<void*, v8::Persistent<v8::FunctionTemplate> > TemplateMap;
 
     TemplateMap& rawTemplateMap() { return m_rawTemplates; }
     TemplateMap& templateMap() { return m_templates; }
@@ -127,11 +128,14 @@ public:
     void clearShouldCollectGarbageSoon() { m_shouldCollectGarbageSoon = false; }
     bool shouldCollectGarbageSoon() const { return m_shouldCollectGarbageSoon; }
 
+    v8::Persistent<v8::FunctionTemplate> privateTemplate(WrapperWorldType, void* privatePointer, v8::InvocationCallback, v8::Handle<v8::Value> data, v8::Handle<v8::Signature>, int length = 0);
+
 private:
     explicit V8PerIsolateData(v8::Isolate*);
     ~V8PerIsolateData();
     static v8::Handle<v8::Value> constructorOfToString(const v8::Arguments&);
 
+    v8::Isolate* m_isolate;
     TemplateMap m_rawTemplates;
     TemplateMap m_templates;
     ScopedPersistent<v8::FunctionTemplate> m_toStringTemplate;
index 6b6fe6f..859dad3 100644 (file)
@@ -139,8 +139,12 @@ void V8Location::searchAttrSetterCustom(v8::Local<v8::String> name, v8::Local<v8
 v8::Handle<v8::Value> V8Location::reloadAttrGetterCustom(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     v8::Isolate* isolate = info.GetIsolate();
-    static v8::Persistent<v8::FunctionTemplate> privateTemplate = v8::Persistent<v8::FunctionTemplate>::New(isolate, v8::FunctionTemplate::New(V8Location::reloadMethodCustom, v8Undefined(), v8::Signature::New(V8Location::GetRawTemplate(isolate))));
-    v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(V8Location::GetTemplate(isolate, worldType(isolate)));
+    // This is only for getting a unique pointer which we can pass to privateTemplate.
+    static String privateTemplateUniqueKey = "reloadPrivateTemplate";
+    WrapperWorldType currentWorldType = worldType(isolate);
+    v8::Persistent<v8::FunctionTemplate> privateTemplate = V8PerIsolateData::from(isolate)->privateTemplate(currentWorldType, &privateTemplateUniqueKey, V8Location::reloadMethodCustom, v8Undefined(), v8::Signature::New(V8Location::GetRawTemplate(isolate)));
+
+    v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(V8Location::GetTemplate(isolate, currentWorldType));
     if (holder.IsEmpty()) {
         // can only reach here by 'object.__proto__.func', and it should passed
         // domain security check already
@@ -148,7 +152,8 @@ v8::Handle<v8::Value> V8Location::reloadAttrGetterCustom(v8::Local<v8::String> n
     }
     Location* imp = V8Location::toNative(holder);
     if (!BindingSecurity::shouldAllowAccessToFrame(BindingState::instance(), imp->frame(), DoNotReportSecurityError)) {
-        static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New(isolate, v8::FunctionTemplate::New(V8Location::reloadMethodCustom, v8Undefined(), v8::Signature::New(V8Location::GetRawTemplate(isolate))));
+        static String sharedTemplateUniqueKey = "reloadSharedTemplate";
+        v8::Persistent<v8::FunctionTemplate> sharedTemplate = V8PerIsolateData::from(info.GetIsolate())->privateTemplate(currentWorldType, &sharedTemplateUniqueKey, V8Location::reloadMethodCustom, v8Undefined(), v8::Signature::New(V8Location::GetRawTemplate(isolate)));
         return sharedTemplate->GetFunction();
     }
     return privateTemplate->GetFunction();
@@ -157,8 +162,12 @@ v8::Handle<v8::Value> V8Location::reloadAttrGetterCustom(v8::Local<v8::String> n
 v8::Handle<v8::Value> V8Location::replaceAttrGetterCustom(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     v8::Isolate* isolate = info.GetIsolate();
-    static v8::Persistent<v8::FunctionTemplate> privateTemplate = v8::Persistent<v8::FunctionTemplate>::New(isolate, v8::FunctionTemplate::New(V8Location::replaceMethodCustom, v8Undefined(), v8::Signature::New(V8Location::GetRawTemplate(isolate))));
-    v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(V8Location::GetTemplate(isolate, worldType(isolate)));
+    // This is only for getting a unique pointer which we can pass to privateTemplateMap.
+    static String privateTemplateUniqueKey = "replacePrivateTemplate";
+    WrapperWorldType currentWorldType = worldType(info.GetIsolate());
+    v8::Persistent<v8::FunctionTemplate> privateTemplate = V8PerIsolateData::from(isolate)->privateTemplate(currentWorldType, &privateTemplateUniqueKey, V8Location::replaceMethodCustom, v8Undefined(), v8::Signature::New(V8Location::GetRawTemplate(isolate)));
+
+    v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(V8Location::GetTemplate(isolate, currentWorldType));
     if (holder.IsEmpty()) {
         // can only reach here by 'object.__proto__.func', and it should passed
         // domain security check already
@@ -166,7 +175,8 @@ v8::Handle<v8::Value> V8Location::replaceAttrGetterCustom(v8::Local<v8::String>
     }
     Location* imp = V8Location::toNative(holder);
     if (!BindingSecurity::shouldAllowAccessToFrame(BindingState::instance(), imp->frame(), DoNotReportSecurityError)) {
-        static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New(isolate, v8::FunctionTemplate::New(V8Location::replaceMethodCustom, v8Undefined(), v8::Signature::New(V8Location::GetRawTemplate(isolate))));
+        static String sharedTemplateUniqueKey = "replaceSharedTemplate";
+        v8::Persistent<v8::FunctionTemplate> sharedTemplate = V8PerIsolateData::from(info.GetIsolate())->privateTemplate(currentWorldType, &sharedTemplateUniqueKey, V8Location::replaceMethodCustom, v8Undefined(), v8::Signature::New(V8Location::GetRawTemplate(isolate)));
         return sharedTemplate->GetFunction();
     }
     return privateTemplate->GetFunction();
@@ -175,9 +185,12 @@ v8::Handle<v8::Value> V8Location::replaceAttrGetterCustom(v8::Local<v8::String>
 v8::Handle<v8::Value> V8Location::assignAttrGetterCustom(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     v8::Isolate* isolate = info.GetIsolate();
-    static v8::Persistent<v8::FunctionTemplate> privateTemplate =
-        v8::Persistent<v8::FunctionTemplate>::New(isolate, v8::FunctionTemplate::New(V8Location::assignMethodCustom, v8Undefined(), v8::Signature::New(V8Location::GetRawTemplate(isolate))));
-    v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(V8Location::GetTemplate(isolate, worldType(isolate)));
+    // This is only for getting a unique pointer which we can pass to privateTemplateMap.
+    static String privateTemplateUniqueKey = "assignPrivateTemplate";
+    WrapperWorldType currentWorldType = worldType(info.GetIsolate());
+    v8::Persistent<v8::FunctionTemplate> privateTemplate = V8PerIsolateData::from(isolate)->privateTemplate(currentWorldType, &privateTemplateUniqueKey, V8Location::assignMethodCustom, v8Undefined(), v8::Signature::New(V8Location::GetRawTemplate(isolate)));
+
+    v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(V8Location::GetTemplate(isolate, currentWorldType));
     if (holder.IsEmpty()) {
         // can only reach here by 'object.__proto__.func', and it should passed
         // domain security check already
@@ -185,7 +198,8 @@ v8::Handle<v8::Value> V8Location::assignAttrGetterCustom(v8::Local<v8::String> n
     }
     Location* imp = V8Location::toNative(holder);
     if (!BindingSecurity::shouldAllowAccessToFrame(BindingState::instance(), imp->frame(), DoNotReportSecurityError)) {
-        static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New(isolate, v8::FunctionTemplate::New(V8Location::assignMethodCustom, v8Undefined(), v8::Signature::New(V8Location::GetRawTemplate(isolate))));
+        static String sharedTemplateUniqueKey = "assignSharedTemplate";
+        v8::Persistent<v8::FunctionTemplate> sharedTemplate = V8PerIsolateData::from(info.GetIsolate())->privateTemplate(currentWorldType, &sharedTemplateUniqueKey, V8Location::assignMethodCustom, v8Undefined(), v8::Signature::New(V8Location::GetRawTemplate(isolate)));
         return sharedTemplate->GetFunction();
     }
     return privateTemplate->GetFunction();