WebKit Bugzilla
Attachment 370493 Details for
Bug 195925
: [WHLSL] Implement property resolver
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for committing
bug-195925-20190523004104.patch (text/plain), 222.81 KB, created by
Myles C. Maxfield
on 2019-05-23 00:41:05 PDT
(
hide
)
Description:
Patch for committing
Filename:
MIME Type:
Creator:
Myles C. Maxfield
Created:
2019-05-23 00:41:05 PDT
Size:
222.81 KB
patch
obsolete
>Subversion Revision: 245672 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index a17fe395da205d1decb0f28a541aaf411e8cf03d..118b6241a90d6d2b19c8ee3dfa989d9d3b7963ac 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,216 @@ >+2019-05-23 Myles C. Maxfield <mmaxfield@apple.com> >+ >+ [WHLSL] Implement property resolver >+ https://bugs.webkit.org/show_bug.cgi?id=195925 >+ <rdar://problem/48219643> >+ >+ Reviewed by Saam Barati and Robin Morisset. >+ >+ The property resolver is the thing that replaces dot expressions, index expressions, and >+ read-modify-write expressions with calls to getters, setters, and anders. This patch doesn't >+ fully implement the property resolver, but implements enough for simple dot expressions to >+ work. This is enough for us to be able to test most of the rest of the compiler. Index >+ expressions and read-modify-write expressions are not fully included in this patch, and will >+ be finished in a follow-up patch. >+ >+ The property resolver may introduce anonymous variables in various places. In order to do >+ this, after the property resolver runs, it will insert all these anonymous variables in the >+ beginning of the function. However, this means that entries in the VariableDeclarations >+ vector will all shift, which means VariableDeclarations have to be allocated on the heap so >+ backreferences to them stay valid. This patch moves the storage associated with these values >+ to living directly in the vector's storage to living in heap storage (via filling the vector >+ with UniqueRefs). >+ >+ This patch also adds the third concept of value-ness. We now have right values, left values, >+ and abstract left values (for things which have setters but have no address). This addition >+ is required for the analysis the property resolver performs. This concept is also present in >+ the spec. >+ >+ Test: webgpu/whlsl-dot-expressions.html >+ >+ * Modules/webgpu/WHLSL/AST/WHLSLAddressSpace.h: >+ (WebCore::WHLSL::AST::TypeAnnotation::TypeAnnotation): >+ (WebCore::WHLSL::AST::TypeAnnotation::leftAddressSpace const): >+ (WebCore::WHLSL::AST::TypeAnnotation::isRightValue const): >+ (WebCore::WHLSL::AST::TypeAnnotation::visit): >+ * Modules/webgpu/WHLSL/AST/WHLSLAssignmentExpression.h: >+ (WebCore::WHLSL::AST::AssignmentExpression::takeRight): >+ * Modules/webgpu/WHLSL/AST/WHLSLConstantExpression.h: >+ * Modules/webgpu/WHLSL/AST/WHLSLDotExpression.h: >+ * Modules/webgpu/WHLSL/AST/WHLSLEntryPointType.h: >+ * Modules/webgpu/WHLSL/AST/WHLSLExpression.h: >+ (WebCore::WHLSL::AST::Expression::maybeResolvedType): >+ (WebCore::WHLSL::AST::Expression::resolvedType): >+ (WebCore::WHLSL::AST::Expression::maybeTypeAnnotation const): >+ (WebCore::WHLSL::AST::Expression::typeAnnotation const): >+ (WebCore::WHLSL::AST::Expression::setTypeAnnotation): >+ (WebCore::WHLSL::AST::Expression::addressSpace const): Deleted. >+ (WebCore::WHLSL::AST::Expression::setAddressSpace): Deleted. >+ * Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h: >+ (WebCore::WHLSL::AST::FloatLiteral::clone const): >+ * Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h: >+ * Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.cpp: >+ (WebCore::WHLSL::AST::IntegerLiteral::valueForSelectedType const): >+ * Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h: >+ (WebCore::WHLSL::AST::IntegerLiteral::clone const): >+ * Modules/webgpu/WHLSL/AST/WHLSLMakeArrayReferenceExpression.h: >+ (WebCore::WHLSL::AST::MakeArrayReferenceExpression::MakeArrayReferenceExpression): >+ (WebCore::WHLSL::AST::MakeArrayReferenceExpression::leftValue): >+ (WebCore::WHLSL::AST::MakeArrayReferenceExpression::lValue): Deleted. >+ * Modules/webgpu/WHLSL/AST/WHLSLMakePointerExpression.h: >+ (WebCore::WHLSL::AST::MakePointerExpression::MakePointerExpression): >+ (WebCore::WHLSL::AST::MakePointerExpression::leftValue): >+ (WebCore::WHLSL::AST::MakePointerExpression::lValue): Deleted. >+ * Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h: >+ (WebCore::WHLSL::AST::NullLiteral::clone const): >+ * Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h: >+ (WebCore::WHLSL::AST::PropertyAccessExpression::possibleGetterOverloads): >+ (WebCore::WHLSL::AST::PropertyAccessExpression::possibleSetterOverloads): >+ (WebCore::WHLSL::AST::PropertyAccessExpression::possibleAnderOverloads): >+ (WebCore::WHLSL::AST::PropertyAccessExpression::getterFunction): >+ (WebCore::WHLSL::AST::PropertyAccessExpression::anderFunction): >+ (WebCore::WHLSL::AST::PropertyAccessExpression::threadAnderFunction): >+ (WebCore::WHLSL::AST::PropertyAccessExpression::setterFunction): >+ (WebCore::WHLSL::AST::PropertyAccessExpression::setPossibleGetterOverloads): >+ (WebCore::WHLSL::AST::PropertyAccessExpression::setPossibleAnderOverloads): >+ (WebCore::WHLSL::AST::PropertyAccessExpression::setPossibleSetterOverloads): >+ (WebCore::WHLSL::AST::PropertyAccessExpression::setGetterFunction): >+ (WebCore::WHLSL::AST::PropertyAccessExpression::setAnderFunction): >+ (WebCore::WHLSL::AST::PropertyAccessExpression::setThreadAnderFunction): >+ (WebCore::WHLSL::AST::PropertyAccessExpression::setSetterFunction): >+ (WebCore::WHLSL::AST::PropertyAccessExpression::takeBase): >+ (WebCore::WHLSL::AST::PropertyAccessExpression::possibleGetOverloads): Deleted. >+ (WebCore::WHLSL::AST::PropertyAccessExpression::possibleSetOverloads): Deleted. >+ (WebCore::WHLSL::AST::PropertyAccessExpression::possibleAndOverloads): Deleted. >+ (WebCore::WHLSL::AST::PropertyAccessExpression::setPossibleGetOverloads): Deleted. >+ (WebCore::WHLSL::AST::PropertyAccessExpression::setPossibleSetOverloads): Deleted. >+ (WebCore::WHLSL::AST::PropertyAccessExpression::setPossibleAndOverloads): Deleted. >+ * Modules/webgpu/WHLSL/AST/WHLSLReadModifyWriteExpression.h: >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::oldVariableReference): >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::newVariableReference): >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::leftValue): >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::takeLeftValue): >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::takeOldValue): >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::takeNewValue): >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::takeNewValueExpression): >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::takeResultExpression): >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::ReadModifyWriteExpression): >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::lValue): Deleted. >+ * Modules/webgpu/WHLSL/AST/WHLSLResolvableType.h: >+ (WebCore::WHLSL::AST::ResolvableType::maybeResolvedType const): >+ (WebCore::WHLSL::AST::ResolvableType::resolvedType const): >+ (WebCore::WHLSL::AST::ResolvableType::maybeResolvedType): >+ (WebCore::WHLSL::AST::ResolvableType::resolvedType): >+ * Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.cpp: >+ (WebCore::WHLSL::AST::ResourceSemantic::isAcceptableType const): >+ * Modules/webgpu/WHLSL/AST/WHLSLSpecializationConstantSemantic.cpp: >+ (WebCore::WHLSL::AST::SpecializationConstantSemantic::isAcceptableType const): >+ * Modules/webgpu/WHLSL/AST/WHLSLStageInOutSemantic.cpp: >+ (WebCore::WHLSL::AST::StageInOutSemantic::isAcceptableType const): >+ * Modules/webgpu/WHLSL/AST/WHLSLStructureDefinition.h: >+ (WebCore::WHLSL::AST::StructureDefinition::find): >+ * Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h: >+ (WebCore::WHLSL::AST::TypeReference::maybeResolvedType const): >+ (WebCore::WHLSL::AST::TypeReference::resolvedType const): >+ * Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.cpp: >+ (WebCore::WHLSL::AST::UnsignedIntegerLiteral::valueForSelectedType const): >+ * Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h: >+ (WebCore::WHLSL::AST::UnsignedIntegerLiteral::clone const): >+ * Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h: >+ * Modules/webgpu/WHLSL/AST/WHLSLVariableDeclarationsStatement.h: >+ (WebCore::WHLSL::AST::VariableDeclarationsStatement::VariableDeclarationsStatement): >+ (WebCore::WHLSL::AST::VariableDeclarationsStatement::variableDeclarations): >+ * Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp: >+ (WebCore::WHLSL::Metal::attributeForSemantic): >+ (WebCore::WHLSL::Metal::EntryPointScaffolding::mangledInputPath): >+ (WebCore::WHLSL::Metal::EntryPointScaffolding::unpackResourcesAndNamedBuiltIns): >+ (WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::helperTypes): >+ (WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::unpack): >+ * Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp: >+ (WebCore::WHLSL::Metal::FunctionDeclarationWriter::visit): >+ (WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit): >+ * Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp: >+ (WebCore::WHLSL::Metal::writeNativeFunction): >+ * Modules/webgpu/WHLSL/Metal/WHLSLNativeTypeWriter.cpp: >+ (WebCore::WHLSL::Metal::writeNativeType): >+ * Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp: >+ (WebCore::WHLSL::Metal::findInVector): >+ (WebCore::WHLSL::Metal::TypeNamer::visit): >+ (WebCore::WHLSL::Metal::TypeNamer::createNameNode): >+ * Modules/webgpu/WHLSL/WHLSLASTDumper.cpp: >+ (WebCore::WHLSL::ASTDumper::visit): >+ * Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp: >+ (WebCore::WHLSL::checkDuplicateFunctions): >+ * Modules/webgpu/WHLSL/WHLSLChecker.cpp: >+ (WebCore::WHLSL::resolveWithOperatorAnderIndexer): >+ (WebCore::WHLSL::resolveWithOperatorLength): >+ (WebCore::WHLSL::resolveWithReferenceComparator): >+ (WebCore::WHLSL::resolveByInstantiation): >+ (WebCore::WHLSL::checkOperatorOverload): >+ (WebCore::WHLSL::Checker::assignTypes): >+ (WebCore::WHLSL::commit): >+ (WebCore::WHLSL::Checker::visit): >+ (WebCore::WHLSL::Checker::recurseAndGetInfo): >+ (WebCore::WHLSL::Checker::getInfo): >+ (WebCore::WHLSL::Checker::assignType): >+ (WebCore::WHLSL::Checker::forwardType): >+ (WebCore::WHLSL::getUnnamedType): >+ (WebCore::WHLSL::Checker::finishVisitingPropertyAccess): Deleted. >+ (WebCore::WHLSL::Checker::recurseAndWrapBaseType): Deleted. >+ * Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.cpp: >+ (WebCore::WHLSL::Gatherer::takeEntryPointItems): >+ (WebCore::WHLSL::Gatherer::visit): >+ * Modules/webgpu/WHLSL/WHLSLInferTypes.cpp: >+ (WebCore::WHLSL::matchAndCommit): >+ (WebCore::WHLSL::commit): >+ (WebCore::WHLSL::inferTypesForCall): >+ * Modules/webgpu/WHLSL/WHLSLLiteralTypeChecker.cpp: >+ (WebCore::WHLSL::getNativeTypeDeclaration): >+ * Modules/webgpu/WHLSL/WHLSLNameResolver.cpp: >+ (WebCore::WHLSL::NameResolver::visit): >+ * Modules/webgpu/WHLSL/WHLSLParser.cpp: >+ (WebCore::WHLSL::Parser::parseParameters): >+ (WebCore::WHLSL::Parser::parseVariableDeclarations): >+ * Modules/webgpu/WHLSL/WHLSLPipelineDescriptor.h: >+ * Modules/webgpu/WHLSL/WHLSLPrepare.cpp: >+ (WebCore::WHLSL::prepareShared): >+ * Modules/webgpu/WHLSL/WHLSLPrepare.h: >+ * Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp: Added. >+ (WebCore::WHLSL::PropertyResolver::visit): >+ (WebCore::WHLSL::setterCall): >+ (WebCore::WHLSL::getterCall): >+ (WebCore::WHLSL::modify): >+ (WebCore::WHLSL::PropertyResolver::simplifyRightValue): >+ (WebCore::WHLSL::LeftValueSimplifier::visit): >+ (WebCore::WHLSL::PropertyResolver::simplifyLeftValue): >+ (WebCore::WHLSL::resolveProperties): >+ * Modules/webgpu/WHLSL/WHLSLPropertyResolver.h: Copied from Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEntryPointType.h. >+ * Modules/webgpu/WHLSL/WHLSLRecursiveTypeChecker.cpp: >+ (WebCore::WHLSL::RecursiveTypeChecker::visit): >+ * Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.cpp: >+ (WebCore::WHLSL::conversionCost): >+ * Modules/webgpu/WHLSL/WHLSLResolvingType.h: >+ (WebCore::WHLSL::ResolvingType::getUnnamedType): >+ * Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt: >+ * Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.cpp: >+ (WebCore::WHLSL::FindArrayTypes::takeArrayTypes): >+ (WebCore::WHLSL::synthesizeArrayOperatorLength): >+ * Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp: >+ (WebCore::WHLSL::FindAllTypes::takeUnnamedTypes): >+ (WebCore::WHLSL::FindAllTypes::takeNamedTypes): >+ (WebCore::WHLSL::synthesizeConstructors): >+ * Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.cpp: >+ (WebCore::WHLSL::synthesizeEnumerationFunctions): >+ * Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.cpp: >+ (WebCore::WHLSL::synthesizeStructureAccessors): >+ * Modules/webgpu/WHLSL/WHLSLVisitor.cpp: >+ (WebCore::WHLSL::Visitor::visit): >+ * Modules/webgpu/WHLSL/WHLSLVisitor.h: >+ * Sources.txt: >+ * WebCore.xcodeproj/project.pbxproj: >+ * platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm: >+ (WebCore::trySetWHLSLFunctionsForPipelineDescriptor): >+ > 2019-05-22 Myles C. Maxfield <mmaxfield@apple.com> > > font-optical-sizing applies the wrong variation value >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAddressSpace.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAddressSpace.h >index 0b204083dfcfb8275c7281af06c3171963ccc66d..425d134667851dab85c827b250cb57afdefc2dde 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAddressSpace.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAddressSpace.h >@@ -28,6 +28,7 @@ > #if ENABLE(WEBGPU) > > #include <cstdint> >+#include <wtf/Variant.h> > > namespace WebCore { > >@@ -57,6 +58,74 @@ static ALWAYS_INLINE String toString(AddressSpace addressSpace) > } > } > >+struct LeftValue { >+ AddressSpace addressSpace; >+}; >+ >+struct AbstractLeftValue { >+}; >+ >+struct RightValue { >+}; >+ >+// FIXME: https://bugs.webkit.org/show_bug.cgi?id=198158 This wrapper might not be necessary. >+class TypeAnnotation { >+public: >+ TypeAnnotation() >+#if !ASSERT_DISABLED >+ : m_empty(true) >+#endif >+ { >+ } >+ >+ TypeAnnotation(LeftValue v) >+ : m_inner(v) >+ { >+ } >+ >+ TypeAnnotation(AbstractLeftValue v) >+ : m_inner(v) >+ { >+ } >+ >+ TypeAnnotation(RightValue v) >+ : m_inner(v) >+ { >+ } >+ >+ TypeAnnotation(const TypeAnnotation&) = default; >+ TypeAnnotation(TypeAnnotation&& other) = default; >+ >+ TypeAnnotation& operator=(const TypeAnnotation&) = default; >+ TypeAnnotation& operator=(TypeAnnotation&& other) = default; >+ >+ Optional<AddressSpace> leftAddressSpace() const >+ { >+ ASSERT(!m_empty); >+ if (WTF::holds_alternative<LeftValue>(m_inner)) >+ return WTF::get<LeftValue>(m_inner).addressSpace; >+ return WTF::nullopt; >+ } >+ >+ bool isRightValue() const >+ { >+ ASSERT(!m_empty); >+ return WTF::holds_alternative<RightValue>(m_inner); >+ } >+ >+ template <typename Visitor> auto visit(const Visitor& visitor) -> decltype(WTF::visit(visitor, std::declval<Variant<LeftValue, AbstractLeftValue, RightValue>&>())) >+ { >+ ASSERT(!m_empty); >+ return WTF::visit(visitor, m_inner); >+ } >+ >+private: >+ Variant<LeftValue, AbstractLeftValue, RightValue> m_inner; >+#if !ASSERT_DISABLED >+ bool m_empty { false }; >+#endif >+}; >+ > } > > } >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAssignmentExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAssignmentExpression.h >index b121fb6c1e1d1792615d9bb0274fe23588a7f2b5..c10ccba50be74e5e2bc241d136a0a0aad5f84daa 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAssignmentExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAssignmentExpression.h >@@ -55,6 +55,7 @@ public: > > Expression& left() { return m_left; } > Expression& right() { return m_right; } >+ UniqueRef<Expression> takeRight() { return WTFMove(m_right); } > > private: > UniqueRef<Expression> m_left; >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpression.h >index 3d1ae1cec357899bd87fffd145406db329f0864a..8eeceb08b04cd28c9b8d359644fdf0ecec523306 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpression.h >@@ -41,7 +41,7 @@ namespace WHLSL { > > namespace AST { > >-// FIXME: macOS Sierra doesn't seem to support putting Variants inside Variants, >+// FIXME: https://bugs.webkit.org/show_bug.cgi?id=198158 macOS Sierra doesn't seem to support putting Variants inside Variants, > // so this is a wrapper class to make sure that doesn't happen. As soon as we don't > // have to support Sierra, this can be migrated to a Variant proper. > class ConstantExpression { >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDotExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDotExpression.h >index 040450115eb16cf15ae7d55b0616d60996cad800..3337fb98358fc5c25823afa7e2a0393f385f7641 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDotExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDotExpression.h >@@ -53,17 +53,17 @@ public: > > bool isDotExpression() const override { return true; } > >- String getFunctionName() const override >+ String getterFunctionName() const override > { > return makeString("operator.", m_fieldName); > } > >- String setFunctionName() const override >+ String setterFunctionName() const override > { > return makeString("operator.", m_fieldName, "="); > } > >- String andFunctionName() const override >+ String anderFunctionName() const override > { > return makeString("operator&.", m_fieldName); > } >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEntryPointType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEntryPointType.h >index 255e4a438190859c6740c623c7260dddfcb8c258..65f6873b46909dead4cb20262b7536e117e57d22 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEntryPointType.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEntryPointType.h >@@ -39,7 +39,6 @@ enum class EntryPointType : uint8_t { > Vertex, > Fragment, > Compute, >- // FIXME: Add an entry point type for testing > }; > > static ALWAYS_INLINE String toString(EntryPointType type) >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLExpression.h >index b7ab20ced2c453f95f1c2e3efc281fda48e5c3ad..7677b994396ba26af4e2f2eb4ebf188d95f681ad 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLExpression.h >@@ -57,7 +57,13 @@ public: > > const Lexer::Token& origin() const { return m_origin; } > >- UnnamedType* resolvedType() { return m_type ? &*m_type : nullptr; } >+ UnnamedType* maybeResolvedType() { return m_type ? &*m_type : nullptr; } >+ >+ UnnamedType& resolvedType() >+ { >+ ASSERT(m_type); >+ return *m_type; >+ } > > void setType(UniqueRef<UnnamedType>&& type) > { >@@ -65,12 +71,18 @@ public: > m_type = WTFMove(type); > } > >- const Optional<AddressSpace>& addressSpace() const { return m_addressSpace; } >+ const TypeAnnotation* maybeTypeAnnotation() const { return m_typeAnnotation ? &*m_typeAnnotation : nullptr; } >+ >+ const TypeAnnotation& typeAnnotation() const >+ { >+ ASSERT(m_typeAnnotation); >+ return *m_typeAnnotation; >+ } > >- void setAddressSpace(Optional<AddressSpace>& addressSpace) >+ void setTypeAnnotation(TypeAnnotation&& typeAnnotation) > { >- ASSERT(!m_addressSpace); >- m_addressSpace = addressSpace; >+ ASSERT(!m_typeAnnotation); >+ m_typeAnnotation = WTFMove(typeAnnotation); > } > > virtual bool isAssignmentExpression() const { return false; } >@@ -97,7 +109,7 @@ public: > private: > Lexer::Token m_origin; > Optional<UniqueRef<UnnamedType>> m_type; >- Optional<AddressSpace> m_addressSpace; >+ Optional<TypeAnnotation> m_typeAnnotation; > }; > > } // namespace AST >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h >index f1fb13feca5b2448c4341b8e7370d5fddb1185c9..11e60fc77fac16c34c61c1a97e9bc393054d6bda 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h >@@ -62,8 +62,8 @@ public: > FloatLiteral clone() const > { > FloatLiteral result(Lexer::Token(origin()), m_value); >- if (result.m_type.resolvedType()) >- result.m_type.resolve(result.m_type.resolvedType()->clone()); >+ if (auto* resolvedType = m_type.maybeResolvedType()) >+ result.m_type.resolve(resolvedType->clone()); > return result; > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h >index 347bcfec4ca42614db9baa7086b5123b2296e680..aa197b5af43bd60388c7185ad146e8ec03d32e8c 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h >@@ -52,17 +52,17 @@ public: > > bool isIndexExpression() const override { return true; } > >- String getFunctionName() const override >+ String getterFunctionName() const override > { > return "operator[]"_str; > } > >- String setFunctionName() const override >+ String setterFunctionName() const override > { > return "operator&[]"_str; > } > >- String andFunctionName() const override >+ String anderFunctionName() const override > { > return "operator[]="_str; > } >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.cpp b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.cpp >index 3cf685a5250d587bc2c768f05def63871751e0db..221e11ec29b56d5106db8ad9494b12ab127c656e 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.cpp >@@ -39,10 +39,8 @@ namespace AST { > > int64_t IntegerLiteral::valueForSelectedType() const > { >- ASSERT(m_type.resolvedType()); >- auto& typeReference = downcast<TypeReference>(*m_type.resolvedType()); >- ASSERT(typeReference.resolvedType()); >- auto& nativeTypeDeclaration = downcast<NativeTypeDeclaration>(*typeReference.resolvedType()); >+ auto& typeReference = downcast<TypeReference>(m_type.resolvedType()); >+ auto& nativeTypeDeclaration = downcast<NativeTypeDeclaration>(typeReference.resolvedType()); > return nativeTypeDeclaration.formatValueFromInteger()(m_value); > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h >index 129aebdcdbea8cb283c21ee2a1f7c4dd9b8d63fd..dbb0fa6cc35a40a71c8f341b8ad08208919afc15 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h >@@ -62,8 +62,8 @@ public: > IntegerLiteral clone() const > { > IntegerLiteral result(Lexer::Token(origin()), m_value); >- if (result.m_type.resolvedType()) >- result.m_type.resolve(result.m_type.resolvedType()->clone()); >+ if (auto* resolvedType = m_type.maybeResolvedType()) >+ result.m_type.resolve(resolvedType->clone()); > return result; > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakeArrayReferenceExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakeArrayReferenceExpression.h >index 6316f54e16326b4a483fa872e1f47bb048edf88e..770cf8ba9f252726f69c1ae6de5ea4a5b12bf77d 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakeArrayReferenceExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakeArrayReferenceExpression.h >@@ -39,9 +39,9 @@ namespace AST { > > class MakeArrayReferenceExpression : public Expression { > public: >- MakeArrayReferenceExpression(Lexer::Token&& origin, UniqueRef<Expression>&& lValue) >+ MakeArrayReferenceExpression(Lexer::Token&& origin, UniqueRef<Expression>&& leftValue) > : Expression(WTFMove(origin)) >- , m_lValue(WTFMove(lValue)) >+ , m_leftValue(WTFMove(leftValue)) > { > } > >@@ -52,10 +52,10 @@ public: > > bool isMakeArrayReferenceExpression() const override { return true; } > >- Expression& lValue() { return m_lValue; } >+ Expression& leftValue() { return m_leftValue; } > > private: >- UniqueRef<Expression> m_lValue; >+ UniqueRef<Expression> m_leftValue; > }; > > } // namespace AST >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakePointerExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakePointerExpression.h >index 7b052b6d5f2887f592df44fd9409c4fa95203aa8..34604d56aecc4b630d7a7e6f796b9c85347ce1fb 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakePointerExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakePointerExpression.h >@@ -39,9 +39,9 @@ namespace AST { > > class MakePointerExpression : public Expression { > public: >- MakePointerExpression(Lexer::Token&& origin, UniqueRef<Expression>&& lValue) >+ MakePointerExpression(Lexer::Token&& origin, UniqueRef<Expression>&& leftValue) > : Expression(WTFMove(origin)) >- , m_lValue(WTFMove(lValue)) >+ , m_leftValue(WTFMove(leftValue)) > { > } > >@@ -52,10 +52,10 @@ public: > > bool isMakePointerExpression() const override { return true; } > >- Expression& lValue() { return m_lValue; } >+ Expression& leftValue() { return m_leftValue; } > > private: >- UniqueRef<Expression> m_lValue; >+ UniqueRef<Expression> m_leftValue; > }; > > } // namespace AST >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h >index 5eb0150394ea171e6bec6792129fc94e86dc1554..3467b2f1db4ca87c6f32711fb8c0e160abe5a535 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h >@@ -59,8 +59,8 @@ public: > NullLiteral clone() const > { > auto result = NullLiteral(Lexer::Token(origin())); >- if (result.m_type.resolvedType()) >- result.m_type.resolve(result.m_type.resolvedType()->clone()); >+ if (auto* resolvedType = m_type.maybeResolvedType()) >+ result.m_type.resolve(resolvedType->clone()); > return result; > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h >index 2ec34e15d8a40e5ad2e2bf89680c21c3344c9988..8f4aa0ea119f6ce0da2ef4a783ba71f10dfc896b 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h >@@ -28,6 +28,7 @@ > #if ENABLE(WEBGPU) > > #include "WHLSLExpression.h" >+#include "WHLSLFunctionDeclaration.h" > #include "WHLSLLexer.h" > #include <wtf/UniqueRef.h> > >@@ -52,34 +53,63 @@ public: > > bool isPropertyAccessExpression() const override { return true; } > >- virtual String getFunctionName() const = 0; >- virtual String setFunctionName() const = 0; >- virtual String andFunctionName() const = 0; >+ virtual String getterFunctionName() const = 0; >+ virtual String setterFunctionName() const = 0; >+ virtual String anderFunctionName() const = 0; > >- Vector<std::reference_wrapper<FunctionDeclaration>, 1>& possibleGetOverloads() { return m_possibleGetOverloads; } >- Vector<std::reference_wrapper<FunctionDeclaration>, 1>& possibleSetOverloads() { return m_possibleSetOverloads; } >- Vector<std::reference_wrapper<FunctionDeclaration>, 1>& possibleAndOverloads() { return m_possibleAndOverloads; } >+ Vector<std::reference_wrapper<FunctionDeclaration>, 1>& possibleGetterOverloads() { return m_possibleGetterOverloads; } >+ Vector<std::reference_wrapper<FunctionDeclaration>, 1>& possibleSetterOverloads() { return m_possibleSetterOverloads; } >+ Vector<std::reference_wrapper<FunctionDeclaration>, 1>& possibleAnderOverloads() { return m_possibleAnderOverloads; } >+ FunctionDeclaration* getterFunction() { return m_getterFunction; } >+ FunctionDeclaration* anderFunction() { return m_anderFunction; } >+ FunctionDeclaration* threadAnderFunction() { return m_threadAnderFunction; } >+ FunctionDeclaration* setterFunction() { return m_setterFunction; } > >- void setPossibleGetOverloads(const Vector<std::reference_wrapper<FunctionDeclaration>, 1>& overloads) >+ void setPossibleGetterOverloads(const Vector<std::reference_wrapper<FunctionDeclaration>, 1>& overloads) > { >- m_possibleGetOverloads = overloads; >+ m_possibleGetterOverloads = overloads; > } >- void setPossibleSetOverloads(const Vector<std::reference_wrapper<FunctionDeclaration>, 1>& overloads) >+ void setPossibleAnderOverloads(const Vector<std::reference_wrapper<FunctionDeclaration>, 1>& overloads) > { >- m_possibleSetOverloads = overloads; >+ m_possibleAnderOverloads = overloads; > } >- void setPossibleAndOverloads(const Vector<std::reference_wrapper<FunctionDeclaration>, 1>& overloads) >+ void setPossibleSetterOverloads(const Vector<std::reference_wrapper<FunctionDeclaration>, 1>& overloads) > { >- m_possibleAndOverloads = overloads; >+ m_possibleSetterOverloads = overloads; >+ } >+ >+ void setGetterFunction(FunctionDeclaration* getterFunction) >+ { >+ m_getterFunction = getterFunction; >+ } >+ >+ void setAnderFunction(FunctionDeclaration* anderFunction) >+ { >+ m_anderFunction = anderFunction; >+ } >+ >+ void setThreadAnderFunction(FunctionDeclaration* threadAnderFunction) >+ { >+ m_threadAnderFunction = threadAnderFunction; >+ } >+ >+ void setSetterFunction(FunctionDeclaration* setterFunction) >+ { >+ m_setterFunction = setterFunction; > } > > Expression& base() { return m_base; } >+ UniqueRef<Expression> takeBase() { return WTFMove(m_base); } > > private: > UniqueRef<Expression> m_base; >- Vector<std::reference_wrapper<FunctionDeclaration>, 1> m_possibleGetOverloads; >- Vector<std::reference_wrapper<FunctionDeclaration>, 1> m_possibleSetOverloads; >- Vector<std::reference_wrapper<FunctionDeclaration>, 1> m_possibleAndOverloads; >+ Vector<std::reference_wrapper<FunctionDeclaration>, 1> m_possibleGetterOverloads; >+ Vector<std::reference_wrapper<FunctionDeclaration>, 1> m_possibleSetterOverloads; >+ Vector<std::reference_wrapper<FunctionDeclaration>, 1> m_possibleAnderOverloads; >+ FunctionDeclaration* m_getterFunction { nullptr }; >+ FunctionDeclaration* m_anderFunction { nullptr }; >+ FunctionDeclaration* m_threadAnderFunction { nullptr }; >+ FunctionDeclaration* m_setterFunction { nullptr }; > }; > > } // namespace AST >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReadModifyWriteExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReadModifyWriteExpression.h >index 79d8d0f708e8d0578312c81794e88edaf3487cf9..b6662a3ca07a507e8063cb492f4c743637323e66 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReadModifyWriteExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReadModifyWriteExpression.h >@@ -41,11 +41,11 @@ namespace WHLSL { > namespace AST { > > /* >- * 1. Evaluate m_lValue >+ * 1. Evaluate m_leftValue > * 2. Assign the result to m_oldValue > * 3. Evaluate m_newValueExpression > * 4. Assign the result to m_newValue >- * 5. Assign the result to m_lValue >+ * 5. Assign the result to m_leftValue > * 6. Evaluate m_resultExpression > * 7. Return the result > */ >@@ -73,38 +73,41 @@ public: > > UniqueRef<VariableReference> oldVariableReference() > { >- // The only reason we don't get use-after-frees is the fact that every instance of ReadModifyWriteExpression is allocated on the heap. > return makeUniqueRef<VariableReference>(VariableReference::wrap(m_oldValue)); > } > > UniqueRef<VariableReference> newVariableReference() > { >- // The only reason we don't get use-after-frees is the fact that every instance of ReadModifyWriteExpression is allocated on the heap. > return makeUniqueRef<VariableReference>(VariableReference::wrap(m_newValue)); > } > > bool isReadModifyWriteExpression() const override { return true; } > >- Expression& lValue() { return m_lValue; } >+ Expression& leftValue() { return m_leftValue; } > VariableDeclaration& oldValue() { return m_oldValue; } > VariableDeclaration& newValue() { return m_newValue; } > Expression* newValueExpression() { return m_newValueExpression ? &*m_newValueExpression : nullptr; } > Expression* resultExpression() { return m_resultExpression ? &*m_resultExpression : nullptr; } >+ UniqueRef<Expression> takeLeftValue() { return WTFMove(m_leftValue); } >+ UniqueRef<VariableDeclaration> takeOldValue() { return WTFMove(m_oldValue); } >+ UniqueRef<VariableDeclaration> takeNewValue() { return WTFMove(m_newValue); } >+ Optional<UniqueRef<Expression>> takeNewValueExpression() { return WTFMove(m_newValueExpression); } >+ Optional<UniqueRef<Expression>> takeResultExpression() { return WTFMove(m_resultExpression); } > > private: > template<class U, class... Args> friend UniqueRef<U> WTF::makeUniqueRef(Args&&...); > >- ReadModifyWriteExpression(Lexer::Token&& origin, UniqueRef<Expression> lValue) >+ ReadModifyWriteExpression(Lexer::Token&& origin, UniqueRef<Expression> leftValue) > : Expression(Lexer::Token(origin)) >- , m_lValue(WTFMove(lValue)) >- , m_oldValue(Lexer::Token(origin), Qualifiers(), WTF::nullopt, String(), WTF::nullopt, WTF::nullopt) >- , m_newValue(WTFMove(origin), Qualifiers(), WTF::nullopt, String(), WTF::nullopt, WTF::nullopt) >+ , m_leftValue(WTFMove(leftValue)) >+ , m_oldValue(makeUniqueRef<VariableDeclaration>(Lexer::Token(origin), Qualifiers(), WTF::nullopt, String(), WTF::nullopt, WTF::nullopt)) >+ , m_newValue(makeUniqueRef<VariableDeclaration>(WTFMove(origin), Qualifiers(), WTF::nullopt, String(), WTF::nullopt, WTF::nullopt)) > { > } > >- UniqueRef<Expression> m_lValue; >- VariableDeclaration m_oldValue; >- VariableDeclaration m_newValue; >+ UniqueRef<Expression> m_leftValue; >+ UniqueRef<VariableDeclaration> m_oldValue; >+ UniqueRef<VariableDeclaration> m_newValue; > Optional<UniqueRef<Expression>> m_newValueExpression; > Optional<UniqueRef<Expression>> m_resultExpression; > }; >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResolvableType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResolvableType.h >index f01f8664881f8804499aa9e77627ddfb17780e8f..c66d65bfbe14e6934e3921dcaeb9d254d007c1cc 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResolvableType.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResolvableType.h >@@ -58,8 +58,19 @@ public: > virtual bool canResolve(const Type&) const = 0; > virtual unsigned conversionCost(const UnnamedType&) const = 0; > >- const UnnamedType* resolvedType() const { return m_resolvedType ? &*m_resolvedType : nullptr; } >- UnnamedType* resolvedType() { return m_resolvedType ? &*m_resolvedType : nullptr; } >+ const UnnamedType* maybeResolvedType() const { return m_resolvedType ? &*m_resolvedType : nullptr; } >+ const UnnamedType& resolvedType() const >+ { >+ ASSERT(m_resolvedType); >+ return *m_resolvedType; >+ } >+ >+ UnnamedType* maybeResolvedType() { return m_resolvedType ? &*m_resolvedType : nullptr; } >+ UnnamedType& resolvedType() >+ { >+ ASSERT(m_resolvedType); >+ return *m_resolvedType; >+ } > > void resolve(UniqueRef<UnnamedType>&& type) > { >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.cpp b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.cpp >index be1a873b63680ce7ef4c0adca296eca9c91ee291..3b58c3d34ca7162c94c03123195df3077adbb49e 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.cpp >@@ -53,9 +53,8 @@ bool ResourceSemantic::isAcceptableType(const UnnamedType& unnamedType, const In > return true; > if (is<TypeReference>(unnamedType)) { > auto& typeReference = downcast<TypeReference>(unnamedType); >- ASSERT(typeReference.resolvedType()); >- if (is<NativeTypeDeclaration>(*typeReference.resolvedType())) >- return downcast<NativeTypeDeclaration>(*typeReference.resolvedType()).isTexture(); >+ if (is<NativeTypeDeclaration>(typeReference.resolvedType())) >+ return downcast<NativeTypeDeclaration>(typeReference.resolvedType()).isTexture(); > } > return false; > case Mode::Texture: >@@ -65,9 +64,8 @@ bool ResourceSemantic::isAcceptableType(const UnnamedType& unnamedType, const In > return true; > if (is<TypeReference>(unnamedType)) { > auto& typeReference = downcast<TypeReference>(unnamedType); >- ASSERT(typeReference.resolvedType()); >- if (is<NativeTypeDeclaration>(*typeReference.resolvedType())) >- return downcast<NativeTypeDeclaration>(*typeReference.resolvedType()).isTexture(); >+ if (is<NativeTypeDeclaration>(typeReference.resolvedType())) >+ return downcast<NativeTypeDeclaration>(typeReference.resolvedType()).isTexture(); > } > return false; > case Mode::Buffer: >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSpecializationConstantSemantic.cpp b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSpecializationConstantSemantic.cpp >index 7b4780951b2f7de1736ec785990a6ed53a3146dc..b8d34a8d3ac7b2b512182399dfc19da0d915e2fe 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSpecializationConstantSemantic.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSpecializationConstantSemantic.cpp >@@ -42,10 +42,9 @@ bool SpecializationConstantSemantic::isAcceptableType(const UnnamedType& unnamed > if (!is<TypeReference>(unnamedType)) > return false; > auto& typeReference = downcast<TypeReference>(unnamedType); >- ASSERT(typeReference.resolvedType()); >- if (!is<NativeTypeDeclaration>(*typeReference.resolvedType())) >+ if (!is<NativeTypeDeclaration>(typeReference.resolvedType())) > return false; >- return downcast<NativeTypeDeclaration>(*typeReference.resolvedType()).isNumber(); >+ return downcast<NativeTypeDeclaration>(typeReference.resolvedType()).isNumber(); > } > > bool SpecializationConstantSemantic::isAcceptableForShaderItemDirection(ShaderItemDirection direction, const Optional<EntryPointType>&) const >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStageInOutSemantic.cpp b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStageInOutSemantic.cpp >index bca315ab85907fb2de753c39823330d5817f2de7..7f24f55aeba8b3d8eb96b14a53cefefc5558c95d 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStageInOutSemantic.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStageInOutSemantic.cpp >@@ -47,13 +47,12 @@ bool StageInOutSemantic::isAcceptableType(const UnnamedType& unnamedType, const > if (!is<TypeReference>(unnamedType)) > return false; > auto& typeReference = downcast<TypeReference>(unnamedType); >- ASSERT(typeReference.resolvedType()); >- auto& resolvedType = *typeReference.resolvedType(); >+ auto& resolvedType = typeReference.resolvedType(); > if (is<EnumerationDefinition>(resolvedType)) > return true; > if (!is<NativeTypeDeclaration>(resolvedType)) > return false; >- auto& nativeTypeDeclaration = downcast<NativeTypeDeclaration>(*typeReference.resolvedType()); >+ auto& nativeTypeDeclaration = downcast<NativeTypeDeclaration>(typeReference.resolvedType()); > return nativeTypeDeclaration.isNumber() > || nativeTypeDeclaration.isVector() > || nativeTypeDeclaration.isMatrix(); >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStructureDefinition.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStructureDefinition.h >index 0260d4506a51cab53819331492e5d7becbdc995b..c97bad06b284fcbc786e9d99810c1d14c65ef0b0 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStructureDefinition.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStructureDefinition.h >@@ -55,7 +55,7 @@ public: > bool isStructureDefinition() const override { return true; } > > StructureElements& structureElements() { return m_structureElements; } >- StructureElement* find(String& name) >+ StructureElement* find(const String& name) > { > auto iterator = std::find_if(m_structureElements.begin(), m_structureElements.end(), [&](StructureElement& structureElement) -> bool { > return structureElement.name() == name; >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h >index bf4c5999f10b17af8d5ed7fbccd47183d0fae0cd..8492e53d536e4fb8bc175271fe9641e81a15bf10 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h >@@ -62,7 +62,12 @@ public: > > String& name() { return m_name; } > TypeArguments& typeArguments() { return m_typeArguments; } >- NamedType* resolvedType() const { return m_resolvedType; } >+ NamedType* maybeResolvedType() const { return m_resolvedType; } >+ NamedType& resolvedType() const >+ { >+ ASSERT(m_resolvedType); >+ return *m_resolvedType; >+ } > > const Type& unifyNode() const override > { >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.cpp b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.cpp >index c8f5419173820ea29e12bfdfcf98ccd28bb11ec0..06610c60d4ff385c54718754754ad7767c10e87d 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.cpp >@@ -39,10 +39,8 @@ namespace AST { > > int64_t UnsignedIntegerLiteral::valueForSelectedType() const > { >- ASSERT(m_type.resolvedType()); >- auto& typeReference = downcast<TypeReference>(*m_type.resolvedType()); >- ASSERT(typeReference.resolvedType()); >- auto& nativeTypeDeclaration = downcast<NativeTypeDeclaration>(*typeReference.resolvedType()); >+ auto& typeReference = downcast<TypeReference>(m_type.resolvedType()); >+ auto& nativeTypeDeclaration = downcast<NativeTypeDeclaration>(typeReference.resolvedType()); > return nativeTypeDeclaration.formatValueFromUnsignedInteger()(m_value); > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h >index 47b9e25b6090a6784e1ed24aeea7abcfe5f907f6..85de20c732c80f140d8a2c58cb55bafe7d160cba 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h >@@ -62,8 +62,8 @@ public: > UnsignedIntegerLiteral clone() const > { > UnsignedIntegerLiteral result(Lexer::Token(origin()), m_value); >- if (result.m_type.resolvedType()) >- result.m_type.resolve(result.m_type.resolvedType()->clone()); >+ if (auto* resolvedType = m_type.maybeResolvedType()) >+ result.m_type.resolve(resolvedType->clone()); > return result; > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h >index 19824f94054e4b3b7d7cf24f63c0119b8a63f4fb..e50aaadde788f4ed89e9c26bf44639c214049cfa 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h >@@ -79,7 +79,7 @@ private: > Optional<UniqueRef<Expression>> m_initializer; > }; > >-using VariableDeclarations = Vector<VariableDeclaration>; >+using VariableDeclarations = Vector<UniqueRef<VariableDeclaration>>; > > } // namespace AST > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclarationsStatement.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclarationsStatement.h >index e8e1fc7f5b238dbb0403e9f4027804a70a7e881c..09a02d01f49684ab963ef8725b0452d5a38edf4b 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclarationsStatement.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclarationsStatement.h >@@ -40,7 +40,7 @@ namespace AST { > > class VariableDeclarationsStatement : public Statement { > public: >- VariableDeclarationsStatement(Lexer::Token&& origin, Vector<VariableDeclaration>&& variableDeclarations) >+ VariableDeclarationsStatement(Lexer::Token&& origin, VariableDeclarations&& variableDeclarations) > : Statement(WTFMove(origin)) > , m_variableDeclarations(WTFMove(variableDeclarations)) > { >@@ -53,10 +53,10 @@ public: > > bool isVariableDeclarationsStatement() const override { return true; } > >- Vector<VariableDeclaration>& variableDeclarations() { return m_variableDeclarations; } >+ Vector<UniqueRef<VariableDeclaration>>& variableDeclarations() { return m_variableDeclarations; } > > private: >- Vector<VariableDeclaration> m_variableDeclarations; >+ VariableDeclarations m_variableDeclarations; > }; > > } // namespace AST >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp b/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp >index 624c562e51ca60c6ef8de28afebac514f2be0dbd..549d5dcf1b37afca3ce6811c45f3c9c4aba72266 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp >@@ -86,7 +86,7 @@ static String attributeForSemantic(AST::Semantic& semantic) > if (WTF::holds_alternative<AST::BuiltInSemantic>(semantic)) > return attributeForSemantic(WTF::get<AST::BuiltInSemantic>(semantic)); > auto& stageInOutSemantic = WTF::get<AST::StageInOutSemantic>(semantic); >- return makeString("[[user(", stageInOutSemantic.index(), ")]]"); >+ return makeString("[[user(user", stageInOutSemantic.index(), ")]]"); > } > > EntryPointScaffolding::EntryPointScaffolding(AST::FunctionDefinition& functionDefinition, Intrinsics& intrinsics, TypeNamer& typeNamer, EntryPointItems& entryPointItems, HashMap<Binding*, size_t>& resourceMap, Layout& layout, std::function<String()>&& generateNextVariableName) >@@ -188,9 +188,9 @@ String EntryPointScaffolding::mangledInputPath(Vector<String>& path) > bool found = false; > AST::StructureDefinition* structureDefinition = nullptr; > for (size_t i = 0; i < m_functionDefinition.parameters().size(); ++i) { >- if (m_functionDefinition.parameters()[i].name() == path[0]) { >+ if (m_functionDefinition.parameters()[i]->name() == path[0]) { > stringBuilder.append(m_parameterVariables[i]); >- auto& unifyNode = m_functionDefinition.parameters()[i].type()->unifyNode(); >+ auto& unifyNode = m_functionDefinition.parameters()[i]->type()->unifyNode(); > if (is<AST::NamedType>(unifyNode)) { > auto& namedType = downcast<AST::NamedType>(unifyNode); > if (is<AST::StructureDefinition>(namedType)) >@@ -249,7 +249,7 @@ String EntryPointScaffolding::unpackResourcesAndNamedBuiltIns() > { > StringBuilder stringBuilder; > for (size_t i = 0; i < m_functionDefinition.parameters().size(); ++i) >- stringBuilder.append(makeString(m_typeNamer.mangledNameForType(*m_functionDefinition.parameters()[i].type()), ' ', m_parameterVariables[i], ";\n")); >+ stringBuilder.append(makeString(m_typeNamer.mangledNameForType(*m_functionDefinition.parameters()[i]->type()), ' ', m_parameterVariables[i], ";\n")); > > for (size_t i = 0; i < m_layout.size(); ++i) { > auto variableName = m_namedBindGroups[i].variableName; >@@ -403,8 +403,8 @@ String FragmentEntryPointScaffolding::helperTypes() > for (auto& namedStageIn : m_namedStageIns) { > auto mangledTypeName = m_typeNamer.mangledNameForType(*m_entryPointItems.inputs[namedStageIn.indexInEntryPointItems].unnamedType); > auto elementName = namedStageIn.elementName; >- auto attributeIndex = namedStageIn.elementName; >- stringBuilder.append(makeString(" ", mangledTypeName, ' ', elementName, " [[user(", attributeIndex, ")]];\n")); >+ auto attributeIndex = namedStageIn.attributeIndex; >+ stringBuilder.append(makeString(" ", mangledTypeName, ' ', elementName, " [[user(user", attributeIndex, ")]];\n")); > } > stringBuilder.append("};\n\n"); > >@@ -446,7 +446,7 @@ String FragmentEntryPointScaffolding::unpack() > for (auto& namedStageIn : m_namedStageIns) { > auto& path = m_entryPointItems.inputs[namedStageIn.indexInEntryPointItems].path; > auto& elementName = namedStageIn.elementName; >- stringBuilder.append(makeString(mangledInputPath(path), " = ", m_stageInStructName, '.', elementName, ";\n")); >+ stringBuilder.append(makeString(mangledInputPath(path), " = ", m_stageInParameterName, '.', elementName, ";\n")); > } > > return stringBuilder.toString(); >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp b/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp >index 2fc14658616c989ca217c69282ae86dc48719f08..543f8c0be7009bc990a35be677198c617bfcd0ac 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp >@@ -107,7 +107,7 @@ void FunctionDeclarationWriter::visit(AST::FunctionDeclaration& functionDeclarat > for (size_t i = 0; i < functionDeclaration.parameters().size(); ++i) { > if (i) > m_stringBuilder.append(", "); >- m_stringBuilder.append(m_typeNamer.mangledNameForType(*functionDeclaration.parameters()[i].type())); >+ m_stringBuilder.append(m_typeNamer.mangledNameForType(*functionDeclaration.parameters()[i]->type())); > } > m_stringBuilder.append(");\n"); > } >@@ -227,7 +227,7 @@ void FunctionDefinitionWriter::visit(AST::FunctionDefinition& functionDefinition > auto parameterName = generateNextVariableName(); > auto addResult = m_variableMapping.add(¶meter, parameterName); > ASSERT_UNUSED(addResult, addResult.isNewEntry); >- m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(*parameter.type()), ' ', parameterName)); >+ m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(*parameter->type()), ' ', parameterName)); > } > m_stringBuilder.append(") {\n"); > checkErrorAndVisit(functionDefinition.block()); >@@ -282,7 +282,7 @@ void FunctionDefinitionWriter::visit(AST::EffectfulExpressionStatement& effectfu > > void FunctionDefinitionWriter::visit(AST::Fallthrough&) > { >- m_stringBuilder.append("[[clang::fallthrough]];\n"); // FIXME: Make sure this is okay. Alternatively, we could do nothing and just return here instead. >+ m_stringBuilder.append("[[clang::fallthrough]];\n"); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195808 Make sure this is okay. Alternatively, we could do nothing and just return here instead. > } > > void FunctionDefinitionWriter::visit(AST::ForLoop& forLoop) >@@ -376,41 +376,37 @@ void FunctionDefinitionWriter::visit(AST::WhileLoop& whileLoop) > > void FunctionDefinitionWriter::visit(AST::IntegerLiteral& integerLiteral) > { >- ASSERT(integerLiteral.resolvedType()); > auto variableName = generateNextVariableName(); >- auto mangledTypeName = m_typeNamer.mangledNameForType(*integerLiteral.resolvedType()); >+ auto mangledTypeName = m_typeNamer.mangledNameForType(integerLiteral.resolvedType()); > m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = static_cast<", mangledTypeName, ">(", integerLiteral.value(), ");\n")); > m_stack.append(variableName); > } > > void FunctionDefinitionWriter::visit(AST::UnsignedIntegerLiteral& unsignedIntegerLiteral) > { >- ASSERT(unsignedIntegerLiteral.resolvedType()); > auto variableName = generateNextVariableName(); >- auto mangledTypeName = m_typeNamer.mangledNameForType(*unsignedIntegerLiteral.resolvedType()); >+ auto mangledTypeName = m_typeNamer.mangledNameForType(unsignedIntegerLiteral.resolvedType()); > m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = static_cast<", mangledTypeName, ">(", unsignedIntegerLiteral.value(), ");\n")); > m_stack.append(variableName); > } > > void FunctionDefinitionWriter::visit(AST::FloatLiteral& floatLiteral) > { >- ASSERT(floatLiteral.resolvedType()); > auto variableName = generateNextVariableName(); >- auto mangledTypeName = m_typeNamer.mangledNameForType(*floatLiteral.resolvedType()); >+ auto mangledTypeName = m_typeNamer.mangledNameForType(floatLiteral.resolvedType()); > m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = static_cast<", mangledTypeName, ">(", floatLiteral.value(), ");\n")); > m_stack.append(variableName); > } > > void FunctionDefinitionWriter::visit(AST::NullLiteral& nullLiteral) > { >- ASSERT(nullLiteral.resolvedType()); >- auto& unifyNode = nullLiteral.resolvedType()->unifyNode(); >+ auto& unifyNode = nullLiteral.resolvedType().unifyNode(); > ASSERT(is<AST::UnnamedType>(unifyNode)); > auto& unnamedType = downcast<AST::UnnamedType>(unifyNode); > bool isArrayReferenceType = is<AST::ArrayReferenceType>(unnamedType); > > auto variableName = generateNextVariableName(); >- m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(*nullLiteral.resolvedType()), ' ', variableName, " = ")); >+ m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(nullLiteral.resolvedType()), ' ', variableName, " = ")); > if (isArrayReferenceType) > m_stringBuilder.append("{ nullptr, 0 }"); > else >@@ -421,20 +417,18 @@ void FunctionDefinitionWriter::visit(AST::NullLiteral& nullLiteral) > > void FunctionDefinitionWriter::visit(AST::BooleanLiteral& booleanLiteral) > { >- ASSERT(booleanLiteral.resolvedType()); > auto variableName = generateNextVariableName(); >- auto mangledTypeName = m_typeNamer.mangledNameForType(*booleanLiteral.resolvedType()); >+ auto mangledTypeName = m_typeNamer.mangledNameForType(booleanLiteral.resolvedType()); > m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = static_cast<", mangledTypeName, ">(", booleanLiteral.value() ? "true" : "false", ");\n")); > m_stack.append(variableName); > } > > void FunctionDefinitionWriter::visit(AST::EnumerationMemberLiteral& enumerationMemberLiteral) > { >- ASSERT(enumerationMemberLiteral.resolvedType()); > ASSERT(enumerationMemberLiteral.enumerationDefinition()); > ASSERT(enumerationMemberLiteral.enumerationDefinition()); > auto variableName = generateNextVariableName(); >- auto mangledTypeName = m_typeNamer.mangledNameForType(*enumerationMemberLiteral.resolvedType()); >+ auto mangledTypeName = m_typeNamer.mangledNameForType(enumerationMemberLiteral.resolvedType()); > m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = ", mangledTypeName, '.', m_typeNamer.mangledNameForEnumerationMember(*enumerationMemberLiteral.enumerationMember()), ";\n")); > m_stack.append(variableName); > } >@@ -474,7 +468,7 @@ void FunctionDefinitionWriter::visit(AST::VariableDeclaration& variableDeclarati > auto variableName = generateNextVariableName(); > auto addResult = m_variableMapping.add(&variableDeclaration, variableName); > ASSERT_UNUSED(addResult, addResult.isNewEntry); >- // FIXME: Implement qualifiers. >+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198160 Implement qualifiers. > if (variableDeclaration.initializer()) { > checkErrorAndVisit(*variableDeclaration.initializer()); > m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(*variableDeclaration.type()), ' ', variableName, " = ", m_stack.takeLast(), ";\n")); >@@ -486,12 +480,21 @@ void FunctionDefinitionWriter::visit(AST::VariableDeclaration& variableDeclarati > > void FunctionDefinitionWriter::visit(AST::AssignmentExpression& assignmentExpression) > { >+ if (is<AST::DereferenceExpression>(assignmentExpression.left())) { >+ checkErrorAndVisit(downcast<AST::DereferenceExpression>(assignmentExpression.left()).pointer()); >+ auto leftName = m_stack.takeLast(); >+ checkErrorAndVisit(assignmentExpression.right()); >+ auto rightName = m_stack.takeLast(); >+ m_stringBuilder.append(makeString('*', leftName, " = ", rightName, ";\n")); >+ m_stack.append(rightName); >+ return; >+ } > checkErrorAndVisit(assignmentExpression.left()); > auto leftName = m_stack.takeLast(); > checkErrorAndVisit(assignmentExpression.right()); > auto rightName = m_stack.takeLast(); > m_stringBuilder.append(makeString(leftName, " = ", rightName, ";\n")); >- m_stack.append(leftName); >+ m_stack.append(rightName); > } > > void FunctionDefinitionWriter::visit(AST::CallExpression& callExpression) >@@ -501,12 +504,11 @@ void FunctionDefinitionWriter::visit(AST::CallExpression& callExpression) > checkErrorAndVisit(argument); > argumentNames.append(m_stack.takeLast()); > } >- ASSERT(callExpression.resolvedType()); > ASSERT(callExpression.function()); > auto iterator = m_functionMapping.find(callExpression.function()); > ASSERT(iterator != m_functionMapping.end()); > auto variableName = generateNextVariableName(); >- m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(*callExpression.resolvedType()), ' ', variableName, " = ", iterator->value, '(')); >+ m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(callExpression.resolvedType()), ' ', variableName, " = ", iterator->value, '(')); > for (size_t i = 0; i < argumentNames.size(); ++i) { > if (i) > m_stringBuilder.append(", "); >@@ -530,9 +532,8 @@ void FunctionDefinitionWriter::visit(AST::DereferenceExpression& dereferenceExpr > { > checkErrorAndVisit(dereferenceExpression.pointer()); > auto right = m_stack.takeLast(); >- ASSERT(dereferenceExpression.resolvedType()); > auto variableName = generateNextVariableName(); >- m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(*dereferenceExpression.resolvedType()), ' ', variableName, " = *", right, ";\n")); >+ m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(dereferenceExpression.resolvedType()), ' ', variableName, " = *", right, ";\n")); > m_stack.append(variableName); > } > >@@ -542,9 +543,8 @@ void FunctionDefinitionWriter::visit(AST::LogicalExpression& logicalExpression) > auto left = m_stack.takeLast(); > checkErrorAndVisit(logicalExpression.right()); > auto right = m_stack.takeLast(); >- ASSERT(logicalExpression.resolvedType()); > auto variableName = generateNextVariableName(); >- m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(*logicalExpression.resolvedType()), ' ', variableName, " = ", left)); >+ m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(logicalExpression.resolvedType()), ' ', variableName, " = ", left)); > switch (logicalExpression.type()) { > case AST::LogicalExpression::Type::And: > m_stringBuilder.append(" && "); >@@ -562,23 +562,21 @@ void FunctionDefinitionWriter::visit(AST::LogicalNotExpression& logicalNotExpres > { > checkErrorAndVisit(logicalNotExpression.operand()); > auto operand = m_stack.takeLast(); >- ASSERT(logicalNotExpression.resolvedType()); > auto variableName = generateNextVariableName(); >- m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(*logicalNotExpression.resolvedType()), ' ', variableName, " = !", operand, ";\n")); >+ m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(logicalNotExpression.resolvedType()), ' ', variableName, " = !", operand, ";\n")); > m_stack.append(variableName); > } > > void FunctionDefinitionWriter::visit(AST::MakeArrayReferenceExpression& makeArrayReferenceExpression) > { >- checkErrorAndVisit(makeArrayReferenceExpression.lValue()); >+ checkErrorAndVisit(makeArrayReferenceExpression.leftValue()); > auto lValue = m_stack.takeLast(); >- ASSERT(makeArrayReferenceExpression.resolvedType()); > auto variableName = generateNextVariableName(); >- auto mangledTypeName = m_typeNamer.mangledNameForType(*makeArrayReferenceExpression.resolvedType()); >- if (is<AST::PointerType>(*makeArrayReferenceExpression.resolvedType())) >+ auto mangledTypeName = m_typeNamer.mangledNameForType(makeArrayReferenceExpression.resolvedType()); >+ if (is<AST::PointerType>(makeArrayReferenceExpression.resolvedType())) > m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = { ", lValue, ", 1 };\n")); >- else if (is<AST::ArrayType>(*makeArrayReferenceExpression.resolvedType())) { >- auto& arrayType = downcast<AST::ArrayType>(*makeArrayReferenceExpression.resolvedType()); >+ else if (is<AST::ArrayType>(makeArrayReferenceExpression.resolvedType())) { >+ auto& arrayType = downcast<AST::ArrayType>(makeArrayReferenceExpression.resolvedType()); > m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = { &(", lValue, "[0]), ", arrayType.numElements(), " };\n")); > } else > m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = { &", lValue, ", 1 };\n")); >@@ -587,11 +585,10 @@ void FunctionDefinitionWriter::visit(AST::MakeArrayReferenceExpression& makeArra > > void FunctionDefinitionWriter::visit(AST::MakePointerExpression& makePointerExpression) > { >- checkErrorAndVisit(makePointerExpression.lValue()); >+ checkErrorAndVisit(makePointerExpression.leftValue()); > auto lValue = m_stack.takeLast(); >- ASSERT(makePointerExpression.resolvedType()); > auto variableName = generateNextVariableName(); >- m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(*makePointerExpression.resolvedType()), ' ', variableName, " = &", lValue, ";\n")); >+ m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(makePointerExpression.resolvedType()), ' ', variableName, " = &", lValue, ";\n")); > m_stack.append(variableName); > } > >@@ -606,9 +603,8 @@ void FunctionDefinitionWriter::visit(AST::TernaryExpression& ternaryExpression) > checkErrorAndVisit(ternaryExpression.predicate()); > auto check = m_stack.takeLast(); > >- ASSERT(ternaryExpression.resolvedType()); > auto variableName = generateNextVariableName(); >- m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(*ternaryExpression.resolvedType()), ' ', variableName, ";\n")); >+ m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(ternaryExpression.resolvedType()), ' ', variableName, ";\n")); > > m_stringBuilder.append(makeString("if (", check, ") {\n")); > checkErrorAndVisit(ternaryExpression.bodyExpression()); >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp b/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp >index 6972e989050a9a1b7da811a87c33c33d1e4ed29c..38e7a71876ee850b0d758945ad1971fec91fd6e0 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp >@@ -111,8 +111,8 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara > } > > ASSERT(nativeFunctionDeclaration.parameters().size() == 1); >- auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0].type()); >- auto& parameterType = nativeFunctionDeclaration.parameters()[0].type()->unifyNode(); >+ auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type()); >+ auto& parameterType = nativeFunctionDeclaration.parameters()[0]->type()->unifyNode(); > if (is<AST::NamedType>(parameterType)) { > auto& parameterNamedType = downcast<AST::NamedType>(parameterType); > if (is<AST::NativeTypeDeclaration>(parameterNamedType)) { >@@ -134,7 +134,7 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara > > if (nativeFunctionDeclaration.name() == "operator.value") { > ASSERT(nativeFunctionDeclaration.parameters().size() == 1); >- auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0].type()); >+ auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type()); > auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type()); > stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameterName, " x) {\n")); > stringBuilder.append(makeString(" return static_cast<", metalReturnName, ">(x);\n")); >@@ -142,11 +142,12 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara > return stringBuilder.toString(); > } > >+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198077 Authors can make a struct field named "length" too. Autogenerated getters for those shouldn't take this codepath. > if (nativeFunctionDeclaration.name() == "operator.length") { > ASSERT_UNUSED(intrinsics, matches(nativeFunctionDeclaration.type(), intrinsics.uintType())); > ASSERT(nativeFunctionDeclaration.parameters().size() == 1); >- auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0].type()); >- auto& parameterType = nativeFunctionDeclaration.parameters()[0].type()->unifyNode(); >+ auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type()); >+ auto& parameterType = nativeFunctionDeclaration.parameters()[0]->type()->unifyNode(); > ASSERT(is<AST::UnnamedType>(parameterType)); > auto& unnamedParameterType = downcast<AST::UnnamedType>(parameterType); > if (is<AST::ArrayType>(unnamedParameterType)) { >@@ -165,45 +166,73 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara > } > > if (nativeFunctionDeclaration.name().startsWith("operator."_str)) { >+ auto mangledFieldName = [&](const String& fieldName) -> String { >+ auto& unifyNode = nativeFunctionDeclaration.parameters()[0]->type()->unifyNode(); >+ auto& namedType = downcast<AST::NamedType>(unifyNode); >+ if (is<AST::StructureDefinition>(namedType)) { >+ auto& structureDefinition = downcast<AST::StructureDefinition>(namedType); >+ auto* structureElement = structureDefinition.find(fieldName); >+ ASSERT(structureElement); >+ return typeNamer.mangledNameForStructureElement(*structureElement); >+ } >+ ASSERT(is<AST::NativeTypeDeclaration>(namedType)); >+ return fieldName; >+ }; >+ > if (nativeFunctionDeclaration.name().endsWith("=")) { > ASSERT(nativeFunctionDeclaration.parameters().size() == 2); >- auto metalParameter1Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0].type()); >- auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1].type()); >+ auto metalParameter1Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type()); >+ auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type()); > auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type()); > auto fieldName = nativeFunctionDeclaration.name().substring("operator."_str.length()); > fieldName = fieldName.substring(0, fieldName.length() - 1); >+ auto metalFieldName = mangledFieldName(fieldName); > stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameter1Name, " v, ", metalParameter2Name, " n) {\n")); >- stringBuilder.append(makeString(" v.", fieldName, " = n;\n")); >+ stringBuilder.append(makeString(" v.", metalFieldName, " = n;\n")); > stringBuilder.append(makeString(" return v;\n")); > stringBuilder.append("}\n"); > return stringBuilder.toString(); > } > > ASSERT(nativeFunctionDeclaration.parameters().size() == 1); >- auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0].type()); >- auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type()); > auto fieldName = nativeFunctionDeclaration.name().substring("operator."_str.length()); >+ auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type()); >+ auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type()); >+ auto metalFieldName = mangledFieldName(fieldName); > stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameterName, " v) {\n")); >- stringBuilder.append(makeString(" return v.", fieldName, ";\n")); >+ stringBuilder.append(makeString(" return v.", metalFieldName, ";\n")); > stringBuilder.append("}\n"); > return stringBuilder.toString(); > } > > if (nativeFunctionDeclaration.name().startsWith("operator&."_str)) { > ASSERT(nativeFunctionDeclaration.parameters().size() == 1); >- auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0].type()); >+ auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type()); > auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type()); > auto fieldName = nativeFunctionDeclaration.name().substring("operator&."_str.length()); >+ >+ String metalFieldName; >+ auto& unnamedType = *nativeFunctionDeclaration.parameters()[0]->type(); >+ auto& unifyNode = downcast<AST::PointerType>(unnamedType).elementType().unifyNode(); >+ auto& namedType = downcast<AST::NamedType>(unifyNode); >+ if (is<AST::StructureDefinition>(namedType)) { >+ auto& structureDefinition = downcast<AST::StructureDefinition>(namedType); >+ auto* structureElement = structureDefinition.find(fieldName); >+ ASSERT(structureElement); >+ metalFieldName = typeNamer.mangledNameForStructureElement(*structureElement); >+ } else >+ metalFieldName = fieldName; >+ > stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameterName, " v) {\n")); >- stringBuilder.append(makeString(" return &(v->", fieldName, ");\n")); >+ stringBuilder.append(makeString(" return &(v->", metalFieldName, ");\n")); > stringBuilder.append("}\n"); > return stringBuilder.toString(); > } > > if (nativeFunctionDeclaration.name() == "operator[]") { > ASSERT(nativeFunctionDeclaration.parameters().size() == 2); >- auto metalParameter1Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0].type()); >- auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1].type()); >+ auto metalParameter1Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type()); >+ auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type()); > auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type()); > stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameter1Name, " m, ", metalParameter2Name, " i) {\n")); > stringBuilder.append(makeString(" return m[i];\n")); >@@ -213,8 +242,8 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara > > if (nativeFunctionDeclaration.name() == "operator&[]") { > ASSERT(nativeFunctionDeclaration.parameters().size() == 2); >- auto metalParameter1Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0].type()); >- auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0].type()); >+ auto metalParameter1Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type()); >+ auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type()); > auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type()); > auto fieldName = nativeFunctionDeclaration.name().substring("operator&[]."_str.length()); > stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameter1Name, " v, ", metalParameter2Name, " n) {\n")); >@@ -225,9 +254,9 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara > > if (nativeFunctionDeclaration.name() == "operator[]=") { > ASSERT(nativeFunctionDeclaration.parameters().size() == 3); >- auto metalParameter1Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0].type()); >- auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1].type()); >- auto metalParameter3Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[2].type()); >+ auto metalParameter1Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type()); >+ auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type()); >+ auto metalParameter3Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[2]->type()); > auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type()); > stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameter1Name, " m, ", metalParameter2Name, " i, ", metalParameter3Name, " v) {\n")); > stringBuilder.append(makeString(" m[i] = v;\n")); >@@ -239,7 +268,7 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara > if (nativeFunctionDeclaration.isOperator()) { > if (nativeFunctionDeclaration.parameters().size() == 1) { > auto operatorName = nativeFunctionDeclaration.name().substring("operator"_str.length()); >- auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0].type()); >+ auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type()); > auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type()); > stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameterName, " x) {\n")); > stringBuilder.append(makeString(" return ", operatorName, "x;\n")); >@@ -249,8 +278,8 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara > > ASSERT(nativeFunctionDeclaration.parameters().size() == 2); > auto operatorName = nativeFunctionDeclaration.name().substring("operator"_str.length()); >- auto metalParameter1Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0].type()); >- auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1].type()); >+ auto metalParameter1Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type()); >+ auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type()); > auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type()); > stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameter1Name, " x, ", metalParameter2Name, " y) {\n")); > stringBuilder.append(makeString(" return x ", operatorName, " y;\n")); >@@ -283,7 +312,7 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara > || nativeFunctionDeclaration.name() == "asuint" > || nativeFunctionDeclaration.name() == "asfloat") { > ASSERT(nativeFunctionDeclaration.parameters().size() == 1); >- auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0].type()); >+ auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type()); > auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type()); > stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameterName, " x) {\n")); > stringBuilder.append(makeString(" return ", mapFunctionName(nativeFunctionDeclaration.name()), "(x);\n")); >@@ -293,8 +322,8 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara > > if (nativeFunctionDeclaration.name() == "pow" || nativeFunctionDeclaration.name() == "atan2") { > ASSERT(nativeFunctionDeclaration.parameters().size() == 2); >- auto metalParameter1Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0].type()); >- auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1].type()); >+ auto metalParameter1Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type()); >+ auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type()); > auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type()); > stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameter1Name, " x, ", metalParameter2Name, " y) {\n")); > stringBuilder.append(makeString(" return ", nativeFunctionDeclaration.name(), "(x, y);\n")); >@@ -336,14 +365,14 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara > if (nativeFunctionDeclaration.name().startsWith("Interlocked"_str)) { > if (nativeFunctionDeclaration.name() == "InterlockedCompareExchange") { > ASSERT(nativeFunctionDeclaration.parameters().size() == 4); >- ASSERT(is<AST::PointerType>(*nativeFunctionDeclaration.parameters()[0].type())); >- auto& firstArgumentPointer = downcast<AST::PointerType>(*nativeFunctionDeclaration.parameters()[0].type()); >+ ASSERT(is<AST::PointerType>(*nativeFunctionDeclaration.parameters()[0]->type())); >+ auto& firstArgumentPointer = downcast<AST::PointerType>(*nativeFunctionDeclaration.parameters()[0]->type()); > auto firstArgumentAddressSpace = firstArgumentPointer.addressSpace(); > auto firstArgumentPointee = typeNamer.mangledNameForType(firstArgumentPointer.elementType()); >- auto secondArgument = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1].type()); >- auto thirdArgument = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[2].type()); >- ASSERT(is<AST::PointerType>(*nativeFunctionDeclaration.parameters()[3].type())); >- auto& fourthArgumentPointer = downcast<AST::PointerType>(*nativeFunctionDeclaration.parameters()[3].type()); >+ auto secondArgument = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type()); >+ auto thirdArgument = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[2]->type()); >+ ASSERT(is<AST::PointerType>(*nativeFunctionDeclaration.parameters()[3]->type())); >+ auto& fourthArgumentPointer = downcast<AST::PointerType>(*nativeFunctionDeclaration.parameters()[3]->type()); > auto fourthArgumentAddressSpace = fourthArgumentPointer.addressSpace(); > auto fourthArgumentPointee = typeNamer.mangledNameForType(fourthArgumentPointer.elementType()); > stringBuilder.append(makeString("void ", outputFunctionName, '(', convertAddressSpace(firstArgumentAddressSpace), ' ', firstArgumentPointee, "* object, ", secondArgument, " compare, ", thirdArgument, " desired, ", convertAddressSpace(fourthArgumentAddressSpace), ' ', fourthArgumentPointee, "* out) {\n")); >@@ -354,13 +383,13 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara > } > > ASSERT(nativeFunctionDeclaration.parameters().size() == 3); >- ASSERT(is<AST::PointerType>(*nativeFunctionDeclaration.parameters()[0].type())); >- auto& firstArgumentPointer = downcast<AST::PointerType>(*nativeFunctionDeclaration.parameters()[0].type()); >+ ASSERT(is<AST::PointerType>(*nativeFunctionDeclaration.parameters()[0]->type())); >+ auto& firstArgumentPointer = downcast<AST::PointerType>(*nativeFunctionDeclaration.parameters()[0]->type()); > auto firstArgumentAddressSpace = firstArgumentPointer.addressSpace(); > auto firstArgumentPointee = typeNamer.mangledNameForType(firstArgumentPointer.elementType()); >- auto secondArgument = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1].type()); >- ASSERT(is<AST::PointerType>(*nativeFunctionDeclaration.parameters()[2].type())); >- auto& thirdArgumentPointer = downcast<AST::PointerType>(*nativeFunctionDeclaration.parameters()[2].type()); >+ auto secondArgument = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type()); >+ ASSERT(is<AST::PointerType>(*nativeFunctionDeclaration.parameters()[2]->type())); >+ auto& thirdArgumentPointer = downcast<AST::PointerType>(*nativeFunctionDeclaration.parameters()[2]->type()); > auto thirdArgumentAddressSpace = thirdArgumentPointer.addressSpace(); > auto thirdArgumentPointee = typeNamer.mangledNameForType(thirdArgumentPointer.elementType()); > auto name = atomicName(nativeFunctionDeclaration.name().substring("Interlocked"_str.length())); >@@ -450,8 +479,6 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara > notImplemented(); > } > >- // FIXME: Add all the functions that the compiler generated. >- > ASSERT_NOT_REACHED(); > return String(); > } >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeTypeWriter.cpp b/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeTypeWriter.cpp >index 45e60fd130d9ba00a34f8ac9dd0f1ab54705246b..4948d9dd3767fb8fcd6a841686e9aaab92873052 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeTypeWriter.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeTypeWriter.cpp >@@ -243,7 +243,7 @@ String writeNativeType(AST::NativeTypeDeclaration& nativeTypeDeclaration) > ASSERT(typeReference->name() == "float4"); > return "float"_str; > })(); >- // FIXME: Specify the second template argument to Metal texture types. >+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195813 Specify the second template argument to Metal texture types. > return makeString(prefix, '<', innerType, '>'); > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp b/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp >index a3c810b016f923140b46a44f8ab5c74254f5af54..41138dda6f8bb3ca22f46cd621003823f804c956 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp >@@ -179,9 +179,8 @@ static Vector<UniqueRef<BaseTypeNameNode>>::iterator findInVector(AST::UnnamedTy > { > return std::find_if(types.begin(), types.end(), [&](BaseTypeNameNode& baseTypeNameNode) -> bool { > if (is<AST::TypeReference>(unnamedType) && is<ReferenceTypeNameNode>(baseTypeNameNode)) { >- auto* resolvedType = downcast<AST::TypeReference>(unnamedType).resolvedType(); >- ASSERT(resolvedType); >- return resolvedType == &downcast<ReferenceTypeNameNode>(baseTypeNameNode).namedType(); >+ auto& resolvedType = downcast<AST::TypeReference>(unnamedType).resolvedType(); >+ return &resolvedType == &downcast<ReferenceTypeNameNode>(baseTypeNameNode).namedType(); > } > if (is<AST::PointerType>(unnamedType) && is<PointerTypeNameNode>(baseTypeNameNode)) > return downcast<AST::PointerType>(unnamedType).addressSpace() == downcast<PointerTypeNameNode>(baseTypeNameNode).addressSpace(); >@@ -278,8 +277,7 @@ void TypeNamer::visit(AST::TypeDefinition& typeDefinition) > > void TypeNamer::visit(AST::Expression& expression) > { >- ASSERT(expression.resolvedType()); >- insert(*expression.resolvedType(), m_trie); >+ insert(expression.resolvedType(), m_trie); > Visitor::visit(expression); > } > >@@ -298,8 +296,7 @@ UniqueRef<BaseTypeNameNode> TypeNamer::createNameNode(AST::UnnamedType& unnamedT > { > if (is<AST::TypeReference>(unnamedType)) { > auto& typeReference = downcast<AST::TypeReference>(unnamedType); >- ASSERT(typeReference.resolvedType()); >- return makeUniqueRef<ReferenceTypeNameNode>(parent, generateNextTypeName(), *typeReference.resolvedType()); >+ return makeUniqueRef<ReferenceTypeNameNode>(parent, generateNextTypeName(), typeReference.resolvedType()); > } > if (is<AST::PointerType>(unnamedType)) { > auto& pointerType = downcast<AST::PointerType>(unnamedType); >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.cpp >index ae31048b8a601f1af29869f938ca2ed4e0bbe73b..5fac87406ba72d317b1e7f157538496977f1552b 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.cpp >@@ -590,13 +590,13 @@ void ASTDumper::visit(AST::LogicalNotExpression& logicalNotExpression) > void ASTDumper::visit(AST::MakeArrayReferenceExpression& makeArrayReferenceExpression) > { > m_out.print("@"); >- visit(makeArrayReferenceExpression.lValue()); >+ visit(makeArrayReferenceExpression.leftValue()); > } > > void ASTDumper::visit(AST::MakePointerExpression& makePointerExpression) > { > m_out.print("&"); >- visit(makePointerExpression.lValue()); >+ visit(makePointerExpression.leftValue()); > } > > void ASTDumper::visit(AST::ReadModifyWriteExpression& readModifyWriteExpression) >@@ -607,7 +607,7 @@ void ASTDumper::visit(AST::ReadModifyWriteExpression& readModifyWriteExpression) > m_out.print("("); > visit(oldVariable.get()); > m_out.print(" = "); >- visit(readModifyWriteExpression.lValue()); >+ visit(readModifyWriteExpression.leftValue()); > m_out.print(", "); > > visit(newVariable.get()); >@@ -615,7 +615,7 @@ void ASTDumper::visit(AST::ReadModifyWriteExpression& readModifyWriteExpression) > visit(*readModifyWriteExpression.newValueExpression()); > m_out.print(", "); > >- visit(readModifyWriteExpression.lValue()); >+ visit(readModifyWriteExpression.leftValue()); > m_out.print(" = "); > visit(newVariable.get()); > m_out.print(", "); >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp >index 61d348af1596623af4c3798ea9981f94a4169565..f8c6876e7d227d7e2192c4262b9bb17ccba969e7 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp >@@ -70,7 +70,7 @@ bool checkDuplicateFunctions(const Program& program) > continue; > bool same = true; > for (size_t k = 0; k < functions[i].get().parameters().size(); ++k) { >- if (!matches(*functions[i].get().parameters()[k].type(), *functions[j].get().parameters()[k].type())) { >+ if (!matches(*functions[i].get().parameters()[k]->type(), *functions[j].get().parameters()[k]->type())) { > same = false; > break; > } >@@ -80,10 +80,11 @@ bool checkDuplicateFunctions(const Program& program) > } > > if (functions[i].get().name() == "operator&[]" && functions[i].get().parameters().size() == 2 >- && is<AST::ArrayReferenceType>(static_cast<const AST::UnnamedType&>(*functions[i].get().parameters()[0].type()))) { >- auto& type = static_cast<const AST::UnnamedType&>(*functions[i].get().parameters()[1].type()); >+ && is<AST::ArrayReferenceType>(static_cast<const AST::UnnamedType&>(*functions[i].get().parameters()[0]->type()))) { >+ auto& type = static_cast<const AST::UnnamedType&>(*functions[i].get().parameters()[1]->type()); > if (is<AST::TypeReference>(type)) { >- if (auto* resolvedType = downcast<AST::TypeReference>(type).resolvedType()) { >+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198161 Shouldn't we already know whether the types have been resolved by now? >+ if (auto* resolvedType = downcast<AST::TypeReference>(type).maybeResolvedType()) { > if (is<AST::NativeTypeDeclaration>(*resolvedType)) { > auto& nativeTypeDeclaration = downcast<AST::NativeTypeDeclaration>(*resolvedType); > if (nativeTypeDeclaration.name() == "uint") >@@ -92,14 +93,14 @@ bool checkDuplicateFunctions(const Program& program) > } > } > } else if (functions[i].get().name() == "operator.length" && functions[i].get().parameters().size() == 1 >- && (is<AST::ArrayReferenceType>(static_cast<const AST::UnnamedType&>(*functions[i].get().parameters()[0].type())) >- || is<AST::ArrayType>(static_cast<const AST::UnnamedType&>(*functions[i].get().parameters()[0].type())))) >+ && (is<AST::ArrayReferenceType>(static_cast<const AST::UnnamedType&>(*functions[i].get().parameters()[0]->type())) >+ || is<AST::ArrayType>(static_cast<const AST::UnnamedType&>(*functions[i].get().parameters()[0]->type())))) > return false; > else if (functions[i].get().name() == "operator==" > && functions[i].get().parameters().size() == 2 >- && is<AST::ReferenceType>(static_cast<const AST::UnnamedType&>(*functions[i].get().parameters()[0].type())) >- && is<AST::ReferenceType>(static_cast<const AST::UnnamedType&>(*functions[i].get().parameters()[1].type())) >- && matches(*functions[i].get().parameters()[0].type(), *functions[i].get().parameters()[1].type())) >+ && is<AST::ReferenceType>(static_cast<const AST::UnnamedType&>(*functions[i].get().parameters()[0]->type())) >+ && is<AST::ReferenceType>(static_cast<const AST::UnnamedType&>(*functions[i].get().parameters()[1]->type())) >+ && matches(*functions[i].get().parameters()[0]->type(), *functions[i].get().parameters()[1]->type())) > return false; > } > return true; >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp >index 1365f26d123482000ee74047cb321e802b2c6083..6ab503a071fb97430d39b6fe1737f463ca3795e0 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp >@@ -112,8 +112,7 @@ public: > > void visit(AST::TypeReference& typeReference) override > { >- ASSERT(typeReference.resolvedType()); >- checkErrorAndVisit(*typeReference.resolvedType()); >+ checkErrorAndVisit(typeReference.resolvedType()); > } > }; > >@@ -122,8 +121,8 @@ static AST::NativeFunctionDeclaration resolveWithOperatorAnderIndexer(AST::CallE > const bool isOperator = true; > auto returnType = makeUniqueRef<AST::PointerType>(Lexer::Token(callExpression.origin()), firstArgument.addressSpace(), firstArgument.elementType().clone()); > AST::VariableDeclarations parameters; >- parameters.append(AST::VariableDeclaration(Lexer::Token(callExpression.origin()), AST::Qualifiers(), { firstArgument.clone() }, String(), WTF::nullopt, WTF::nullopt)); >- parameters.append(AST::VariableDeclaration(Lexer::Token(callExpression.origin()), AST::Qualifiers(), { AST::TypeReference::wrap(Lexer::Token(callExpression.origin()), intrinsics.uintType()) }, String(), WTF::nullopt, WTF::nullopt)); >+ parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(callExpression.origin()), AST::Qualifiers(), firstArgument.clone(), String(), WTF::nullopt, WTF::nullopt)); >+ parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(callExpression.origin()), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(AST::TypeReference::wrap(Lexer::Token(callExpression.origin()), intrinsics.uintType())), String(), WTF::nullopt, WTF::nullopt)); > return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(callExpression.origin()), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator&[]", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator)); > } > >@@ -132,7 +131,7 @@ static AST::NativeFunctionDeclaration resolveWithOperatorLength(AST::CallExpress > const bool isOperator = true; > auto returnType = AST::TypeReference::wrap(Lexer::Token(callExpression.origin()), intrinsics.uintType()); > AST::VariableDeclarations parameters; >- parameters.append(AST::VariableDeclaration(Lexer::Token(callExpression.origin()), AST::Qualifiers(), { firstArgument.clone() }, String(), WTF::nullopt, WTF::nullopt)); >+ parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(callExpression.origin()), AST::Qualifiers(), firstArgument.clone(), String(), WTF::nullopt, WTF::nullopt)); > return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(callExpression.origin()), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator.length", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator)); > } > >@@ -147,14 +146,14 @@ static AST::NativeFunctionDeclaration resolveWithReferenceComparator(AST::CallEx > return unnamedType->clone(); > }, [&](RefPtr<ResolvableTypeReference>&) -> UniqueRef<AST::UnnamedType> { > // We encountered "null == null". >- // FIXME: This can probably be generalized, using the "preferred type" infrastructure used by generic literals >+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198162 This can probably be generalized, using the "preferred type" infrastructure used by generic literals > ASSERT_NOT_REACHED(); > return AST::TypeReference::wrap(Lexer::Token(callExpression.origin()), intrinsics.intType()); > })); > })); > AST::VariableDeclarations parameters; >- parameters.append(AST::VariableDeclaration(Lexer::Token(callExpression.origin()), AST::Qualifiers(), { argumentType->clone() }, String(), WTF::nullopt, WTF::nullopt)); >- parameters.append(AST::VariableDeclaration(Lexer::Token(callExpression.origin()), AST::Qualifiers(), { WTFMove(argumentType) }, String(), WTF::nullopt, WTF::nullopt)); >+ parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(callExpression.origin()), AST::Qualifiers(), argumentType->clone(), String(), WTF::nullopt, WTF::nullopt)); >+ parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(callExpression.origin()), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(WTFMove(argumentType)), String(), WTF::nullopt, WTF::nullopt)); > return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(callExpression.origin()), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator==", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator)); > } > >@@ -203,8 +202,8 @@ static Optional<AST::NativeFunctionDeclaration> resolveByInstantiation(AST::Call > auto rightAcceptability = acceptability(types[1].get()); > bool success = false; > if (leftAcceptability == Acceptability::Yes && rightAcceptability == Acceptability::Yes) { >- auto& unnamedType1 = types[0].get().getUnnamedType(); >- auto& unnamedType2 = types[1].get().getUnnamedType(); >+ auto& unnamedType1 = *types[0].get().getUnnamedType(); >+ auto& unnamedType2 = *types[1].get().getUnnamedType(); > success = matches(unnamedType1, unnamedType2); > } else if ((leftAcceptability == Acceptability::Maybe && rightAcceptability == Acceptability::Yes) > || (leftAcceptability == Acceptability::Yes && rightAcceptability == Acceptability::Maybe)) >@@ -304,14 +303,14 @@ static bool checkOperatorOverload(const AST::FunctionDefinition& functionDefinit > size_t numExpectedParameters = kind == CheckKind::Index ? 2 : 1; > if (functionDefinition.parameters().size() != numExpectedParameters) > return false; >- auto& firstParameterUnifyNode = (*functionDefinition.parameters()[0].type())->unifyNode(); >+ auto& firstParameterUnifyNode = (*functionDefinition.parameters()[0]->type())->unifyNode(); > if (is<AST::UnnamedType>(firstParameterUnifyNode)) { > auto& unnamedType = downcast<AST::UnnamedType>(firstParameterUnifyNode); > if (is<AST::PointerType>(unnamedType) || is<AST::ArrayReferenceType>(unnamedType) || is<AST::ArrayType>(unnamedType)) > return false; > } > if (kind == CheckKind::Index) { >- auto& secondParameterUnifyNode = (*functionDefinition.parameters()[1].type())->unifyNode(); >+ auto& secondParameterUnifyNode = (*functionDefinition.parameters()[1]->type())->unifyNode(); > if (!is<AST::NamedType>(secondParameterUnifyNode)) > return false; > auto& namedType = downcast<AST::NamedType>(secondParameterUnifyNode); >@@ -328,14 +327,14 @@ static bool checkOperatorOverload(const AST::FunctionDefinition& functionDefinit > size_t numExpectedParameters = kind == CheckKind::Index ? 3 : 2; > if (functionDefinition.parameters().size() != numExpectedParameters) > return false; >- auto& firstArgumentUnifyNode = (*functionDefinition.parameters()[0].type())->unifyNode(); >+ auto& firstArgumentUnifyNode = (*functionDefinition.parameters()[0]->type())->unifyNode(); > if (is<AST::UnnamedType>(firstArgumentUnifyNode)) { > auto& unnamedType = downcast<AST::UnnamedType>(firstArgumentUnifyNode); > if (is<AST::PointerType>(unnamedType) || is<AST::ArrayReferenceType>(unnamedType) || is<AST::ArrayType>(unnamedType)) > return false; > } > if (kind == CheckKind::Index) { >- auto& secondParameterUnifyNode = (*functionDefinition.parameters()[1].type())->unifyNode(); >+ auto& secondParameterUnifyNode = (*functionDefinition.parameters()[1]->type())->unifyNode(); > if (!is<AST::NamedType>(secondParameterUnifyNode)) > return false; > auto& namedType = downcast<AST::NamedType>(secondParameterUnifyNode); >@@ -345,9 +344,9 @@ static bool checkOperatorOverload(const AST::FunctionDefinition& functionDefinit > if (!nativeTypeDeclaration.isInt()) > return false; > } >- if (!matches(functionDefinition.type(), *functionDefinition.parameters()[0].type())) >+ if (!matches(functionDefinition.type(), *functionDefinition.parameters()[0]->type())) > return false; >- auto& valueType = *functionDefinition.parameters()[numExpectedParameters - 1].type(); >+ auto& valueType = *functionDefinition.parameters()[numExpectedParameters - 1]->type(); > auto getterName = functionDefinition.name().substring(0, functionDefinition.name().length() - 1); > auto* getterFuncs = nameContext.getFunctions(getterName); > if (!getterFuncs) >@@ -355,7 +354,7 @@ static bool checkOperatorOverload(const AST::FunctionDefinition& functionDefinit > Vector<ResolvingType> argumentTypes; > Vector<std::reference_wrapper<ResolvingType>> argumentTypeReferences; > for (size_t i = 0; i < numExpectedParameters - 1; ++i) >- argumentTypes.append((*functionDefinition.parameters()[0].type())->clone()); >+ argumentTypes.append((*functionDefinition.parameters()[0]->type())->clone()); > for (auto& argumentType : argumentTypes) > argumentTypeReferences.append(argumentType); > auto* overload = resolveFunctionOverloadImpl(*getterFuncs, argumentTypeReferences, nullptr); >@@ -378,7 +377,7 @@ static bool checkOperatorOverload(const AST::FunctionDefinition& functionDefinit > return false; > } > { >- auto& unifyNode = (*functionDefinition.parameters()[0].type())->unifyNode(); >+ auto& unifyNode = (*functionDefinition.parameters()[0]->type())->unifyNode(); > if (!is<AST::UnnamedType>(unifyNode)) > return false; > auto& unnamedType = downcast<AST::UnnamedType>(unifyNode); >@@ -392,7 +391,7 @@ static bool checkOperatorOverload(const AST::FunctionDefinition& functionDefinit > return true; > if (functionDefinition.name() == "operator++" || functionDefinition.name() == "operator--") { > return functionDefinition.parameters().size() == 1 >- && matches(*functionDefinition.parameters()[0].type(), functionDefinition.type()); >+ && matches(*functionDefinition.parameters()[0]->type(), functionDefinition.type()); > } > if (functionDefinition.name() == "operator+" || functionDefinition.name() == "operator-") > return functionDefinition.parameters().size() == 1 || functionDefinition.parameters().size() == 2; >@@ -447,19 +446,18 @@ public: > > private: > bool checkShaderType(const AST::FunctionDefinition&); >- void finishVisitingPropertyAccess(AST::PropertyAccessExpression&, AST::UnnamedType& wrappedBaseType, AST::UnnamedType* extraArgumentType = nullptr); > bool isBoolType(ResolvingType&); > struct RecurseInfo { > ResolvingType& resolvingType; >- Optional<AST::AddressSpace>& addressSpace; >+ AST::TypeAnnotation& typeAnnotation; > }; >- Optional<RecurseInfo> recurseAndGetInfo(AST::Expression&, bool requiresLValue = false); >- Optional<RecurseInfo> getInfo(AST::Expression&, bool requiresLValue = false); >+ Optional<RecurseInfo> recurseAndGetInfo(AST::Expression&, bool requiresLeftValue = false); >+ Optional<RecurseInfo> getInfo(AST::Expression&, bool requiresLeftValue = false); > Optional<UniqueRef<AST::UnnamedType>> recurseAndWrapBaseType(AST::PropertyAccessExpression&); > bool recurseAndRequireBoolType(AST::Expression&); >- void assignType(AST::Expression&, UniqueRef<AST::UnnamedType>&&, Optional<AST::AddressSpace> = WTF::nullopt); >- void assignType(AST::Expression&, RefPtr<ResolvableTypeReference>&&, Optional<AST::AddressSpace> = WTF::nullopt); >- void forwardType(AST::Expression&, ResolvingType&, Optional<AST::AddressSpace> = WTF::nullopt); >+ void assignType(AST::Expression&, UniqueRef<AST::UnnamedType>&&, AST::TypeAnnotation); >+ void assignType(AST::Expression&, RefPtr<ResolvableTypeReference>&&, AST::TypeAnnotation); >+ void forwardType(AST::Expression&, ResolvingType&, AST::TypeAnnotation); > > void visit(AST::FunctionDefinition&) override; > void visit(AST::EnumerationDefinition&) override; >@@ -494,7 +492,7 @@ private: > void visit(AST::CallExpression&) override; > > HashMap<AST::Expression*, ResolvingType> m_typeMap; >- HashMap<AST::Expression*, Optional<AST::AddressSpace>> m_addressSpaceMap; >+ HashMap<AST::Expression*, AST::TypeAnnotation> m_typeAnnotations; > HashSet<String> m_vertexEntryPoints; > HashSet<String> m_fragmentEntryPoints; > HashSet<String> m_computeEntryPoints; >@@ -527,19 +525,19 @@ bool Checker::assignTypes() > keyValuePair.key->setType(unnamedType->clone()); > return true; > }, [&](RefPtr<ResolvableTypeReference>& resolvableTypeReference) -> bool { >- if (!resolvableTypeReference->resolvableType().resolvedType()) { >+ if (!resolvableTypeReference->resolvableType().maybeResolvedType()) { > if (!static_cast<bool>(commit(resolvableTypeReference->resolvableType()))) > return false; > } >- keyValuePair.key->setType(resolvableTypeReference->resolvableType().resolvedType()->clone()); >+ keyValuePair.key->setType(resolvableTypeReference->resolvableType().resolvedType().clone()); > return true; > })); > if (!success) > return false; > } > >- for (auto& keyValuePair : m_addressSpaceMap) >- keyValuePair.key->setAddressSpace(keyValuePair.value); >+ for (auto& keyValuePair : m_typeAnnotations) >+ keyValuePair.key->setTypeAnnotation(WTFMove(keyValuePair.value)); > return true; > } > >@@ -621,6 +619,17 @@ static Optional<UniqueRef<AST::UnnamedType>> matchAndCommit(ResolvingType& resol > })); > } > >+static Optional<UniqueRef<AST::UnnamedType>> commit(ResolvingType& resolvingType) >+{ >+ return resolvingType.visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& unnamedType) -> Optional<UniqueRef<AST::UnnamedType>> { >+ return unnamedType->clone(); >+ }, [&](RefPtr<ResolvableTypeReference>& resolvableTypeReference) -> Optional<UniqueRef<AST::UnnamedType>> { >+ if (!resolvableTypeReference->resolvableType().maybeResolvedType()) >+ return commit(resolvableTypeReference->resolvableType()); >+ return resolvableTypeReference->resolvableType().resolvedType().clone(); >+ })); >+} >+ > void Checker::visit(AST::EnumerationDefinition& enumerationDefinition) > { > auto* baseType = ([&]() -> AST::NativeTypeDeclaration* { >@@ -643,18 +652,22 @@ void Checker::visit(AST::EnumerationDefinition& enumerationDefinition) > > auto enumerationMembers = enumerationDefinition.enumerationMembers(); > >- for (auto& member : enumerationMembers) { >- if (!member.get().value()) >- continue; >- >+ auto matchAndCommitMember = [&](AST::EnumerationMember& member) -> bool { > bool success = false; >- member.get().value()->visit(WTF::makeVisitor([&](AST::Expression& value) { >+ member.value()->visit(WTF::makeVisitor([&](AST::Expression& value) { > auto valueInfo = recurseAndGetInfo(value); > if (!valueInfo) > return; > success = static_cast<bool>(matchAndCommit(valueInfo->resolvingType, *baseType)); > })); >- if (!success) { >+ return success; >+ }; >+ >+ for (auto& member : enumerationMembers) { >+ if (!member.get().value()) >+ continue; >+ >+ if (!matchAndCommitMember(member)) { > setError(); > return; > } >@@ -679,6 +692,12 @@ void Checker::visit(AST::EnumerationDefinition& enumerationDefinition) > } > ASSERT(nextValue >= std::numeric_limits<int>::min()); > member.get().setValue(AST::ConstantExpression(AST::IntegerLiteral(Lexer::Token(member.get().origin()), static_cast<int>(nextValue)))); >+ >+ if (!matchAndCommitMember(member)) { >+ setError(); >+ return; >+ } >+ > nextValue = baseType->successor()(nextValue); > } > } >@@ -722,32 +741,32 @@ void Checker::visit(AST::EnumerationDefinition& enumerationDefinition) > > void Checker::visit(AST::TypeReference& typeReference) > { >- ASSERT(typeReference.resolvedType()); >+ ASSERT(typeReference.maybeResolvedType()); > > for (auto& typeArgument : typeReference.typeArguments()) > checkErrorAndVisit(typeArgument); > } > >-auto Checker::recurseAndGetInfo(AST::Expression& expression, bool requiresLValue) -> Optional<RecurseInfo> >+auto Checker::recurseAndGetInfo(AST::Expression& expression, bool requiresLeftValue) -> Optional<RecurseInfo> > { > Visitor::visit(expression); > if (error()) > return WTF::nullopt; >- return getInfo(expression, requiresLValue); >+ return getInfo(expression, requiresLeftValue); > } > >-auto Checker::getInfo(AST::Expression& expression, bool requiresLValue) -> Optional<RecurseInfo> >+auto Checker::getInfo(AST::Expression& expression, bool requiresLeftValue) -> Optional<RecurseInfo> > { > auto typeIterator = m_typeMap.find(&expression); > ASSERT(typeIterator != m_typeMap.end()); > >- auto addressSpaceIterator = m_addressSpaceMap.find(&expression); >- ASSERT(addressSpaceIterator != m_addressSpaceMap.end()); >- if (requiresLValue && !addressSpaceIterator->value) { >+ auto typeAnnotationIterator = m_typeAnnotations.find(&expression); >+ ASSERT(typeAnnotationIterator != m_typeAnnotations.end()); >+ if (requiresLeftValue && typeAnnotationIterator->value.isRightValue()) { > setError(); > return WTF::nullopt; > } >- return {{ typeIterator->value, addressSpaceIterator->value }}; >+ return {{ typeIterator->value, typeAnnotationIterator->value }}; > } > > void Checker::visit(AST::VariableDeclaration& variableDeclaration) >@@ -767,20 +786,33 @@ void Checker::visit(AST::VariableDeclaration& variableDeclaration) > } > } > >-void Checker::assignType(AST::Expression& expression, UniqueRef<AST::UnnamedType>&& unnamedType, Optional<AST::AddressSpace> addressSpace) >+void Checker::assignType(AST::Expression& expression, UniqueRef<AST::UnnamedType>&& unnamedType, AST::TypeAnnotation typeAnnotation = AST::RightValue()) > { > auto addResult = m_typeMap.add(&expression, WTFMove(unnamedType)); > ASSERT_UNUSED(addResult, addResult.isNewEntry); >- auto addressSpaceAddResult = m_addressSpaceMap.add(&expression, addressSpace); >- ASSERT_UNUSED(addressSpaceAddResult, addressSpaceAddResult.isNewEntry); >+ auto typeAnnotationAddResult = m_typeAnnotations.add(&expression, WTFMove(typeAnnotation)); >+ ASSERT_UNUSED(typeAnnotationAddResult, typeAnnotationAddResult.isNewEntry); > } > >-void Checker::assignType(AST::Expression& expression, RefPtr<ResolvableTypeReference>&& resolvableTypeReference, Optional<AST::AddressSpace> addressSpace) >+void Checker::assignType(AST::Expression& expression, RefPtr<ResolvableTypeReference>&& resolvableTypeReference, AST::TypeAnnotation typeAnnotation = AST::RightValue()) > { > auto addResult = m_typeMap.add(&expression, WTFMove(resolvableTypeReference)); > ASSERT_UNUSED(addResult, addResult.isNewEntry); >- auto addressSpaceAddResult = m_addressSpaceMap.add(&expression, addressSpace); >- ASSERT_UNUSED(addressSpaceAddResult, addressSpaceAddResult.isNewEntry); >+ auto typeAnnotationAddResult = m_typeAnnotations.add(&expression, WTFMove(typeAnnotation)); >+ ASSERT_UNUSED(typeAnnotationAddResult, typeAnnotationAddResult.isNewEntry); >+} >+ >+void Checker::forwardType(AST::Expression& expression, ResolvingType& resolvingType, AST::TypeAnnotation typeAnnotation = AST::RightValue()) >+{ >+ resolvingType.visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& result) { >+ auto addResult = m_typeMap.add(&expression, result->clone()); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ }, [&](RefPtr<ResolvableTypeReference>& result) { >+ auto addResult = m_typeMap.add(&expression, result.copyRef()); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ })); >+ auto typeAnnotationAddResult = m_typeAnnotations.add(&expression, WTFMove(typeAnnotation)); >+ ASSERT_UNUSED(typeAnnotationAddResult, typeAnnotationAddResult.isNewEntry); > } > > void Checker::visit(AST::AssignmentExpression& assignmentExpression) >@@ -789,6 +821,11 @@ void Checker::visit(AST::AssignmentExpression& assignmentExpression) > if (!leftInfo) > return; > >+ if (leftInfo->typeAnnotation.isRightValue()) { >+ setError(); >+ return; >+ } >+ > auto rightInfo = recurseAndGetInfo(assignmentExpression.right()); > if (!rightInfo) > return; >@@ -802,32 +839,19 @@ void Checker::visit(AST::AssignmentExpression& assignmentExpression) > assignType(assignmentExpression, WTFMove(*resultType)); > } > >-void Checker::forwardType(AST::Expression& expression, ResolvingType& resolvingType, Optional<AST::AddressSpace> addressSpace) >-{ >- resolvingType.visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& result) { >- auto addResult = m_typeMap.add(&expression, result->clone()); >- ASSERT_UNUSED(addResult, addResult.isNewEntry); >- }, [&](RefPtr<ResolvableTypeReference>& result) { >- auto addResult = m_typeMap.add(&expression, result.copyRef()); >- ASSERT_UNUSED(addResult, addResult.isNewEntry); >- })); >- auto addressSpaceAddResult = m_addressSpaceMap.add(&expression, addressSpace); >- ASSERT_UNUSED(addressSpaceAddResult, addressSpaceAddResult.isNewEntry); >-} >- > void Checker::visit(AST::ReadModifyWriteExpression& readModifyWriteExpression) > { >- auto lValueInfo = recurseAndGetInfo(readModifyWriteExpression.lValue(), true); >- if (!lValueInfo) >+ auto leftValueInfo = recurseAndGetInfo(readModifyWriteExpression.leftValue(), true); >+ if (!leftValueInfo) > return; > >- // FIXME: Figure out what to do with the ReadModifyWriteExpression's AnonymousVariables. >+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198166 Figure out what to do with the ReadModifyWriteExpression's AnonymousVariables. > > auto newValueInfo = recurseAndGetInfo(*readModifyWriteExpression.newValueExpression()); > if (!newValueInfo) > return; > >- if (!matchAndCommit(lValueInfo->resolvingType, newValueInfo->resolvingType)) { >+ if (!matchAndCommit(leftValueInfo->resolvingType, newValueInfo->resolvingType)) { > setError(); > return; > } >@@ -845,7 +869,7 @@ static AST::UnnamedType* getUnnamedType(ResolvingType& resolvingType) > return &type; > }, [](RefPtr<ResolvableTypeReference>& type) -> AST::UnnamedType* { > // FIXME: If the type isn't committed, should we just commit() it now? >- return type->resolvableType().resolvedType(); >+ return type->resolvableType().maybeResolvedType(); > })); > } > >@@ -873,231 +897,162 @@ void Checker::visit(AST::DereferenceExpression& dereferenceExpression) > return; > } > >- assignType(dereferenceExpression, pointerType->clone(), pointerType->addressSpace()); >+ assignType(dereferenceExpression, pointerType->clone(), AST::LeftValue { pointerType->addressSpace() }); > } > > void Checker::visit(AST::MakePointerExpression& makePointerExpression) > { >- auto lValueInfo = recurseAndGetInfo(makePointerExpression.lValue(), true); >- if (!lValueInfo) >+ auto leftValueInfo = recurseAndGetInfo(makePointerExpression.leftValue(), true); >+ if (!leftValueInfo) > return; > >- auto* lValueType = getUnnamedType(lValueInfo->resolvingType); >- if (!lValueType) { >+ auto leftAddressSpace = leftValueInfo->typeAnnotation.leftAddressSpace(); >+ if (!leftAddressSpace) { > setError(); > return; > } > >- assignType(makePointerExpression, makeUniqueRef<AST::PointerType>(Lexer::Token(makePointerExpression.origin()), *lValueInfo->addressSpace, lValueType->clone())); >+ auto* leftValueType = getUnnamedType(leftValueInfo->resolvingType); >+ if (!leftValueType) { >+ setError(); >+ return; >+ } >+ >+ assignType(makePointerExpression, makeUniqueRef<AST::PointerType>(Lexer::Token(makePointerExpression.origin()), *leftAddressSpace, leftValueType->clone())); > } > > void Checker::visit(AST::MakeArrayReferenceExpression& makeArrayReferenceExpression) > { >- auto lValueInfo = recurseAndGetInfo(makeArrayReferenceExpression.lValue()); >- if (!lValueInfo) >+ auto leftValueInfo = recurseAndGetInfo(makeArrayReferenceExpression.leftValue()); >+ if (!leftValueInfo) > return; > >- auto* lValueType = getUnnamedType(lValueInfo->resolvingType); >- if (!lValueType) { >+ auto* leftValueType = getUnnamedType(leftValueInfo->resolvingType); >+ if (!leftValueType) { > setError(); > return; > } > >- auto& unifyNode = lValueType->unifyNode(); >+ auto& unifyNode = leftValueType->unifyNode(); > if (is<AST::UnnamedType>(unifyNode)) { > auto& unnamedType = downcast<AST::UnnamedType>(unifyNode); > if (is<AST::PointerType>(unnamedType)) { > auto& pointerType = downcast<AST::PointerType>(unnamedType); >- // FIXME: Save the fact that we're not targetting the item; we're targetting the item's inner element. >+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198163 Save the fact that we're not targetting the item; we're targetting the item's inner element. > assignType(makeArrayReferenceExpression, makeUniqueRef<AST::ArrayReferenceType>(Lexer::Token(makeArrayReferenceExpression.origin()), pointerType.addressSpace(), pointerType.elementType().clone())); > return; > } > >- if (!lValueInfo->addressSpace) { >+ auto leftAddressSpace = leftValueInfo->typeAnnotation.leftAddressSpace(); >+ if (!leftAddressSpace) { > setError(); > return; > } > > if (is<AST::ArrayType>(unnamedType)) { > auto& arrayType = downcast<AST::ArrayType>(unnamedType); >- // FIXME: Save the number of elements. >- assignType(makeArrayReferenceExpression, makeUniqueRef<AST::ArrayReferenceType>(Lexer::Token(makeArrayReferenceExpression.origin()), *lValueInfo->addressSpace, arrayType.type().clone())); >+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198163 Save the number of elements. >+ assignType(makeArrayReferenceExpression, makeUniqueRef<AST::ArrayReferenceType>(Lexer::Token(makeArrayReferenceExpression.origin()), *leftAddressSpace, arrayType.type().clone())); > return; > } > } > >- if (!lValueInfo->addressSpace) { >+ auto leftAddressSpace = leftValueInfo->typeAnnotation.leftAddressSpace(); >+ if (!leftAddressSpace) { > setError(); > return; > } > >- assignType(makeArrayReferenceExpression, makeUniqueRef<AST::ArrayReferenceType>(Lexer::Token(makeArrayReferenceExpression.origin()), *lValueInfo->addressSpace, lValueType->clone())); >+ assignType(makeArrayReferenceExpression, makeUniqueRef<AST::ArrayReferenceType>(Lexer::Token(makeArrayReferenceExpression.origin()), *leftAddressSpace, leftValueType->clone())); > } > >-void Checker::finishVisitingPropertyAccess(AST::PropertyAccessExpression& propertyAccessExpression, AST::UnnamedType& wrappedBaseType, AST::UnnamedType* extraArgumentType) >+void Checker::visit(AST::DotExpression& dotExpression) > { >- using OverloadResolution = std::tuple<AST::FunctionDeclaration*, AST::UnnamedType*>; >- >- AST::FunctionDeclaration* getFunction; >- AST::UnnamedType* getReturnType; >- std::tie(getFunction, getReturnType) = ([&]() -> OverloadResolution { >- ResolvingType getArgumentType1(wrappedBaseType.clone()); >- Optional<ResolvingType> getArgumentType2; >- if (extraArgumentType) >- getArgumentType2 = ResolvingType(extraArgumentType->clone()); >- >- Vector<std::reference_wrapper<ResolvingType>> getArgumentTypes; >- getArgumentTypes.append(getArgumentType1); >- if (getArgumentType2) >- getArgumentTypes.append(*getArgumentType2); >- >- auto* getFunction = resolveFunctionOverloadImpl(propertyAccessExpression.possibleGetOverloads(), getArgumentTypes, nullptr); >- if (!getFunction) >- return std::make_pair(nullptr, nullptr); >- return std::make_pair(getFunction, &getFunction->type()); >- })(); >+ auto baseInfo = recurseAndGetInfo(dotExpression.base()); >+ if (!baseInfo) >+ return; >+ auto baseUnnamedType = commit(baseInfo->resolvingType); >+ if (!baseUnnamedType) >+ return; > >- AST::FunctionDeclaration* andFunction; >- AST::UnnamedType* andReturnType; >- std::tie(andFunction, andReturnType) = ([&]() -> OverloadResolution { >- auto computeAndArgumentType = [&](AST::UnnamedType& unnamedType) -> Optional<ResolvingType> { >- if (is<AST::ArrayReferenceType>(unnamedType)) >- return { unnamedType.clone() }; >- if (is<AST::ArrayType>(unnamedType)) >- return { ResolvingType(makeUniqueRef<AST::ArrayReferenceType>(Lexer::Token(propertyAccessExpression.origin()), AST::AddressSpace::Thread, downcast<AST::ArrayType>(unnamedType).type().clone())) }; >- if (is<AST::PointerType>(unnamedType)) >- return WTF::nullopt; >- return { ResolvingType(makeUniqueRef<AST::PointerType>(Lexer::Token(propertyAccessExpression.origin()), AST::AddressSpace::Thread, downcast<AST::TypeReference>(unnamedType).clone())) }; >- }; >- auto computeAndReturnType = [&](AST::UnnamedType& unnamedType) -> AST::UnnamedType* { >- if (is<AST::PointerType>(unnamedType)) >- return &downcast<AST::PointerType>(unnamedType).elementType(); >- return nullptr; >- }; >+ AST::FunctionDeclaration* getterFunction = nullptr; >+ AST::UnnamedType* getterReturnType = nullptr; >+ { >+ Vector<std::reference_wrapper<ResolvingType>> getterArgumentTypes { baseInfo->resolvingType }; >+ getterFunction = resolveFunctionOverloadImpl(dotExpression.possibleGetterOverloads(), getterArgumentTypes, nullptr); >+ if (getterFunction) >+ getterReturnType = &getterFunction->type(); >+ } > >- auto andArgumentType1 = computeAndArgumentType(wrappedBaseType); >- if (!andArgumentType1) >- return std::make_pair(nullptr, nullptr); >- Optional<ResolvingType> andArgumentType2; >- if (extraArgumentType) >- andArgumentType2 = ResolvingType(extraArgumentType->clone()); >- >- Vector<std::reference_wrapper<ResolvingType>> andArgumentTypes; >- andArgumentTypes.append(*andArgumentType1); >- if (andArgumentType2) >- andArgumentTypes.append(*andArgumentType2); >- >- auto* andFunction = resolveFunctionOverloadImpl(propertyAccessExpression.possibleAndOverloads(), andArgumentTypes, nullptr); >- if (!andFunction) >- return std::make_pair(nullptr, nullptr); >- return std::make_pair(andFunction, computeAndReturnType(andFunction->type())); >- })(); >+ AST::FunctionDeclaration* anderFunction = nullptr; >+ AST::UnnamedType* anderReturnType = nullptr; >+ if (auto leftAddressSpace = baseInfo->typeAnnotation.leftAddressSpace()) { >+ auto argumentType = makeUniqueRef<AST::PointerType>(Lexer::Token(dotExpression.origin()), *leftAddressSpace, baseUnnamedType->get().clone()); >+ Vector<std::reference_wrapper<ResolvingType>> anderArgumentTypes { baseInfo->resolvingType }; >+ anderFunction = resolveFunctionOverloadImpl(dotExpression.possibleAnderOverloads(), anderArgumentTypes, nullptr); >+ if (anderFunction) >+ anderReturnType = &downcast<AST::PointerType>(anderFunction->type()).elementType(); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198164 Enforce the return of anders will always be a pointer >+ } > >- if (!getReturnType && !andReturnType) { >- setError(); >- return; >+ AST::FunctionDeclaration* threadAnderFunction = nullptr; >+ AST::UnnamedType* threadAnderReturnType = nullptr; >+ { >+ auto argumentType = makeUniqueRef<AST::PointerType>(Lexer::Token(dotExpression.origin()), AST::AddressSpace::Thread, baseUnnamedType->get().clone()); >+ Vector<std::reference_wrapper<ResolvingType>> threadAnderArgumentTypes { baseInfo->resolvingType }; >+ threadAnderFunction = resolveFunctionOverloadImpl(dotExpression.possibleAnderOverloads(), threadAnderArgumentTypes, nullptr); >+ if (threadAnderFunction) >+ threadAnderReturnType = &downcast<AST::PointerType>(threadAnderFunction->type()).elementType(); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198164 Enforce the return of anders will always be a pointer > } > >- if (getReturnType && andReturnType && !matches(*getReturnType, *andReturnType)) { >+ if (!getterFunction && !anderFunction) { > setError(); > return; > } >- >- AST::FunctionDeclaration* setFunction; >- AST::UnnamedType* setReturnType; >- std::tie(setFunction, setReturnType) = ([&]() -> OverloadResolution { >- ResolvingType setArgument1Type(wrappedBaseType.clone()); >- Optional<ResolvingType> setArgumentType2; >- if (extraArgumentType) >- setArgumentType2 = ResolvingType(extraArgumentType->clone()); >- ResolvingType setArgument3Type(getReturnType ? getReturnType->clone() : andReturnType->clone()); >- >- Vector<std::reference_wrapper<ResolvingType>> setArgumentTypes; >- setArgumentTypes.append(setArgument1Type); >- if (setArgumentType2) >- setArgumentTypes.append(*setArgumentType2); >- setArgumentTypes.append(setArgument3Type); >- >- auto* setFunction = resolveFunctionOverloadImpl(propertyAccessExpression.possibleSetOverloads(), setArgumentTypes, nullptr); >- if (!setFunction) >- return std::make_pair(nullptr, nullptr); >- return std::make_pair(setFunction, &setFunction->type()); >- })(); >- >- if (setFunction) { >- if (!matches(setFunction->type(), wrappedBaseType)) { >- setError(); >- return; >- } >+ if (getterFunction && anderFunction) { >+ setError(); >+ return; > } >- >- Optional<AST::AddressSpace> addressSpace; >- if (getReturnType || andReturnType) { >- // FIXME: The reference compiler has "else if (!node.base.isLValue && !baseType.isArrayRef)", >- // but I don't understand why it exists. I haven't written it here, and I'll investigate >- // if we can remove it from the reference compiler. >- if (is<AST::ReferenceType>(wrappedBaseType)) >- addressSpace = downcast<AST::ReferenceType>(wrappedBaseType).addressSpace(); >- else { >- auto addressSpaceIterator = m_addressSpaceMap.find(&propertyAccessExpression.base()); >- ASSERT(addressSpaceIterator != m_addressSpaceMap.end()); >- if (addressSpaceIterator->value) >- addressSpace = *addressSpaceIterator->value; >- else { >- setError(); >- return; >- } >- } >+ if (anderFunction && threadAnderFunction && !matches(*anderReturnType, *threadAnderReturnType)) { >+ setError(); >+ return; > } > >- // FIXME: Generate the call expressions >+ AST::UnnamedType* fieldType = getterReturnType ? getterReturnType : anderReturnType; > >- assignType(propertyAccessExpression, getReturnType ? getReturnType->clone() : andReturnType->clone(), addressSpace); >-} >- >-Optional<UniqueRef<AST::UnnamedType>> Checker::recurseAndWrapBaseType(AST::PropertyAccessExpression& propertyAccessExpression) >-{ >- auto baseInfo = recurseAndGetInfo(propertyAccessExpression.base()); >- if (!baseInfo) >- return WTF::nullopt; >- >- auto* baseType = getUnnamedType(baseInfo->resolvingType); >- if (!baseType) { >- setError(); >- return WTF::nullopt; >+ AST::FunctionDeclaration* setterFunction = nullptr; >+ AST::UnnamedType* setterReturnType = nullptr; >+ { >+ ResolvingType fieldResolvingType(fieldType->clone()); >+ Vector<std::reference_wrapper<ResolvingType>> setterArgumentTypes { baseInfo->resolvingType, fieldResolvingType }; >+ setterFunction = resolveFunctionOverloadImpl(dotExpression.possibleSetterOverloads(), setterArgumentTypes, nullptr); >+ if (setterFunction) >+ setterReturnType = &setterFunction->type(); > } >- auto& baseUnifyNode = baseType->unifyNode(); >- if (is<AST::UnnamedType>(baseUnifyNode)) >- return downcast<AST::UnnamedType>(baseUnifyNode).clone(); >- ASSERT(is<AST::NamedType>(baseUnifyNode)); >- return { AST::TypeReference::wrap(Lexer::Token(propertyAccessExpression.origin()), downcast<AST::NamedType>(baseUnifyNode)) }; >-} > >-void Checker::visit(AST::DotExpression& dotExpression) >-{ >- auto baseType = recurseAndWrapBaseType(dotExpression); >- if (!baseType) >+ if (setterFunction && anderFunction) { >+ setError(); > return; >+ } > >- finishVisitingPropertyAccess(dotExpression, *baseType); >+ dotExpression.setGetterFunction(getterFunction); >+ dotExpression.setAnderFunction(anderFunction); >+ dotExpression.setThreadAnderFunction(threadAnderFunction); >+ dotExpression.setSetterFunction(setterFunction); >+ >+ AST::TypeAnnotation typeAnnotation = AST::RightValue(); >+ if (auto leftAddressSpace = baseInfo->typeAnnotation.leftAddressSpace()) { >+ if (anderFunction) >+ typeAnnotation = AST::LeftValue { *leftAddressSpace }; >+ else if (setterFunction) >+ typeAnnotation = AST::AbstractLeftValue(); >+ } else if (!baseInfo->typeAnnotation.isRightValue() && (setterFunction || anderFunction)) >+ typeAnnotation = AST::AbstractLeftValue(); >+ assignType(dotExpression, fieldType->clone(), WTFMove(typeAnnotation)); > } > >-void Checker::visit(AST::IndexExpression& indexExpression) >+void Checker::visit(AST::IndexExpression&) > { >- auto baseType = recurseAndWrapBaseType(indexExpression); >- if (!baseType) >- return; >- >- auto indexInfo = recurseAndGetInfo(indexExpression.indexExpression()); >- if (!indexInfo) >- return; >- auto indexExpressionType = getUnnamedType(indexInfo->resolvingType); >- if (!indexExpressionType) { >- setError(); >- return; >- } >- >- finishVisitingPropertyAccess(indexExpression, WTFMove(*baseType), indexExpressionType); >+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198163 Implement this. > } > > void Checker::visit(AST::VariableReference& variableReference) >@@ -1105,10 +1060,10 @@ void Checker::visit(AST::VariableReference& variableReference) > ASSERT(variableReference.variable()); > ASSERT(variableReference.variable()->type()); > >- Optional<AST::AddressSpace> addressSpace; >- if (!variableReference.variable()->isAnonymous()) >- addressSpace = AST::AddressSpace::Thread; >- assignType(variableReference, variableReference.variable()->type()->clone(), addressSpace); >+ AST::TypeAnnotation typeAnnotation = AST::RightValue(); >+ if (!variableReference.variable()->isAnonymous()) // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198166 This doesn't seem right. >+ typeAnnotation = AST::LeftValue { AST::AddressSpace::Thread }; >+ assignType(variableReference, variableReference.variable()->type()->clone(), WTFMove(typeAnnotation)); > } > > void Checker::visit(AST::Return& returnStatement) >@@ -1407,7 +1362,7 @@ void Checker::visit(AST::CommaExpression& commaExpression) > if (error()) > return; > auto lastInfo = getInfo(commaExpression.list().last()); >- forwardType(commaExpression, lastInfo->resolvingType); >+ forwardType(commaExpression, lastInfo->resolvingType, lastInfo->typeAnnotation); > } > > void Checker::visit(AST::TernaryExpression& ternaryExpression) >@@ -1456,7 +1411,7 @@ void Checker::visit(AST::CallExpression& callExpression) > } > > for (size_t i = 0; i < function->parameters().size(); ++i) { >- if (!matchAndCommit(types[i].get(), *function->parameters()[i].type())) { >+ if (!matchAndCommit(types[i].get(), *function->parameters()[i]->type())) { > setError(); > return; > } >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.cpp >index a32af5ef36f25c33a3251a695edecaae97775c47..996dd84072d529fa08980d2c1a098ba165bfe54b 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.cpp >@@ -60,7 +60,7 @@ public: > m_currentSemantic = nullptr; > } > >- Vector<EntryPointItem>&& takeEntryPointItems() >+ Vector<EntryPointItem> takeEntryPointItems() > { > return WTFMove(m_entryPointItems); > } >@@ -111,10 +111,9 @@ public: > > void visit(AST::TypeReference& typeReference) > { >- ASSERT(typeReference.resolvedType()); > m_typeReferences.append(typeReference); > auto depth = m_typeReferences.size(); >- checkErrorAndVisit(*typeReference.resolvedType()); >+ checkErrorAndVisit(typeReference.resolvedType()); > ASSERT_UNUSED(depth, m_typeReferences.size() == depth); > m_typeReferences.removeLast(); > } >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.cpp >index 2fcc6f139de84a32c4c707ca060b9be1b42fd3e0..66993626b45ac61417ed9ae95514b1e54c746591 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.cpp >@@ -104,7 +104,7 @@ bool matches(const AST::UnnamedType& unnamedType, const AST::NamedType& other) > > static Optional<UniqueRef<AST::UnnamedType>> matchAndCommit(AST::Type& unifyNode, AST::ResolvableType& resolvableType) > { >- ASSERT(!resolvableType.resolvedType()); >+ ASSERT(!resolvableType.maybeResolvedType()); > if (!resolvableType.canResolve(unifyNode)) > return WTF::nullopt; > if (is<AST::NamedType>(unifyNode)) { >@@ -131,8 +131,8 @@ Optional<UniqueRef<AST::UnnamedType>> matchAndCommit(AST::NamedType& namedType, > > Optional<UniqueRef<AST::UnnamedType>> matchAndCommit(AST::ResolvableType& resolvableType1, AST::ResolvableType& resolvableType2) > { >- ASSERT(!resolvableType1.resolvedType()); >- ASSERT(!resolvableType2.resolvedType()); >+ ASSERT(!resolvableType1.maybeResolvedType()); >+ ASSERT(!resolvableType2.maybeResolvedType()); > if (is<AST::FloatLiteralType>(resolvableType1) && is<AST::FloatLiteralType>(resolvableType2)) { > resolvableType1.resolve(downcast<AST::FloatLiteralType>(resolvableType1).preferredType().clone()); > resolvableType2.resolve(downcast<AST::FloatLiteralType>(resolvableType2).preferredType().clone()); >@@ -157,7 +157,7 @@ Optional<UniqueRef<AST::UnnamedType>> matchAndCommit(AST::ResolvableType& resolv > > Optional<UniqueRef<AST::UnnamedType>> commit(AST::ResolvableType& resolvableType) > { >- ASSERT(!resolvableType.resolvedType()); >+ ASSERT(!resolvableType.maybeResolvedType()); > if (is<AST::FloatLiteralType>(resolvableType)) { > auto& floatLiteralType = downcast<AST::FloatLiteralType>(resolvableType); > resolvableType.resolve(floatLiteralType.preferredType().clone()); >@@ -227,9 +227,9 @@ bool inferTypesForCall(AST::FunctionDeclaration& possibleFunction, Vector<std::r > return false; > for (size_t i = 0; i < possibleFunction.parameters().size(); ++i) { > auto success = argumentTypes[i].get().visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& unnamedType) -> bool { >- return matches(*possibleFunction.parameters()[i].type(), unnamedType); >+ return matches(*possibleFunction.parameters()[i]->type(), unnamedType); > }, [&](RefPtr<ResolvableTypeReference>& resolvableTypeReference) -> bool { >- return resolvableTypeReference->resolvableType().canResolve(possibleFunction.parameters()[i].type()->unifyNode()); >+ return resolvableTypeReference->resolvableType().canResolve(possibleFunction.parameters()[i]->type()->unifyNode()); > })); > if (!success) > return false; >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLLiteralTypeChecker.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLLiteralTypeChecker.cpp >index b4e5f439dad2a5e54f14e503f4585c1f1742aae1..9a7b22d05f552d962b6141584c4750ec61ff77e8 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLLiteralTypeChecker.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLLiteralTypeChecker.cpp >@@ -42,15 +42,12 @@ namespace WHLSL { > #if !ASSERT_DISABLED > static AST::NativeTypeDeclaration* getNativeTypeDeclaration(AST::ResolvableType& resolvableType) > { >- if (!resolvableType.resolvedType()) >+ if (!is<AST::TypeReference>(resolvableType.resolvedType())) > return nullptr; >- if (!is<AST::TypeReference>(*resolvableType.resolvedType())) >+ auto& typeReference = downcast<AST::TypeReference>(resolvableType.resolvedType()); >+ if (!is<AST::NativeTypeDeclaration>(typeReference.resolvedType())) > return nullptr; >- auto& typeReference = downcast<AST::TypeReference>(*resolvableType.resolvedType()); >- ASSERT(typeReference.resolvedType()); >- if (!is<AST::NativeTypeDeclaration>(*typeReference.resolvedType())) >- return nullptr; >- return &downcast<AST::NativeTypeDeclaration>(*typeReference.resolvedType()); >+ return &downcast<AST::NativeTypeDeclaration>(typeReference.resolvedType()); > } > > class LiteralTypeChecker : public Visitor { >@@ -79,7 +76,7 @@ private: > > void visit(AST::NullLiteralType& nullLiteralType) override > { >- ASSERT(nullLiteralType.resolvedType()); >+ ASSERT(nullLiteralType.maybeResolvedType()); > } > }; > #endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.cpp >index 05350e0dc985ecb390f586f0a34d2a6ecfedca32..ec8cf77fc52d794440d4d55a73407ceb3ff4654e 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.cpp >@@ -65,7 +65,7 @@ void NameResolver::visit(AST::TypeReference& typeReference) > } > > Visitor::visit(typeReference); >- if (typeReference.resolvedType()) >+ if (typeReference.maybeResolvedType()) // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198161 Shouldn't we know by now whether the type has been resolved or not? > return; > > auto* candidates = m_nameContext.getTypes(typeReference.name()); >@@ -174,12 +174,12 @@ void NameResolver::visit(AST::Return& returnStatement) > > void NameResolver::visit(AST::PropertyAccessExpression& propertyAccessExpression) > { >- if (auto* getFunctions = m_nameContext.getFunctions(propertyAccessExpression.getFunctionName())) >- propertyAccessExpression.setPossibleGetOverloads(*getFunctions); >- if (auto* setFunctions = m_nameContext.getFunctions(propertyAccessExpression.setFunctionName())) >- propertyAccessExpression.setPossibleSetOverloads(*setFunctions); >- if (auto* andFunctions = m_nameContext.getFunctions(propertyAccessExpression.andFunctionName())) >- propertyAccessExpression.setPossibleAndOverloads(*andFunctions); >+ if (auto* getterFunctions = m_nameContext.getFunctions(propertyAccessExpression.getterFunctionName())) >+ propertyAccessExpression.setPossibleGetterOverloads(*getterFunctions); >+ if (auto* setterFunctions = m_nameContext.getFunctions(propertyAccessExpression.setterFunctionName())) >+ propertyAccessExpression.setPossibleSetterOverloads(*setterFunctions); >+ if (auto* anderFunctions = m_nameContext.getFunctions(propertyAccessExpression.anderFunctionName())) >+ propertyAccessExpression.setPossibleAnderOverloads(*anderFunctions); > Visitor::visit(propertyAccessExpression); > } > >@@ -196,10 +196,10 @@ void NameResolver::visit(AST::DotExpression& dotExpression) > if (auto* member = enumerationDefinition.memberByName(memberName)) { > static_assert(sizeof(AST::EnumerationMemberLiteral) <= sizeof(AST::DotExpression), "Dot expressions need to be able to become EnumerationMemberLiterals without updating backreferences"); > Lexer::Token origin = dotExpression.origin(); >- // FIXME: Perhaps do this with variants or a Rewriter instead. >+ void* location = &dotExpression; > dotExpression.~DotExpression(); > auto enumerationMemberLiteral = AST::EnumerationMemberLiteral::wrap(WTFMove(origin), WTFMove(baseName), WTFMove(memberName), enumerationDefinition, *member); >- new (&dotExpression) AST::EnumerationMemberLiteral(WTFMove(enumerationMemberLiteral)); >+ new (location) AST::EnumerationMemberLiteral(WTFMove(enumerationMemberLiteral)); > return; > } > setError(); >@@ -254,7 +254,7 @@ void NameResolver::visit(AST::EnumerationMemberLiteral& enumerationMemberLiteral > setError(); > } > >-// FIXME: Make sure all the names have been resolved. >+// FIXME: https://bugs.webkit.org/show_bug.cgi?id=198167 Make sure all the names have been resolved. > > bool resolveNamesInTypes(Program& program, NameResolver& nameResolver) > { >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp >index 2efcfb11e2a50d56637b984acd1f14ce147c11af..94752382fbee2fa8b22fb4796b13218827765f5a 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp >@@ -38,7 +38,7 @@ namespace WebCore { > > namespace WHLSL { > >-// FIXME: Return a better error code from this, and report it to JavaScript. >+// FIXME: https://bugs.webkit.org/show_bug.cgi?id=195682 Return a better error code from this, and report it to JavaScript. > auto Parser::parse(Program& program, StringView stringView, Mode mode) -> Optional<Error> > { > m_lexer = Lexer(stringView); >@@ -1083,13 +1083,13 @@ auto Parser::parseParameters() -> Expected<AST::VariableDeclarations, Error> > auto firstParameter = parseParameter(); > if (!firstParameter) > return Unexpected<Error>(firstParameter.error()); >- parameters.append(WTFMove(*firstParameter)); >+ parameters.append(makeUniqueRef<AST::VariableDeclaration>(WTFMove(*firstParameter))); > > while (tryType(Lexer::Token::Type::Comma)) { > auto parameter = parseParameter(); > if (!parameter) > return Unexpected<Error>(parameter.error()); >- parameters.append(WTFMove(*parameter)); >+ parameters.append(makeUniqueRef<AST::VariableDeclaration>(WTFMove(*parameter))); > } > > auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); >@@ -1568,14 +1568,14 @@ auto Parser::parseVariableDeclarations() -> Expected<AST::VariableDeclarationsSt > if (!firstVariableDeclaration) > return Unexpected<Error>(firstVariableDeclaration.error()); > >- Vector<AST::VariableDeclaration> result; >- result.append(WTFMove(*firstVariableDeclaration)); >+ Vector<UniqueRef<AST::VariableDeclaration>> result; >+ result.append(makeUniqueRef<AST::VariableDeclaration>(WTFMove(*firstVariableDeclaration))); > > while (tryType(Lexer::Token::Type::Comma)) { > auto variableDeclaration = parseVariableDeclaration((*type)->clone()); > if (!variableDeclaration) > return Unexpected<Error>(variableDeclaration.error()); >- result.append(WTFMove(*variableDeclaration)); >+ result.append(makeUniqueRef<AST::VariableDeclaration>(WTFMove(*variableDeclaration))); > } > > return AST::VariableDeclarationsStatement(WTFMove(*origin), WTFMove(result)); >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPipelineDescriptor.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPipelineDescriptor.h >index 5c4c0b5bb921b06bb5ccd7065fc5b6b408276d2d..5bb666591937454b8eb0c38a37dd2b9ebc2093aa 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPipelineDescriptor.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPipelineDescriptor.h >@@ -118,7 +118,7 @@ enum class BindingType : uint8_t { > Sampler, > Texture, > StorageBuffer, >- // FIXME: Add the dynamic types >+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198168 Add the dynamic types > }; > > struct Binding { >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp >index 58ad42ae683704a1807d62eb28d76d3c09f38619..95f7ca2a5e715f52fd5badcd7a467febba8d230b 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp >@@ -38,6 +38,7 @@ > #include "WHLSLNameResolver.h" > #include "WHLSLParser.h" > #include "WHLSLProgram.h" >+#include "WHLSLPropertyResolver.h" > #include "WHLSLRecursionChecker.h" > #include "WHLSLRecursiveTypeChecker.h" > #include "WHLSLSemanticMatcher.h" >@@ -117,7 +118,7 @@ static Optional<Program> prepareShared(String& whlslSource) > RUN_PASS(check, program); > > checkLiteralTypes(program); >- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195788 Resolve properties here >+ resolveProperties(program); > findHighZombies(program); > RUN_PASS(checkStatementBehavior, program); > RUN_PASS(checkRecursion, program); >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h >index 97490a6e2fa41ad34d35c56c46c72d427f9917ba..5bd6df06dc691a72f1ce24dfc55576ec7f5284ab 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h >@@ -34,7 +34,7 @@ namespace WebCore { > > namespace WHLSL { > >-// FIXME: Generate descriptive error messages and return them here. >+// FIXME: https://bugs.webkit.org/show_bug.cgi?id=195682 Generate descriptive error messages and return them here. > struct RenderPrepareResult { > String metalSource; > String mangledVertexEntryPointName; >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..c712107d239d9ca9da3311344e3812a58eb457f7 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp >@@ -0,0 +1,746 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "WHLSLPropertyResolver.h" >+ >+#if ENABLE(WEBGPU) >+ >+#include "WHLSLAssignmentExpression.h" >+#include "WHLSLCallExpression.h" >+#include "WHLSLCommaExpression.h" >+#include "WHLSLDereferenceExpression.h" >+#include "WHLSLDotExpression.h" >+#include "WHLSLFunctionDeclaration.h" >+#include "WHLSLFunctionDefinition.h" >+#include "WHLSLMakePointerExpression.h" >+#include "WHLSLPointerType.h" >+#include "WHLSLReadModifyWriteExpression.h" >+#include "WHLSLVariableDeclaration.h" >+#include "WHLSLVariableReference.h" >+#include "WHLSLVisitor.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class PropertyResolver : public Visitor { >+public: >+private: >+ void visit(AST::FunctionDefinition&) override; >+ void visit(AST::DotExpression&) override; >+ void visit(AST::AssignmentExpression&) override; >+ void visit(AST::ReadModifyWriteExpression&) override; >+ >+ bool simplifyRightValue(AST::DotExpression&); >+ bool simplifyAbstractLeftValue(AST::AssignmentExpression&, AST::DotExpression&, UniqueRef<AST::Expression>&& right); >+ void simplifyLeftValue(AST::Expression&); >+ >+ AST::VariableDeclarations m_variableDeclarations; >+}; >+ >+void PropertyResolver::visit(AST::DotExpression& dotExpression) >+{ >+ // Unless we're inside an AssignmentExpression or a ReadModifyWriteExpression, we're a right value. >+ if (!simplifyRightValue(dotExpression)) >+ setError(); >+} >+ >+void PropertyResolver::visit(AST::FunctionDefinition& functionDefinition) >+{ >+ Visitor::visit(functionDefinition); >+ if (!m_variableDeclarations.isEmpty()) >+ functionDefinition.block().statements().insert(0, makeUniqueRef<AST::VariableDeclarationsStatement>(Lexer::Token(m_variableDeclarations[0]->origin()), WTFMove(m_variableDeclarations))); >+} >+ >+static Optional<UniqueRef<AST::Expression>> setterCall(AST::DotExpression& dotExpression, UniqueRef<AST::Expression>&& newValue, const std::function<UniqueRef<AST::Expression>()>& leftValueFactory, const std::function<UniqueRef<AST::Expression>()>& pointerToLeftValueFactory) >+{ >+ if (dotExpression.anderFunction()) { >+ // *operator&.foo(&v) = newValue >+ if (!dotExpression.threadAnderFunction()) >+ return WTF::nullopt; >+ >+ Vector<UniqueRef<AST::Expression>> arguments; >+ arguments.append(pointerToLeftValueFactory()); >+ auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(dotExpression.origin()), String(dotExpression.threadAnderFunction()->name()), WTFMove(arguments)); >+ callExpression->setType(dotExpression.threadAnderFunction()->type().clone()); >+ callExpression->setTypeAnnotation(AST::RightValue()); >+ callExpression->setFunction(*dotExpression.threadAnderFunction()); >+ >+ auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(Lexer::Token(dotExpression.origin()), WTFMove(callExpression)); >+ dereferenceExpression->setType(downcast<AST::PointerType>(dotExpression.threadAnderFunction()->type()).elementType().clone()); >+ dereferenceExpression->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); >+ >+ auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(dotExpression.origin()), WTFMove(dereferenceExpression), WTFMove(newValue)); >+ assignmentExpression->setType(downcast<AST::PointerType>(dotExpression.threadAnderFunction()->type()).elementType().clone()); >+ assignmentExpression->setTypeAnnotation(AST::RightValue()); >+ >+ return UniqueRef<AST::Expression>(WTFMove(assignmentExpression)); >+ } >+ >+ // v = operator.foo=(v, newValue) >+ ASSERT(dotExpression.setterFunction()); >+ >+ Vector<UniqueRef<AST::Expression>> arguments; >+ arguments.append(leftValueFactory()); >+ arguments.append(WTFMove(newValue)); >+ auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(dotExpression.origin()), String(dotExpression.setterFunction()->name()), WTFMove(arguments)); >+ callExpression->setType(dotExpression.setterFunction()->type().clone()); >+ callExpression->setTypeAnnotation(AST::RightValue()); >+ callExpression->setFunction(*dotExpression.setterFunction()); >+ >+ auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(dotExpression.origin()), leftValueFactory(), WTFMove(callExpression)); >+ assignmentExpression->setType(dotExpression.setterFunction()->type().clone()); >+ assignmentExpression->setTypeAnnotation(AST::RightValue()); >+ >+ return UniqueRef<AST::Expression>(WTFMove(assignmentExpression)); >+} >+ >+static Optional<UniqueRef<AST::Expression>> getterCall(AST::DotExpression& dotExpression, const std::function<UniqueRef<AST::Expression>()>& leftValueFactory, const std::function<UniqueRef<AST::Expression>()>& pointerToLeftValueFactory) >+{ >+ if (dotExpression.anderFunction()) { >+ // *operator&.foo(&v) >+ if (!dotExpression.threadAnderFunction()) >+ return WTF::nullopt; >+ >+ Vector<UniqueRef<AST::Expression>> arguments; >+ arguments.append(pointerToLeftValueFactory()); >+ auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(dotExpression.origin()), String(dotExpression.threadAnderFunction()->name()), WTFMove(arguments)); >+ callExpression->setType(dotExpression.threadAnderFunction()->type().clone()); >+ callExpression->setTypeAnnotation(AST::RightValue()); >+ callExpression->setFunction(*dotExpression.threadAnderFunction()); >+ >+ auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(Lexer::Token(dotExpression.origin()), WTFMove(callExpression)); >+ dereferenceExpression->setType(downcast<AST::PointerType>(dotExpression.threadAnderFunction()->type()).elementType().clone()); >+ dereferenceExpression->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); >+ >+ return UniqueRef<AST::Expression>(WTFMove(dereferenceExpression)); >+ } >+ >+ // operator.foo(v) >+ ASSERT(dotExpression.getterFunction()); >+ >+ Vector<UniqueRef<AST::Expression>> arguments; >+ arguments.append(leftValueFactory()); >+ auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(dotExpression.origin()), String(dotExpression.getterFunction()->name()), WTFMove(arguments)); >+ callExpression->setType(dotExpression.getterFunction()->type().clone()); >+ callExpression->setTypeAnnotation(AST::RightValue()); >+ callExpression->setFunction(*dotExpression.getterFunction()); >+ >+ return UniqueRef<AST::Expression>(WTFMove(callExpression)); >+} >+ >+struct ModifyResult { >+ AST::Expression& innerLeftValue; >+ Vector<UniqueRef<AST::Expression>> expressions; >+ Vector<UniqueRef<AST::VariableDeclaration>> variableDeclarations; >+}; >+struct ModificationResult { >+ Vector<UniqueRef<AST::Expression>> expressions; >+ UniqueRef<AST::Expression> result; >+}; >+static Optional<ModifyResult> modify(AST::DotExpression& dotExpression, std::function<Optional<ModificationResult>(Optional<UniqueRef<AST::Expression>>&&)> modification) >+{ >+ // Consider a.b.c.d++; >+ // This would get transformed into: >+ // >+ // Step 1: >+ // p = &a; >+ // >+ // Step 2: >+ // q = operator.b(*p); >+ // r = operator.c(q); >+ // >+ // Step 3: >+ // oldValue = operator.d(r); >+ // newValue = ...; >+ // >+ // Step 4: >+ // r = operator.d=(r, newValue); >+ // q = operator.c=(q, r); >+ // >+ // Step 4: >+ // *p = operator.b=(*p, q); >+ >+ // If the expression is a.b.c.d = e, Step 3 disappears and "newValue" in step 4 becomes "e". >+ >+ >+ // Find the ".b" ".c" and ".d" expressions. They end up in the order [".d", ".c", ".b"]. >+ Vector<std::reference_wrapper<AST::DotExpression>> chain; >+ AST::DotExpression* iterator = &dotExpression; >+ while (true) { >+ chain.append(*iterator); >+ if (iterator->base().typeAnnotation().leftAddressSpace()) >+ break; >+ ASSERT(!iterator->base().typeAnnotation().isRightValue()); >+ ASSERT(is<AST::DotExpression>(iterator->base())); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198163 Make this work with index expressions >+ iterator = &downcast<AST::DotExpression>(iterator->base()); >+ } >+ auto leftExpression = iterator->takeBase(); >+ AST::Expression& innerLeftExpression = leftExpression; >+ >+ // Create "p" variable. >+ auto pointerVariable = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(leftExpression->origin()), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(makeUniqueRef<AST::PointerType>(Lexer::Token(leftExpression->origin()), *leftExpression->typeAnnotation().leftAddressSpace(), leftExpression->resolvedType().clone())), String(), WTF::nullopt, WTF::nullopt); >+ >+ // Create "q" and "r" variables. >+ Vector<UniqueRef<AST::VariableDeclaration>> intermediateVariables; >+ intermediateVariables.reserveInitialCapacity(chain.size() - 1); >+ for (size_t i = 1; i < chain.size(); ++i) { >+ auto& dotExpression = static_cast<AST::DotExpression&>(chain[i]); >+ intermediateVariables.uncheckedAppend(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(dotExpression.origin()), AST::Qualifiers(), dotExpression.resolvedType().clone(), String(), WTF::nullopt, WTF::nullopt)); >+ } >+ >+ Vector<UniqueRef<AST::Expression>> expressions; >+ >+ // Step 1: >+ { >+ auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(innerLeftExpression.origin()), WTFMove(leftExpression)); >+ makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(innerLeftExpression.origin()), *innerLeftExpression.typeAnnotation().leftAddressSpace(), innerLeftExpression.resolvedType().clone())); >+ makePointerExpression->setTypeAnnotation(AST::RightValue()); >+ >+ auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(pointerVariable)); >+ ASSERT(pointerVariable->type()); >+ variableReference->setType(pointerVariable->type()->clone()); >+ variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ >+ auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(innerLeftExpression.origin()), WTFMove(variableReference), WTFMove(makePointerExpression)); >+ assignmentExpression->setType(pointerVariable->type()->clone()); >+ assignmentExpression->setTypeAnnotation(AST::RightValue()); >+ >+ expressions.append(WTFMove(assignmentExpression)); >+ } >+ >+ // Step 2: >+ AST::VariableDeclaration* previous = nullptr; >+ auto previousLeftValue = [&]() -> UniqueRef<AST::Expression> { >+ if (previous) { >+ auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(*previous)); >+ ASSERT(previous->type()); >+ variableReference->setType(previous->type()->clone()); >+ variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ return variableReference; >+ } >+ >+ auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(pointerVariable)); >+ ASSERT(pointerVariable->type()); >+ variableReference->setType(pointerVariable->type()->clone()); >+ variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ >+ auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(Lexer::Token(dotExpression.origin()), WTFMove(variableReference)); >+ ASSERT(pointerVariable->type()); >+ dereferenceExpression->setType(downcast<AST::PointerType>(*pointerVariable->type()).elementType().clone()); >+ dereferenceExpression->setTypeAnnotation(AST::LeftValue { downcast<AST::PointerType>(*pointerVariable->type()).addressSpace() }); >+ return dereferenceExpression; >+ }; >+ auto pointerToPreviousLeftValue = [&]() -> UniqueRef<AST::Expression> { >+ if (previous) { >+ auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(*previous)); >+ ASSERT(previous->type()); >+ variableReference->setType(previous->type()->clone()); >+ variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ >+ auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(dotExpression.origin()), WTFMove(variableReference)); >+ ASSERT(previous->type()); >+ makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(dotExpression.origin()), AST::AddressSpace::Thread, previous->type()->clone())); >+ makePointerExpression->setTypeAnnotation(AST::RightValue()); >+ return makePointerExpression; >+ } >+ >+ auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(pointerVariable)); >+ ASSERT(pointerVariable->type()); >+ variableReference->setType(pointerVariable->type()->clone()); >+ variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ return variableReference; >+ }; >+ for (size_t i = chain.size(); --i; ) { >+ AST::DotExpression& dotExpression = chain[i]; >+ AST::VariableDeclaration& variableDeclaration = intermediateVariables[i - 1]; >+ >+ auto callExpression = getterCall(dotExpression, previousLeftValue, pointerToPreviousLeftValue); >+ >+ if (!callExpression) >+ return WTF::nullopt; >+ >+ auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration)); >+ ASSERT(variableDeclaration.type()); >+ variableReference->setType(variableDeclaration.type()->clone()); >+ variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ >+ auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(dotExpression.origin()), WTFMove(variableReference), WTFMove(*callExpression)); >+ assignmentExpression->setType(variableDeclaration.type()->clone()); >+ assignmentExpression->setTypeAnnotation(AST::RightValue()); >+ >+ expressions.append(WTFMove(assignmentExpression)); >+ >+ previous = &variableDeclaration; >+ } >+ auto lastGetterCallExpression = getterCall(chain[0], previousLeftValue, pointerToPreviousLeftValue); >+ >+ // Step 3: >+ auto modificationResult = modification(WTFMove(lastGetterCallExpression)); >+ if (!modificationResult) >+ return WTF::nullopt; >+ for (size_t i = 0; i < modificationResult->expressions.size(); ++i) >+ expressions.append(WTFMove(modificationResult->expressions[i])); >+ >+ // Step 4: >+ UniqueRef<AST::Expression> rightValue = WTFMove(modificationResult->result); >+ auto expressionType = rightValue->resolvedType().clone(); >+ for (size_t i = 0; i < chain.size() - 1; ++i) { >+ AST::DotExpression& dotExpression = chain[i]; >+ AST::VariableDeclaration& variableDeclaration = intermediateVariables[i]; >+ >+ auto assignmentExpression = setterCall(dotExpression, WTFMove(rightValue), [&]() -> UniqueRef<AST::Expression> { >+ auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration)); >+ ASSERT(variableDeclaration.type()); >+ variableReference->setType(variableDeclaration.type()->clone()); >+ variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ return variableReference; >+ }, [&]() -> UniqueRef<AST::Expression> { >+ auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration)); >+ ASSERT(variableDeclaration.type()); >+ variableReference->setType(variableDeclaration.type()->clone()); >+ variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ >+ auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(dotExpression.origin()), WTFMove(variableReference)); >+ ASSERT(variableDeclaration.type()); >+ makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(dotExpression.origin()), AST::AddressSpace::Thread, variableDeclaration.type()->clone())); >+ makePointerExpression->setTypeAnnotation(AST::RightValue()); >+ return makePointerExpression; >+ }); >+ >+ if (!assignmentExpression) >+ return WTF::nullopt; >+ >+ expressions.append(WTFMove(*assignmentExpression)); >+ >+ rightValue = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration)); >+ ASSERT(variableDeclaration.type()); >+ rightValue->setType(variableDeclaration.type()->clone()); >+ rightValue->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ } >+ >+ // Step 5: >+ { >+ auto assignmentExpression = setterCall(chain[chain.size() - 1], WTFMove(rightValue), [&]() -> UniqueRef<AST::Expression> { >+ auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(pointerVariable)); >+ ASSERT(pointerVariable->type()); >+ variableReference->setType(pointerVariable->type()->clone()); >+ variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ >+ auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(Lexer::Token(dotExpression.origin()), WTFMove(variableReference)); >+ ASSERT(pointerVariable->type()); >+ dereferenceExpression->setType(downcast<AST::PointerType>(*pointerVariable->type()).elementType().clone()); >+ dereferenceExpression->setTypeAnnotation(AST::LeftValue { downcast<AST::PointerType>(*pointerVariable->type()).addressSpace() }); >+ return dereferenceExpression; >+ }, [&]() -> UniqueRef<AST::Expression> { >+ auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(pointerVariable)); >+ ASSERT(pointerVariable->type()); >+ variableReference->setType(pointerVariable->type()->clone()); >+ variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ return variableReference; >+ }); >+ >+ if (!assignmentExpression) >+ return WTF::nullopt; >+ >+ expressions.append(WTFMove(*assignmentExpression)); >+ } >+ >+ Vector<UniqueRef<AST::VariableDeclaration>> variableDeclarations; >+ variableDeclarations.append(WTFMove(pointerVariable)); >+ for (auto& intermediateVariable : intermediateVariables) >+ variableDeclarations.append(WTFMove(intermediateVariable)); >+ >+ return {{ innerLeftExpression, WTFMove(expressions), WTFMove(variableDeclarations) }}; >+} >+ >+void PropertyResolver::visit(AST::AssignmentExpression& assignmentExpression) >+{ >+ if (assignmentExpression.left().typeAnnotation().leftAddressSpace()) { >+ simplifyLeftValue(assignmentExpression.left()); >+ checkErrorAndVisit(assignmentExpression.right()); >+ return; >+ } >+ ASSERT(!assignmentExpression.left().typeAnnotation().isRightValue()); >+ if (!is<AST::DotExpression>(assignmentExpression.left())) { >+ setError(); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198163 Make this work with index expressions. >+ return; >+ } >+ >+ auto type = assignmentExpression.right().resolvedType().clone(); >+ >+ checkErrorAndVisit(assignmentExpression.right()); >+ >+ auto modifyResult = modify(downcast<AST::DotExpression>(assignmentExpression.left()), [&](Optional<UniqueRef<AST::Expression>>&&) -> Optional<ModificationResult> { >+ return {{ Vector<UniqueRef<AST::Expression>>(), assignmentExpression.takeRight() }}; >+ }); >+ >+ if (!modifyResult) { >+ setError(); >+ return; >+ } >+ simplifyLeftValue(modifyResult->innerLeftValue); >+ >+ static_assert(sizeof(AST::CommaExpression) <= sizeof(AST::AssignmentExpression), "Assignment expressions need to be able to become comma expressions without updating backreferences"); >+ Lexer::Token origin = assignmentExpression.origin(); >+ void* location = &assignmentExpression; >+ assignmentExpression.~AssignmentExpression(); >+ auto* commaExpression = new (location) AST::CommaExpression(WTFMove(origin), WTFMove(modifyResult->expressions)); >+ commaExpression->setType(WTFMove(type)); >+ commaExpression->setTypeAnnotation(AST::RightValue()); >+ >+ for (auto& variableDeclaration : modifyResult->variableDeclarations) >+ m_variableDeclarations.append(WTFMove(variableDeclaration)); >+} >+ >+void PropertyResolver::visit(AST::ReadModifyWriteExpression& readModifyWriteExpression) >+{ >+ if (readModifyWriteExpression.leftValue().typeAnnotation().leftAddressSpace()) { >+ // Consider a++; >+ // This would get transformed into: >+ // >+ // p = &a; >+ // oldValue = *p; >+ // newValue = ...; >+ // *p = newValue; >+ >+ auto baseType = readModifyWriteExpression.leftValue().resolvedType().clone(); >+ auto pointerType = makeUniqueRef<AST::PointerType>(Lexer::Token(readModifyWriteExpression.leftValue().origin()), *readModifyWriteExpression.leftValue().typeAnnotation().leftAddressSpace(), baseType->clone()); >+ >+ auto pointerVariable = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(readModifyWriteExpression.leftValue().origin()), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(pointerType->clone()), String(), WTF::nullopt, WTF::nullopt); >+ >+ Vector<UniqueRef<AST::Expression>> expressions; >+ >+ { >+ auto origin = Lexer::Token(readModifyWriteExpression.leftValue().origin()); >+ auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(origin), readModifyWriteExpression.takeLeftValue()); >+ makePointerExpression->setType(pointerType->clone()); >+ makePointerExpression->setTypeAnnotation(AST::RightValue()); >+ >+ auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(pointerVariable)); >+ variableReference->setType(pointerType->clone()); >+ variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ >+ auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(WTFMove(origin), WTFMove(variableReference), WTFMove(makePointerExpression)); >+ assignmentExpression->setType(pointerType->clone()); >+ assignmentExpression->setTypeAnnotation(AST::RightValue()); >+ >+ expressions.append(WTFMove(assignmentExpression)); >+ } >+ >+ { >+ auto variableReference1 = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(pointerVariable)); >+ variableReference1->setType(pointerType->clone()); >+ variableReference1->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ >+ auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(Lexer::Token(readModifyWriteExpression.origin()), WTFMove(variableReference1)); >+ dereferenceExpression->setType(baseType->clone()); >+ dereferenceExpression->setTypeAnnotation(AST::RightValue()); >+ >+ auto variableReference2 = readModifyWriteExpression.oldVariableReference(); >+ variableReference2->setType(baseType->clone()); >+ variableReference2->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ >+ auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(readModifyWriteExpression.origin()), WTFMove(variableReference2), WTFMove(dereferenceExpression)); >+ assignmentExpression->setType(baseType->clone()); >+ assignmentExpression->setTypeAnnotation(AST::RightValue()); >+ >+ expressions.append(WTFMove(assignmentExpression)); >+ } >+ >+ { >+ auto variableReference = readModifyWriteExpression.newVariableReference(); >+ variableReference->setType(baseType->clone()); >+ variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ >+ auto newValueExpression = readModifyWriteExpression.takeNewValueExpression(); >+ ASSERT(newValueExpression); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198170 Relax this constraint. >+ auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(readModifyWriteExpression.origin()), WTFMove(variableReference), WTFMove(*newValueExpression)); >+ assignmentExpression->setType(baseType->clone()); >+ assignmentExpression->setTypeAnnotation(AST::RightValue()); >+ >+ expressions.append(WTFMove(assignmentExpression)); >+ } >+ >+ { >+ auto variableReference1 = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(pointerVariable)); >+ variableReference1->setType(pointerType->clone()); >+ variableReference1->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ >+ auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(Lexer::Token(readModifyWriteExpression.origin()), WTFMove(variableReference1)); >+ dereferenceExpression->setType(baseType->clone()); >+ dereferenceExpression->setTypeAnnotation(AST::RightValue()); >+ >+ auto variableReference2 = readModifyWriteExpression.newVariableReference(); >+ variableReference2->setType(baseType->clone()); >+ variableReference2->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ >+ auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(readModifyWriteExpression.origin()), WTFMove(dereferenceExpression), WTFMove(variableReference2)); >+ assignmentExpression->setType(baseType->clone()); >+ assignmentExpression->setTypeAnnotation(AST::RightValue()); >+ >+ expressions.append(WTFMove(assignmentExpression)); >+ } >+ >+ auto resultExpression = readModifyWriteExpression.takeResultExpression(); >+ ASSERT(resultExpression); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198170 Be resilient to this being null. >+ auto type = (*resultExpression)->resolvedType().clone(); >+ expressions.append(WTFMove(*resultExpression)); >+ >+ UniqueRef<AST::VariableDeclaration> oldVariableDeclaration = readModifyWriteExpression.takeOldValue(); >+ UniqueRef<AST::VariableDeclaration> newVariableDeclaration = readModifyWriteExpression.takeNewValue(); >+ >+ static_assert(sizeof(AST::CommaExpression) <= sizeof(AST::ReadModifyWriteExpression), "ReadModifyWrite expressions need to be able to become comma expressions without updating backreferences"); >+ Lexer::Token origin = readModifyWriteExpression.origin(); >+ void* location = &readModifyWriteExpression; >+ readModifyWriteExpression.~ReadModifyWriteExpression(); >+ auto* commaExpression = new (location) AST::CommaExpression(WTFMove(origin), WTFMove(expressions)); >+ commaExpression->setType(WTFMove(type)); >+ commaExpression->setTypeAnnotation(AST::RightValue()); >+ >+ m_variableDeclarations.append(WTFMove(pointerVariable)); >+ m_variableDeclarations.append(WTFMove(oldVariableDeclaration)); >+ m_variableDeclarations.append(WTFMove(newVariableDeclaration)); >+ return; >+ } >+ >+ ASSERT(!readModifyWriteExpression.leftValue().typeAnnotation().isRightValue()); >+ if (!is<AST::DotExpression>(readModifyWriteExpression.leftValue())) { >+ setError(); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198163 Make this work with index expressions. >+ return; >+ } >+ auto modifyResult = modify(downcast<AST::DotExpression>(readModifyWriteExpression.leftValue()), [&](Optional<UniqueRef<AST::Expression>>&& lastGetterCallExpression) -> Optional<ModificationResult> { >+ Vector<UniqueRef<AST::Expression>> expressions; >+ if (!lastGetterCallExpression) >+ return WTF::nullopt; >+ >+ { >+ auto variableReference = readModifyWriteExpression.oldVariableReference(); >+ variableReference->setType(readModifyWriteExpression.leftValue().resolvedType().clone()); >+ variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ >+ auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(readModifyWriteExpression.leftValue().origin()), WTFMove(variableReference), WTFMove(*lastGetterCallExpression)); >+ assignmentExpression->setType(readModifyWriteExpression.leftValue().resolvedType().clone()); >+ assignmentExpression->setTypeAnnotation(AST::RightValue()); >+ >+ expressions.append(WTFMove(assignmentExpression)); >+ } >+ >+ { >+ auto variableReference = readModifyWriteExpression.newVariableReference(); >+ variableReference->setType(readModifyWriteExpression.leftValue().resolvedType().clone()); >+ variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? >+ >+ auto newValueExpression = readModifyWriteExpression.takeNewValueExpression(); >+ ASSERT(newValueExpression); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198170 Relax this constraint >+ auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(readModifyWriteExpression.leftValue().origin()), WTFMove(variableReference), WTFMove(*newValueExpression)); >+ assignmentExpression->setType(readModifyWriteExpression.leftValue().resolvedType().clone()); >+ assignmentExpression->setTypeAnnotation(AST::RightValue()); >+ >+ expressions.append(WTFMove(assignmentExpression)); >+ } >+ >+ return {{ WTFMove(expressions), readModifyWriteExpression.newVariableReference() }}; >+ }); >+ >+ if (!modifyResult) { >+ setError(); >+ return; >+ } >+ simplifyLeftValue(modifyResult->innerLeftValue); >+ >+ auto resultExpression = readModifyWriteExpression.takeResultExpression(); >+ ASSERT(resultExpression); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198170 Be resilient to this being null. >+ auto type = (*resultExpression)->resolvedType().clone(); >+ modifyResult->expressions.append(WTFMove(*resultExpression)); >+ >+ UniqueRef<AST::VariableDeclaration> oldVariableDeclaration = readModifyWriteExpression.takeOldValue(); >+ UniqueRef<AST::VariableDeclaration> newVariableDeclaration = readModifyWriteExpression.takeNewValue(); >+ >+ static_assert(sizeof(AST::CommaExpression) <= sizeof(AST::ReadModifyWriteExpression), "ReadModifyWrite expressions need to be able to become comma expressions without updating backreferences"); >+ Lexer::Token origin = readModifyWriteExpression.origin(); >+ void* location = &readModifyWriteExpression; >+ readModifyWriteExpression.~ReadModifyWriteExpression(); >+ auto* commaExpression = new (location) AST::CommaExpression(WTFMove(origin), WTFMove(modifyResult->expressions)); >+ commaExpression->setType(WTFMove(type)); >+ commaExpression->setTypeAnnotation(AST::RightValue()); >+ >+ for (auto& variableDeclaration : modifyResult->variableDeclarations) >+ m_variableDeclarations.append(WTFMove(variableDeclaration)); >+ m_variableDeclarations.append(WTFMove(oldVariableDeclaration)); >+ m_variableDeclarations.append(WTFMove(newVariableDeclaration)); >+} >+ >+bool PropertyResolver::simplifyRightValue(AST::DotExpression& dotExpression) >+{ >+ Lexer::Token origin = dotExpression.origin(); >+ >+ if (auto* anderFunction = dotExpression.anderFunction()) { >+ auto& base = dotExpression.base(); >+ if (auto leftAddressSpace = base.typeAnnotation().leftAddressSpace()) { >+ auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(origin), dotExpression.takeBase()); >+ makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(origin), *leftAddressSpace, base.resolvedType().clone())); >+ makePointerExpression->setTypeAnnotation(AST::RightValue()); >+ >+ Vector<UniqueRef<AST::Expression>> arguments; >+ arguments.append(WTFMove(makePointerExpression)); >+ auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(origin), String(anderFunction->name()), WTFMove(arguments)); >+ callExpression->setType(anderFunction->type().clone()); >+ callExpression->setTypeAnnotation(AST::RightValue()); >+ callExpression->setFunction(*anderFunction); >+ >+ static_assert(sizeof(AST::DereferenceExpression) <= sizeof(AST::DotExpression), "Dot expressions need to be able to become dereference expressions without updating backreferences"); >+ void* location = &dotExpression; >+ dotExpression.~DotExpression(); >+ auto* dereferenceExpression = new (location) AST::DereferenceExpression(WTFMove(origin), WTFMove(callExpression)); >+ dereferenceExpression->setType(downcast<AST::PointerType>(anderFunction->type()).elementType().clone()); >+ dereferenceExpression->setTypeAnnotation(AST::LeftValue { downcast<AST::PointerType>(anderFunction->type()).addressSpace() }); >+ return true; >+ } >+ >+ // We have an ander, but no left value to call it on. Let's save the value into a temporary variable to create a left value. >+ // This is effectively inlining the functions the spec says are generated. >+ if (!dotExpression.threadAnderFunction()) >+ return false; >+ >+ auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(origin), AST::Qualifiers(), base.resolvedType().clone(), String(), WTF::nullopt, WTF::nullopt); >+ >+ auto variableReference1 = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration)); >+ variableReference1->setType(base.resolvedType().clone()); >+ variableReference1->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); >+ >+ auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(origin), WTFMove(variableReference1), dotExpression.takeBase()); >+ assignmentExpression->setType(base.resolvedType().clone()); >+ assignmentExpression->setTypeAnnotation(AST::RightValue()); >+ >+ auto variableReference2 = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration)); >+ variableReference2->setType(base.resolvedType().clone()); >+ variableReference2->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); >+ >+ auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(origin), WTFMove(variableReference2)); >+ makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(origin), AST::AddressSpace::Thread, base.resolvedType().clone())); >+ makePointerExpression->setTypeAnnotation(AST::RightValue()); >+ >+ Vector<UniqueRef<AST::Expression>> arguments; >+ arguments.append(WTFMove(makePointerExpression)); >+ auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(origin), String(anderFunction->name()), WTFMove(arguments)); >+ callExpression->setType(anderFunction->type().clone()); >+ callExpression->setTypeAnnotation(AST::RightValue()); >+ callExpression->setFunction(*anderFunction); >+ >+ auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(WTFMove(origin), WTFMove(callExpression)); >+ dereferenceExpression->setType(downcast<AST::PointerType>(anderFunction->type()).elementType().clone()); >+ dereferenceExpression->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); >+ >+ static_assert(sizeof(AST::CommaExpression) <= sizeof(AST::DotExpression), "Dot expressions need to be able to become comma expressions without updating backreferences"); >+ void* location = &dotExpression; >+ dotExpression.~DotExpression(); >+ Vector<UniqueRef<AST::Expression>> expressions; >+ expressions.append(WTFMove(assignmentExpression)); >+ expressions.append(WTFMove(dereferenceExpression)); >+ auto* commaExpression = new (location) AST::CommaExpression(WTFMove(origin), WTFMove(expressions)); >+ commaExpression->setType(downcast<AST::PointerType>(anderFunction->type()).elementType().clone()); >+ commaExpression->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); >+ >+ m_variableDeclarations.append(WTFMove(variableDeclaration)); >+ return true; >+ } >+ >+ static_assert(sizeof(AST::CallExpression) <= sizeof(AST::DotExpression), "Dot expressions need to be able to become call expressions without updating backreferences"); >+ ASSERT(dotExpression.getterFunction()); >+ auto& getterFunction = *dotExpression.getterFunction(); >+ Vector<UniqueRef<AST::Expression>> arguments; >+ arguments.append(dotExpression.takeBase()); >+ void* location = &dotExpression; >+ dotExpression.~DotExpression(); >+ auto* callExpression = new (location) AST::CallExpression(WTFMove(origin), String(getterFunction.name()), WTFMove(arguments)); >+ callExpression->setFunction(getterFunction); >+ callExpression->setType(getterFunction.type().clone()); >+ callExpression->setTypeAnnotation(AST::RightValue()); >+ return true; >+} >+ >+class LeftValueSimplifier : public Visitor { >+public: >+ void visit(AST::DotExpression&) override; >+ void visit(AST::DereferenceExpression&) override; >+ >+private: >+}; >+ >+void LeftValueSimplifier::visit(AST::DotExpression& dotExpression) >+{ >+ Visitor::visit(dotExpression); >+ ASSERT(dotExpression.base().typeAnnotation().leftAddressSpace()); >+ ASSERT(dotExpression.anderFunction()); >+ >+ Lexer::Token origin = dotExpression.origin(); >+ auto* anderFunction = dotExpression.anderFunction(); >+ auto& base = dotExpression.base(); >+ auto leftAddressSpace = *dotExpression.base().typeAnnotation().leftAddressSpace(); >+ auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(origin), dotExpression.takeBase()); >+ makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(origin), leftAddressSpace, base.resolvedType().clone())); >+ makePointerExpression->setTypeAnnotation(AST::RightValue()); >+ >+ Vector<UniqueRef<AST::Expression>> arguments; >+ arguments.append(WTFMove(makePointerExpression)); >+ auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(origin), String(anderFunction->name()), WTFMove(arguments)); >+ callExpression->setType(anderFunction->type().clone()); >+ callExpression->setTypeAnnotation(AST::RightValue()); >+ callExpression->setFunction(*anderFunction); >+ >+ static_assert(sizeof(AST::DereferenceExpression) <= sizeof(AST::DotExpression), "Dot expressions need to be able to become dereference expressions without updating backreferences"); >+ void* location = &dotExpression; >+ dotExpression.~DotExpression(); >+ auto* dereferenceExpression = new (location) AST::DereferenceExpression(WTFMove(origin), WTFMove(callExpression)); >+ dereferenceExpression->setType(downcast<AST::PointerType>(anderFunction->type()).elementType().clone()); >+ dereferenceExpression->setTypeAnnotation(AST::LeftValue { downcast<AST::PointerType>(anderFunction->type()).addressSpace() }); >+} >+ >+void LeftValueSimplifier::visit(AST::DereferenceExpression& dereferenceExpression) >+{ >+ // Dereference expressions are the only expressions where the children might be more-right than we are. >+ // For example, a dereference expression may be a left value but its child may be a call expression which is a right value. >+ // LeftValueSimplifier doesn't handle right values, so we instead need to use PropertyResolver. >+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198170 What about function call arguments? >+ PropertyResolver().Visitor::visit(dereferenceExpression); >+} >+ >+void PropertyResolver::simplifyLeftValue(AST::Expression& expression) >+{ >+ LeftValueSimplifier().Visitor::visit(expression); >+} >+ >+void resolveProperties(Program& program) >+{ >+ PropertyResolver().Visitor::visit(program); >+} >+ >+} // namespace WHLSL >+ >+} // namespace WebCore >+ >+#endif // ENABLE(WEBGPU) >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.h >new file mode 100644 >index 0000000000000000000000000000000000000000..e2205f902bcc94eca9ef33b58da1c701ab72b347 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.h >@@ -0,0 +1,42 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if ENABLE(WEBGPU) >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class Program; >+ >+void resolveProperties(Program&); >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursiveTypeChecker.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursiveTypeChecker.cpp >index d5a7b0d169e74fbf1e7ba7a14c73e4224993acbe..12a7048405d0607bd48a97b5fb1a6b7282c445f1 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursiveTypeChecker.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursiveTypeChecker.cpp >@@ -85,8 +85,8 @@ void RecursiveTypeChecker::visit(AST::TypeReference& typeReference) > > for (auto& typeArgument : typeReference.typeArguments()) > checkErrorAndVisit(typeArgument); >- if (typeReference.resolvedType()) >- checkErrorAndVisit(*typeReference.resolvedType()); >+ if (typeReference.maybeResolvedType()) // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198161 Shouldn't we know by now whether the type has been resolved or not? >+ checkErrorAndVisit(typeReference.resolvedType()); > } > > void RecursiveTypeChecker::visit(AST::ReferenceType&) >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.cpp >index e7838ce3f725ae09aba1edb50a6592c346313ee5..dc934dbf726a814a0804b4ccb5752dbecb81f38b 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.cpp >@@ -44,7 +44,7 @@ static unsigned conversionCost(AST::FunctionDeclaration& candidate, const Vector > conversionCost += argumentTypes[i].get().visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>&) -> unsigned { > return 0; > }, [&](RefPtr<ResolvableTypeReference>& resolvableTypeReference) -> unsigned { >- return resolvableTypeReference->resolvableType().conversionCost(*candidate.parameters()[i].type()); >+ return resolvableTypeReference->resolvableType().conversionCost(*candidate.parameters()[i]->type()); > })); > } > // The return type can never be a literal type, so its conversion cost is always 0. >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolvingType.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolvingType.h >index ca5cbb5929cf9e1818c2cd741e79d936caac68ee..2424a8037b3204bfaba3dff1c4b1d54c07a711f5 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolvingType.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolvingType.h >@@ -72,6 +72,7 @@ private: > > // This is a thin wrapper around a Variant. > // It exists so we can make sure that the default constructor does the right thing. >+// FIXME: https://bugs.webkit.org/show_bug.cgi?id=198158 This wrapper might not be necessary. > class ResolvingType { > public: > ResolvingType() >@@ -102,10 +103,11 @@ public: > return *this; > } > >- AST::UnnamedType& getUnnamedType() >+ AST::UnnamedType* getUnnamedType() > { >- ASSERT(WTF::holds_alternative<UniqueRef<AST::UnnamedType>>(m_inner)); >- return WTF::get<UniqueRef<AST::UnnamedType>>(m_inner); >+ if (WTF::holds_alternative<UniqueRef<AST::UnnamedType>>(m_inner)) >+ return &WTF::get<UniqueRef<AST::UnnamedType>>(m_inner); >+ return nullptr; > } > > template <typename Visitor> auto visit(const Visitor& visitor) -> decltype(WTF::visit(visitor, std::declval<Variant<UniqueRef<AST::UnnamedType>, RefPtr<ResolvableTypeReference>>&>())) >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt >index 79a2c60e0606b13265bb230367acf97250bf9a7f..0fb5d3932d45fb0afde0959615ebd81feaa91c53 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt >@@ -390,4 +390,13 @@ native void AllMemoryBarrierWithGroupSync(); > native void DeviceMemoryBarrierWithGroupSync(); > native void GroupMemoryBarrierWithGroupSync(); > >+operator float4(float x, float y, float z, float w) { >+ float4 result; >+ result.x = x; >+ result.y = y; >+ result.z = z; >+ result.w = w; >+ return result; >+} >+ > // FIXME: https://bugs.webkit.org/show_bug.cgi?id=192890 Insert the rest of the standard library once the parser is fast enough >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.cpp >index ae3ca64239e3b59d36aaaaeec7ba471bcb67ceb9..9cb5c81ebf913a8bb94b4cda4303adb8464babb0 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.cpp >@@ -47,7 +47,7 @@ public: > Visitor::visit(arrayType); > } > >- Vector<std::reference_wrapper<AST::ArrayType>>&& takeArrayTypes() >+ Vector<std::reference_wrapper<AST::ArrayType>> takeArrayTypes() > { > return WTFMove(m_arrayTypes); > } >@@ -65,7 +65,7 @@ bool synthesizeArrayOperatorLength(Program& program) > bool isOperator = true; > > for (auto& arrayType : arrayTypes) { >- AST::VariableDeclaration variableDeclaration(Lexer::Token(arrayType.get().origin()), AST::Qualifiers(), { arrayType.get().clone() }, String(), WTF::nullopt, WTF::nullopt); >+ auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(arrayType.get().origin()), AST::Qualifiers(), arrayType.get().clone(), String(), WTF::nullopt, WTF::nullopt); > AST::VariableDeclarations parameters; > parameters.append(WTFMove(variableDeclaration)); > AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(arrayType.get().origin()), AST::AttributeBlock(), WTF::nullopt, AST::TypeReference::wrap(Lexer::Token(arrayType.get().origin()), program.intrinsics().uintType()), "operator.length"_str, WTFMove(parameters), WTF::nullopt, isOperator)); >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp >index cd7c3702adbea29ac18c5cbe6db6087b9e02ed8a..f2850622c67afca1607022d81f4773c593a0203c 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp >@@ -85,12 +85,12 @@ public: > Visitor::visit(nativeTypeDeclaration); > } > >- Vector<std::reference_wrapper<AST::UnnamedType>>&& takeUnnamedTypes() >+ Vector<std::reference_wrapper<AST::UnnamedType>> takeUnnamedTypes() > { > return WTFMove(m_unnamedTypes); > } > >- Vector<std::reference_wrapper<AST::NamedType>>&& takeNamedTypes() >+ Vector<std::reference_wrapper<AST::NamedType>> takeNamedTypes() > { > return WTFMove(m_namedTypes); > } >@@ -110,7 +110,7 @@ bool synthesizeConstructors(Program& program) > bool isOperator = true; > > for (auto& unnamedType : unnamedTypes) { >- AST::VariableDeclaration variableDeclaration(Lexer::Token(unnamedType.get().origin()), AST::Qualifiers(), { unnamedType.get().clone() }, String(), WTF::nullopt, WTF::nullopt); >+ auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(unnamedType.get().origin()), AST::Qualifiers(), unnamedType.get().clone(), String(), WTF::nullopt, WTF::nullopt); > AST::VariableDeclarations parameters; > parameters.append(WTFMove(variableDeclaration)); > AST::NativeFunctionDeclaration copyConstructor(AST::FunctionDeclaration(Lexer::Token(unnamedType.get().origin()), AST::AttributeBlock(), WTF::nullopt, unnamedType.get().clone(), "operator cast"_str, WTFMove(parameters), WTF::nullopt, isOperator)); >@@ -127,7 +127,7 @@ bool synthesizeConstructors(Program& program) > if (is<AST::NativeTypeDeclaration>(static_cast<AST::NamedType&>(namedType)) && downcast<AST::NativeTypeDeclaration>(static_cast<AST::NamedType&>(namedType)).isAtomic()) > continue; > >- AST::VariableDeclaration variableDeclaration(Lexer::Token(namedType.get().origin()), AST::Qualifiers(), { AST::TypeReference::wrap(Lexer::Token(namedType.get().origin()), namedType.get()) }, String(), WTF::nullopt, WTF::nullopt); >+ auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(namedType.get().origin()), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(AST::TypeReference::wrap(Lexer::Token(namedType.get().origin()), namedType.get())), String(), WTF::nullopt, WTF::nullopt); > AST::VariableDeclarations parameters; > parameters.append(WTFMove(variableDeclaration)); > AST::NativeFunctionDeclaration copyConstructor(AST::FunctionDeclaration(Lexer::Token(namedType.get().origin()), AST::AttributeBlock(), WTF::nullopt, AST::TypeReference::wrap(Lexer::Token(namedType.get().origin()), namedType.get()), "operator cast"_str, WTFMove(parameters), WTF::nullopt, isOperator)); >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.cpp >index 1797fe5394c81eacd3954abc6a8a65a6c8fc96e2..d74af33a1f05a692219c8cce4afdcc929510971d 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.cpp >@@ -41,8 +41,8 @@ bool synthesizeEnumerationFunctions(Program& program) > bool isOperator = true; > for (auto& enumerationDefinition : program.enumerationDefinitions()) { > { >- AST::VariableDeclaration variableDeclaration1(Lexer::Token(enumerationDefinition->origin()), AST::Qualifiers(), { AST::TypeReference::wrap(Lexer::Token(enumerationDefinition->origin()), enumerationDefinition) }, String(), WTF::nullopt, WTF::nullopt); >- AST::VariableDeclaration variableDeclaration2(Lexer::Token(enumerationDefinition->origin()), AST::Qualifiers(), { AST::TypeReference::wrap(Lexer::Token(enumerationDefinition->origin()), enumerationDefinition) }, String(), WTF::nullopt, WTF::nullopt); >+ auto variableDeclaration1 = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(enumerationDefinition->origin()), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(AST::TypeReference::wrap(Lexer::Token(enumerationDefinition->origin()), enumerationDefinition)), String(), WTF::nullopt, WTF::nullopt); >+ auto variableDeclaration2 = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(enumerationDefinition->origin()), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(AST::TypeReference::wrap(Lexer::Token(enumerationDefinition->origin()), enumerationDefinition)), String(), WTF::nullopt, WTF::nullopt); > AST::VariableDeclarations parameters; > parameters.append(WTFMove(variableDeclaration1)); > parameters.append(WTFMove(variableDeclaration2)); >@@ -52,7 +52,7 @@ bool synthesizeEnumerationFunctions(Program& program) > } > > { >- AST::VariableDeclaration variableDeclaration(Lexer::Token(enumerationDefinition->origin()), AST::Qualifiers(), { AST::TypeReference::wrap(Lexer::Token(enumerationDefinition->origin()), enumerationDefinition) }, String(), WTF::nullopt, WTF::nullopt); >+ auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(enumerationDefinition->origin()), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(AST::TypeReference::wrap(Lexer::Token(enumerationDefinition->origin()), enumerationDefinition)), String(), WTF::nullopt, WTF::nullopt); > AST::VariableDeclarations parameters; > parameters.append(WTFMove(variableDeclaration)); > AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(enumerationDefinition->origin()), AST::AttributeBlock(), WTF::nullopt, enumerationDefinition->type().clone(), "operator.value"_str, WTFMove(parameters), WTF::nullopt, isOperator)); >@@ -61,7 +61,7 @@ bool synthesizeEnumerationFunctions(Program& program) > } > > { >- AST::VariableDeclaration variableDeclaration(Lexer::Token(enumerationDefinition->origin()), AST::Qualifiers(), { AST::TypeReference::wrap(Lexer::Token(enumerationDefinition->origin()), enumerationDefinition) }, String(), WTF::nullopt, WTF::nullopt); >+ auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(enumerationDefinition->origin()), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(AST::TypeReference::wrap(Lexer::Token(enumerationDefinition->origin()), enumerationDefinition)), String(), WTF::nullopt, WTF::nullopt); > AST::VariableDeclarations parameters; > parameters.append(WTFMove(variableDeclaration)); > AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(enumerationDefinition->origin()), AST::AttributeBlock(), WTF::nullopt, enumerationDefinition->type().clone(), "operator cast"_str, WTFMove(parameters), WTF::nullopt, isOperator)); >@@ -70,10 +70,10 @@ bool synthesizeEnumerationFunctions(Program& program) > } > > { >- AST::VariableDeclaration variableDeclaration(Lexer::Token(enumerationDefinition->origin()), AST::Qualifiers(), enumerationDefinition->type().clone(), String(), WTF::nullopt, WTF::nullopt); >+ auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(enumerationDefinition->origin()), AST::Qualifiers(), enumerationDefinition->type().clone(), String(), WTF::nullopt, WTF::nullopt); > AST::VariableDeclarations parameters; > parameters.append(WTFMove(variableDeclaration)); >- AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(enumerationDefinition->origin()), AST::AttributeBlock(), WTF::nullopt, { AST::TypeReference::wrap(Lexer::Token(enumerationDefinition->origin()), enumerationDefinition) }, "operator cast"_str, WTFMove(parameters), WTF::nullopt, isOperator)); >+ AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(enumerationDefinition->origin()), AST::AttributeBlock(), WTF::nullopt, UniqueRef<AST::UnnamedType>(AST::TypeReference::wrap(Lexer::Token(enumerationDefinition->origin()), enumerationDefinition)), "operator cast"_str, WTFMove(parameters), WTF::nullopt, isOperator)); > if (!program.append(WTFMove(nativeFunctionDeclaration))) > return false; > } >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.cpp >index 826722137e4c3e38227780dae12b29aaba1b72ee..945d0ceefaa39ce5074607d2c4493cf397e983de 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.cpp >@@ -46,7 +46,7 @@ bool synthesizeStructureAccessors(Program& program) > for (auto& structureElement : structureDefinition->structureElements()) { > { > // The getter: operator.field >- AST::VariableDeclaration variableDeclaration(Lexer::Token(structureElement.origin()), AST::Qualifiers(), { AST::TypeReference::wrap(Lexer::Token(structureElement.origin()), structureDefinition) }, String(), WTF::nullopt, WTF::nullopt); >+ auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(structureElement.origin()), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(AST::TypeReference::wrap(Lexer::Token(structureElement.origin()), structureDefinition)), String(), WTF::nullopt, WTF::nullopt); > AST::VariableDeclarations parameters; > parameters.append(WTFMove(variableDeclaration)); > AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(structureElement.origin()), AST::AttributeBlock(), WTF::nullopt, structureElement.type().clone(), makeString("operator.", structureElement.name()), WTFMove(parameters), WTF::nullopt, isOperator)); >@@ -56,8 +56,8 @@ bool synthesizeStructureAccessors(Program& program) > > { > // The setter: operator.field= >- AST::VariableDeclaration variableDeclaration1(Lexer::Token(structureElement.origin()), AST::Qualifiers(), { AST::TypeReference::wrap(Lexer::Token(structureElement.origin()), structureDefinition) }, String(), WTF::nullopt, WTF::nullopt); >- AST::VariableDeclaration variableDeclaration2(Lexer::Token(structureElement.origin()), AST::Qualifiers(), { structureElement.type().clone() }, String(), WTF::nullopt, WTF::nullopt); >+ auto variableDeclaration1 = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(structureElement.origin()), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(AST::TypeReference::wrap(Lexer::Token(structureElement.origin()), structureDefinition)), String(), WTF::nullopt, WTF::nullopt); >+ auto variableDeclaration2 = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(structureElement.origin()), AST::Qualifiers(), structureElement.type().clone(), String(), WTF::nullopt, WTF::nullopt); > AST::VariableDeclarations parameters; > parameters.append(WTFMove(variableDeclaration1)); > parameters.append(WTFMove(variableDeclaration2)); >@@ -69,7 +69,7 @@ bool synthesizeStructureAccessors(Program& program) > // The ander: operator&.field > auto createAnder = [&](AST::AddressSpace addressSpace) -> AST::NativeFunctionDeclaration { > auto argumentType = makeUniqueRef<AST::PointerType>(Lexer::Token(structureElement.origin()), addressSpace, AST::TypeReference::wrap(Lexer::Token(structureElement.origin()), structureDefinition)); >- AST::VariableDeclaration variableDeclaration(Lexer::Token(structureElement.origin()), AST::Qualifiers(), { WTFMove(argumentType) }, String(), WTF::nullopt, WTF::nullopt); >+ auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(structureElement.origin()), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(WTFMove(argumentType)), String(), WTF::nullopt, WTF::nullopt); > AST::VariableDeclarations parameters; > parameters.append(WTFMove(variableDeclaration)); > auto returnType = makeUniqueRef<AST::PointerType>(Lexer::Token(structureElement.origin()), addressSpace, structureElement.type().clone()); >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.cpp >index 73b2cf6faa34b30fc70ff7892dfd332570e585e0..7d0ee35aa379a171110d9c944fdcdfee22af62ac 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.cpp >@@ -118,8 +118,8 @@ void Visitor::visit(AST::TypeReference& typeReference) > { > for (auto& typeArgument : typeReference.typeArguments()) > checkErrorAndVisit(typeArgument); >- if (typeReference.resolvedType() && is<AST::TypeDefinition>(*typeReference.resolvedType())) { >- auto& typeDefinition = downcast<AST::TypeDefinition>(*typeReference.resolvedType()); >+ if (typeReference.maybeResolvedType() && is<AST::TypeDefinition>(typeReference.resolvedType())) { >+ auto& typeDefinition = downcast<AST::TypeDefinition>(typeReference.resolvedType()); > checkErrorAndVisit(typeDefinition.type()); > } > } >@@ -254,29 +254,29 @@ void Visitor::visit(AST::BooleanLiteral&) > > void Visitor::visit(AST::IntegerLiteralType& integerLiteralType) > { >- if (integerLiteralType.resolvedType()) >- checkErrorAndVisit(*integerLiteralType.resolvedType()); >+ if (integerLiteralType.maybeResolvedType()) >+ checkErrorAndVisit(integerLiteralType.resolvedType()); > checkErrorAndVisit(integerLiteralType.preferredType()); > } > > void Visitor::visit(AST::UnsignedIntegerLiteralType& unsignedIntegerLiteralType) > { >- if (unsignedIntegerLiteralType.resolvedType()) >- checkErrorAndVisit(*unsignedIntegerLiteralType.resolvedType()); >+ if (unsignedIntegerLiteralType.maybeResolvedType()) >+ checkErrorAndVisit(unsignedIntegerLiteralType.resolvedType()); > checkErrorAndVisit(unsignedIntegerLiteralType.preferredType()); > } > > void Visitor::visit(AST::FloatLiteralType& floatLiteralType) > { >- if (floatLiteralType.resolvedType()) >- checkErrorAndVisit(*floatLiteralType.resolvedType()); >+ if (floatLiteralType.maybeResolvedType()) >+ checkErrorAndVisit(floatLiteralType.resolvedType()); > checkErrorAndVisit(floatLiteralType.preferredType()); > } > > void Visitor::visit(AST::NullLiteralType& nullLiteralType) > { >- if (nullLiteralType.resolvedType()) >- checkErrorAndVisit(*nullLiteralType.resolvedType()); >+ if (nullLiteralType.maybeResolvedType()) >+ checkErrorAndVisit(nullLiteralType.resolvedType()); > } > > void Visitor::visit(AST::EnumerationMemberLiteral&) >@@ -466,7 +466,7 @@ void Visitor::visit(AST::Trap&) > void Visitor::visit(AST::VariableDeclarationsStatement& variableDeclarationsStatement) > { > for (auto& variableDeclaration : variableDeclarationsStatement.variableDeclarations()) >- checkErrorAndVisit(variableDeclaration); >+ checkErrorAndVisit(variableDeclaration.get()); > } > > void Visitor::visit(AST::WhileLoop& whileLoop) >@@ -523,17 +523,17 @@ void Visitor::visit(AST::LogicalNotExpression& logicalNotExpression) > > void Visitor::visit(AST::MakeArrayReferenceExpression& makeArrayReferenceExpression) > { >- checkErrorAndVisit(makeArrayReferenceExpression.lValue()); >+ checkErrorAndVisit(makeArrayReferenceExpression.leftValue()); > } > > void Visitor::visit(AST::MakePointerExpression& makePointerExpression) > { >- checkErrorAndVisit(makePointerExpression.lValue()); >+ checkErrorAndVisit(makePointerExpression.leftValue()); > } > > void Visitor::visit(AST::ReadModifyWriteExpression& readModifyWriteExpression) > { >- checkErrorAndVisit(readModifyWriteExpression.lValue()); >+ checkErrorAndVisit(readModifyWriteExpression.leftValue()); > checkErrorAndVisit(readModifyWriteExpression.oldValue()); > checkErrorAndVisit(readModifyWriteExpression.newValue()); > if (readModifyWriteExpression.newValueExpression()) >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.h >index cc8c86fef71399caba8b1c4f0c39d68c0aeac725..04dbc6becdd2757a183c270a33df09fd5f15b89b 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.h >@@ -105,7 +105,7 @@ class Visitor { > public: > virtual ~Visitor() = default; > >- // FIXME: Add a way to visit a const Program >+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198171 Add a way to visit a const Program > > virtual void visit(Program&); > virtual void visit(AST::UnnamedType&); >@@ -192,7 +192,7 @@ protected: > } > > private: >- bool m_error { false }; // FIXME: Migrate this to be some sort of descriptive string. >+ bool m_error { false }; // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195682 Migrate this to be some sort of descriptive string. > }; > > } // namespace WHLSL >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index 26614f1720783cbd3ef79eaafcc69609123f4af7..141022a6e60a09f31be5dbfbd029ed77fac0f4ac 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -349,6 +349,7 @@ Modules/webgpu/WHLSL/AST/WHLSLTypeReference.cpp > Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.cpp > Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.cpp > Modules/webgpu/WHLSL/WHLSLPrepare.cpp >+Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp > Modules/webgpu/WebGPU.cpp > Modules/webgpu/WebGPUAdapter.cpp > Modules/webgpu/WebGPUBindGroup.cpp >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 9d3918f728c31e3d09ae48997f970148bdb47546..e6a1f5f1d719b4af63fd9dda7e1afd745a6de907 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -6394,6 +6394,8 @@ > 1CA0C2EC21EED6F600A11860 /* WHLSLLiteralTypeChecker.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLLiteralTypeChecker.cpp; sourceTree = "<group>"; }; > 1CA19E030DC255950065A994 /* EventLoopMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = EventLoopMac.mm; sourceTree = "<group>"; }; > 1CA19E150DC255CA0065A994 /* EventLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventLoop.h; sourceTree = "<group>"; }; >+ 1CAA82F62242AE0500E84BBB /* WHLSLPropertyResolver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLPropertyResolver.cpp; sourceTree = "<group>"; }; >+ 1CAA82F72242AE0500E84BBB /* WHLSLPropertyResolver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLPropertyResolver.h; sourceTree = "<group>"; }; > 1CAF347E0A6C405200ABE06E /* WebScriptObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebScriptObject.h; sourceTree = "<group>"; }; > 1CAF347F0A6C405200ABE06E /* WebScriptObject.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebScriptObject.mm; sourceTree = "<group>"; }; > 1CAF34800A6C405200ABE06E /* WebScriptObjectPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebScriptObjectPrivate.h; sourceTree = "<group>"; }; >@@ -13211,6 +13213,8 @@ > C20F4F6421DFBE5C0070C45A /* WHLSLTypeReference.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLTypeReference.cpp; sourceTree = "<group>"; }; > C20F4F6621DFF2360070C45A /* WHLSLIntegerLiteral.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLIntegerLiteral.cpp; sourceTree = "<group>"; }; > C20F4F6721DFF3A70070C45A /* WHLSLUnsignedIntegerLiteral.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLUnsignedIntegerLiteral.cpp; sourceTree = "<group>"; }; >+ C20F88AA22966B0E00D610FA /* WHLSLASTDumper.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLASTDumper.cpp; sourceTree = "<group>"; }; >+ C20F88AC22966B0F00D610FA /* WHLSLASTDumper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLASTDumper.h; sourceTree = "<group>"; }; > C210E91121B4BD1000B7F83D /* WHLSLLexer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLLexer.cpp; sourceTree = "<group>"; }; > C210E91221B4BD1000B7F83D /* WHLSLLexer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLLexer.h; sourceTree = "<group>"; }; > C2138A1321DDECD300F516BA /* WHLSLBuiltInSemantic.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLBuiltInSemantic.cpp; sourceTree = "<group>"; }; >@@ -25395,6 +25399,8 @@ > children = ( > 1CA0C2F621EEDAD200A11860 /* AST */, > 1CECB3AD21F2B96400F44542 /* Metal */, >+ C20F88AA22966B0E00D610FA /* WHLSLASTDumper.cpp */, >+ C20F88AC22966B0F00D610FA /* WHLSLASTDumper.h */, > C234A9B221E92C1F003C984D /* WHLSLCheckDuplicateFunctions.cpp */, > C234A9AE21E92C1A003C984D /* WHLSLCheckDuplicateFunctions.h */, > 1C840B9B21EC400900D0500D /* WHLSLChecker.cpp */, >@@ -25423,6 +25429,8 @@ > C24A57BA21FEAFEA004C6DD1 /* WHLSLPrepare.cpp */, > C24A57BB21FEAFEA004C6DD1 /* WHLSLPrepare.h */, > C21BF73A21CD8D7000227979 /* WHLSLProgram.h */, >+ 1CAA82F62242AE0500E84BBB /* WHLSLPropertyResolver.cpp */, >+ 1CAA82F72242AE0500E84BBB /* WHLSLPropertyResolver.h */, > 1CA0C2E021EEB5F500A11860 /* WHLSLRecursionChecker.cpp */, > 1CA0C2DE21EEB5F400A11860 /* WHLSLRecursionChecker.h */, > C234A9AD21E92C19003C984D /* WHLSLRecursiveTypeChecker.cpp */, >diff --git a/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm b/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm >index 8fb4a26ca48b54caab187db29e3469a38504405f..e0292b8f544d4eacdba179fc0b234e4ec3aa73fd 100644 >--- a/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm >+++ b/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm >@@ -263,6 +263,8 @@ static bool trySetWHLSLFunctionsForPipelineDescriptor(const char* const function > if (!result) > return false; > >+ WTFLogAlways("Metal Source: %s", result->metalSource.utf8().data()); >+ > NSError *error = nil; > auto library = adoptNS([device.platformDevice() newLibraryWithSource:result->metalSource options:nil error:&error]); > ASSERT(library); >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 47453ae318256f230dadef3e0ecfe9e78400d930..503e2598c815288f4c1c718944b826e6af1218ce 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,14 @@ >+2019-05-23 Myles C. Maxfield <mmaxfield@apple.com> >+ >+ [WHLSL] Implement property resolver >+ https://bugs.webkit.org/show_bug.cgi?id=195925 >+ <rdar://problem/48219643> >+ >+ Reviewed by Saam Barati and Robin Morisset. >+ >+ * webgpu/whlsl-dot-expressions-expected.html: Added. >+ * webgpu/whlsl-dot-expressions.html: Added. >+ > 2019-05-22 Myles C. Maxfield <mmaxfield@apple.com> > > font-optical-sizing applies the wrong variation value >diff --git a/LayoutTests/webgpu/whlsl-dot-expressions-expected.html b/LayoutTests/webgpu/whlsl-dot-expressions-expected.html >new file mode 100644 >index 0000000000000000000000000000000000000000..f417050f9a743f05e9006fc91ac64d502dadd633 >--- /dev/null >+++ b/LayoutTests/webgpu/whlsl-dot-expressions-expected.html >@@ -0,0 +1,19 @@ >+<!DOCTYPE html> >+<html> >+<head> >+</head> >+<body> >+<canvas id="canvas" width="400" height="400"></canvas> >+<script> >+async function start() { >+ const canvas = document.getElementById("canvas"); >+ const context = canvas.getContext("2d"); >+ context.fillStyle = "blue"; >+ context.fillRect(0, 0, 400, 400); >+ context.fillStyle = "white"; >+ context.fillRect(100, 100, 200, 200); >+} >+window.addEventListener("load", start); >+</script> >+</body> >+</html> >diff --git a/LayoutTests/webgpu/whlsl-dot-expressions.html b/LayoutTests/webgpu/whlsl-dot-expressions.html >new file mode 100644 >index 0000000000000000000000000000000000000000..18ac9e64e47189e7606a1506a2a68ac01cb278ec >--- /dev/null >+++ b/LayoutTests/webgpu/whlsl-dot-expressions.html >@@ -0,0 +1,124 @@ >+<!DOCTYPE html> >+<html> >+<head> >+</head> >+<body> >+<canvas id="canvas" width="400" height="400"></canvas> >+<script> >+const shaderSource = ` >+struct VertexOut { >+ float4 position : SV_Position; >+ float shade : attribute(0); >+} >+ >+vertex VertexOut vertexShader(float4 position : attribute(0), float shade : attribute(1)) { >+ VertexOut result; >+ result.position = position; >+ result.shade = shade; >+ return result; >+} >+ >+fragment float4 fragmentShader(float shade : attribute(0)) : SV_Target 0 { >+ return float4(shade, shade, shade, 1.0); >+} >+`; >+async function start() { >+ const adapter = await navigator.gpu.requestAdapter(); >+ const device = await adapter.requestDevice(); >+ >+ const shaderModule = device.createShaderModule({code: shaderSource, isWHLSL: true}); >+ const vertexStage = {module: shaderModule, entryPoint: "vertexShader"}; >+ const fragmentStage = {module: shaderModule, entryPoint: "fragmentShader"}; >+ const primitiveTopology = "triangle-strip"; >+ const rasterizationState = {frontFace: "cw", cullMode: "none"}; >+ const alphaBlend = {}; >+ const colorBlend = {}; >+ const colorStates = [{format: "rgba8unorm", alphaBlend, colorBlend, writeMask: 15}]; // GPUColorWriteBits.ALL >+ const depthStencilState = null; >+ >+ const attribute0 = {shaderLocation: 0, inputSlot: 0, format: "float4", offset: 0}; >+ const attribute1 = {shaderLocation: 1, inputSlot: 0, format: "float", offset: 16}; >+ const attributes = [attribute0, attribute1]; >+ const input0 = {inputSlot: 0, stride: 20 }; >+ const inputs = [input0]; >+ const inputState = {indexFormat: "uint32", attributes, inputs}; >+ >+ const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "uniform-buffer"}]}; >+ const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor); >+ const pipelineLayoutDescriptor = {bindGroupLayouts: [bindGroupLayout]}; >+ const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor); >+ >+ const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, inputState, sampleCount: 1, layout: pipelineLayout}; >+ const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor); >+ >+ const vertexBuffer0Descriptor = {size: Float32Array.BYTES_PER_ELEMENT * 5 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE}; >+ const vertexBuffer0 = device.createBuffer(vertexBuffer0Descriptor); >+ const vertexBuffer0ArrayBuffer = await vertexBuffer0.mapWriteAsync(); >+ const vertexBuffer0Float32Array = new Float32Array(vertexBuffer0ArrayBuffer); >+ vertexBuffer0Float32Array[0] = -0.5; >+ vertexBuffer0Float32Array[1] = -0.5; >+ vertexBuffer0Float32Array[2] = 1.0; >+ vertexBuffer0Float32Array[3] = 1.0; >+ vertexBuffer0Float32Array[4] = 1.0; >+ >+ vertexBuffer0Float32Array[5] = -0.5; >+ vertexBuffer0Float32Array[6] = 0.5; >+ vertexBuffer0Float32Array[7] = 1.0; >+ vertexBuffer0Float32Array[8] = 1.0; >+ vertexBuffer0Float32Array[9] = 1.0; >+ >+ vertexBuffer0Float32Array[10] = 0.5; >+ vertexBuffer0Float32Array[11] = -0.5; >+ vertexBuffer0Float32Array[12] = 1.0; >+ vertexBuffer0Float32Array[13] = 1.0; >+ vertexBuffer0Float32Array[14] = 1.0; >+ >+ vertexBuffer0Float32Array[15] = 0.5; >+ vertexBuffer0Float32Array[16] = 0.5; >+ vertexBuffer0Float32Array[17] = 1.0; >+ vertexBuffer0Float32Array[18] = 1.0; >+ vertexBuffer0Float32Array[19] = 1.0; >+ vertexBuffer0.unmap(); >+ >+ const resourceBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.MAP_WRITE}; >+ const resourceBuffer = device.createBuffer(resourceBufferDescriptor); >+ const resourceBufferArrayBuffer = await resourceBuffer.mapWriteAsync(); >+ const resourceBufferFloat32Array = new Float32Array(resourceBufferArrayBuffer); >+ resourceBufferFloat32Array[0] = 1; >+ resourceBuffer.unmap(); >+ >+ const bufferBinding = {buffer: resourceBuffer, size: 4}; >+ const bindGroupBinding = {binding: 0, resource: bufferBinding}; >+ const bindGroupDescriptor = {layout: bindGroupLayout, bindings: [bindGroupBinding]}; >+ const bindGroup = device.createBindGroup(bindGroupDescriptor); >+ >+ const canvas = document.getElementById("canvas"); >+ const context = canvas.getContext("gpu"); >+ const swapChainDescriptor = {device, format: "bgra8unorm"}; >+ const swapChain = context.configureSwapChain(swapChainDescriptor); >+ const outputTexture = swapChain.getCurrentTexture(); >+ const outputTextureView = outputTexture.createDefaultView(); >+ >+ const commandEncoder = device.createCommandEncoder(); // {} >+ const red = {r: 0, g: 0, b: 1, a: 1}; >+ const colorAttachments = [{attachment: outputTextureView, resolveTarget: null, loadOp: "clear", storeOp: "store", clearColor: red}]; >+ const depthStencilAttachment = null; >+ const renderPassDescriptor = {colorAttachments, depthStencilAttachment}; >+ const renderPassEncoder = commandEncoder.beginRenderPass(renderPassDescriptor); >+ renderPassEncoder.setPipeline(renderPipeline); >+ renderPassEncoder.setBindGroup(0, bindGroup); >+ renderPassEncoder.setVertexBuffers(0, [vertexBuffer0], [0]); >+ renderPassEncoder.draw(4, 1, 0, 0); >+ renderPassEncoder.endPass(); >+ const commandBuffer = commandEncoder.finish(); >+ device.getQueue().submit([commandBuffer]); >+ >+ if (window.testRunner) >+ testRunner.notifyDone(); >+} >+if (window.testRunner) >+ testRunner.waitUntilDone(); >+window.addEventListener("load", start); >+</script> >+</body> >+</html>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 195925
:
365100
|
365130
|
365275
|
365291
|
365455
|
365648
|
365651
|
365669
|
365787
|
369928
|
370332
|
370338
|
370361
|
370366
|
370369
| 370493