- 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;