Changeset 246138 in webkit
- Timestamp:
- Jun 5, 2019 7:17:15 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 35 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r246129 r246138 1 2019-06-05 Myles C. Maxfield <mmaxfield@apple.com> 2 3 [WHLSL] Educate the property resolver about IndexExpressions 4 https://bugs.webkit.org/show_bug.cgi?id=198399 5 6 Reviewed by Saam Barati. 7 8 * webgpu/propertyresolver/ander-abstract-lvalue-expected.html: Added. 9 * webgpu/propertyresolver/ander-abstract-lvalue.html: Added. 10 * webgpu/propertyresolver/ander-expected.html: Added. 11 * webgpu/propertyresolver/ander-lvalue-3-levels-expected.html: Added. 12 * webgpu/propertyresolver/ander-lvalue-3-levels.html: Added. 13 * webgpu/propertyresolver/ander-lvalue-expected.html: Added. 14 * webgpu/propertyresolver/ander-lvalue.html: Added. 15 * webgpu/propertyresolver/ander.html: Added. 16 * webgpu/propertyresolver/getter-expected.html: Added. 17 * webgpu/propertyresolver/getter.html: Added. 18 * webgpu/propertyresolver/indexer-ander-abstract-lvalue-expected.html: Added. 19 * webgpu/propertyresolver/indexer-ander-abstract-lvalue.html: Added. 20 * webgpu/propertyresolver/indexer-ander-expected.html: Added. 21 * webgpu/propertyresolver/indexer-ander-lvalue-3-levels-expected.html: Added. 22 * webgpu/propertyresolver/indexer-ander-lvalue-3-levels.html: Added. 23 * webgpu/propertyresolver/indexer-ander-lvalue-expected.html: Added. 24 * webgpu/propertyresolver/indexer-ander-lvalue.html: Added. 25 * webgpu/propertyresolver/indexer-ander.html: Added. 26 * webgpu/propertyresolver/indexer-getter-expected.html: Added. 27 * webgpu/propertyresolver/indexer-getter.html: Added. 28 * webgpu/propertyresolver/indexer-setter-abstract-lvalue-3-levels-expected.html: Added. 29 * webgpu/propertyresolver/indexer-setter-abstract-lvalue-3-levels.html: Added. 30 * webgpu/propertyresolver/indexer-setter-abstract-lvalue-expected.html: Added. 31 * webgpu/propertyresolver/indexer-setter-abstract-lvalue.html: Added. 32 * webgpu/propertyresolver/indexer-setter-expected.html: Added. 33 * webgpu/propertyresolver/indexer-setter-lvalue-expected.html: Added. 34 * webgpu/propertyresolver/indexer-setter-lvalue.html: Added. 35 * webgpu/propertyresolver/indexer-setter.html: Added. 36 * webgpu/propertyresolver/setter-abstract-lvalue-3-levels-expected.html: Added. 37 * webgpu/propertyresolver/setter-abstract-lvalue-3-levels.html: Added. 38 * webgpu/propertyresolver/setter-abstract-lvalue-expected.html: Added. 39 * webgpu/propertyresolver/setter-abstract-lvalue.html: Added. 40 * webgpu/propertyresolver/setter-lvalue-expected.html: Added. 41 * webgpu/propertyresolver/setter-lvalue.html: Added. 42 1 43 2019-06-05 Daniel Bates <dabates@apple.com> 2 44 -
trunk/Source/WebCore/ChangeLog
r246135 r246138 1 2019-06-05 Myles C. Maxfield <mmaxfield@apple.com> 2 3 [WHLSL] Educate the property resolver about IndexExpressions 4 https://bugs.webkit.org/show_bug.cgi?id=198399 5 6 Reviewed by Saam Barati. 7 8 This is part one of two patches which will allow buffers to work. This patch 9 adds support in the property resolver for index expressions. Index expressions 10 get turned into calls to "getter indexers", "setter indexers", or "ander 11 indexers". They work almost identically to dot expressions, except there is an 12 extra "index" expression which gets turned into an extra argument to those 13 functions. 14 15 There's actually a bit of a trick here. Let's say we need to run a getter and 16 a setter separately (e.g. "foo[3]++;"). The index expression can't be duplicated 17 for both the getter and the setter (e.g. the functions are 18 int operator[](Foo, uint) and Foo operator[]=(Foo, uint, int), and we aren't 19 allowed to execute the index expression multiple times. Consider if that "3" 20 in the example is actually "bar()" with some side effect. So, we have to run 21 the index expression once at the correct time, and save its result to a temporary 22 variable, and then pass in the temporary variable into the getter and setter. 23 24 So, if the code says "foo[bar()][baz()] = quux();" the following sequence of 25 functions get run: 26 27 - bar() 28 - operator[](Foo, uint) 29 - baz() 30 - quux() 31 - operator[]=(OtherType, uint, OtherOtherType) 32 - operator[]=(Foo, uint, OtherType) 33 34 The next patch will modify the WebGPU JavaScript implementation to send buffer 35 lengths to the shader, and for the shader compiler to correctly unpack this 36 information and place it inside the array references. That should be everything 37 that's needed to get buffers to work. After that, hooking up compute should be 38 fairly trivial. 39 40 Tests: webgpu/propertyresolver/ander-abstract-lvalue.html 41 webgpu/propertyresolver/ander-lvalue-3-levels.html 42 webgpu/propertyresolver/ander-lvalue.html 43 webgpu/propertyresolver/ander.html 44 webgpu/propertyresolver/getter.html 45 webgpu/propertyresolver/indexer-ander-abstract-lvalue.html 46 webgpu/propertyresolver/indexer-ander-lvalue-3-levels.html 47 webgpu/propertyresolver/indexer-ander-lvalue.html 48 webgpu/propertyresolver/indexer-ander.html 49 webgpu/propertyresolver/indexer-getter.html 50 webgpu/propertyresolver/indexer-setter-abstract-lvalue-3-levels.html 51 webgpu/propertyresolver/indexer-setter-abstract-lvalue.html 52 webgpu/propertyresolver/indexer-setter-lvalue.html 53 webgpu/propertyresolver/indexer-setter.html 54 webgpu/propertyresolver/setter-abstract-lvalue-3-levels.html 55 webgpu/propertyresolver/setter-abstract-lvalue.html 56 webgpu/propertyresolver/setter-lvalue.html 57 58 * Modules/webgpu/WHLSL/AST/WHLSLAddressSpace.h: 59 (WebCore::WHLSL::AST::toString): 60 * Modules/webgpu/WHLSL/AST/WHLSLEntryPointType.h: 61 (WebCore::WHLSL::AST::toString): 62 * Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h: 63 (WebCore::WHLSL::AST::IndexExpression::takeIndex): 64 * Modules/webgpu/WHLSL/AST/WHLSLReferenceType.h: 65 * Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp: 66 (WebCore::WHLSL::Metal::writeNativeFunction): 67 (WebCore::WHLSL::Metal::convertAddressSpace): Deleted. 68 * Modules/webgpu/WHLSL/WHLSLChecker.cpp: 69 (WebCore::WHLSL::checkOperatorOverload): 70 (WebCore::WHLSL::Checker::finishVisiting): 71 (WebCore::WHLSL::Checker::visit): 72 * Modules/webgpu/WHLSL/WHLSLInferTypes.h: 73 * Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp: 74 (WebCore::WHLSL::PropertyResolver::visit): 75 (WebCore::WHLSL::setterCall): 76 (WebCore::WHLSL::getterCall): 77 (WebCore::WHLSL::modify): 78 (WebCore::WHLSL::PropertyResolver::simplifyRightValue): 79 (WebCore::WHLSL::LeftValueSimplifier::finishVisiting): 80 (WebCore::WHLSL::LeftValueSimplifier::visit): 81 * Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt: 82 * Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.cpp: 83 (WebCore::WHLSL::synthesizeStructureAccessors): 84 1 85 2019-06-05 Robin Morisset <rmorisset@apple.com> 2 86 -
trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAddressSpace.h
r245680 r246138 44 44 }; 45 45 46 staticALWAYS_INLINE String toString(AddressSpace addressSpace)46 ALWAYS_INLINE String toString(AddressSpace addressSpace) 47 47 { 48 48 switch (addressSpace) { -
trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEntryPointType.h
r245680 r246138 42 42 }; 43 43 44 staticALWAYS_INLINE String toString(EntryPointType type)44 ALWAYS_INLINE String toString(EntryPointType type) 45 45 { 46 46 switch (type) { -
trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h
r245680 r246138 60 60 String setterFunctionName() const override 61 61 { 62 return "operator &[]"_str;62 return "operator[]="_str; 63 63 } 64 64 65 65 String anderFunctionName() const override 66 66 { 67 return "operator []="_str;67 return "operator&[]"_str; 68 68 } 69 69 70 70 Expression& indexExpression() { return m_index; } 71 UniqueRef<Expression> takeIndex() { return WTFMove(m_index); } 71 72 72 73 private: -
trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReferenceType.h
r246115 r246138 54 54 ReferenceType(ReferenceType&&) = default; 55 55 56 bool isReferenceType() const override { return false; }56 bool isReferenceType() const override { return true; } 57 57 58 58 AddressSpace addressSpace() const { return m_addressSpace; } -
trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp
r245680 r246138 64 64 } 65 65 66 static String convertAddressSpace(AST::AddressSpace addressSpace)67 {68 switch (addressSpace) {69 case AST::AddressSpace::Constant:70 return "constant"_str;71 case AST::AddressSpace::Device:72 return "device"_str;73 case AST::AddressSpace::Threadgroup:74 return "threadgroup"_str;75 default:76 ASSERT(addressSpace == AST::AddressSpace::Thread);77 return "thread"_str;78 }79 }80 81 66 static String atomicName(String input) 82 67 { … … 376 361 auto fourthArgumentAddressSpace = fourthArgumentPointer.addressSpace(); 377 362 auto fourthArgumentPointee = typeNamer.mangledNameForType(fourthArgumentPointer.elementType()); 378 stringBuilder.append(makeString("void ", outputFunctionName, '(', convertAddressSpace(firstArgumentAddressSpace), ' ', firstArgumentPointee, "* object, ", secondArgument, " compare, ", thirdArgument, " desired, ", convertAddressSpace(fourthArgumentAddressSpace), ' ', fourthArgumentPointee, "* out) {\n"));363 stringBuilder.append(makeString("void ", outputFunctionName, '(', toString(firstArgumentAddressSpace), ' ', firstArgumentPointee, "* object, ", secondArgument, " compare, ", thirdArgument, " desired, ", toString(fourthArgumentAddressSpace), ' ', fourthArgumentPointee, "* out) {\n")); 379 364 stringBuilder.append(" atomic_compare_exchange_weak_explicit(object, &compare, desired, memory_order_relaxed);\n"); 380 365 stringBuilder.append(" *out = compare;\n"); … … 394 379 auto thirdArgumentPointee = typeNamer.mangledNameForType(thirdArgumentPointer.elementType()); 395 380 auto name = atomicName(nativeFunctionDeclaration.name().substring("Interlocked"_str.length())); 396 stringBuilder.append(makeString("void ", outputFunctionName, '(', convertAddressSpace(firstArgumentAddressSpace), ' ', firstArgumentPointee, "* object, ", secondArgument, " operand, ", convertAddressSpace(thirdArgumentAddressSpace), ' ', thirdArgumentPointee, "* out) {\n"));381 stringBuilder.append(makeString("void ", outputFunctionName, '(', toString(firstArgumentAddressSpace), ' ', firstArgumentPointee, "* object, ", secondArgument, " operand, ", toString(thirdArgumentAddressSpace), ' ', thirdArgumentPointee, "* out) {\n")); 397 382 stringBuilder.append(makeString(" *out = atomic_fetch_", name, "_explicit(object, operand, memory_order_relaxed);\n")); 398 383 stringBuilder.append("}\n"); -
trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp
r246121 r246138 37 37 #include "WHLSLDoWhileLoop.h" 38 38 #include "WHLSLDotExpression.h" 39 #include "WHLSLEntryPointType.h" 39 40 #include "WHLSLForLoop.h" 40 41 #include "WHLSLGatherEntryPointItems.h" … … 355 356 Vector<std::reference_wrapper<ResolvingType>> argumentTypeReferences; 356 357 for (size_t i = 0; i < numExpectedParameters - 1; ++i) 357 argumentTypes.append((*functionDefinition.parameters()[ 0]->type())->clone());358 argumentTypes.append((*functionDefinition.parameters()[i]->type())->clone()); 358 359 for (auto& argumentType : argumentTypes) 359 360 argumentTypeReferences.append(argumentType); … … 492 493 void visit(AST::CallExpression&) override; 493 494 495 void finishVisiting(AST::PropertyAccessExpression&, ResolvingType* additionalArgumentType = nullptr); 496 494 497 HashMap<AST::Expression*, ResolvingType> m_typeMap; 495 498 HashMap<AST::Expression*, AST::TypeAnnotation> m_typeAnnotations; … … 967 970 } 968 971 969 void Checker:: visit(AST::DotExpression& dotExpression)970 { 971 auto baseInfo = recurseAndGetInfo( dotExpression.base());972 void Checker::finishVisiting(AST::PropertyAccessExpression& propertyAccessExpression, ResolvingType* additionalArgumentType) 973 { 974 auto baseInfo = recurseAndGetInfo(propertyAccessExpression.base()); 972 975 if (!baseInfo) 973 976 return; … … 980 983 { 981 984 Vector<std::reference_wrapper<ResolvingType>> getterArgumentTypes { baseInfo->resolvingType }; 982 getterFunction = resolveFunctionOverloadImpl(dotExpression.possibleGetterOverloads(), getterArgumentTypes, nullptr); 983 if (getterFunction) 985 if (additionalArgumentType) 986 getterArgumentTypes.append(*additionalArgumentType); 987 if ((getterFunction = resolveFunctionOverloadImpl(propertyAccessExpression.possibleGetterOverloads(), getterArgumentTypes, nullptr))) 984 988 getterReturnType = &getterFunction->type(); 985 989 } … … 987 991 AST::FunctionDeclaration* anderFunction = nullptr; 988 992 AST::UnnamedType* anderReturnType = nullptr; 989 if (auto leftAddressSpace = baseInfo->typeAnnotation.leftAddressSpace()) { 990 auto argumentType = makeUniqueRef<AST::PointerType>(Lexer::Token(dotExpression.origin()), *leftAddressSpace, baseUnnamedType->get().clone()); 991 Vector<std::reference_wrapper<ResolvingType>> anderArgumentTypes { baseInfo->resolvingType }; 992 anderFunction = resolveFunctionOverloadImpl(dotExpression.possibleAnderOverloads(), anderArgumentTypes, nullptr); 993 if (anderFunction) 993 auto leftAddressSpace = baseInfo->typeAnnotation.leftAddressSpace(); 994 if (leftAddressSpace) { 995 ResolvingType argumentType = { makeUniqueRef<AST::PointerType>(Lexer::Token(propertyAccessExpression.origin()), *leftAddressSpace, baseUnnamedType->get().clone()) }; 996 Vector<std::reference_wrapper<ResolvingType>> anderArgumentTypes { argumentType }; 997 if (additionalArgumentType) 998 anderArgumentTypes.append(*additionalArgumentType); 999 if ((anderFunction = resolveFunctionOverloadImpl(propertyAccessExpression.possibleAnderOverloads(), anderArgumentTypes, nullptr))) 994 1000 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 995 1001 } … … 998 1004 AST::UnnamedType* threadAnderReturnType = nullptr; 999 1005 { 1000 auto argumentType = makeUniqueRef<AST::PointerType>(Lexer::Token(dotExpression.origin()), AST::AddressSpace::Thread, baseUnnamedType->get().clone()); 1001 Vector<std::reference_wrapper<ResolvingType>> threadAnderArgumentTypes { baseInfo->resolvingType }; 1002 threadAnderFunction = resolveFunctionOverloadImpl(dotExpression.possibleAnderOverloads(), threadAnderArgumentTypes, nullptr); 1003 if (threadAnderFunction) 1006 ResolvingType argumentType = { makeUniqueRef<AST::PointerType>(Lexer::Token(propertyAccessExpression.origin()), AST::AddressSpace::Thread, baseUnnamedType->get().clone()) }; 1007 Vector<std::reference_wrapper<ResolvingType>> threadAnderArgumentTypes { argumentType }; 1008 if (additionalArgumentType) 1009 threadAnderArgumentTypes.append(*additionalArgumentType); 1010 if ((threadAnderFunction = resolveFunctionOverloadImpl(propertyAccessExpression.possibleAnderOverloads(), threadAnderArgumentTypes, nullptr))) 1004 1011 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 1005 1012 } 1006 1013 1007 if (!getterFunction && !anderFunction) { 1008 setError(); 1009 return; 1010 } 1011 if (getterFunction && anderFunction) { 1012 setError(); 1013 return; 1014 } 1014 if (leftAddressSpace && !anderFunction && !getterFunction) { 1015 setError(); 1016 return; 1017 } 1018 1019 if (!leftAddressSpace && !threadAnderFunction && !getterFunction) { 1020 setError(); 1021 return; 1022 } 1023 1024 if (threadAnderFunction && getterFunction) { 1025 setError(); 1026 return; 1027 } 1028 1015 1029 if (anderFunction && threadAnderFunction && !matches(*anderReturnType, *threadAnderReturnType)) { 1016 1030 setError(); … … 1018 1032 } 1019 1033 1020 AST::UnnamedType* fieldType = getterReturnType ? getterReturnType : anderReturnType; 1034 if (getterFunction && anderFunction && !matches(*getterReturnType, *anderReturnType)) { 1035 setError(); 1036 return; 1037 } 1038 1039 if (getterFunction && threadAnderFunction && !matches(*getterReturnType, *threadAnderReturnType)) { 1040 setError(); 1041 return; 1042 } 1043 1044 AST::UnnamedType* fieldType = getterReturnType ? getterReturnType : anderReturnType ? anderReturnType : threadAnderReturnType; 1021 1045 1022 1046 AST::FunctionDeclaration* setterFunction = nullptr; … … 1024 1048 { 1025 1049 ResolvingType fieldResolvingType(fieldType->clone()); 1026 Vector<std::reference_wrapper<ResolvingType>> setterArgumentTypes { baseInfo->resolvingType, fieldResolvingType }; 1027 setterFunction = resolveFunctionOverloadImpl(dotExpression.possibleSetterOverloads(), setterArgumentTypes, nullptr); 1050 Vector<std::reference_wrapper<ResolvingType>> setterArgumentTypes { baseInfo->resolvingType }; 1051 if (additionalArgumentType) 1052 setterArgumentTypes.append(*additionalArgumentType); 1053 setterArgumentTypes.append(fieldResolvingType); 1054 setterFunction = resolveFunctionOverloadImpl(propertyAccessExpression.possibleSetterOverloads(), setterArgumentTypes, nullptr); 1028 1055 if (setterFunction) 1029 1056 setterReturnType = &setterFunction->type(); 1030 1057 } 1031 1058 1032 if (setterFunction && anderFunction) {1033 setError(); 1034 return; 1035 } 1036 1037 dotExpression.setGetterFunction(getterFunction);1038 dotExpression.setAnderFunction(anderFunction);1039 dotExpression.setThreadAnderFunction(threadAnderFunction);1040 dotExpression.setSetterFunction(setterFunction);1059 if (setterFunction && !getterFunction) { 1060 setError(); 1061 return; 1062 } 1063 1064 propertyAccessExpression.setGetterFunction(getterFunction); 1065 propertyAccessExpression.setAnderFunction(anderFunction); 1066 propertyAccessExpression.setThreadAnderFunction(threadAnderFunction); 1067 propertyAccessExpression.setSetterFunction(setterFunction); 1041 1068 1042 1069 AST::TypeAnnotation typeAnnotation = AST::RightValue(); … … 1046 1073 else if (setterFunction) 1047 1074 typeAnnotation = AST::AbstractLeftValue(); 1048 } else if (!baseInfo->typeAnnotation.isRightValue() && (setterFunction || anderFunction))1075 } else if (!baseInfo->typeAnnotation.isRightValue() && (setterFunction || threadAnderFunction)) 1049 1076 typeAnnotation = AST::AbstractLeftValue(); 1050 assignType(dotExpression, fieldType->clone(), WTFMove(typeAnnotation)); 1051 } 1052 1053 void Checker::visit(AST::IndexExpression&) 1054 { 1055 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198163 Implement this. 1077 assignType(propertyAccessExpression, fieldType->clone(), WTFMove(typeAnnotation)); 1078 } 1079 1080 void Checker::visit(AST::DotExpression& dotExpression) 1081 { 1082 finishVisiting(dotExpression); 1083 } 1084 1085 void Checker::visit(AST::IndexExpression& indexExpression) 1086 { 1087 auto baseInfo = recurseAndGetInfo(indexExpression.indexExpression()); 1088 if (!baseInfo) 1089 return; 1090 finishVisiting(indexExpression, &baseInfo->resolvingType); 1056 1091 } 1057 1092 … … 1363 1398 return; 1364 1399 auto lastInfo = getInfo(commaExpression.list().last()); 1365 forwardType(commaExpression, lastInfo->resolvingType , lastInfo->typeAnnotation);1400 forwardType(commaExpression, lastInfo->resolvingType); 1366 1401 } 1367 1402 -
trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.h
r243091 r246138 48 48 bool matches(const AST::NamedType&, const AST::NamedType&); 49 49 bool matches(const AST::UnnamedType&, const AST::NamedType&); 50 // FIXME: Is anyone actually using the return type here?51 50 Optional<UniqueRef<AST::UnnamedType>> matchAndCommit(AST::UnnamedType&, AST::ResolvableType&); 52 51 Optional<UniqueRef<AST::UnnamedType>> matchAndCommit(AST::NamedType&, AST::ResolvableType&); -
trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp
r245745 r246138 52 52 void visit(AST::FunctionDefinition&) override; 53 53 void visit(AST::DotExpression&) override; 54 void visit(AST::IndexExpression&) override; 54 55 void visit(AST::AssignmentExpression&) override; 55 56 void visit(AST::ReadModifyWriteExpression&) override; 56 57 57 bool simplifyRightValue(AST:: DotExpression&);58 bool simplifyRightValue(AST::PropertyAccessExpression&); 58 59 bool simplifyAbstractLeftValue(AST::AssignmentExpression&, AST::DotExpression&, UniqueRef<AST::Expression>&& right); 59 60 void simplifyLeftValue(AST::Expression&); … … 69 70 } 70 71 72 void PropertyResolver::visit(AST::IndexExpression& indexExpression) 73 { 74 checkErrorAndVisit(indexExpression.indexExpression()); 75 // Unless we're inside an AssignmentExpression or a ReadModifyWriteExpression, we're a right value. 76 if (!simplifyRightValue(indexExpression)) 77 setError(); 78 } 79 71 80 void PropertyResolver::visit(AST::FunctionDefinition& functionDefinition) 72 81 { … … 76 85 } 77 86 78 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) 79 { 80 if (dotExpression.anderFunction()) { 87 static Optional<UniqueRef<AST::Expression>> setterCall(AST::PropertyAccessExpression& propertyAccessExpression, AST::FunctionDeclaration* relevantAnder, UniqueRef<AST::Expression>&& newValue, const std::function<UniqueRef<AST::Expression>()>& leftValueFactory, const std::function<UniqueRef<AST::Expression>()>& pointerToLeftValueFactory, AST::VariableDeclaration* indexVariable) 88 { 89 auto maybeAddIndexArgument = [&](Vector<UniqueRef<AST::Expression>>& arguments) { 90 if (!indexVariable) 91 return; 92 auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(*indexVariable)); 93 ASSERT(indexVariable->type()); 94 variableReference->setType(indexVariable->type()->clone()); 95 variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? 96 arguments.append(WTFMove(variableReference)); 97 }; 98 99 if (relevantAnder) { 81 100 // *operator&.foo(&v) = newValue 82 if (!dotExpression.threadAnderFunction())83 return WTF::nullopt;84 85 101 Vector<UniqueRef<AST::Expression>> arguments; 86 102 arguments.append(pointerToLeftValueFactory()); 87 auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(dotExpression.origin()), String(dotExpression.threadAnderFunction()->name()), WTFMove(arguments)); 88 callExpression->setType(dotExpression.threadAnderFunction()->type().clone()); 103 maybeAddIndexArgument(arguments); 104 105 auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(propertyAccessExpression.origin()), String(relevantAnder->name()), WTFMove(arguments)); 106 callExpression->setType(relevantAnder->type().clone()); 89 107 callExpression->setTypeAnnotation(AST::RightValue()); 90 callExpression->setFunction(* dotExpression.threadAnderFunction());91 92 auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(Lexer::Token( dotExpression.origin()), WTFMove(callExpression));93 dereferenceExpression->setType(downcast<AST::PointerType>( dotExpression.threadAnderFunction()->type()).elementType().clone());108 callExpression->setFunction(*relevantAnder); 109 110 auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(Lexer::Token(propertyAccessExpression.origin()), WTFMove(callExpression)); 111 dereferenceExpression->setType(downcast<AST::PointerType>(relevantAnder->type()).elementType().clone()); 94 112 dereferenceExpression->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); 95 113 96 auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token( dotExpression.origin()), WTFMove(dereferenceExpression), WTFMove(newValue));97 assignmentExpression->setType(downcast<AST::PointerType>( dotExpression.threadAnderFunction()->type()).elementType().clone());114 auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(propertyAccessExpression.origin()), WTFMove(dereferenceExpression), WTFMove(newValue)); 115 assignmentExpression->setType(downcast<AST::PointerType>(relevantAnder->type()).elementType().clone()); 98 116 assignmentExpression->setTypeAnnotation(AST::RightValue()); 99 117 … … 102 120 103 121 // v = operator.foo=(v, newValue) 104 ASSERT( dotExpression.setterFunction());122 ASSERT(propertyAccessExpression.setterFunction()); 105 123 106 124 Vector<UniqueRef<AST::Expression>> arguments; 107 125 arguments.append(leftValueFactory()); 126 maybeAddIndexArgument(arguments); 108 127 arguments.append(WTFMove(newValue)); 109 auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(dotExpression.origin()), String(dotExpression.setterFunction()->name()), WTFMove(arguments)); 110 callExpression->setType(dotExpression.setterFunction()->type().clone()); 128 129 auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(propertyAccessExpression.origin()), String(propertyAccessExpression.setterFunction()->name()), WTFMove(arguments)); 130 callExpression->setType(propertyAccessExpression.setterFunction()->type().clone()); 111 131 callExpression->setTypeAnnotation(AST::RightValue()); 112 callExpression->setFunction(* dotExpression.setterFunction());113 114 auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token( dotExpression.origin()), leftValueFactory(), WTFMove(callExpression));115 assignmentExpression->setType( dotExpression.setterFunction()->type().clone());132 callExpression->setFunction(*propertyAccessExpression.setterFunction()); 133 134 auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(propertyAccessExpression.origin()), leftValueFactory(), WTFMove(callExpression)); 135 assignmentExpression->setType(propertyAccessExpression.setterFunction()->type().clone()); 116 136 assignmentExpression->setTypeAnnotation(AST::RightValue()); 117 137 … … 119 139 } 120 140 121 static Optional<UniqueRef<AST::Expression>> getterCall(AST::DotExpression& dotExpression, const std::function<UniqueRef<AST::Expression>()>& leftValueFactory, const std::function<UniqueRef<AST::Expression>()>& pointerToLeftValueFactory) 122 { 123 if (dotExpression.anderFunction()) { 141 static Optional<UniqueRef<AST::Expression>> getterCall(AST::PropertyAccessExpression& propertyAccessExpression, AST::FunctionDeclaration* relevantAnder, const std::function<UniqueRef<AST::Expression>()>& leftValueFactory, const std::function<UniqueRef<AST::Expression>()>& pointerToLeftValueFactory, AST::VariableDeclaration* indexVariable) 142 { 143 auto maybeAddIndexArgument = [&](Vector<UniqueRef<AST::Expression>>& arguments) { 144 if (!indexVariable) 145 return; 146 auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(*indexVariable)); 147 ASSERT(indexVariable->type()); 148 variableReference->setType(indexVariable->type()->clone()); 149 variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? 150 arguments.append(WTFMove(variableReference)); 151 }; 152 153 if (relevantAnder) { 124 154 // *operator&.foo(&v) 125 if (!dotExpression.threadAnderFunction())126 return WTF::nullopt;127 128 155 Vector<UniqueRef<AST::Expression>> arguments; 129 156 arguments.append(pointerToLeftValueFactory()); 130 auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(dotExpression.origin()), String(dotExpression.threadAnderFunction()->name()), WTFMove(arguments)); 131 callExpression->setType(dotExpression.threadAnderFunction()->type().clone()); 157 maybeAddIndexArgument(arguments); 158 159 auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(propertyAccessExpression.origin()), String(relevantAnder->name()), WTFMove(arguments)); 160 callExpression->setType(relevantAnder->type().clone()); 132 161 callExpression->setTypeAnnotation(AST::RightValue()); 133 callExpression->setFunction(* dotExpression.threadAnderFunction());134 135 auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(Lexer::Token( dotExpression.origin()), WTFMove(callExpression));136 dereferenceExpression->setType(downcast<AST::PointerType>( dotExpression.threadAnderFunction()->type()).elementType().clone());162 callExpression->setFunction(*relevantAnder); 163 164 auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(Lexer::Token(propertyAccessExpression.origin()), WTFMove(callExpression)); 165 dereferenceExpression->setType(downcast<AST::PointerType>(relevantAnder->type()).elementType().clone()); 137 166 dereferenceExpression->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); 138 167 … … 141 170 142 171 // operator.foo(v) 143 ASSERT( dotExpression.getterFunction());172 ASSERT(propertyAccessExpression.getterFunction()); 144 173 145 174 Vector<UniqueRef<AST::Expression>> arguments; 146 175 arguments.append(leftValueFactory()); 147 auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(dotExpression.origin()), String(dotExpression.getterFunction()->name()), WTFMove(arguments)); 148 callExpression->setType(dotExpression.getterFunction()->type().clone()); 176 maybeAddIndexArgument(arguments); 177 178 auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(propertyAccessExpression.origin()), String(propertyAccessExpression.getterFunction()->name()), WTFMove(arguments)); 179 callExpression->setType(propertyAccessExpression.getterFunction()->type().clone()); 149 180 callExpression->setTypeAnnotation(AST::RightValue()); 150 callExpression->setFunction(* dotExpression.getterFunction());181 callExpression->setFunction(*propertyAccessExpression.getterFunction()); 151 182 152 183 return UniqueRef<AST::Expression>(WTFMove(callExpression)); … … 162 193 UniqueRef<AST::Expression> result; 163 194 }; 164 static Optional<ModifyResult> modify(AST:: DotExpression& dotExpression, std::function<Optional<ModificationResult>(Optional<UniqueRef<AST::Expression>>&&)> modification)195 static Optional<ModifyResult> modify(AST::PropertyAccessExpression& propertyAccessExpression, std::function<Optional<ModificationResult>(Optional<UniqueRef<AST::Expression>>&&)> modification) 165 196 { 166 197 // Consider a.b.c.d++; … … 182 213 // q = operator.c=(q, r); 183 214 // 184 // Step 4:215 // Step 5: 185 216 // *p = operator.b=(*p, q); 186 217 … … 189 220 190 221 // Find the ".b" ".c" and ".d" expressions. They end up in the order [".d", ".c", ".b"]. 191 Vector<std::reference_wrapper<AST:: DotExpression>> chain;192 AST:: DotExpression* iterator = &dotExpression;222 Vector<std::reference_wrapper<AST::PropertyAccessExpression>> chain; 223 AST::PropertyAccessExpression* iterator = &propertyAccessExpression; 193 224 while (true) { 194 225 chain.append(*iterator); … … 196 227 break; 197 228 ASSERT(!iterator->base().typeAnnotation().isRightValue()); 198 ASSERT(is<AST:: DotExpression>(iterator->base())); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198163 Make this work with index expressions199 iterator = &downcast<AST:: DotExpression>(iterator->base());229 ASSERT(is<AST::PropertyAccessExpression>(iterator->base())); 230 iterator = &downcast<AST::PropertyAccessExpression>(iterator->base()); 200 231 } 201 232 auto leftExpression = iterator->takeBase(); … … 209 240 intermediateVariables.reserveInitialCapacity(chain.size() - 1); 210 241 for (size_t i = 1; i < chain.size(); ++i) { 211 auto& dotExpression = static_cast<AST::DotExpression&>(chain[i]); 212 intermediateVariables.uncheckedAppend(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(dotExpression.origin()), AST::Qualifiers(), dotExpression.resolvedType().clone(), String(), WTF::nullopt, WTF::nullopt)); 242 auto& propertyAccessExpression = static_cast<AST::PropertyAccessExpression&>(chain[i]); 243 intermediateVariables.uncheckedAppend(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(propertyAccessExpression.origin()), AST::Qualifiers(), propertyAccessExpression.resolvedType().clone(), String(), WTF::nullopt, WTF::nullopt)); 244 } 245 246 // Consider a[foo()][b] = c; 247 // Naively, This would get expanded to: 248 // 249 // temp = operator[](a, foo()); 250 // temp = operator[]=(temp, b, c); 251 // a = operator[]=(a, foo(), temp); 252 // 253 // However, if we did this, we would have to run foo() twice, which would be incorrect. 254 // Instead, we need to save foo() and b into more temporary variables. 255 // These temporary variables are parallel to "chain" above, with nullopt referring to a DotExpression (which doesn't have an index value to save to a variable). 256 // 257 // Instead, this gets expanded to: 258 // 259 // p = &a; 260 // temp = foo(); 261 // q = operator[](*p, temp); 262 // temp2 = b; 263 // q = operator[]=(q, temp2, c); 264 // *p = operator[]=(*p, temp, q); 265 266 Vector<Optional<UniqueRef<AST::VariableDeclaration>>> indexVariables; 267 indexVariables.reserveInitialCapacity(chain.size()); 268 for (AST::PropertyAccessExpression& propertyAccessExpression : chain) { 269 if (!is<AST::IndexExpression>(propertyAccessExpression)) { 270 indexVariables.append(WTF::nullopt); 271 continue; 272 } 273 auto& indexExpression = downcast<AST::IndexExpression>(propertyAccessExpression); 274 indexVariables.uncheckedAppend(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(propertyAccessExpression.origin()), AST::Qualifiers(), indexExpression.indexExpression().resolvedType().clone(), String(), WTF::nullopt, WTF::nullopt)); 213 275 } 214 276 … … 249 311 variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? 250 312 251 auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(Lexer::Token( dotExpression.origin()), WTFMove(variableReference));313 auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(Lexer::Token(propertyAccessExpression.origin()), WTFMove(variableReference)); 252 314 ASSERT(pointerVariable->type()); 253 315 dereferenceExpression->setType(downcast<AST::PointerType>(*pointerVariable->type()).elementType().clone()); … … 262 324 variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? 263 325 264 auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token( dotExpression.origin()), WTFMove(variableReference));326 auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(propertyAccessExpression.origin()), WTFMove(variableReference)); 265 327 ASSERT(previous->type()); 266 makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token( dotExpression.origin()), AST::AddressSpace::Thread, previous->type()->clone()));328 makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(propertyAccessExpression.origin()), AST::AddressSpace::Thread, previous->type()->clone())); 267 329 makePointerExpression->setTypeAnnotation(AST::RightValue()); 268 330 return makePointerExpression; … … 275 337 return variableReference; 276 338 }; 339 auto appendIndexAssignment = [&](AST::PropertyAccessExpression& propertyAccessExpression, Optional<UniqueRef<AST::VariableDeclaration>>& indexVariable) { 340 if (!indexVariable) 341 return; 342 343 auto& indexExpression = downcast<AST::IndexExpression>(propertyAccessExpression); 344 345 auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(*indexVariable)); 346 ASSERT(indexVariable->get().type()); 347 variableReference->setType(indexVariable->get().type()->clone()); 348 variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? 349 350 auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(propertyAccessExpression.origin()), WTFMove(variableReference), indexExpression.takeIndex()); 351 assignmentExpression->setType(indexVariable->get().type()->clone()); 352 assignmentExpression->setTypeAnnotation(AST::RightValue()); 353 354 expressions.append(WTFMove(assignmentExpression)); 355 }; 277 356 for (size_t i = chain.size(); --i; ) { 278 AST:: DotExpression& dotExpression = chain[i];357 AST::PropertyAccessExpression& propertyAccessExpression = chain[i]; 279 358 AST::VariableDeclaration& variableDeclaration = intermediateVariables[i - 1]; 280 281 auto callExpression = getterCall(dotExpression, previousLeftValue, pointerToPreviousLeftValue); 359 Optional<UniqueRef<AST::VariableDeclaration>>& indexVariable = indexVariables[i]; 360 361 appendIndexAssignment(propertyAccessExpression, indexVariable); 362 363 AST::FunctionDeclaration* relevantAnder = i == chain.size() - 1 ? propertyAccessExpression.anderFunction() : propertyAccessExpression.threadAnderFunction(); 364 auto callExpression = getterCall(propertyAccessExpression, relevantAnder, previousLeftValue, pointerToPreviousLeftValue, indexVariable ? &*indexVariable : nullptr); 282 365 283 366 if (!callExpression) … … 289 372 variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? 290 373 291 auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token( dotExpression.origin()), WTFMove(variableReference), WTFMove(*callExpression));374 auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(propertyAccessExpression.origin()), WTFMove(variableReference), WTFMove(*callExpression)); 292 375 assignmentExpression->setType(variableDeclaration.type()->clone()); 293 376 assignmentExpression->setTypeAnnotation(AST::RightValue()); … … 297 380 previous = &variableDeclaration; 298 381 } 299 auto lastGetterCallExpression = getterCall(chain[0], previousLeftValue, pointerToPreviousLeftValue); 382 appendIndexAssignment(chain[0], indexVariables[0]); 383 AST::FunctionDeclaration* relevantAnder = chain.size() == 1 ? propertyAccessExpression.anderFunction() : propertyAccessExpression.threadAnderFunction(); 384 auto lastGetterCallExpression = getterCall(chain[0], relevantAnder, previousLeftValue, pointerToPreviousLeftValue, indexVariables[0] ? &*(indexVariables[0]) : nullptr); 300 385 301 386 // Step 3: … … 310 395 auto expressionType = rightValue->resolvedType().clone(); 311 396 for (size_t i = 0; i < chain.size() - 1; ++i) { 312 AST:: DotExpression& dotExpression = chain[i];397 AST::PropertyAccessExpression& propertyAccessExpression = chain[i]; 313 398 AST::VariableDeclaration& variableDeclaration = intermediateVariables[i]; 314 315 auto assignmentExpression = setterCall(dotExpression, WTFMove(rightValue), [&]() -> UniqueRef<AST::Expression> { 399 Optional<UniqueRef<AST::VariableDeclaration>>& indexVariable = indexVariables[i]; 400 401 auto assignmentExpression = setterCall(propertyAccessExpression, propertyAccessExpression.threadAnderFunction(), WTFMove(rightValue), [&]() -> UniqueRef<AST::Expression> { 316 402 auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration)); 317 403 ASSERT(variableDeclaration.type()); … … 325 411 variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? 326 412 327 auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token( dotExpression.origin()), WTFMove(variableReference));413 auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(propertyAccessExpression.origin()), WTFMove(variableReference)); 328 414 ASSERT(variableDeclaration.type()); 329 makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token( dotExpression.origin()), AST::AddressSpace::Thread, variableDeclaration.type()->clone()));415 makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(propertyAccessExpression.origin()), AST::AddressSpace::Thread, variableDeclaration.type()->clone())); 330 416 makePointerExpression->setTypeAnnotation(AST::RightValue()); 331 417 return makePointerExpression; 332 } );418 }, indexVariable ? &*indexVariable : nullptr); 333 419 334 420 if (!assignmentExpression) … … 345 431 // Step 5: 346 432 { 347 auto assignmentExpression = setterCall(chain[chain.size() - 1], WTFMove(rightValue), [&]() -> UniqueRef<AST::Expression> { 433 AST::PropertyAccessExpression& propertyAccessExpression = chain[chain.size() - 1]; 434 auto assignmentExpression = setterCall(propertyAccessExpression, propertyAccessExpression.anderFunction(), WTFMove(rightValue), [&]() -> UniqueRef<AST::Expression> { 348 435 auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(pointerVariable)); 349 436 ASSERT(pointerVariable->type()); … … 351 438 variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? 352 439 353 auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(Lexer::Token( dotExpression.origin()), WTFMove(variableReference));440 auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(Lexer::Token(propertyAccessExpression.origin()), WTFMove(variableReference)); 354 441 ASSERT(pointerVariable->type()); 355 442 dereferenceExpression->setType(downcast<AST::PointerType>(*pointerVariable->type()).elementType().clone()); … … 362 449 variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right? 363 450 return variableReference; 364 } );451 }, indexVariables[indexVariables.size() - 1] ? &*(indexVariables[indexVariables.size() - 1]) : nullptr); 365 452 366 453 if (!assignmentExpression) … … 374 461 for (auto& intermediateVariable : intermediateVariables) 375 462 variableDeclarations.append(WTFMove(intermediateVariable)); 463 for (auto& indexVariable : indexVariables) { 464 if (indexVariable) 465 variableDeclarations.append(WTFMove(*indexVariable)); 466 } 376 467 377 468 return {{ innerLeftExpression, WTFMove(expressions), WTFMove(variableDeclarations) }}; … … 386 477 } 387 478 ASSERT(!assignmentExpression.left().typeAnnotation().isRightValue()); 388 if (!is<AST::DotExpression>(assignmentExpression.left())) { 389 setError(); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198163 Make this work with index expressions. 390 return; 391 } 479 ASSERT(is<AST::PropertyAccessExpression>(assignmentExpression.left())); 392 480 393 481 auto type = assignmentExpression.right().resolvedType().clone(); … … 395 483 checkErrorAndVisit(assignmentExpression.right()); 396 484 397 auto modifyResult = modify(downcast<AST:: DotExpression>(assignmentExpression.left()), [&](Optional<UniqueRef<AST::Expression>>&&) -> Optional<ModificationResult> {485 auto modifyResult = modify(downcast<AST::PropertyAccessExpression>(assignmentExpression.left()), [&](Optional<UniqueRef<AST::Expression>>&&) -> Optional<ModificationResult> { 398 486 return {{ Vector<UniqueRef<AST::Expression>>(), assignmentExpression.takeRight() }}; 399 487 }); … … 425 513 // *p = newValue; 426 514 515 simplifyLeftValue(readModifyWriteExpression.leftValue()); 516 427 517 auto baseType = readModifyWriteExpression.leftValue().resolvedType().clone(); 428 518 auto pointerType = makeUniqueRef<AST::PointerType>(Lexer::Token(readModifyWriteExpression.leftValue().origin()), *readModifyWriteExpression.leftValue().typeAnnotation().leftAddressSpace(), baseType->clone()); … … 521 611 522 612 ASSERT(!readModifyWriteExpression.leftValue().typeAnnotation().isRightValue()); 523 if (!is<AST:: DotExpression>(readModifyWriteExpression.leftValue())) {524 setError(); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198163 Make this work with index expressions.613 if (!is<AST::PropertyAccessExpression>(readModifyWriteExpression.leftValue())) { 614 setError(); 525 615 return; 526 616 } 527 auto modifyResult = modify(downcast<AST:: DotExpression>(readModifyWriteExpression.leftValue()), [&](Optional<UniqueRef<AST::Expression>>&& lastGetterCallExpression) -> Optional<ModificationResult> {617 auto modifyResult = modify(downcast<AST::PropertyAccessExpression>(readModifyWriteExpression.leftValue()), [&](Optional<UniqueRef<AST::Expression>>&& lastGetterCallExpression) -> Optional<ModificationResult> { 528 618 Vector<UniqueRef<AST::Expression>> expressions; 529 619 if (!lastGetterCallExpression) … … 582 672 } 583 673 584 bool PropertyResolver::simplifyRightValue(AST:: DotExpression& dotExpression)585 { 586 Lexer::Token origin = dotExpression.origin();587 588 checkErrorAndVisit( dotExpression.base());589 590 if (auto* anderFunction = dotExpression.anderFunction()) {591 auto& base = dotExpression.base();592 if (auto leftAddressSpace = base.typeAnnotation().leftAddressSpace()) {593 auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(origin), dotExpression.takeBase());674 bool PropertyResolver::simplifyRightValue(AST::PropertyAccessExpression& propertyAccessExpression) 675 { 676 Lexer::Token origin = propertyAccessExpression.origin(); 677 678 checkErrorAndVisit(propertyAccessExpression.base()); 679 680 auto& base = propertyAccessExpression.base(); 681 if (auto leftAddressSpace = base.typeAnnotation().leftAddressSpace()) { 682 if (auto* anderFunction = propertyAccessExpression.anderFunction()) { 683 auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(origin), propertyAccessExpression.takeBase()); 594 684 makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(origin), *leftAddressSpace, base.resolvedType().clone())); 595 685 makePointerExpression->setTypeAnnotation(AST::RightValue()); … … 597 687 Vector<UniqueRef<AST::Expression>> arguments; 598 688 arguments.append(WTFMove(makePointerExpression)); 689 if (is<AST::IndexExpression>(propertyAccessExpression)) 690 arguments.append(downcast<AST::IndexExpression>(propertyAccessExpression).takeIndex()); 599 691 auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(origin), String(anderFunction->name()), WTFMove(arguments)); 600 692 callExpression->setType(anderFunction->type().clone()); … … 602 694 callExpression->setFunction(*anderFunction); 603 695 604 auto* dereferenceExpression = AST::replaceWith<AST::DereferenceExpression>( dotExpression, WTFMove(origin), WTFMove(callExpression));696 auto* dereferenceExpression = AST::replaceWith<AST::DereferenceExpression>(propertyAccessExpression, WTFMove(origin), WTFMove(callExpression)); 605 697 dereferenceExpression->setType(downcast<AST::PointerType>(anderFunction->type()).elementType().clone()); 606 698 dereferenceExpression->setTypeAnnotation(AST::LeftValue { downcast<AST::PointerType>(anderFunction->type()).addressSpace() }); 607 699 return true; 608 700 } 609 610 // 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. 611 // This is effectively inlining the functions the spec says are generated. 612 if (!dotExpression.threadAnderFunction()) 613 return false; 614 615 auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(origin), AST::Qualifiers(), base.resolvedType().clone(), String(), WTF::nullopt, WTF::nullopt); 616 617 auto variableReference1 = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration)); 618 variableReference1->setType(base.resolvedType().clone()); 619 variableReference1->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); 620 621 auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(origin), WTFMove(variableReference1), dotExpression.takeBase()); 622 assignmentExpression->setType(base.resolvedType().clone()); 623 assignmentExpression->setTypeAnnotation(AST::RightValue()); 624 625 auto variableReference2 = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration)); 626 variableReference2->setType(base.resolvedType().clone()); 627 variableReference2->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); 628 629 auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(origin), WTFMove(variableReference2)); 630 makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(origin), AST::AddressSpace::Thread, base.resolvedType().clone())); 631 makePointerExpression->setTypeAnnotation(AST::RightValue()); 632 701 } 702 703 if (propertyAccessExpression.getterFunction()) { 704 auto& getterFunction = *propertyAccessExpression.getterFunction(); 633 705 Vector<UniqueRef<AST::Expression>> arguments; 634 arguments.append(WTFMove(makePointerExpression)); 635 auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(origin), String(anderFunction->name()), WTFMove(arguments)); 636 callExpression->setType(anderFunction->type().clone()); 706 arguments.append(propertyAccessExpression.takeBase()); 707 if (is<AST::IndexExpression>(propertyAccessExpression)) 708 arguments.append(downcast<AST::IndexExpression>(propertyAccessExpression).takeIndex()); 709 auto* callExpression = AST::replaceWith<AST::CallExpression>(propertyAccessExpression, WTFMove(origin), String(getterFunction.name()), WTFMove(arguments)); 710 callExpression->setFunction(getterFunction); 711 callExpression->setType(getterFunction.type().clone()); 637 712 callExpression->setTypeAnnotation(AST::RightValue()); 638 callExpression->setFunction(*anderFunction);639 640 auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(WTFMove(origin), WTFMove(callExpression));641 dereferenceExpression->setType(downcast<AST::PointerType>(anderFunction->type()).elementType().clone());642 dereferenceExpression->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread });643 644 Vector<UniqueRef<AST::Expression>> expressions;645 expressions.append(WTFMove(assignmentExpression));646 expressions.append(WTFMove(dereferenceExpression));647 auto* commaExpression = AST::replaceWith<AST::CommaExpression>(dotExpression, WTFMove(origin), WTFMove(expressions));648 commaExpression->setType(downcast<AST::PointerType>(anderFunction->type()).elementType().clone());649 commaExpression->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread });650 651 m_variableDeclarations.append(WTFMove(variableDeclaration));652 713 return true; 653 714 } 654 715 655 ASSERT(dotExpression.getterFunction()); 656 auto& getterFunction = *dotExpression.getterFunction(); 716 // 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. 717 // This is effectively inlining the functions the spec says are generated. 718 ASSERT(propertyAccessExpression.threadAnderFunction()); 719 auto* threadAnderFunction = propertyAccessExpression.threadAnderFunction(); 720 721 auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(origin), AST::Qualifiers(), base.resolvedType().clone(), String(), WTF::nullopt, WTF::nullopt); 722 723 auto variableReference1 = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration)); 724 variableReference1->setType(base.resolvedType().clone()); 725 variableReference1->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); 726 727 auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(origin), WTFMove(variableReference1), propertyAccessExpression.takeBase()); 728 assignmentExpression->setType(base.resolvedType().clone()); 729 assignmentExpression->setTypeAnnotation(AST::RightValue()); 730 731 auto variableReference2 = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration)); 732 variableReference2->setType(base.resolvedType().clone()); 733 variableReference2->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); 734 735 auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(origin), WTFMove(variableReference2)); 736 makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(origin), AST::AddressSpace::Thread, base.resolvedType().clone())); 737 makePointerExpression->setTypeAnnotation(AST::RightValue()); 738 657 739 Vector<UniqueRef<AST::Expression>> arguments; 658 arguments.append(dotExpression.takeBase()); 659 auto* callExpression = AST::replaceWith<AST::CallExpression>(dotExpression, WTFMove(origin), String(getterFunction.name()), WTFMove(arguments)); 660 callExpression->setFunction(getterFunction); 661 callExpression->setType(getterFunction.type().clone()); 740 arguments.append(WTFMove(makePointerExpression)); 741 if (is<AST::IndexExpression>(propertyAccessExpression)) 742 arguments.append(downcast<AST::IndexExpression>(propertyAccessExpression).takeIndex()); 743 auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(origin), String(threadAnderFunction->name()), WTFMove(arguments)); 744 callExpression->setType(threadAnderFunction->type().clone()); 662 745 callExpression->setTypeAnnotation(AST::RightValue()); 746 callExpression->setFunction(*threadAnderFunction); 747 748 auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(WTFMove(origin), WTFMove(callExpression)); 749 dereferenceExpression->setType(downcast<AST::PointerType>(threadAnderFunction->type()).elementType().clone()); 750 dereferenceExpression->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); 751 752 Vector<UniqueRef<AST::Expression>> expressions; 753 expressions.append(WTFMove(assignmentExpression)); 754 expressions.append(WTFMove(dereferenceExpression)); 755 auto* commaExpression = AST::replaceWith<AST::CommaExpression>(propertyAccessExpression, WTFMove(origin), WTFMove(expressions)); 756 commaExpression->setType(downcast<AST::PointerType>(threadAnderFunction->type()).elementType().clone()); 757 commaExpression->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); 758 759 m_variableDeclarations.append(WTFMove(variableDeclaration)); 663 760 return true; 761 664 762 } 665 763 666 764 class LeftValueSimplifier : public Visitor { 667 p ublic:765 private: 668 766 void visit(AST::DotExpression&) override; 767 void visit(AST::IndexExpression&) override; 669 768 void visit(AST::DereferenceExpression&) override; 670 769 671 private: 770 void finishVisiting(AST::PropertyAccessExpression&); 672 771 }; 673 772 674 void LeftValueSimplifier::visit(AST::DotExpression& dotExpression) 675 { 676 Visitor::visit(dotExpression); 677 ASSERT(dotExpression.base().typeAnnotation().leftAddressSpace()); 678 ASSERT(dotExpression.anderFunction()); 679 680 Lexer::Token origin = dotExpression.origin(); 681 auto* anderFunction = dotExpression.anderFunction(); 682 auto& base = dotExpression.base(); 683 auto leftAddressSpace = *dotExpression.base().typeAnnotation().leftAddressSpace(); 684 auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(origin), dotExpression.takeBase()); 773 void LeftValueSimplifier::finishVisiting(AST::PropertyAccessExpression& propertyAccessExpression) 774 { 775 ASSERT(propertyAccessExpression.base().typeAnnotation().leftAddressSpace()); 776 ASSERT(propertyAccessExpression.anderFunction()); 777 778 Lexer::Token origin = propertyAccessExpression.origin(); 779 auto* anderFunction = propertyAccessExpression.anderFunction(); 780 auto& base = propertyAccessExpression.base(); 781 auto leftAddressSpace = *propertyAccessExpression.base().typeAnnotation().leftAddressSpace(); 782 auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(origin), propertyAccessExpression.takeBase()); 685 783 makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(origin), leftAddressSpace, base.resolvedType().clone())); 686 784 makePointerExpression->setTypeAnnotation(AST::RightValue()); … … 688 786 Vector<UniqueRef<AST::Expression>> arguments; 689 787 arguments.append(WTFMove(makePointerExpression)); 788 if (is<AST::IndexExpression>(propertyAccessExpression)) 789 arguments.append(downcast<AST::IndexExpression>(propertyAccessExpression).takeIndex()); 690 790 auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(origin), String(anderFunction->name()), WTFMove(arguments)); 691 791 callExpression->setType(anderFunction->type().clone()); … … 693 793 callExpression->setFunction(*anderFunction); 694 794 695 auto* dereferenceExpression = AST::replaceWith<AST::DereferenceExpression>( dotExpression, WTFMove(origin), WTFMove(callExpression));795 auto* dereferenceExpression = AST::replaceWith<AST::DereferenceExpression>(propertyAccessExpression, WTFMove(origin), WTFMove(callExpression)); 696 796 dereferenceExpression->setType(downcast<AST::PointerType>(anderFunction->type()).elementType().clone()); 697 797 dereferenceExpression->setTypeAnnotation(AST::LeftValue { downcast<AST::PointerType>(anderFunction->type()).addressSpace() }); 798 } 799 800 void LeftValueSimplifier::visit(AST::DotExpression& dotExpression) 801 { 802 Visitor::visit(dotExpression); 803 finishVisiting(dotExpression); 804 } 805 806 void LeftValueSimplifier::visit(AST::IndexExpression& indexExpression) 807 { 808 Visitor::visit(indexExpression); 809 PropertyResolver().Visitor::visit(indexExpression.indexExpression()); 810 finishVisiting(indexExpression); 698 811 } 699 812 … … 703 816 // For example, a dereference expression may be a left value but its child may be a call expression which is a right value. 704 817 // LeftValueSimplifier doesn't handle right values, so we instead need to use PropertyResolver. 705 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198170 What about function call arguments?706 818 PropertyResolver().Visitor::visit(dereferenceExpression); 707 819 } -
trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt
r246121 r246138 376 376 native typedef TextureDepthCube<float>; 377 377 378 native operator uchar(ushort); 379 native operator uchar(uint); 380 native operator uchar(char); 381 native operator uchar(short); 382 native operator uchar(int); 383 native operator uchar(half); 384 native operator uchar(float); 385 native operator ushort(uchar); 386 native operator ushort(uint); 387 native operator ushort(char); 388 native operator ushort(short); 389 native operator ushort(int); 390 native operator ushort(half); 391 native operator ushort(float); 392 native operator uint(uchar); 393 native operator uint(ushort); 394 native operator uint(char); 395 native operator uint(short); 396 native operator uint(int); 397 native operator uint(half); 398 native operator uint(float); 399 native operator char(uchar); 400 native operator char(ushort); 401 native operator char(uint); 402 native operator char(short); 403 native operator char(int); 404 native operator char(half); 405 native operator char(float); 406 native operator short(uchar); 407 native operator short(ushort); 408 native operator short(uint); 409 native operator short(char); 410 native operator short(int); 411 native operator short(half); 412 native operator short(float); 413 native operator int(uchar); 414 native operator int(ushort); 415 native operator int(uint); 416 native operator int(char); 417 native operator int(short); 418 native operator int(half); 419 native operator int(float); 420 native operator half(uchar); 421 native operator half(ushort); 422 native operator half(uint); 423 native operator half(char); 424 native operator half(short); 425 native operator half(int); 426 native operator half(float); 427 native operator float(uchar); 428 native operator float(ushort); 429 native operator float(uint); 430 native operator float(char); 431 native operator float(short); 432 native operator float(int); 433 native operator float(half); 434 378 435 native float operator.x(float4); 379 436 native float operator.y(float4); -
trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.cpp
r245680 r246138 45 45 for (auto& structureDefinition : program.structureDefinitions()) { 46 46 for (auto& structureElement : structureDefinition->structureElements()) { 47 {48 // The getter: operator.field49 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);50 AST::VariableDeclarations parameters;51 parameters.append(WTFMove(variableDeclaration));52 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));53 if (!program.append(WTFMove(nativeFunctionDeclaration)))54 return false;55 }56 57 {58 // The setter: operator.field=59 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);60 auto variableDeclaration2 = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(structureElement.origin()), AST::Qualifiers(), structureElement.type().clone(), String(), WTF::nullopt, WTF::nullopt);61 AST::VariableDeclarations parameters;62 parameters.append(WTFMove(variableDeclaration1));63 parameters.append(WTFMove(variableDeclaration2));64 AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(structureElement.origin()), AST::AttributeBlock(), WTF::nullopt, AST::TypeReference::wrap(Lexer::Token(structureElement.origin()), structureDefinition), makeString("operator.", structureElement.name(), '='), WTFMove(parameters), WTF::nullopt, isOperator));65 if (!program.append(WTFMove(nativeFunctionDeclaration)))66 return false;67 }68 69 47 // The ander: operator&.field 70 48 auto createAnder = [&](AST::AddressSpace addressSpace) -> AST::NativeFunctionDeclaration {
Note: See TracChangeset
for help on using the changeset viewer.