📄 codegeneratorjs.pm
字号:
my @entries = (); foreach my $attribute (@{$dataNode->attributes}) { my $name = $attribute->signature->name; push(@hashKeys, $name); my @specials = (); push(@specials, "DontDelete") unless $attribute->signature->extendedAttributes->{"Deletable"}; push(@specials, "DontEnum") if $attribute->signature->extendedAttributes->{"DontEnum"}; push(@specials, "ReadOnly") if $attribute->type =~ /readonly/; my $special = (@specials > 0) ? join("|", @specials) : "0"; push(@hashSpecials, $special); my $getter = "js" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : ""); push(@hashValue1, $getter); if ($attribute->type =~ /readonly/) { push(@hashValue2, "0"); } else { my $setter = "setJS" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : ""); push(@hashValue2, $setter); } } if ($dataNode->extendedAttributes->{"GenerateConstructor"}) { push(@hashKeys, "constructor"); my $getter = "js" . $interfaceName . "Constructor"; push(@hashValue1, $getter); push(@hashValue2, "0"); push(@hashSpecials, "DontEnum|ReadOnly"); # FIXME: Setting the constructor should be possible. } $object->GenerateHashTable($hashName, $hashSize, \@hashKeys, \@hashSpecials, \@hashValue1, \@hashValue2); } my $numConstants = @{$dataNode->constants}; my $numFunctions = @{$dataNode->functions}; # - Add all constants if ($dataNode->extendedAttributes->{"GenerateConstructor"}) { $hashSize = $numConstants; $hashName = $className . "ConstructorTable"; @hashKeys = (); @hashValue1 = (); @hashValue2 = (); @hashSpecials = (); # FIXME: we should not need a function for every constant. foreach my $constant (@{$dataNode->constants}) { push(@hashKeys, $constant->name); my $getter = "js" . $interfaceName . $codeGenerator->WK_ucfirst($constant->name); push(@hashValue1, $getter); push(@hashValue2, "0"); push(@hashSpecials, "DontDelete|ReadOnly"); } $object->GenerateHashTable($hashName, $hashSize, \@hashKeys, \@hashSpecials, \@hashValue1, \@hashValue2); my $protoClassName; $protoClassName = "${className}Prototype"; push(@implContent, constructorFor($className, $protoClassName, $interfaceName, $visibleClassName, $dataNode->extendedAttributes->{"CanBeConstructed"})); } # - Add functions and constants to a hashtable definition $hashSize = $numFunctions + $numConstants; $hashName = $className . "PrototypeTable"; @hashKeys = (); @hashValue1 = (); @hashValue2 = (); @hashSpecials = (); # FIXME: we should not need a function for every constant. foreach my $constant (@{$dataNode->constants}) { push(@hashKeys, $constant->name); my $getter = "js" . $interfaceName . $codeGenerator->WK_ucfirst($constant->name); push(@hashValue1, $getter); push(@hashValue2, "0"); push(@hashSpecials, "DontDelete|ReadOnly"); } foreach my $function (@{$dataNode->functions}) { my $name = $function->signature->name; push(@hashKeys, $name); my $value = $codeGenerator->WK_lcfirst($className) . "PrototypeFunction" . $codeGenerator->WK_ucfirst($name); push(@hashValue1, $value); my $numParameters = @{$function->parameters}; push(@hashValue2, $numParameters); my @specials = (); push(@specials, "DontDelete") unless $function->signature->extendedAttributes->{"Deletable"}; push(@specials, "DontEnum") if $function->signature->extendedAttributes->{"DontEnum"}; push(@specials, "Function"); my $special = (@specials > 0) ? join("|", @specials) : "0"; push(@hashSpecials, $special); } $object->GenerateHashTable($hashName, $hashSize, \@hashKeys, \@hashSpecials, \@hashValue1, \@hashValue2); if ($dataNode->extendedAttributes->{"NoStaticTables"}) { push(@implContent, "static const HashTable* get${className}PrototypeTable(ExecState* exec)\n"); push(@implContent, "{\n"); push(@implContent, " return getHashTableForGlobalData(exec->globalData(), &${className}PrototypeTable);\n"); push(@implContent, "}\n"); push(@implContent, "const ClassInfo ${className}Prototype::s_info = { \"${visibleClassName}Prototype\", 0, 0, get${className}PrototypeTable };\n\n"); } else { push(@implContent, "const ClassInfo ${className}Prototype::s_info = { \"${visibleClassName}Prototype\", 0, &${className}PrototypeTable, 0 };\n\n"); } if ($interfaceName eq "DOMWindow") { push(@implContent, "void* ${className}Prototype::operator new(size_t size)\n"); push(@implContent, "{\n"); push(@implContent, " return JSDOMWindow::commonJSGlobalData()->heap.allocate(size);\n"); push(@implContent, "}\n\n"); } elsif ($interfaceName eq "WorkerContext") { push(@implContent, "void* ${className}Prototype::operator new(size_t size, JSGlobalData* globalData)\n"); push(@implContent, "{\n"); push(@implContent, " return globalData->heap.allocate(size);\n"); push(@implContent, "}\n\n"); } else { push(@implContent, "JSObject* ${className}Prototype::self(ExecState* exec)\n"); push(@implContent, "{\n"); push(@implContent, " return getDOMPrototype<${className}>(exec);\n"); push(@implContent, "}\n\n"); } if ($numConstants > 0 || $numFunctions > 0) { push(@implContent, "bool ${className}Prototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)\n"); push(@implContent, "{\n"); if ($numConstants eq 0) { push(@implContent, " return getStaticFunctionSlot<JSObject>(exec, " . prototypeHashTableAccessor($dataNode->extendedAttributes->{"NoStaticTables"}, $className) . ", this, propertyName, slot);\n"); } elsif ($numFunctions eq 0) { push(@implContent, " return getStaticValueSlot<${className}Prototype, JSObject>(exec, " . prototypeHashTableAccessor($dataNode->extendedAttributes->{"NoStaticTables"}, $className) . ", this, propertyName, slot);\n"); } else { push(@implContent, " return getStaticPropertySlot<${className}Prototype, JSObject>(exec, " . prototypeHashTableAccessor($dataNode->extendedAttributes->{"NoStaticTables"}, $className) . ", this, propertyName, slot);\n"); } push(@implContent, "}\n\n"); } # - Initialize static ClassInfo object if ($numAttributes > 0 && $dataNode->extendedAttributes->{"NoStaticTables"}) { push(@implContent, "static const HashTable* get${className}Table(ExecState* exec)\n"); push(@implContent, "{\n"); push(@implContent, " return getHashTableForGlobalData(exec->globalData(), &${className}Table);\n"); push(@implContent, "}\n"); } push(@implContent, "const ClassInfo $className" . "::s_info = { \"${visibleClassName}\", "); if ($hasParent) { push(@implContent, "&" . $parentClassName . "::s_info, "); } else { push(@implContent, "0, "); } if ($numAttributes > 0 && !$dataNode->extendedAttributes->{"NoStaticTables"}) { push(@implContent, "&${className}Table"); } else { push(@implContent, "0"); } if ($numAttributes > 0 && $dataNode->extendedAttributes->{"NoStaticTables"}) { push(@implContent, ", get${className}Table "); } else { push(@implContent, ", 0 "); } push(@implContent, "};\n\n"); # Get correct pass/store types respecting PODType flag my $podType = $dataNode->extendedAttributes->{"PODType"}; my $implType = $podType ? "JSSVGPODTypeWrapper<$podType> " : $implClassName; my $needsSVGContext = IsSVGTypeNeedingContextParameter($implClassName); my $parentNeedsSVGContext = ($needsSVGContext and $parentClassName =~ /SVG/); # Constructor if ($interfaceName eq "DOMWindow") { AddIncludesForType("JSDOMWindowShell"); push(@implContent, "${className}::$className(PassRefPtr<Structure> structure, PassRefPtr<$implType> impl, JSDOMWindowShell* shell)\n"); push(@implContent, " : $parentClassName(structure, impl, shell)\n"); } else { my $contextArg = ""; if ($needsSVGContext) { if ($hasParent && !$parentNeedsSVGContext) { $contextArg = ", SVGElement*"; } else { $contextArg = ", SVGElement* context"; } } push(@implContent, "${className}::$className(PassRefPtr<Structure> structure, PassRefPtr<$implType> impl$contextArg)\n"); if ($hasParent) { push(@implContent, " : $parentClassName(structure, impl" . ($parentNeedsSVGContext ? ", context" : "") . ")\n"); } else { push(@implContent, " : $parentClassName(structure)\n"); push(@implContent, " , m_context(context)\n") if $needsSVGContext; push(@implContent, " , m_impl(impl)\n"); } } push(@implContent, "{\n"); push(@implContent, "}\n\n"); # Destructor if (!$hasParent) { push(@implContent, "${className}::~$className()\n"); push(@implContent, "{\n"); if ($interfaceName eq "Node") { push(@implContent, " forgetDOMNode(m_impl->document(), m_impl.get());\n"); } else { if ($podType) { my $animatedType = $implClassName; $animatedType =~ s/SVG/SVGAnimated/; # Special case for JSSVGNumber if ($codeGenerator->IsSVGAnimatedType($animatedType) and $podType ne "float") { push(@implContent, " JSSVGDynamicPODTypeWrapperCache<$podType, $animatedType>::forgetWrapper(m_impl.get());\n"); } } push(@implContent, " forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get());\n"); } push(@implContent, "\n}\n\n"); } # Document needs a special destructor because it's a special case for caching. It needs # its own special handling rather than relying on the caching that Node normally does. if ($interfaceName eq "Document") { push(@implContent, "${className}::~$className()\n"); push(@implContent, "{\n forgetDOMObject(*Heap::heap(this)->globalData(), static_cast<${implClassName}*>(impl()));\n}\n\n"); } if (!$dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"}) { push(@implContent, "JSObject* ${className}::createPrototype(ExecState* exec)\n"); push(@implContent, "{\n"); if ($hasParent && $parentClassName ne "JSC::DOMNodeFilter") { push(@implContent, " return new (exec) ${className}Prototype(${className}Prototype::createStructure(${parentClassName}Prototype::self(exec)));\n"); } else { push(@implContent, " return new (exec) ${className}Prototype(${className}Prototype::createStructure(exec->lexicalGlobalObject()->objectPrototype()));\n"); } push(@implContent, "}\n\n"); } my $hasGetter = $numAttributes > 0 || $dataNode->extendedAttributes->{"GenerateConstructor"} || $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"} || $dataNode->extendedAttributes->{"HasNameGetter"} || $dataNode->extendedAttributes->{"HasOverridingNameGetter"}; # Attributes if ($hasGetter) { if (!$dataNode->extendedAttributes->{"InlineGetOwnPropertySlot"}) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -