📄 codegeneratorjs.pm
字号:
}}sub prototypeHashTableAccessor{ my $noStaticTables = shift; my $className = shift; if ($noStaticTables) { return "get${className}PrototypeTable(exec)"; } else { return "&${className}PrototypeTable"; }}sub GenerateGetOwnPropertySlotBody{ my ($dataNode, $interfaceName, $className, $implClassName, $hasAttributes, $inlined) = @_; my $namespaceMaybe = ($inlined ? "JSC::" : ""); my @getOwnPropertySlotImpl = (); if ($interfaceName eq "NamedNodeMap" or $interfaceName eq "HTMLCollection") { push(@getOwnPropertySlotImpl, " ${namespaceMaybe}JSValuePtr proto = prototype();\n"); push(@getOwnPropertySlotImpl, " if (proto.isObject() && static_cast<${namespaceMaybe}JSObject*>(asObject(proto))->hasProperty(exec, propertyName))\n"); push(@getOwnPropertySlotImpl, " return false;\n\n"); } my $manualLookupGetterGeneration = sub { my $requiresManualLookup = $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasNameGetter"}; if ($requiresManualLookup) { push(@getOwnPropertySlotImpl, " const ${namespaceMaybe}HashEntry* entry = ${className}Table.entry(exec, propertyName);\n"); push(@getOwnPropertySlotImpl, " if (entry) {\n"); push(@getOwnPropertySlotImpl, " slot.setCustom(this, entry->propertyGetter());\n"); push(@getOwnPropertySlotImpl, " return true;\n"); push(@getOwnPropertySlotImpl, " }\n"); } }; if (!$dataNode->extendedAttributes->{"HasOverridingNameGetter"}) { &$manualLookupGetterGeneration(); } if ($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"}) { push(@getOwnPropertySlotImpl, " bool ok;\n"); push(@getOwnPropertySlotImpl, " unsigned index = propertyName.toUInt32(&ok, false);\n"); push(@getOwnPropertySlotImpl, " if (ok && index < static_cast<$implClassName*>(impl())->length()) {\n"); if ($dataNode->extendedAttributes->{"HasCustomIndexGetter"}) { push(@getOwnPropertySlotImpl, " slot.setValue(getByIndex(exec, index));\n"); } else { push(@getOwnPropertySlotImpl, " slot.setCustomIndex(this, index, indexGetter);\n"); } push(@getOwnPropertySlotImpl, " return true;\n"); push(@getOwnPropertySlotImpl, " }\n"); } if ($dataNode->extendedAttributes->{"HasNameGetter"} || $dataNode->extendedAttributes->{"HasOverridingNameGetter"}) { push(@getOwnPropertySlotImpl, " if (canGetItemsForName(exec, static_cast<$implClassName*>(impl()), propertyName)) {\n"); push(@getOwnPropertySlotImpl, " slot.setCustom(this, nameGetter);\n"); push(@getOwnPropertySlotImpl, " return true;\n"); push(@getOwnPropertySlotImpl, " }\n"); if ($inlined) { $headerIncludes{"AtomicString.h"} = 1; } else { $implIncludes{"AtomicString.h"} = 1; } } if ($dataNode->extendedAttributes->{"HasOverridingNameGetter"}) { &$manualLookupGetterGeneration(); } if ($dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"}) { push(@getOwnPropertySlotImpl, " if (customGetOwnPropertySlot(exec, propertyName, slot))\n"); push(@getOwnPropertySlotImpl, " return true;\n"); } if ($hasAttributes) { if ($inlined) { die "Cannot inline if NoStaticTables is set." if ($dataNode->extendedAttributes->{"NoStaticTables"}); push(@getOwnPropertySlotImpl, " return ${namespaceMaybe}getStaticValueSlot<$className, Base>(exec, s_info.staticPropHashTable, this, propertyName, slot);\n"); } else { push(@getOwnPropertySlotImpl, " return ${namespaceMaybe}getStaticValueSlot<$className, Base>(exec, " . hashTableAccessor($dataNode->extendedAttributes->{"NoStaticTables"}, $className) . ", this, propertyName, slot);\n"); } } else { push(@getOwnPropertySlotImpl, " return Base::getOwnPropertySlot(exec, propertyName, slot);\n"); } return @getOwnPropertySlotImpl;}sub GenerateHeader{ my $object = shift; my $dataNode = shift; my $interfaceName = $dataNode->name; my $className = "JS$interfaceName"; my $implClassName = $interfaceName; # We only support multiple parents with SVG (for now). if (@{$dataNode->parents} > 1) { die "A class can't have more than one parent" unless $interfaceName =~ /SVG/; $codeGenerator->AddMethodsConstantsAndAttributesFromParentClasses($dataNode); } my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"}; my $hasRealParent = @{$dataNode->parents} > 0; my $hasParent = $hasLegacyParent || $hasRealParent; my $parentClassName = GetParentClassName($dataNode); my $conditional = $dataNode->extendedAttributes->{"Conditional"}; # - Add default header template @headerContentHeader = split("\r", $headerTemplate); # - Add header protection push(@headerContentHeader, "\n#ifndef $className" . "_h"); push(@headerContentHeader, "\n#define $className" . "_h\n\n"); my $conditionalString; if ($conditional) { $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")"; push(@headerContentHeader, "\n#if ${conditionalString}\n\n"); } if ($hasParent) { push(@headerContentHeader, "#include \"$parentClassName.h\"\n"); } else { push(@headerContentHeader, "#include \"JSDOMBinding.h\"\n"); push(@headerContentHeader, "#include <runtime/JSGlobalObject.h>\n"); push(@headerContentHeader, "#include <runtime/ObjectPrototype.h>\n"); } if ($dataNode->extendedAttributes->{"CustomCall"}) { push(@headerContentHeader, "#include <runtime/CallData.h>\n"); } if ($dataNode->extendedAttributes->{"InlineGetOwnPropertySlot"}) { push(@headerContentHeader, "#include <runtime/Lookup.h>\n"); push(@headerContentHeader, "#include <wtf/AlwaysInline.h>\n"); } if ($hasParent && $dataNode->extendedAttributes->{"GenerateNativeConverter"}) { push(@headerContentHeader, "#include \"${implClassName}.h\""); } # Get correct pass/store types respecting PODType flag my $podType = $dataNode->extendedAttributes->{"PODType"}; my $implType = $podType ? "JSSVGPODTypeWrapper<$podType> " : $implClassName; push(@headerContentHeader, "#include \"$podType.h\"\n") if $podType and $podType ne "float"; push(@headerContentHeader, "#include \"JSSVGPODTypeWrapper.h\"\n") if $podType; my $numConstants = @{$dataNode->constants}; my $numAttributes = @{$dataNode->attributes}; my $numFunctions = @{$dataNode->functions}; push(@headerContent, "\nnamespace WebCore {\n\n"); # Implementation class forward declaration AddClassForwardIfNeeded($implClassName) unless $podType; AddClassForwardIfNeeded("JSDOMWindowShell") if $interfaceName eq "DOMWindow"; # Class declaration push(@headerContent, "class $className : public $parentClassName {\n"); push(@headerContent, " typedef $parentClassName Base;\n"); push(@headerContent, "public:\n"); # Constructor if ($interfaceName eq "DOMWindow") { push(@headerContent, " $className(PassRefPtr<JSC::Structure>, PassRefPtr<$implType>, JSDOMWindowShell*);\n"); } elsif (IsSVGTypeNeedingContextParameter($implClassName)) { push(@headerContent, " $className(PassRefPtr<JSC::Structure>, PassRefPtr<$implType>, SVGElement* context);\n"); } else { push(@headerContent, " $className(PassRefPtr<JSC::Structure>, PassRefPtr<$implType>);\n"); } # Destructor push(@headerContent, " virtual ~$className();\n") if (!$hasParent or $interfaceName eq "Document"); # Prototype push(@headerContent, " static JSC::JSObject* createPrototype(JSC::ExecState*);\n") unless ($dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"}); $implIncludes{"${className}Custom.h"} = 1 if $dataNode->extendedAttributes->{"CustomHeader"} || $dataNode->extendedAttributes->{"CustomPutFunction"}; my $hasGetter = $numAttributes > 0 || $dataNode->extendedAttributes->{"GenerateConstructor"} || $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"} || $dataNode->extendedAttributes->{"HasNameGetter"} || $dataNode->extendedAttributes->{"HasOverridingNameGetter"}; # Getters if ($hasGetter) { push(@headerContent, " virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&);\n"); push(@headerContent, " virtual bool getOwnPropertySlot(JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);\n") if ($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"}) && !$dataNode->extendedAttributes->{"HasOverridingNameGetter"}; push(@headerContent, " bool customGetOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&);\n") if $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"}; } # Check if we have any writable properties my $hasReadWriteProperties = 0; foreach (@{$dataNode->attributes}) { if ($_->type !~ /^readonly\ attribute$/) { $hasReadWriteProperties = 1; } } my $hasSetter = $hasReadWriteProperties || $dataNode->extendedAttributes->{"CustomPutFunction"} || $dataNode->extendedAttributes->{"HasCustomIndexSetter"}; # Getters if ($hasSetter) { push(@headerContent, " virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValuePtr, JSC::PutPropertySlot&);\n"); push(@headerContent, " virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValuePtr);\n") if $dataNode->extendedAttributes->{"HasCustomIndexSetter"}; push(@headerContent, " bool customPut(JSC::ExecState*, const JSC::Identifier&, JSC::JSValuePtr, JSC::PutPropertySlot&);\n") if $dataNode->extendedAttributes->{"CustomPutFunction"}; } # Class info push(@headerContent, " virtual const JSC::ClassInfo* classInfo() const { return &s_info; }\n"); push(@headerContent, " static const JSC::ClassInfo s_info;\n\n"); # Structure ID if ($interfaceName eq "DOMWindow") { push(@headerContent, " static PassRefPtr<JSC::Structure> createStructure(JSC::JSValuePtr prototype)\n" . " {\n" . " return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, JSC::ImplementsHasInstance | JSC::NeedsThisConversion));\n" . " }\n\n"); } elsif ($hasGetter) { push(@headerContent, " static PassRefPtr<JSC::Structure> createStructure(JSC::JSValuePtr prototype)\n" . " {\n" . " return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType));\n" . " }\n\n"); } # Custom mark function push(@headerContent, " virtual void mark();\n\n") if $dataNode->extendedAttributes->{"CustomMarkFunction"}; # Custom pushEventHandlerScope function push(@headerContent, " virtual void pushEventHandlerScope(JSC::ExecState*, JSC::ScopeChain&) const;\n\n") if $dataNode->extendedAttributes->{"CustomPushEventHandlerScope"}; # Custom call functions push(@headerContent, " virtual JSC::CallType getCallData(JSC::CallData&);\n\n") if $dataNode->extendedAttributes->{"CustomCall"}; # Custom deleteProperty function push(@headerContent, " virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier&);\n") if $dataNode->extendedAttributes->{"CustomDeleteProperty"}; # Custom getPropertyNames function push(@headerContent, " virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);\n") if ($dataNode->extendedAttributes->{"CustomGetPropertyNames"} || $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"}); push(@headerContent, " bool customGetPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);\n") if $dataNode->extendedAttributes->{"CustomGetPropertyNames"}; # Custom getPropertyAttributes function push(@headerContent, " virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, unsigned& attributes) const;\n") if $dataNode->extendedAttributes->{"CustomGetPropertyAttributes"}; # Custom defineGetter function
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -