Title: [144865] trunk/Source/WebCore
Revision
144865
Author
morr...@google.com
Date
2013-03-05 18:52:34 -0800 (Tue, 05 Mar 2013)

Log Message

[Custom Elements][V8] Custom Element doesn't need its own WrapperTypeInfo
https://bugs.webkit.org/show_bug.cgi?id=111411

Reviewed by Kentaro Hara.

No new tests. No observable change yet.

This is a preparation for Bug 110436, where WebKit is going to
allow any HTML element to be a superclass of custom elements.

This change eliminates WrapperTypeInfo for custom element. Instead
of that, the wrapper of a custom element picks WrapperTypeInfo
from most descendant built-in HTML element. For example, think about
following hierarchy:

- ... <- HTMLElement <- HTMLDivElememnt <- ExistingCustomElement <- NewCustomElement

In this case, both ExistingCustomElement and NewCustomElement has
HTMLDivElememnt's type info. This is because HTMLDivElememnt is
the most descendant (or "the nearest") built-in HTML
element. (HTMLElement isn't the most descendant.
ExistingCustomElement isn't a built-in.)

Using such WrapperTypeInfos, created custom element wrappers can
get appropriate set of method and properties regardless of its
super-elements.

This change tells the prototype object of each built-in object
which WrapperTypeInfo the native backing wants:
HTMLDivElememnt.prototype knows V8HTMLDivElement::info for
example. The pointer to the type info is stored into an internal
field. On wrapper construction, createWrapper() walks up the
prototype chain and pick the first one.

* bindings/v8/V8DOMConfiguration.cpp:
(WebCore::V8DOMConfiguration::configureTemplate):
* bindings/v8/V8HTMLCustomElement.cpp:
(WebCore::findWrapperTypeOf):
(WebCore::V8HTMLCustomElement::createWrapper):
* bindings/v8/V8HTMLCustomElement.h:
* bindings/v8/V8PerContextData.cpp:
(WebCore::V8PerContextData::constructorForTypeSlowCase):
* bindings/v8/WrapperTypeInfo.h:
(WebCore):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (144864 => 144865)


--- trunk/Source/WebCore/ChangeLog	2013-03-06 02:51:18 UTC (rev 144864)
+++ trunk/Source/WebCore/ChangeLog	2013-03-06 02:52:34 UTC (rev 144865)
@@ -1,3 +1,50 @@
+2013-03-05  Hajime Morrita  <morr...@google.com>
+
+        [Custom Elements][V8] Custom Element doesn't need its own WrapperTypeInfo
+        https://bugs.webkit.org/show_bug.cgi?id=111411
+
+        Reviewed by Kentaro Hara.
+
+        No new tests. No observable change yet.
+
+        This is a preparation for Bug 110436, where WebKit is going to
+        allow any HTML element to be a superclass of custom elements.
+
+        This change eliminates WrapperTypeInfo for custom element. Instead
+        of that, the wrapper of a custom element picks WrapperTypeInfo
+        from most descendant built-in HTML element. For example, think about
+        following hierarchy:
+
+        - ... <- HTMLElement <- HTMLDivElememnt <- ExistingCustomElement <- NewCustomElement
+
+        In this case, both ExistingCustomElement and NewCustomElement has
+        HTMLDivElememnt's type info. This is because HTMLDivElememnt is
+        the most descendant (or "the nearest") built-in HTML
+        element. (HTMLElement isn't the most descendant.
+        ExistingCustomElement isn't a built-in.)
+
+        Using such WrapperTypeInfos, created custom element wrappers can
+        get appropriate set of method and properties regardless of its
+        super-elements.
+
+        This change tells the prototype object of each built-in object
+        which WrapperTypeInfo the native backing wants:
+        HTMLDivElememnt.prototype knows V8HTMLDivElement::info for
+        example. The pointer to the type info is stored into an internal
+        field. On wrapper construction, createWrapper() walks up the
+        prototype chain and pick the first one.
+
+        * bindings/v8/V8DOMConfiguration.cpp:
+        (WebCore::V8DOMConfiguration::configureTemplate):
+        * bindings/v8/V8HTMLCustomElement.cpp:
+        (WebCore::findWrapperTypeOf):
+        (WebCore::V8HTMLCustomElement::createWrapper):
+        * bindings/v8/V8HTMLCustomElement.h:
+        * bindings/v8/V8PerContextData.cpp:
+        (WebCore::V8PerContextData::constructorForTypeSlowCase):
+        * bindings/v8/WrapperTypeInfo.h:
+        (WebCore):
+
 2013-03-05  Aaron Colwell  <acolw...@chromium.org>
 
         Heap-use-after-free in WebCore::HTMLMediaElement::~HTMLMediaElement

Modified: trunk/Source/WebCore/bindings/v8/V8DOMConfiguration.cpp (144864 => 144865)


--- trunk/Source/WebCore/bindings/v8/V8DOMConfiguration.cpp	2013-03-06 02:51:18 UTC (rev 144864)
+++ trunk/Source/WebCore/bindings/v8/V8DOMConfiguration.cpp	2013-03-06 02:52:34 UTC (rev 144865)
@@ -33,8 +33,6 @@
 
 namespace WebCore {
 
-const int prototypeInternalFieldcount = 1;
-
 void V8DOMConfiguration::batchConfigureAttributes(v8::Handle<v8::ObjectTemplate> instance, v8::Handle<v8::ObjectTemplate> prototype, const BatchedAttribute* attributes, size_t attributeCount, v8::Isolate* isolate)
 {
     for (size_t i = 0; i < attributeCount; ++i)
@@ -68,7 +66,7 @@
         // This is needed since bug 110436 asks WebKit to tell native-initiated prototypes from pure-JS ones.
         // This doesn't mark kinds "root" classes like Node, where setting this changes prototype chain structure.
         v8::Local<v8::ObjectTemplate> prototype = functionDescriptor->PrototypeTemplate();
-        prototype->SetInternalFieldCount(prototypeInternalFieldcount);
+        prototype->SetInternalFieldCount(v8PrototypeInternalFieldcount);
     }
 
     if (attributeCount)

Modified: trunk/Source/WebCore/bindings/v8/V8HTMLCustomElement.cpp (144864 => 144865)


--- trunk/Source/WebCore/bindings/v8/V8HTMLCustomElement.cpp	2013-03-06 02:51:18 UTC (rev 144864)
+++ trunk/Source/WebCore/bindings/v8/V8HTMLCustomElement.cpp	2013-03-06 02:52:34 UTC (rev 144865)
@@ -38,13 +38,22 @@
 #include "CustomElementRegistry.h"
 #include "HTMLElement.h"
 #include "V8CustomElementConstructor.h"
-#include "V8HTMLSpanElement.h"
+#include "V8HTMLUnknownElement.h"
 
 namespace WebCore {
 
-// FIXME: Each custom elements should have its own GetTemplate method so that it can be derived from different super element.
-WrapperTypeInfo V8HTMLCustomElement::info = { &V8HTMLElement::GetTemplate, V8HTMLElement::derefObject, 0, V8HTMLElement::toEventTarget, 0, 0, &V8HTMLElement::info, WrapperTypeObjectPrototype };
+static WrapperTypeInfo* findWrapperTypeOf(v8::Handle<v8::Value> chain)
+{
+    while (!chain.IsEmpty() && chain->IsObject()) {
+        v8::Handle<v8::Object> chainObject = v8::Handle<v8::Object>::Cast(chain);
+        if (v8PrototypeInternalFieldcount == chainObject->InternalFieldCount())
+            return reinterpret_cast<WrapperTypeInfo*>(chainObject->GetAlignedPointerFromInternalField(v8PrototypeTypeIndex));
+        chain = chainObject->GetPrototype();
+    }
 
+    return 0;
+}
+
 v8::Handle<v8::Object> V8HTMLCustomElement::createWrapper(PassRefPtr<HTMLElement> impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
     ASSERT(impl);
@@ -57,22 +66,31 @@
         return v8::Handle<v8::Object>();
     }
 
-    v8::Handle<v8::Object> wrapper = V8DOMWrapper::createWrapper(creationContext, &info, impl.get(), isolate);
-    if (wrapper.IsEmpty())
-        return wrapper;
-
     // The constructor and registered lifecycle callbacks should be visible only from main world.
     // FIXME: This shouldn't be needed once each custom element has its own FunctionTemplate
     // https://bugs.webkit.org/show_bug.cgi?id=108138
-    if (CustomElementHelpers::isFeatureAllowed(creationContext->CreationContext())) {
-        v8::Handle<v8::Value> wrapperValue = WebCore::toV8(constructor.get(), creationContext, isolate);
-        if (wrapperValue.IsEmpty() || !wrapperValue->IsObject())
-            return v8::Handle<v8::Object>();
-        v8::Handle<v8::Object> constructorWapper = v8::Handle<v8::Object>::Cast(wrapperValue);
-        wrapper->SetPrototype(constructorWapper->Get(v8String("prototype", isolate)));
+    if (!CustomElementHelpers::isFeatureAllowed(creationContext->CreationContext())) {
+        v8::Handle<v8::Object> wrapper = V8DOMWrapper::createWrapper(creationContext, &V8HTMLElement::info, impl.get(), isolate);
+        if (!wrapper.IsEmpty())
+            V8DOMWrapper::associateObjectWithWrapper(impl, &V8HTMLElement::info, wrapper, isolate, WrapperConfiguration::Dependent);
+        return wrapper;
     }
 
-    V8DOMWrapper::associateObjectWithWrapper(impl, &info, wrapper, isolate, WrapperConfiguration::Dependent);
+    v8::Handle<v8::Value> constructorValue = WebCore::toV8(constructor.get(), creationContext, isolate);
+    if (constructorValue.IsEmpty() || !constructorValue->IsObject())
+        return v8::Handle<v8::Object>();
+    v8::Handle<v8::Object> constructorWapper = v8::Handle<v8::Object>::Cast(constructorValue);
+    v8::Handle<v8::Object> prototype = v8::Handle<v8::Object>::Cast(constructorWapper->Get(v8::String::NewSymbol("prototype")));
+    WrapperTypeInfo* typeInfo = findWrapperTypeOf(prototype);
+    if (!typeInfo)
+        return v8::Handle<v8::Object>();
+
+    v8::Handle<v8::Object> wrapper = V8DOMWrapper::createWrapper(creationContext, typeInfo, impl.get(), isolate);
+    if (wrapper.IsEmpty())
+        return v8::Handle<v8::Object>();
+
+    wrapper->SetPrototype(prototype);
+    V8DOMWrapper::associateObjectWithWrapper(impl, typeInfo, wrapper, isolate, WrapperConfiguration::Dependent);
     return wrapper;
 }
 

Modified: trunk/Source/WebCore/bindings/v8/V8HTMLCustomElement.h (144864 => 144865)


--- trunk/Source/WebCore/bindings/v8/V8HTMLCustomElement.h	2013-03-06 02:51:18 UTC (rev 144864)
+++ trunk/Source/WebCore/bindings/v8/V8HTMLCustomElement.h	2013-03-06 02:52:34 UTC (rev 144865)
@@ -45,7 +45,6 @@
 
 class V8HTMLCustomElement {
 public:
-    static WrapperTypeInfo info;
     static v8::Handle<v8::Value> toV8(HTMLElement*, v8::Handle<v8::Object> creationContext = v8::Handle<v8::Object>(), v8::Isolate* = 0);
     static v8::Handle<v8::Object> wrap(HTMLElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
 

Modified: trunk/Source/WebCore/bindings/v8/V8PerContextData.cpp (144864 => 144865)


--- trunk/Source/WebCore/bindings/v8/V8PerContextData.cpp	2013-03-06 02:51:18 UTC (rev 144864)
+++ trunk/Source/WebCore/bindings/v8/V8PerContextData.cpp	2013-03-06 02:52:34 UTC (rev 144865)
@@ -126,6 +126,9 @@
     v8::Local<v8::Value> prototypeValue = function->Get(v8::String::NewSymbol("prototype"));
     if (!prototypeValue.IsEmpty() && prototypeValue->IsObject()) {
         v8::Local<v8::Object> prototypeObject = v8::Local<v8::Object>::Cast(prototypeValue);
+        if (prototypeObject->InternalFieldCount() == v8PrototypeInternalFieldcount
+            && type->wrapperTypePrototype == WrapperTypeObjectPrototype)
+            prototypeObject->SetAlignedPointerInInternalField(v8PrototypeTypeIndex, type);
         type->installPerContextPrototypeProperties(prototypeObject, m_context->GetIsolate());
         if (type->wrapperTypePrototype == WrapperTypeErrorPrototype)
             prototypeObject->SetPrototype(m_errorPrototype.get());

Modified: trunk/Source/WebCore/bindings/v8/WrapperTypeInfo.h (144864 => 144865)


--- trunk/Source/WebCore/bindings/v8/WrapperTypeInfo.h	2013-03-06 02:51:18 UTC (rev 144864)
+++ trunk/Source/WebCore/bindings/v8/WrapperTypeInfo.h	2013-03-06 02:52:34 UTC (rev 144865)
@@ -43,6 +43,8 @@
     static const int v8DOMWrapperTypeIndex = 0;
     static const int v8DOMWrapperObjectIndex = 1;
     static const int v8DefaultWrapperInternalFieldCount = 2;
+    static const int v8PrototypeTypeIndex = 0;
+    static const int v8PrototypeInternalFieldcount = 1;
 
     static const uint16_t v8DOMNodeClassId = 1;
     static const uint16_t v8DOMObjectClassId = 2;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to