[WHLSL] Remove getters/setters/anders
authorsbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 31 Aug 2019 00:13:42 +0000 (00:13 +0000)
committersbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 31 Aug 2019 00:13:42 +0000 (00:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=201008

Reviewed by Robin Morisset.

Source/WebCore:

This patch changes WHLSL in a significant way. This patch removes getters/setters/anders
from the language. In our experience writing WHLSL shaders, these parts of the language
went unused, and they added a lot of complexity to the implementation of the compiler.

This patch now treats field accesses and array indexes as intrinsics inside the compiler.
This patch removes all notions of named operators, anders, and indexed operators
from the compiler and the standard library. The checker now intrinsically knows the
return type for property accesses and indexed expressions based on what the
base type is.

To make this work in practice was difficult, since getters/setters/anders
solved a lot of the difficult problems we had in generating metal code. For
example, all swizzle operators were getters and setters, so assigning to a
swizzle fell out naturally from implementing setters. However, during metal
codegen, all we see is a dot expression with "xy" as a property. Our previous
architecture of emitting Metal code using pointers which represent lvalues
doesn't work because you can't take the address of a swizzle. For example,
"auto* x = &vector.yz" is invalid metal code.

So, this patch changes the entire metal code generator to emit WHLSL expressions
as Metal expressions. To do this, I had to change a lot about how the compiler
was implemented:
- I changed the indexed accesses of matrices to return columns instead of
rows. This allowed WHLSL code like `mat[0].xy = 42` to be compiled into
the equivalent metal code of `mat[0].xy = 42`.
- I changed the native function inliner to emit expressions instead of
statements.
- We also simplify the language by removing null and requiring all
reference type variables to have an initializer. This means that
null is no longer a valid value, which allows us to omit null checks
inside the metal code generator. To make this work with array
accesses, we now clamp accesses instead of returning null for OOB
accesses.

I've also filed one required bug as a followup. I didn't include it in this
patch to make it easier to review along. Currently, there are two places in
metal codegen where we evaluate effects twice. That will be fixed in:
https://bugs.webkit.org/show_bug.cgi?id=201251

Tests: webgpu/whlsl/address-of-swizzle.html
       webgpu/whlsl/array-oob-alias.html
       webgpu/whlsl/matrix-index-assign.html
       webgpu/whlsl/matrix-index-order.html
       webgpu/whlsl/oob-access-2.html
       webgpu/whlsl/operator-syntax.html

* Modules/webgpu/WHLSL/AST/WHLSLAST.h:
* Modules/webgpu/WHLSL/AST/WHLSLConstantExpression.h:
* Modules/webgpu/WHLSL/AST/WHLSLDotExpression.h:
* Modules/webgpu/WHLSL/AST/WHLSLExpression.cpp:
(WebCore::WHLSL::AST::Expression::destroy):
(WebCore::WHLSL::AST::Expression::destruct):
(WebCore::WHLSL::AST::PropertyAccessExpression::getterFunctionName const): Deleted.
(WebCore::WHLSL::AST::PropertyAccessExpression::setterFunctionName const): Deleted.
(WebCore::WHLSL::AST::PropertyAccessExpression::anderFunctionName const): Deleted.
* Modules/webgpu/WHLSL/AST/WHLSLExpression.h:
(WebCore::WHLSL::AST::Expression::copyTypeTo const):
(WebCore::WHLSL::AST::Expression::isMakePointerExpression const):
(WebCore::WHLSL::AST::Expression::isNullLiteral const): Deleted.
* Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h:
* Modules/webgpu/WHLSL/AST/WHLSLNativeTypeDeclaration.h:
* Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h: Removed.
* Modules/webgpu/WHLSL/AST/WHLSLNullLiteralType.cpp: Removed.
* Modules/webgpu/WHLSL/AST/WHLSLNullLiteralType.h: Removed.
* Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h:
(WebCore::WHLSL::AST::PropertyAccessExpression::getterFunction): Deleted.
(WebCore::WHLSL::AST::PropertyAccessExpression::anderFunction): Deleted.
(WebCore::WHLSL::AST::PropertyAccessExpression::threadAnderFunction): Deleted.
(WebCore::WHLSL::AST::PropertyAccessExpression::setterFunction): Deleted.
(WebCore::WHLSL::AST::PropertyAccessExpression::setGetterFunction): Deleted.
(WebCore::WHLSL::AST::PropertyAccessExpression::setAnderFunction): Deleted.
(WebCore::WHLSL::AST::PropertyAccessExpression::setThreadAnderFunction): Deleted.
(WebCore::WHLSL::AST::PropertyAccessExpression::setSetterFunction): Deleted.
(): Deleted.
* Modules/webgpu/WHLSL/AST/WHLSLType.cpp:
(WebCore::WHLSL::AST::Type::destroy):
(WebCore::WHLSL::AST::Type::destruct):
(WebCore::WHLSL::AST::ResolvableType::canResolve const):
(WebCore::WHLSL::AST::ResolvableType::conversionCost const):
* Modules/webgpu/WHLSL/AST/WHLSLType.h:
(WebCore::WHLSL::AST::Type::isIntegerLiteralType const):
(WebCore::WHLSL::AST::Type::isNullLiteralType const): Deleted.
* Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp:
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::HoistedVariableCollector::HoistedVariableCollector):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::emitLoop):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::emitConstantExpressionString):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::appendRightValueWithNullability): Deleted.
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::appendRightValue): Deleted.
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::appendLeftValue): Deleted.
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::takeLastValue): Deleted.
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::takeLastValueAndNullability): Deleted.
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::takeLastLeftValue): Deleted.
* Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.cpp:
(WebCore::WHLSL::Metal::metalCodePrologue):
(WebCore::WHLSL::Metal::generateMetalCode):
(WebCore::WHLSL::Metal::metalCodeProlog): Deleted.
* Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp:
(WebCore::WHLSL::Metal::inlineNativeFunction):
(WebCore::WHLSL::Metal::vectorInnerType): Deleted.
* Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.h:
* Modules/webgpu/WHLSL/Metal/WHLSLNativeTypeWriter.cpp:
(WebCore::WHLSL::Metal::writeNativeType):
* Modules/webgpu/WHLSL/WHLSLASTDumper.cpp:
(WebCore::WHLSL::ASTDumper::visit):
* Modules/webgpu/WHLSL/WHLSLASTDumper.h:
* Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp:
(WebCore::WHLSL::checkDuplicateFunctions):
* Modules/webgpu/WHLSL/WHLSLChecker.cpp:
(WebCore::WHLSL::resolveByInstantiation):
(WebCore::WHLSL::checkOperatorOverload):
(WebCore::WHLSL::Checker::wrappedUintType):
(WebCore::WHLSL::Checker::normalizedTypeForFunctionKey):
(WebCore::WHLSL::Checker::visit):
(WebCore::WHLSL::matchAndCommit):
(WebCore::WHLSL::Checker::resolveFunction):
(WebCore::WHLSL::Checker::assignConcreteType):
(WebCore::WHLSL::resolveWithOperatorLength): Deleted.
(WebCore::WHLSL::Checker::genericPointerType): Deleted.
(WebCore::WHLSL::Checker::finishVisiting): Deleted.
* Modules/webgpu/WHLSL/WHLSLHighZombieFinder.cpp:
(WebCore::WHLSL::findHighZombies):
(): Deleted.
* Modules/webgpu/WHLSL/WHLSLInferTypes.cpp:
(WebCore::WHLSL::matchAndCommit):
(WebCore::WHLSL::commit):
* Modules/webgpu/WHLSL/WHLSLIntrinsics.h:
(WebCore::WHLSL::Intrinsics::boolVectorTypeForSize const):
(WebCore::WHLSL::Intrinsics::uintVectorTypeForSize const):
(WebCore::WHLSL::Intrinsics::intVectorTypeForSize const):
(WebCore::WHLSL::Intrinsics::floatVectorTypeForSize const):
* Modules/webgpu/WHLSL/WHLSLLexer.cpp:
(WebCore::WHLSL::Lexer::consumeTokenFromStream):
* Modules/webgpu/WHLSL/WHLSLLiteralTypeChecker.cpp:
* Modules/webgpu/WHLSL/WHLSLParser.cpp:
(WebCore::WHLSL::Parser::parseConstantExpression):
(WebCore::WHLSL::Parser::parseEnumerationMember):
(WebCore::WHLSL::Parser::parseTerm):
* Modules/webgpu/WHLSL/WHLSLPrepare.cpp:
(WebCore::WHLSL::prepareShared):
* Modules/webgpu/WHLSL/WHLSLProgram.cpp: Added.
(WebCore::WHLSL::Program::isValidVectorProperty):
* Modules/webgpu/WHLSL/WHLSLProgram.h:
* Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp:
(WebCore::WHLSL::resolveProperties):
(WebCore::WHLSL::PropertyResolver::visit): Deleted.
(WebCore::WHLSL::wrapAnderCallArgument): Deleted.
(WebCore::WHLSL::anderCallArgument): Deleted.
(WebCore::WHLSL::setterCall): Deleted.
(WebCore::WHLSL::getterCall): Deleted.
(WebCore::WHLSL::modify): Deleted.
(WebCore::WHLSL::PropertyResolver::simplifyRightValue): Deleted.
(WebCore::WHLSL::LeftValueSimplifier::finishVisiting): Deleted.
(WebCore::WHLSL::LeftValueSimplifier::visit): Deleted.
(WebCore::WHLSL::PropertyResolver::simplifyLeftValue): Deleted.
* Modules/webgpu/WHLSL/WHLSLPruneUnreachableStandardLibraryFunctions.cpp:
* Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt:
* Modules/webgpu/WHLSL/WHLSLStandardLibraryUtilities.cpp:
* Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.cpp: Removed.
* Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.h: Removed.
* Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.cpp:
(WebCore::WHLSL::synthesizeEnumerationFunctions):
* Modules/webgpu/WHLSL/WHLSLVisitor.cpp:
(WebCore::WHLSL::Visitor::visit):
* Modules/webgpu/WHLSL/WHLSLVisitor.h:
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:

LayoutTests:

* webgpu/whlsl/address-of-swizzle-expected.txt: Added.
* webgpu/whlsl/address-of-swizzle.html: Added.
* webgpu/whlsl/array-oob-alias-expected.txt: Copied from LayoutTests/webgpu/whlsl/structure-field-access-on-null-expected.txt.
* webgpu/whlsl/array-oob-alias.html: Copied from LayoutTests/webgpu/whlsl/structure-field-access-on-null.html.
* webgpu/whlsl/bad-ander-expected.txt: Removed.
* webgpu/whlsl/bad-ander.html: Removed.
* webgpu/whlsl/duplicate-types-should-not-produce-duplicate-ctors.html:
* webgpu/whlsl/increment-setter.html:
* webgpu/whlsl/index-ander-expected.txt: Removed.
* webgpu/whlsl/index-ander.html: Removed.
* webgpu/whlsl/index-setter-getter-expected.txt: Removed.
* webgpu/whlsl/index-setter-getter.html: Removed.
* webgpu/whlsl/make-array-reference.html:
* webgpu/whlsl/matrix-index-assign-expected.txt: Added.
* webgpu/whlsl/matrix-index-assign.html: Added.
* webgpu/whlsl/matrix-index-order-expected.txt: Added.
* webgpu/whlsl/matrix-index-order.html: Added.
* webgpu/whlsl/matrix-memory-layout.html:
* webgpu/whlsl/matrix.html:
* webgpu/whlsl/null-arg-expected.txt:
* webgpu/whlsl/null-arg.html:
* webgpu/whlsl/null-dereference-expected.txt: Removed.
* webgpu/whlsl/null-dereference.html: Removed.
* webgpu/whlsl/oob-access-2-expected.txt: Added.
* webgpu/whlsl/oob-access-2.html: Added.
* webgpu/whlsl/oob-access.html:
* webgpu/whlsl/operator-syntax-expected.txt: Added.
* webgpu/whlsl/operator-syntax.html: Added.
* webgpu/whlsl/operator-vector-assign.html:
* webgpu/whlsl/operator-vector-load.html:
* webgpu/whlsl/override-subscript-expected.txt: Removed.
* webgpu/whlsl/override-subscript.html: Removed.
* webgpu/whlsl/propertyresolver/ander-abstract-lvalue-expected.html: Removed.
* webgpu/whlsl/propertyresolver/ander-abstract-lvalue.html: Removed.
* webgpu/whlsl/propertyresolver/ander-expected.html: Removed.
* webgpu/whlsl/propertyresolver/ander-lvalue-3-levels-expected.html: Removed.
* webgpu/whlsl/propertyresolver/ander-lvalue-3-levels.html: Removed.
* webgpu/whlsl/propertyresolver/ander-lvalue-expected.html: Removed.
* webgpu/whlsl/propertyresolver/ander-lvalue.html: Removed.
* webgpu/whlsl/propertyresolver/ander.html: Removed.
* webgpu/whlsl/propertyresolver/getter-expected.html: Removed.
* webgpu/whlsl/propertyresolver/getter.html: Removed.
* webgpu/whlsl/propertyresolver/indexer-ander-abstract-lvalue-expected.html: Removed.
* webgpu/whlsl/propertyresolver/indexer-ander-abstract-lvalue.html: Removed.
* webgpu/whlsl/propertyresolver/indexer-ander-expected.html: Removed.
* webgpu/whlsl/propertyresolver/indexer-ander-lvalue-3-levels-expected.html: Removed.
* webgpu/whlsl/propertyresolver/indexer-ander-lvalue-3-levels.html: Removed.
* webgpu/whlsl/propertyresolver/indexer-ander-lvalue-expected.html: Removed.
* webgpu/whlsl/propertyresolver/indexer-ander-lvalue.html: Removed.
* webgpu/whlsl/propertyresolver/indexer-ander.html: Removed.
* webgpu/whlsl/propertyresolver/indexer-getter-expected.html: Removed.
* webgpu/whlsl/propertyresolver/indexer-getter.html: Removed.
* webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue-3-levels-expected.html: Removed.
* webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue-3-levels.html: Removed.
* webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue-expected.html: Removed.
* webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue.html: Removed.
* webgpu/whlsl/propertyresolver/indexer-setter-expected.html: Removed.
* webgpu/whlsl/propertyresolver/indexer-setter-lvalue-expected.html: Removed.
* webgpu/whlsl/propertyresolver/indexer-setter-lvalue.html: Removed.
* webgpu/whlsl/propertyresolver/indexer-setter.html: Removed.
* webgpu/whlsl/propertyresolver/setter-abstract-lvalue-3-levels-expected.html: Removed.
* webgpu/whlsl/propertyresolver/setter-abstract-lvalue-3-levels.html: Removed.
* webgpu/whlsl/propertyresolver/setter-abstract-lvalue-expected.html: Removed.
* webgpu/whlsl/propertyresolver/setter-abstract-lvalue.html: Removed.
* webgpu/whlsl/propertyresolver/setter-lvalue-expected.html: Removed.
* webgpu/whlsl/propertyresolver/setter-lvalue.html: Removed.
* webgpu/whlsl/setter-spec-tests.html:
* webgpu/whlsl/simple-getter-setter-expected.txt:
* webgpu/whlsl/simple-getter-setter.html:
* webgpu/whlsl/structure-field-access-on-null-expected.txt: Removed.
* webgpu/whlsl/structure-field-access-on-null.html: Removed.
* webgpu/whlsl/test-harness-test.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249351 268f45cc-cd09-0410-ab3c-d52691b4dbfc

115 files changed:
LayoutTests/ChangeLog
LayoutTests/webgpu/whlsl/address-of-swizzle-expected.txt [new file with mode: 0644]
LayoutTests/webgpu/whlsl/address-of-swizzle.html [new file with mode: 0644]
LayoutTests/webgpu/whlsl/array-oob-alias-expected.txt [moved from LayoutTests/webgpu/whlsl/structure-field-access-on-null-expected.txt with 100% similarity]
LayoutTests/webgpu/whlsl/array-oob-alias.html [moved from LayoutTests/webgpu/whlsl/structure-field-access-on-null.html with 53% similarity]
LayoutTests/webgpu/whlsl/bad-ander-expected.txt [deleted file]
LayoutTests/webgpu/whlsl/bad-ander.html [deleted file]
LayoutTests/webgpu/whlsl/duplicate-types-should-not-produce-duplicate-ctors.html
LayoutTests/webgpu/whlsl/increment-setter.html
LayoutTests/webgpu/whlsl/index-ander-expected.txt [deleted file]
LayoutTests/webgpu/whlsl/index-ander.html [deleted file]
LayoutTests/webgpu/whlsl/index-setter-getter-expected.txt [deleted file]
LayoutTests/webgpu/whlsl/index-setter-getter.html [deleted file]
LayoutTests/webgpu/whlsl/make-array-reference.html
LayoutTests/webgpu/whlsl/matrix-index-assign-expected.txt [new file with mode: 0644]
LayoutTests/webgpu/whlsl/matrix-index-assign.html [new file with mode: 0644]
LayoutTests/webgpu/whlsl/matrix-index-order-expected.txt [new file with mode: 0644]
LayoutTests/webgpu/whlsl/matrix-index-order.html [new file with mode: 0644]
LayoutTests/webgpu/whlsl/matrix-memory-layout.html
LayoutTests/webgpu/whlsl/matrix.html
LayoutTests/webgpu/whlsl/null-arg-expected.txt
LayoutTests/webgpu/whlsl/null-arg.html
LayoutTests/webgpu/whlsl/null-dereference-expected.txt [deleted file]
LayoutTests/webgpu/whlsl/null-dereference.html [deleted file]
LayoutTests/webgpu/whlsl/oob-access-2-expected.txt [new file with mode: 0644]
LayoutTests/webgpu/whlsl/oob-access-2.html [new file with mode: 0644]
LayoutTests/webgpu/whlsl/oob-access.html
LayoutTests/webgpu/whlsl/operator-syntax-expected.txt [new file with mode: 0644]
LayoutTests/webgpu/whlsl/operator-syntax.html [new file with mode: 0644]
LayoutTests/webgpu/whlsl/operator-vector-assign.html
LayoutTests/webgpu/whlsl/operator-vector-load.html
LayoutTests/webgpu/whlsl/override-subscript-expected.txt [deleted file]
LayoutTests/webgpu/whlsl/override-subscript.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/ander-abstract-lvalue-expected.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/ander-abstract-lvalue.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/ander-expected.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/ander-lvalue-3-levels-expected.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/ander-lvalue-3-levels.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/ander-lvalue-expected.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/ander-lvalue.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/ander.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/getter-expected.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/getter.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-abstract-lvalue-expected.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-abstract-lvalue.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-expected.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-lvalue-3-levels-expected.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-lvalue-3-levels.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-lvalue-expected.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-lvalue.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/indexer-getter-expected.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/indexer-getter.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue-3-levels-expected.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue-3-levels.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue-expected.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-expected.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-lvalue-expected.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-lvalue.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/setter-abstract-lvalue-3-levels-expected.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/setter-abstract-lvalue-3-levels.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/setter-abstract-lvalue-expected.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/setter-abstract-lvalue.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/setter-lvalue-expected.html [deleted file]
LayoutTests/webgpu/whlsl/propertyresolver/setter-lvalue.html [deleted file]
LayoutTests/webgpu/whlsl/setter-spec-tests.html
LayoutTests/webgpu/whlsl/simple-getter-setter-expected.txt
LayoutTests/webgpu/whlsl/simple-getter-setter.html
LayoutTests/webgpu/whlsl/test-harness-test.html
Source/WebCore/ChangeLog
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAST.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDotExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLExpression.cpp
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNativeTypeDeclaration.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h [deleted file]
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteralType.h [deleted file]
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLType.cpp
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLType.h
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.cpp
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.h
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeTypeWriter.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLHighZombieFinder.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLIntrinsics.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLLexer.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLLiteralTypeChecker.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLProgram.cpp [moved from Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteralType.cpp with 77% similarity]
Source/WebCore/Modules/webgpu/WHLSL/WHLSLProgram.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLPruneUnreachableStandardLibraryFunctions.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt
Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibraryUtilities.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.cpp [deleted file]
Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.h [deleted file]
Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.cpp [deleted file]
Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.h [deleted file]
Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.h
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj

index 778783f..424658e 100644 (file)
@@ -1,3 +1,83 @@
+2019-08-30  Saam Barati  <sbarati@apple.com>
+
+        [WHLSL] Remove getters/setters/anders
+        https://bugs.webkit.org/show_bug.cgi?id=201008
+
+        Reviewed by Robin Morisset.
+
+        * webgpu/whlsl/address-of-swizzle-expected.txt: Added.
+        * webgpu/whlsl/address-of-swizzle.html: Added.
+        * webgpu/whlsl/array-oob-alias-expected.txt: Copied from LayoutTests/webgpu/whlsl/structure-field-access-on-null-expected.txt.
+        * webgpu/whlsl/array-oob-alias.html: Copied from LayoutTests/webgpu/whlsl/structure-field-access-on-null.html.
+        * webgpu/whlsl/bad-ander-expected.txt: Removed.
+        * webgpu/whlsl/bad-ander.html: Removed.
+        * webgpu/whlsl/duplicate-types-should-not-produce-duplicate-ctors.html:
+        * webgpu/whlsl/increment-setter.html:
+        * webgpu/whlsl/index-ander-expected.txt: Removed.
+        * webgpu/whlsl/index-ander.html: Removed.
+        * webgpu/whlsl/index-setter-getter-expected.txt: Removed.
+        * webgpu/whlsl/index-setter-getter.html: Removed.
+        * webgpu/whlsl/make-array-reference.html:
+        * webgpu/whlsl/matrix-index-assign-expected.txt: Added.
+        * webgpu/whlsl/matrix-index-assign.html: Added.
+        * webgpu/whlsl/matrix-index-order-expected.txt: Added.
+        * webgpu/whlsl/matrix-index-order.html: Added.
+        * webgpu/whlsl/matrix-memory-layout.html:
+        * webgpu/whlsl/matrix.html:
+        * webgpu/whlsl/null-arg-expected.txt:
+        * webgpu/whlsl/null-arg.html:
+        * webgpu/whlsl/null-dereference-expected.txt: Removed.
+        * webgpu/whlsl/null-dereference.html: Removed.
+        * webgpu/whlsl/oob-access-2-expected.txt: Added.
+        * webgpu/whlsl/oob-access-2.html: Added.
+        * webgpu/whlsl/oob-access.html:
+        * webgpu/whlsl/operator-syntax-expected.txt: Added.
+        * webgpu/whlsl/operator-syntax.html: Added.
+        * webgpu/whlsl/operator-vector-assign.html:
+        * webgpu/whlsl/operator-vector-load.html:
+        * webgpu/whlsl/override-subscript-expected.txt: Removed.
+        * webgpu/whlsl/override-subscript.html: Removed.
+        * webgpu/whlsl/propertyresolver/ander-abstract-lvalue-expected.html: Removed.
+        * webgpu/whlsl/propertyresolver/ander-abstract-lvalue.html: Removed.
+        * webgpu/whlsl/propertyresolver/ander-expected.html: Removed.
+        * webgpu/whlsl/propertyresolver/ander-lvalue-3-levels-expected.html: Removed.
+        * webgpu/whlsl/propertyresolver/ander-lvalue-3-levels.html: Removed.
+        * webgpu/whlsl/propertyresolver/ander-lvalue-expected.html: Removed.
+        * webgpu/whlsl/propertyresolver/ander-lvalue.html: Removed.
+        * webgpu/whlsl/propertyresolver/ander.html: Removed.
+        * webgpu/whlsl/propertyresolver/getter-expected.html: Removed.
+        * webgpu/whlsl/propertyresolver/getter.html: Removed.
+        * webgpu/whlsl/propertyresolver/indexer-ander-abstract-lvalue-expected.html: Removed.
+        * webgpu/whlsl/propertyresolver/indexer-ander-abstract-lvalue.html: Removed.
+        * webgpu/whlsl/propertyresolver/indexer-ander-expected.html: Removed.
+        * webgpu/whlsl/propertyresolver/indexer-ander-lvalue-3-levels-expected.html: Removed.
+        * webgpu/whlsl/propertyresolver/indexer-ander-lvalue-3-levels.html: Removed.
+        * webgpu/whlsl/propertyresolver/indexer-ander-lvalue-expected.html: Removed.
+        * webgpu/whlsl/propertyresolver/indexer-ander-lvalue.html: Removed.
+        * webgpu/whlsl/propertyresolver/indexer-ander.html: Removed.
+        * webgpu/whlsl/propertyresolver/indexer-getter-expected.html: Removed.
+        * webgpu/whlsl/propertyresolver/indexer-getter.html: Removed.
+        * webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue-3-levels-expected.html: Removed.
+        * webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue-3-levels.html: Removed.
+        * webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue-expected.html: Removed.
+        * webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue.html: Removed.
+        * webgpu/whlsl/propertyresolver/indexer-setter-expected.html: Removed.
+        * webgpu/whlsl/propertyresolver/indexer-setter-lvalue-expected.html: Removed.
+        * webgpu/whlsl/propertyresolver/indexer-setter-lvalue.html: Removed.
+        * webgpu/whlsl/propertyresolver/indexer-setter.html: Removed.
+        * webgpu/whlsl/propertyresolver/setter-abstract-lvalue-3-levels-expected.html: Removed.
+        * webgpu/whlsl/propertyresolver/setter-abstract-lvalue-3-levels.html: Removed.
+        * webgpu/whlsl/propertyresolver/setter-abstract-lvalue-expected.html: Removed.
+        * webgpu/whlsl/propertyresolver/setter-abstract-lvalue.html: Removed.
+        * webgpu/whlsl/propertyresolver/setter-lvalue-expected.html: Removed.
+        * webgpu/whlsl/propertyresolver/setter-lvalue.html: Removed.
+        * webgpu/whlsl/setter-spec-tests.html:
+        * webgpu/whlsl/simple-getter-setter-expected.txt:
+        * webgpu/whlsl/simple-getter-setter.html:
+        * webgpu/whlsl/structure-field-access-on-null-expected.txt: Removed.
+        * webgpu/whlsl/structure-field-access-on-null.html: Removed.
+        * webgpu/whlsl/test-harness-test.html:
+
 2019-08-30  Ryan Haddad  <ryanhaddad@apple.com>
 
         Unreviewed, rolling out r249338.
diff --git a/LayoutTests/webgpu/whlsl/address-of-swizzle-expected.txt b/LayoutTests/webgpu/whlsl/address-of-swizzle-expected.txt
new file mode 100644 (file)
index 0000000..095ac0e
--- /dev/null
@@ -0,0 +1,4 @@
+
+PASS cantTakeAddressOfSwizzle 
+PASS cantAssignRvalueSwizzle 
+
diff --git a/LayoutTests/webgpu/whlsl/address-of-swizzle.html b/LayoutTests/webgpu/whlsl/address-of-swizzle.html
new file mode 100644 (file)
index 0000000..d32f279
--- /dev/null
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>bad swizzle.</title>
+<script src="js/test-harness.js"></script>
+<script src="../js/webgpu-functions.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+const whlslTests = {};
+
+whlslTests.cantTakeAddressOfSwizzle = async () => {
+    await checkFail(`
+        void foo() {
+            int2 v;
+            thread int* x = &v.x;
+        }
+    `);
+
+    await checkFail(`
+        void foo() {
+            int2 v;
+            thread int2* x = &v.xy;
+        }
+    `);
+};
+
+whlslTests.cantAssignRvalueSwizzle = async () => {
+    await checkFail(`
+        int2 x() {
+            int2 v;
+            return v;
+        }
+        void foo() {
+            x().xy = int2(10, 20);
+        }
+    `);
+};
+
+runTests(whlslTests);
+</script>
+</html>
@@ -2,7 +2,7 @@
 <html>
 <meta charset=utf-8>
 <meta name="timeout" content="long">
-<title>field ander on nullptr should return null.</title>
+<title>oob on arrays.</title>
 <script src="js/test-harness.js"></script>
 <script src="../js/webgpu-functions.js"></script>
 <script src="../../resources/testharness.js"></script>
@@ -21,15 +21,46 @@ whlslTests.fieldShouldBeNull = async () => {
             Foo[10] foos;
             thread Foo* foo = &foos[i];
             thread int* ptr = &(foo->z);
-            return ptr == null && foo == null;
+            *ptr = 42;
+            return foos[0].z == 42;
+        }
+
+        bool bar() {
+            Foo[10] foos;
+            thread Foo* foo = &foos[424242];
+            thread int* ptr = &(foo->z);
+            return foo == &foos[0];
+        }
+
+        float3 retFloat3()
+        {
+            return float3(10.0, 0.0, 0.0);
+        }
+
+        float[10] retFloatArray()
+        {
+            float[10] v;
+            v[0] = 10.0;
+            return v;
+        }
+
+        bool baz() {
+            return retFloat3()[42] == 10.0;
+        }
+
+        bool jaz() {
+            return retFloatArray()[42] == 10.0;
         }
     `;
 
     for (let i = 0; i < 10; ++i)
-        assert_equals(await callBoolFunction(program,  "foo", [makeUint(i)]), false);
+        assert_equals(await callBoolFunction(program,  "foo", [makeUint(i)]), i === 0 ? true : false);
     assert_equals(await callBoolFunction(program,  "foo", [makeUint(10)]), true);
     assert_equals(await callBoolFunction(program,  "foo", [makeUint(1000000)]), true);
     assert_equals(await callBoolFunction(program,  "foo", [makeUint(0xffffffff)]), true);
+    assert_equals(await callBoolFunction(program,  "bar", []), true);
+    assert_equals(await callBoolFunction(program,  "baz", []), true);
+    assert_equals(await callBoolFunction(program,  "jaz", []), true);
 };
 
 runTests(whlslTests);
diff --git a/LayoutTests/webgpu/whlsl/bad-ander-expected.txt b/LayoutTests/webgpu/whlsl/bad-ander-expected.txt
deleted file mode 100644 (file)
index c98a74c..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-
-PASS indexAnderDoesntReturnPointer 
-PASS indexAnderDoesntTakeReference 
-PASS anderDoesntReturnPointer 
-PASS anderDoesntTakeReference 
-PASS anderWithBadIndex 
-PASS anderWithNothingWrong 
-PASS anderWithWrongNumberOfArguments 
-
diff --git a/LayoutTests/webgpu/whlsl/bad-ander.html b/LayoutTests/webgpu/whlsl/bad-ander.html
deleted file mode 100644 (file)
index 1ea627c..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-<!DOCTYPE html>
-<html>
-<meta charset=utf-8>
-<meta name="timeout" content="long">
-<title>Test prefix/postfix.</title>
-<script src="js/test-harness.js"></script>
-<script src="../js/webgpu-functions.js"></script>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script>
-const whlslTests = {};
-
-whlslTests.indexAnderDoesntReturnPointer = async () =>
-{
-    await checkFail(
-        `
-            struct Foo {
-                int x;
-            }
-            int operator&[](thread Foo* foo, uint)
-            {
-                return foo->x;
-            }
-        `);
-}
-
-whlslTests.indexAnderDoesntTakeReference = async () =>
-{
-    await checkFail(
-        `
-            struct Foo {
-                int x;
-            }
-            thread int* operator&[](Foo foo, uint)
-            {
-                return &foo.x;
-            }
-        `);
-}
-
-whlslTests.anderDoesntReturnPointer = async () => {
-    await checkFail(
-        `
-            struct Foo {
-                int x;
-            }
-            int operator&.foo(thread Foo* foo)
-            {
-                return foo->x;
-            }
-        `);
-}
-
-whlslTests.anderDoesntTakeReference = async () =>
-{
-    await checkFail(
-        `
-            struct Foo {
-                int x;
-            }
-            thread int* operator&.foo(Foo foo)
-            {
-                return &foo.x;
-            }
-        `);
-}
-
-whlslTests.anderWithBadIndex = async () =>
-{
-    await checkFail(`int foo(thread int[] x) { return x[-1]; }`);
-
-    await checkFail(`int foo(thread int[] x) { return x[1.f]; }`);
-
-    await checkFail(`int foo(thread int[] x, int y) { return x[y]; }`);
-
-    await checkFail(`int foo(thread int[] x, float y) { return x[y]; }`);
-}
-
-whlslTests.anderWithNothingWrong = async () =>
-{
-    let program = `
-        struct Foo {
-            int x;
-        }
-        thread int* operator&.foo(thread Foo* foo)
-        {
-            return &foo->x;
-        }
-        int foo()
-        {
-            Foo x;
-            x.x = 13;
-            return x.foo;
-        }
-    `;
-    assert_equals(await callIntFunction(program, "foo", []), 13);
-}
-
-whlslTests.anderWithWrongNumberOfArguments = async () => {
-    await checkFail(
-        `
-            thread int* operator&.foo()
-            {
-                int x;
-                return &x;
-            }
-        `);
-
-    await checkFail(
-        `
-            struct Foo {
-                int x;
-            }
-            thread int* operator&.foo(thread Foo* foo, int blah)
-            {
-                return &foo->x;
-            }
-        `);
-}
-
-runTests(whlslTests);
-</script>
-</html>
index e72a473..6a8b260 100644 (file)
@@ -19,16 +19,20 @@ typedef XYZ3 = XYZ;
 
 [numthreads(2, 1, 1)]
 compute void computeShader(device float[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) {
-    thread int* x;
-    thread int* y;
-    thread float* f1;
-    thread float* f2;
+    int value;
+    float value2;
+    int[10] value3;
+
+    thread int* x = &value;
+    thread int* y = &value;
+    thread float* f1 = &value2;
+    thread float* f2 = &value2;
     XYZ1 a;
     XYZ2 b;
     XYZ3 c;
-    thread int[] intArrayRef1;
-    thread int[] intArrayRef2;
-    if (*x == *y && x == y && x == null && f1 == null && *f1 == 0) {
+    thread int[] intArrayRef1 = @value3;
+    thread int[] intArrayRef2 = @value3;
+    if (*x == *y && x == y) {
         buffer[uint(threadID.x)] = buffer[uint(threadID.x)] * 2.0;
     }
 }
index d8f63e5..b94144e 100644 (file)
@@ -15,22 +15,17 @@ whlslTests.incrementSetter = async () =>
     let program = `
         struct Foo {
             int z;
-        }
-        int operator.w(Foo foo) {
-            return 8;
-        }
-        Foo operator.w=(Foo foo, int value) {
-            foo.z = value;
-            return foo;
+            int w;
         }
         int bar() {
             Foo foo;
             foo.z = 3;
+            foo.w = 1;
             int value = foo.w++;
             return value*100 + foo.z*10 + foo.w;
         }
     `;
-    assert_equals(await callIntFunction(program, "bar", []), 898);
+    assert_equals(await callIntFunction(program, "bar", []), 100 + 30 + 2);
 }
 
 runTests(whlslTests);
diff --git a/LayoutTests/webgpu/whlsl/index-ander-expected.txt b/LayoutTests/webgpu/whlsl/index-ander-expected.txt
deleted file mode 100644 (file)
index 86cb494..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-
-PASS indexAnderWithNothingWrong 
-PASS indexAnderWithWrongNumberOfArguments 
-
diff --git a/LayoutTests/webgpu/whlsl/index-ander.html b/LayoutTests/webgpu/whlsl/index-ander.html
deleted file mode 100644 (file)
index a941910..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-<!DOCTYPE html>
-<html>
-<meta charset=utf-8>
-<meta name="timeout" content="long">
-<title>Test structs.</title>
-<script src="js/test-harness.js"></script>
-<script src="../js/webgpu-functions.js"></script>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script>
-const whlslTests = {};
-
-whlslTests.indexAnderWithNothingWrong = async () =>
-{
-    let program = `
-        struct Foo {
-            int x;
-        }
-        thread int* operator&[](thread Foo* foo, uint)
-        {
-            return &foo->x;
-        }
-        int foo()
-        {
-            Foo x;
-            x.x = 13;
-            return x[666];
-        }
-    `;
-    assert_equals(await callIntFunction(program, "foo", []), 13);
-}
-
-whlslTests.indexAnderWithWrongNumberOfArguments = async () =>
-{
-    await checkFail(
-        `
-            thread int* operator&[]()
-            {
-                int x;
-                return &x;
-            }
-        `);
-        
-    await checkFail(
-        `
-            struct Foo {
-                int x;
-            }
-            thread int* operator&[](thread Foo* foo)
-            {
-                return &foo->x;
-            }
-        `);
-        
-    await checkFail(
-        `
-            struct Foo {
-                int x;
-            }
-            thread int* operator&[](thread Foo* foo, uint, uint)
-            {
-                return &foo->x;
-            }
-        `);
-}
-
-runTests(whlslTests);
-</script>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/index-setter-getter-expected.txt b/LayoutTests/webgpu/whlsl/index-setter-getter-expected.txt
deleted file mode 100644 (file)
index b3639d0..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-
-PASS indexSetterWithNoGetterOverload 
-PASS indexSetterWithNoGetterOverloadFixed 
-PASS notLoneIndexSetter 
-PASS loneIndexSetter 
-PASS loneIndexSetterPointer 
-
diff --git a/LayoutTests/webgpu/whlsl/index-setter-getter.html b/LayoutTests/webgpu/whlsl/index-setter-getter.html
deleted file mode 100644 (file)
index 6b70297..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-<!DOCTYPE html>
-<html>
-<meta charset=utf-8>
-<meta name="timeout" content="long">
-<title>Test structs.</title>
-<script src="js/test-harness.js"></script>
-<script src="../js/webgpu-functions.js"></script>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script>
-const whlslTests = {};
-
-whlslTests.indexSetterWithNoGetterOverload = async () =>
-{
-    await checkFail(
-        `
-            struct Foo { }
-            struct Bar { }
-            int operator[](Foo, uint)
-            {
-                return 534;
-            }
-            Bar operator[]=(Bar, uint, int)
-            {
-                return Bar();
-            }
-        `);
-        
-};
-
-whlslTests.indexSetterWithNoGetterOverloadFixed = async () =>
-{
-    const program = `
-        struct Bar { }
-        int operator[](Bar, uint)
-        {
-            return 534;
-        }
-        Bar operator[]=(Bar, uint, int)
-        {
-            return Bar();
-        }
-        int foo() { return Bar()[0]; }
-        int bar() {
-            Bar b;
-            b[0] = 400;
-            return b[0];
-        }
-    `;
-    assert_equals(await callIntFunction(program, "foo", []), 534);
-    assert_equals(await callIntFunction(program, "bar", []), 534);
-};
-
-whlslTests.notLoneIndexSetter = async () =>
-{
-    const program = `
-        int operator[](int, uint)
-        {
-            return 65;
-        }
-        int operator[]=(int, uint, int)
-        {
-            return 543;
-        }
-        int foo() {
-            int x;
-            return x[0];
-        }
-        int bar() {
-            int x;
-            x[0] = 42;
-            return x;
-        }
-    `;
-    assert_equals(await callIntFunction(program, "foo", []), 65);
-    assert_equals(await callIntFunction(program, "bar", []), 543);
-};
-
-whlslTests.loneIndexSetter = async () =>
-{
-    await checkFail(
-        `
-            int operator[]=(int, uint, int)
-            {
-                return 543;
-            }
-        `);
-        
-};
-
-whlslTests.loneIndexSetterPointer = async () =>
-{
-    await checkFail(
-        `
-            thread int* operator[]=(thread int* ptr, uint, int)
-            {
-                return ptr;
-            }
-        `);
-        
-};
-
-runTests(whlslTests);
-</script>
-</html>
index 44c4018..67a8801 100644 (file)
@@ -14,7 +14,7 @@ bool test1() {
         return false;
     if (array[0] != 42)
         return false;
-    if (array[120213] != 0)
+    if (array[120213] != 42)
         return false;
 
     array[0] = 1337;
@@ -35,7 +35,7 @@ bool test2() {
         return false;
     if (array[0] != 42)
         return false;
-    if (array[12374217] != 0)
+    if (array[12374217] != 42)
         return false;
     
     *ptr = 666;
@@ -87,16 +87,17 @@ bool test3() {
 }
 
 bool test4() {
-    thread int* ptr = null;
+    int x = 42;
+    thread int* ptr = &x;
 
     thread int[] array = @ptr;
-    if (array.length != 0)
+    if (array.length != 1)
         return false;
 
-    if (array[0] != 0)
+    if (array[0] != 42)
         return false;
 
-    if (array[100000] != 0)
+    if (array[100000] != 42)
         return false;
 
     return true;
diff --git a/LayoutTests/webgpu/whlsl/matrix-index-assign-expected.txt b/LayoutTests/webgpu/whlsl/matrix-index-assign-expected.txt
new file mode 100644 (file)
index 0000000..b2fffe4
--- /dev/null
@@ -0,0 +1,3 @@
+
+PASS fieldShouldBeNull 
+
diff --git a/LayoutTests/webgpu/whlsl/matrix-index-assign.html b/LayoutTests/webgpu/whlsl/matrix-index-assign.html
new file mode 100644 (file)
index 0000000..c878178
--- /dev/null
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>matrix-index-assign-swizzle.</title>
+<script src="js/test-harness.js"></script>
+<script src="../js/webgpu-functions.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+const whlslTests = {};
+
+whlslTests.fieldShouldBeNull = async () => {
+    const program = `
+        bool foo() {
+            float2x3 mat;
+            mat[0] = float3(10.0, 20.0, 30.0);
+
+            if (!all(mat[0] == float3(10.0, 20.0, 30.0)))
+                return false;
+
+            if (!all(mat[0].xy == float2(10.0, 20.0)))
+                return false;
+
+            if (!all(mat[0].yx == float2(20.0, 10.0)))
+                return false;
+
+            mat[0].xy = float2(1.0, 2.0);
+            if (!all(mat[0].xy == float2(1.0, 2.0)))
+                return false;
+
+            mat[0].yx.yx = float2(100.0, 200.0);
+            if (!all(mat[0].xy == float2(100.0, 200.0)))
+                return false;
+
+            return true;
+        }
+    `;
+
+    assert_equals(await callBoolFunction(program,  "foo", []), true);
+};
+
+runTests(whlslTests);
+</script>
+</html>
diff --git a/LayoutTests/webgpu/whlsl/matrix-index-order-expected.txt b/LayoutTests/webgpu/whlsl/matrix-index-order-expected.txt
new file mode 100644 (file)
index 0000000..ba4ca02
--- /dev/null
@@ -0,0 +1,6 @@
+
+PASS matMul 
+PASS matMul2 
+PASS matMul3 
+PASS matMul4 
+
diff --git a/LayoutTests/webgpu/whlsl/matrix-index-order.html b/LayoutTests/webgpu/whlsl/matrix-index-order.html
new file mode 100644 (file)
index 0000000..5994432
--- /dev/null
@@ -0,0 +1,142 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>matrix-index-order.</title>
+<script src="js/test-harness.js"></script>
+<script src="../js/webgpu-functions.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+const whlslTests = {};
+
+whlslTests.matMul = async () => {
+    const program = `
+        bool foo() {
+            float2x3 a = float2x3(
+                float3(1, 2, 3),
+                float3(4, 5, 6)
+            );
+
+            float3x2 b = float3x2(
+                float2(7, 8),
+                float2(9, 10),
+                float2(11, 12)
+            );
+
+            float3x3 result = mul(a, b);
+
+            float3x3 expected = float3x3(
+                float3(39, 54, 69),
+                float3(49, 68, 87),
+                float3(59, 82, 105)
+            );
+            return all(expected == result);
+        }
+    `;
+
+    assert_equals(await callBoolFunction(program,  "foo", []), true);
+};
+
+whlslTests.matMul2 = async () => {
+    const program = `
+        bool foo() {
+            float2x2 a = float2x2(
+                float2(1, 8),
+                float2(5, 12)
+            );
+
+            float2 b = float2(22, 45);
+
+            float2 result = mul(a, b);
+
+            float2 expected = float2(247, 716);
+
+            return all(expected == result);
+        }
+    `;
+
+    assert_equals(await callBoolFunction(program,  "foo", []), true);
+};
+
+whlslTests.matMul3 = async () => {
+    const program = `
+        bool foo() {
+            float2x2 a = float2x2(
+                float2(1, 2),
+                float2(3, 4)
+            );
+
+            float2x2 b = float2x2(
+                float2(5, 6),
+                float2(7, 8)
+            );
+
+            float2x2 result = mul(a, b);
+
+            float2x2 expected = float2x2(
+                float2(23, 34),
+                float2(31, 46)
+            );
+
+            return all(expected == result);
+        }
+
+        bool bar() {
+            float2x2 b = float2x2(
+                float2(1, 2),
+                float2(3, 4)
+            );
+
+            float2x2 a = float2x2(
+                float2(5, 6),
+                float2(7, 8)
+            );
+
+            float2x2 result = mul(a, b);
+
+            float2x2 expected = float2x2(
+                float2(19, 22),
+                float2(43, 50)
+            );
+
+            return all(expected == result);
+        }
+    `;
+
+    assert_equals(await callBoolFunction(program,  "foo", []), true);
+    assert_equals(await callBoolFunction(program,  "bar", []), true);
+};
+
+whlslTests.matMul4 = async () => {
+    const program = `
+        bool foo() {
+            float2x4 a = float2x4(
+                float4(1, 2, 3, 4),
+                float4(5, 6, 7, 8)
+            );
+
+            float3x2 b = float3x2(
+                float2(9, 10),
+                float2(11, 12),
+                float2(13, 14)
+            );
+
+            float3x4 result = mul(a, b);
+
+            float3x4 expected = float3x4(
+                float4(59, 78, 97, 116),
+                float4(71, 94, 117, 140),
+                float4(83, 110, 137, 164)
+            );
+
+            return all(expected == result);
+        }
+    `;
+
+    assert_equals(await callBoolFunction(program,  "foo", []), true);
+};
+
+runTests(whlslTests);
+</script>
+</html>
index 5a36d5d..bd09748 100644 (file)
@@ -60,20 +60,20 @@ async function start(device) {
     const bufferArrayBuffer = await buffer.mapWriteAsync();
     const bufferFloat32Array = new Float32Array(bufferArrayBuffer);
     bufferFloat32Array[0] = 0;
-    bufferFloat32Array[1] = 4;
-    bufferFloat32Array[2] = 8;
-    bufferFloat32Array[3] = 12;
-    bufferFloat32Array[4] = 1;
+    bufferFloat32Array[1] = 1;
+    bufferFloat32Array[2] = 2;
+    bufferFloat32Array[3] = 3;
+    bufferFloat32Array[4] = 4;
     bufferFloat32Array[5] = 5;
-    bufferFloat32Array[6] = 9;
-    bufferFloat32Array[7] = 13;
-    bufferFloat32Array[8] = 2;
-    bufferFloat32Array[9] = 6;
+    bufferFloat32Array[6] = 6;
+    bufferFloat32Array[7] = 7;
+    bufferFloat32Array[8] = 8;
+    bufferFloat32Array[9] = 9;
     bufferFloat32Array[10] = 10;
-    bufferFloat32Array[11] = 14;
-    bufferFloat32Array[12] = 3;
-    bufferFloat32Array[13] = 7;
-    bufferFloat32Array[14] = 11;
+    bufferFloat32Array[11] = 11;
+    bufferFloat32Array[12] = 12;
+    bufferFloat32Array[13] = 13;
+    bufferFloat32Array[14] = 14;
     bufferFloat32Array[15] = 15;
     buffer.unmap();
 
@@ -98,23 +98,23 @@ async function start(device) {
     const resultsArrayBuffer = await resultsBuffer.mapReadAsync();
     const resultsFloat32Array = new Float32Array(resultsArrayBuffer);
     if (resultsFloat32Array[0] === 1
-        && resultsFloat32Array[1] === 5
-        && resultsFloat32Array[2] === 9
-        && resultsFloat32Array[3] === 13
+        && resultsFloat32Array[1] === 2
+        && resultsFloat32Array[2] === 3
+        && resultsFloat32Array[3] === 4
 
-        && resultsFloat32Array[4] === 2
+        && resultsFloat32Array[4] === 5
         && resultsFloat32Array[5] === 6
-        && resultsFloat32Array[6] === 10
-        && resultsFloat32Array[7] === 14
+        && resultsFloat32Array[6] === 7
+        && resultsFloat32Array[7] === 8
 
-        && resultsFloat32Array[8] === 3
-        && resultsFloat32Array[9] === 7
+        && resultsFloat32Array[8] === 9
+        && resultsFloat32Array[9] === 10
         && resultsFloat32Array[10] === 11
-        && resultsFloat32Array[11] === 15
+        && resultsFloat32Array[11] === 12
 
-        && resultsFloat32Array[12] === 4
-        && resultsFloat32Array[13] === 8
-        && resultsFloat32Array[14] === 12
+        && resultsFloat32Array[12] === 13
+        && resultsFloat32Array[13] === 14
+        && resultsFloat32Array[14] === 15
         && resultsFloat32Array[15] === 16)
         testPassed("");
     else
index fe3620e..dc9e47f 100644 (file)
@@ -67,20 +67,28 @@ compute void computeShader(device float[] buffer : register(u0), float3 threadID
         return;
 
     fourtyTwo[1337] = 50;
+    if (fourtyTwo.x != 50)
+        return;
+
+    fourtyTwo[1337] = 42;
     foo[1] = fourtyTwo;
     if (!allEqual(foo, 42))
         return;
 
     fourtyTwo[1000000] = 50;
+    if (fourtyTwo.x != 50)
+        return;
+
+    fourtyTwo[1337] = 42;
     foo[1] = fourtyTwo;
     if (!allEqual(foo, 42))
         return;
 
-    float3 shouldBeZero = foo[100000];
-    if (shouldBeZero.x != 0 || shouldBeZero.y != 0 || shouldBeZero.z != 0)
+    float3 shouldBeFourtyTwo = foo[100000];
+    if (shouldBeFourtyTwo.x != 42 || shouldBeFourtyTwo.y != 42 || shouldBeFourtyTwo.z != 42)
         return;
 
-    if (fourtyTwo[10000000] != 0)
+    if (fourtyTwo[10000000] != 42)
         return;
 
     buffer[uint(threadID.x)] = buffer[uint(threadID.x)] * 2.0;
@@ -145,7 +153,7 @@ async function start(device) {
         && resultsFloat32Array[7] == 8)
         testPassed("");
     else
-        testFailed("");
+        testFailed("not correct");
     resultsBuffer.unmap();
 }
 window.jsTestIsAsync = true;
index 02b7ca0..58a5d03 100644 (file)
@@ -2,7 +2,7 @@
 <html>
 <meta charset=utf-8>
 <meta name="timeout" content="long">
-<title>Test structs.</title>
+<title>null.</title>
 <script src="js/test-harness.js"></script>
 <script src="../js/webgpu-functions.js"></script>
 <script src="../../resources/testharness.js"></script>
@@ -10,9 +10,9 @@
 <script>
 const whlslTests = {};
 
-whlslTests.passNullToPtrMonomorphic = async () =>
+whlslTests.nullIsError = async () =>
 {
-    let program = `
+    await checkFail(`
         int foo(thread int* ptr)
         {
             return *ptr;
@@ -21,11 +21,23 @@ whlslTests.passNullToPtrMonomorphic = async () =>
         {
             return foo(null);
         }
-    `;
-    assert_equals(await callIntFunction(program, "bar", []), 0);
+    `);
+
+    await checkFail(`
+        void bar()
+        {
+            thread int* x;
+        }
+    `);
+
+    await checkFail(`
+        void bar()
+        {
+            thread int[] x;
+        }
+    `);
 }
 
 runTests(whlslTests);
 </script>
 </html>
-
diff --git a/LayoutTests/webgpu/whlsl/null-dereference-expected.txt b/LayoutTests/webgpu/whlsl/null-dereference-expected.txt
deleted file mode 100644 (file)
index 4882f90..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-PASS 
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/LayoutTests/webgpu/whlsl/null-dereference.html b/LayoutTests/webgpu/whlsl/null-dereference.html
deleted file mode 100644 (file)
index 5790c10..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../js/webgpu-functions.js"></script>
-<script src="../../resources/js-test-pre.js"></script>
-</head>
-<body>
-<script>
-const shaderSource = `
-typedef Foo = thread int*;
-Foo getNullPtr()
-{
-    return null;
-}
-
-struct XYZ {
-    float x;
-    float y;
-    float z;
-}
-
-[numthreads(2, 1, 1)]
-compute void computeShader(device float[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) {
-    Foo ptr = null;
-    *ptr = 42;
-    *getNullPtr() = 42;
-    if (*ptr == 0) {
-        if (ptr == getNullPtr()) {
-            if (*getNullPtr() == 0) {
-                thread XYZ* xyzPtr = null;
-                XYZ xyz;
-                xyz.x = 1;
-                xyz.y = 1;
-                xyz.z = 1;
-                if (xyz.z == 1.0 && xyz.y == 1.0 && xyz.z == 1.0) {
-                    *xyzPtr = xyz;
-                    xyz = *xyzPtr;
-                    if (xyz.z == 0.0 && xyz.y == 0.0 && xyz.z == 0.0) {
-                        if (&*getNullPtr() == null) {
-                            if (&*(&*getNullPtr()) == null) {
-                                buffer[uint(threadID.x)] = buffer[uint(threadID.x)] * 2.0;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-`;
-
-async function start(device) {
-    const shaderModule = device.createShaderModule({code: shaderSource});
-    const computeStage = {module: shaderModule, entryPoint: "computeShader"};
-
-    const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "storage-buffer"}]};
-    const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor);
-    const pipelineLayoutDescriptor = {bindGroupLayouts: [bindGroupLayout]};
-    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
-
-    const computePipelineDescriptor = {computeStage, layout: pipelineLayout};
-    const computePipeline = device.createComputePipeline(computePipelineDescriptor);
-
-    const size = Float32Array.BYTES_PER_ELEMENT * 8;
-
-    const bufferDescriptor = {size, usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.TRANSFER_SRC};
-    const buffer = device.createBuffer(bufferDescriptor);
-    const bufferArrayBuffer = await buffer.mapWriteAsync();
-    const bufferFloat32Array = new Float32Array(bufferArrayBuffer);
-    bufferFloat32Array[0] = 1;
-    bufferFloat32Array[1] = 2;
-    bufferFloat32Array[2] = 3;
-    bufferFloat32Array[3] = 4;
-    bufferFloat32Array[4] = 5;
-    bufferFloat32Array[5] = 6;
-    bufferFloat32Array[6] = 7;
-    bufferFloat32Array[7] = 8;
-    buffer.unmap();
-
-    const resultsBufferDescriptor = {size, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.TRANSFER_DST | GPUBufferUsage.MAP_READ};
-    const resultsBuffer = device.createBuffer(resultsBufferDescriptor);
-
-    const bufferBinding = {buffer: resultsBuffer, size};
-    const bindGroupBinding = {binding: 0, resource: bufferBinding};
-    const bindGroupDescriptor = {layout: bindGroupLayout, bindings: [bindGroupBinding]};
-    const bindGroup = device.createBindGroup(bindGroupDescriptor);
-
-    const commandEncoder = device.createCommandEncoder(); // {}
-    commandEncoder.copyBufferToBuffer(buffer, 0, resultsBuffer, 0, size);
-    const computePassEncoder = commandEncoder.beginComputePass();
-    computePassEncoder.setPipeline(computePipeline);
-    computePassEncoder.setBindGroup(0, bindGroup);
-    computePassEncoder.dispatch(2, 1, 1);
-    computePassEncoder.endPass();
-    const commandBuffer = commandEncoder.finish();
-    device.getQueue().submit([commandBuffer]);
-
-    const resultsArrayBuffer = await resultsBuffer.mapReadAsync();
-    const resultsFloat32Array = new Float32Array(resultsArrayBuffer);
-    if (resultsFloat32Array[0] == 2
-        && resultsFloat32Array[1] == 4
-        && resultsFloat32Array[2] == 6
-        && resultsFloat32Array[3] == 8
-        && resultsFloat32Array[4] == 5
-        && resultsFloat32Array[5] == 6
-        && resultsFloat32Array[6] == 7
-        && resultsFloat32Array[7] == 8)
-        testPassed("");
-    else
-        testFailed("");
-    resultsBuffer.unmap();
-}
-window.jsTestIsAsync = true;
-getBasicDevice().then(function(device) {
-    start(device).then(function() {
-        finishJSTest();
-    }, function() {
-        testFailed("");
-        finishJSTest();
-    });
-}, function() {
-    testPassed("");
-    finishJSTest();
-});
-</script>
-<script src="../../resources/js-test-post.js"></script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/oob-access-2-expected.txt b/LayoutTests/webgpu/whlsl/oob-access-2-expected.txt
new file mode 100644 (file)
index 0000000..95456c4
--- /dev/null
@@ -0,0 +1,3 @@
+
+PASS oob 
+
diff --git a/LayoutTests/webgpu/whlsl/oob-access-2.html b/LayoutTests/webgpu/whlsl/oob-access-2.html
new file mode 100644 (file)
index 0000000..dccca5d
--- /dev/null
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>OOB.</title>
+<script src="js/test-harness.js"></script>
+<script src="../js/webgpu-functions.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+const whlslTests = {};
+
+whlslTests.oob = async () => {
+    const program = `
+        int foo()
+        {
+            int x = 3;
+            thread int[] a = @x;
+            a[424242] = 25;
+            return x;
+        }
+
+        int bar()
+        {
+            int[10] x;
+            thread int[] a = @x;
+            a[424242] = 25;
+            return x[0];
+        }
+
+        int baz()
+        {
+            int[10] x;
+            thread int[] a = @x;
+            a[424242] = 25;
+            return x[1];
+        }
+    `;
+    assert_equals(await callIntFunction(program, "foo", []), 25);
+    assert_equals(await callIntFunction(program, "bar", []), 25);
+    assert_equals(await callIntFunction(program, "baz", []), 0);
+};
+
+runTests(whlslTests);
+</script>
+</html>
index 11ca6cc..3b634a3 100644 (file)
@@ -7,7 +7,7 @@
 <body>
 <script>
 const shaderSource = `
-[numthreads(2, 1, 1)]
+[numthreads(4, 1, 1)]
 compute void computeShader(device float[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) {
     buffer[1337] = 0.0;
     buffer[42424242] = 0.0;
@@ -57,14 +57,14 @@ async function start(device) {
     const computePassEncoder = commandEncoder.beginComputePass();
     computePassEncoder.setPipeline(computePipeline);
     computePassEncoder.setBindGroup(0, bindGroup);
-    computePassEncoder.dispatch(2, 1, 1);
+    computePassEncoder.dispatch(1, 1, 1);
     computePassEncoder.endPass();
     const commandBuffer = commandEncoder.finish();
     device.getQueue().submit([commandBuffer]);
 
     const resultsArrayBuffer = await resultsBuffer.mapReadAsync();
     const resultsFloat32Array = new Float32Array(resultsArrayBuffer);
-    if (resultsFloat32Array[0] == 2
+    if (resultsFloat32Array[0] == 0
         && resultsFloat32Array[1] == 4
         && resultsFloat32Array[2] == 6
         && resultsFloat32Array[3] == 8
diff --git a/LayoutTests/webgpu/whlsl/operator-syntax-expected.txt b/LayoutTests/webgpu/whlsl/operator-syntax-expected.txt
new file mode 100644 (file)
index 0000000..9e90f26
--- /dev/null
@@ -0,0 +1,3 @@
+
+PASS operatorSyntax 
+
diff --git a/LayoutTests/webgpu/whlsl/operator-syntax.html b/LayoutTests/webgpu/whlsl/operator-syntax.html
new file mode 100644 (file)
index 0000000..1e1b779
--- /dev/null
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>Some operators should be syntax errors.</title>
+<script src="js/test-harness.js"></script>
+<script src="../js/webgpu-functions.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+const whlslTests = {};
+
+whlslTests.operatorSyntax = async () =>
+{
+    await checkFail(`
+        struct Foo { }
+        int operator.foo(Foo) { return 42; }
+    `);
+    await checkFail(`
+        struct Foo { }
+        int operator.foo=(Foo) { return 42; }
+    `);
+
+    await checkFail(`
+        struct Foo { }
+        thread int* operator&.foo(Foo) { int x; return &x; }
+    `);
+
+    await checkFail(`
+        struct Foo { }
+        int operator[](Foo, uint) { return 42; }
+    `);
+
+    await checkFail(`
+        struct Foo { }
+        int operator[]=(Foo, uint) { return 42; }
+    `);
+
+    await checkFail(`
+        struct Foo { }
+        thread int* operator&[](Foo, uint) { int x; return &x; }
+    `);
+}
+
+runTests(whlslTests);
+</script>
+</html>
index f2aa007..8b4e664 100644 (file)
@@ -17,11 +17,11 @@ whlslTests.vectorIndexAssign = async () => {
             int2 x;
             x[0] = 20;
             x[1] = 10;
-            x[5000] = 20;
+            x[5000] = 40;
             return x.x / x.y + x[5000];
         }
     `;
-    assert_equals(await callIntFunction(program,  "foo", []), 2);
+    assert_equals(await callIntFunction(program,  "foo", []), 40 / 10 + 40);
 };
 
 runTests(whlslTests);
index a650905..67b3746 100644 (file)
@@ -17,11 +17,11 @@ whlslTests.vectorIndexLoad = async () => {
             int2 x;
             x.x = 20;
             x.y = 10;
-            x[5000] = 20;
+            x[5000] = 40;
             return x[0] / x[1] + x[5000];
         }
     `;
-    assert_equals(await callIntFunction(program,  "foo", []), 2);
+    assert_equals(await callIntFunction(program,  "foo", []), 40/10 + 40);
 };
 
 runTests(whlslTests);
diff --git a/LayoutTests/webgpu/whlsl/override-subscript-expected.txt b/LayoutTests/webgpu/whlsl/override-subscript-expected.txt
deleted file mode 100644 (file)
index 3864009..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-
-PASS overrideSubscriptStruct 
-PASS overrideSubscriptStructAndDoStores 
-PASS overrideSubscriptStructAndUsePointers 
-PASS overrideSubscriptStructAndUsePointersIncorrectly 
-
diff --git a/LayoutTests/webgpu/whlsl/override-subscript.html b/LayoutTests/webgpu/whlsl/override-subscript.html
deleted file mode 100644 (file)
index 236f744..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-<!DOCTYPE html>
-<html>
-<meta charset=utf-8>
-<meta name="timeout" content="long">
-<title>Test override subscripts.</title>
-<script src="js/test-harness.js"></script>
-<script src="../js/webgpu-functions.js"></script>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script>
-const whlslTests = {};
-
-whlslTests.overrideSubscriptStruct = async () =>
-{
-    let program = `
-        struct Foo {
-            int x;
-            int y;
-        }
-        thread int* operator&[](thread Foo* foo, uint index)
-        {
-            if (index == 0)
-                return &foo->x;
-            if (index == 1)
-                return &foo->y;
-            return null;
-        }
-        int foo()
-        {
-            Foo foo;
-            foo.x = 498;
-            foo.y = 19;
-            return foo[0] + foo[1] * 3;
-        }
-    `;
-    assert_equals(await callIntFunction(program, "foo", []), 498 + 19 * 3);
-}
-
-whlslTests.overrideSubscriptStructAndDoStores = async () =>
-{
-    let program = `
-        struct Foo {
-            int x;
-            int y;
-        }
-        thread int* operator&[](thread Foo* foo, uint index)
-        {
-            if (index == 0)
-                return &foo->x;
-            if (index == 1)
-                return &foo->y;
-            return null;
-        }
-        int foo()
-        {
-            Foo foo;
-            foo[0] = 498;
-            foo[1] = 19;
-            return foo.x + foo.y;
-        }
-    `;
-    assert_equals(await callIntFunction(program, "foo", []), 498 + 19);
-}
-
-whlslTests.overrideSubscriptStructAndUsePointers = async () =>
-{
-    let program = `
-        struct Foo {
-            int x;
-            int y;
-        }
-        thread int* operator&[](thread Foo* foo, uint index)
-        {
-            if (index == 0)
-                return &foo->x;
-            if (index == 1)
-                return &foo->y;
-            return null;
-        }
-        int bar(thread Foo* foo)
-        {
-            return (*foo)[0] + (*foo)[1];
-        }
-        int foo()
-        {
-            Foo foo;
-            foo.x = 498;
-            foo.y = 19;
-            return bar(&foo);
-        }
-    `;
-    assert_equals(await callIntFunction(program, "foo", []), 498 + 19);
-}
-
-whlslTests.overrideSubscriptStructAndUsePointersIncorrectly = async () =>
-{
-    checkFail(
-        `
-            struct Foo {
-                int x;
-                int y;
-            }
-            thread int* operator&[](thread Foo* foo, uint index)
-            {
-                if (index == 0)
-                    return &foo->x;
-                if (index == 1)
-                    return &foo->y;
-                return null;
-            }
-            int bar(thread Foo* foo)
-            {
-                return foo[0] + foo[1];
-            }
-            int foo()
-            {
-                Foo foo;
-                foo.x = 498;
-                foo.y = 19;
-                return bar(&foo);
-            }
-        `);
-}
-
-runTests(whlslTests);
-</script>
-</html>
-
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/ander-abstract-lvalue-expected.html b/LayoutTests/webgpu/whlsl/propertyresolver/ander-abstract-lvalue-expected.html
deleted file mode 100644 (file)
index 6dd184d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const canvas = document.getElementById("canvas");
-drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/ander-abstract-lvalue.html b/LayoutTests/webgpu/whlsl/propertyresolver/ander-abstract-lvalue.html
deleted file mode 100644 (file)
index 4f866fc..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const shaderSource = `
-vertex float4 vertexShader(float4 position : attribute(0)) : SV_Position {
-    return position;
-}
-
-struct Foo {
-    float x;
-}
-
-thread float* operator&.y(thread Foo* f) {
-    return &f->x;
-}
-
-struct Bar {
-    Foo z;
-}
-
-Foo operator.w(Bar b) {
-    return b.z;
-}
-
-Bar operator.w=(Bar b, Foo a) {
-    b.z = a;
-    return b;
-}
-
-fragment float4 fragmentShader() : SV_Target 0 {
-    Bar b;
-    b.w.y = 1.0;
-    return float4(b.w.y, b.w.y, b.w.y, 1.0);
-}
-`;
-
-const canvas = document.getElementById("canvas");
-
-async function start(device) {
-    const shaderModule = device.createShaderModule({code: shaderSource});
-    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, format: "float4"};
-    const input0 = {stride: 16, attributeSet: [attribute0]};
-    const inputs = [input0];
-    const vertexInput = {vertexBuffers: inputs};
-
-    const pipelineLayoutDescriptor = {bindGroupLayouts: []};
-    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
-
-    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
-    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
-
-    const vertexBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
-    const vertexBuffer = device.createBuffer(vertexBufferDescriptor);
-    const vertexBufferArrayBuffer = await vertexBuffer.mapWriteAsync();
-    const vertexBufferFloat32Array = new Float32Array(vertexBufferArrayBuffer);
-    vertexBufferFloat32Array[0] = -0.5;
-    vertexBufferFloat32Array[1] = -0.5;
-    vertexBufferFloat32Array[2] = 1.0;
-    vertexBufferFloat32Array[3] = 1;
-    vertexBufferFloat32Array[4] = -0.5;
-    vertexBufferFloat32Array[5] = 0.5;
-    vertexBufferFloat32Array[6] = 1.0;
-    vertexBufferFloat32Array[7] = 1;
-    vertexBufferFloat32Array[8] = 0.5;
-    vertexBufferFloat32Array[9] = -0.5;
-    vertexBufferFloat32Array[10] = 1.0;
-    vertexBufferFloat32Array[11] = 1;
-    vertexBufferFloat32Array[12] = 0.5;
-    vertexBufferFloat32Array[13] = 0.5;
-    vertexBufferFloat32Array[14] = 1.0;
-    vertexBufferFloat32Array[15] = 1;
-    vertexBuffer.unmap();
-
-    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.setVertexBuffers(0, [vertexBuffer], [0]);
-    renderPassEncoder.draw(4, 1, 0, 0);
-    renderPassEncoder.endPass();
-    const commandBuffer = commandEncoder.finish();
-    device.getQueue().submit([commandBuffer]);
-}
-if (window.testRunner)
-    testRunner.waitUntilDone();
-getBasicDevice().then(function(device) {
-    start(device).then(function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    }, function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    });
-}, function() {
-    drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-    if (window.testRunner)
-        testRunner.notifyDone();
-});
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/ander-expected.html b/LayoutTests/webgpu/whlsl/propertyresolver/ander-expected.html
deleted file mode 100644 (file)
index 6dd184d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const canvas = document.getElementById("canvas");
-drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/ander-lvalue-3-levels-expected.html b/LayoutTests/webgpu/whlsl/propertyresolver/ander-lvalue-3-levels-expected.html
deleted file mode 100644 (file)
index 6dd184d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const canvas = document.getElementById("canvas");
-drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/ander-lvalue-3-levels.html b/LayoutTests/webgpu/whlsl/propertyresolver/ander-lvalue-3-levels.html
deleted file mode 100644 (file)
index aa9a13b..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const shaderSource = `
-vertex float4 vertexShader(float4 position : attribute(0)) : SV_Position {
-    return position;
-}
-
-struct Foo {
-    float x;
-}
-
-thread float* operator&.y(thread Foo* f) {
-    return &f->x;
-}
-
-struct Bar {
-    Foo z;
-}
-
-thread Foo* operator&.w(thread Bar* b) {
-    return &b->z;
-}
-
-struct Baz {
-    Bar p;
-}
-
-thread Bar* operator&.q(thread Baz* b) {
-    return &b->p;
-}
-
-fragment float4 fragmentShader() : SV_Target 0 {
-    Baz b;
-    b.q.w.y = 1.0;
-    return float4(b.q.w.y, b.q.w.y, b.q.w.y, 1.0);
-}
-`;
-
-const canvas = document.getElementById("canvas");
-
-async function start(device) {
-    const shaderModule = device.createShaderModule({code: shaderSource});
-    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, format: "float4"};
-    const input0 = {stride: 16, attributeSet: [attribute0]};
-    const inputs = [input0];
-    const vertexInput = {vertexBuffers: inputs};
-
-    const pipelineLayoutDescriptor = {bindGroupLayouts: []};
-    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
-
-    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
-    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
-
-    const vertexBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
-    const vertexBuffer = device.createBuffer(vertexBufferDescriptor);
-    const vertexBufferArrayBuffer = await vertexBuffer.mapWriteAsync();
-    const vertexBufferFloat32Array = new Float32Array(vertexBufferArrayBuffer);
-    vertexBufferFloat32Array[0] = -0.5;
-    vertexBufferFloat32Array[1] = -0.5;
-    vertexBufferFloat32Array[2] = 1.0;
-    vertexBufferFloat32Array[3] = 1;
-    vertexBufferFloat32Array[4] = -0.5;
-    vertexBufferFloat32Array[5] = 0.5;
-    vertexBufferFloat32Array[6] = 1.0;
-    vertexBufferFloat32Array[7] = 1;
-    vertexBufferFloat32Array[8] = 0.5;
-    vertexBufferFloat32Array[9] = -0.5;
-    vertexBufferFloat32Array[10] = 1.0;
-    vertexBufferFloat32Array[11] = 1;
-    vertexBufferFloat32Array[12] = 0.5;
-    vertexBufferFloat32Array[13] = 0.5;
-    vertexBufferFloat32Array[14] = 1.0;
-    vertexBufferFloat32Array[15] = 1;
-    vertexBuffer.unmap();
-
-    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.setVertexBuffers(0, [vertexBuffer], [0]);
-    renderPassEncoder.draw(4, 1, 0, 0);
-    renderPassEncoder.endPass();
-    const commandBuffer = commandEncoder.finish();
-    device.getQueue().submit([commandBuffer]);
-}
-if (window.testRunner)
-    testRunner.waitUntilDone();
-getBasicDevice().then(function(device) {
-    start(device).then(function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    }, function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    });
-}, function() {
-    drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-    if (window.testRunner)
-        testRunner.notifyDone();
-});
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/ander-lvalue-expected.html b/LayoutTests/webgpu/whlsl/propertyresolver/ander-lvalue-expected.html
deleted file mode 100644 (file)
index 6dd184d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const canvas = document.getElementById("canvas");
-drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/ander-lvalue.html b/LayoutTests/webgpu/whlsl/propertyresolver/ander-lvalue.html
deleted file mode 100644 (file)
index 949b1dd..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const shaderSource = `
-vertex float4 vertexShader(float4 position : attribute(0)) : SV_Position {
-    return position;
-}
-
-struct Foo {
-    float x;
-}
-
-thread float* operator&.y(thread Foo* f) {
-    return &f->x;
-}
-
-struct Bar {
-    Foo z;
-}
-
-thread Foo* operator&.w(thread Bar* b) {
-    return &b->z;
-}
-
-fragment float4 fragmentShader() : SV_Target 0 {
-    Bar b;
-    b.w.y = 1.0;
-    return float4(b.w.y, b.w.y, b.w.y, 1.0);
-}
-`;
-
-const canvas = document.getElementById("canvas");
-
-async function start(device) {
-    const shaderModule = device.createShaderModule({code: shaderSource});
-    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, format: "float4"};
-    const input0 = {stride: 16, attributeSet: [attribute0]};
-    const inputs = [input0];
-    const vertexInput = {vertexBuffers: inputs};
-
-    const pipelineLayoutDescriptor = {bindGroupLayouts: []};
-    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
-
-    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
-    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
-
-    const vertexBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
-    const vertexBuffer = device.createBuffer(vertexBufferDescriptor);
-    const vertexBufferArrayBuffer = await vertexBuffer.mapWriteAsync();
-    const vertexBufferFloat32Array = new Float32Array(vertexBufferArrayBuffer);
-    vertexBufferFloat32Array[0] = -0.5;
-    vertexBufferFloat32Array[1] = -0.5;
-    vertexBufferFloat32Array[2] = 1.0;
-    vertexBufferFloat32Array[3] = 1;
-    vertexBufferFloat32Array[4] = -0.5;
-    vertexBufferFloat32Array[5] = 0.5;
-    vertexBufferFloat32Array[6] = 1.0;
-    vertexBufferFloat32Array[7] = 1;
-    vertexBufferFloat32Array[8] = 0.5;
-    vertexBufferFloat32Array[9] = -0.5;
-    vertexBufferFloat32Array[10] = 1.0;
-    vertexBufferFloat32Array[11] = 1;
-    vertexBufferFloat32Array[12] = 0.5;
-    vertexBufferFloat32Array[13] = 0.5;
-    vertexBufferFloat32Array[14] = 1.0;
-    vertexBufferFloat32Array[15] = 1;
-    vertexBuffer.unmap();
-
-    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.setVertexBuffers(0, [vertexBuffer], [0]);
-    renderPassEncoder.draw(4, 1, 0, 0);
-    renderPassEncoder.endPass();
-    const commandBuffer = commandEncoder.finish();
-    device.getQueue().submit([commandBuffer]);
-}
-if (window.testRunner)
-    testRunner.waitUntilDone();
-getBasicDevice().then(function(device) {
-    start(device).then(function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    }, function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    });
-}, function() {
-    drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-    if (window.testRunner)
-        testRunner.notifyDone();
-});
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/ander.html b/LayoutTests/webgpu/whlsl/propertyresolver/ander.html
deleted file mode 100644 (file)
index a448461..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const shaderSource = `
-vertex float4 vertexShader(float4 position : attribute(0)) : SV_Position {
-    return position;
-}
-
-struct Foo {
-    float x;
-}
-
-thread float* operator&.y(thread Foo* f) {
-    return &f->x;
-}
-
-Foo generateFoo() {
-    Foo f;
-    f.x = 1.0;
-    return f;
-}
-
-fragment float4 fragmentShader() : SV_Target 0 {
-    return float4(generateFoo().y, generateFoo().y, generateFoo().y, 1.0);
-}
-`;
-
-const canvas = document.getElementById("canvas");
-
-async function start(device) {
-    const shaderModule = device.createShaderModule({code: shaderSource});
-    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, format: "float4"};
-    const input0 = {stride: 16, attributeSet: [attribute0]};
-    const inputs = [input0];
-    const vertexInput = {vertexBuffers: inputs};
-
-    const pipelineLayoutDescriptor = {bindGroupLayouts: []};
-    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
-
-    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
-    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
-
-    const vertexBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
-    const vertexBuffer = device.createBuffer(vertexBufferDescriptor);
-    const vertexBufferArrayBuffer = await vertexBuffer.mapWriteAsync();
-    const vertexBufferFloat32Array = new Float32Array(vertexBufferArrayBuffer);
-    vertexBufferFloat32Array[0] = -0.5;
-    vertexBufferFloat32Array[1] = -0.5;
-    vertexBufferFloat32Array[2] = 1.0;
-    vertexBufferFloat32Array[3] = 1;
-    vertexBufferFloat32Array[4] = -0.5;
-    vertexBufferFloat32Array[5] = 0.5;
-    vertexBufferFloat32Array[6] = 1.0;
-    vertexBufferFloat32Array[7] = 1;
-    vertexBufferFloat32Array[8] = 0.5;
-    vertexBufferFloat32Array[9] = -0.5;
-    vertexBufferFloat32Array[10] = 1.0;
-    vertexBufferFloat32Array[11] = 1;
-    vertexBufferFloat32Array[12] = 0.5;
-    vertexBufferFloat32Array[13] = 0.5;
-    vertexBufferFloat32Array[14] = 1.0;
-    vertexBufferFloat32Array[15] = 1;
-    vertexBuffer.unmap();
-
-    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.setVertexBuffers(0, [vertexBuffer], [0]);
-    renderPassEncoder.draw(4, 1, 0, 0);
-    renderPassEncoder.endPass();
-    const commandBuffer = commandEncoder.finish();
-    device.getQueue().submit([commandBuffer]);
-}
-if (window.testRunner)
-    testRunner.waitUntilDone();
-getBasicDevice().then(function(device) {
-    start(device).then(function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    }, function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    });
-}, function() {
-    drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-    if (window.testRunner)
-        testRunner.notifyDone();
-});
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/getter-expected.html b/LayoutTests/webgpu/whlsl/propertyresolver/getter-expected.html
deleted file mode 100644 (file)
index 6dd184d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const canvas = document.getElementById("canvas");
-drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/getter.html b/LayoutTests/webgpu/whlsl/propertyresolver/getter.html
deleted file mode 100644 (file)
index ddeaf27..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const shaderSource = `
-vertex float4 vertexShader(float4 position : attribute(0)) : SV_Position {
-    return position;
-}
-
-struct Foo {
-    float x;
-}
-
-float operator.y(Foo f) {
-    return f.x;
-}
-
-fragment float4 fragmentShader() : SV_Target 0 {
-    Foo f;
-    f.x = 1.0;
-    return float4(f.y, f.y, f.y, 1.0);
-}
-`;
-
-const canvas = document.getElementById("canvas");
-
-async function start(device) {
-    const shaderModule = device.createShaderModule({code: shaderSource});
-    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, format: "float4"};
-    const input0 = {stride: 16, attributeSet: [attribute0]};
-    const inputs = [input0];
-    const vertexInput = {vertexBuffers: inputs};
-
-    const pipelineLayoutDescriptor = {bindGroupLayouts: []};
-    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
-
-    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
-    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
-
-    const vertexBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
-    const vertexBuffer = device.createBuffer(vertexBufferDescriptor);
-    const vertexBufferArrayBuffer = await vertexBuffer.mapWriteAsync();
-    const vertexBufferFloat32Array = new Float32Array(vertexBufferArrayBuffer);
-    vertexBufferFloat32Array[0] = -0.5;
-    vertexBufferFloat32Array[1] = -0.5;
-    vertexBufferFloat32Array[2] = 1.0;
-    vertexBufferFloat32Array[3] = 1;
-    vertexBufferFloat32Array[4] = -0.5;
-    vertexBufferFloat32Array[5] = 0.5;
-    vertexBufferFloat32Array[6] = 1.0;
-    vertexBufferFloat32Array[7] = 1;
-    vertexBufferFloat32Array[8] = 0.5;
-    vertexBufferFloat32Array[9] = -0.5;
-    vertexBufferFloat32Array[10] = 1.0;
-    vertexBufferFloat32Array[11] = 1;
-    vertexBufferFloat32Array[12] = 0.5;
-    vertexBufferFloat32Array[13] = 0.5;
-    vertexBufferFloat32Array[14] = 1.0;
-    vertexBufferFloat32Array[15] = 1;
-    vertexBuffer.unmap();
-
-    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.setVertexBuffers(0, [vertexBuffer], [0]);
-    renderPassEncoder.draw(4, 1, 0, 0);
-    renderPassEncoder.endPass();
-    const commandBuffer = commandEncoder.finish();
-    device.getQueue().submit([commandBuffer]);
-}
-if (window.testRunner)
-    testRunner.waitUntilDone();
-getBasicDevice().then(function(device) {
-    start(device).then(function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    }, function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    });
-}, function() {
-    drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-    if (window.testRunner)
-        testRunner.notifyDone();
-});
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-abstract-lvalue-expected.html b/LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-abstract-lvalue-expected.html
deleted file mode 100644 (file)
index 6dd184d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const canvas = document.getElementById("canvas");
-drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-abstract-lvalue.html b/LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-abstract-lvalue.html
deleted file mode 100644 (file)
index 182e465..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const shaderSource = `
-vertex float4 vertexShader(float4 position : attribute(0)) : SV_Position {
-    return position;
-}
-
-struct Foo {
-    float x;
-}
-
-thread float* operator&[](thread Foo* f, uint index) {
-    return &f->x;
-}
-
-struct Bar {
-    Foo z;
-}
-
-Foo operator[](Bar b, uint index) {
-    return b.z;
-}
-
-Bar operator[]=(Bar b, uint index, Foo a) {
-    b.z = a;
-    return b;
-}
-
-fragment float4 fragmentShader() : SV_Target 0 {
-    Bar b;
-    b[2][3] = 1.0;
-    return float4(b[2][3], b[2][3], b[2][3], 1.0);
-}
-`;
-
-const canvas = document.getElementById("canvas");
-
-async function start(device) {
-    const shaderModule = device.createShaderModule({code: shaderSource});
-    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, format: "float4"};
-    const input0 = {stride: 16, attributeSet: [attribute0]};
-    const inputs = [input0];
-    const vertexInput = {vertexBuffers: inputs};
-
-    const pipelineLayoutDescriptor = {bindGroupLayouts: []};
-    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
-
-    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
-    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
-
-    const vertexBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
-    const vertexBuffer = device.createBuffer(vertexBufferDescriptor);
-    const vertexBufferArrayBuffer = await vertexBuffer.mapWriteAsync();
-    const vertexBufferFloat32Array = new Float32Array(vertexBufferArrayBuffer);
-    vertexBufferFloat32Array[0] = -0.5;
-    vertexBufferFloat32Array[1] = -0.5;
-    vertexBufferFloat32Array[2] = 1.0;
-    vertexBufferFloat32Array[3] = 1;
-    vertexBufferFloat32Array[4] = -0.5;
-    vertexBufferFloat32Array[5] = 0.5;
-    vertexBufferFloat32Array[6] = 1.0;
-    vertexBufferFloat32Array[7] = 1;
-    vertexBufferFloat32Array[8] = 0.5;
-    vertexBufferFloat32Array[9] = -0.5;
-    vertexBufferFloat32Array[10] = 1.0;
-    vertexBufferFloat32Array[11] = 1;
-    vertexBufferFloat32Array[12] = 0.5;
-    vertexBufferFloat32Array[13] = 0.5;
-    vertexBufferFloat32Array[14] = 1.0;
-    vertexBufferFloat32Array[15] = 1;
-    vertexBuffer.unmap();
-
-    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.setVertexBuffers(0, [vertexBuffer], [0]);
-    renderPassEncoder.draw(4, 1, 0, 0);
-    renderPassEncoder.endPass();
-    const commandBuffer = commandEncoder.finish();
-    device.getQueue().submit([commandBuffer]);
-}
-if (window.testRunner)
-    testRunner.waitUntilDone();
-getBasicDevice().then(function(device) {
-    start(device).then(function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    }, function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    });
-}, function() {
-    drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-    if (window.testRunner)
-        testRunner.notifyDone();
-});
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-expected.html b/LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-expected.html
deleted file mode 100644 (file)
index 6dd184d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const canvas = document.getElementById("canvas");
-drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-lvalue-3-levels-expected.html b/LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-lvalue-3-levels-expected.html
deleted file mode 100644 (file)
index 6dd184d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const canvas = document.getElementById("canvas");
-drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-lvalue-3-levels.html b/LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-lvalue-3-levels.html
deleted file mode 100644 (file)
index 707672e..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const shaderSource = `
-vertex float4 vertexShader(float4 position : attribute(0)) : SV_Position {
-    return position;
-}
-
-struct Foo {
-    float x;
-}
-
-thread float* operator&[](thread Foo* f, uint index) {
-    return &f->x;
-}
-
-struct Bar {
-    Foo z;
-}
-
-thread Foo* operator&[](thread Bar* b, uint index) {
-    return &b->z;
-}
-
-struct Baz {
-    Bar p;
-}
-
-thread Bar* operator&[](thread Baz* b, uint index) {
-    return &b->p;
-}
-
-fragment float4 fragmentShader() : SV_Target 0 {
-    Baz b;
-    b[1][2][3] = 1.0;
-    return float4(b[1][2][3], b[1][2][3], b[1][2][3], 1.0);
-}
-`;
-
-const canvas = document.getElementById("canvas");
-
-async function start(device) {
-    const shaderModule = device.createShaderModule({code: shaderSource});
-    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, format: "float4"};
-    const input0 = {stride: 16, attributeSet: [attribute0]};
-    const inputs = [input0];
-    const vertexInput = {vertexBuffers: inputs};
-
-    const pipelineLayoutDescriptor = {bindGroupLayouts: []};
-    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
-
-    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
-    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
-
-    const vertexBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
-    const vertexBuffer = device.createBuffer(vertexBufferDescriptor);
-    const vertexBufferArrayBuffer = await vertexBuffer.mapWriteAsync();
-    const vertexBufferFloat32Array = new Float32Array(vertexBufferArrayBuffer);
-    vertexBufferFloat32Array[0] = -0.5;
-    vertexBufferFloat32Array[1] = -0.5;
-    vertexBufferFloat32Array[2] = 1.0;
-    vertexBufferFloat32Array[3] = 1;
-    vertexBufferFloat32Array[4] = -0.5;
-    vertexBufferFloat32Array[5] = 0.5;
-    vertexBufferFloat32Array[6] = 1.0;
-    vertexBufferFloat32Array[7] = 1;
-    vertexBufferFloat32Array[8] = 0.5;
-    vertexBufferFloat32Array[9] = -0.5;
-    vertexBufferFloat32Array[10] = 1.0;
-    vertexBufferFloat32Array[11] = 1;
-    vertexBufferFloat32Array[12] = 0.5;
-    vertexBufferFloat32Array[13] = 0.5;
-    vertexBufferFloat32Array[14] = 1.0;
-    vertexBufferFloat32Array[15] = 1;
-    vertexBuffer.unmap();
-
-    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.setVertexBuffers(0, [vertexBuffer], [0]);
-    renderPassEncoder.draw(4, 1, 0, 0);
-    renderPassEncoder.endPass();
-    const commandBuffer = commandEncoder.finish();
-    device.getQueue().submit([commandBuffer]);
-}
-if (window.testRunner)
-    testRunner.waitUntilDone();
-getBasicDevice().then(function(device) {
-    start(device).then(function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    }, function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    });
-}, function() {
-    drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-    if (window.testRunner)
-        testRunner.notifyDone();
-});
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-lvalue-expected.html b/LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-lvalue-expected.html
deleted file mode 100644 (file)
index 6dd184d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const canvas = document.getElementById("canvas");
-drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-lvalue.html b/LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander-lvalue.html
deleted file mode 100644 (file)
index 3e85a4c..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const shaderSource = `
-vertex float4 vertexShader(float4 position : attribute(0)) : SV_Position {
-    return position;
-}
-
-struct Foo {
-    float x;
-}
-
-thread float* operator&[](thread Foo* f, uint index) {
-    return &f->x;
-}
-
-struct Bar {
-    Foo z;
-}
-
-thread Foo* operator&[](thread Bar* b, uint index) {
-    return &b->z;
-}
-
-fragment float4 fragmentShader() : SV_Target 0 {
-    Bar b;
-    b[1][2] = 1.0;
-    return float4(b[1][2], b[1][2], b[1][2], 1.0);
-}
-`;
-
-const canvas = document.getElementById("canvas");
-
-async function start(device) {
-    const shaderModule = device.createShaderModule({code: shaderSource});
-    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, format: "float4"};
-    const input0 = {stride: 16, attributeSet: [attribute0]};
-    const inputs = [input0];
-    const vertexInput = {vertexBuffers: inputs};
-
-    const pipelineLayoutDescriptor = {bindGroupLayouts: []};
-    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
-
-    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
-    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
-
-    const vertexBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
-    const vertexBuffer = device.createBuffer(vertexBufferDescriptor);
-    const vertexBufferArrayBuffer = await vertexBuffer.mapWriteAsync();
-    const vertexBufferFloat32Array = new Float32Array(vertexBufferArrayBuffer);
-    vertexBufferFloat32Array[0] = -0.5;
-    vertexBufferFloat32Array[1] = -0.5;
-    vertexBufferFloat32Array[2] = 1.0;
-    vertexBufferFloat32Array[3] = 1;
-    vertexBufferFloat32Array[4] = -0.5;
-    vertexBufferFloat32Array[5] = 0.5;
-    vertexBufferFloat32Array[6] = 1.0;
-    vertexBufferFloat32Array[7] = 1;
-    vertexBufferFloat32Array[8] = 0.5;
-    vertexBufferFloat32Array[9] = -0.5;
-    vertexBufferFloat32Array[10] = 1.0;
-    vertexBufferFloat32Array[11] = 1;
-    vertexBufferFloat32Array[12] = 0.5;
-    vertexBufferFloat32Array[13] = 0.5;
-    vertexBufferFloat32Array[14] = 1.0;
-    vertexBufferFloat32Array[15] = 1;
-    vertexBuffer.unmap();
-
-    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.setVertexBuffers(0, [vertexBuffer], [0]);
-    renderPassEncoder.draw(4, 1, 0, 0);
-    renderPassEncoder.endPass();
-    const commandBuffer = commandEncoder.finish();
-    device.getQueue().submit([commandBuffer]);
-}
-if (window.testRunner)
-    testRunner.waitUntilDone();
-getBasicDevice().then(function(device) {
-    start(device).then(function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    }, function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    });
-}, function() {
-    drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-    if (window.testRunner)
-        testRunner.notifyDone();
-});
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander.html b/LayoutTests/webgpu/whlsl/propertyresolver/indexer-ander.html
deleted file mode 100644 (file)
index cbde75f..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const shaderSource = `
-vertex float4 vertexShader(float4 position : attribute(0)) : SV_Position {
-    return position;
-}
-
-struct Foo {
-    float x;
-}
-
-thread float* operator&[](thread Foo* f, uint index) {
-    return &f->x;
-}
-
-Foo generateFoo() {
-    Foo f;
-    f.x = 1.0;
-    return f;
-}
-
-fragment float4 fragmentShader() : SV_Target 0 {
-    return float4(generateFoo()[0], generateFoo()[1], generateFoo()[2], 1.0);
-}
-`;
-
-const canvas = document.getElementById("canvas");
-
-async function start(device) {
-    const shaderModule = device.createShaderModule({code: shaderSource});
-    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, format: "float4"};
-    const input0 = {stride: 16, attributeSet: [attribute0]};
-    const inputs = [input0];
-    const vertexInput = {vertexBuffers: inputs};
-
-    const pipelineLayoutDescriptor = {bindGroupLayouts: []};
-    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
-
-    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
-    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
-
-    const vertexBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
-    const vertexBuffer = device.createBuffer(vertexBufferDescriptor);
-    const vertexBufferArrayBuffer = await vertexBuffer.mapWriteAsync();
-    const vertexBufferFloat32Array = new Float32Array(vertexBufferArrayBuffer);
-    vertexBufferFloat32Array[0] = -0.5;
-    vertexBufferFloat32Array[1] = -0.5;
-    vertexBufferFloat32Array[2] = 1.0;
-    vertexBufferFloat32Array[3] = 1;
-    vertexBufferFloat32Array[4] = -0.5;
-    vertexBufferFloat32Array[5] = 0.5;
-    vertexBufferFloat32Array[6] = 1.0;
-    vertexBufferFloat32Array[7] = 1;
-    vertexBufferFloat32Array[8] = 0.5;
-    vertexBufferFloat32Array[9] = -0.5;
-    vertexBufferFloat32Array[10] = 1.0;
-    vertexBufferFloat32Array[11] = 1;
-    vertexBufferFloat32Array[12] = 0.5;
-    vertexBufferFloat32Array[13] = 0.5;
-    vertexBufferFloat32Array[14] = 1.0;
-    vertexBufferFloat32Array[15] = 1;
-    vertexBuffer.unmap();
-
-    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.setVertexBuffers(0, [vertexBuffer], [0]);
-    renderPassEncoder.draw(4, 1, 0, 0);
-    renderPassEncoder.endPass();
-    const commandBuffer = commandEncoder.finish();
-    device.getQueue().submit([commandBuffer]);
-}
-if (window.testRunner)
-    testRunner.waitUntilDone();
-getBasicDevice().then(function(device) {
-    start(device).then(function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    }, function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    });
-}, function() {
-    drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-    if (window.testRunner)
-        testRunner.notifyDone();
-});
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/indexer-getter-expected.html b/LayoutTests/webgpu/whlsl/propertyresolver/indexer-getter-expected.html
deleted file mode 100644 (file)
index 6dd184d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const canvas = document.getElementById("canvas");
-drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/indexer-getter.html b/LayoutTests/webgpu/whlsl/propertyresolver/indexer-getter.html
deleted file mode 100644 (file)
index 8a5d9a2..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const shaderSource = `
-vertex float4 vertexShader(float4 position : attribute(0)) : SV_Position {
-    return position;
-}
-
-struct Foo {
-    float x;
-}
-
-float operator[](Foo f, uint index) {
-    return float(index);
-}
-
-fragment float4 fragmentShader() : SV_Target 0 {
-    Foo f;
-    return float4(f[1], f[1], f[1], 1.0);
-}
-`;
-
-const canvas = document.getElementById("canvas");
-
-async function start(device) {
-    const shaderModule = device.createShaderModule({code: shaderSource});
-    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, format: "float4"};
-    const input0 = {stride: 16, attributeSet: [attribute0]};
-    const inputs = [input0];
-    const vertexInput = {vertexBuffers: inputs};
-
-    const pipelineLayoutDescriptor = {bindGroupLayouts: []};
-    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
-
-    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
-    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
-
-    const vertexBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
-    const vertexBuffer = device.createBuffer(vertexBufferDescriptor);
-    const vertexBufferArrayBuffer = await vertexBuffer.mapWriteAsync();
-    const vertexBufferFloat32Array = new Float32Array(vertexBufferArrayBuffer);
-    vertexBufferFloat32Array[0] = -0.5;
-    vertexBufferFloat32Array[1] = -0.5;
-    vertexBufferFloat32Array[2] = 1.0;
-    vertexBufferFloat32Array[3] = 1;
-    vertexBufferFloat32Array[4] = -0.5;
-    vertexBufferFloat32Array[5] = 0.5;
-    vertexBufferFloat32Array[6] = 1.0;
-    vertexBufferFloat32Array[7] = 1;
-    vertexBufferFloat32Array[8] = 0.5;
-    vertexBufferFloat32Array[9] = -0.5;
-    vertexBufferFloat32Array[10] = 1.0;
-    vertexBufferFloat32Array[11] = 1;
-    vertexBufferFloat32Array[12] = 0.5;
-    vertexBufferFloat32Array[13] = 0.5;
-    vertexBufferFloat32Array[14] = 1.0;
-    vertexBufferFloat32Array[15] = 1;
-    vertexBuffer.unmap();
-
-    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.setVertexBuffers(0, [vertexBuffer], [0]);
-    renderPassEncoder.draw(4, 1, 0, 0);
-    renderPassEncoder.endPass();
-    const commandBuffer = commandEncoder.finish();
-    device.getQueue().submit([commandBuffer]);
-}
-if (window.testRunner)
-    testRunner.waitUntilDone();
-getBasicDevice().then(function(device) {
-    start(device).then(function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    }, function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    });
-}, function() {
-    drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-    if (window.testRunner)
-        testRunner.notifyDone();
-});
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue-3-levels-expected.html b/LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue-3-levels-expected.html
deleted file mode 100644 (file)
index 6dd184d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const canvas = document.getElementById("canvas");
-drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue-3-levels.html b/LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue-3-levels.html
deleted file mode 100644 (file)
index 853aa2e..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const shaderSource = `
-vertex float4 vertexShader(float4 position : attribute(0)) : SV_Position {
-    return position;
-}
-
-struct Foo {
-    float x;
-}
-
-float operator[](Foo f, uint index) {
-    return f.x;
-}
-
-Foo operator[]=(Foo f, uint index, float x) {
-    f.x = x;
-    return f;
-}
-
-struct Bar {
-    Foo z;
-}
-
-Foo operator[](Bar b, uint index) {
-    return b.z;
-}
-
-Bar operator[]=(Bar b, uint index, Foo a) {
-    b.z = a;
-    return b;
-}
-
-struct Baz {
-    Bar p;
-}
-
-Bar operator[](Baz b, uint index) {
-    return b.p;
-}
-
-Baz operator[]=(Baz b, uint index, Bar a) {
-    b.p = a;
-    return b;
-}
-
-fragment float4 fragmentShader() : SV_Target 0 {
-    Baz b;
-    b[2][3][4] = 1.0;
-    return float4(b[2][3][4], b[2][3][4], b[2][3][4], 1.0);
-}
-`;
-
-const canvas = document.getElementById("canvas");
-
-async function start(device) {
-    const shaderModule = device.createShaderModule({code: shaderSource});
-    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, format: "float4"};
-    const input0 = {stride: 16, attributeSet: [attribute0]};
-    const inputs = [input0];
-    const vertexInput = {vertexBuffers: inputs};
-
-    const pipelineLayoutDescriptor = {bindGroupLayouts: []};
-    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
-
-    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
-    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
-
-    const vertexBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
-    const vertexBuffer = device.createBuffer(vertexBufferDescriptor);
-    const vertexBufferArrayBuffer = await vertexBuffer.mapWriteAsync();
-    const vertexBufferFloat32Array = new Float32Array(vertexBufferArrayBuffer);
-    vertexBufferFloat32Array[0] = -0.5;
-    vertexBufferFloat32Array[1] = -0.5;
-    vertexBufferFloat32Array[2] = 1.0;
-    vertexBufferFloat32Array[3] = 1;
-    vertexBufferFloat32Array[4] = -0.5;
-    vertexBufferFloat32Array[5] = 0.5;
-    vertexBufferFloat32Array[6] = 1.0;
-    vertexBufferFloat32Array[7] = 1;
-    vertexBufferFloat32Array[8] = 0.5;
-    vertexBufferFloat32Array[9] = -0.5;
-    vertexBufferFloat32Array[10] = 1.0;
-    vertexBufferFloat32Array[11] = 1;
-    vertexBufferFloat32Array[12] = 0.5;
-    vertexBufferFloat32Array[13] = 0.5;
-    vertexBufferFloat32Array[14] = 1.0;
-    vertexBufferFloat32Array[15] = 1;
-    vertexBuffer.unmap();
-
-    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.setVertexBuffers(0, [vertexBuffer], [0]);
-    renderPassEncoder.draw(4, 1, 0, 0);
-    renderPassEncoder.endPass();
-    const commandBuffer = commandEncoder.finish();
-    device.getQueue().submit([commandBuffer]);
-}
-if (window.testRunner)
-    testRunner.waitUntilDone();
-getBasicDevice().then(function(device) {
-    start(device).then(function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    }, function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    });
-}, function() {
-    drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-    if (window.testRunner)
-        testRunner.notifyDone();
-});
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue-expected.html b/LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue-expected.html
deleted file mode 100644 (file)
index 6dd184d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const canvas = document.getElementById("canvas");
-drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue.html b/LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-abstract-lvalue.html
deleted file mode 100644 (file)
index da61b14..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const shaderSource = `
-vertex float4 vertexShader(float4 position : attribute(0)) : SV_Position {
-    return position;
-}
-
-struct Foo {
-    float x;
-}
-
-float operator[](Foo f, uint index) {
-    return f.x;
-}
-
-Foo operator[]=(Foo f, uint index, float x) {
-    f.x = x;
-    return f;
-}
-
-struct Bar {
-    Foo z;
-}
-
-Foo operator[](Bar b, uint index) {
-    return b.z;
-}
-
-Bar operator[]=(Bar b, uint index, Foo a) {
-    b.z = a;
-    return b;
-}
-
-fragment float4 fragmentShader() : SV_Target 0 {
-    Bar b;
-    b[2][3] = 1.0;
-    return float4(b[2][3], b[2][3], b[2][3], 1.0);
-}
-`;
-
-const canvas = document.getElementById("canvas");
-
-async function start(device) {
-    const shaderModule = device.createShaderModule({code: shaderSource});
-    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, format: "float4"};
-    const input0 = {stride: 16, attributeSet: [attribute0]};
-    const inputs = [input0];
-    const vertexInput = {vertexBuffers: inputs};
-
-    const pipelineLayoutDescriptor = {bindGroupLayouts: []};
-    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
-
-    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
-    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
-
-    const vertexBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
-    const vertexBuffer = device.createBuffer(vertexBufferDescriptor);
-    const vertexBufferArrayBuffer = await vertexBuffer.mapWriteAsync();
-    const vertexBufferFloat32Array = new Float32Array(vertexBufferArrayBuffer);
-    vertexBufferFloat32Array[0] = -0.5;
-    vertexBufferFloat32Array[1] = -0.5;
-    vertexBufferFloat32Array[2] = 1.0;
-    vertexBufferFloat32Array[3] = 1;
-    vertexBufferFloat32Array[4] = -0.5;
-    vertexBufferFloat32Array[5] = 0.5;
-    vertexBufferFloat32Array[6] = 1.0;
-    vertexBufferFloat32Array[7] = 1;
-    vertexBufferFloat32Array[8] = 0.5;
-    vertexBufferFloat32Array[9] = -0.5;
-    vertexBufferFloat32Array[10] = 1.0;
-    vertexBufferFloat32Array[11] = 1;
-    vertexBufferFloat32Array[12] = 0.5;
-    vertexBufferFloat32Array[13] = 0.5;
-    vertexBufferFloat32Array[14] = 1.0;
-    vertexBufferFloat32Array[15] = 1;
-    vertexBuffer.unmap();
-
-    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.setVertexBuffers(0, [vertexBuffer], [0]);
-    renderPassEncoder.draw(4, 1, 0, 0);
-    renderPassEncoder.endPass();
-    const commandBuffer = commandEncoder.finish();
-    device.getQueue().submit([commandBuffer]);
-}
-if (window.testRunner)
-    testRunner.waitUntilDone();
-getBasicDevice().then(function(device) {
-    start(device).then(function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    }, function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    });
-}, function() {
-    drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-    if (window.testRunner)
-        testRunner.notifyDone();
-});
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-expected.html b/LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-expected.html
deleted file mode 100644 (file)
index 6dd184d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const canvas = document.getElementById("canvas");
-drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-lvalue-expected.html b/LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-lvalue-expected.html
deleted file mode 100644 (file)
index 6dd184d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const canvas = document.getElementById("canvas");
-drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-lvalue.html b/LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter-lvalue.html
deleted file mode 100644 (file)
index bec9d92..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const shaderSource = `
-vertex float4 vertexShader(float4 position : attribute(0)) : SV_Position {
-    return position;
-}
-
-struct Foo {
-    float x;
-}
-
-float operator[](Foo f, uint index) {
-    return f.x;
-}
-
-Foo operator[]=(Foo f, uint index, float x) {
-    f.x = x;
-    return f;
-}
-
-struct Bar {
-    Foo z;
-}
-
-thread Foo* operator&[](thread Bar* b, uint index) {
-    return &b->z;
-}
-
-fragment float4 fragmentShader() : SV_Target 0 {
-    Bar b;
-    b[2][3] = 1.0;
-    return float4(b[2][3], b[2][3], b[2][3], 1.0);
-}
-`;
-
-const canvas = document.getElementById("canvas");
-
-async function start(device) {
-    const shaderModule = device.createShaderModule({code: shaderSource});
-    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, format: "float4"};
-    const input0 = {stride: 16, attributeSet: [attribute0]};
-    const inputs = [input0];
-    const vertexInput = {vertexBuffers: inputs};
-
-    const pipelineLayoutDescriptor = {bindGroupLayouts: []};
-    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
-
-    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
-    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
-
-    const vertexBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
-    const vertexBuffer = device.createBuffer(vertexBufferDescriptor);
-    const vertexBufferArrayBuffer = await vertexBuffer.mapWriteAsync();
-    const vertexBufferFloat32Array = new Float32Array(vertexBufferArrayBuffer);
-    vertexBufferFloat32Array[0] = -0.5;
-    vertexBufferFloat32Array[1] = -0.5;
-    vertexBufferFloat32Array[2] = 1.0;
-    vertexBufferFloat32Array[3] = 1;
-    vertexBufferFloat32Array[4] = -0.5;
-    vertexBufferFloat32Array[5] = 0.5;
-    vertexBufferFloat32Array[6] = 1.0;
-    vertexBufferFloat32Array[7] = 1;
-    vertexBufferFloat32Array[8] = 0.5;
-    vertexBufferFloat32Array[9] = -0.5;
-    vertexBufferFloat32Array[10] = 1.0;
-    vertexBufferFloat32Array[11] = 1;
-    vertexBufferFloat32Array[12] = 0.5;
-    vertexBufferFloat32Array[13] = 0.5;
-    vertexBufferFloat32Array[14] = 1.0;
-    vertexBufferFloat32Array[15] = 1;
-    vertexBuffer.unmap();
-
-    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.setVertexBuffers(0, [vertexBuffer], [0]);
-    renderPassEncoder.draw(4, 1, 0, 0);
-    renderPassEncoder.endPass();
-    const commandBuffer = commandEncoder.finish();
-    device.getQueue().submit([commandBuffer]);
-}
-if (window.testRunner)
-    testRunner.waitUntilDone();
-getBasicDevice().then(function(device) {
-    start(device).then(function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    }, function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    });
-}, function() {
-    drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-    if (window.testRunner)
-        testRunner.notifyDone();
-});
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter.html b/LayoutTests/webgpu/whlsl/propertyresolver/indexer-setter.html
deleted file mode 100644 (file)
index b61623a..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const shaderSource = `
-vertex float4 vertexShader(float4 position : attribute(0)) : SV_Position {
-    return position;
-}
-
-struct Foo {
-    float x;
-}
-
-thread float* operator&[](thread Foo* f, uint index) {
-    return &f->x;
-}
-
-struct Bar {
-    Foo z;
-}
-
-Foo operator[](Bar b, uint index) {
-    return b.z;
-}
-
-Bar operator[]=(Bar b, uint index, Foo a) {
-    b.z = a;
-    return b;
-}
-
-fragment float4 fragmentShader() : SV_Target 0 {
-    Bar b;
-    Foo foo;
-    foo.x = 1.0;
-    b[1] = foo;
-    foo = b[1];
-    return float4(foo.x, foo.x, foo.x, 1.0);
-}
-`;
-
-const canvas = document.getElementById("canvas");
-
-async function start(device) {
-    const shaderModule = device.createShaderModule({code: shaderSource});
-    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, format: "float4"};
-    const input0 = {stride: 16, attributeSet: [attribute0]};
-    const inputs = [input0];
-    const vertexInput = {vertexBuffers: inputs};
-
-    const pipelineLayoutDescriptor = {bindGroupLayouts: []};
-    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
-
-    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
-    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
-
-    const vertexBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
-    const vertexBuffer = device.createBuffer(vertexBufferDescriptor);
-    const vertexBufferArrayBuffer = await vertexBuffer.mapWriteAsync();
-    const vertexBufferFloat32Array = new Float32Array(vertexBufferArrayBuffer);
-    vertexBufferFloat32Array[0] = -0.5;
-    vertexBufferFloat32Array[1] = -0.5;
-    vertexBufferFloat32Array[2] = 1.0;
-    vertexBufferFloat32Array[3] = 1;
-    vertexBufferFloat32Array[4] = -0.5;
-    vertexBufferFloat32Array[5] = 0.5;
-    vertexBufferFloat32Array[6] = 1.0;
-    vertexBufferFloat32Array[7] = 1;
-    vertexBufferFloat32Array[8] = 0.5;
-    vertexBufferFloat32Array[9] = -0.5;
-    vertexBufferFloat32Array[10] = 1.0;
-    vertexBufferFloat32Array[11] = 1;
-    vertexBufferFloat32Array[12] = 0.5;
-    vertexBufferFloat32Array[13] = 0.5;
-    vertexBufferFloat32Array[14] = 1.0;
-    vertexBufferFloat32Array[15] = 1;
-    vertexBuffer.unmap();
-
-    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.setVertexBuffers(0, [vertexBuffer], [0]);
-    renderPassEncoder.draw(4, 1, 0, 0);
-    renderPassEncoder.endPass();
-    const commandBuffer = commandEncoder.finish();
-    device.getQueue().submit([commandBuffer]);
-}
-if (window.testRunner)
-    testRunner.waitUntilDone();
-getBasicDevice().then(function(device) {
-    start(device).then(function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    }, function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    });
-}, function() {
-    drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-    if (window.testRunner)
-        testRunner.notifyDone();
-});
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/setter-abstract-lvalue-3-levels-expected.html b/LayoutTests/webgpu/whlsl/propertyresolver/setter-abstract-lvalue-3-levels-expected.html
deleted file mode 100644 (file)
index 6dd184d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const canvas = document.getElementById("canvas");
-drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/setter-abstract-lvalue-3-levels.html b/LayoutTests/webgpu/whlsl/propertyresolver/setter-abstract-lvalue-3-levels.html
deleted file mode 100644 (file)
index 418b859..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const shaderSource = `
-vertex float4 vertexShader(float4 position : attribute(0)) : SV_Position {
-    return position;
-}
-
-struct Foo {
-    float x;
-}
-
-float operator.y(Foo f) {
-    return f.x;
-}
-
-Foo operator.y=(Foo f, float x) {
-    f.x = x;
-    return f;
-}
-
-struct Bar {
-    Foo z;
-}
-
-Foo operator.w(Bar b) {
-    return b.z;
-}
-
-Bar operator.w=(Bar b, Foo a) {
-    b.z = a;
-    return b;
-}
-
-struct Baz {
-    Bar p;
-}
-
-Bar operator.q(Baz b) {
-    return b.p;
-}
-
-Baz operator.q=(Baz b, Bar a) {
-    b.p = a;
-    return b;
-}
-
-fragment float4 fragmentShader() : SV_Target 0 {
-    Baz b;
-    b.q.w.y = 1.0;
-    return float4(b.q.w.y, b.q.w.y, b.q.w.y, 1.0);
-}
-`;
-
-const canvas = document.getElementById("canvas");
-
-async function start(device) {
-    const shaderModule = device.createShaderModule({code: shaderSource});
-    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, format: "float4"};
-    const input0 = {stride: 16, attributeSet: [attribute0]};
-    const inputs = [input0];
-    const vertexInput = {vertexBuffers: inputs};
-
-    const pipelineLayoutDescriptor = {bindGroupLayouts: []};
-    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
-
-    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
-    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
-
-    const vertexBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
-    const vertexBuffer = device.createBuffer(vertexBufferDescriptor);
-    const vertexBufferArrayBuffer = await vertexBuffer.mapWriteAsync();
-    const vertexBufferFloat32Array = new Float32Array(vertexBufferArrayBuffer);
-    vertexBufferFloat32Array[0] = -0.5;
-    vertexBufferFloat32Array[1] = -0.5;
-    vertexBufferFloat32Array[2] = 1.0;
-    vertexBufferFloat32Array[3] = 1;
-    vertexBufferFloat32Array[4] = -0.5;
-    vertexBufferFloat32Array[5] = 0.5;
-    vertexBufferFloat32Array[6] = 1.0;
-    vertexBufferFloat32Array[7] = 1;
-    vertexBufferFloat32Array[8] = 0.5;
-    vertexBufferFloat32Array[9] = -0.5;
-    vertexBufferFloat32Array[10] = 1.0;
-    vertexBufferFloat32Array[11] = 1;
-    vertexBufferFloat32Array[12] = 0.5;
-    vertexBufferFloat32Array[13] = 0.5;
-    vertexBufferFloat32Array[14] = 1.0;
-    vertexBufferFloat32Array[15] = 1;
-    vertexBuffer.unmap();
-
-    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.setVertexBuffers(0, [vertexBuffer], [0]);
-    renderPassEncoder.draw(4, 1, 0, 0);
-    renderPassEncoder.endPass();
-    const commandBuffer = commandEncoder.finish();
-    device.getQueue().submit([commandBuffer]);
-}
-if (window.testRunner)
-    testRunner.waitUntilDone();
-getBasicDevice().then(function(device) {
-    start(device).then(function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    }, function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    });
-}, function() {
-    drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-    if (window.testRunner)
-        testRunner.notifyDone();
-});
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/setter-abstract-lvalue-expected.html b/LayoutTests/webgpu/whlsl/propertyresolver/setter-abstract-lvalue-expected.html
deleted file mode 100644 (file)
index 6dd184d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const canvas = document.getElementById("canvas");
-drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/setter-abstract-lvalue.html b/LayoutTests/webgpu/whlsl/propertyresolver/setter-abstract-lvalue.html
deleted file mode 100644 (file)
index 96ad8c8..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const shaderSource = `
-vertex float4 vertexShader(float4 position : attribute(0)) : SV_Position {
-    return position;
-}
-
-struct Foo {
-    float x;
-}
-
-float operator.y(Foo f) {
-    return f.x;
-}
-
-Foo operator.y=(Foo f, float x) {
-    f.x = x;
-    return f;
-}
-
-struct Bar {
-    Foo z;
-}
-
-Foo operator.w(Bar b) {
-    return b.z;
-}
-
-Bar operator.w=(Bar b, Foo a) {
-    b.z = a;
-    return b;
-}
-
-fragment float4 fragmentShader() : SV_Target 0 {
-    Bar b;
-    b.w.y = 1.0;
-    return float4(b.w.y, b.w.y, b.w.y, 1.0);
-}
-`;
-
-const canvas = document.getElementById("canvas");
-
-async function start(device) {
-    const shaderModule = device.createShaderModule({code: shaderSource});
-    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, format: "float4"};
-    const input0 = {stride: 16, attributeSet: [attribute0]};
-    const inputs = [input0];
-    const vertexInput = {vertexBuffers: inputs};
-
-    const pipelineLayoutDescriptor = {bindGroupLayouts: []};
-    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
-
-    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
-    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
-
-    const vertexBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
-    const vertexBuffer = device.createBuffer(vertexBufferDescriptor);
-    const vertexBufferArrayBuffer = await vertexBuffer.mapWriteAsync();
-    const vertexBufferFloat32Array = new Float32Array(vertexBufferArrayBuffer);
-    vertexBufferFloat32Array[0] = -0.5;
-    vertexBufferFloat32Array[1] = -0.5;
-    vertexBufferFloat32Array[2] = 1.0;
-    vertexBufferFloat32Array[3] = 1;
-    vertexBufferFloat32Array[4] = -0.5;
-    vertexBufferFloat32Array[5] = 0.5;
-    vertexBufferFloat32Array[6] = 1.0;
-    vertexBufferFloat32Array[7] = 1;
-    vertexBufferFloat32Array[8] = 0.5;
-    vertexBufferFloat32Array[9] = -0.5;
-    vertexBufferFloat32Array[10] = 1.0;
-    vertexBufferFloat32Array[11] = 1;
-    vertexBufferFloat32Array[12] = 0.5;
-    vertexBufferFloat32Array[13] = 0.5;
-    vertexBufferFloat32Array[14] = 1.0;
-    vertexBufferFloat32Array[15] = 1;
-    vertexBuffer.unmap();
-
-    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.setVertexBuffers(0, [vertexBuffer], [0]);
-    renderPassEncoder.draw(4, 1, 0, 0);
-    renderPassEncoder.endPass();
-    const commandBuffer = commandEncoder.finish();
-    device.getQueue().submit([commandBuffer]);
-}
-if (window.testRunner)
-    testRunner.waitUntilDone();
-getBasicDevice().then(function(device) {
-    start(device).then(function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    }, function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    });
-}, function() {
-    drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-    if (window.testRunner)
-        testRunner.notifyDone();
-});
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/setter-lvalue-expected.html b/LayoutTests/webgpu/whlsl/propertyresolver/setter-lvalue-expected.html
deleted file mode 100644 (file)
index 6dd184d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const canvas = document.getElementById("canvas");
-drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-</script>
-</body>
-</html>
diff --git a/LayoutTests/webgpu/whlsl/propertyresolver/setter-lvalue.html b/LayoutTests/webgpu/whlsl/propertyresolver/setter-lvalue.html
deleted file mode 100644 (file)
index d50f8b8..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="../../js/webgpu-functions.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="400" height="400"></canvas>
-<script>
-const shaderSource = `
-vertex float4 vertexShader(float4 position : attribute(0)) : SV_Position {
-    return position;
-}
-
-struct Foo {
-    float x;
-}
-
-float operator.y(Foo f) {
-    return f.x;
-}
-
-Foo operator.y=(Foo f, float x) {
-    f.x = x;
-    return f;
-}
-
-struct Bar {
-    Foo z;
-}
-
-thread Foo* operator&.w(thread Bar* b) {
-    return &b->z;
-}
-
-fragment float4 fragmentShader() : SV_Target 0 {
-    Bar b;
-    b.w.y = 1.0;
-    return float4(b.w.y, b.w.y, b.w.y, 1.0);
-}
-`;
-
-const canvas = document.getElementById("canvas");
-
-async function start(device) {
-    const shaderModule = device.createShaderModule({code: shaderSource});
-    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, format: "float4"};
-    const input0 = {stride: 16, attributeSet: [attribute0]};
-    const inputs = [input0];
-    const vertexInput = {vertexBuffers: inputs};
-
-    const pipelineLayoutDescriptor = {bindGroupLayouts: []};
-    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
-
-    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
-    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
-
-    const vertexBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
-    const vertexBuffer = device.createBuffer(vertexBufferDescriptor);
-    const vertexBufferArrayBuffer = await vertexBuffer.mapWriteAsync();
-    const vertexBufferFloat32Array = new Float32Array(vertexBufferArrayBuffer);
-    vertexBufferFloat32Array[0] = -0.5;
-    vertexBufferFloat32Array[1] = -0.5;
-    vertexBufferFloat32Array[2] = 1.0;
-    vertexBufferFloat32Array[3] = 1;
-    vertexBufferFloat32Array[4] = -0.5;
-    vertexBufferFloat32Array[5] = 0.5;
-    vertexBufferFloat32Array[6] = 1.0;
-    vertexBufferFloat32Array[7] = 1;
-    vertexBufferFloat32Array[8] = 0.5;
-    vertexBufferFloat32Array[9] = -0.5;
-    vertexBufferFloat32Array[10] = 1.0;
-    vertexBufferFloat32Array[11] = 1;
-    vertexBufferFloat32Array[12] = 0.5;
-    vertexBufferFloat32Array[13] = 0.5;
-    vertexBufferFloat32Array[14] = 1.0;
-    vertexBufferFloat32Array[15] = 1;
-    vertexBuffer.unmap();
-
-    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.setVertexBuffers(0, [vertexBuffer], [0]);
-    renderPassEncoder.draw(4, 1, 0, 0);
-    renderPassEncoder.endPass();
-    const commandBuffer = commandEncoder.finish();
-    device.getQueue().submit([commandBuffer]);
-}
-if (window.testRunner)
-    testRunner.waitUntilDone();
-getBasicDevice().then(function(device) {
-    start(device).then(function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    }, function() {
-        if (window.testRunner)
-            testRunner.notifyDone();
-    });
-}, function() {
-    drawWhiteSquareOnBlueBackgroundInSoftware(canvas);
-    if (window.testRunner)
-        testRunner.notifyDone();
-});
-</script>
-</body>
-</html>
index 1866bc2..5040509 100644 (file)
@@ -12,7 +12,7 @@ const whlslTests = {};
 
 whlslTests.setterWithMatchedType = async () =>
 {
-    const program = `
+    await checkFail(`
         int operator.foo(int)
         {
             return 5;
@@ -30,10 +30,7 @@ whlslTests.setterWithMatchedType = async () =>
             int x;
             return x.foo;
         }
-    `;
-
-    assert_equals(await callIntFunction(program, "foo", []), 543);
-    //assert_equals(await callIntFunction(program, "bar", []), 5);
+    `);
 }
 
 whlslTests.setterWithNoGetterOverload = async () =>
