[WHLSL] Implement out-of-bounds and nullptr behavior
authorsbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 14 Jun 2019 18:01:05 +0000 (18:01 +0000)
committersbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 14 Jun 2019 18:01:05 +0000 (18:01 +0000)
commiteeb3367714e1d9586b8fb70e8c1dce742748f6f1
tree59b7ffc7413570bd012676ec59d9fc4233bc3acb
parentd5815d094a02ffd677d5ab610466ffe46dd28c3e
[WHLSL] Implement out-of-bounds and nullptr behavior
https://bugs.webkit.org/show_bug.cgi?id=198600
<rdar://problem/51668853>

Reviewed by Robin Morisset.

Source/WebCore:

The behavior we're implementing is:
- OOB writes are ignored.
- OOB reads return zero.
- Writes to null are ignored.
- Reads from null return zero.
- &*x == x, including &*null == null.

We implement this like so:
- The value stack in FunctionWriter turns into a stack of pairs: rvalues and lvalues.
  rvalues are represented the same as before. Lvalues are always pointers.
- Anything that produces an lvalue must push a pointer to the stack. Not
  all things produce lvalues, so that entry in the stack may be empty.
  However, all things that produce lvalues also produce rvalues. So, "*x = 42" works,
  and so does "foo(*x)". Nodes that produce lvalues are responsible for also producing
  an rvalue, which should be the value as if the lvalue was dereferenced at that point
  in program execution. So the "*x" in "thread int* x = null; *x" produces the int zero
  for its rvalue, and null for its lvalue.
- Dereference just works, as dereference produces both an lvalue and rvalue. Dereference
  node's child must also be an lvalue. So we just forward that value along on
  the stack. For the rvalue, if we try to dereference nullptr, we just fill in
  zero bytes instead. Otherwise, the rvalue is the result of dereferencing the
  non-null pointer.
- Assignment expressions check if the incoming lvalue is null. If it is, it
  skips the assignment.
- operator&[] returns nullptr on an OOB access. Then, based on the above
  behavior, we get the desired OOB reads return zero, and OOB writes are
  ignored.
- MakePointerExpression just takes the last lvalue off the stack (which must
  be a pointer) and returns it as an rvalue.
- VariableReference will push both the variable value and a pointer to the variable
  onto the stack.

This patch also fixes a few bugs where we weren't giving certain AST nodes the
proper address space values.

This patch also removes code to generate native functions for operators
"operator[]" and "operator[]=" as we should never be generating these
ourselves. We should only be generating the "operator&[]" ander.

Tests: webgpu/whlsl-null-dereference.html
       webgpu/whlsl-oob-access.html

* Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp:
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::FunctionDefinitionWriter):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::appendRightValue):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::appendLeftValue):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::takeLastValue):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::takeLastLeftValue):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::emitLoop):
* Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp:
(WebCore::WHLSL::Metal::writeNativeFunction):
* Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.h:
* Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp:
(WebCore::WHLSL::Metal::TypeNamer::emitUnnamedTypeDefinition):
* Modules/webgpu/WHLSL/WHLSLPreserveVariableLifetimes.cpp:
(WebCore::WHLSL::PreserveLifetimes::assignVariableIntoStruct):
* Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp:
(WebCore::WHLSL::PropertyResolver::visit):
* Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt:
* platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm:
(WebCore::trySetFunctions):
* platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm:
(WebCore::trySetFunctions):

LayoutTests:

* webgpu/whlsl-null-dereference-expected.txt: Added.
* webgpu/whlsl-null-dereference.html: Added.
* webgpu/whlsl-oob-access-expected.txt: Added.
* webgpu/whlsl-oob-access.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246438 268f45cc-cd09-0410-ab3c-d52691b4dbfc
15 files changed:
LayoutTests/ChangeLog
LayoutTests/webgpu/whlsl-null-dereference-expected.txt [new file with mode: 0644]
LayoutTests/webgpu/whlsl-null-dereference.html [new file with mode: 0644]
LayoutTests/webgpu/whlsl-oob-access-expected.txt [new file with mode: 0644]
LayoutTests/webgpu/whlsl-oob-access.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.h
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLPreserveVariableLifetimes.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt
Source/WebCore/platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm
Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm