summaryrefslogtreecommitdiff
path: root/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorV8.pm
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorV8.pm')
-rw-r--r--src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorV8.pm1792
1 files changed, 1142 insertions, 650 deletions
diff --git a/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorV8.pm b/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorV8.pm
index 95b2aa2fb9..68007e20d3 100644
--- a/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorV8.pm
+++ b/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorV8.pm
@@ -7,8 +7,6 @@
# Copyright (C) 2007, 2008, 2009 Google Inc.
# Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au>
#
-# This file is part of the KDE project
-#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
@@ -20,7 +18,7 @@
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
-# aint with this library; see the file COPYING.LIB. If not, write to
+# along with this library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#
@@ -86,11 +84,6 @@ sub finish
$object->WriteData();
}
-sub leftShift($$) {
- my ($value, $distance) = @_;
- return (($value << $distance) & 0xFFFFFFFF);
-}
-
# Workaround for V8 bindings difference where RGBColor is not a POD type.
sub IsPodType
{
@@ -128,13 +121,6 @@ sub GenerateModule
$module = $dataNode->module;
}
-sub GetLegacyHeaderIncludes
-{
- my $legacyParent = shift;
-
- die "Don't know what headers to include for module $module";
-}
-
sub AvoidInclusionOfType
{
my $type = shift;
@@ -144,28 +130,21 @@ sub AvoidInclusionOfType
return 0;
}
-sub UsesManualToJSImplementation
-{
- my $type = shift;
-
- return 1 if $type eq "SVGPathSeg";
- return 0;
-}
-
sub AddIncludesForType
{
my $type = $codeGenerator->StripModule(shift);
# When we're finished with the one-file-per-class
# reorganization, we won't need these special cases.
- if ($codeGenerator->IsPrimitiveType($type) or AvoidInclusionOfType($type)) {
- } elsif ($type =~ /SVGPathSeg/) {
- $joinedName = $type;
- $joinedName =~ s/Abs|Rel//;
- $implIncludes{"${joinedName}.h"} = 1;
- } else {
+ if (!$codeGenerator->IsPrimitiveType($type) and !AvoidInclusionOfType($type) and $type ne "Date") {
# default, include the same named file
- $implIncludes{GetImplementationFileName(${type})} = 1;
+ $implIncludes{GetV8HeaderName(${type})} = 1;
+
+ if ($type =~ /SVGPathSeg/) {
+ $joinedName = $type;
+ $joinedName =~ s/Abs|Rel//;
+ $implIncludes{"${joinedName}.h"} = 1;
+ }
}
# additional includes (things needed to compile the bindings but not the header)
@@ -204,25 +183,6 @@ sub AddIncludesForSVGAnimatedType
$implIncludes{"SVGAnimatedTemplate.h"} = 1;
}
-sub AddClassForwardIfNeeded
-{
- my $implClassName = shift;
-
- # SVGAnimatedLength/Number/etc.. are typedefs to SVGAnimtatedTemplate, so don't use class forwards for them!
- push(@headerContent, "class $implClassName;\n\n") unless $codeGenerator->IsSVGAnimatedType($implClassName);
-}
-
-sub GetImplementationFileName
-{
- my $iface = shift;
- return "Event.h" if $iface eq "DOMTimeStamp";
- return "NamedAttrMap.h" if $iface eq "NamedNodeMap";
- return "NameNodeList.h" if $iface eq "NodeList";
- return "XMLHttpRequest.h" if $iface eq "XMLHttpRequest";
-
- return "${iface}.h";
-}
-
# If the node has a [Conditional=XXX] attribute, returns an "ENABLE(XXX)" string for use in an #if.
sub GenerateConditionalString
{
@@ -260,39 +220,109 @@ sub GenerateHeader
# Get correct pass/store types respecting PODType flag
my $podType = $dataNode->extendedAttributes->{"PODType"};
- my $passType = $podType ? "JSSVGPODTypeWrapper<$podType>*" : "$implClassName*";
push(@headerContent, "#include \"$podType.h\"\n") if $podType and ($podType ne "double" and $podType ne "float" and $podType ne "RGBA32");
push(@headerContent, "#include <v8.h>\n");
push(@headerContent, "#include <wtf/HashMap.h>\n");
push(@headerContent, "#include \"StringHash.h\"\n");
-
- push(@headerContent, "\nnamespace WebCore {\n\n");
- push(@headerContent, "class V8ClassIndex;\n");
+ push(@headerContent, "#include \"WrapperTypeInfo.h\"\n");
+ push(@headerContent, GetHeaderClassInclude($implClassName));
+ push(@headerContent, "\nnamespace WebCore {\n");
+ if ($podType) {
+ push(@headerContent, "\ntemplate<typename PODType> class V8SVGPODTypeWrapper;\n");
+ }
push(@headerContent, "\nclass $className {\n");
+
+ my $nativeType = GetNativeTypeForConversions($interfaceName);
+ if ($podType) {
+ $nativeType = "V8SVGPODTypeWrapper<${nativeType} >";
+ }
+ my $forceNewObjectParameter = IsDOMNodeType($interfaceName) ? ", bool forceNewObject = false" : "";
push(@headerContent, <<END);
- public:
- static bool HasInstance(v8::Handle<v8::Value> value);
- static v8::Persistent<v8::FunctionTemplate> GetRawTemplate();
+public:
+ static bool HasInstance(v8::Handle<v8::Value> value);
+ static v8::Persistent<v8::FunctionTemplate> GetRawTemplate();
+ static v8::Persistent<v8::FunctionTemplate> GetTemplate();
+ static ${nativeType}* toNative(v8::Handle<v8::Object>);
+ static v8::Handle<v8::Object> wrap(${nativeType}*${forceNewObjectParameter});
+ static void derefObject(void*);
+ static WrapperTypeInfo info;
END
+ if (IsActiveDomType($implClassName)) {
+ push(@headerContent, " static ActiveDOMObject* toActiveDOMObject(v8::Handle<v8::Object>);\n");
+ }
if ($implClassName eq "DOMWindow") {
- push(@headerContent, <<END);
- static v8::Persistent<v8::ObjectTemplate> GetShadowObjectTemplate();
+ push(@headerContent, <<END);
+ static v8::Persistent<v8::ObjectTemplate> GetShadowObjectTemplate();
END
}
- push(@headerContent, <<END);
+ my @enabledAtRuntime;
+ foreach my $function (@{$dataNode->functions}) {
+ my $name = $function->signature->name;
+ my $attrExt = $function->signature->extendedAttributes;
- private:
- static v8::Persistent<v8::FunctionTemplate> GetTemplate();
+ if ($attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
+ push(@headerContent, <<END);
+ static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments&);
+END
+ }
+
+ if ($attrExt->{"EnabledAtRuntime"}) {
+ push(@enabledAtRuntime, $function);
+ }
+ }
+
+ if ($dataNode->extendedAttributes->{"CustomConstructor"} || $dataNode->extendedAttributes->{"CanBeConstructed"}) {
+ push(@headerContent, <<END);
+ static v8::Handle<v8::Value> constructorCallback(const v8::Arguments& args);
+END
+ }
+
+ foreach my $attribute (@{$dataNode->attributes}) {
+ my $name = $attribute->signature->name;
+ my $attrExt = $attribute->signature->extendedAttributes;
+ if ($attrExt->{"V8CustomGetter"} || $attrExt->{"CustomGetter"}
+ || $attrExt->{"V8Custom"} || $attrExt->{"Custom"}) {
+ push(@headerContent, <<END);
+ static v8::Handle<v8::Value> ${name}AccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
+END
+ }
+ if ($attrExt->{"V8CustomSetter"} || $attrExt->{"CustomSetter"}
+ || $attrExt->{"V8Custom"} || $attrExt->{"Custom"}) {
+ push(@headerContent, <<END);
+ static void ${name}AccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
+END
+ }
+ if ($attrExt->{"EnabledAtRuntime"}) {
+ push(@enabledAtRuntime, $attribute);
+ }
+ }
+
+ GenerateHeaderNamedAndIndexedPropertyAccessors($dataNode);
+ GenerateHeaderCustomCall($dataNode);
+ GenerateHeaderCustomInternalFieldIndices($dataNode);
+
+ if ($dataNode->extendedAttributes->{"CheckDomainSecurity"}) {
+ push(@headerContent, <<END);
+ static bool namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType, v8::Local<v8::Value> data);
+ static bool indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType, v8::Local<v8::Value> data);
+END
+ }
- friend class V8ClassIndex;
+ push(@headerContent, <<END);
};
+ v8::Handle<v8::Value> toV8(${nativeType}*${forceNewObjectParameter});
+END
+ if (IsRefPtrType($implClassName)) {
+ push(@headerContent, <<END);
+ v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} >${forceNewObjectParameter});
END
+ }
push(@headerContent, "}\n\n");
push(@headerContent, "#endif // $className" . "_H\n");
@@ -300,6 +330,151 @@ END
push(@headerContent, "#endif // ${conditionalString}\n\n") if $conditionalString;
}
+sub GetInternalFields
+{
+ my $dataNode = shift;
+ my $name = $dataNode->name;
+
+ my @customInternalFields = ();
+
+ # We can't ask whether a parent type has a given extendedAttribute, so special-case Node, AbstractWorker and WorkerContext to include all sub-types.
+ # FIXME: SVGElementInstance should probably have the EventTarget extended attribute, but doesn't.
+ if ($dataNode->extendedAttributes->{"EventTarget"} || IsNodeSubType($dataNode) || IsSubType($dataNode, "AbstractWorker") || IsSubType($dataNode, "WorkerContext")
+ || $name eq "SVGElementInstance") {
+ push(@customInternalFields, "eventListenerCacheIndex");
+ }
+
+ if (IsSubType($dataNode, "Document")) {
+ push(@customInternalFields, "implementationIndex");
+ if ($name eq "HTMLDocument") {
+ push(@customInternalFields, ("markerIndex", "shadowIndex"));
+ }
+ } elsif (IsSubType($dataNode, "StyleSheet") || $name eq "NamedNodeMap") {
+ push(@customInternalFields, "ownerNodeIndex");
+ } elsif ($name eq "MessageChannel") {
+ push(@customInternalFields, ("port1Index", "port2Index"));
+ } elsif ($name eq "DOMWindow") {
+ push(@customInternalFields, ("consoleIndex", "historyIndex", "locationbarIndex", "menubarIndex", "navigatorIndex",
+ "personalbarIndex", "screenIndex", "scrollbarsIndex", "selectionIndex", "statusbarIndex", "toolbarIndex", "locationIndex",
+ "domSelectionIndex", "enteredIsolatedWorldIndex"));
+ }
+ return @customInternalFields;
+}
+
+sub GetHeaderClassInclude
+{
+ my $className = shift;
+ if ($className =~ /SVGPathSeg/) {
+ $className =~ s/Abs|Rel//;
+ }
+ return "" if (AvoidInclusionOfType($className));
+ return "#include \"SVGAnimatedTemplate.h\"\n" if ($codeGenerator->IsSVGAnimatedType($className));
+ return "#include \"${className}.h\"\n";
+}
+
+sub GenerateHeaderCustomInternalFieldIndices
+{
+ my $dataNode = shift;
+ my @customInternalFields = GetInternalFields($dataNode);
+ my $customFieldCounter = 0;
+ foreach my $customInternalField (@customInternalFields) {
+ push(@headerContent, <<END);
+ static const int ${customInternalField} = v8DefaultWrapperInternalFieldCount + ${customFieldCounter};
+END
+ $customFieldCounter++;
+ }
+ push(@headerContent, <<END);
+ static const int internalFieldCount = v8DefaultWrapperInternalFieldCount + ${customFieldCounter};
+END
+}
+
+my %indexerSpecialCases = (
+ "Storage" => 1,
+ "HTMLAppletElement" => 1,
+ "HTMLDocument" => 1,
+ "HTMLEmbedElement" => 1,
+ "HTMLObjectElement" => 1
+);
+
+sub GenerateHeaderNamedAndIndexedPropertyAccessors
+{
+ my $dataNode = shift;
+ my $interfaceName = $dataNode->name;
+ my $hasCustomIndexedGetter = $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"};
+ my $hasCustomIndexedSetter = $dataNode->extendedAttributes->{"HasCustomIndexSetter"} && !$dataNode->extendedAttributes->{"HasNumericIndexGetter"};
+ my $hasCustomNamedGetter = $dataNode->extendedAttributes->{"HasNameGetter"} || $dataNode->extendedAttributes->{"HasOverridingNameGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"};
+ my $hasCustomNamedSetter = $dataNode->extendedAttributes->{"DelegatingPutFunction"};
+ my $hasCustomDeleters = $dataNode->extendedAttributes->{"CustomDeleteProperty"};
+ my $hasCustomEnumerator = $dataNode->extendedAttributes->{"CustomGetPropertyNames"};
+ if ($interfaceName eq "HTMLOptionsCollection") {
+ $interfaceName = "HTMLCollection";
+ $hasCustomIndexedGetter = 1;
+ $hasCustomNamedGetter = 1;
+ }
+ if ($interfaceName eq "DOMWindow") {
+ $hasCustomDeleterr = 0;
+ $hasEnumerator = 0;
+ }
+ if ($interfaceName eq "HTMLSelectElement" || $interfaceName eq "HTMLAppletElement" || $interfaceName eq "HTMLEmbedElement" || $interfaceName eq "HTMLObjectElement") {
+ $hasCustomNamedGetter = 1;
+ }
+ my $isIndexerSpecialCase = exists $indexerSpecialCases{$interfaceName};
+
+ if ($hasCustomIndexedGetter || $isIndexerSpecialCase) {
+ push(@headerContent, <<END);
+ static v8::Handle<v8::Value> indexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info);
+END
+ }
+
+ if ($isIndexerSpecialCase || $hasCustomIndexedSetter) {
+ push(@headerContent, <<END);
+ static v8::Handle<v8::Value> indexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
+END
+ }
+ if ($hasCustomDeleters) {
+ push(@headerContent, <<END);
+ static v8::Handle<v8::Boolean> indexedPropertyDeleter(uint32_t index, const v8::AccessorInfo& info);
+END
+ }
+ if ($hasCustomNamedGetter) {
+ push(@headerContent, <<END);
+ static v8::Handle<v8::Value> namedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
+END
+ }
+ if ($hasCustomNamedSetter) {
+ push(@headerContent, <<END);
+ static v8::Handle<v8::Value> namedPropertySetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
+END
+ }
+ if ($hasCustomDeleters || $interfaceName eq "HTMLDocument") {
+ push(@headerContent, <<END);
+ static v8::Handle<v8::Boolean> namedPropertyDeleter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
+END
+ }
+ if ($hasCustomEnumerator) {
+ push(@headerContent, <<END);
+ static v8::Handle<v8::Array> namedPropertyEnumerator(const v8::AccessorInfo& info);
+END
+ }
+}
+
+sub GenerateHeaderCustomCall
+{
+ my $dataNode = shift;
+
+ if ($dataNode->extendedAttributes->{"CustomCall"}) {
+ push(@headerContent, " static v8::Handle<v8::Value> callAsFunctionCallback(const v8::Arguments&);\n");
+ }
+ if ($dataNode->name eq "Event") {
+ push(@headerContent, " static v8::Handle<v8::Value> dataTransferAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
+ push(@headerContent, " static void valueAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);\n");
+ }
+ if ($dataNode->name eq "Location") {
+ push(@headerContent, " static v8::Handle<v8::Value> assignAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
+ push(@headerContent, " static v8::Handle<v8::Value> reloadAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
+ push(@headerContent, " static v8::Handle<v8::Value> replaceAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
+ }
+}
sub GenerateSetDOMException
{
@@ -314,66 +489,30 @@ sub GenerateSetDOMException
return $result;
}
-sub IsNodeSubType
+sub IsSubType
{
my $dataNode = shift;
- return 1 if ($dataNode->name eq "Node");
+ my $parentType = shift;
+ return 1 if ($dataNode->name eq $parentType);
foreach (@allParents) {
my $parent = $codeGenerator->StripModule($_);
- return 1 if $parent eq "Node";
+ return 1 if $parent eq $parentType;
}
return 0;
}
-sub GetHiddenDependencyIndex
-{
- my $dataNode = shift;
- my $attribute = shift;
- my $name = $dataNode->name;
- return "V8Custom::kNodeEventListenerCacheIndex" if IsNodeSubType($dataNode);
- return "V8Custom::kSVGElementInstanceEventListenerCacheIndex" if $name eq "SVGElementInstance";
- return "V8Custom::kAbstractWorkerRequestCacheIndex" if $name eq "AbstractWorker";
- return "V8Custom::kWorkerRequestCacheIndex" if $name eq "Worker";
- return "V8Custom::kDedicatedWorkerContextRequestCacheIndex" if $name eq "DedicatedWorkerContext";
- return "V8Custom::kWorkerContextRequestCacheIndex" if $name eq "WorkerContext";
- return "V8Custom::kWorkerContextRequestCacheIndex" if $name eq "SharedWorkerContext";
- return "V8Custom::kMessagePortRequestCacheIndex" if $name eq "MessagePort";
- return "V8Custom::kWebSocketCacheIndex" if $name eq "WebSocket";
- return "V8Custom::kXMLHttpRequestCacheIndex" if $name eq "XMLHttpRequest";
- return "V8Custom::kXMLHttpRequestCacheIndex" if $name eq "XMLHttpRequestUpload";
- return "V8Custom::kDOMApplicationCacheCacheIndex" if $name eq "DOMApplicationCache";
- return "V8Custom::kNotificationRequestCacheIndex" if $name eq "Notification";
- return "V8Custom::kDOMWindowEventListenerCacheIndex" if $name eq "DOMWindow";
- die "Unexpected name " . $name . " when generating " . $attribute;
-}
-
-sub HolderToNative
+sub IsNodeSubType
{
my $dataNode = shift;
- my $implClassName = shift;
- my $classIndex = shift;
-
- if (IsNodeSubType($dataNode)) {
- push(@implContentDecls, <<END);
- $implClassName* imp = V8DOMWrapper::convertDOMWrapperToNode<$implClassName>(holder);
-END
-
- } else {
- push(@implContentDecls, <<END);
- $implClassName* imp = V8DOMWrapper::convertToNativeObject<$implClassName>(V8ClassIndex::$classIndex, holder);
-END
-
- }
+ return IsSubType($dataNode, "Node");
}
sub GenerateDomainSafeFunctionGetter
{
my $function = shift;
- my $dataNode = shift;
- my $classIndex = shift;
my $implClassName = shift;
- my $className = "V8" . $dataNode->name;
+ my $className = "V8" . $implClassName;
my $funcName = $function->signature->name;
my $signature = "v8::Signature::New(" . $className . "::GetRawTemplate())";
@@ -381,36 +520,26 @@ sub GenerateDomainSafeFunctionGetter
$signature = "v8::Local<v8::Signature>()";
}
- my $newTemplateString = GenerateNewFunctionTemplate($function, $dataNode, $signature);
-
- $implIncludes{"V8Proxy.h"} = 1;
+ my $newTemplateString = GenerateNewFunctionTemplate($function, $implClassName, $signature);
push(@implContentDecls, <<END);
- static v8::Handle<v8::Value> ${funcName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
+static v8::Handle<v8::Value> ${funcName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
INC_STATS(\"DOM.$implClassName.$funcName._get\");
- static v8::Persistent<v8::FunctionTemplate> private_template =
- v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
- v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
+ static v8::Persistent<v8::FunctionTemplate> private_template = v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
+ v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(${className}::GetTemplate(), info.This());
if (holder.IsEmpty()) {
- // can only reach here by 'object.__proto__.func', and it should passed
- // domain security check already
-
- return private_template->GetFunction();
+ // can only reach here by 'object.__proto__.func', and it should passed
+ // domain security check already
+ return private_template->GetFunction();
}
-END
-
- HolderToNative($dataNode, $implClassName, $classIndex);
-
- push(@implContentDecls, <<END);
- if (!V8Proxy::canAccessFrame(imp->frame(), false)) {
- static v8::Persistent<v8::FunctionTemplate> shared_template =
- v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
- return shared_template->GetFunction();
-
- } else {
- return private_template->GetFunction();
+ ${implClassName}* imp = ${className}::toNative(holder);
+ if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), false)) {
+ static v8::Persistent<v8::FunctionTemplate> shared_template = v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
+ return shared_template->GetFunction();
}
- }
+ return private_template->GetFunction();
+}
END
}
@@ -418,37 +547,32 @@ END
sub GenerateConstructorGetter
{
my $implClassName = shift;
- my $classIndex = shift;
push(@implContentDecls, <<END);
- static v8::Handle<v8::Value> ${implClassName}ConstructorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
+static v8::Handle<v8::Value> ${implClassName}ConstructorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
INC_STATS(\"DOM.$implClassName.constructors._get\");
v8::Handle<v8::Value> data = info.Data();
- ASSERT(data->IsNumber());
- V8ClassIndex::V8WrapperType type = V8ClassIndex::FromInt(data->Int32Value());
+ ASSERT(data->IsExternal() || data->IsNumber());
+ WrapperTypeInfo* type = WrapperTypeInfo::unwrap(data);
END
- if ($classIndex eq "DOMWINDOW") {
+ if ($implClassName eq "DOMWindow") {
push(@implContentDecls, <<END);
- DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder());
// Get the proxy corresponding to the DOMWindow if possible to
// make sure that the constructor function is constructed in the
// context of the DOMWindow and not in the context of the caller.
- return V8DOMWrapper::getConstructor(type, window);
+ return V8DOMWrapper::getConstructor(type, V8DOMWindow::toNative(info.Holder()));
END
- } elsif ($classIndex eq "DEDICATEDWORKERCONTEXT" or $classIndex eq "WORKERCONTEXT" or $classIndex eq "SHAREDWORKERCONTEXT") {
- $implIncludes{"WorkerContextExecutionProxy.h"} = 1;
+ } elsif ($implClassName eq "DedicatedWorkerContext" or $implClassName eq "WorkerContext" or $implClassName eq "SharedWorkerContext") {
push(@implContentDecls, <<END);
- WorkerContext* workerContext = V8DOMWrapper::convertToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, info.Holder());
- return V8DOMWrapper::getConstructor(type, workerContext);
+ return V8DOMWrapper::getConstructor(type, V8WorkerContext::toNative(info.Holder()));
END
} else {
- push(@implContentDecls, " return v8::Undefined();");
+ push(@implContentDecls, " return v8::Handle<v8::Value>();");
}
push(@implContentDecls, <<END);
-
- }
+}
END
}
@@ -457,23 +581,20 @@ sub GenerateNormalAttrGetter
{
my $attribute = shift;
my $dataNode = shift;
- my $classIndex = shift;
my $implClassName = shift;
my $interfaceName = shift;
my $attrExt = $attribute->signature->extendedAttributes;
my $attrName = $attribute->signature->name;
- $implIncludes{"V8Proxy.h"} = 1;
my $attrType = GetTypeFromSignature($attribute->signature);
my $attrIsPodType = IsPodType($attrType);
- my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0);
+ my $nativeType = GetNativeTypeFromSignature($attribute->signature, -1);
my $isPodType = IsPodType($implClassName);
my $skipContext = 0;
-
if ($isPodType) {
$implClassName = GetNativeType($implClassName);
$implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
@@ -496,17 +617,18 @@ sub GenerateNormalAttrGetter
$attrIsPodType = 0;
}
- my $getterStringUsesImp = $implClassName ne "double";
+ my $getterStringUsesImp = $implClassName ne "float";
# Getter
push(@implContentDecls, <<END);
- static v8::Handle<v8::Value> ${attrName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
+static v8::Handle<v8::Value> ${attrName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
INC_STATS(\"DOM.$implClassName.$attrName._get\");
END
if ($isPodType) {
push(@implContentDecls, <<END);
- V8SVGPODTypeWrapper<$implClassName>* imp_wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder());
+ V8SVGPODTypeWrapper<$implClassName>* imp_wrapper = V8SVGPODTypeWrapper<$implClassName>::toNative(info.Holder());
$implClassName imp_instance = *imp_wrapper;
END
if ($getterStringUsesImp) {
@@ -516,30 +638,42 @@ END
}
} elsif ($attrExt->{"v8OnProto"} || $attrExt->{"V8DisallowShadowing"}) {
- if ($classIndex eq "DOMWINDOW") {
- push(@implContentDecls, <<END);
+ if ($interfaceName eq "DOMWindow") {
+ push(@implContentDecls, <<END);
v8::Handle<v8::Object> holder = info.Holder();
END
- } else {
- # perform lookup first
+ } else {
+ # perform lookup first
+ push(@implContentDecls, <<END);
+ v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8${interfaceName}::GetTemplate(), info.This());
+ if (holder.IsEmpty()) return v8::Handle<v8::Value>();
+END
+ }
push(@implContentDecls, <<END);
- v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
- if (holder.IsEmpty()) return v8::Undefined();
+ ${implClassName}* imp = V8${implClassName}::toNative(holder);
END
- }
- HolderToNative($dataNode, $implClassName, $classIndex);
} else {
+ my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
+ if ($getterStringUsesImp && $reflect && IsNodeSubType($dataNode) && $codeGenerator->IsStringType($attrType)) {
+ # Generate super-compact call for regular attribute getter:
+ my $contentAttributeName = $reflect eq "1" ? $attrName : $reflect;
+ my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
+ $implIncludes{"${namespace}.h"} = 1;
+ push(@implContentDecls, " return getElementStringAttr(info, ${namespace}::${contentAttributeName}Attr);\n");
+ push(@implContentDecls, "}\n\n");
+ return;
+ # Skip the rest of the function!
+ }
push(@implContentDecls, <<END);
- v8::Handle<v8::Object> holder = info.Holder();
+ ${implClassName}* imp = V8${implClassName}::toNative(info.Holder());
END
- HolderToNative($dataNode, $implClassName, $classIndex);
}
# Generate security checks if necessary
if ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) {
- push(@implContentDecls, " if (!V8Proxy::checkNodeSecurity(imp->$attrName())) return v8::Undefined();\n\n");
+ push(@implContentDecls, " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->$attrName())) return v8::Handle<v8::Value>();\n\n");
} elsif ($attribute->signature->extendedAttributes->{"CheckFrameSecurity"}) {
- push(@implContentDecls, " if (!V8Proxy::checkNodeSecurity(imp->contentDocument())) return v8::Undefined();\n\n");
+ push(@implContentDecls, " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->contentDocument())) return v8::Handle<v8::Value>();\n\n");
}
my $useExceptions = 1 if @{$attribute->getterExceptions} and !($isPodType);
@@ -553,7 +687,12 @@ END
}
my $getterFunc = $codeGenerator->WK_lcfirst($attrName);
- $getterFunc .= "Animated" if $codeGenerator->IsSVGAnimatedType($attribute->signature->type);
+
+ if ($codeGenerator->IsSVGAnimatedType($attribute->signature->type)) {
+ # Some SVGFE*Element.idl use 'operator' as attribute name; rewrite as '_operator' to avoid clashes with C/C++
+ $getterFunc = "_" . $getterFunc if ($attrName =~ /operator/);
+ $getterFunc .= "Animated";
+ }
my $returnType = GetTypeFromSignature($attribute->signature);
@@ -579,10 +718,6 @@ END
$getterString = "imp_instance";
}
- if ($nativeType eq "String") {
- $getterString = "toString($getterString)";
- }
-
my $result;
my $wrapper;
@@ -619,7 +754,7 @@ END
} else {
if ($attribute->signature->type eq "EventListener" && $dataNode->name eq "DOMWindow") {
push(@implContentDecls, " if (!imp->document())\n");
- push(@implContentDecls, " return v8::Undefined();\n");
+ push(@implContentDecls, " return v8::Handle<v8::Value>();\n");
}
if ($useExceptions) {
@@ -635,60 +770,37 @@ END
}
if (IsSVGTypeNeedingContextParameter($attrType) && !$skipContext) {
- my $resultObject = $result;
if ($attrIsPodType) {
- $resultObject = "wrapper";
+ push(@implContentDecls, GenerateSVGContextAssignment($implClassName, "wrapper.get()", " "));
+ } else {
+ push(@implContentDecls, GenerateSVGContextRetrieval($implClassName, " "));
+ # The templating associated with passing withSVGContext()'s return value directly into toV8 can get compilers confused,
+ # so just manually set the return value to a PassRefPtr of the expected type.
+ push(@implContentDecls, " PassRefPtr<$attrType> resultAsPassRefPtr = V8Proxy::withSVGContext($result, context);\n");
+ $result = "resultAsPassRefPtr";
}
- $resultObject = "WTF::getPtr(" . $resultObject . ")";
- push(@implContentDecls, GenerateSVGContextAssignment($implClassName, $resultObject, " "));
}
if ($attrIsPodType) {
- my $classIndex = uc($attrType);
- push(@implContentDecls, " return V8DOMWrapper::convertToV8Object(V8ClassIndex::$classIndex, wrapper.release());\n");
+ $implIncludes{"V8${attrType}.h"} = 1;
+ push(@implContentDecls, " return toV8(wrapper.release().get());\n");
} else {
push(@implContentDecls, " " . ReturnNativeToJSValue($attribute->signature, $result, " ").";\n");
}
- push(@implContentDecls, " }\n\n"); # end of getter
-}
-
-
-sub GenerateReplaceableAttrSetter
-{
- my $implClassName = shift;
-
- $implIncludes{"V8Proxy.h"} = 1;
-
- push(@implContentDecls,
- " static void ${attrName}AttrSetter(v8::Local<v8::String> name," .
- " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n");
-
- push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n");
-
- push(@implContentDecls, " v8::Local<v8::String> ${attrName}_string = v8::String::New(\"${attrName}\");\n");
- push(@implContentDecls, " info.Holder()->Delete(${attrName}_string);\n");
- push(@implContentDecls, " info.This()->Set(${attrName}_string, value);\n");
- push(@implContentDecls, " }\n\n");
+ push(@implContentDecls, "}\n\n"); # end of getter
}
-
sub GenerateNormalAttrSetter
{
my $attribute = shift;
my $dataNode = shift;
- my $classIndex = shift;
my $implClassName = shift;
my $interfaceName = shift;
my $attrExt = $attribute->signature->extendedAttributes;
- $implIncludes{"V8Proxy.h"} = 1;
-
- push(@implContentDecls,
- " static void ${attrName}AttrSetter(v8::Local<v8::String> name," .
- " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n");
-
+ push(@implContentDecls, "static void ${attrName}AttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)\n{\n");
push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n");
my $isPodType = IsPodType($implClassName);
@@ -696,37 +808,51 @@ sub GenerateNormalAttrSetter
if ($isPodType) {
$implClassName = GetNativeType($implClassName);
$implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
- push(@implContentDecls, " V8SVGPODTypeWrapper<$implClassName>* wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder());\n");
+ push(@implContentDecls, " V8SVGPODTypeWrapper<$implClassName>* wrapper = V8SVGPODTypeWrapper<$implClassName>::toNative(info.Holder());\n");
push(@implContentDecls, " $implClassName imp_instance = *wrapper;\n");
push(@implContentDecls, " $implClassName* imp = &imp_instance;\n");
} elsif ($attrExt->{"v8OnProto"}) {
- if ($classIndex eq "DOMWINDOW") {
+ if ($interfaceName eq "DOMWindow") {
push(@implContentDecls, <<END);
v8::Handle<v8::Object> holder = info.Holder();
END
} else {
# perform lookup first
push(@implContentDecls, <<END);
- v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
+ v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8${interfaceName}::GetTemplate(), info.This());
if (holder.IsEmpty()) return;
END
}
- HolderToNative($dataNode, $implClassName, $classIndex);
+ push(@implContentDecls, <<END);
+ ${implClassName}* imp = V8${implClassName}::toNative(holder);
+END
} else {
+ my $attrType = GetTypeFromSignature($attribute->signature);
+ my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
+ my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
+ if (($reflect || $reflectURL) && IsNodeSubType($dataNode) && $codeGenerator->IsStringType($attrType)) {
+ # Generate super-compact call for regular attribute setter:
+ my $contentAttributeName = ($reflect || $reflectURL) eq "1" ? $attrName : ($reflect || $reflectURL);
+ my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
+ $implIncludes{"${namespace}.h"} = 1;
+ push(@implContentDecls, " setElementStringAttr(info, ${namespace}::${contentAttributeName}Attr, value);\n");
+ push(@implContentDecls, "}\n\n");
+ return;
+ # Skip the rest of the function!
+ }
+
push(@implContentDecls, <<END);
- v8::Handle<v8::Object> holder = info.Holder();
+ ${implClassName}* imp = V8${implClassName}::toNative(info.Holder());
END
- HolderToNative($dataNode, $implClassName, $classIndex);
}
my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0);
if ($attribute->signature->type eq "EventListener") {
if ($dataNode->name eq "DOMWindow") {
push(@implContentDecls, " if (!imp->document())\n");
- push(@implContentDecls, " return;\n");
+ push(@implContentDecls, " return;\n");
}
- push(@implContentDecls, " $nativeType v = V8DOMWrapper::getEventListener(imp, value, true, ListenerFindOrCreate);\n");
} else {
push(@implContentDecls, " $nativeType v = " . JSValueToNative($attribute->signature, "value") . ";\n");
}
@@ -751,7 +877,7 @@ END
push(@implContentDecls, " ExceptionCode ec = 0;\n");
}
- if ($implClassName eq "double") {
+ if ($implClassName eq "float") {
push(@implContentDecls, " *imp = $result;\n");
} else {
my $implSetterFunctionName = $codeGenerator->WK_ucfirst($attrName);
@@ -764,20 +890,10 @@ END
push(@implContentDecls, " imp->setAttribute(${namespace}::${contentAttributeName}Attr, $result");
} elsif ($attribute->signature->type eq "EventListener") {
$implIncludes{"V8AbstractEventListener.h"} = 1;
- $implIncludes{"V8CustomBinding.h"} = 1;
- $cacheIndex = GetHiddenDependencyIndex($dataNode, $attrName);
- push(@implContentDecls, " $nativeType old = imp->$attrName();\n");
- push(@implContentDecls, " V8AbstractEventListener* oldListener = old ? V8AbstractEventListener::cast(old.get()) : 0;\n");
- push(@implContentDecls, " if (oldListener) {\n");
- push(@implContentDecls, " v8::Local<v8::Object> oldListenerObject = oldListener->getExistingListenerObject();\n");
- push(@implContentDecls, " if (!oldListenerObject.IsEmpty())\n");
- push(@implContentDecls, " removeHiddenDependency(holder, oldListenerObject, $cacheIndex);\n");
- push(@implContentDecls, " }\n");
- push(@implContentDecls, " imp->set$implSetterFunctionName($result);\n");
- push(@implContentDecls, " if ($result)\n");
- push(@implContentDecls, " createHiddenDependency(holder, value, $cacheIndex");
+ push(@implContentDecls, " transferHiddenDependency(info.Holder(), imp->$attrName(), value, V8${interfaceName}::eventListenerCacheIndex);\n");
+ push(@implContentDecls, " imp->set$implSetterFunctionName(V8DOMWrapper::getEventListener(value, true, ListenerFindOrCreate)");
} else {
- push(@implContentDecls, " imp->set$implSetterFunctionName(" . $result);
+ push(@implContentDecls, " imp->set$implSetterFunctionName($result");
}
push(@implContentDecls, ", ec") if $useExceptions;
push(@implContentDecls, ");\n");
@@ -804,16 +920,14 @@ END
}
push(@implContentDecls, " return;\n");
- push(@implContentDecls, " }\n\n"); # end of setter
+ push(@implContentDecls, "}\n\n"); # end of setter
}
-sub GenerateNewFunctionTemplate
+sub GetFunctionTemplateCallbackName
{
$function = shift;
- $dataNode = shift;
- $signature = shift;
+ $interfaceName = shift;
- my $interfaceName = $dataNode->name;
my $name = $function->signature->name;
if ($function->signature->extendedAttributes->{"Custom"} ||
@@ -822,48 +936,85 @@ sub GenerateNewFunctionTemplate
$function->signature->extendedAttributes->{"V8Custom"}) {
die "Custom and V8Custom should be mutually exclusive!"
}
- my $customFunc = $function->signature->extendedAttributes->{"Custom"} ||
- $function->signature->extendedAttributes->{"V8Custom"};
- if ($customFunc eq 1) {
- $customFunc = $interfaceName . $codeGenerator->WK_ucfirst($name);
- }
- return "v8::FunctionTemplate::New(V8Custom::v8${customFunc}Callback, v8::Handle<v8::Value>(), $signature)";
+ return "V8${interfaceName}::${name}Callback";
} else {
- return "v8::FunctionTemplate::New(${interfaceName}Internal::${name}Callback, v8::Handle<v8::Value>(), $signature)";
+ return "${interfaceName}Internal::${name}Callback";
+ }
+}
+
+sub GenerateNewFunctionTemplate
+{
+ $function = shift;
+ $interfaceName = shift;
+ $signature = shift;
+
+ my $callback = GetFunctionTemplateCallbackName($function, $interfaceName);
+ return "v8::FunctionTemplate::New($callback, v8::Handle<v8::Value>(), $signature)";
+}
+
+sub GenerateEventListenerCallback
+{
+ my $implClassName = shift;
+ my $functionName = shift;
+ my $lookupType = ($functionName eq "add") ? "OrCreate" : "Only";
+ my $passRefPtrHandling = ($functionName eq "add") ? "" : ".get()";
+ my $hiddenDependencyAction = ($functionName eq "add") ? "create" : "remove";
+
+ push(@implContentDecls, <<END);
+static v8::Handle<v8::Value> ${functionName}EventListenerCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.${implClassName}.${functionName}EventListener()");
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(args[1], false, ListenerFind${lookupType});
+ if (listener) {
+ V8${implClassName}::toNative(args.Holder())->${functionName}EventListener(v8ValueToAtomicWebCoreString(args[0]), listener${passRefPtrHandling}, args[2]->BooleanValue());
+ ${hiddenDependencyAction}HiddenDependency(args.Holder(), args[1], V8${implClassName}::eventListenerCacheIndex);
}
+ return v8::Undefined();
+}
+
+END
}
sub GenerateFunctionCallback
{
my $function = shift;
my $dataNode = shift;
- my $classIndex = shift;
my $implClassName = shift;
my $interfaceName = $dataNode->name;
my $name = $function->signature->name;
- push(@implContentDecls,
-" static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args) {\n" .
-" INC_STATS(\"DOM.$implClassName.$name\");\n");
+ # Adding and removing event listeners are not standard callback behavior,
+ # but they are extremely consistent across the various classes that take event listeners,
+ # so we can generate them as a "special case".
+ if ($name eq "addEventListener") {
+ GenerateEventListenerCallback($implClassName, "add");
+ return;
+ } elsif ($name eq "removeEventListener") {
+ GenerateEventListenerCallback($implClassName, "remove");
+ return;
+ }
+
+ push(@implContentDecls, <<END);
+static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args) {
+ INC_STATS(\"DOM.$implClassName.$name\");
+END
my $numParameters = @{$function->parameters};
if ($function->signature->extendedAttributes->{"RequiresAllArguments"}) {
- push(@implContentDecls,
- " if (args.Length() < $numParameters) return v8::Undefined();\n");
+ push(@implContentDecls, " if (args.Length() < $numParameters) return v8::Handle<v8::Value>();\n");
}
if (IsPodType($implClassName)) {
my $nativeClassName = GetNativeType($implClassName);
- push(@implContentDecls, " V8SVGPODTypeWrapper<$nativeClassName>* imp_wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<$nativeClassName> >(V8ClassIndex::$classIndex, args.Holder());\n");
+ push(@implContentDecls, " V8SVGPODTypeWrapper<$nativeClassName>* imp_wrapper = V8SVGPODTypeWrapper<$nativeClassName>::toNative(args.Holder());\n");
push(@implContentDecls, " $nativeClassName imp_instance = *imp_wrapper;\n");
push(@implContentDecls, " $nativeClassName* imp = &imp_instance;\n");
} else {
push(@implContentDecls, <<END);
- v8::Handle<v8::Object> holder = args.Holder();
+ ${implClassName}* imp = V8${implClassName}::toNative(args.Holder());
END
- HolderToNative($dataNode, $implClassName, $classIndex);
}
# Check domain security if needed
@@ -871,26 +1022,43 @@ END
|| $interfaceName eq "DOMWindow")
&& !$function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) {
# We have not find real use cases yet.
- push(@implContentDecls,
-" if (!V8Proxy::canAccessFrame(imp->frame(), true)) {\n".
-" return v8::Undefined();\n" .
-" }\n");
+ push(@implContentDecls, <<END);
+ if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true))
+ return v8::Handle<v8::Value>();
+END
}
+ my $raisesExceptions = @{$function->raisesExceptions};
+ if (!$raisesExceptions) {
+ foreach my $parameter (@{$function->parameters}) {
+ if (TypeCanFailConversion($parameter) or $parameter->extendedAttributes->{"IsIndex"}) {
+ $raisesExceptions = 1;
+ }
+ }
+ }
- if (@{$function->raisesExceptions}) {
+ if ($raisesExceptions) {
$implIncludes{"ExceptionCode.h"} = 1;
push(@implContentDecls, " ExceptionCode ec = 0;\n");
+ push(@implContentDecls, " {\n");
+ # The brace here is needed to prevent the ensuing 'goto fail's from jumping past constructors
+ # of objects (like Strings) declared later, causing compile errors. The block scope ends
+ # right before the label 'fail:'.
}
if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) {
- push(@implContentDecls, " ScriptCallStack callStack(args, $numParameters);\n");
+ push(@implContentDecls, <<END);
+ OwnPtr<ScriptCallStack> callStack(ScriptCallStack::create(args, $numParameters));
+ if (!callStack)
+ return v8::Undefined();
+END
$implIncludes{"ScriptCallStack.h"} = 1;
}
if ($function->signature->extendedAttributes->{"SVGCheckSecurityDocument"}) {
- push(@implContentDecls,
-" if (!V8Proxy::checkNodeSecurity(imp->getSVGDocument(ec)))\n" .
-" return v8::Undefined();\n");
+ push(@implContentDecls, <<END);
+ if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->getSVGDocument(ec)))
+ return v8::Handle<v8::Value>();
+END
}
my $paramIndex = 0;
@@ -911,7 +1079,7 @@ END
push(@implContentDecls, " bool ${parameterName}Ok;\n");
}
- push(@implContentDecls, " " . GetNativeTypeFromSignature($parameter, 1) . " $parameterName = ");
+ push(@implContentDecls, " " . GetNativeTypeFromSignature($parameter, $paramIndex) . " $parameterName = ");
push(@implContentDecls, JSValueToNative($parameter, "args[$paramIndex]",
BasicTypeCanFailConversion($parameter) ? "${parameterName}Ok" : undef) . ";\n");
@@ -919,8 +1087,8 @@ END
$implIncludes{"ExceptionCode.h"} = 1;
push(@implContentDecls,
" if (UNLIKELY(!$parameterName" . (BasicTypeCanFailConversion($parameter) ? "Ok" : "") . ")) {\n" .
-" V8Proxy::setDOMException(TYPE_MISMATCH_ERR);\n" .
-" return v8::Handle<v8::Value>();\n" .
+" ec = TYPE_MISMATCH_ERR;\n" .
+" goto fail;\n" .
" }\n");
}
@@ -928,8 +1096,8 @@ END
$implIncludes{"ExceptionCode.h"} = 1;
push(@implContentDecls,
" if (UNLIKELY($parameterName < 0)) {\n" .
-" V8Proxy::setDOMException(INDEX_SIZE_ERR);\n" .
-" return v8::Handle<v8::Value>();\n" .
+" ec = INDEX_SIZE_ERR;\n" .
+" goto fail;\n" .
" }\n");
}
@@ -939,7 +1107,15 @@ END
# Build the function call string.
my $callString = GenerateFunctionCallString($function, $paramIndex, " ", $implClassName);
push(@implContentDecls, "$callString");
- push(@implContentDecls, " }\n\n");
+
+ if ($raisesExceptions) {
+ push(@implContentDecls, " }\n");
+ push(@implContentDecls, " fail:\n");
+ push(@implContentDecls, " V8Proxy::setDOMException(ec);\n");
+ push(@implContentDecls, " return v8::Handle<v8::Value>();\n");
+ }
+
+ push(@implContentDecls, "}\n\n");
}
sub GenerateBatchedAttributeData
@@ -991,7 +1167,7 @@ sub GenerateSingleBatchedAttribute
"";
if ($customAccessor eq 1) {
# use the naming convension, interface + (capitalize) attr name
- $customAccessor = $interfaceName . $codeGenerator->WK_ucfirst($attrName);
+ $customAccessor = $interfaceName . "::" . $attrName;
}
my $getter;
@@ -1008,17 +1184,17 @@ sub GenerateSingleBatchedAttribute
}
my $on_proto = "0 /* on instance */";
- my $data = "V8ClassIndex::INVALID_CLASS_INDEX /* no data */";
+ my $data = "0 /* no data */";
# Constructor
if ($attribute->signature->type =~ /Constructor$/) {
my $constructorType = $codeGenerator->StripModule($attribute->signature->type);
$constructorType =~ s/Constructor$//;
- my $constructorIndex = uc($constructorType);
+ $implIncludes{"V8${constructorType}.h"} = 1;
if ($customAccessor) {
- $getter = "V8Custom::v8${customAccessor}AccessorGetter";
+ $getter = "V8${customAccessor}AccessorGetter";
} else {
- $data = "V8ClassIndex::${constructorIndex}";
+ $data = "&V8${constructorType}::info";
$getter = "${interfaceName}Internal::${interfaceName}ConstructorGetter";
}
$setter = "0";
@@ -1032,12 +1208,12 @@ sub GenerateSingleBatchedAttribute
# Custom Setter
if ($attrExt->{"CustomSetter"} || $attrExt->{"V8CustomSetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
$hasCustomSetter = 1;
- $setter = "V8Custom::v8${customAccessor}AccessorSetter";
+ $setter = "V8${customAccessor}AccessorSetter";
}
# Custom Getter
- if ($attrExt->{"CustomGetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
- $getter = "V8Custom::v8${customAccessor}AccessorGetter";
+ if ($attrExt->{"CustomGetter"} || $attrExt->{"V8CustomGetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
+ $getter = "V8${customAccessor}AccessorGetter";
}
}
@@ -1078,14 +1254,184 @@ sub GenerateSingleBatchedAttribute
END
}
+sub GenerateImplementationIndexer
+{
+ my $dataNode = shift;
+ my $indexer = shift;
+ my $interfaceName = $dataNode->name;
+
+ # FIXME: Figure out what HasNumericIndexGetter is really supposed to do. Right now, it's only set on WebGL-related files.
+ my $hasCustomSetter = $dataNode->extendedAttributes->{"HasCustomIndexSetter"} && !$dataNode->extendedAttributes->{"HasNumericIndexGetter"};
+ my $hasGetter = $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"};
+
+ # FIXME: Find a way to not have to special-case HTMLOptionsCollection.
+ if ($interfaceName eq "HTMLOptionsCollection") {
+ $hasGetter = 1;
+ }
+ # FIXME: If the parent interface of $dataNode already has
+ # HasIndexGetter, we don't need to handle the getter here.
+ if ($interfaceName eq "WebKitCSSTransformValue") {
+ $hasGetter = 0;
+ }
+
+ # FIXME: Investigate and remove this nastinesss. In V8, named property handling and indexer handling are apparently decoupled,
+ # which means that object[X] where X is a number doesn't reach named property indexer. So we need to provide
+ # simplistic, mirrored indexer handling in addition to named property handling.
+ my $isSpecialCase = exists $indexerSpecialCases{$interfaceName};
+ if ($isSpecialCase) {
+ $hasGetter = 1;
+ if ($dataNode->extendedAttributes->{"DelegatingPutFunction"}) {
+ $hasCustomSetter = 1;
+ }
+ }
+
+ if (!$hasGetter) {
+ return;
+ }
+
+ $implIncludes{"V8Collection.h"} = 1;
+
+ my $indexerType = $indexer ? $indexer->type : 0;
+
+ # FIXME: Remove this once toV8 helper methods are implemented (see https://bugs.webkit.org/show_bug.cgi?id=32563).
+ if ($interfaceName eq "WebKitCSSKeyframesRule") {
+ $indexerType = "WebKitCSSKeyframeRule";
+ }
+
+ if ($indexerType && !$hasCustomSetter) {
+ if ($indexerType eq "DOMString") {
+ my $conversion = $indexer->extendedAttributes->{"ConvertNullStringTo"};
+ if ($conversion && $conversion eq "Null") {
+ push(@implContent, <<END);
+ setCollectionStringOrNullIndexedGetter<${interfaceName}>(desc);
+END
+ } else {
+ push(@implContent, <<END);
+ setCollectionStringIndexedGetter<${interfaceName}>(desc);
+END
+ }
+ } else {
+ push(@implContent, <<END);
+ setCollectionIndexedGetter<${interfaceName}, ${indexerType}>(desc);
+END
+ # Include the header for this indexer type, because setCollectionIndexedGetter() requires toV8() for this type.
+ $implIncludes{"V8${indexerType}.h"} = 1;
+ }
+
+ return;
+ }
+
+ my $hasDeleter = $dataNode->extendedAttributes->{"CustomDeleteProperty"};
+ my $hasEnumerator = !$isSpecialCase && IsNodeSubType($dataNode);
+ my $setOn = "Instance";
+
+ # V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCallbacks) and it's used on DOMWindow
+ # instead of deleters or enumerators. In addition, the getter should be set on prototype template, to
+ # get implementation straight out of the DOMWindow prototype regardless of what prototype is actually set
+ # on the object.
+ if ($interfaceName eq "DOMWindow") {
+ $setOn = "Prototype";
+ $hasDeleter = 0;
+ }
+
+ push(@implContent, " desc->${setOn}Template()->SetIndexedPropertyHandler(V8${interfaceName}::indexedPropertyGetter");
+ push(@implContent, $hasCustomSetter ? ", V8${interfaceName}::indexedPropertySetter" : ", 0");
+ push(@implContent, ", 0"); # IndexedPropertyQuery -- not being used at the moment.
+ push(@implContent, $hasDeleter ? ", V8${interfaceName}::indexedPropertyDeleter" : ", 0");
+ push(@implContent, ", nodeCollectionIndexedPropertyEnumerator<${interfaceName}>") if $hasEnumerator;
+ push(@implContent, ");\n");
+}
+
+sub GenerateImplementationNamedPropertyGetter
+{
+ my $dataNode = shift;
+ my $namedPropertyGetter = shift;
+ my $interfaceName = $dataNode->name;
+ my $hasCustomGetter = $dataNode->extendedAttributes->{"HasOverridingNameGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"};
+
+ # FIXME: Remove hard-coded HTMLOptionsCollection reference by changing HTMLOptionsCollection to not inherit
+ # from HTMLCollection per W3C spec (http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109/html.html#HTMLOptionsCollection).
+ if ($interfaceName eq "HTMLOptionsCollection") {
+ $interfaceName = "HTMLCollection";
+ $hasCustomGetter = 1;
+ }
+
+ if ($interfaceName eq "HTMLAppletElement" || $interfaceName eq "HTMLEmbedElement" || $interfaceName eq "HTMLObjectElement") {
+ $hasCustomGetter = 1;
+ }
+
+ my $hasGetter = $dataNode->extendedAttributes->{"HasNameGetter"} || $hasCustomGetter || $namedPropertyGetter;
+ if (!$hasGetter) {
+ return;
+ }
+
+ if ($namedPropertyGetter && $namedPropertyGetter->type ne "Node" && !$namedPropertyGetter->extendedAttributes->{"Custom"} && !$hasCustomGetter) {
+ $implIncludes{"V8Collection.h"} = 1;
+ my $type = $namedPropertyGetter->type;
+ push(@implContent, <<END);
+ setCollectionNamedGetter<${interfaceName}, ${type}>(desc);
+END
+ return;
+ }
+
+ my $hasSetter = $dataNode->extendedAttributes->{"DelegatingPutFunction"};
+ # FIXME: Try to remove hard-coded HTMLDocument reference by aligning handling of document.all with JSC bindings.
+ my $hasDeleter = $dataNode->extendedAttributes->{"CustomDeleteProperty"} || $interfaceName eq "HTMLDocument";
+ my $hasEnumerator = $dataNode->extendedAttributes->{"CustomGetPropertyNames"};
+ my $setOn = "Instance";
+
+ # V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCallbacks) and it's used on DOMWindow
+ # instead of deleters or enumerators. In addition, the getter should be set on prototype template, to
+ # get implementation straight out of the DOMWindow prototype regardless of what prototype is actually set
+ # on the object.
+ if ($interfaceName eq "DOMWindow") {
+ $setOn = "Prototype";
+ $hasDeleter = 0;
+ $hasEnumerator = 0;
+ }
+
+ push(@implContent, " desc->${setOn}Template()->SetNamedPropertyHandler(V8${interfaceName}::namedPropertyGetter, ");
+ push(@implContent, $hasSetter ? "V8${interfaceName}::namedPropertySetter, " : "0, ");
+ push(@implContent, "0, "); # NamedPropertyQuery -- not being used at the moment.
+ push(@implContent, $hasDeleter ? "V8${interfaceName}::namedPropertyDeleter, " : "0, ");
+ push(@implContent, $hasEnumerator ? "V8${interfaceName}::namedPropertyEnumerator" : "0");
+ push(@implContent, ");\n");
+}
+
+sub GenerateImplementationCustomCall
+{
+ my $dataNode = shift;
+ my $interfaceName = $dataNode->name;
+ my $hasCustomCall = $dataNode->extendedAttributes->{"CustomCall"};
+
+ # FIXME: Remove hard-coded HTMLOptionsCollection reference.
+ if ($interfaceName eq "HTMLOptionsCollection") {
+ $interfaceName = "HTMLCollection";
+ $hasCustomCall = 1;
+ }
+
+ if ($hasCustomCall) {
+ push(@implContent, " desc->InstanceTemplate()->SetCallAsFunctionHandler(V8${interfaceName}::callAsFunctionCallback);\n");
+ }
+}
+
+sub GenerateImplementationMasqueradesAsUndefined
+{
+ my $dataNode = shift;
+ if ($dataNode->extendedAttributes->{"MasqueradesAsUndefined"})
+ {
+ push(@implContent, " desc->InstanceTemplate()->MarkAsUndetectable();\n");
+ }
+}
+
sub GenerateImplementation
{
my $object = shift;
my $dataNode = shift;
my $interfaceName = $dataNode->name;
+ my $visibleInterfaceName = GetVisibleInterfaceName($interfaceName);
my $className = "V8$interfaceName";
my $implClassName = $interfaceName;
- my $classIndex = uc($codeGenerator->StripModule($interfaceName));
my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
my $conditionalString = GenerateConditionalString($dataNode);
@@ -1095,8 +1441,12 @@ sub GenerateImplementation
push(@implFixedHeader,
"#include \"config.h\"\n" .
+ "#include \"RuntimeEnabledFeatures.h\"\n" .
"#include \"V8Proxy.h\"\n" .
- "#include \"V8Binding.h\"\n\n" .
+ "#include \"V8Binding.h\"\n" .
+ "#include \"V8BindingState.h\"\n" .
+ "#include \"V8DOMWrapper.h\"\n" .
+ "#include \"V8IsolatedContext.h\"\n\n" .
"#undef LOG\n\n");
push(@implFixedHeader, "\n#if ${conditionalString}\n\n") if $conditionalString;
@@ -1108,14 +1458,15 @@ sub GenerateImplementation
$implIncludes{"${className}.h"} = 1;
AddIncludesForType($interfaceName);
- $implIncludes{"V8Proxy.h"} = 1;
- push(@implContentDecls, "namespace WebCore {\n");
+ my $toActive = IsActiveDomType($interfaceName) ? "${className}::toActiveDOMObject" : "0";
+
+ push(@implContentDecls, "namespace WebCore {\n\n");
+ push(@implContentDecls, "WrapperTypeInfo ${className}::info = { ${className}::GetTemplate, ${className}::derefObject, ${toActive} };\n\n");
push(@implContentDecls, "namespace ${interfaceName}Internal {\n\n");
push(@implContentDecls, "template <typename T> void V8_USE(T) { }\n\n");
my $hasConstructors = 0;
-
# Generate property accessors for attributes.
for ($index = 0; $index < @{$dataNode->attributes}; $index++) {
$attribute = @{$dataNode->attributes}[$index];
@@ -1124,9 +1475,8 @@ sub GenerateImplementation
# Generate special code for the constructor attributes.
if ($attrType =~ /Constructor$/) {
- if ($attribute->signature->extendedAttributes->{"CustomGetter"}) {
- $implIncludes{"V8CustomBinding.h"} = 1;
- } else {
+ if (!($attribute->signature->extendedAttributes->{"CustomGetter"} ||
+ $attribute->signature->extendedAttributes->{"V8CustomGetter"})) {
$hasConstructors = 1;
}
next;
@@ -1141,46 +1491,48 @@ sub GenerateImplementation
# implementation.
if ($attribute->signature->extendedAttributes->{"Custom"} ||
$attribute->signature->extendedAttributes->{"V8Custom"}) {
- $implIncludes{"V8CustomBinding.h"} = 1;
next;
}
# Generate the accessor.
- if ($attribute->signature->extendedAttributes->{"CustomGetter"}) {
- $implIncludes{"V8CustomBinding.h"} = 1;
- } else {
- GenerateNormalAttrGetter($attribute, $dataNode, $classIndex, $implClassName, $interfaceName);
+ if (!($attribute->signature->extendedAttributes->{"CustomGetter"} ||
+ $attribute->signature->extendedAttributes->{"V8CustomGetter"})) {
+ GenerateNormalAttrGetter($attribute, $dataNode, $implClassName, $interfaceName);
}
- if ($attribute->signature->extendedAttributes->{"CustomSetter"} ||
- $attribute->signature->extendedAttributes->{"V8CustomSetter"}) {
- $implIncludes{"V8CustomBinding.h"} = 1;
- } elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) {
- $dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"} || die "Replaceable attribute can only be used in interface that defines ExtendsDOMGlobalObject attribute!";
- # GenerateReplaceableAttrSetter($implClassName);
- } elsif ($attribute->type !~ /^readonly/ && !$attribute->signature->extendedAttributes->{"V8ReadOnly"}) {
- GenerateNormalAttrSetter($attribute, $dataNode, $classIndex, $implClassName, $interfaceName);
+ if (!$attribute->signature->extendedAttributes->{"CustomSetter"} &&
+ !$attribute->signature->extendedAttributes->{"V8CustomSetter"} &&
+ !$attribute->signature->extendedAttributes->{"Replaceable"} &&
+ $attribute->type !~ /^readonly/ &&
+ !$attribute->signature->extendedAttributes->{"V8ReadOnly"}) {
+ GenerateNormalAttrSetter($attribute, $dataNode, $implClassName, $interfaceName);
}
}
if ($hasConstructors) {
- GenerateConstructorGetter($implClassName, $classIndex);
+ GenerateConstructorGetter($implClassName);
}
+ my $indexer;
+ my $namedPropertyGetter;
# Generate methods for functions.
foreach my $function (@{$dataNode->functions}) {
- # hack for addEventListener/RemoveEventListener
- # FIXME: avoid naming conflict
- if ($function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"V8Custom"}) {
- $implIncludes{"V8CustomBinding.h"} = 1;
- } else {
- GenerateFunctionCallback($function, $dataNode, $classIndex, $implClassName);
+ if (!($function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"V8Custom"})) {
+ GenerateFunctionCallback($function, $dataNode, $implClassName);
+ }
+
+ if ($function->signature->name eq "item") {
+ $indexer = $function->signature;
+ }
+
+ if ($function->signature->name eq "namedItem") {
+ $namedPropertyGetter = $function->signature;
}
# If the function does not need domain security check, we need to
# generate an access getter that returns different function objects
# for different calling context.
if (($dataNode->extendedAttributes->{"CheckDomainSecurity"} || ($interfaceName eq "DOMWindow")) && $function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) {
- GenerateDomainSafeFunctionGetter($function, $dataNode, $classIndex, $implClassName);
+ GenerateDomainSafeFunctionGetter($function, $implClassName);
}
}
@@ -1194,6 +1546,7 @@ sub GenerateImplementation
my @enabledAtRuntime;
my @normal;
foreach my $attribute (@$attributes) {
+
if ($interfaceName eq "DOMWindow" && $attribute->signature->extendedAttributes->{"V8DisallowShadowing"}) {
push(@disallowsShadowing, $attribute);
} elsif ($attribute->signature->extendedAttributes->{"EnabledAtRuntime"}) {
@@ -1218,6 +1571,38 @@ sub GenerateImplementation
push(@implContent, "};\n");
}
+ # Setup table of standard callback functions
+ $num_callbacks = 0;
+ $has_callbacks = 0;
+ foreach my $function (@{$dataNode->functions}) {
+ my $attrExt = $function->signature->extendedAttributes;
+ # Don't put any nonstandard functions into this table:
+ if ($attrExt->{"V8OnInstance"}) {
+ next;
+ }
+ if ($attrExt->{"EnabledAtRuntime"} || RequiresCustomSignature($function) || $attrExt->{"V8DoNotCheckSignature"}) {
+ next;
+ }
+ if ($attrExt->{"DoNotCheckDomainSecurity"} &&
+ ($dataNode->extendedAttributes->{"CheckDomainSecurity"} || $interfaceName eq "DOMWindow")) {
+ next;
+ }
+ if ($attrExt->{"DontEnum"} || $attrExt->{"V8ReadOnly"}) {
+ next;
+ }
+ if (!$has_callbacks) {
+ $has_callbacks = 1;
+ push(@implContent, "static const BatchedCallback ${interfaceName}_callbacks[] = {\n");
+ }
+ my $name = $function->signature->name;
+ my $callback = GetFunctionTemplateCallbackName($function, $interfaceName);
+ push(@implContent, <<END);
+ {"$name", $callback},
+END
+ $num_callbacks++;
+ }
+ push(@implContent, "};\n") if $has_callbacks;
+
# Setup constants
my $has_constants = 0;
if (@{$dataNode->constants}) {
@@ -1240,60 +1625,100 @@ END
push(@implContentDecls, "} // namespace ${interfaceName}Internal\n\n");
- my $access_check = "/* no access check */";
+ # In namespace WebCore, add generated implementation for 'CanBeConstructed'.
+ if ($dataNode->extendedAttributes->{"CanBeConstructed"} && !$dataNode->extendedAttributes->{"CustomConstructor"}) {
+ push(@implContent, <<END);
+v8::Handle<v8::Value> ${className}::constructorCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.${interfaceName}.Contructor");
+ return V8Proxy::constructDOMObject<$interfaceName>(args, &info);
+}
+END
+ }
+
+ my $access_check = "";
if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} && !($interfaceName eq "DOMWindow")) {
- $access_check = "instance->SetAccessCheckCallbacks(V8Custom::v8${interfaceName}NamedSecurityCheck, V8Custom::v8${interfaceName}IndexedSecurityCheck, v8::Integer::New(V8ClassIndex::ToInt(V8ClassIndex::${classIndex})));";
+ $access_check = "instance->SetAccessCheckCallbacks(V8${interfaceName}::namedSecurityCheck, V8${interfaceName}::indexedSecurityCheck, v8::External::Wrap(&V8${interfaceName}::info));";
}
# For the DOMWindow interface, generate the shadow object template
# configuration method.
if ($implClassName eq "DOMWindow") {
push(@implContent, <<END);
-static v8::Persistent<v8::ObjectTemplate> ConfigureShadowObjectTemplate(v8::Persistent<v8::ObjectTemplate> templ) {
- batchConfigureAttributes(templ,
- v8::Handle<v8::ObjectTemplate>(),
- shadow_attrs,
- sizeof(shadow_attrs)/sizeof(*shadow_attrs));
- return templ;
+static v8::Persistent<v8::ObjectTemplate> ConfigureShadowObjectTemplate(v8::Persistent<v8::ObjectTemplate> templ)
+{
+ batchConfigureAttributes(templ, v8::Handle<v8::ObjectTemplate>(), shadow_attrs, sizeof(shadow_attrs)/sizeof(*shadow_attrs));
+
+ // Install a security handler with V8.
+ templ->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheck, V8DOMWindow::indexedSecurityCheck, v8::External::Wrap(&V8DOMWindow::info));
+ templ->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
+ return templ;
}
END
}
+ # find the super descriptor
+ my $parentClassTemplate = "";
+ foreach (@{$dataNode->parents}) {
+ my $parent = $codeGenerator->StripModule($_);
+ if ($parent eq "EventTarget") { next; }
+ $implIncludes{"V8${parent}.h"} = 1;
+ $parentClassTemplate = "V8" . $parent . "::GetTemplate()";
+ last;
+ }
+ if (!$parentClassTemplate) {
+ $parentClassTemplate = "v8::Persistent<v8::FunctionTemplate>()";
+ }
+
# Generate the template configuration method
push(@implContent, <<END);
-static v8::Persistent<v8::FunctionTemplate> Configure${className}Template(v8::Persistent<v8::FunctionTemplate> desc) {
- v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
+static v8::Persistent<v8::FunctionTemplate> Configure${className}Template(v8::Persistent<v8::FunctionTemplate> desc)
+{
+ v8::Local<v8::Signature> default_signature = configureTemplate(desc, \"${visibleInterfaceName}\", $parentClassTemplate, V8${interfaceName}::internalFieldCount,
END
- if (IsNodeSubType($dataNode)) {
+ # Set up our attributes if we have them
+ if ($has_attributes) {
push(@implContent, <<END);
- instance->SetInternalFieldCount(V8Custom::kNodeMinimumInternalFieldCount);
+ ${interfaceName}_attrs, sizeof(${interfaceName}_attrs)/sizeof(*${interfaceName}_attrs),
END
} else {
push(@implContent, <<END);
- instance->SetInternalFieldCount(V8Custom::kDefaultWrapperInternalFieldCount);
+ NULL, 0,
END
}
- push(@implContent, <<END);
- v8::Local<v8::Signature> default_signature = v8::Signature::New(desc);
- v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
- $access_check
+ if ($has_callbacks) {
+ push(@implContent, <<END);
+ ${interfaceName}_callbacks, sizeof(${interfaceName}_callbacks)/sizeof(*${interfaceName}_callbacks));
END
+ } else {
+ push(@implContent, <<END);
+ NULL, 0);
+END
+ }
-
- # Set up our attributes if we have them
- if ($has_attributes) {
+ if ($dataNode->extendedAttributes->{"CustomConstructor"} || $dataNode->extendedAttributes->{"CanBeConstructed"}) {
push(@implContent, <<END);
- batchConfigureAttributes(instance, proto, ${interfaceName}_attrs, sizeof(${interfaceName}_attrs)/sizeof(*${interfaceName}_attrs));
+ desc->SetCallHandler(V8${interfaceName}::constructorCallback);
END
}
+ if ($access_check or @enabledAtRuntime or @{$dataNode->functions} or $has_constants) {
+ push(@implContent, <<END);
+ v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
+ v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
+END
+ }
+
+ push(@implContent, " $access_check\n");
+
# Setup the enable-at-runtime attrs if we have them
foreach my $runtime_attr (@enabledAtRuntime) {
- $enable_function = $interfaceName . $codeGenerator->WK_ucfirst($runtime_attr->signature->name);
+ # A function named RuntimeEnabledFeatures::{methodName}Enabled() need to be written by hand.
+ $enable_function = "RuntimeEnabledFeatures::" . $codeGenerator->WK_lcfirst($runtime_attr->signature->name) . "Enabled";
my $conditionalString = GenerateConditionalString($runtime_attr->signature);
push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString;
- push(@implContent, " if (V8Custom::v8${enable_function}Enabled()) {\n");
+ push(@implContent, " if (${enable_function}()) {\n");
push(@implContent, " static const BatchedAttribute attrData =\\\n");
GenerateSingleBatchedAttribute($interfaceName, $runtime_attr, ";", " ");
push(@implContent, <<END);
@@ -1303,8 +1728,15 @@ END
push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
}
+ GenerateImplementationIndexer($dataNode, $indexer);
+ GenerateImplementationNamedPropertyGetter($dataNode, $namedPropertyGetter);
+ GenerateImplementationCustomCall($dataNode);
+ GenerateImplementationMasqueradesAsUndefined($dataNode);
+
# Define our functions with Set() or SetAccessor()
+ $total_functions = 0;
foreach my $function (@{$dataNode->functions}) {
+ $total_functions++;
my $attrExt = $function->signature->extendedAttributes;
my $name = $function->signature->name;
@@ -1326,8 +1758,8 @@ END
my $conditional = "";
if ($attrExt->{"EnabledAtRuntime"}) {
# Only call Set()/SetAccessor() if this method should be enabled
- $enable_function = $interfaceName . $codeGenerator->WK_ucfirst($function->signature->name);
- $conditional = "if (V8Custom::v8${enable_function}Enabled())\n";
+ $enable_function = "RuntimeEnabledFeatures::" . $codeGenerator->WK_lcfirst($function->signature->name) . "Enabled";
+ $conditional = "if (${enable_function}())\n ";
}
if ($attrExt->{"DoNotCheckDomainSecurity"} &&
@@ -1349,108 +1781,333 @@ END
$property_attributes .= "|v8::ReadOnly";
push(@implContent, <<END);
- // $commentInfo
- $conditional $template->SetAccessor(
- v8::String::New("$name"),
- ${interfaceName}Internal::${name}AttrGetter,
- 0,
- v8::Handle<v8::Value>(),
- v8::ALL_CAN_READ,
- static_cast<v8::PropertyAttribute>($property_attributes));
+ // $commentInfo
+ ${conditional}$template->SetAccessor(v8::String::New("$name"), ${interfaceName}Internal::${name}AttrGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>($property_attributes));
END
+ $num_callbacks++;
next;
}
my $signature = "default_signature";
- if ($attrExt->{"V8DoNotCheckSignature"}){
+ if ($attrExt->{"V8DoNotCheckSignature"}) {
$signature = "v8::Local<v8::Signature>()";
}
if (RequiresCustomSignature($function)) {
$signature = "${name}_signature";
- push(@implContent, "\n // Custom Signature '$name'\n", CreateCustomSignature($function));
+ push(@implContent, "\n // Custom Signature '$name'\n", CreateCustomSignature($function));
}
# Normal function call is a template
- my $templateFunction = GenerateNewFunctionTemplate($function, $dataNode, $signature);
+ my $callback = GetFunctionTemplateCallbackName($function, $interfaceName);
+ if ($property_attributes eq "v8::DontDelete") {
+ $property_attributes = "";
+ } else {
+ $property_attributes = ", static_cast<v8::PropertyAttribute>($property_attributes)";
+ }
- push(@implContent, <<END);
+ if ($template eq "proto" && $conditional eq "" && $signature eq "default_signature" && $property_attributes eq "") {
+ # Standard type of callback, already created in the batch, so skip it here.
+ next;
+ }
- // $commentInfo
- $conditional ${template}->Set(
- v8::String::New("$name"),
- $templateFunction,
- static_cast<v8::PropertyAttribute>($property_attributes));
+ push(@implContent, <<END);
+ ${conditional}$template->Set(v8::String::New("$name"), v8::FunctionTemplate::New($callback, v8::Handle<v8::Value>(), ${signature})$property_attributes);
END
+ $num_callbacks++;
}
- # set the super descriptor
- foreach (@{$dataNode->parents}) {
- my $parent = $codeGenerator->StripModule($_);
- if ($parent eq "EventTarget") { next; }
- $implIncludes{"V8${parent}.h"} = 1;
- my $parentClassIndex = uc($codeGenerator->StripModule($parent));
- push(@implContent, " desc->Inherit(V8DOMWrapper::getTemplate(V8ClassIndex::${parentClassIndex}));\n");
- last;
+ die "Wrong number of callbacks generated for $interfaceName ($num_callbacks, should be $total_functions)" if $num_callbacks != $total_functions;
+
+ if ($has_constants) {
+ push(@implContent, <<END);
+ batchConfigureConstants(desc, proto, ${interfaceName}_consts, sizeof(${interfaceName}_consts)/sizeof(*${interfaceName}_consts));
+END
}
- # Set the class name. This is used when printing objects.
- push(@implContent, " desc->SetClassName(v8::String::New(\"${interfaceName}\"));\n");
+ # Special cases
+ if ($interfaceName eq "DOMWindow") {
+ push(@implContent, <<END);
- if ($has_constants) {
+ proto->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
+ desc->SetHiddenPrototype(true);
+ instance->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
+ // Set access check callbacks, but turned off initially.
+ // When a context is detached from a frame, turn on the access check.
+ // Turning on checks also invalidates inline caches of the object.
+ instance->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheck, V8DOMWindow::indexedSecurityCheck, v8::External::Wrap(&V8DOMWindow::info), false);
+END
+ }
+ if ($interfaceName eq "Location") {
push(@implContent, <<END);
- batchConfigureConstants(desc, proto, ${interfaceName}_consts, sizeof(${interfaceName}_consts)/sizeof(*${interfaceName}_consts));
+
+ // For security reasons, these functions are on the instance instead
+ // of on the prototype object to ensure that they cannot be overwritten.
+ instance->SetAccessor(v8::String::New("reload"), V8Location::reloadAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
+ instance->SetAccessor(v8::String::New("replace"), V8Location::replaceAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
+ instance->SetAccessor(v8::String::New("assign"), V8Location::assignAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
END
}
+ my $nativeType = GetNativeTypeForConversions($interfaceName);
+ if ($dataNode->extendedAttributes->{"PODType"}) {
+ $nativeType = "V8SVGPODTypeWrapper<${nativeType}>";
+ }
push(@implContent, <<END);
- return desc;
+
+ // Custom toString template
+ desc->Set(getToStringName(), getToStringTemplate());
+ return desc;
+}
+
+v8::Persistent<v8::FunctionTemplate> ${className}::GetRawTemplate()
+{
+ static v8::Persistent<v8::FunctionTemplate> ${className}_raw_cache_ = createRawTemplate();
+ return ${className}_raw_cache_;
}
-v8::Persistent<v8::FunctionTemplate> ${className}::GetRawTemplate() {
- static v8::Persistent<v8::FunctionTemplate> ${className}_raw_cache_;
- if (${className}_raw_cache_.IsEmpty()) {
- v8::HandleScope scope;
- v8::Local<v8::FunctionTemplate> result = v8::FunctionTemplate::New(V8Proxy::checkNewLegal);
- ${className}_raw_cache_ = v8::Persistent<v8::FunctionTemplate>::New(result);
- }
- return ${className}_raw_cache_;
+v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate()\
+{
+ static v8::Persistent<v8::FunctionTemplate> ${className}_cache_ = Configure${className}Template(GetRawTemplate());
+ return ${className}_cache_;
}
-v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate() {
- static v8::Persistent<v8::FunctionTemplate> ${className}_cache_;
- if (${className}_cache_.IsEmpty())
- ${className}_cache_ = Configure${className}Template(GetRawTemplate());
- return ${className}_cache_;
+${nativeType}* ${className}::toNative(v8::Handle<v8::Object> object)
+{
+ return reinterpret_cast<${nativeType}*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex));
}
-bool ${className}::HasInstance(v8::Handle<v8::Value> value) {
- return GetRawTemplate()->HasInstance(value);
+bool ${className}::HasInstance(v8::Handle<v8::Value> value)
+{
+ return GetRawTemplate()->HasInstance(value);
}
END
+ if (IsActiveDomType($interfaceName)) {
+ # MessagePort is handled like an active dom object even though it doesn't inherit
+ # from ActiveDOMObject, so don't try to cast it to ActiveDOMObject.
+ my $returnValue = $interfaceName eq "MessagePort" ? "0" : "toNative(object)";
+ push(@implContent, <<END);
+ActiveDOMObject* ${className}::toActiveDOMObject(v8::Handle<v8::Object> object)
+{
+ return ${returnValue};
+}
+END
+ }
+
if ($implClassName eq "DOMWindow") {
push(@implContent, <<END);
-v8::Persistent<v8::ObjectTemplate> V8DOMWindow::GetShadowObjectTemplate() {
- static v8::Persistent<v8::ObjectTemplate> V8DOMWindowShadowObject_cache_;
- if (V8DOMWindowShadowObject_cache_.IsEmpty()) {
- V8DOMWindowShadowObject_cache_ = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New());
- ConfigureShadowObjectTemplate(V8DOMWindowShadowObject_cache_);
- }
- return V8DOMWindowShadowObject_cache_;
+v8::Persistent<v8::ObjectTemplate> V8DOMWindow::GetShadowObjectTemplate()
+{
+ static v8::Persistent<v8::ObjectTemplate> V8DOMWindowShadowObject_cache_;
+ if (V8DOMWindowShadowObject_cache_.IsEmpty()) {
+ V8DOMWindowShadowObject_cache_ = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New());
+ ConfigureShadowObjectTemplate(V8DOMWindowShadowObject_cache_);
+ }
+ return V8DOMWindowShadowObject_cache_;
}
END
}
+ GenerateToV8Converters($dataNode, $interfaceName, $className, $nativeType);
+
+ push(@implContent, <<END);
+
+void ${className}::derefObject(void* object)
+{
+END
+
+ if (IsRefPtrType($interfaceName)) {
+ push(@implContent, <<END);
+ static_cast<${nativeType}*>(object)->deref();
+END
+ }
+
push(@implContent, <<END);
+}
+
} // namespace WebCore
END
push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
}
+sub GenerateToV8Converters
+{
+ my $dataNode = shift;
+ my $interfaceName = shift;
+ my $className = shift;
+ my $nativeType = shift;
+
+ my $domMapFunction = GetDomMapFunction($dataNode, $interfaceName);
+ my $forceNewObjectInput = IsDOMNodeType($interfaceName) ? ", bool forceNewObject" : "";
+ my $forceNewObjectCall = IsDOMNodeType($interfaceName) ? ", forceNewObject" : "";
+
+ push(@implContent, <<END);
+
+v8::Handle<v8::Object> ${className}::wrap(${nativeType}* impl${forceNewObjectInput})
+{
+ v8::Handle<v8::Object> wrapper;
+ V8Proxy* proxy = 0;
+END
+
+ if (IsNodeSubType($dataNode)) {
+ push(@implContent, <<END);
+ if (impl->document()) {
+ proxy = V8Proxy::retrieve(impl->document()->frame());
+ if (proxy && static_cast<Node*>(impl->document()) == static_cast<Node*>(impl))
+ proxy->windowShell()->initContextIfNeeded();
+ }
+
+END
+ }
+
+ if ($domMapFunction) {
+ push(@implContent, " if (!forceNewObject) {\n") if IsDOMNodeType($interfaceName);
+ if (IsNodeSubType($dataNode)) {
+ push(@implContent, " wrapper = V8DOMWrapper::getWrapper(impl);\n");
+ } else {
+ push(@implContent, " wrapper = ${domMapFunction}.get(impl);\n");
+ }
+ push(@implContent, <<END);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+END
+ push(@implContent, " }\n") if IsDOMNodeType($interfaceName);
+ }
+ if (IsNodeSubType($dataNode)) {
+ push(@implContent, <<END);
+
+ v8::Handle<v8::Context> context;
+ if (proxy)
+ context = proxy->context();
+
+ // Enter the node's context and create the wrapper in that context.
+ if (!context.IsEmpty())
+ context->Enter();
+END
+ }
+
+ push(@implContent, <<END);
+ wrapper = V8DOMWrapper::instantiateV8Object(proxy, &info, impl);
+END
+
+ if (IsNodeSubType($dataNode)) {
+ push(@implContent, <<END);
+ // Exit the node's context if it was entered.
+ if (!context.IsEmpty())
+ context->Exit();
+END
+ }
+
+ push(@implContent, <<END);
+ if (wrapper.IsEmpty())
+ return wrapper;
+END
+ push(@implContent, "\n impl->ref();\n") if IsRefPtrType($interfaceName);
+
+ if ($domMapFunction) {
+ push(@implContent, <<END);
+ ${domMapFunction}.set(impl, v8::Persistent<v8::Object>::New(wrapper));
+END
+ }
+
+ push(@implContent, <<END);
+ return wrapper;
+}
+END
+
+ if (IsRefPtrType($interfaceName)) {
+ push(@implContent, <<END);
+
+v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} > impl${forceNewObjectInput})
+{
+ return toV8(impl.get()${forceNewObjectCall});
+}
+END
+ }
+
+ if (!HasCustomToV8Implementation($dataNode, $interfaceName)) {
+ push(@implContent, <<END);
+
+v8::Handle<v8::Value> toV8(${nativeType}* impl${forceNewObjectInput})
+{
+ if (!impl)
+ return v8::Null();
+ return ${className}::wrap(impl${forceNewObjectCall});
+}
+END
+ }
+}
+
+sub HasCustomToV8Implementation {
+ # FIXME: This subroutine is lame. Probably should be an .idl attribute (CustomToV8)?
+ $dataNode = shift;
+ $interfaceName = shift;
+
+ # We generate a custom converter (but JSC doesn't) for the following:
+ return 1 if $interfaceName eq "BarInfo";
+ return 1 if $interfaceName eq "CSSStyleSheet";
+ return 1 if $interfaceName eq "CanvasPixelArray";
+ return 1 if $interfaceName eq "DOMSelection";
+ return 1 if $interfaceName eq "DOMWindow";
+ return 1 if $interfaceName eq "Element";
+ return 1 if $interfaceName eq "Location";
+ return 1 if $interfaceName eq "HTMLDocument";
+ return 1 if $interfaceName eq "HTMLElement";
+ return 1 if $interfaceName eq "History";
+ return 1 if $interfaceName eq "NamedNodeMap";
+ return 1 if $interfaceName eq "Navigator";
+ return 1 if $interfaceName eq "SVGDocument";
+ return 1 if $interfaceName eq "SVGElement";
+ return 1 if $interfaceName eq "Screen";
+ return 1 if $interfaceName eq "WorkerContext";
+ # We don't generate a custom converter (but JSC does) for the following:
+ return 0 if $interfaceName eq "AbstractWorker";
+ return 0 if $interfaceName eq "CanvasRenderingContext";
+ return 0 if $interfaceName eq "ImageData";
+ return 0 if $interfaceName eq "SVGElementInstance";
+
+ # For everything else, do what JSC does.
+ return $dataNode->extendedAttributes->{"CustomToJS"};
+}
+
+sub GetDomMapFunction
+{
+ my $dataNode = shift;
+ my $type = shift;
+ return "getDOMSVGElementInstanceMap()" if $type eq "SVGElementInstance";
+ return "getDOMNodeMap()" if IsNodeSubType($dataNode);
+ # Only use getDOMSVGObjectWithContextMap() for non-node svg objects
+ return "getDOMSVGObjectWithContextMap()" if $type =~ /SVG/;
+ return "" if $type eq "DOMImplementation";
+ return "getActiveDOMObjectMap()" if IsActiveDomType($type);
+ return "getDOMObjectMap()";
+}
+
+sub IsActiveDomType
+{
+ # FIXME: Consider making this an .idl attribute.
+ my $type = shift;
+ return 1 if $type eq "MessagePort";
+ return 1 if $type eq "XMLHttpRequest";
+ return 1 if $type eq "WebSocket";
+ return 1 if $type eq "Worker";
+ return 1 if $type eq "SharedWorker";
+ return 0;
+}
+
+sub GetNativeTypeForConversions
+{
+ my $type = shift;
+ return "FloatRect" if $type eq "SVGRect";
+ return "FloatPoint" if $type eq "SVGPoint";
+ return "AffineTransform" if $type eq "SVGMatrix";
+ return "float" if $type eq "SVGNumber";
+ return $type;
+}
sub GenerateFunctionCallString()
{
@@ -1497,7 +2154,6 @@ sub GenerateFunctionCallString()
my $first = 1;
my $index = 0;
- my $nodeToReturn = 0;
foreach my $parameter (@{$function->parameters}) {
if ($index eq $numberOfParameters) {
@@ -1519,16 +2175,20 @@ sub GenerateFunctionCallString()
} else {
$functionString .= $paramName;
}
-
- if ($parameter->extendedAttributes->{"Return"}) {
- $nodeToReturn = $parameter->name;
- }
$index++;
}
if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) {
$functionString .= ", " if not $first;
- $functionString .= "&callStack";
+ $functionString .= "callStack.get()";
+ if ($first) { $first = 0; }
+ }
+
+ if ($function->signature->extendedAttributes->{"NeedsUserGestureCheck"}) {
+ $functionString .= ", " if not $first;
+ # FIXME: We need to pass DOMWrapperWorld as a parameter.
+ # See http://trac.webkit.org/changeset/54182
+ $functionString .= "processingUserGesture()";
if ($first) { $first = 0; }
}
@@ -1541,24 +2201,10 @@ sub GenerateFunctionCallString()
my $return = "result";
my $returnIsRef = IsRefPtrType($returnType);
- if ($nodeToReturn) {
- # Special case for insertBefore, replaceChild, removeChild and
- # appendChild functions from Node.
- $result .= $indent . "bool success = $functionString;\n";
- if (@{$function->raisesExceptions}) {
- $result .= GenerateSetDOMException($indent);
- }
- $result .= $indent . "if (success)\n";
- $result .= $indent . " " .
- "return V8DOMWrapper::convertNodeToV8Object($nodeToReturn);\n";
- $result .= $indent . "return v8::Null();\n";
- return $result;
- } elsif ($returnType eq "void") {
+ if ($returnType eq "void") {
$result .= $indent . "$functionString;\n";
} elsif ($copyFirst) {
- $result .=
- $indent . GetNativeType($returnType, 0) . " result = *imp;\n" .
- $indent . "$functionString;\n";
+ $result .= $indent . GetNativeType($returnType, 0) . " result = *imp;\n" . $indent . "$functionString;\n";
} elsif ($returnsListItemPodType) {
$result .= $indent . "RefPtr<SVGPODListItem<$nativeReturnType> > result = $functionString;\n";
} elsif (@{$function->raisesExceptions} or $returnsPodType or $isPodType or IsSVGTypeNeedingContextParameter($returnType)) {
@@ -1570,7 +2216,7 @@ sub GenerateFunctionCallString()
}
if (@{$function->raisesExceptions}) {
- $result .= GenerateSetDOMException($indent);
+ $result .= $indent . "if (UNLIKELY(ec)) goto fail;\n";
}
# If the return type is a POD type, separate out the wrapper generation
@@ -1612,8 +2258,8 @@ sub GenerateFunctionCallString()
}
if ($returnsPodType) {
- my $classIndex = uc($returnType);
- $result .= $indent . "return V8DOMWrapper::convertToV8Object(V8ClassIndex::$classIndex, wrapper.release());\n";
+ $implIncludes{"V8${returnType}.h"} = 1;
+ $result .= $indent . "return toV8(wrapper.release());\n";
} else {
$return .= ".release()" if ($returnIsRef);
$result .= $indent . ReturnNativeToJSValue($function->signature, $return, $indent) . ";\n";
@@ -1627,19 +2273,14 @@ sub GetTypeFromSignature
{
my $signature = shift;
- my $type = $codeGenerator->StripModule($signature->type);
- if (($type eq "DOMString") && $signature->extendedAttributes->{"HintAtomic"}) {
- $type = "AtomicString";
- }
-
- return $type;
+ return $codeGenerator->StripModule($signature->type);
}
sub GetNativeTypeFromSignature
{
my $signature = shift;
- my $isParameter = shift;
+ my $parameterIndex = shift;
my $type = GetTypeFromSignature($signature);
@@ -1648,117 +2289,39 @@ sub GetNativeTypeFromSignature
return "int";
}
- return GetNativeType($type, $isParameter);
-}
-
-sub IsRefPtrType
-{
- my $type = shift;
- return 1 if $type eq "Attr";
- return 1 if $type eq "CanvasActiveInfo";
- return 1 if $type eq "CanvasArray";
- return 1 if $type eq "CanvasArrayBuffer";
- return 1 if $type eq "CanvasBooleanArray";
- return 1 if $type eq "CanvasByteArray";
- return 1 if $type eq "CanvasBuffer";
- return 1 if $type eq "CanvasFloatArray";
- return 1 if $type eq "CanvasFramebuffer";
- return 1 if $type eq "CanvasGradient";
- return 1 if $type eq "CanvasIntArray";
- return 1 if $type eq "CanvasObject";
- return 1 if $type eq "CanvasProgram";
- return 1 if $type eq "CanvasRenderbuffer";
- return 1 if $type eq "CanvasShader";
- return 1 if $type eq "CanvasShortArray";
- return 1 if $type eq "CanvasTexture";
- return 1 if $type eq "CanvasUnsignedByteArray";
- return 1 if $type eq "CanvasUnsignedIntArray";
- return 1 if $type eq "CanvasUnsignedShortArray";
- return 1 if $type eq "ClientRect";
- return 1 if $type eq "ClientRectList";
- return 1 if $type eq "CDATASection";
- return 1 if $type eq "Comment";
- return 1 if $type eq "CSSRule";
- return 1 if $type eq "CSSStyleRule";
- return 1 if $type eq "CSSCharsetRule";
- return 1 if $type eq "CSSImportRule";
- return 1 if $type eq "CSSMediaRule";
- return 1 if $type eq "CSSFontFaceRule";
- return 1 if $type eq "CSSPageRule";
- return 1 if $type eq "CSSPrimitiveValue";
- return 1 if $type eq "CSSStyleSheet";
- return 1 if $type eq "CSSStyleDeclaration";
- return 1 if $type eq "CSSValue";
- return 1 if $type eq "CSSRuleList";
- return 1 if $type eq "Database";
- return 1 if $type eq "Document";
- return 1 if $type eq "DocumentFragment";
- return 1 if $type eq "DocumentType";
- return 1 if $type eq "Element";
- return 1 if $type eq "EntityReference";
- return 1 if $type eq "Event";
- return 1 if $type eq "EventListener";
- return 1 if $type eq "FileList";
- return 1 if $type eq "HTMLCollection";
- return 1 if $type eq "HTMLAllCollection";
- return 1 if $type eq "HTMLDocument";
- return 1 if $type eq "HTMLElement";
- return 1 if $type eq "HTMLOptionsCollection";
- return 1 if $type eq "ImageData";
- return 1 if $type eq "Media";
- return 1 if $type eq "MediaError";
- return 1 if $type eq "MimeType";
- return 1 if $type eq "Node";
- return 1 if $type eq "NodeList";
- return 1 if $type eq "NodeFilter";
- return 1 if $type eq "NodeIterator";
- return 1 if $type eq "NSResolver";
- return 1 if $type eq "Plugin";
- return 1 if $type eq "ProcessingInstruction";
- return 1 if $type eq "Range";
- return 1 if $type eq "RGBColor";
- return 1 if $type eq "Text";
- return 1 if $type eq "TextMetrics";
- return 1 if $type eq "TimeRanges";
- return 1 if $type eq "TreeWalker";
- return 1 if $type eq "WebKitCSSMatrix";
- return 1 if $type eq "WebKitPoint";
- return 1 if $type eq "XPathExpression";
- return 1 if $type eq "XPathNSResolver";
- return 1 if $type eq "XPathResult";
-
- return 1 if $type eq "SVGAngle";
- return 1 if $type eq "SVGElementInstance";
- return 1 if $type eq "SVGElementInstanceList";
- return 1 if $type =~ /^SVGPathSeg/;
-
- return 1 if $type =~ /^SVGAnimated/;
+ $type = GetNativeType($type, $parameterIndex >= 0 ? 1 : 0);
- return 0;
-}
-
-sub IsVideoClassName
-{
- my $class = shift;
- return 1 if $class eq "V8HTMLAudioElement";
- return 1 if $class eq "V8HTMLMediaElement";
- return 1 if $class eq "V8HTMLSourceElement";
- return 1 if $class eq "V8HTMLVideoElement";
- return 1 if $class eq "V8MediaError";
- return 1 if $class eq "V8TimeRanges";
+ if ($parameterIndex >= 0 && $type eq "V8Parameter") {
+ my $mode = "";
+ if ($signature->extendedAttributes->{"ConvertUndefinedOrNullToNullString"}) {
+ $mode = "WithUndefinedOrNullCheck";
+ } elsif ($signature->extendedAttributes->{"ConvertNullToNullString"}) {
+ $mode = "WithNullCheck";
+ }
+ $type .= "<$mode>";
+ }
- return 0;
+ return $type;
}
-sub IsWorkerClassName
+sub IsRefPtrType
{
- my $class = shift;
- return 1 if $class eq "V8Worker";
- return 1 if $class eq "V8WorkerContext";
- return 1 if $class eq "V8WorkerLocation";
- return 1 if $class eq "V8WorkerNavigator";
+ my $type = shift;
- return 0;
+ return 0 if $type eq "boolean";
+ return 0 if $type eq "float";
+ return 0 if $type eq "int";
+ return 0 if $type eq "Date";
+ return 0 if $type eq "DOMString";
+ return 0 if $type eq "double";
+ return 0 if $type eq "short";
+ return 0 if $type eq "long";
+ return 0 if $type eq "unsigned";
+ return 0 if $type eq "unsigned long";
+ return 0 if $type eq "unsigned short";
+ return 0 if $type eq "SVGAnimatedPoints";
+
+ return 1;
}
sub GetNativeType
@@ -1766,28 +2329,34 @@ sub GetNativeType
my $type = shift;
my $isParameter = shift;
- if ($type eq "float" or $type eq "AtomicString" or $type eq "double") {
+ if ($type eq "float" or $type eq "double") {
return $type;
}
+ return "V8Parameter" if ($type eq "DOMString" or $type eq "DOMUserData") and $isParameter;
return "int" if $type eq "int";
return "int" if $type eq "short" or $type eq "unsigned short";
return "unsigned" if $type eq "unsigned long";
return "int" if $type eq "long";
+ return "long long" if $type eq "long long";
return "unsigned long long" if $type eq "unsigned long long";
return "bool" if $type eq "boolean";
return "String" if $type eq "DOMString";
return "Range::CompareHow" if $type eq "CompareHow";
return "FloatRect" if $type eq "SVGRect";
return "FloatPoint" if $type eq "SVGPoint";
- return "TransformationMatrix" if $type eq "SVGMatrix";
+ return "AffineTransform" if $type eq "SVGMatrix";
return "SVGTransform" if $type eq "SVGTransform";
return "SVGLength" if $type eq "SVGLength";
- return "double" if $type eq "SVGNumber";
+ return "SVGAngle" if $type eq "SVGAngle";
+ return "float" if $type eq "SVGNumber";
+ return "SVGPreserveAspectRatio" if $type eq "SVGPreserveAspectRatio";
return "SVGPaint::SVGPaintType" if $type eq "SVGPaintType";
return "DOMTimeStamp" if $type eq "DOMTimeStamp";
return "unsigned" if $type eq "unsigned int";
return "Node*" if $type eq "EventTarget" and $isParameter;
+ return "double" if $type eq "Date";
+ return "ScriptValue" if $type eq "DOMObject";
return "String" if $type eq "DOMUserData"; # FIXME: Temporary hack?
@@ -1803,69 +2372,6 @@ sub GetNativeType
return "${type}*";
}
-
-my %typeCanFailConversion = (
- "AtomicString" => 0,
- "Attr" => 1,
- "CanvasArray" => 0,
- "CanvasBuffer" => 0,
- "CanvasByteArray" => 0,
- "CanvasFloatArray" => 0,
- "CanvasFramebuffer" => 0,
- "CanvasGradient" => 0,
- "CanvasIntArray" => 0,
- "CanvasPixelArray" => 0,
- "CanvasProgram" => 0,
- "CanvasRenderbuffer" => 0,
- "CanvasShader" => 0,
- "CanvasShortArray" => 0,
- "CanvasTexture" => 0,
- "CompareHow" => 0,
- "DataGridColumn" => 0,
- "DOMString" => 0,
- "DOMWindow" => 0,
- "DocumentType" => 0,
- "Element" => 0,
- "Event" => 0,
- "EventListener" => 0,
- "EventTarget" => 0,
- "HTMLCanvasElement" => 0,
- "HTMLElement" => 0,
- "HTMLImageElement" => 0,
- "HTMLOptionElement" => 0,
- "HTMLVideoElement" => 0,
- "Node" => 0,
- "NodeFilter" => 0,
- "MessagePort" => 0,
- "NSResolver" => 0,
- "Range" => 0,
- "SQLResultSet" => 0,
- "Storage" => 0,
- "SVGAngle" => 0,
- "SVGElement" => 0,
- "SVGLength" => 1,
- "SVGMatrix" => 1,
- "SVGNumber" => 0,
- "SVGPaintType" => 0,
- "SVGPathSeg" => 0,
- "SVGPoint" => 1,
- "SVGRect" => 1,
- "SVGTransform" => 1,
- "VoidCallback" => 1,
- "WebKitCSSMatrix" => 0,
- "WebKitPoint" => 0,
- "XPathEvaluator" => 0,
- "XPathNSResolver" => 0,
- "XPathResult" => 0,
- "boolean" => 0,
- "double" => 0,
- "float" => 0,
- "long" => 0,
- "unsigned long" => 0,
- "unsigned short" => 0,
-);
-
-
sub TranslateParameter
{
my $signature = shift;
@@ -1881,9 +2387,11 @@ sub BasicTypeCanFailConversion
my $signature = shift;
my $type = GetTypeFromSignature($signature);
+ return 1 if $type eq "SVGAngle";
return 1 if $type eq "SVGLength";
return 1 if $type eq "SVGMatrix";
return 1 if $type eq "SVGPoint";
+ return 1 if $type eq "SVGPreserveAspectRatio";
return 1 if $type eq "SVGRect";
return 1 if $type eq "SVGTransform";
return 0;
@@ -1896,10 +2404,9 @@ sub TypeCanFailConversion
my $type = GetTypeFromSignature($signature);
$implIncludes{"ExceptionCode.h"} = 1 if $type eq "Attr";
-
- return $typeCanFailConversion{$type} if exists $typeCanFailConversion{$type};
-
- die "Don't know whether a JS value can fail conversion to type $type.";
+ return 1 if $type eq "Attr";
+ return 1 if $type eq "VoidCallback";
+ return BasicTypeCanFailConversion($signature);
}
sub JSValueToNative
@@ -1917,19 +2424,13 @@ sub JSValueToNative
return "$value->NumberValue()" if $type eq "SVGNumber";
return "toInt32($value${maybeOkParam})" if $type eq "unsigned long" or $type eq "unsigned short" or $type eq "long";
+ return "toInt64($value)" if $type eq "unsigned long long" or $type eq "long long";
return "static_cast<Range::CompareHow>($value->Int32Value())" if $type eq "CompareHow";
return "static_cast<SVGPaint::SVGPaintType>($value->ToInt32()->Int32Value())" if $type eq "SVGPaintType";
+ return "toWebCoreDate($value)" if $type eq "Date";
- if ($type eq "AtomicString") {
- return "v8ValueToAtomicWebCoreStringWithNullCheck($value)" if $signature->extendedAttributes->{"ConvertNullToNullString"};
- return "v8ValueToAtomicWebCoreString($value)";
- }
-
- return "toWebCoreString($value)" if $type eq "DOMUserData";
- if ($type eq "DOMString") {
- return "toWebCoreStringWithNullCheck($value)" if $signature->extendedAttributes->{"ConvertNullToNullString"};
- return "toWebCoreStringWithNullOrUndefinedCheck($value)" if $signature->extendedAttributes->{"ConvertUndefinedOrNullToNullString"};
- return "toWebCoreString($value)";
+ if ($type eq "DOMString" or $type eq "DOMUserData") {
+ return $value;
}
if ($type eq "SerializedScriptValue") {
@@ -1937,6 +2438,11 @@ sub JSValueToNative
return "SerializedScriptValue::create($value)";
}
+ if ($type eq "DOMObject") {
+ $implIncludes{"ScriptValue.h"} = 1;
+ return "ScriptValue($value)";
+ }
+
if ($type eq "NodeFilter") {
return "V8DOMWrapper::wrapNativeNodeFilter($value)";
}
@@ -1950,12 +2456,11 @@ sub JSValueToNative
}
# Default, assume autogenerated type conversion routines
- $implIncludes{"V8Proxy.h"} = 1;
if ($type eq "EventTarget") {
$implIncludes{"V8Node.h"} = 1;
# EventTarget is not in DOM hierarchy, but all Nodes are EventTarget.
- return "V8Node::HasInstance($value) ? V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast($value)) : 0";
+ return "V8Node::HasInstance($value) ? V8Node::toNative(v8::Handle<v8::Object>::Cast($value)) : 0";
}
if ($type eq "XPathNSResolver") {
@@ -1963,51 +2468,49 @@ sub JSValueToNative
}
AddIncludesForType($type);
- # $implIncludes{"$type.h"} = 1 unless AvoidInclusionOfType($type);
if (IsDOMNodeType($type)) {
$implIncludes{"V8${type}.h"} = 1;
# Perform type checks on the parameter, if it is expected Node type,
# return NULL.
- return "V8${type}::HasInstance($value) ? V8DOMWrapper::convertDOMWrapperToNode<${type}>(v8::Handle<v8::Object>::Cast($value)) : 0";
+ return "V8${type}::HasInstance($value) ? V8${type}::toNative(v8::Handle<v8::Object>::Cast($value)) : 0";
} else {
- # TODO: Temporary to avoid Window name conflict.
- my $classIndex = uc($type);
- my $implClassName = ${type};
-
$implIncludes{"V8$type.h"} = 1;
if (IsPodType($type)) {
my $nativeType = GetNativeType($type);
$implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
- return "V8SVGPODTypeUtil::toSVGPODType<${nativeType}>(V8ClassIndex::${classIndex}, $value${maybeOkParam})"
+ return "V8SVGPODTypeUtil::toSVGPODType<${nativeType}>(&V8${type}::info, $value${maybeOkParam})"
}
$implIncludes{"V8${type}.h"} = 1;
# Perform type checks on the parameter, if it is expected Node type,
# return NULL.
- return "V8${type}::HasInstance($value) ? V8DOMWrapper::convertToNativeObject<${implClassName}>(V8ClassIndex::${classIndex}, v8::Handle<v8::Object>::Cast($value)) : 0";
+ return "V8${type}::HasInstance($value) ? V8${type}::toNative(v8::Handle<v8::Object>::Cast($value)) : 0";
}
}
-
sub GetV8HeaderName
{
my $type = shift;
- return "V8" . GetImplementationFileName($type);
+ return "V8Event.h" if $type eq "DOMTimeStamp";
+ return "EventListener.h" if $type eq "EventListener";
+ return "EventTarget.h" if $type eq "EventTarget";
+ return "SerializedScriptValue.h" if $type eq "SerializedScriptValue";
+ return "ScriptValue.h" if $type eq "DOMObject";
+ return "V8${type}.h";
}
-
sub CreateCustomSignature
{
my $function = shift;
my $count = @{$function->parameters};
my $name = $function->signature->name;
- my $result = " const int ${name}_argc = ${count};\n" .
- " v8::Handle<v8::FunctionTemplate> ${name}_argv[${name}_argc] = { ";
+ my $result = " const int ${name}_argc = ${count};\n" .
+ " v8::Handle<v8::FunctionTemplate> ${name}_argv[${name}_argc] = { ";
my $first = 1;
foreach my $parameter (@{$function->parameters}) {
if ($first) { $first = 0; }
@@ -2028,7 +2531,7 @@ sub CreateCustomSignature
}
}
$result .= " };\n";
- $result .= " v8::Handle<v8::Signature> ${name}_signature = v8::Signature::New(desc, ${name}_argc, ${name}_argv);\n";
+ $result .= " v8::Handle<v8::Signature> ${name}_signature = v8::Signature::New(desc, ${name}_argc, ${name}_argv);\n";
return $result;
}
@@ -2043,9 +2546,9 @@ sub RequiresCustomSignature
}
foreach my $parameter (@{$function->parameters}) {
- if (IsWrapperType($parameter->type)) {
- return 1;
- }
+ if (IsWrapperType($parameter->type)) {
+ return 1;
+ }
}
return 0;
}
@@ -2053,17 +2556,20 @@ sub RequiresCustomSignature
my %non_wrapper_types = (
'float' => 1,
- 'AtomicString' => 1,
'double' => 1,
'short' => 1,
'unsigned short' => 1,
'long' => 1,
'unsigned long' => 1,
'boolean' => 1,
+ 'long long' => 1,
+ 'unsigned long long' => 1,
'DOMString' => 1,
'CompareHow' => 1,
+ 'SVGAngle' => 1,
'SVGRect' => 1,
'SVGPoint' => 1,
+ 'SVGPreserveAspectRatio' => 1,
'SVGMatrix' => 1,
'SVGTransform' => 1,
'SVGLength' => 1,
@@ -2071,6 +2577,7 @@ my %non_wrapper_types = (
'SVGPaintType' => 1,
'DOMTimeStamp' => 1,
'JSObject' => 1,
+ 'DOMObject' => 1,
'EventTarget' => 1,
'NodeFilter' => 1,
'EventListener' => 1
@@ -2119,11 +2626,10 @@ sub ReturnNativeToJSValue
my $value = shift;
my $indent = shift;
my $type = GetTypeFromSignature($signature);
- my $className= "V8$type";
return "return v8::Date::New(static_cast<double>($value))" if $type eq "DOMTimeStamp";
- return "return $value ? v8::True() : v8::False()" if $type eq "boolean";
- return "return v8::Undefined()" if $type eq "void";
+ return "return v8Boolean($value)" if $type eq "boolean";
+ return "return v8::Handle<v8::Value>()" if $type eq "void"; # equivalent to v8::Undefined()
# For all the types where we use 'int' as the representation type,
# we use Integer::New which has a fast Smi conversion check.
@@ -2131,7 +2637,9 @@ sub ReturnNativeToJSValue
return "return v8::Integer::New($value)" if $nativeType eq "int";
return "return v8::Integer::NewFromUnsigned($value)" if $nativeType eq "unsigned";
+ return "return v8DateOrNull($value);" if $type eq "Date";
return "return v8::Number::New($value)" if $codeGenerator->IsPrimitiveType($type) or $type eq "SVGPaintType";
+ return "return $value.v8Value()" if $nativeType eq "ScriptValue";
if ($codeGenerator->IsStringType($type)) {
my $conv = $signature->extendedAttributes->{"ConvertNullStringTo"};
@@ -2145,61 +2653,36 @@ sub ReturnNativeToJSValue
return "return v8String($value)";
}
- # V8 specific.
- my $implClassName = $type;
AddIncludesForType($type);
- # $implIncludes{GetImplementationFileName($type)} = 1 unless AvoidInclusionOfType($type);
# special case for non-DOM node interfaces
if (IsDOMNodeType($type)) {
- if ($signature->extendedAttributes->{"ReturnsNew"}) {
- return "return V8DOMWrapper::convertNewNodeToV8Object($value)";
- } else {
- return "return V8DOMWrapper::convertNodeToV8Object($value)";
- }
+ return "return toV8(${value}" . ($signature->extendedAttributes->{"ReturnsNew"} ? ", true)" : ")");
}
- if ($type eq "EventTarget" or $type eq "SVGElementInstance") {
+ if ($type eq "EventTarget") {
return "return V8DOMWrapper::convertEventTargetToV8Object($value)";
}
- if ($type eq "Event") {
- return "return V8DOMWrapper::convertEventToV8Object($value)";
- }
-
if ($type eq "EventListener") {
- return "return V8DOMWrapper::convertEventListenerToV8Object(imp->scriptExecutionContext(), $value)";
+ $implIncludes{"V8AbstractEventListener.h"} = 1;
+ return "return ${value} ? v8::Handle<v8::Value>(static_cast<V8AbstractEventListener*>(${value})->getListenerObject(imp->scriptExecutionContext())) : v8::Handle<v8::Value>(v8::Null())";
}
if ($type eq "SerializedScriptValue") {
$implIncludes{"$type.h"} = 1;
- return "return v8String($value->toString())";
+ return "return $value->deserialize()";
}
- if ($type eq "DedicatedWorkerContext" or $type eq "WorkerContext" or $type eq "SharedWorkerContext") {
- $implIncludes{"WorkerContextExecutionProxy.h"} = 1;
- return "return WorkerContextExecutionProxy::convertWorkerContextToV8Object($value)";
- }
-
- if ($type eq "WorkerLocation" or $type eq "WorkerNavigator" or $type eq "NotificationCenter") {
- $implIncludes{"WorkerContextExecutionProxy.h"} = 1;
- my $classIndex = uc($type);
+ $implIncludes{"wtf/RefCounted.h"} = 1;
+ $implIncludes{"wtf/RefPtr.h"} = 1;
+ $implIncludes{"wtf/GetPtr.h"} = 1;
- return "return WorkerContextExecutionProxy::convertToV8Object(V8ClassIndex::$classIndex, $value)";
+ if (IsPodType($type)) {
+ $value = GenerateSVGStaticPodTypeWrapper($type, $value) . ".get()";
}
- else {
- $implIncludes{"wtf/RefCounted.h"} = 1;
- $implIncludes{"wtf/RefPtr.h"} = 1;
- $implIncludes{"wtf/GetPtr.h"} = 1;
- my $classIndex = uc($type);
-
- if (IsPodType($type)) {
- $value = GenerateSVGStaticPodTypeWrapper($type, $value);
- }
-
- return "return V8DOMWrapper::convertToV8Object(V8ClassIndex::$classIndex, $value)";
- }
+ return "return toV8($value)";
}
sub GenerateSVGStaticPodTypeWrapper {
@@ -2333,6 +2816,15 @@ sub IsSVGListTypeNeedingSpecialHandling
return 0;
}
+sub GetVisibleInterfaceName
+{
+ my $interfaceName = shift;
+
+ return "DOMException" if $interfaceName eq "DOMCoreException";
+ return "FormData" if $interfaceName eq "DOMFormData";
+ return $interfaceName;
+}
+
sub DebugPrint
{
my $output = shift;