@@ -56,7 +53,7 @@ whlslTests.setterWithNoGetterOverload = async () =>
 
 whlslTests.setterWithNoGetterOverloadFixed = async () =>
 {
-    const program =`
+    await checkFail(`
         struct Bar { }
         int operator.foo(Bar)
         {
@@ -75,14 +72,12 @@ whlslTests.setterWithNoGetterOverloadFixed = async () =>
             bar.foo = 52;
             return bar.foo;
         }
-    `;
-    assert_equals(await callIntFunction(program, "foo", []), 534);
-    assert_equals(await callIntFunction(program, "bar", []), 534);
+    `);
 }
 
 whlslTests.recursiveSetters = async () =>
 {
-    let program = `
+    await checkFail(`
         struct Foo {
             int x;
             int y;
@@ -101,8 +96,7 @@ whlslTests.recursiveSetters = async () =>
             foo.bar.c = 8;
             return foo.x*10 + foo.y;
         }
-    `;
-    assert_equals(await callIntFunction(program, "f", []), 83);
+    `);
 }
 
 whlslTests.loneSetter = async () =>
index 8ce6d68..68933fe 100644 (file)
 <script>
 const whlslTests = {};
 
-whlslTests.simpleGetter = async () => {
+whlslTests.simplePropertyGet = async () => {
     let program = `
         struct Foo {
             int x;
         }
-        int operator.y(Foo foo)
-        {
-            return foo.x;
-        }
         int foo()
         {
             Foo foo;
             foo.x = 7804;
-            return foo.y;
-        }
-    `;
-    assert_equals(await callIntFunction(program, "foo", []), 7804);
-};
-
-whlslTests.simpleSetter = async () => {
-    let program = `
-        struct Foo {
-            int x;
-        }
-        int operator.y(Foo foo)
-        {
-            return foo.x;
-        }
-        Foo operator.y=(Foo foo, int value)
-        {
-            foo.x = value;
-            return foo;
-        }
-        int foo()
-        {
-            Foo foo;
-            foo.y = 7804;
             return foo.x;
         }
     `;
index a068a81..e51db36 100644 (file)
@@ -161,7 +161,7 @@ whlslTests.float4x4tests = () => {
         });
     }, "Upload a float4x4[] and store into a float4x4[].");
 
-    checkArrays("float4x4", "return float4x4(float4(0, 1, 2, 3), float4(4, 5, 6, 7), float4(8, 9, 10, 11), float4(12, 13, 14, 15));", [], float4x4expected);
+    checkArrays("float4x4", "return float4x4(float4(0, 1, 2, 3), float4(4, 5, 6, 7), float4(8, 9, 10, 11), float4(12, 13, 14, 15));", [], float4x4ColumnExpected);
     checkArrays("float4x4", "return in0;", [float4x4expected], float4x4expected);
     let multiple4x4args = [];
     for (let i = 0; i < 16; ++i) {
index a1bdb9c..9ede879 100644 (file)
@@ -1,3 +1,178 @@
+2019-08-30  Saam Barati  <sbarati@apple.com>
+
+        [WHLSL] Remove getters/setters/anders
+        https://bugs.webkit.org/show_bug.cgi?id=201008
+
+        Reviewed by Robin Morisset.
+
+        This patch changes WHLSL in a significant way. This patch removes getters/setters/anders
+        from the language. In our experience writing WHLSL shaders, these parts of the language
+        went unused, and they added a lot of complexity to the implementation of the compiler.
+        
+        This patch now treats field accesses and array indexes as intrinsics inside the compiler.
+        This patch removes all notions of named operators, anders, and indexed operators
+        from the compiler and the standard library. The checker now intrinsically knows the
+        return type for property accesses and indexed expressions based on what the
+        base type is.
+        
+        To make this work in practice was difficult, since getters/setters/anders
+        solved a lot of the difficult problems we had in generating metal code. For
+        example, all swizzle operators were getters and setters, so assigning to a
+        swizzle fell out naturally from implementing setters. However, during metal
+        codegen, all we see is a dot expression with "xy" as a property. Our previous
+        architecture of emitting Metal code using pointers which represent lvalues
+        doesn't work because you can't take the address of a swizzle. For example,
+        "auto* x = &vector.yz" is invalid metal code.
+        
+        So, this patch changes the entire metal code generator to emit WHLSL expressions
+        as Metal expressions. To do this, I had to change a lot about how the compiler
+        was implemented:
+        - I changed the indexed accesses of matrices to return columns instead of
+        rows. This allowed WHLSL code like `mat[0].xy = 42` to be compiled into
+        the equivalent metal code of `mat[0].xy = 42`.
+        - I changed the native function inliner to emit expressions instead of
+        statements.
+        - We also simplify the language by removing null and requiring all
+        reference type variables to have an initializer. This means that
+        null is no longer a valid value, which allows us to omit null checks
+        inside the metal code generator. To make this work with array
+        accesses, we now clamp accesses instead of returning null for OOB
+        accesses.
+        
+        I've also filed one required bug as a followup. I didn't include it in this
+        patch to make it easier to review along. Currently, there are two places in
+        metal codegen where we evaluate effects twice. That will be fixed in:
+        https://bugs.webkit.org/show_bug.cgi?id=201251
+
+        Tests: webgpu/whlsl/address-of-swizzle.html
+               webgpu/whlsl/array-oob-alias.html
+               webgpu/whlsl/matrix-index-assign.html
+               webgpu/whlsl/matrix-index-order.html
+               webgpu/whlsl/oob-access-2.html
+               webgpu/whlsl/operator-syntax.html
+
+        * Modules/webgpu/WHLSL/AST/WHLSLAST.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLConstantExpression.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLDotExpression.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLExpression.cpp:
+        (WebCore::WHLSL::AST::Expression::destroy):
+        (WebCore::WHLSL::AST::Expression::destruct):
+        (WebCore::WHLSL::AST::PropertyAccessExpression::getterFunctionName const): Deleted.
+        (WebCore::WHLSL::AST::PropertyAccessExpression::setterFunctionName const): Deleted.
+        (WebCore::WHLSL::AST::PropertyAccessExpression::anderFunctionName const): Deleted.
+        * Modules/webgpu/WHLSL/AST/WHLSLExpression.h:
+        (WebCore::WHLSL::AST::Expression::copyTypeTo const):
+        (WebCore::WHLSL::AST::Expression::isMakePointerExpression const):
+        (WebCore::WHLSL::AST::Expression::isNullLiteral const): Deleted.
+        * Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLNativeTypeDeclaration.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h: Removed.
+        * Modules/webgpu/WHLSL/AST/WHLSLNullLiteralType.cpp: Removed.
+        * Modules/webgpu/WHLSL/AST/WHLSLNullLiteralType.h: Removed.
+        * Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h:
+        (WebCore::WHLSL::AST::PropertyAccessExpression::getterFunction): Deleted.
+        (WebCore::WHLSL::AST::PropertyAccessExpression::anderFunction): Deleted.
+        (WebCore::WHLSL::AST::PropertyAccessExpression::threadAnderFunction): Deleted.
+        (WebCore::WHLSL::AST::PropertyAccessExpression::setterFunction): Deleted.
+        (WebCore::WHLSL::AST::PropertyAccessExpression::setGetterFunction): Deleted.
+        (WebCore::WHLSL::AST::PropertyAccessExpression::setAnderFunction): Deleted.
+        (WebCore::WHLSL::AST::PropertyAccessExpression::setThreadAnderFunction): Deleted.
+        (WebCore::WHLSL::AST::PropertyAccessExpression::setSetterFunction): Deleted.
+        (): Deleted.
+        * Modules/webgpu/WHLSL/AST/WHLSLType.cpp:
+        (WebCore::WHLSL::AST::Type::destroy):
+        (WebCore::WHLSL::AST::Type::destruct):
+        (WebCore::WHLSL::AST::ResolvableType::canResolve const):
+        (WebCore::WHLSL::AST::ResolvableType::conversionCost const):
+        * Modules/webgpu/WHLSL/AST/WHLSLType.h:
+        (WebCore::WHLSL::AST::Type::isIntegerLiteralType const):
+        (WebCore::WHLSL::AST::Type::isNullLiteralType const): Deleted.
+        * Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp:
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::HoistedVariableCollector::HoistedVariableCollector):
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit):
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::emitLoop):
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::emitConstantExpressionString):
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::appendRightValueWithNullability): Deleted.
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::appendRightValue): Deleted.
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::appendLeftValue): Deleted.
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::takeLastValue): Deleted.
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::takeLastValueAndNullability): Deleted.
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::takeLastLeftValue): Deleted.
+        * Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.cpp:
+        (WebCore::WHLSL::Metal::metalCodePrologue):
+        (WebCore::WHLSL::Metal::generateMetalCode):
+        (WebCore::WHLSL::Metal::metalCodeProlog): Deleted.
+        * Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp:
+        (WebCore::WHLSL::Metal::inlineNativeFunction):
+        (WebCore::WHLSL::Metal::vectorInnerType): Deleted.
+        * Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.h:
+        * Modules/webgpu/WHLSL/Metal/WHLSLNativeTypeWriter.cpp:
+        (WebCore::WHLSL::Metal::writeNativeType):
+        * Modules/webgpu/WHLSL/WHLSLASTDumper.cpp:
+        (WebCore::WHLSL::ASTDumper::visit):
+        * Modules/webgpu/WHLSL/WHLSLASTDumper.h:
+        * Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp:
+        (WebCore::WHLSL::checkDuplicateFunctions):
+        * Modules/webgpu/WHLSL/WHLSLChecker.cpp:
+        (WebCore::WHLSL::resolveByInstantiation):
+        (WebCore::WHLSL::checkOperatorOverload):
+        (WebCore::WHLSL::Checker::wrappedUintType):
+        (WebCore::WHLSL::Checker::normalizedTypeForFunctionKey):
+        (WebCore::WHLSL::Checker::visit):
+        (WebCore::WHLSL::matchAndCommit):
+        (WebCore::WHLSL::Checker::resolveFunction):
+        (WebCore::WHLSL::Checker::assignConcreteType):
+        (WebCore::WHLSL::resolveWithOperatorLength): Deleted.
+        (WebCore::WHLSL::Checker::genericPointerType): Deleted.
+        (WebCore::WHLSL::Checker::finishVisiting): Deleted.
+        * Modules/webgpu/WHLSL/WHLSLHighZombieFinder.cpp:
+        (WebCore::WHLSL::findHighZombies):
+        (): Deleted.
+        * Modules/webgpu/WHLSL/WHLSLInferTypes.cpp:
+        (WebCore::WHLSL::matchAndCommit):
+        (WebCore::WHLSL::commit):
+        * Modules/webgpu/WHLSL/WHLSLIntrinsics.h:
+        (WebCore::WHLSL::Intrinsics::boolVectorTypeForSize const):
+        (WebCore::WHLSL::Intrinsics::uintVectorTypeForSize const):
+        (WebCore::WHLSL::Intrinsics::intVectorTypeForSize const):
+        (WebCore::WHLSL::Intrinsics::floatVectorTypeForSize const):
+        * Modules/webgpu/WHLSL/WHLSLLexer.cpp:
+        (WebCore::WHLSL::Lexer::consumeTokenFromStream):
+        * Modules/webgpu/WHLSL/WHLSLLiteralTypeChecker.cpp:
+        * Modules/webgpu/WHLSL/WHLSLParser.cpp:
+        (WebCore::WHLSL::Parser::parseConstantExpression):
+        (WebCore::WHLSL::Parser::parseEnumerationMember):
+        (WebCore::WHLSL::Parser::parseTerm):
+        * Modules/webgpu/WHLSL/WHLSLPrepare.cpp:
+        (WebCore::WHLSL::prepareShared):
+        * Modules/webgpu/WHLSL/WHLSLProgram.cpp: Added.
+        (WebCore::WHLSL::Program::isValidVectorProperty):
+        * Modules/webgpu/WHLSL/WHLSLProgram.h:
+        * Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp:
+        (WebCore::WHLSL::resolveProperties):
+        (WebCore::WHLSL::PropertyResolver::visit): Deleted.
+        (WebCore::WHLSL::wrapAnderCallArgument): Deleted.
+        (WebCore::WHLSL::anderCallArgument): Deleted.
+        (WebCore::WHLSL::setterCall): Deleted.
+        (WebCore::WHLSL::getterCall): Deleted.
+        (WebCore::WHLSL::modify): Deleted.
+        (WebCore::WHLSL::PropertyResolver::simplifyRightValue): Deleted.
+        (WebCore::WHLSL::LeftValueSimplifier::finishVisiting): Deleted.
+        (WebCore::WHLSL::LeftValueSimplifier::visit): Deleted.
+        (WebCore::WHLSL::PropertyResolver::simplifyLeftValue): Deleted.
+        * Modules/webgpu/WHLSL/WHLSLPruneUnreachableStandardLibraryFunctions.cpp:
+        * Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt:
+        * Modules/webgpu/WHLSL/WHLSLStandardLibraryUtilities.cpp:
+        * Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.cpp: Removed.
+        * Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.h: Removed.
+        * Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.cpp:
+        (WebCore::WHLSL::synthesizeEnumerationFunctions):
+        * Modules/webgpu/WHLSL/WHLSLVisitor.cpp:
+        (WebCore::WHLSL::Visitor::visit):
+        * Modules/webgpu/WHLSL/WHLSLVisitor.h:
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+
 2019-08-30  Zalan Bujtas  <zalan@apple.com>
 
         [LFC] Pass FormattingContext to Geometry/Quirks/BlockMarginCollapsing classes
index c70c106..aacc594 100644 (file)
@@ -69,8 +69,6 @@
 #include "WHLSLNamedType.h"
 #include "WHLSLNativeFunctionDeclaration.h"
 #include "WHLSLNativeTypeDeclaration.h"
-#include "WHLSLNullLiteral.h"
-#include "WHLSLNullLiteralType.h"
 #include "WHLSLNumThreadsFunctionAttribute.h"
 #include "WHLSLPointerType.h"
 #include "WHLSLPropertyAccessExpression.h"
index 8f22f57..4142774 100644 (file)
@@ -31,7 +31,6 @@
 #include "WHLSLEnumerationMemberLiteral.h"
 #include "WHLSLFloatLiteral.h"
 #include "WHLSLIntegerLiteral.h"
-#include "WHLSLNullLiteral.h"
 #include "WHLSLUnsignedIntegerLiteral.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/Variant.h>
@@ -63,11 +62,6 @@ public:
     {
     }
 
-    ConstantExpression(NullLiteral&& nullLiteral)
-        : m_variant(WTFMove(nullLiteral))
-    {
-    }
-
     ConstantExpression(BooleanLiteral&& booleanLiteral)
         : m_variant(WTFMove(booleanLiteral))
     {
@@ -90,12 +84,12 @@ public:
         return WTF::get<IntegerLiteral>(m_variant);
     }
 
-    template <typename Visitor> auto visit(const Visitor& visitor) -> decltype(WTF::visit(visitor, std::declval<Variant<IntegerLiteral, UnsignedIntegerLiteral, FloatLiteral, NullLiteral, BooleanLiteral, EnumerationMemberLiteral>&>()))
+    template <typename Visitor> auto visit(const Visitor& visitor) -> decltype(WTF::visit(visitor, std::declval<Variant<IntegerLiteral, UnsignedIntegerLiteral, FloatLiteral, BooleanLiteral, EnumerationMemberLiteral>&>()))
     {
         return WTF::visit(visitor, m_variant);
     }
 
-    template <typename Visitor> auto visit(const Visitor& visitor) const -> decltype(WTF::visit(visitor, std::declval<Variant<IntegerLiteral, UnsignedIntegerLiteral, FloatLiteral, NullLiteral, BooleanLiteral, EnumerationMemberLiteral>&>()))
+    template <typename Visitor> auto visit(const Visitor& visitor) const -> decltype(WTF::visit(visitor, std::declval<Variant<IntegerLiteral, UnsignedIntegerLiteral, FloatLiteral, BooleanLiteral, EnumerationMemberLiteral>&>()))
     {
         return WTF::visit(visitor, m_variant);
     }
@@ -108,8 +102,6 @@ public:
             return unsignedIntegerLiteral.clone();
         }, [&](const FloatLiteral& floatLiteral) -> ConstantExpression {
             return floatLiteral.clone();
-        }, [&](const NullLiteral& nullLiteral) -> ConstantExpression {
-            return nullLiteral.clone();
         }, [&](const BooleanLiteral& booleanLiteral) -> ConstantExpression {
             return booleanLiteral.clone();
         }, [&](const EnumerationMemberLiteral& enumerationMemberLiteral) -> ConstantExpression {
@@ -127,8 +119,6 @@ public:
             value = unsignedIntegerLiteral.value();
         }, [&](const FloatLiteral& floatLiteral) {
             value = floatLiteral.value();
-        }, [&](const NullLiteral&) {
-            result = WTF::holds_alternative<NullLiteral>(other.m_variant);
         }, [&](const BooleanLiteral& booleanLiteral) {
             if (WTF::holds_alternative<BooleanLiteral>(other.m_variant)) {
                 const auto& otherBooleanLiteral = WTF::get<BooleanLiteral>(other.m_variant);
@@ -152,8 +142,6 @@ public:
             result = value == unsignedIntegerLiteral.value();
         }, [&](const FloatLiteral& floatLiteral) {
             result = value == floatLiteral.value();
-        }, [&](const NullLiteral&) {
-            result = false;
         }, [&](const BooleanLiteral&) {
             result = false;
         }, [&](const EnumerationMemberLiteral&) {
@@ -169,7 +157,6 @@ private:
         IntegerLiteral,
         UnsignedIntegerLiteral,
         FloatLiteral,
-        NullLiteral,
         BooleanLiteral,
         EnumerationMemberLiteral
         > m_variant;
index d85c6a6..04ffbfc 100644 (file)
@@ -45,6 +45,7 @@ public:
         : PropertyAccessExpression(location, Kind::Dot, WTFMove(base))
         , m_fieldName(WTFMove(fieldName))
     {
+        UNUSED_PARAM(m_padding);
     }
 
     ~DotExpression() = default;
@@ -52,25 +53,12 @@ public:
     DotExpression(const DotExpression&) = delete;
     DotExpression(DotExpression&&) = default;
 
-    String getterFunctionName() const
-    {
-        return makeString("operator.", m_fieldName);
-    }
-
-    String setterFunctionName() const
-    {
-        return makeString("operator.", m_fieldName, "=");
-    }
-
-    String anderFunctionName() const
-    {
-        return makeString("operator&.", m_fieldName);
-    }
-
     String& fieldName() { return m_fieldName; }
 
 private:
     String m_fieldName;
+    // This is used to allow for replaceWith into a bigger type.
+    char m_padding[12];
 };
 
 } // namespace AST
index 6befc7c..99cb9b3 100644 (file)
@@ -72,9 +72,6 @@ void Expression::destroy(Expression& expression)
     case Expression::Kind::MakePointer:
         delete &downcast<MakePointerExpression>(expression);
         break;
-    case Expression::Kind::NullLiteral:
-        delete &downcast<NullLiteral>(expression);
-        break;
     case Expression::Kind::Dot:
         delete &downcast<DotExpression>(expression);
         break;
@@ -138,9 +135,6 @@ void Expression::destruct(Expression& expression)
     case Expression::Kind::MakePointer:
         downcast<MakePointerExpression>(expression).~MakePointerExpression();
         break;
-    case Expression::Kind::NullLiteral:
-        downcast<NullLiteral>(expression).~NullLiteral();
-        break;
     case Expression::Kind::Dot:
         downcast<DotExpression>(expression).~DotExpression();
         break;
@@ -168,33 +162,6 @@ void Expression::destruct(Expression& expression)
     }
 }
 
-String PropertyAccessExpression::getterFunctionName() const
-{
-    if (is<DotExpression>(*this))
-        return downcast<DotExpression>(*this).getterFunctionName();
-    if (is<IndexExpression>(*this))
-        return downcast<IndexExpression>(*this).getterFunctionName();
-    RELEASE_ASSERT_NOT_REACHED();
-}
-
-String PropertyAccessExpression::setterFunctionName() const
-{
-    if (is<DotExpression>(*this))
-        return downcast<DotExpression>(*this).setterFunctionName();
-    if (is<IndexExpression>(*this))
-        return downcast<IndexExpression>(*this).setterFunctionName();
-    RELEASE_ASSERT_NOT_REACHED();
-}
-
-String PropertyAccessExpression::anderFunctionName() const
-{
-    if (is<DotExpression>(*this))
-        return downcast<DotExpression>(*this).anderFunctionName();
-    if (is<IndexExpression>(*this))
-        return downcast<IndexExpression>(*this).anderFunctionName();
-    RELEASE_ASSERT_NOT_REACHED();
-}
-
 } // namespace AST
 
 } // namespace WHLSL
index e15ef91..eeb0983 100644 (file)
@@ -64,7 +64,6 @@ public:
         LogicalNot,
         MakeArrayReference,
         MakePointer,
-        NullLiteral,
         ReadModifyWrite,
         Ternary,
         UnsignedIntegerLiteral,
@@ -119,8 +118,6 @@ public:
     {
         if (auto* resolvedType = const_cast<Expression*>(this)->maybeResolvedType())
             other.setType(*resolvedType);
-        if (auto* typeAnnotation = maybeTypeAnnotation())
-            other.setTypeAnnotation(TypeAnnotation(*typeAnnotation));
     }
 
     Kind kind() const  { return m_kind; }
@@ -138,7 +135,6 @@ public:
     bool isLogicalNotExpression() const { return kind() == Kind::LogicalNot; }
     bool isMakeArrayReferenceExpression() const { return kind() == Kind::MakeArrayReference; }
     bool isMakePointerExpression() const { return kind() == Kind::MakePointer; }
-    bool isNullLiteral() const { return kind() == Kind::NullLiteral; }
     bool isPropertyAccessExpression() const { return isDotExpression() || isIndexExpression(); }
     bool isReadModifyWriteExpression() const { return kind() == Kind::ReadModifyWrite; }
     bool isTernaryExpression() const { return kind() == Kind::Ternary; }
index 9c761c4..682449a 100644 (file)
@@ -52,21 +52,6 @@ public:
     IndexExpression(const IndexExpression&) = delete;
     IndexExpression(IndexExpression&&) = default;
 
-    String getterFunctionName() const
-    {
-        return "operator[]"_str;
-    }
-
-    String setterFunctionName() const
-    {
-        return "operator[]="_str;
-    }
-
-    String anderFunctionName() const
-    {
-        return "operator&[]"_str;
-    }
-
     Expression& indexExpression() { return m_index; }
     UniqueRef<Expression> takeIndex() { return WTFMove(m_index); }
 
index 8fea37a..da71d52 100644 (file)
@@ -86,11 +86,29 @@ private:
 public:
     unsigned numberOfMatrixRows()
     {
-        return matrixDimension(1);
+        return matrixDimension(2);
     }
     unsigned numberOfMatrixColumns()
     {
-        return matrixDimension(2);
+        return matrixDimension(1);
+    }
+
+    TypeReference& vectorTypeArgument()
+    {
+        ASSERT(isVector());
+        return WTF::get<Ref<AST::TypeReference>>(typeArguments()[0]);
+    }
+
+    unsigned vectorSize()
+    {
+        ASSERT(isVector());
+        return WTF::get<AST::ConstantExpression>(typeArguments()[1]).integerLiteral().value();
+    }
+
+    TypeReference& matrixTypeArgument()
+    {
+        ASSERT(isMatrix());
+        return WTF::get<Ref<AST::TypeReference>>(typeArguments()[0]);
     }
 
     void setIsInt() { m_isInt = true; }
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h
deleted file mode 100644 (file)
index 7db03ec..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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)
-
-#include "WHLSLExpression.h"
-#include "WHLSLNullLiteralType.h"
-#include <wtf/FastMalloc.h>
-
-namespace WebCore {
-
-namespace WHLSL {
-
-namespace AST {
-
-class NullLiteral final : public Expression {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    NullLiteral(CodeLocation location)
-        : Expression(location, Kind::NullLiteral)
-    {
-    }
-
-    ~NullLiteral() = default;
-
-    NullLiteral(const NullLiteral&) = delete;
-    NullLiteral(NullLiteral&&) = default;
-
-    NullLiteral& operator=(const NullLiteral&) = delete;
-    NullLiteral& operator=(NullLiteral&&) = default;
-
-    NullLiteralType& type() { return m_type; }
-
-    NullLiteral clone() const
-    {
-        auto result = NullLiteral(codeLocation());
-        if (auto* resolvedType = m_type.maybeResolvedType())
-            result.m_type.resolve(const_cast<AST::UnnamedType&>(*resolvedType));
-        copyTypeTo(result);
-        return result;
-    }
-
-private:
-    NullLiteralType m_type;
-};
-
-} // namespace AST
-
-}
-
-}
-
-DEFINE_DEFAULT_DELETE(NullLiteral)
-
-SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(NullLiteral, isNullLiteral())
-
-#endif
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteralType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteralType.h
deleted file mode 100644 (file)
index 85b2b28..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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)
-
-#include "WHLSLResolvableType.h"
-#include <wtf/FastMalloc.h>
-
-namespace WebCore {
-
-namespace WHLSL {
-
-namespace AST {
-
-class NullLiteralType final : public ResolvableType {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    NullLiteralType()
-        : ResolvableType(Kind::NullLiteral)
-    { }
-
-    ~NullLiteralType() = default;
-
-    NullLiteralType(const NullLiteralType&) = delete;
-    NullLiteralType(NullLiteralType&&) = default;
-
-    NullLiteralType& operator=(const NullLiteralType&) = delete;
-    NullLiteralType& operator=(NullLiteralType&&) = default;
-
-    bool canResolve(const Type&) const;
-    unsigned conversionCost(const UnnamedType&) const;
-
-private:
-};
-
-} // namespace AST
-
-}
-
-}
-
-DEFINE_DEFAULT_DELETE(NullLiteralType)
-
-SPECIALIZE_TYPE_TRAITS_WHLSL_TYPE(NullLiteralType, isNullLiteralType())
-
-#endif
index f7ff886..c4c6dd9 100644 (file)
@@ -53,45 +53,12 @@ public:
     PropertyAccessExpression(const PropertyAccessExpression&) = delete;
     PropertyAccessExpression(PropertyAccessExpression&&) = default;
 
-    String getterFunctionName() const;
-    String setterFunctionName() const;
-    String anderFunctionName() const;
-
-    FunctionDeclaration* getterFunction() { return m_getterFunction; }
-    FunctionDeclaration* anderFunction() { return m_anderFunction; }
-    FunctionDeclaration* threadAnderFunction() { return m_threadAnderFunction; }
-    FunctionDeclaration* setterFunction() { return m_setterFunction; }
-
-    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>& baseReference() { return m_base; }
     UniqueRef<Expression> takeBase() { return WTFMove(m_base); }
 
 private:
     UniqueRef<Expression> m_base;
-    FunctionDeclaration* m_getterFunction { nullptr };
-    FunctionDeclaration* m_anderFunction { nullptr };
-    FunctionDeclaration* m_threadAnderFunction { nullptr };
-    FunctionDeclaration* m_setterFunction { nullptr };
 };
 
 } // namespace AST
index efd1280..32c606e 100644 (file)
@@ -71,9 +71,6 @@ void Type::destroy(Type& type)
     case Kind::IntegerLiteral:
         delete &downcast<IntegerLiteralType>(type);
         break;
-    case Kind::NullLiteral:
-        delete &downcast<NullLiteralType>(type);
-        break;
     case Kind::UnsignedIntegerLiteral:
         delete &downcast<UnsignedIntegerLiteralType>(type);
         break;
@@ -115,9 +112,6 @@ void Type::destruct(Type& type)
     case Kind::IntegerLiteral:
         downcast<IntegerLiteralType>(type).~IntegerLiteralType();
         break;
-    case Kind::NullLiteral:
-        downcast<NullLiteralType>(type).~NullLiteralType();
-        break;
     case Kind::UnsignedIntegerLiteral:
         downcast<UnsignedIntegerLiteralType>(type).~UnsignedIntegerLiteralType();
         break;
@@ -157,8 +151,6 @@ bool ResolvableType::canResolve(const Type& type) const
         return downcast<FloatLiteralType>(*this).canResolve(type);
     case Kind::IntegerLiteral:
         return downcast<IntegerLiteralType>(*this).canResolve(type);
-    case Kind::NullLiteral:
-        return downcast<NullLiteralType>(*this).canResolve(type);
     case Kind::UnsignedIntegerLiteral:
         return downcast<UnsignedIntegerLiteralType>(*this).canResolve(type);
     default:
@@ -173,8 +165,6 @@ unsigned ResolvableType::conversionCost(const UnnamedType& type) const
         return downcast<FloatLiteralType>(*this).conversionCost(type);
     case Kind::IntegerLiteral:
         return downcast<IntegerLiteralType>(*this).conversionCost(type);
-    case Kind::NullLiteral:
-        return downcast<NullLiteralType>(*this).conversionCost(type);
     case Kind::UnsignedIntegerLiteral:
         return downcast<UnsignedIntegerLiteralType>(*this).conversionCost(type);
     default:
index 1066f16..82a8c19 100644 (file)
@@ -58,7 +58,6 @@ public:
         // ResolvableTypes
         FloatLiteral,
         IntegerLiteral,
-        NullLiteral,
         UnsignedIntegerLiteral,
     };
 
@@ -93,7 +92,6 @@ public:
 
     bool isFloatLiteralType() const { return kind() == Kind::FloatLiteral; }
     bool isIntegerLiteralType() const { return kind() == Kind::IntegerLiteral; }
-    bool isNullLiteralType() const { return kind() == Kind::NullLiteral; }
     bool isUnsignedIntegerLiteralType() const { return kind() == Kind::UnsignedIntegerLiteral; }
 
     Type& unifyNode();
index bb7ddcd..729f51d 100644 (file)
@@ -63,7 +63,57 @@ static void declareFunction(StringBuilder& stringBuilder, AST::FunctionDeclarati
     stringBuilder.append(");\n");
 }
 
+struct Variable {
+    MangledVariableName name;
+    MangledTypeName type;
+};
+
 class FunctionDefinitionWriter : public Visitor {
+    class HoistedVariableCollector : public Visitor {
+        public:
+        HoistedVariableCollector(FunctionDefinitionWriter& functionDefinitionWriter)
+            : functionDefinitionWriter(functionDefinitionWriter)
+        {
+        }
+
+        void visit(AST::CallExpression& callExpression) override
+        {
+            Vector<Variable> variables;
+            size_t size = callExpression.arguments().size();
+            bool isVoid = matches(callExpression.resolvedType(), functionDefinitionWriter.m_intrinsics.voidType());
+            if (!isVoid)
+                ++size;
+            variables.reserveInitialCapacity(size);
+
+            for (auto& argument : callExpression.arguments()) {
+                auto type = functionDefinitionWriter.m_typeNamer.mangledNameForType(argument->resolvedType());
+                auto name = functionDefinitionWriter.generateNextVariableName();
+                variables.uncheckedAppend(Variable { name, type });
+            }
+
+            if (!isVoid)
+                variables.uncheckedAppend(Variable { functionDefinitionWriter.generateNextVariableName(), functionDefinitionWriter.m_typeNamer.mangledNameForType(callExpression.resolvedType()) });
+
+            toHoist.add(&callExpression, WTFMove(variables));
+
+            Visitor::visit(callExpression);
+        }
+
+        void visit(AST::ReadModifyWriteExpression& readModifyWrite) override
+        {
+            Vector<Variable> variables;
+            variables.append(Variable { functionDefinitionWriter.generateNextVariableName(), functionDefinitionWriter.m_typeNamer.mangledNameForType(*readModifyWrite.oldValue().type()) });
+            variables.append(Variable { functionDefinitionWriter.generateNextVariableName(), functionDefinitionWriter.m_typeNamer.mangledNameForType(*readModifyWrite.newValue().type()) });
+
+            toHoist.add(&readModifyWrite, WTFMove(variables));
+
+            Visitor::visit(readModifyWrite);
+        }
+
+        FunctionDefinitionWriter& functionDefinitionWriter;
+        HashMap<AST::Expression*, Vector<Variable>> toHoist;
+    };
+
 public:
     FunctionDefinitionWriter(StringBuilder& stringBuilder, Intrinsics& intrinsics, TypeNamer& typeNamer, HashMap<AST::FunctionDeclaration*, MangledFunctionName>& functionMapping, Layout& layout)
         : m_stringBuilder(stringBuilder)
@@ -100,14 +150,12 @@ protected:
     void visit(AST::IntegerLiteral&) override;
     void visit(AST::UnsignedIntegerLiteral&) override;
     void visit(AST::FloatLiteral&) override;
-    void visit(AST::NullLiteral&) override;
     void visit(AST::BooleanLiteral&) override;
     void visit(AST::EnumerationMemberLiteral&) override;
     void visit(AST::Expression&) override;
-    void visit(AST::DotExpression&) override;
     void visit(AST::GlobalVariableReference&) override;
+    void visit(AST::DotExpression&) override;
     void visit(AST::IndexExpression&) override;
-    void visit(AST::PropertyAccessExpression&) override;
     void visit(AST::VariableDeclaration&) override;
     void visit(AST::AssignmentExpression&) override;
     void visit(AST::CallExpression&) override;
@@ -131,65 +179,6 @@ protected:
 
     MangledVariableName generateNextVariableName() { return { m_variableCount++ }; }
 
-    enum class Nullability : uint8_t {
-        NotNull,
-        CanBeNull
-    };
-
-    struct StackItem {
-        MangledVariableName value;
-        MangledVariableName leftValue;
-        Nullability valueNullability;
-        Nullability leftValueNullability;
-        std::function<MangledVariableName()> generateLeftValue;
-    };
-
-    struct StackValue {
-        MangledVariableName value;
-        Nullability nullability;
-    };
-
-    // This is the important data flow step where we can take the nullability of an lvalue
-    // and transfer it into the nullability of an rvalue. This is conveyed in MakePointerExpression
-    // and DereferenceExpression. MakePointerExpression will try to produce rvalues which are
-    // non-null, and DereferenceExpression will take a non-null rvalue and try to produce
-    // a non-null lvalue.
-    void appendRightValueWithNullability(AST::Expression&, MangledVariableName value, Nullability nullability)
-    {
-        m_stack.append({ WTFMove(value), { }, nullability, Nullability::CanBeNull, { } });
-    }
-
-    void appendRightValue(AST::Expression& expression, MangledVariableName value)
-    {
-        appendRightValueWithNullability(expression, WTFMove(value), Nullability::CanBeNull);
-    }
-
-    void appendLeftValue(AST::Expression& expression, MangledVariableName value, MangledVariableName leftValue, Nullability nullability, std::function<MangledVariableName()> generateLeftValue = { })
-    {
-        ASSERT_UNUSED(expression, expression.typeAnnotation().leftAddressSpace());
-        ASSERT(leftValue || generateLeftValue);
-        m_stack.append({ WTFMove(value), WTFMove(leftValue), Nullability::CanBeNull, nullability, WTFMove(generateLeftValue) });
-    }
-
-    MangledVariableName takeLastValue()
-    {
-        return m_stack.takeLast().value;
-    }
-
-    StackValue takeLastValueAndNullability()
-    {
-        auto last = m_stack.takeLast();
-        return { last.value, last.valueNullability };
-    }
-
-    StackValue takeLastLeftValue()
-    {
-        auto last = m_stack.takeLast();
-        if (!last.leftValue)
-            last.leftValue = last.generateLeftValue();
-        return { last.leftValue, last.leftValueNullability };
-    }
-
     enum class BreakContext {
         Loop,
         Switch
@@ -203,12 +192,12 @@ protected:
     HashMap<AST::FunctionDeclaration*, MangledFunctionName>& m_functionMapping;
     HashMap<AST::VariableDeclaration*, MangledVariableName> m_variableMapping;
 
-    Vector<StackItem> m_stack;
     std::unique_ptr<EntryPointScaffolding> m_entryPointScaffolding;
     Layout& m_layout;
     unsigned m_variableCount { 0 };
     Optional<MangledVariableName> m_breakOutOfCurrentLoopEarlyVariable;
     Indentation<4> m_indent { 0 };
+    HashMap<AST::Expression*, Vector<Variable>> m_hoistedVariables;
 };
 
 void FunctionDefinitionWriter::visit(AST::NativeFunctionDeclaration&)
@@ -218,6 +207,20 @@ void FunctionDefinitionWriter::visit(AST::NativeFunctionDeclaration&)
 
 void FunctionDefinitionWriter::visit(AST::FunctionDefinition& functionDefinition)
 {
+
+    {
+        HoistedVariableCollector collector(*this);
+        collector.Visitor::visit(functionDefinition);
+        m_hoistedVariables = WTFMove(collector.toHoist);
+    }
+
+    auto defineHoistedVariables = [&] {
+        for (const auto& vector : m_hoistedVariables.values()) {
+            for (auto variable : vector)
+                m_stringBuilder.append(m_indent, variable.type, ' ', variable.name, ";\n");
+        }
+    };
+
     auto iterator = m_functionMapping.find(&functionDefinition);
     ASSERT(iterator != m_functionMapping.end());
     if (functionDefinition.entryPointType()) {
@@ -238,8 +241,10 @@ void FunctionDefinitionWriter::visit(AST::FunctionDefinition& functionDefinition
                 auto addResult = m_variableMapping.add(&functionDefinition.parameters()[i], m_entryPointScaffolding->parameterVariables()[i]);
                 ASSERT_UNUSED(addResult, addResult.isNewEntry);
             }
+
+            defineHoistedVariables();
+
             checkErrorAndVisit(functionDefinition.block());
-            ASSERT(m_stack.isEmpty());
         }
         m_stringBuilder.append("}\n\n");
 
@@ -248,17 +253,22 @@ void FunctionDefinitionWriter::visit(AST::FunctionDefinition& functionDefinition
         ASSERT(m_entryPointScaffolding == nullptr);
         m_stringBuilder.append(m_indent, m_typeNamer.mangledNameForType(functionDefinition.type()), ' ', iterator->value, '(');
         for (size_t i = 0; i < functionDefinition.parameters().size(); ++i) {
-            auto& parameter = functionDefinition.parameters()[i];
             if (i)
                 m_stringBuilder.append(", ");
+            auto& parameter = functionDefinition.parameters()[i];
             auto parameterName = generateNextVariableName();
             auto addResult = m_variableMapping.add(&parameter, parameterName);
             ASSERT_UNUSED(addResult, addResult.isNewEntry);
             m_stringBuilder.append(m_typeNamer.mangledNameForType(*parameter->type()), ' ', parameterName);
         }
         m_stringBuilder.append(")\n");
+
+        m_stringBuilder.append("{\n");
+
+        defineHoistedVariables();
+
         checkErrorAndVisit(functionDefinition.block());
-        ASSERT(m_stack.isEmpty());
+        m_stringBuilder.append("}\n");
         m_stringBuilder.append('\n');
     }
 }
@@ -309,8 +319,9 @@ void FunctionDefinitionWriter::visit(AST::Continue&)
 
 void FunctionDefinitionWriter::visit(AST::EffectfulExpressionStatement& effectfulExpressionStatement)
 {
+    m_stringBuilder.append(m_indent);
     checkErrorAndVisit(effectfulExpressionStatement.effectfulExpression());
-    takeLastValue(); // The statement is already effectful, so we don't need to do anything with the result.
+    m_stringBuilder.append(";\n");
 }
 
 void FunctionDefinitionWriter::visit(AST::Fallthrough&)
@@ -330,10 +341,12 @@ void FunctionDefinitionWriter::emitLoop(LoopConditionLocation loopConditionLocat
         IndentationScope whileScope(m_indent);
 
         if (loopConditionLocation == LoopConditionLocation::BeforeBody && conditionExpression) {
+            m_stringBuilder.append(
+                m_indent, "if (!(");
             checkErrorAndVisit(*conditionExpression);
             m_stringBuilder.append(
-                m_indent, "if (!", takeLastValue(), ")\n",
-                m_indent, "    break;\n");
+                "))\n",
+                "    break;\n");
         }
 
         m_stringBuilder.append(m_indent, "do {\n");
@@ -350,17 +363,18 @@ void FunctionDefinitionWriter::emitLoop(LoopConditionLocation loopConditionLocat
             m_indent, "    break;\n");
 
         if (increment) {
+            m_stringBuilder.append("(");
             checkErrorAndVisit(*increment);
-            // Expression results get pushed to m_stack. We don't use the result
-            // of increment, so we dispense of that now.
-            takeLastValue();
+            m_stringBuilder.append(");\n");
         }
 
         if (loopConditionLocation == LoopConditionLocation::AfterBody && conditionExpression) {
+            m_stringBuilder.append(
+                m_indent, "if (!(");
             checkErrorAndVisit(*conditionExpression);
             m_stringBuilder.append(
-                m_indent, "if (!", takeLastValue(), ")\n",
-                m_indent, "    break;\n");
+                "))\n",
+                "    break;\n");
         }
     }
 
@@ -390,12 +404,15 @@ void FunctionDefinitionWriter::visit(AST::ForLoop& forLoop)
 
 void FunctionDefinitionWriter::visit(AST::IfStatement& ifStatement)
 {
+    m_stringBuilder.append(m_indent, "if (");
     checkErrorAndVisit(ifStatement.conditional());
-    m_stringBuilder.append(m_indent, "if (", takeLastValue(), ") {\n");
+    m_stringBuilder.append(") {\n");
+
     {
         IndentationScope ifScope(m_indent);
         checkErrorAndVisit(ifStatement.body());
     }
+
     if (ifStatement.elseBody()) {
         m_stringBuilder.append(m_indent, "} else {\n");
         {
@@ -403,29 +420,34 @@ void FunctionDefinitionWriter::visit(AST::IfStatement& ifStatement)
             checkErrorAndVisit(*ifStatement.elseBody());
         }
     }
+
     m_stringBuilder.append(m_indent, "}\n");
 }
 
 void FunctionDefinitionWriter::visit(AST::Return& returnStatement)
 {
     if (returnStatement.value()) {
+        auto tempReturnName = generateNextVariableName(); 
+        m_stringBuilder.append(m_indent, m_typeNamer.mangledNameForType(returnStatement.value()->resolvedType()), ' ', tempReturnName, " = "); 
         checkErrorAndVisit(*returnStatement.value());
+        m_stringBuilder.append(";\n");
 
         if (m_entryPointScaffolding) {
             auto variableName = generateNextVariableName();
-            m_entryPointScaffolding->emitPack(m_stringBuilder, takeLastValue(), variableName, m_indent);
+            m_entryPointScaffolding->emitPack(m_stringBuilder, tempReturnName, variableName, m_indent);
             m_stringBuilder.append(m_indent, "return ", variableName, ";\n");
         } else
-            m_stringBuilder.append(m_indent, "return ", takeLastValue(), ";\n");
+            m_stringBuilder.append(m_indent, "return ", tempReturnName, ";\n");
     } else
         m_stringBuilder.append(m_indent, "return;\n");
 }
 
 void FunctionDefinitionWriter::visit(AST::SwitchStatement& switchStatement)
 {
+    m_stringBuilder.append(m_indent, "switch (");
     checkErrorAndVisit(switchStatement.value());
+    m_stringBuilder.append(") {");
 
-    m_stringBuilder.append(m_indent, "switch (", takeLastValue(), ") {");
     {
         IndentationScope switchScope(m_indent);
         for (auto& switchCase : switchStatement.switchCases())
@@ -454,59 +476,34 @@ void FunctionDefinitionWriter::visit(AST::VariableDeclarationsStatement& variabl
 
 void FunctionDefinitionWriter::visit(AST::IntegerLiteral& integerLiteral)
 {
-    auto variableName = generateNextVariableName();
     auto mangledTypeName = m_typeNamer.mangledNameForType(integerLiteral.resolvedType());
-    m_stringBuilder.append(m_indent, mangledTypeName, ' ', variableName, " = static_cast<", mangledTypeName, ">(", integerLiteral.value(), ");\n");
-    appendRightValue(integerLiteral, variableName);
+    m_stringBuilder.append("static_cast<", mangledTypeName, ">(", integerLiteral.value(), ")");
 }
 
 void FunctionDefinitionWriter::visit(AST::UnsignedIntegerLiteral& unsignedIntegerLiteral)
 {
-    auto variableName = generateNextVariableName();
     auto mangledTypeName = m_typeNamer.mangledNameForType(unsignedIntegerLiteral.resolvedType());
-    m_stringBuilder.append(m_indent, mangledTypeName, ' ', variableName, " = static_cast<", mangledTypeName, ">(", unsignedIntegerLiteral.value(), ");\n");
-    appendRightValue(unsignedIntegerLiteral, variableName);
+    m_stringBuilder.append("static_cast<", mangledTypeName, ">(", unsignedIntegerLiteral.value(), ")");
 }
 
 void FunctionDefinitionWriter::visit(AST::FloatLiteral& floatLiteral)
 {
-    auto variableName = generateNextVariableName();
     auto mangledTypeName = m_typeNamer.mangledNameForType(floatLiteral.resolvedType());
-    m_stringBuilder.append(m_indent, mangledTypeName, ' ', variableName, " = static_cast<", mangledTypeName, ">(", floatLiteral.value(), ");\n");
-    appendRightValue(floatLiteral, variableName);
-}
-
-void FunctionDefinitionWriter::visit(AST::NullLiteral& nullLiteral)
-{
-    auto& unifyNode = nullLiteral.resolvedType().unifyNode();
-    auto& unnamedType = downcast<AST::UnnamedType>(unifyNode);
-    bool isArrayReferenceType = is<AST::ArrayReferenceType>(unnamedType);
-
-    auto variableName = generateNextVariableName();
-    m_stringBuilder.append(m_indent, m_typeNamer.mangledNameForType(nullLiteral.resolvedType()), ' ', variableName, " = ");
-    if (isArrayReferenceType)
-        m_stringBuilder.append("{ nullptr, 0 };\n");
-    else
-        m_stringBuilder.append("nullptr;\n");
-    appendRightValue(nullLiteral, variableName);
+    m_stringBuilder.append("static_cast<", mangledTypeName, ">(", floatLiteral.value(), ")");
 }
 
 void FunctionDefinitionWriter::visit(AST::BooleanLiteral& booleanLiteral)
 {
-    auto variableName = generateNextVariableName();
     auto mangledTypeName = m_typeNamer.mangledNameForType(booleanLiteral.resolvedType());
-    m_stringBuilder.append(m_indent, mangledTypeName, ' ', variableName, " = static_cast<", mangledTypeName, ">(", booleanLiteral.value() ? "true" : "false", ");\n");
-    appendRightValue(booleanLiteral, variableName);
+    m_stringBuilder.append("static_cast<", mangledTypeName, ">(", booleanLiteral.value() ? "true" : "false", ")");
 }
 
 void FunctionDefinitionWriter::visit(AST::EnumerationMemberLiteral& enumerationMemberLiteral)
 {
     ASSERT(enumerationMemberLiteral.enumerationDefinition());
     ASSERT(enumerationMemberLiteral.enumerationDefinition());
-    auto variableName = generateNextVariableName();
     auto mangledTypeName = m_typeNamer.mangledNameForType(enumerationMemberLiteral.resolvedType());
-    m_stringBuilder.append(m_indent, mangledTypeName, ' ', variableName, " = ", mangledTypeName, "::", m_typeNamer.mangledNameForEnumerationMember(*enumerationMemberLiteral.enumerationMember()), ";\n");
-    appendRightValue(enumerationMemberLiteral, variableName);
+    m_stringBuilder.append(mangledTypeName, "::", m_typeNamer.mangledNameForEnumerationMember(*enumerationMemberLiteral.enumerationMember()));
 }
 
 void FunctionDefinitionWriter::visit(AST::Expression& expression)
@@ -514,50 +511,94 @@ void FunctionDefinitionWriter::visit(AST::Expression& expression)
     Visitor::visit(expression);
 }
 
-void FunctionDefinitionWriter::visit(AST::DotExpression& dotExpression)
-{
-    // This should be lowered already.
-    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195788 Replace this with ASSERT_NOT_REACHED().
-    notImplemented();
-    appendRightValue(dotExpression, generateNextVariableName());
-}
-
 void FunctionDefinitionWriter::visit(AST::GlobalVariableReference& globalVariableReference)
 {
-    auto valueName = generateNextVariableName();
-    MangledTypeName mangledTypeName = m_typeNamer.mangledNameForType(globalVariableReference.resolvedType());
-
+    MangledStructureElementName mangledFieldName = m_typeNamer.mangledNameForStructureElement(globalVariableReference.structField());
+    m_stringBuilder.append('(');
     checkErrorAndVisit(globalVariableReference.base());
-    MangledVariableName structVariable = takeLastValue();
+    m_stringBuilder.append(")->", mangledFieldName);
+}
 
-    MangledStructureElementName mangledFieldName = m_typeNamer.mangledNameForStructureElement(globalVariableReference.structField());
+void FunctionDefinitionWriter::visit(AST::DotExpression& dotExpression)
+{
+    auto& type = dotExpression.base().resolvedType().unifyNode();
 
-    m_stringBuilder.append(
-        m_indent, mangledTypeName, ' ', valueName, " = ", structVariable, "->", mangledFieldName, ";\n");
+    if (is<AST::StructureDefinition>(type)) {
+        auto& structureDefinition = downcast<AST::StructureDefinition>(type);
+        auto* structureElement = structureDefinition.find(dotExpression.fieldName());
+        ASSERT(structureElement);
+        auto elementName = m_typeNamer.mangledNameForStructureElement(*structureElement);
 
-    appendLeftValue(globalVariableReference, valueName, { }, Nullability::NotNull,
-        [this, mangledTypeName, structVariable, mangledFieldName] {
-            auto pointerName = generateNextVariableName();
-            m_stringBuilder.append(
-                m_indent, "thread ", mangledTypeName, "* ", pointerName, " = &", structVariable, "->", mangledFieldName, ";\n");
-            return pointerName;
-        });
+        m_stringBuilder.append('(');
+        checkErrorAndVisit(dotExpression.base());
+        m_stringBuilder.append(").", elementName);
+    } else {
+        String elementName = dotExpression.fieldName();
+        if (elementName == "length" && (is<AST::ArrayReferenceType>(type) || is<AST::ArrayType>(type) || (is<AST::NativeTypeDeclaration>(type) && downcast<AST::NativeTypeDeclaration>(type).isVector()))) {
+            if (is<AST::ArrayReferenceType>(type)) {
+                m_stringBuilder.append('(');
+                checkErrorAndVisit(dotExpression.base());
+                m_stringBuilder.append(").length");
+            } else if (is<AST::ArrayType>(type)) {
+                m_stringBuilder.append('(');
+                checkErrorAndVisit(dotExpression.base());
+                m_stringBuilder.append(", ", downcast<AST::ArrayType>(type).numElements(), ")");
+            } else {
+                m_stringBuilder.append('(');
+                checkErrorAndVisit(dotExpression.base());
+                m_stringBuilder.append(", ", downcast<AST::NativeTypeDeclaration>(type).vectorSize(), ")");
+            }
+        } else {
+            m_stringBuilder.append('(');
+            checkErrorAndVisit(dotExpression.base());
+            m_stringBuilder.append(").", elementName);
+        }
+    }
 }
 
 void FunctionDefinitionWriter::visit(AST::IndexExpression& indexExpression)
 {
-    // This should be lowered already.
-    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195788 Replace this with ASSERT_NOT_REACHED().
-    notImplemented();
-    appendRightValue(indexExpression, generateNextVariableName());
-}
-
-void FunctionDefinitionWriter::visit(AST::PropertyAccessExpression& propertyAccessExpression)
-{
-    // This should be lowered already.
-    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195788 Replace this with ASSERT_NOT_REACHED().
-    notImplemented();
-    appendRightValue(propertyAccessExpression, generateNextVariableName());
+    // FIXME: Make it so that evaluating index and base twice doesn't execute effects twice:
+    // https://bugs.webkit.org/show_bug.cgi?id=201251
+
+    auto& type = indexExpression.base().resolvedType().unifyNode();
+    if (is<AST::ArrayReferenceType>(type)) {
+        m_stringBuilder.append('(');
+        checkErrorAndVisit(indexExpression.base());
+        m_stringBuilder.append(").pointer[(");
+        checkErrorAndVisit(indexExpression.indexExpression());
+        m_stringBuilder.append(") < (");
+        checkErrorAndVisit(indexExpression.base());
+        m_stringBuilder.append(").length ? ");
+        checkErrorAndVisit(indexExpression.indexExpression());
+        m_stringBuilder.append(" : 0]");
+    } else if (is<AST::ArrayType>(type)) {
+        m_stringBuilder.append('(');
+        checkErrorAndVisit(indexExpression.base());
+        m_stringBuilder.append(").data()[(");
+        checkErrorAndVisit(indexExpression.indexExpression());
+        m_stringBuilder.append(") < ", downcast<AST::ArrayType>(type).numElements(), " ? ");
+        checkErrorAndVisit(indexExpression.indexExpression());
+        m_stringBuilder.append(" : 0]");
+    } else if (is<AST::NativeTypeDeclaration>(type)) {
+        auto& nativeType = downcast<AST::NativeTypeDeclaration>(type);
+        unsigned size;
+        if (nativeType.isMatrix())
+            size = nativeType.numberOfMatrixColumns();
+        else if (nativeType.isVector())
+            size = nativeType.vectorSize();
+        else
+            RELEASE_ASSERT_NOT_REACHED();
+
+        m_stringBuilder.append('(');
+        checkErrorAndVisit(indexExpression.base());
+        m_stringBuilder.append(")[(");
+        checkErrorAndVisit(indexExpression.indexExpression());
+        m_stringBuilder.append(" < ", size, ") ? (");
+        checkErrorAndVisit(indexExpression.indexExpression());
+        m_stringBuilder.append(") : 0]");
+    } else
+        RELEASE_ASSERT_NOT_REACHED(); 
 }
 
 void FunctionDefinitionWriter::visit(AST::VariableDeclaration& variableDeclaration)
@@ -568,181 +609,185 @@ void FunctionDefinitionWriter::visit(AST::VariableDeclaration& variableDeclarati
     ASSERT_UNUSED(addResult, addResult.isNewEntry);
     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198160 Implement qualifiers.
     if (variableDeclaration.initializer()) {
+        m_stringBuilder.append(m_indent, m_typeNamer.mangledNameForType(*variableDeclaration.type()), ' ', variableName, " = ");
         checkErrorAndVisit(*variableDeclaration.initializer());
-        m_stringBuilder.append(m_indent, m_typeNamer.mangledNameForType(*variableDeclaration.type()), ' ', variableName, " = ", takeLastValue(), ";\n");
+        m_stringBuilder.append(";\n");
     } else
         m_stringBuilder.append(m_indent, m_typeNamer.mangledNameForType(*variableDeclaration.type()), ' ', variableName, " = { };\n");
 }
 
 void FunctionDefinitionWriter::visit(AST::AssignmentExpression& assignmentExpression)
 {
+    m_stringBuilder.append('(');
     checkErrorAndVisit(assignmentExpression.left());
-    auto [pointerName, nullability] = takeLastLeftValue();
+    m_stringBuilder.append(')');
+    m_stringBuilder.append(" = (");
     checkErrorAndVisit(assignmentExpression.right());
-    auto [rightName, rightNullability] = takeLastValueAndNullability();
-
-    if (nullability == Nullability::CanBeNull)
-        m_stringBuilder.append(
-            m_indent, "if (", pointerName, ")\n",
-            m_indent, "    *", pointerName, " = ", rightName, ";\n");
-    else
-        m_stringBuilder.append(m_indent, "*", pointerName, " = ", rightName, ";\n");
-    appendRightValueWithNullability(assignmentExpression, rightName, rightNullability);
+    m_stringBuilder.append(')');
 }
 
 void FunctionDefinitionWriter::visit(AST::CallExpression& callExpression)
 {
+    auto iter = m_hoistedVariables.find(&callExpression);
+    RELEASE_ASSERT(iter != m_hoistedVariables.end());
+    auto& variables = iter->value;
+    RELEASE_ASSERT(callExpression.arguments().size() <= variables.size());
     Vector<MangledVariableName> argumentNames;
-    for (auto& argument : callExpression.arguments()) {
-        checkErrorAndVisit(argument);
-        argumentNames.append(takeLastValue());
-    }
 
-    bool isVoid = matches(callExpression.resolvedType(), m_intrinsics.voidType());
-    MangledVariableName returnName;
-    if (!isVoid) {
-        returnName = generateNextVariableName();
-        m_stringBuilder.append(m_indent, m_typeNamer.mangledNameForType(callExpression.resolvedType()), ' ', returnName, ";\n");
+    MangledVariableName resultName;
+    if (!matches(callExpression.resolvedType(), m_intrinsics.voidType()))
+        resultName = variables.last().name;
+
+    m_stringBuilder.append('(');
+    for (size_t i = 0; i < callExpression.arguments().size(); ++i) {
+        argumentNames.append(variables[i].name);
+        m_stringBuilder.append(variables[i].name, " = (");
+        checkErrorAndVisit(callExpression.arguments()[i]);
+        m_stringBuilder.append("), ");
     }
 
     if (is<AST::NativeFunctionDeclaration>(callExpression.function())) {
-        auto generateNextVariableName = [this]() -> MangledVariableName {
-            return this->generateNextVariableName();
-        };
-
-        m_stringBuilder.append('\n');
-        inlineNativeFunction(m_stringBuilder, downcast<AST::NativeFunctionDeclaration>(callExpression.function()), returnName, argumentNames, m_intrinsics, m_typeNamer, WTFMove(generateNextVariableName), m_indent);
-        m_stringBuilder.append('\n');
+        inlineNativeFunction(m_stringBuilder, downcast<AST::NativeFunctionDeclaration>(callExpression.function()), argumentNames, resultName, m_typeNamer);
     } else {
-        m_stringBuilder.append(m_indent);
-
         auto iterator = m_functionMapping.find(&callExpression.function());
         ASSERT(iterator != m_functionMapping.end());
-        if (!isVoid)
-            m_stringBuilder.append(returnName, " = ");
         m_stringBuilder.append(iterator->value, '(');
-        for (size_t i = 0; i < argumentNames.size(); ++i) {
+        for (size_t i = 0; i < callExpression.arguments().size(); ++i) {
             if (i)
                 m_stringBuilder.append(", ");
-            m_stringBuilder.append(argumentNames[i]);
+            m_stringBuilder.append(variables[i].name);
         }
-        m_stringBuilder.append(");\n");
+        m_stringBuilder.append(')');
     }
 
-    appendRightValue(callExpression, returnName);
+    m_stringBuilder.append(')');
 }
 
 void FunctionDefinitionWriter::visit(AST::CommaExpression& commaExpression)
 {
-    Optional<MangledVariableName> result;
+    m_stringBuilder.append('(');
+    bool ranOnce = false;
     for (auto& expression : commaExpression.list()) {
+        if (ranOnce)
+            m_stringBuilder.append(", ");
+        ranOnce = true;
         checkErrorAndVisit(expression);
-        result = takeLastValue();
     }
-    ASSERT(result);
-    appendRightValue(commaExpression, *result);
+    m_stringBuilder.append(')');
 }
 
 void FunctionDefinitionWriter::visit(AST::DereferenceExpression& dereferenceExpression)
 {
+    m_stringBuilder.append("*(");
     checkErrorAndVisit(dereferenceExpression.pointer());
-    auto [inputPointer, nullability] = takeLastValueAndNullability();
-    auto resultValue = generateNextVariableName();
-    auto resultType = m_typeNamer.mangledNameForType(dereferenceExpression.resolvedType());
-
-    if (nullability == Nullability::CanBeNull) {
-        m_stringBuilder.append(
-            m_indent, resultType , ' ', resultValue, " = ", inputPointer, " ? ", '*', inputPointer, " : ", resultType, "{ };\n");
-    } else
-        m_stringBuilder.append(m_indent, resultValue, " = *", inputPointer, ";\n");
-
-    appendLeftValue(dereferenceExpression, resultValue, inputPointer, nullability);
+    m_stringBuilder.append(')');
 }
 
 void FunctionDefinitionWriter::visit(AST::LogicalExpression& logicalExpression)
 {
+    m_stringBuilder.append("((");
     checkErrorAndVisit(logicalExpression.left());
-    auto left = takeLastValue();
-    checkErrorAndVisit(logicalExpression.right());
-    auto right = takeLastValue();
-    auto variableName = generateNextVariableName();
+    m_stringBuilder.append(')');
 
-    m_stringBuilder.append(
-        m_indent, m_typeNamer.mangledNameForType(logicalExpression.resolvedType()), ' ', variableName, " = ", left);
     switch (logicalExpression.type()) {
     case AST::LogicalExpression::Type::And:
         m_stringBuilder.append(" && ");
         break;
-    default:
-        ASSERT(logicalExpression.type() == AST::LogicalExpression::Type::Or);
+    case AST::LogicalExpression::Type::Or:
         m_stringBuilder.append(" || ");
         break;
     }
-    m_stringBuilder.append(right, ";\n");
-    appendRightValue(logicalExpression, variableName);
+
+    m_stringBuilder.append('(');
+    checkErrorAndVisit(logicalExpression.right());
+    m_stringBuilder.append("))");
 }
 
 void FunctionDefinitionWriter::visit(AST::LogicalNotExpression& logicalNotExpression)
 {
+    m_stringBuilder.append("!(");
     checkErrorAndVisit(logicalNotExpression.operand());
-    auto operand = takeLastValue();
-    auto variableName = generateNextVariableName();
-
-    m_stringBuilder.append(
-        m_indent, m_typeNamer.mangledNameForType(logicalNotExpression.resolvedType()), ' ', variableName, " = !", operand, ";\n");
-    appendRightValue(logicalNotExpression, variableName);
+    m_stringBuilder.append(')');
 }
 
 void FunctionDefinitionWriter::visit(AST::MakeArrayReferenceExpression& makeArrayReferenceExpression)
 {
-    checkErrorAndVisit(makeArrayReferenceExpression.leftValue());
     // FIXME: This needs to be made to work. It probably should be using the last leftValue too.
     // https://bugs.webkit.org/show_bug.cgi?id=198838
-    auto variableName = generateNextVariableName();
-
     auto mangledTypeName = m_typeNamer.mangledNameForType(makeArrayReferenceExpression.resolvedType());
     if (is<AST::PointerType>(makeArrayReferenceExpression.leftValue().resolvedType())) {
-        auto ptrValue = takeLastValue();
-        m_stringBuilder.append(
-            m_indent, mangledTypeName, ' ', variableName, " = ", ptrValue, " ? ", mangledTypeName, "{ ", ptrValue, ", 1 } : ", mangledTypeName, "{ nullptr, 0 };\n");
+        m_stringBuilder.append(mangledTypeName, "{ ");
+        checkErrorAndVisit(makeArrayReferenceExpression.leftValue());
+        m_stringBuilder.append(", 1 }");
     } else if (is<AST::ArrayType>(makeArrayReferenceExpression.leftValue().resolvedType())) {
-        auto lValue = takeLastLeftValue().value;
         auto& arrayType = downcast<AST::ArrayType>(makeArrayReferenceExpression.leftValue().resolvedType());
-        m_stringBuilder.append(m_indent, mangledTypeName, ' ', variableName, " = { ", lValue, "->data(), ", arrayType.numElements(), " };\n");
+        m_stringBuilder.append(mangledTypeName, " { ");
+        checkErrorAndVisit(makeArrayReferenceExpression.leftValue());
+        m_stringBuilder.append(".data(), ", arrayType.numElements(), " }");
     } else {
-        auto lValue = takeLastLeftValue().value;
-        m_stringBuilder.append(m_indent, mangledTypeName, ' ', variableName, " = { ", lValue, ", 1 };\n");
+        m_stringBuilder.append(mangledTypeName, " { &");
+        checkErrorAndVisit(makeArrayReferenceExpression.leftValue());
+        m_stringBuilder.append(", 1 }");
     }
-    appendRightValue(makeArrayReferenceExpression, variableName);
 }
 
 void FunctionDefinitionWriter::visit(AST::MakePointerExpression& makePointerExpression)
 {
+    m_stringBuilder.append("&(");
     checkErrorAndVisit(makePointerExpression.leftValue());
-    auto [pointer, nullability] = takeLastLeftValue();
-    auto variableName = generateNextVariableName();
-    m_stringBuilder.append(m_indent, m_typeNamer.mangledNameForType(makePointerExpression.resolvedType()), ' ', variableName, " = ", pointer, ";\n");
-    appendRightValueWithNullability(makePointerExpression, variableName, nullability);
+    m_stringBuilder.append(')');
 }
 
-void FunctionDefinitionWriter::visit(AST::ReadModifyWriteExpression&)
+void FunctionDefinitionWriter::visit(AST::ReadModifyWriteExpression& readModifyWrite)
 {
-    // This should be lowered already.
-    ASSERT_NOT_REACHED();
+    /*
+     *  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_leftValue
+     *  6. Evaluate m_resultExpression
+     *  7. Return the result
+     */
+
+    auto iter = m_hoistedVariables.find(&readModifyWrite);
+    RELEASE_ASSERT(iter != m_hoistedVariables.end());
+    auto& variables = iter->value;
+    RELEASE_ASSERT(variables.size() == 2);
+
+    MangledVariableName oldValueVariable = variables[0].name;
+    MangledVariableName newValueVariable = variables[1].name;
+
+    m_variableMapping.add(&readModifyWrite.oldValue(), oldValueVariable);
+    m_variableMapping.add(&readModifyWrite.newValue(), newValueVariable);
+
+    m_stringBuilder.append('(');
+
+    m_stringBuilder.append(oldValueVariable, " = ");
+    checkErrorAndVisit(readModifyWrite.leftValue());
+
+    m_stringBuilder.append(", ", newValueVariable, " = ");
+    checkErrorAndVisit(readModifyWrite.newValueExpression());
+
+    // FIXME: Make it so that evaluating left value twice doesn't execute effects twice:
+    // https://bugs.webkit.org/show_bug.cgi?id=201251
+    m_stringBuilder.append(", ");
+    checkErrorAndVisit(readModifyWrite.leftValue());
+    m_stringBuilder.append(" = ", newValueVariable, ", ");
+
+    checkErrorAndVisit(readModifyWrite.resultExpression());
+    m_stringBuilder.append(')');
 }
 
 void FunctionDefinitionWriter::visit(AST::TernaryExpression& ternaryExpression)
 {
+    m_stringBuilder.append('(');
     checkErrorAndVisit(ternaryExpression.predicate());
-    auto check = takeLastValue();
+    m_stringBuilder.append(") ? (");
     checkErrorAndVisit(ternaryExpression.bodyExpression());
-    auto body = takeLastValue();
+    m_stringBuilder.append(") : (");
     checkErrorAndVisit(ternaryExpression.elseExpression());
-    auto elseBody = takeLastValue();
-
-    auto variableName = generateNextVariableName();
-    m_stringBuilder.append(m_indent, m_typeNamer.mangledNameForType(ternaryExpression.resolvedType()), ' ', variableName, " = ", check, " ? ", body, " : ", elseBody, ";\n");
-    appendRightValue(ternaryExpression, variableName);
+    m_stringBuilder.append(')');
 }
 
 void FunctionDefinitionWriter::visit(AST::VariableReference& variableReference)
@@ -752,13 +797,7 @@ void FunctionDefinitionWriter::visit(AST::VariableReference& variableReference)
     ASSERT(iterator != m_variableMapping.end());
 
     MangledVariableName variableName = iterator->value;
-
-    appendLeftValue(variableReference, variableName, { }, Nullability::NotNull,
-        [this, &variableReference, variableName] {
-            auto pointerName = generateNextVariableName();
-            m_stringBuilder.append(m_indent, "thread ", m_typeNamer.mangledNameForType(variableReference.resolvedType()), "* ", pointerName, " = &", variableName, ";\n");
-            return pointerName;
-        });
+    m_stringBuilder.append(variableName);
 }
 
 void FunctionDefinitionWriter::emitConstantExpressionString(AST::ConstantExpression& constantExpression)
@@ -773,9 +812,6 @@ void FunctionDefinitionWriter::emitConstantExpressionString(AST::ConstantExpress
         [&](AST::FloatLiteral& floatLiteral) {
             m_stringBuilder.append(floatLiteral.value());
         },
-        [&](AST::NullLiteral&) {
-            m_stringBuilder.append("nullptr");
-        },
         [&](AST::BooleanLiteral& booleanLiteral) {
             if (booleanLiteral.value())
                 m_stringBuilder.append("true");
index 0252c66..3d75745 100644 (file)
@@ -41,7 +41,7 @@ namespace Metal {
 
 static constexpr bool dumpMetalCode = false;
 
-static StringView metalCodeProlog()
+static StringView metalCodePrologue()
 {
     return StringView {
         "#include <metal_stdlib>\n"
@@ -53,7 +53,171 @@ static StringView metalCodeProlog()
         "\n"
         "using namespace metal;\n"
         "\n"
+        "template <typename T, int Cols, int Rows>\n"
+        "struct WSLMatrix\n"
+        "{\n"
+        "    vec<T, Rows> columns[Cols];\n"
+        "    private:\n"
+        "    template <typename U, int... R>\n"
+        "    static vec<T, Rows> build_col(initializer_list<U> col, _integer_sequence<int, R...>)\n"
+        "    {\n"
+        "        return {(R < col.size() ? *(col.begin() + R) : U())...};\n"
+        "    }\n"
+        "    template <int... R>\n"
+        "    static vec<T, Rows> build_full_col(int c, initializer_list<T> elems, _integer_sequence<int, R...>)\n"
+        "    {\n"
+        "        return {*(elems.begin() + c * Rows + R)...};\n"
+        "    }\n"
+        "    struct cols_init_tag { };\n"
+        "    struct cols_all_tag { };\n"
+        "    struct elems_all_tag { };\n"
+        "    template <int... C>\n"
+        "    inline explicit WSLMatrix(cols_init_tag, initializer_list<vec<T, Rows>> cols, _integer_sequence<int, C...>) thread\n"
+        "        : columns{(C < cols.size() ? *(cols.begin() + C) : vec<T, Rows>())...}\n"
+        "    {\n"
+        "    }\n"
+        "    template <typename... U>\n"
+        "    inline explicit WSLMatrix(cols_all_tag, U... cols) thread\n"
+        "        : columns{ cols... }\n"
+        "    {\n"
+        "    }\n"
+        "    template <typename... U>\n"
+        "    inline explicit WSLMatrix(elems_all_tag, U... elems) thread\n"
+        "        : WSLMatrix({T(elems)...}, _make_integer_sequence<int, Cols>())\n"
+        "        {\n"
+        "        }\n"
+        "    template <int... C>\n"
+        "    inline explicit WSLMatrix(initializer_list<T> elems, _integer_sequence<int, C...>) thread\n"
+        "        : columns{build_full_col(C, elems, _make_integer_sequence<int, Rows>())...}\n"
+        "    {\n"
+        "    }\n"
+        "    template <int... C>\n"
+        "    inline explicit WSLMatrix(cols_init_tag, initializer_list<vec<T, Rows>> cols, _integer_sequence<int, C...>) constant\n"
+        "        : columns{(C < cols.size() ? *(cols.begin() + C) : vec<T, Rows>())...}\n"
+        "    {\n"
+        "    }\n"
+        "    template <typename... U>\n"
+        "    inline explicit WSLMatrix(cols_all_tag, U... cols) constant\n"
+        "        : columns{ cols... }\n"
+        "    {\n"
+        "    }\n"
+        "    template <typename... U>\n"
+        "    inline explicit WSLMatrix(elems_all_tag, U... elems) constant\n"
+        "        : WSLMatrix({T(elems)...}, _make_integer_sequence<int, Cols>())\n"
+        "        {\n"
+        "        }\n"
+        "    template <int... C>\n"
+        "    inline explicit WSLMatrix(initializer_list<T> elems, _integer_sequence<int, C...>) constant\n"
+        "        : columns{build_full_col(C, elems, _make_integer_sequence<int, Rows>())...}\n"
+        "    {\n"
+        "    }\n"
+        "    public:\n"
+        "    inline WSLMatrix() thread = default;\n"
+        "    inline WSLMatrix(initializer_list<vec<T, Rows>> cols) thread\n"
+        "        : WSLMatrix(cols_init_tag(), cols, _make_integer_sequence<int, Cols>())\n"
+        "    {\n"
+        "    }\n"
+        "    template <typename... U>\n"
+        "    inline explicit WSLMatrix(U... vals) thread\n"
+        "        : WSLMatrix(conditional_t<sizeof...(U) == Cols, cols_all_tag, elems_all_tag>(), vals...)\n"
+        "    {\n"
+        "    }\n"
+        "    inline WSLMatrix() constant = default;\n"
+        "    inline WSLMatrix(initializer_list<vec<T, Rows>> cols) constant\n"
+        "        : WSLMatrix(cols_init_tag(), cols, _make_integer_sequence<int, Cols>())\n"
+        "    {\n"
+        "    }\n"
+        "    inline explicit WSLMatrix(T val) constant\n"
+        "        : WSLMatrix(val, _make_integer_sequence<int, Cols>())\n"
+        "    {\n"
+        "    }\n"
+        "    template <typename... U>\n"
+        "    inline explicit WSLMatrix(U... vals) constant\n"
+        "        : WSLMatrix(conditional_t<sizeof...(U) == Cols, cols_all_tag, elems_all_tag>(), vals...)\n"
+        "    {\n"
+        "    }\n"
+        "    inline WSLMatrix(const thread WSLMatrix<T, Cols, Rows> &that) thread = default;\n"
+        "    template <typename U>\n"
+        "    inline explicit WSLMatrix(const thread WSLMatrix<U, Cols, Rows> &that) thread\n"
+        "        : WSLMatrix(that, _make_integer_sequence<int, Cols>())\n"
+        "    {\n"
+        "    }\n"
+        "    inline WSLMatrix(const device WSLMatrix<T, Cols, Rows> &that) thread = default;\n"
+        "    template <typename U>\n"
+        "    inline explicit WSLMatrix(const device WSLMatrix<U, Cols, Rows> &that) thread\n"
+        "        : WSLMatrix(that, _make_integer_sequence<int, Cols>())\n"
+        "    {\n"
+        "    }\n"
+        "    inline WSLMatrix(const constant WSLMatrix<T, Cols, Rows> &that) thread = default;\n"
+        "    template <typename U>\n"
+        "    inline explicit WSLMatrix(const constant WSLMatrix<U, Cols, Rows> &that) thread\n"
+        "        : WSLMatrix(that, _make_integer_sequence<int, Cols>())\n"
+        "    {\n"
+        "    }\n"
+        "    inline WSLMatrix(const threadgroup WSLMatrix<T, Cols, Rows> &that) thread = default;\n"
+        "    template <typename U>\n"
+        "    inline explicit WSLMatrix(const threadgroup WSLMatrix<U, Cols, Rows> &that) thread\n"
+        "        : WSLMatrix(that, _make_integer_sequence<int, Cols>())\n"
+        "    {\n"
+        "    }\n"
+        "    inline WSLMatrix(const thread WSLMatrix<T, Cols, Rows> &that) constant = default;\n"
+        "    template <typename U>\n"
+        "    inline explicit WSLMatrix(const thread WSLMatrix<U, Cols, Rows> &that) constant\n"
+        "        : WSLMatrix(that, _make_integer_sequence<int, Cols>())\n"
+        "    {\n"
+        "    }\n"
+        "    inline WSLMatrix(const device WSLMatrix<T, Cols, Rows> &that) constant = default;\n"
+        "    template <typename U>\n"
+        "    inline explicit WSLMatrix(const device WSLMatrix<U, Cols, Rows> &that) constant\n"
+        "        : WSLMatrix(that, _make_integer_sequence<int, Cols>())\n"
+        "    {\n"
+        "    }\n"
+        "    inline WSLMatrix(const constant WSLMatrix<T, Cols, Rows> &that) constant = default;\n"
+        "    template <typename U>\n"
+        "    inline explicit WSLMatrix(const constant WSLMatrix<U, Cols, Rows> &that) constant\n"
+        "        : WSLMatrix(that, _make_integer_sequence<int, Cols>())\n"
+        "    {\n"
+        "    }\n"
+        "    inline WSLMatrix(const threadgroup WSLMatrix<T, Cols, Rows> &that) constant = default;\n"
+        "    template <typename U>\n"
+        "    inline explicit WSLMatrix(const threadgroup WSLMatrix<U, Cols, Rows> &that) constant\n"
+        "        : WSLMatrix(that, _make_integer_sequence<int, Cols>())\n"
+        "    {\n"
+        "    }\n"
+        "    public:\n"
+        "    inline thread vec<T, Rows> &operator[](int r) thread\n"
+        "    {\n"
+        "        return columns[r];\n"
+        "    }\n"
+        "    inline device vec<T, Rows> &operator[](int r) device\n"
+        "    {\n"
+        "        return columns[r];\n"
+        "    }\n"
+        "    inline threadgroup vec<T, Rows> &operator[](int r) threadgroup\n"
+        "    {\n"
+        "        return columns[r];\n"
+        "    }\n"
+        "    inline const thread vec<T, Rows> &operator[](int r) const thread\n"
+        "    {\n"
+        "        return columns[r];\n"
+        "    }\n"
+        "    inline const device vec<T, Rows> &operator[](int r) const device\n"
+        "    {\n"
+        "        return columns[r];\n"
+        "    }\n"
+        "    inline const constant vec<T, Rows> &operator[](int r) const constant\n"
+        "    {\n"
+        "        return columns[r];\n"
+        "    }\n"
+        "    inline const threadgroup vec<T, Rows> &operator[](int r) const threadgroup\n"
+        "    {\n"
+        "        return columns[r];\n"
+        "    }\n"
+        "};\n"
+
+
     };
+
 }
 
 static void dumpMetalCodeIfNeeded(StringBuilder& stringBuilder)
@@ -67,7 +231,7 @@ static void dumpMetalCodeIfNeeded(StringBuilder& stringBuilder)
 RenderMetalCode generateMetalCode(Program& program, MatchedRenderSemantics&& matchedSemantics, Layout& layout)
 {
     StringBuilder stringBuilder;
-    stringBuilder.append(metalCodeProlog());
+    stringBuilder.append(metalCodePrologue());
 
     TypeNamer typeNamer(program);
     typeNamer.emitMetalTypes(stringBuilder);
@@ -82,7 +246,7 @@ RenderMetalCode generateMetalCode(Program& program, MatchedRenderSemantics&& mat
 ComputeMetalCode generateMetalCode(Program& program, MatchedComputeSemantics&& matchedSemantics, Layout& layout)
 {
     StringBuilder stringBuilder;
-    stringBuilder.append(metalCodeProlog());
+    stringBuilder.append(metalCodePrologue());
 
     TypeNamer typeNamer(program);
     typeNamer.emitMetalTypes(stringBuilder);
index 07ef65b..e7b121a 100644 (file)
@@ -95,16 +95,6 @@ static int vectorLength(AST::NativeTypeDeclaration& nativeTypeDeclaration)
     return vectorLength;
 }
 
-static AST::NamedType& vectorInnerType(AST::NativeTypeDeclaration& nativeTypeDeclaration)
-{
-    if (nativeTypeDeclaration.typeArguments().isEmpty())
-        return nativeTypeDeclaration;
-
-    ASSERT(nativeTypeDeclaration.typeArguments().size() == 2);
-    ASSERT(WTF::holds_alternative<Ref<AST::TypeReference>>(nativeTypeDeclaration.typeArguments()[0]));
-    return WTF::get<Ref<AST::TypeReference>>(nativeTypeDeclaration.typeArguments()[0])->resolvedType();
-}
-
 static const char* vectorSuffix(int vectorLength)
 {
     switch (vectorLength) {
@@ -120,7 +110,7 @@ static const char* vectorSuffix(int vectorLength)
     }
 }
 
-void inlineNativeFunction(StringBuilder& stringBuilder, AST::NativeFunctionDeclaration& nativeFunctionDeclaration, MangledVariableName returnName, const Vector<MangledVariableName>& args, Intrinsics& intrinsics, TypeNamer& typeNamer, std::function<MangledVariableName()>&& generateNextVariableName, Indentation<4> indent)
+void inlineNativeFunction(StringBuilder& stringBuilder, AST::NativeFunctionDeclaration& nativeFunctionDeclaration, const Vector<MangledVariableName>& args, MangledVariableName resultName, TypeNamer& typeNamer)
 {
     auto asMatrixType = [&] (AST::UnnamedType& unnamedType) -> AST::NativeTypeDeclaration* {
         auto& realType = unnamedType.unifyNode();
@@ -139,333 +129,76 @@ void inlineNativeFunction(StringBuilder& stringBuilder, AST::NativeFunctionDecla
         auto metalReturnTypeName = typeNamer.mangledNameForType(returnType);
 
         if (!nativeFunctionDeclaration.parameters().size()) {
-            stringBuilder.append(indent, returnName, " = { };\n");
+            stringBuilder.append(metalReturnTypeName, " { }");
             return;
         }
 
         if (nativeFunctionDeclaration.parameters().size() == 1) {
             auto& parameterType = *nativeFunctionDeclaration.parameters()[0]->type();
-            auto metalParameterTypeName = typeNamer.mangledNameForType(parameterType);
 
             auto isEnumerationDefinition = [] (auto& type) {
                 return is<AST::NamedType>(type) && is<AST::EnumerationDefinition>(downcast<AST::NamedType>(type));
             };
             auto& unifiedReturnType = returnType.unifyNode();
             if (isEnumerationDefinition(unifiedReturnType) && !isEnumerationDefinition(parameterType.unifyNode())) {
-                auto variableName = generateNextVariableName();
-                stringBuilder.append(indent, metalParameterTypeName, ' ', variableName, " = ", args[0], ";\n");
                 auto& enumerationDefinition = downcast<AST::EnumerationDefinition>(downcast<AST::NamedType>(unifiedReturnType));
-                stringBuilder.append(indent, "switch (", variableName, ") {\n");
-                {
-                    IndentationScope switchScope(indent);
-                    bool hasZeroCase = false;
-                    for (auto& member : enumerationDefinition.enumerationMembers()) {
-                        hasZeroCase |= !member.get().value();
-                        stringBuilder.append(
-                            indent, "case ", member.get().value(), ":\n",
-                            indent, "    break;\n");
-                    }
-                    ASSERT_UNUSED(hasZeroCase, hasZeroCase);
-                    stringBuilder.append(
-                        indent, "default:\n",
-                        indent, "    ", variableName, " = 0;\n",
-                        indent, "    break;\n",
-                        indent, "}\n");
+                stringBuilder.append("static_cast<", metalReturnTypeName, ">((");
+                bool loopedOnce = false;
+                bool hasZeroCase = false;
+                for (auto& member : enumerationDefinition.enumerationMembers()) {
+                    if (loopedOnce)
+                        stringBuilder.append(" || ");
+                    hasZeroCase |= !member.get().value();
+                    stringBuilder.append(args[0], " == ", member.get().value());
+                    loopedOnce = true;
                 }
-                stringBuilder.append(indent, returnName, " = static_cast<", metalReturnTypeName, ">(", variableName, ");\n");
+                ASSERT_UNUSED(hasZeroCase, hasZeroCase);
+
+                stringBuilder.append(") ? ", args[0], " : 0)");
             } else
-                stringBuilder.append(indent, returnName, " = static_cast<", metalReturnTypeName, ">(", args[0], ");\n");
+                stringBuilder.append("static_cast<", metalReturnTypeName, ">(", args[0], ")");
 
             return;
         }
 
         if (auto* matrixType = asMatrixType(returnType)) {
-            unsigned numRows = matrixType->numberOfMatrixRows();
-            unsigned numColumns = matrixType->numberOfMatrixColumns();
-            RELEASE_ASSERT(nativeFunctionDeclaration.parameters().size() == numRows || nativeFunctionDeclaration.parameters().size() == numRows * numColumns);
-
-            auto variableName = generateNextVariableName();
-
-            stringBuilder.append(indent, metalReturnTypeName, ' ', variableName, ";\n");
-
-            // We need to abide by the memory layout we use for matrices here.
-            if (nativeFunctionDeclaration.parameters().size() == numRows) {
-                // operator matrixMxN (vectorN, ..., vectorN)
-                for (unsigned i = 0; i < numRows; ++i) {
-                    for (unsigned j = 0; j < numColumns; ++j)
-                        stringBuilder.append(indent, variableName, "[", j * numRows + i, "] = ", args[i], "[", j, "];\n");
-                }
-            } else {
-                // operator matrixMxN (scalar, ..., scalar)
-                unsigned index = 0;
-                for (unsigned i = 0; i < numRows; ++i) {
-                    for (unsigned j = 0; j < numColumns; ++j) {
-                        stringBuilder.append(indent, variableName, '[', j * numRows + i, "] = ", args[index], ";\n");
-                        ++index;
-                    }
-                }
+            stringBuilder.append(metalReturnTypeName, '(');
+            for (size_t i = 0; i < args.size(); ++i) {
+                if (i)
+                    stringBuilder.append(", ");
+                stringBuilder.append(args[i]);
             }
-
-            stringBuilder.append(indent, returnName, " = ", variableName, ";\n");
+            stringBuilder.append(')');
             return;
         }
 
-        stringBuilder.append(indent, returnName, " = ", metalReturnTypeName, "(");
+        stringBuilder.append(metalReturnTypeName, '(');
         for (unsigned i = 0; i < nativeFunctionDeclaration.parameters().size(); ++i) {
-            if (i > 0)
+            if (i)
                 stringBuilder.append(", ");
             stringBuilder.append(args[i]);
         }
-        stringBuilder.append(");\n");
-        return;
-    }
-
-    // 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& parameterType = nativeFunctionDeclaration.parameters()[0]->type()->unifyNode();
-        auto& unnamedParameterType = downcast<AST::UnnamedType>(parameterType);
-        if (is<AST::ArrayType>(unnamedParameterType)) {
-            auto& arrayParameterType = downcast<AST::ArrayType>(unnamedParameterType);
-            stringBuilder.append(
-                indent, returnName, " = ", arrayParameterType.numElements(), ";\n");
-            return;
-        }
-
-        ASSERT(is<AST::ArrayReferenceType>(unnamedParameterType));
-        stringBuilder.append(
-            indent, returnName, " = ", args[0], ".length;\n");
-        return;
-    }
-
-    if (nativeFunctionDeclaration.name().startsWith("operator."_str)) {
-        auto appendMangledFieldName = [&] (const String& fieldName) {
-            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);
-                stringBuilder.append(typeNamer.mangledNameForStructureElement(*structureElement));
-                return;
-            }
-            ASSERT(is<AST::NativeTypeDeclaration>(namedType));
-            stringBuilder.append(fieldName);
-        };
-
-        if (nativeFunctionDeclaration.name().endsWith("=")) {
-            ASSERT(nativeFunctionDeclaration.parameters().size() == 2);
-            auto fieldName = nativeFunctionDeclaration.name().substring("operator."_str.length());
-            fieldName = fieldName.substring(0, fieldName.length() - 1);
-
-            stringBuilder.append(
-                indent, returnName, " = ", args[0], ";\n",
-                indent, returnName, '.');
-            appendMangledFieldName(fieldName);
-            stringBuilder.append(" = ", args[1], ";\n");
-
-            return;
-        }
-
-        ASSERT(nativeFunctionDeclaration.parameters().size() == 1);
-        auto fieldName = nativeFunctionDeclaration.name().substring("operator."_str.length());
-        stringBuilder.append(
-            indent, returnName, " = ", args[0], '.');
-        appendMangledFieldName(fieldName);
-        stringBuilder.append(";\n");
-        return;
-    }
-
-    if (nativeFunctionDeclaration.name().startsWith("operator&."_str)) {
-        ASSERT(nativeFunctionDeclaration.parameters().size() == 1);
-        auto fieldName = nativeFunctionDeclaration.name().substring("operator&."_str.length());
-
-        stringBuilder.append(
-            indent, returnName, " = ", args[0], " ? &(", args[0], "->");
-
-        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);
-            stringBuilder.append(typeNamer.mangledNameForStructureElement(*structureElement));
-        } else
-            stringBuilder.append(fieldName);
-
-        stringBuilder.append(") : nullptr;\n");
-
-        return;
-    }
-
-    if (nativeFunctionDeclaration.name() == "operator&[]") {
-        ASSERT(nativeFunctionDeclaration.parameters().size() == 2);
-        ASSERT(is<AST::ArrayReferenceType>(*nativeFunctionDeclaration.parameters()[0]->type()));
-
-        stringBuilder.append(
-            indent, returnName, " = (", args[1], " < ", args[0], ".length) ? ", " &(", args[0], ".pointer[", args[1], "]) : nullptr;\n");
-            
-        return;
-    }
-
-    auto vectorSize = [&] () -> unsigned {
-        auto& typeReference = downcast<AST::TypeReference>(*nativeFunctionDeclaration.parameters()[0]->type());
-        auto& vectorType = downcast<AST::NativeTypeDeclaration>(downcast<AST::TypeReference>(downcast<AST::TypeDefinition>(typeReference.resolvedType()).type()).resolvedType());
-        ASSERT(vectorType.name() == "vector");
-        ASSERT(vectorType.typeArguments().size() == 2);
-        return WTF::get<AST::ConstantExpression>(vectorType.typeArguments()[1]).integerLiteral().value();
-    };
-
-    auto getMatrixType = [&] () -> AST::NativeTypeDeclaration& {
-        auto& typeReference = downcast<AST::TypeReference>(*nativeFunctionDeclaration.parameters()[0]->type());
-        auto& result = downcast<AST::NativeTypeDeclaration>(downcast<AST::TypeReference>(downcast<AST::TypeDefinition>(typeReference.resolvedType()).type()).resolvedType());
-        ASSERT(result.isMatrix());
-        return result;
-    };
-
-    if (nativeFunctionDeclaration.name() == "operator[]") {
-        ASSERT(nativeFunctionDeclaration.parameters().size() == 2);
-        auto& typeReference = downcast<AST::TypeReference>(*nativeFunctionDeclaration.parameters()[0]->type());
-        size_t numTypeArguments = downcast<AST::NativeTypeDeclaration>(downcast<AST::TypeReference>(downcast<AST::TypeDefinition>(typeReference.resolvedType()).type()).resolvedType()).typeArguments().size();
-        if (numTypeArguments == 3) {
-            auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
-
-            unsigned numberOfRows = getMatrixType().numberOfMatrixRows();
-            unsigned numberOfColumns = getMatrixType().numberOfMatrixColumns();
-            
-            stringBuilder.append(indent, "do {\n");
-            {
-                IndentationScope scope(indent);
-
-                stringBuilder.append(
-                    indent, metalReturnName, " result;\n",
-                    indent, "if (", args[1], " >= ", numberOfRows, ") {\n",
-                    indent, "    ", returnName, " = ", metalReturnName, "(0);\n",
-                    indent, "    break;\n",
-                    indent, "}\n",
-                    indent, "result[0] = ", args[0], '[', args[1], "];\n",
-                    indent, "result[1] = ", args[0], '[', args[1], " + ", numberOfRows, "];\n");
-
-                if (numberOfColumns >= 3)
-                    stringBuilder.append(indent, "result[2] = ", args[0], '[', args[1], " + ", numberOfRows * 2, "];\n");
-                if (numberOfColumns >= 4)
-                    stringBuilder.append(indent, "result[3] = ", args[0], '[', args[1], " + ", numberOfRows * 3, "];\n");
-    
-                stringBuilder.append(indent, returnName, " = result;\n");
-            }
-            stringBuilder.append("} while (0);\n");
-        } else {
-            RELEASE_ASSERT(numTypeArguments == 2);
-            unsigned numElements = vectorSize();
-
-            auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
-
-            stringBuilder.append(indent, "do {\n");
-            {
-                IndentationScope scope(indent);
-                stringBuilder.append(
-                    indent, metalReturnName, " result;\n",
-                    indent, "if (", args[1], " >= ", numElements, ") {\n",
-                    indent, "    ", returnName, " = ", metalReturnName, "(0);\n",
-                    indent, "    break;\n",
-                    indent, "}\n",
-                    indent, "result = ", args[0], "[", args[1], "];\n",
-                    indent, returnName, " = result;\n");
-            }
-            stringBuilder.append(indent, "} while (0);\n");
-        }
-
-        return;
-    }
-
-    if (nativeFunctionDeclaration.name() == "operator[]=") {
-        auto& typeReference = downcast<AST::TypeReference>(*nativeFunctionDeclaration.parameters()[0]->type());
-        size_t numTypeArguments = downcast<AST::NativeTypeDeclaration>(downcast<AST::TypeReference>(downcast<AST::TypeDefinition>(typeReference.resolvedType()).type()).resolvedType()).typeArguments().size();
-        if (numTypeArguments == 3) {
-            ASSERT(nativeFunctionDeclaration.parameters().size() == 3);
-            auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type());
-            auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
-
-            unsigned numberOfRows = getMatrixType().numberOfMatrixRows();
-            unsigned numberOfColumns = getMatrixType().numberOfMatrixColumns();
-
-            stringBuilder.append(indent, "do {\n");
-            {
-                IndentationScope scope(indent);
-
-                stringBuilder.append(
-                    indent, metalReturnName, " m = ", args[0], ";\n",
-                    indent, metalParameter2Name, " i = ", args[1], ";\n",
-                    indent, "if (i >= ", numberOfRows, ") {\n",
-                    indent, "    ", returnName, " = m;\n",
-                    indent, "    break;\n",
-                    indent, "}\n",
-                    indent, "m[i] = ", args[2], "[0];\n",
-                    indent, "m[i + ", numberOfRows, "] = ", args[2], "[1];\n");
-                if (numberOfColumns >= 3)
-                    stringBuilder.append(indent, "m[i + ", numberOfRows * 2, "] = ", args[2], "[2];\n");
-                if (numberOfColumns >= 4)
-                    stringBuilder.append(indent, "m[i + ", numberOfRows * 3, "] = ", args[2], "[3];\n");
-                stringBuilder.append(indent, returnName, " = m;\n");
-            }
-            
-            stringBuilder.append(indent, "} while(0);\n");
-        } else {
-            RELEASE_ASSERT(numTypeArguments == 2);
-
-            ASSERT(nativeFunctionDeclaration.parameters().size() == 3);
-            auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type());
-            auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
-
-            unsigned numElements = vectorSize();
-
-            stringBuilder.append(indent, "do {\n");
-            {
-                IndentationScope scope(indent);
-
-                stringBuilder.append(
-                    indent, metalReturnName, " v = ", args[0], ";\n",
-                    indent, metalParameter2Name, " i = ", args[1], ";\n",
-                    indent, "if (i >= ", numElements, ") {\n",
-                    indent, "    ", returnName, " = v;\n",
-                    indent, "    break;\n",
-                    indent, "}\n",
-                    indent, "v[i] = ", args[2], ";\n",
-                    indent, returnName, " = v;\n");
-            }
-            stringBuilder.append(indent, "} while(0);\n");
-        }
-
+        stringBuilder.append(')');
         return;
     }
 
     if (nativeFunctionDeclaration.isOperator()) {
         auto operatorName = nativeFunctionDeclaration.name().substring("operator"_str.length());
-        auto metalReturnType = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
+
         if (nativeFunctionDeclaration.parameters().size() == 1) {
+            // This is ok to do since the args to this function are all temps.
+            // So things like ++ and -- are ok to do.
+
             if (auto* matrixType = asMatrixType(nativeFunctionDeclaration.type())) {
-                stringBuilder.append(indent, "{\n");
-                {
-                    IndentationScope scope(indent);
-                    stringBuilder.append(
-                        indent, metalReturnType, " x = ", args[0], ";\n",
-                        indent, "for (size_t i = 0; i < x.size(); ++i)\n",
-                        indent, "    x[i] = ", operatorName, "x[i];\n",
-                        indent, returnName, " = x;\n");
+                stringBuilder.append('(');
+                for (unsigned i = 0; i < matrixType->numberOfMatrixColumns(); ++i) {
+                    if (i)
+                        stringBuilder.append(", ");
+                    stringBuilder.append(resultName, '[', i, "] = ", operatorName, args[0], '[', i, ']');
                 }
-                stringBuilder.append(indent, "}\n");
-            } else {
-                stringBuilder.append(indent, "{\n");
-                {
-                    IndentationScope scope(indent);
-                    stringBuilder.append(
-                        indent, metalReturnType, " x = ", args[0], ";\n",
-                        indent, returnName, " = ", operatorName, "x;\n");
-                }
-                stringBuilder.append(indent, "}\n");
-            }
+                stringBuilder.append(", ", resultName, ')');
+            } else
+                stringBuilder.append(operatorName, args[0]);
             return;
         }
 
@@ -473,49 +206,40 @@ void inlineNativeFunction(StringBuilder& stringBuilder, AST::NativeFunctionDecla
         if (auto* leftMatrix = asMatrixType(*nativeFunctionDeclaration.parameters()[0]->type())) {
             if (auto* rightMatrix = asMatrixType(*nativeFunctionDeclaration.parameters()[1]->type())) {
                 // matrix <op> matrix
-                stringBuilder.append(indent, "{\n");
-                {
-                    IndentationScope scope(indent);
-                    stringBuilder.append(
-                        indent, metalReturnType, " x;\n",
-                        indent, "for (size_t i = 0; i < x.size(); ++i)\n",
-                        indent, "    x[i] = ", args[0], "[i] ", operatorName, ' ', args[1], "[i];\n",
-                        indent, returnName, " = x;\n");
+                stringBuilder.append('(');
+                for (unsigned i = 0; i < leftMatrix->numberOfMatrixColumns(); ++i) {
+                    if (i)
+                        stringBuilder.append(", ");
+                    stringBuilder.append(resultName, '[', i, "] = ", args[0], '[', i, "] ", operatorName, ' ', args[1], '[', i, ']');
                 }
-                stringBuilder.append(indent, "}\n");
+                stringBuilder.append(", ", resultName, ')');
             } else {
                 // matrix <op> scalar
-                stringBuilder.append(indent, "{\n");
-                {
-                    IndentationScope scope(indent);
-                    stringBuilder.append(
-                        indent, metalReturnType, " x;\n",
-                        indent, "for (size_t i = 0; i < x.size(); ++i)\n",
-                        indent, "    x[i] = ", args[0], "[i] ", operatorName, ' ', args[1], ";\n",
-                        indent, returnName, " = x;\n");
+                stringBuilder.append('(');
+                for (unsigned i = 0; i < leftMatrix->numberOfMatrixColumns(); ++i) {
+                    if (i)
+                        stringBuilder.append(", ");
+                    stringBuilder.append(resultName, '[', i, "] = ", args[0], '[', i, "] ", operatorName, ' ', args[1]);
                 }
-                stringBuilder.append(indent, "}\n");
+                stringBuilder.append(", ", resultName, ')');
             }
         } else if (auto* rightMatrix = asMatrixType(*nativeFunctionDeclaration.parameters()[1]->type())) {
             ASSERT(!asMatrixType(*nativeFunctionDeclaration.parameters()[0]->type()));
             // scalar <op> matrix
-            stringBuilder.append(indent, "{\n");
-            {
-                IndentationScope scope(indent);
-                stringBuilder.append(
-                    indent, metalReturnType, " x;\n",
-                    indent, "for (size_t i = 0; i < x.size(); ++i)\n",
-                    indent, "    x[i] = ", args[0], ' ', operatorName, ' ', args[1], "[i];\n",
-                    indent, returnName, " = x;\n");
+            stringBuilder.append('(');
+            for (unsigned i = 0; i < rightMatrix->numberOfMatrixColumns(); ++i) {
+                if (i)
+                    stringBuilder.append(", ");
+                stringBuilder.append(resultName, '[', i, "] = ", args[0], ' ', operatorName, ' ', args[1], '[', i, ']');
             }
-            stringBuilder.append(indent, "}\n");
+            stringBuilder.append(", ", resultName, ')');
         } else {
             // scalar <op> scalar
             // vector <op> vector
             // vector <op> scalar
             // scalar <op> vector
             stringBuilder.append(
-                indent, returnName, " = ", args[0], ' ', operatorName, ' ', args[1], ";\n");
+                '(', args[0], ' ', operatorName, ' ', args[1], ')');
         }
 
         return;
@@ -548,35 +272,36 @@ void inlineNativeFunction(StringBuilder& stringBuilder, AST::NativeFunctionDecla
         || nativeFunctionDeclaration.name() == "length") {
         ASSERT(nativeFunctionDeclaration.parameters().size() == 1);
         stringBuilder.append(
-            indent, returnName, " = ", mapFunctionName(nativeFunctionDeclaration.name()), '(', args[0], ");\n");
+            mapFunctionName(nativeFunctionDeclaration.name()), '(', args[0], ')');
         return;
     }
 
     if (nativeFunctionDeclaration.name() == "pow" || nativeFunctionDeclaration.name() == "atan2") {
         ASSERT(nativeFunctionDeclaration.parameters().size() == 2);
         stringBuilder.append(
-            indent, returnName, " = ", nativeFunctionDeclaration.name(), "(", args[0], ", ", args[1], ");\n");
+            nativeFunctionDeclaration.name(), '(', args[0], ", ", args[1], ')');
         return;
     }
 
     if (nativeFunctionDeclaration.name() == "clamp") {
         ASSERT(nativeFunctionDeclaration.parameters().size() == 3);
-        if (asMatrixType(nativeFunctionDeclaration.type())) {
-            auto metalReturnType = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
-            
-            stringBuilder.append(indent, "{\n");
-            {
-                IndentationScope scope(indent);
-                stringBuilder.append(
-                    indent, metalReturnType, " x;\n",
-                    indent, "for (size_t i = 0; i < x.size(); ++i) \n",
-                    indent, "    x[i] = clamp(", args[0], "[i], ", args[1], "[i], ", args[2], "[i]);",
-                    indent, returnName, " = x;\n");
+
+        if (auto* matrixType = asMatrixType(nativeFunctionDeclaration.type())) {
+            stringBuilder.append('(');
+            bool ranOnce = false;
+            for (unsigned i = 0; i < matrixType->numberOfMatrixColumns(); ++i) {
+                for (unsigned j = 0; j < matrixType->numberOfMatrixRows(); ++j) {
+                    if (ranOnce)
+                        stringBuilder.append(", ");
+                    ranOnce = true;
+                    stringBuilder.append(
+                        resultName, '[', i, "][", j, "] = clamp(", args[0], '[', i, "][", j, "], ", args[1], '[', i, "][", j, "], ", args[2], '[', i, "][", j, "])");
+                }
             }
-            stringBuilder.append(indent, "}\n");
+            stringBuilder.append(", ", resultName, ")");
         } else {
             stringBuilder.append(
-                indent, returnName, " = clamp(", args[0], ", ", args[1], ", ", args[2], ");\n");
+                "clamp(", args[0], ", ", args[1], ", ", args[2], ')');
         }
         return;
     }
@@ -584,23 +309,21 @@ void inlineNativeFunction(StringBuilder& stringBuilder, AST::NativeFunctionDecla
     if (nativeFunctionDeclaration.name() == "AllMemoryBarrierWithGroupSync") {
         ASSERT(!nativeFunctionDeclaration.parameters().size());
         stringBuilder.append(
-            indent, "threadgroup_barrier(mem_flags::mem_device);\n",
-            indent, "threadgroup_barrier(mem_flags::mem_threadgroup);\n",
-            indent, "threadgroup_barrier(mem_flags::mem_texture);\n");
+            "(threadgroup_barrier(mem_flags::mem_device), threadgroup_barrier(mem_flags::mem_threadgroup), threadgroup_barrier(mem_flags::mem_texture))");
         return;
     }
 
     if (nativeFunctionDeclaration.name() == "DeviceMemoryBarrierWithGroupSync") {
         ASSERT(!nativeFunctionDeclaration.parameters().size());
         stringBuilder.append(
-            indent, "threadgroup_barrier(mem_flags::mem_device);\n");
+            "threadgroup_barrier(mem_flags::mem_device)");
         return;
     }
 
     if (nativeFunctionDeclaration.name() == "GroupMemoryBarrierWithGroupSync") {
         ASSERT(!nativeFunctionDeclaration.parameters().size());
         stringBuilder.append(
-            indent, "threadgroup_barrier(mem_flags::mem_threadgroup);\n");
+            "threadgroup_barrier(mem_flags::mem_threadgroup)");
         return;
     }
 
@@ -608,15 +331,15 @@ void inlineNativeFunction(StringBuilder& stringBuilder, AST::NativeFunctionDecla
         if (nativeFunctionDeclaration.name() == "InterlockedCompareExchange") {
             ASSERT(nativeFunctionDeclaration.parameters().size() == 4);
             stringBuilder.append(
-                indent, "atomic_compare_exchange_weak_explicit(", args[0], ", &", args[1], ", ", args[2], ", memory_order_relaxed, memory_order_relaxed);\n",
-                indent, '*', args[3], " = ", args[1], ";\n");
+                "(atomic_compare_exchange_weak_explicit(", args[0], ", &", args[1], ", ", args[2], ", memory_order_relaxed, memory_order_relaxed), ",
+                '*', args[3], " = ", args[1], ')');
             return;
         }
 
         ASSERT(nativeFunctionDeclaration.parameters().size() == 3);
         auto name = atomicName(nativeFunctionDeclaration.name().substring("Interlocked"_str.length()));
         stringBuilder.append(
-            indent, '*', args[2], " = atomic_", name, "_explicit(", args[0], ", ", args[1], ", memory_order_relaxed);\n");
+            '*', args[2], " = atomic_", name, "_explicit(", args[0], ", ", args[1], ", memory_order_relaxed)");
         return;
     }
 
@@ -630,7 +353,7 @@ void inlineNativeFunction(StringBuilder& stringBuilder, AST::NativeFunctionDecla
         auto returnVectorLength = vectorLength(returnType);
 
         stringBuilder.append(
-            indent, returnName, " = ", args[0], ".sample(", args[1], ", ");
+            args[0], ".sample(", args[1], ", ");
 
         if (textureType.isTextureArray()) {
             ASSERT(locationVectorLength > 1);
@@ -642,81 +365,66 @@ void inlineNativeFunction(StringBuilder& stringBuilder, AST::NativeFunctionDecla
         stringBuilder.append(")");
         if (!textureType.isDepthTexture())
             stringBuilder.append(".", "xyzw"_str.substring(0, returnVectorLength));
-        stringBuilder.append(";\n");
 
         return;
     }
 
     if (nativeFunctionDeclaration.name() == "Load") {
         ASSERT(nativeFunctionDeclaration.parameters().size() == 2);
-        
+
         auto& textureType = downcast<AST::NativeTypeDeclaration>(downcast<AST::NamedType>(nativeFunctionDeclaration.parameters()[0]->type()->unifyNode()));
         auto& locationType = downcast<AST::NativeTypeDeclaration>(downcast<AST::NamedType>(nativeFunctionDeclaration.parameters()[1]->type()->unifyNode()));
         auto locationVectorLength = vectorLength(locationType);
         auto& returnType = downcast<AST::NativeTypeDeclaration>(downcast<AST::NamedType>(nativeFunctionDeclaration.type().unifyNode()));
         auto returnVectorLength = vectorLength(returnType);
+        auto locationTypeName = typeNamer.mangledNameForType(locationType);
 
-        auto metalReturnName = typeNamer.mangledNameForType(returnType);
-
-        stringBuilder.append(indent, "do {\n");
-        {
-            IndentationScope scope(indent);
+        stringBuilder.append('(', args[1], " = ");
+        if (textureType.isTextureArray()) {
+            ASSERT(locationVectorLength > 1);
+            stringBuilder.append("clamp(", args[1], ", ", locationTypeName, '(');
+            for (int i = 0; i < locationVectorLength; ++i) {
+                if (i)
+                    stringBuilder.append(", ");
+                stringBuilder.append('0');
+            }
+            stringBuilder.append("), ", locationTypeName, '(');
 
-            if (textureType.isTextureArray()) {
-                ASSERT(locationVectorLength > 1);
-                String dimensions[] = { "width"_str, "height"_str, "depth"_str };
-                for (int i = 0; i < locationVectorLength - 1; ++i) {
-                    auto suffix = "xyzw"_str.substring(i, 1);
-                    stringBuilder.append(
-                        indent, "if (", args[1], '.', suffix, " < 0 || static_cast<uint32_t>(", args[1], '.', suffix, ") >= ", args[0], ".get_", dimensions[i], "()) {\n",
-                        indent, "    ", returnName, " = ", metalReturnName, "(0);\n",
-                        indent, "    break;\n",
-                        indent, "}\n");
-                }
-                auto suffix = "xyzw"_str.substring(locationVectorLength - 1, 1);
+            String dimensions[] = { "width"_str, "height"_str, "depth"_str };
+            for (int i = 0; i < locationVectorLength - 1; ++i) {
+                if (i)
+                    stringBuilder.append(", ");
                 stringBuilder.append(
-                    indent, "if (", args[1], '.', suffix, " < 0 || static_cast<uint32_t>(", args[1], '.', suffix, ") >= ", args[0], ".get_array_size()) {\n",
-                    indent, "    ", returnName, " = ", metalReturnName, "(0);\n",
-                    indent, "    break;\n",
-                    indent, "}\n");
-            } else {
-                if (locationVectorLength == 1) {
-                    stringBuilder.append(
-                        indent, "if (", args[1], " < 0 || static_cast<uint32_t>(", args[1], ") >= ", args[0], ".get_width()) {\n",
-                        indent, "    ", returnName, " = ", metalReturnName, "(0);\n",
-                        indent, "    break;\n",
-                        indent, "}\n");
-                } else {
-                    stringBuilder.append(
-                        indent, "if (", args[1], ".x < 0 || static_cast<uint32_t>(", args[1], ".x) >= ", args[0], ".get_width()) {\n",
-                        indent, "    ", returnName, " = ", metalReturnName, "(0);\n",
-                        indent, "    break;\n",
-                        indent, "}\n",
-                        indent, "if (", args[1], ".y < 0 || static_cast<uint32_t>(", args[1], ".y) >= ", args[0], ".get_height()) {\n",
-                        indent, "    ", returnName, " = ", metalReturnName, "(0);\n",
-                        indent, "    break;\n",
-                        indent, "}\n");
-                    if (locationVectorLength >= 3) {
-                        stringBuilder.append(
-                            indent, "if (", args[1], ".z < 0 || static_cast<uint32_t>(", args[1], ".z) >= ", args[0], ".get_depth()) {\n",
-                            indent, "    ", returnName, " = ", metalReturnName, "(0);\n",
-                            indent, "    break;\n",
-                            indent, "}\n");
-                    }
-                }
+                    args[0], ".get_", dimensions[i], "() - 1");
+            }
+            stringBuilder.append(
+                args[0], ".get_array_size() - 1))");
+        } else {
+            if (locationVectorLength == 1)
+                stringBuilder.append("clamp(", args[1], ", 0, ", args[0], ".get_width() - 1)");
+            else {
+                stringBuilder.append("clamp(", args[1], ", ", locationTypeName, "(0, 0");
+                if (locationVectorLength >= 3)
+                    stringBuilder.append(", 0");
+                stringBuilder.append("), ", locationTypeName, '(', args[0], ".get_width() - 1, ", args[0], ".get_height() - 1");
+                if (locationVectorLength >= 3)
+                    stringBuilder.append(", ", args[0], ".get_depth() - 1");
+                stringBuilder.append("))");
             }
-            stringBuilder.append(indent, returnName, " = ", args[0], ".read(");
-            if (textureType.isTextureArray()) {
-                ASSERT(locationVectorLength > 1);
-                stringBuilder.append("uint", vectorSuffix(locationVectorLength - 1), '(', args[1], '.', "xyzw"_str.substring(0, locationVectorLength - 1), "), uint(", args[1], '.', "xyzw"_str.substring(locationVectorLength - 1, 1), ')');
-            } else
-                stringBuilder.append("uint", vectorSuffix(locationVectorLength), '(', args[1], ')');
-            stringBuilder.append(')');
-            if (!textureType.isDepthTexture())
-                stringBuilder.append('.', "xyzw"_str.substring(0, returnVectorLength));
-            stringBuilder.append(";\n");
         }
-        stringBuilder.append(indent, "} while(0);\n");
+
+        stringBuilder.append(", ", args[0], ".read(");
+
+        if (textureType.isTextureArray()) {
+            ASSERT(locationVectorLength > 1);
+            stringBuilder.append("uint", vectorSuffix(locationVectorLength - 1), '(', args[1], '.', "xyzw"_str.substring(0, locationVectorLength - 1), "), uint(", args[1], '.', "xyzw"_str.substring(locationVectorLength - 1, 1), ')');
+        } else
+            stringBuilder.append("uint", vectorSuffix(locationVectorLength), '(', args[1], ')');
+        stringBuilder.append(')');
+        if (!textureType.isDepthTexture())
+            stringBuilder.append('.', "xyzw"_str.substring(0, returnVectorLength));
+
+        stringBuilder.append(')');
 
         return;
     }
@@ -724,18 +432,20 @@ void inlineNativeFunction(StringBuilder& stringBuilder, AST::NativeFunctionDecla
     if (nativeFunctionDeclaration.name() == "load") {
         ASSERT(nativeFunctionDeclaration.parameters().size() == 1);
         stringBuilder.append(
-            indent, returnName, " = atomic_load_explicit(", args[0], ", memory_order_relaxed);\n");
+            "atomic_load_explicit(", args[0], ", memory_order_relaxed)");
         return;
     }
 
     if (nativeFunctionDeclaration.name() == "store") {
         ASSERT(nativeFunctionDeclaration.parameters().size() == 2);
         stringBuilder.append(
-            indent, "atomic_store_explicit(", args[0], ", ", args[1], ", memory_order_relaxed);\n");
+            "atomic_store_explicit(", args[0], ", ", args[1], ", memory_order_relaxed)");
         return;
     }
 
     if (nativeFunctionDeclaration.name() == "GetDimensions") {
+        stringBuilder.append('(');
+
         auto& textureType = downcast<AST::NativeTypeDeclaration>(downcast<AST::NamedType>(nativeFunctionDeclaration.parameters()[0]->type()->unifyNode()));
 
         size_t index = 1;
@@ -767,38 +477,35 @@ void inlineNativeFunction(StringBuilder& stringBuilder, AST::NativeFunctionDecla
         ASSERT(index == nativeFunctionDeclaration.parameters().size());
 
         stringBuilder.append(
-            indent, "if (", widthName, ")\n",
-            indent, "    *", widthName, " = ", args[0], ".get_width(");
+            '*', widthName, " = ", args[0], ".get_width(");
         if (hasMipLevel)
             stringBuilder.append(args[1]);
-        stringBuilder.append(");\n");
+        stringBuilder.append(')');
 
         if (heightName) {
             stringBuilder.append(
-                indent, "if (", *heightName, ")\n",
-                indent, "    *", *heightName, " = ", args[0], ".get_height(");
+                ", *", *heightName, " = ", args[0], ".get_height(");
             if (hasMipLevel)
                 stringBuilder.append(args[1]);
-            stringBuilder.append(");\n");
+            stringBuilder.append(')');
         }
         if (depthName) {
             stringBuilder.append(
-                indent, "if (", *depthName, ")\n",
-                indent, "    *", *depthName, " = ", args[0], ".get_depth(");
+                ", *", *depthName, " = ", args[0], ".get_depth(");
             if (hasMipLevel)
                 stringBuilder.append(args[1]);
-            stringBuilder.append(");\n");
+            stringBuilder.append(')');
         }
         if (elementsName) {
             stringBuilder.append(
-                indent, "if (", *elementsName, ")\n",
-                indent, "    *", *elementsName, " = ", args[0], ".get_array_size();\n");
+                ", *", *elementsName, " = ", args[0], ".get_array_size()");
         }
         if (numberOfLevelsName) {
             stringBuilder.append(
-                indent, "if (", *numberOfLevelsName, ")\n",
-                indent, "    *", *numberOfLevelsName, " = ", args[0], ".get_num_mip_levels();\n");
+                ", *", *numberOfLevelsName, " = ", args[0], ".get_num_mip_levels()");
         }
+
+        stringBuilder.append(')');
         return;
     }
 
@@ -838,66 +545,8 @@ void inlineNativeFunction(StringBuilder& stringBuilder, AST::NativeFunctionDecla
     }
 
     if (nativeFunctionDeclaration.name() == "Store") {
-        ASSERT(nativeFunctionDeclaration.parameters().size() == 3);
-        
-        auto& textureType = downcast<AST::NativeTypeDeclaration>(downcast<AST::NamedType>(nativeFunctionDeclaration.parameters()[0]->type()->unifyNode()));
-        auto& itemType = downcast<AST::NativeTypeDeclaration>(downcast<AST::NamedType>(nativeFunctionDeclaration.parameters()[1]->type()->unifyNode()));
-        auto& itemVectorInnerType = vectorInnerType(itemType);
-        auto itemVectorLength = vectorLength(itemType);
-        auto& locationType = downcast<AST::NativeTypeDeclaration>(downcast<AST::NamedType>(nativeFunctionDeclaration.parameters()[2]->type()->unifyNode()));
-        auto locationVectorLength = vectorLength(locationType);
-
-        auto metalInnerTypeName = typeNamer.mangledNameForType(itemVectorInnerType);
-
-        stringBuilder.append("do {\n");
-        {
-            IndentationScope scope(indent);
-
-            if (textureType.isTextureArray()) {
-                ASSERT(locationVectorLength > 1);
-                String dimensions[] = { "width"_str, "height"_str, "depth"_str };
-                for (int i = 0; i < locationVectorLength - 1; ++i) {
-                    auto suffix = "xyzw"_str.substring(i, 1);
-                    stringBuilder.append(
-                        indent, "if (", args[2], ".", suffix, " >= ", args[0], ".get_", dimensions[i], "())\n",
-                        indent, "    break;\n");
-                }
-                auto suffix = "xyzw"_str.substring(locationVectorLength - 1, 1);
-                stringBuilder.append(
-                    indent, "if (", args[2], '.', suffix, " >= ", args[0], ".get_array_size())\n",
-                    indent, "    break;\n");
-            } else {
-                if (locationVectorLength == 1) {
-                    stringBuilder.append(
-                        indent, "if (", args[2], " >= ", args[0], ".get_width()) \n",
-                        indent, "    break;\n");
-                } else {
-                    stringBuilder.append(
-                        indent, "if (", args[2], ".x >= ", args[0], ".get_width())\n",
-                        indent, "    break;\n",
-                        indent, "if (", args[2], ".y >= ", args[0], ".get_height())\n",
-                        indent, "    break;\n");
-                    if (locationVectorLength >= 3) {
-                        stringBuilder.append(
-                            indent, "if (", args[2], ".z >= ", args[0], ".get_depth())\n",
-                            indent, "    break;\n");
-                    }
-                }
-            }
-            stringBuilder.append(indent, args[0], ".write(vec<", metalInnerTypeName, ", 4>(", args[1]);
-            for (int i = 0; i < 4 - itemVectorLength; ++i)
-                stringBuilder.append(", 0");
-            stringBuilder.append("), ");
-            if (textureType.isTextureArray()) {
-                ASSERT(locationVectorLength > 1);
-                stringBuilder.append("uint", vectorSuffix(locationVectorLength - 1), '(', args[2], '.', "xyzw"_str.substring(0, locationVectorLength - 1), "), uint(", args[2], ".", "xyzw"_str.substring(locationVectorLength - 1, 1), ')');
-            } else
-                stringBuilder.append("uint", vectorSuffix(locationVectorLength), '(', args[2], ')');
-            stringBuilder.append(");\n");
-        }
-        stringBuilder.append(indent, "} while(0);\n");
-
-        return;
+        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195813 Implement this
+        notImplemented();
     }
 
     if (nativeFunctionDeclaration.name() == "GatherAlpha") {
index 483e90a..982af3d 100644 (file)
@@ -45,7 +45,7 @@ namespace Metal {
 
 class TypeNamer;
 
-void inlineNativeFunction(StringBuilder&, AST::NativeFunctionDeclaration&, MangledVariableName returnName, const Vector<MangledVariableName>& argumentNames, Intrinsics&, TypeNamer&, std::function<MangledVariableName()>&&, Indentation<4>);
+void inlineNativeFunction(StringBuilder&, AST::NativeFunctionDeclaration&, const Vector<MangledVariableName>& argumentNames, MangledVariableName resultName, TypeNamer&);
 
 }
 
index 334e090..008483b 100644 (file)
@@ -38,11 +38,6 @@ namespace WHLSL {
 
 namespace Metal {
 
-enum class MatrixType : uint8_t {
-    Float,
-    Bool
-};
-
 String writeNativeType(AST::NativeTypeDeclaration& nativeTypeDeclaration)
 {
     if (nativeTypeDeclaration.name() == "void")
@@ -101,35 +96,14 @@ String writeNativeType(AST::NativeTypeDeclaration& nativeTypeDeclaration)
         auto& unifyNode = typeReference->unifyNode();
         auto& namedType = downcast<AST::NamedType>(unifyNode);
         auto& parameterType = downcast<AST::NativeTypeDeclaration>(namedType);
-        auto matrixType = ([&]() -> MatrixType {
+        auto prefix = ([&] {
             if (parameterType.name() == "bool")
-                return MatrixType::Bool;
+                return "bool";
             ASSERT(parameterType.name() == "float");
-            return MatrixType::Float;
+            return "float";
         })();
 
-        ASSERT(WTF::holds_alternative<AST::ConstantExpression>(nativeTypeDeclaration.typeArguments()[1]));
-        auto& constantExpression1 = WTF::get<AST::ConstantExpression>(nativeTypeDeclaration.typeArguments()[1]);
-        auto& integerLiteral1 = constantExpression1.integerLiteral();
-        unsigned rows = integerLiteral1.value();
-        ASSERT(rows == 2 || rows == 3 || rows == 4);
-
-        ASSERT(WTF::holds_alternative<AST::ConstantExpression>(nativeTypeDeclaration.typeArguments()[2]));
-        auto& constantExpression2 = WTF::get<AST::ConstantExpression>(nativeTypeDeclaration.typeArguments()[2]);
-        auto& integerLiteral2 = constantExpression2.integerLiteral();
-        unsigned columns = integerLiteral2.value();
-        ASSERT(columns == 2 || columns == 3 || columns == 4);
-
-        switch (matrixType) {
-        case MatrixType::Float: {
-            unsigned alignment = columns == 2 ? 8 : 16;
-            if (columns == 3)
-                columns = 4;
-            return makeString("array<float, ", columns * rows, "> __attribute__((aligned(", alignment, ")))");
-        }
-        case MatrixType::Bool:
-            return makeString("array<bool, ", columns * rows, ">");
-        }
+        return makeString("WSLMatrix<", prefix, ", ", nativeTypeDeclaration.numberOfMatrixColumns(), ", ", nativeTypeDeclaration.numberOfMatrixRows(), ">");
     }
     ASSERT(nativeTypeDeclaration.typeArguments().size() == 1);
     ASSERT(WTF::holds_alternative<Ref<AST::TypeReference>>(nativeTypeDeclaration.typeArguments()[0]));
index 396f84f..64bbacb 100644 (file)
@@ -302,12 +302,6 @@ void ASTDumper::visit(AST::FloatLiteral& floatLiteral)
     m_out.print(floatLiteral.value());
 }
 
-void ASTDumper::visit(AST::NullLiteral& nullLiteral)
-{
-    m_out.print("null");
-    visit(nullLiteral.type());
-}
-
 void ASTDumper::visit(AST::BooleanLiteral& booleanLiteral)
 {
     if (booleanLiteral.value())
@@ -328,10 +322,6 @@ void ASTDumper::visit(AST::FloatLiteralType&)
 {
 }
 
-void ASTDumper::visit(AST::NullLiteralType&)
-{
-}
-
 void ASTDumper::visit(AST::EnumerationMemberLiteral& enumerationMemberLiteral)
 {
     m_out.print(enumerationMemberLiteral.left(), ".", enumerationMemberLiteral.right());
@@ -425,7 +415,6 @@ void ASTDumper::visit(AST::Expression& expression)
     bool skipParens = is<AST::BooleanLiteral>(expression)
         || is<AST::FloatLiteral>(expression)
         || is<AST::IntegerLiteral>(expression)
-        || is<AST::NullLiteral>(expression)
         || is<AST::UnsignedIntegerLiteral>(expression)
         || is<AST::EnumerationMemberLiteral>(expression)
         || is<AST::CommaExpression>(expression)
index e35834c..412a0a0 100644 (file)
@@ -71,12 +71,10 @@ public:
     void visit(AST::IntegerLiteral&) override;
     void visit(AST::UnsignedIntegerLiteral&) override;
     void visit(AST::FloatLiteral&) override;
-    void visit(AST::NullLiteral&) override;
     void visit(AST::BooleanLiteral&) override;
     void visit(AST::IntegerLiteralType&) override;
     void visit(AST::UnsignedIntegerLiteralType&) override;
     void visit(AST::FloatLiteralType&) override;
-    void visit(AST::NullLiteralType&) override;
     void visit(AST::EnumerationMemberLiteral&) override;
     void visit(AST::FunctionAttribute&) override;
     void visit(AST::NumThreadsFunctionAttribute&) override;
index 9fef3a1..0ce8758 100644 (file)
@@ -122,24 +122,7 @@ private:
 Expected<void, Error> checkDuplicateFunctions(const Program& program)
 {
     auto passesStaticChecks = [&] (const AST::FunctionDeclaration& function) -> Expected<void, Error> {
-        if (function.name() == "operator&[]" && function.parameters().size() == 2
-            && is<AST::ArrayReferenceType>(static_cast<const AST::UnnamedType&>(*function.parameters()[0]->type()))) {
-            auto& type = static_cast<const AST::UnnamedType&>(*function.parameters()[1]->type());
-            if (is<AST::TypeReference>(type)) {
-                // 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")
-                            return makeUnexpected(Error("Cannot define array reference ander."));
-                    }
-                }
-            }
-        } else if (function.name() == "operator.length" && function.parameters().size() == 1
-            && (is<AST::ArrayReferenceType>(static_cast<const AST::UnnamedType&>(*function.parameters()[0]->type()))
-            || is<AST::ArrayType>(static_cast<const AST::UnnamedType&>(*function.parameters()[0]->type()))))
-            return makeUnexpected(Error("Cannot define operator.length for an array."));
-        else if (function.name() == "operator=="
+        if (function.name() == "operator=="
             && function.parameters().size() == 2
             && is<AST::ReferenceType>(static_cast<const AST::UnnamedType&>(*function.parameters()[0]->type()))
             && is<AST::ReferenceType>(static_cast<const AST::UnnamedType&>(*function.parameters()[1]->type()))
index 5aea3c5..fb44780 100644 (file)
@@ -199,76 +199,6 @@ private:
     AST::NamedType* m_castReturnType;
 };
 
-class AndOverloadTypeKey {
-public:
-    AndOverloadTypeKey() = default;
-    AndOverloadTypeKey(WTF::HashTableDeletedValueType)
-    {
-        m_type = bitwise_cast<AST::UnnamedType*>(static_cast<uintptr_t>(1));
-    }
-
-    AndOverloadTypeKey(AST::UnnamedType& type, AST::AddressSpace addressSpace)
-        : m_type(&type)
-        , m_addressSpace(addressSpace)
-    { }
-
-    bool isEmptyValue() const { return !m_type; }
-    bool isHashTableDeletedValue() const { return m_type == bitwise_cast<AST::UnnamedType*>(static_cast<uintptr_t>(1)); }
-
-    unsigned hash() const
-    {
-        return IntHash<uint8_t>::hash(static_cast<uint8_t>(m_addressSpace)) ^ m_type->hash();
-    }
-
-    bool operator==(const AndOverloadTypeKey& other) const
-    {
-        return m_addressSpace == other.m_addressSpace
-            && *m_type == *other.m_type;
-    }
-
-    struct Hash {
-        static unsigned hash(const AndOverloadTypeKey& key)
-        {
-            return key.hash();
-        }
-
-        static bool equal(const AndOverloadTypeKey& a, const AndOverloadTypeKey& b)
-        {
-            return a == b;
-        }
-
-        static const bool safeToCompareToEmptyOrDeleted = false;
-    };
-
-    struct Traits : public WTF::SimpleClassHashTraits<AndOverloadTypeKey> {
-        static const bool hasIsEmptyValueFunction = true;
-        static bool isEmptyValue(const AndOverloadTypeKey& key) { return key.isEmptyValue(); }
-    };
-
-private:
-    AST::UnnamedType* m_type { nullptr };
-    AST::AddressSpace m_addressSpace;
-};
-
-static AST::NativeFunctionDeclaration resolveWithOperatorAnderIndexer(CodeLocation location, AST::ArrayReferenceType& firstArgument, const Intrinsics& intrinsics)
-{
-    const bool isOperator = true;
-    auto returnType = AST::PointerType::create(location, firstArgument.addressSpace(), firstArgument.elementType());
-    AST::VariableDeclarations parameters;
-    parameters.append(makeUniqueRef<AST::VariableDeclaration>(location, AST::Qualifiers(), &firstArgument, String(), nullptr, nullptr));
-    parameters.append(makeUniqueRef<AST::VariableDeclaration>(location, AST::Qualifiers(), AST::TypeReference::wrap(location, intrinsics.uintType()), String(), nullptr, nullptr));
-    return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(location, AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator&[]", String::ConstructFromLiteral), WTFMove(parameters), nullptr, isOperator, ParsingMode::StandardLibrary));
-}
-
-static AST::NativeFunctionDeclaration resolveWithOperatorLength(CodeLocation location, AST::UnnamedType& firstArgument, const Intrinsics& intrinsics)
-{
-    const bool isOperator = true;
-    auto returnType = AST::TypeReference::wrap(location, intrinsics.uintType());
-    AST::VariableDeclarations parameters;
-    parameters.append(makeUniqueRef<AST::VariableDeclaration>(location, AST::Qualifiers(), &firstArgument, String(), nullptr, nullptr));
-    return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(location, AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator.length", String::ConstructFromLiteral), WTFMove(parameters), nullptr, isOperator, ParsingMode::StandardLibrary));
-}
-
 static AST::NativeFunctionDeclaration resolveWithReferenceComparator(CodeLocation location, ResolvingType& firstArgument, ResolvingType& secondArgument, const Intrinsics& intrinsics)
 {
     const bool isOperator = true;
@@ -293,44 +223,18 @@ static AST::NativeFunctionDeclaration resolveWithReferenceComparator(CodeLocatio
 
 enum class Acceptability {
     Yes,
-    Maybe,
     No
 };
 
 static Optional<AST::NativeFunctionDeclaration> resolveByInstantiation(const String& name, CodeLocation location, const Vector<std::reference_wrapper<ResolvingType>>& types, const Intrinsics& intrinsics)
 {
-    if (name == "operator&[]" && types.size() == 2) {
-        auto* firstArgumentArrayRef = types[0].get().visit(WTF::makeVisitor([](Ref<AST::UnnamedType>& unnamedType) -> AST::ArrayReferenceType* {
-            if (is<AST::ArrayReferenceType>(static_cast<AST::UnnamedType&>(unnamedType)))
-                return &downcast<AST::ArrayReferenceType>(static_cast<AST::UnnamedType&>(unnamedType));
-            return nullptr;
-        }, [](RefPtr<ResolvableTypeReference>&) -> AST::ArrayReferenceType* {
-            return nullptr;
-        }));
-        bool secondArgumentIsUint = types[1].get().visit(WTF::makeVisitor([&](Ref<AST::UnnamedType>& unnamedType) -> bool {
-            return matches(unnamedType, intrinsics.uintType());
-        }, [&](RefPtr<ResolvableTypeReference>& resolvableTypeReference) -> bool {
-            return resolvableTypeReference->resolvableType().canResolve(intrinsics.uintType());
-        }));
-        if (firstArgumentArrayRef && secondArgumentIsUint)
-            return resolveWithOperatorAnderIndexer(location, *firstArgumentArrayRef, intrinsics);
-    } else if (name == "operator.length" && types.size() == 1) {
-        auto* firstArgumentReference = types[0].get().visit(WTF::makeVisitor([](Ref<AST::UnnamedType>& unnamedType) -> AST::UnnamedType* {
-            if (is<AST::ArrayReferenceType>(static_cast<AST::UnnamedType&>(unnamedType)) || is<AST::ArrayType>(static_cast<AST::UnnamedType&>(unnamedType)))
-                return unnamedType.ptr();
-            return nullptr;
-        }, [](RefPtr<ResolvableTypeReference>&) -> AST::UnnamedType* {
-            return nullptr;
-        }));
-        if (firstArgumentReference)
-            return resolveWithOperatorLength(location, *firstArgumentReference, intrinsics);
-    } else if (name == "operator==" && types.size() == 2) {
+    if (name == "operator==" && types.size() == 2) {
         auto acceptability = [](ResolvingType& resolvingType) -> Acceptability {
             return resolvingType.visit(WTF::makeVisitor([](Ref<AST::UnnamedType>& unnamedType) -> Acceptability {
                 auto& unifyNode = unnamedType->unifyNode();
                 return is<AST::UnnamedType>(unifyNode) && is<AST::ReferenceType>(downcast<AST::UnnamedType>(unifyNode)) ? Acceptability::Yes : Acceptability::No;
-            }, [](RefPtr<ResolvableTypeReference>& resolvableTypeReference) -> Acceptability {
-                return is<AST::NullLiteralType>(resolvableTypeReference->resolvableType()) ? Acceptability::Maybe : Acceptability::No;
+            }, [](RefPtr<ResolvableTypeReference>&) -> Acceptability {
+                return Acceptability::No;
             }));
         };
         auto leftAcceptability = acceptability(types[0].get());
@@ -340,9 +244,7 @@ static Optional<AST::NativeFunctionDeclaration> resolveByInstantiation(const Str
             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))
-            success = true;
+        } 
         if (success)
             return resolveWithReferenceComparator(location, types[0].get(), types[1].get(), intrinsics);
     }
@@ -427,97 +329,13 @@ static bool checkSemantics(Vector<EntryPointItem>& inputItems, Vector<EntryPoint
     return true;
 }
 
-static bool checkOperatorOverload(const AST::FunctionDefinition& functionDefinition, NameContext& nameContext, AST::NameSpace currentNameSpace)
+static bool checkOperatorOverload(const AST::FunctionDefinition& functionDefinition)
 {
     enum class CheckKind {
         Index,
         Dot
     };
 
-    auto checkGetter = [&](CheckKind kind) -> bool {
-        size_t numExpectedParameters = kind == CheckKind::Index ? 2 : 1;
-        if (functionDefinition.parameters().size() != numExpectedParameters)
-            return false;
-        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();
-            if (!is<AST::NamedType>(secondParameterUnifyNode))
-                return false;
-            auto& namedType = downcast<AST::NamedType>(secondParameterUnifyNode);
-            if (!is<AST::NativeTypeDeclaration>(namedType))
-                return false;
-            auto& nativeTypeDeclaration = downcast<AST::NativeTypeDeclaration>(namedType);
-            if (!nativeTypeDeclaration.isInt())
-                return false;
-        }
-        return true;
-    };
-
-    auto checkSetter = [&](CheckKind kind) -> bool {
-        size_t numExpectedParameters = kind == CheckKind::Index ? 3 : 2;
-        if (functionDefinition.parameters().size() != numExpectedParameters)
-            return false;
-        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();
-            if (!is<AST::NamedType>(secondParameterUnifyNode))
-                return false;
-            auto& namedType = downcast<AST::NamedType>(secondParameterUnifyNode);
-            if (!is<AST::NativeTypeDeclaration>(namedType))
-                return false;
-            auto& nativeTypeDeclaration = downcast<AST::NativeTypeDeclaration>(namedType);
-            if (!nativeTypeDeclaration.isInt())
-                return false;
-        }
-        if (!matches(functionDefinition.type(), *functionDefinition.parameters()[0]->type()))
-            return false;
-        auto& valueType = *functionDefinition.parameters()[numExpectedParameters - 1]->type();
-        auto getterName = functionDefinition.name().substring(0, functionDefinition.name().length() - 1);
-        auto getterFuncs = nameContext.getFunctions(getterName, currentNameSpace);
-        Vector<ResolvingType> argumentTypes;
-        Vector<std::reference_wrapper<ResolvingType>> argumentTypeReferences;
-        for (size_t i = 0; i < numExpectedParameters - 1; ++i)
-            argumentTypes.append(*functionDefinition.parameters()[i]->type());
-        for (auto& argumentType : argumentTypes)
-            argumentTypeReferences.append(argumentType);
-        auto* overload = resolveFunctionOverload(getterFuncs, argumentTypeReferences, currentNameSpace);
-        if (!overload)
-            return false;
-        auto& resultType = overload->type();
-        return matches(resultType, valueType);
-    };
-
-    auto checkAnder = [&](CheckKind kind) -> bool {
-        size_t numExpectedParameters = kind == CheckKind::Index ? 2 : 1;
-        if (functionDefinition.parameters().size() != numExpectedParameters)
-            return false;
-        {
-            auto& unifyNode = functionDefinition.type().unifyNode();
-            if (!is<AST::UnnamedType>(unifyNode))
-                return false;
-            auto& unnamedType = downcast<AST::UnnamedType>(unifyNode);
-            if (!is<AST::PointerType>(unnamedType))
-                return false;
-        }
-        {
-            auto& unifyNode = functionDefinition.parameters()[0]->type()->unifyNode();
-            if (!is<AST::UnnamedType>(unifyNode))
-                return false;
-            auto& unnamedType = downcast<AST::UnnamedType>(unifyNode);
-            return is<AST::PointerType>(unnamedType) || is<AST::ArrayReferenceType>(unnamedType);
-        }
-    };
-
     if (!functionDefinition.isOperator())
         return true;
     if (functionDefinition.isCast())
@@ -539,19 +357,6 @@ static bool checkOperatorOverload(const AST::FunctionDefinition& functionDefinit
         return functionDefinition.parameters().size() == 2;
     if (functionDefinition.name() == "operator~")
         return functionDefinition.parameters().size() == 1;
-    if (functionDefinition.name() == "operator[]")
-        return checkGetter(CheckKind::Index);
-    if (functionDefinition.name() == "operator[]=")
-        return checkSetter(CheckKind::Index);
-    if (functionDefinition.name() == "operator&[]")
-        return checkAnder(CheckKind::Index);
-    if (functionDefinition.name().startsWith("operator.")) {
-        if (functionDefinition.name().endsWith("="))
-            return checkSetter(CheckKind::Dot);
-        return checkGetter(CheckKind::Dot);
-    }
-    if (functionDefinition.name().startsWith("operator&."))
-        return checkAnder(CheckKind::Dot);
     return false;
 }
 
@@ -600,10 +405,12 @@ private:
     RefPtr<AST::UnnamedType> recurseAndWrapBaseType(AST::PropertyAccessExpression&);
     bool recurseAndRequireBoolType(AST::Expression&);
     void assignConcreteType(AST::Expression&, Ref<AST::UnnamedType>, AST::TypeAnnotation);
+    void assignConcreteType(AST::Expression&, AST::NamedType&, 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::FunctionDeclaration&) override;
     void visit(AST::EnumerationDefinition&) override;
     void visit(AST::TypeReference&) override;
     void visit(AST::VariableDeclaration&) override;
@@ -621,7 +428,6 @@ private:
     void visit(AST::IntegerLiteral&) override;
     void visit(AST::UnsignedIntegerLiteral&) override;
     void visit(AST::FloatLiteral&) override;
-    void visit(AST::NullLiteral&) override;
     void visit(AST::BooleanLiteral&) override;
     void visit(AST::EnumerationMemberLiteral&) override;
     void visit(AST::LogicalNotExpression&) override;
@@ -635,12 +441,8 @@ private:
     void visit(AST::TernaryExpression&) override;
     void visit(AST::CallExpression&) override;
 
-    void finishVisiting(AST::PropertyAccessExpression&, ResolvingType* additionalArgumentType = nullptr);
-
     AST::FunctionDeclaration* resolveFunction(Vector<std::reference_wrapper<ResolvingType>>& types, const String& name, CodeLocation, AST::NamedType* castReturnType = nullptr);
 
-    RefPtr<AST::UnnamedType> argumentTypeForAndOverload(AST::UnnamedType& baseType, AST::AddressSpace);
-
     AST::UnnamedType& wrappedFloatType()
     {
         if (!m_wrappedFloatType)
@@ -648,11 +450,11 @@ private:
         return *m_wrappedFloatType;
     }
 
-    AST::UnnamedType& genericPointerType()
+    AST::UnnamedType& wrappedUintType()
     {
-        if (!m_genericPointerType)
-            m_genericPointerType = AST::PointerType::create({ }, AST::AddressSpace::Thread, AST::TypeReference::wrap({ }, m_intrinsics.floatType()));
-        return *m_genericPointerType;
+        if (!m_wrappedUintType)
+            m_wrappedUintType = AST::TypeReference::wrap({ }, m_intrinsics.uintType());
+        return *m_wrappedUintType;
     }
 
     AST::UnnamedType& normalizedTypeForFunctionKey(AST::UnnamedType& type)
@@ -661,14 +463,11 @@ private:
         if (unifyNode == &m_intrinsics.uintType() || unifyNode == &m_intrinsics.intType())
             return wrappedFloatType();
 
-        if (is<AST::ReferenceType>(type))
-            return genericPointerType();
-
         return type;
     }
 
     RefPtr<AST::TypeReference> m_wrappedFloatType;
-    RefPtr<AST::UnnamedType> m_genericPointerType;
+    RefPtr<AST::TypeReference> m_wrappedUintType;
     HashMap<AST::Expression*, std::unique_ptr<ResolvingType>> m_typeMap;
     HashSet<String> m_vertexEntryPoints[AST::nameSpaceCount];
     HashSet<String> m_fragmentEntryPoints[AST::nameSpaceCount];
@@ -677,8 +476,8 @@ private:
     Program& m_program;
     AST::FunctionDefinition* m_currentFunction { nullptr };
     HashMap<FunctionKey, Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>, FunctionKey::Hash, FunctionKey::Traits> m_functions;
-    HashMap<AndOverloadTypeKey, RefPtr<AST::UnnamedType>, AndOverloadTypeKey::Hash, AndOverloadTypeKey::Traits> m_andOverloadTypeMap;
     AST::NameSpace m_currentNameSpace { AST::NameSpace::StandardLibrary };
+    bool m_isVisitingParameters { false };
 };
 
 void Checker::visit(Program& program)
@@ -733,6 +532,13 @@ bool Checker::checkShaderType(const AST::FunctionDefinition& functionDefinition)
     }
 }
 
+void Checker::visit(AST::FunctionDeclaration& functionDeclaration)
+{
+    m_isVisitingParameters = true;
+    Visitor::visit(functionDeclaration);
+    m_isVisitingParameters = false;
+}
+
 void Checker::visit(AST::FunctionDefinition& functionDefinition)
 {
     m_currentNameSpace = functionDefinition.nameSpace();
@@ -752,7 +558,7 @@ void Checker::visit(AST::FunctionDefinition& functionDefinition)
             return;
         }
     }
-    if (!checkOperatorOverload(functionDefinition, m_program.nameContext(), m_currentNameSpace)) {
+    if (!checkOperatorOverload(functionDefinition)) {
         setError(Error("Operator does not match expected signature.", functionDefinition.codeLocation()));
         return;
     }
@@ -790,6 +596,17 @@ static RefPtr<AST::UnnamedType> matchAndCommit(ResolvingType& resolvingType, AST
     }));
 }
 
+static bool matchAndCommit(ResolvingType& resolvingType, AST::NamedType& namedType)
+{
+    return resolvingType.visit(WTF::makeVisitor([&](Ref<AST::UnnamedType>& resolvingType) {
+        if (matches(resolvingType, namedType))
+            return true;
+        return false;
+    }, [&](RefPtr<ResolvableTypeReference>& resolvingType) -> bool {
+        return matchAndCommit(namedType, resolvingType->resolvableType());
+    }));
+}
+
 static RefPtr<AST::UnnamedType> commit(ResolvingType& resolvingType)
 {
     return resolvingType.visit(WTF::makeVisitor([&](Ref<AST::UnnamedType>& unnamedType) -> RefPtr<AST::UnnamedType> {
@@ -818,9 +635,6 @@ AST::FunctionDeclaration* Checker::resolveFunction(Vector<std::reference_wrapper
                 || resolvableTypeReference->resolvableType().isUnsignedIntegerLiteralType())
                 return &wrappedFloatType();
 
-            if (resolvableTypeReference->resolvableType().isNullLiteralType())
-                return &genericPointerType();
-
             return commit(resolvableTypeReference->resolvableType()).get();
         }));
 
@@ -958,6 +772,14 @@ void Checker::visit(AST::VariableDeclaration& variableDeclaration)
             setError(Error("Declared variable type does not match its initializer's type.", variableDeclaration.codeLocation()));
             return;
         }
+    } else if (!m_isVisitingParameters && is<AST::ReferenceType>(variableDeclaration.type()->unifyNode())) {
+        if (is<AST::PointerType>(variableDeclaration.type()->unifyNode()))
+