⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 246438 in webkit


Ignore:
Timestamp:
Jun 14, 2019, 11:01:05 AM (7 years ago)
Author:
sbarati@apple.com
Message:

[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.
Location:
trunk
Files:
4 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r246436 r246438  
     12019-06-14  Saam Barati  <sbarati@apple.com>
     2
     3        [WHLSL] Implement out-of-bounds and nullptr behavior
     4        https://bugs.webkit.org/show_bug.cgi?id=198600
     5        <rdar://problem/51668853>
     6
     7        Reviewed by Robin Morisset.
     8
     9        * webgpu/whlsl-null-dereference-expected.txt: Added.
     10        * webgpu/whlsl-null-dereference.html: Added.
     11        * webgpu/whlsl-oob-access-expected.txt: Added.
     12        * webgpu/whlsl-oob-access.html: Added.
     13
    1142019-06-14  Youenn Fablet  <youenn@apple.com>
    215
  • trunk/Source/WebCore/ChangeLog

    r246437 r246438  
     12019-06-14  Saam Barati  <sbarati@apple.com>
     2
     3        [WHLSL] Implement out-of-bounds and nullptr behavior
     4        https://bugs.webkit.org/show_bug.cgi?id=198600
     5        <rdar://problem/51668853>
     6
     7        Reviewed by Robin Morisset.
     8
     9        The behavior we're implementing is:
     10        - OOB writes are ignored.
     11        - OOB reads return zero.
     12        - Writes to null are ignored.
     13        - Reads from null return zero.
     14        - &*x == x, including &*null == null.
     15       
     16        We implement this like so:
     17        - The value stack in FunctionWriter turns into a stack of pairs: rvalues and lvalues.
     18          rvalues are represented the same as before. Lvalues are always pointers.
     19        - Anything that produces an lvalue must push a pointer to the stack. Not
     20          all things produce lvalues, so that entry in the stack may be empty.
     21          However, all things that produce lvalues also produce rvalues. So, "*x = 42" works,
     22          and so does "foo(*x)". Nodes that produce lvalues are responsible for also producing
     23          an rvalue, which should be the value as if the lvalue was dereferenced at that point
     24          in program execution. So the "*x" in "thread int* x = null; *x" produces the int zero
     25          for its rvalue, and null for its lvalue.
     26        - Dereference just works, as dereference produces both an lvalue and rvalue. Dereference
     27          node's child must also be an lvalue. So we just forward that value along on
     28          the stack. For the rvalue, if we try to dereference nullptr, we just fill in
     29          zero bytes instead. Otherwise, the rvalue is the result of dereferencing the
     30          non-null pointer.
     31        - Assignment expressions check if the incoming lvalue is null. If it is, it
     32          skips the assignment.
     33        - operator&[] returns nullptr on an OOB access. Then, based on the above
     34          behavior, we get the desired OOB reads return zero, and OOB writes are
     35          ignored.
     36        - MakePointerExpression just takes the last lvalue off the stack (which must
     37          be a pointer) and returns it as an rvalue.
     38        - VariableReference will push both the variable value and a pointer to the variable
     39          onto the stack.
     40
     41        This patch also fixes a few bugs where we weren't giving certain AST nodes the
     42        proper address space values.
     43
     44        This patch also removes code to generate native functions for operators
     45        "operator[]" and "operator[]=" as we should never be generating these
     46        ourselves. We should only be generating the "operator&[]" ander.
     47
     48        Tests: webgpu/whlsl-null-dereference.html
     49               webgpu/whlsl-oob-access.html
     50
     51        * Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp:
     52        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::FunctionDefinitionWriter):
     53        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::appendRightValue):
     54        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::appendLeftValue):
     55        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::takeLastValue):
     56        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::takeLastLeftValue):
     57        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit):
     58        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::emitLoop):
     59        * Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp:
     60        (WebCore::WHLSL::Metal::writeNativeFunction):
     61        * Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.h:
     62        * Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp:
     63        (WebCore::WHLSL::Metal::TypeNamer::emitUnnamedTypeDefinition):
     64        * Modules/webgpu/WHLSL/WHLSLPreserveVariableLifetimes.cpp:
     65        (WebCore::WHLSL::PreserveLifetimes::assignVariableIntoStruct):
     66        * Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp:
     67        (WebCore::WHLSL::PropertyResolver::visit):
     68        * Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt:
     69        * platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm:
     70        (WebCore::trySetFunctions):
     71        * platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm:
     72        (WebCore::trySetFunctions):
     73
    1742019-06-14  Jer Noble  <jer.noble@apple.com>
    275
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp

    r246428 r246438  
    8989        , m_layout(layout)
    9090    {
    91     }
     91        m_stringBuilder.append(makeString(
     92            "template <typename T>\n"
     93            "inline void ", memsetZeroFunctionName, "(thread T& value)\n"
     94            "{\n"
     95            "    thread char* ptr = static_cast<thread char*>(static_cast<thread void*>(&value));\n"
     96            "    for (size_t i = 0; i < sizeof(T); ++i)\n"
     97            "        ptr[i] = 0;\n"
     98            "}\n"));
     99    }
     100
     101    static constexpr const char* memsetZeroFunctionName = "memsetZero";
    92102
    93103    virtual ~FunctionDefinitionWriter() = default;
     
    154164    }
    155165
     166    struct StackItem {
     167        String value;
     168        String leftValue;
     169    };
     170
     171    void appendRightValue(AST::Expression&, String value)
     172    {
     173        m_stack.append({ WTFMove(value), String() });
     174    }
     175
     176    void appendLeftValue(AST::Expression& expression, String value, String leftValue)
     177    {
     178        ASSERT_UNUSED(expression, expression.typeAnnotation().leftAddressSpace());
     179        m_stack.append({ WTFMove(value), WTFMove(leftValue) });
     180    }
     181
     182    String takeLastValue()
     183    {
     184        ASSERT(m_stack.last().value);
     185        return m_stack.takeLast().value;
     186    }
     187
     188    String takeLastLeftValue()
     189    {
     190        ASSERT(m_stack.last().leftValue);
     191        return m_stack.takeLast().leftValue;
     192    }
     193
    156194    Intrinsics& m_intrinsics;
    157195    TypeNamer& m_typeNamer;
     
    159197    HashMap<AST::VariableDeclaration*, String> m_variableMapping;
    160198    StringBuilder m_stringBuilder;
    161     Vector<String> m_stack;
     199
     200    Vector<StackItem> m_stack;
    162201    std::unique_ptr<EntryPointScaffolding> m_entryPointScaffolding;
    163202    Layout& m_layout;
     
    170209    auto iterator = m_functionMapping.find(&nativeFunctionDeclaration);
    171210    ASSERT(iterator != m_functionMapping.end());
    172     m_stringBuilder.append(writeNativeFunction(nativeFunctionDeclaration, iterator->value, m_intrinsics, m_typeNamer));
     211    m_stringBuilder.append(writeNativeFunction(nativeFunctionDeclaration, iterator->value, m_intrinsics, m_typeNamer, memsetZeroFunctionName));
    173212}
    174213
     
    247286{
    248287    checkErrorAndVisit(effectfulExpressionStatement.effectfulExpression());
    249     m_stack.takeLast(); // The statement is already effectful, so we don't need to do anything with the result.
     288    takeLastValue(); // The statement is already effectful, so we don't need to do anything with the result.
    250289}
    251290
     
    265304    if (loopConditionLocation == LoopConditionLocation::BeforeBody && conditionExpression) {
    266305        checkErrorAndVisit(*conditionExpression);
    267         m_stringBuilder.append(makeString("if (!", m_stack.takeLast(), ") break;\n"));
     306        m_stringBuilder.append(makeString("if (!", takeLastValue(), ") break;\n"));
    268307    }
    269308
     
    277316        // Expression results get pushed to m_stack. We don't use the result
    278317        // of increment, so we dispense of that now.
    279         m_stack.takeLast();
     318        takeLastValue();
    280319    }
    281320
    282321    if (loopConditionLocation == LoopConditionLocation::AfterBody && conditionExpression) {
    283322        checkErrorAndVisit(*conditionExpression);
    284         m_stringBuilder.append(makeString("if (!", m_stack.takeLast(), ") break;\n"));
     323        m_stringBuilder.append(makeString("if (!", takeLastValue(), ") break;\n"));
    285324    }
    286325
     
    306345    }, [&](UniqueRef<AST::Expression>& expression) {
    307346        checkErrorAndVisit(expression);
    308         m_stack.takeLast(); // We don't need to do anything with the result.
     347        takeLastValue(); // We don't need to do anything with the result.
    309348    }), forLoop.initialization());
    310349
     
    316355{
    317356    checkErrorAndVisit(ifStatement.conditional());
    318     m_stringBuilder.append(makeString("if (", m_stack.takeLast(), ") {\n"));
     357    m_stringBuilder.append(makeString("if (", takeLastValue(), ") {\n"));
    319358    checkErrorAndVisit(ifStatement.body());
    320359    if (ifStatement.elseBody()) {
     
    331370        if (m_entryPointScaffolding) {
    332371            auto variableName = generateNextVariableName();
    333             m_stringBuilder.append(m_entryPointScaffolding->pack(m_stack.takeLast(), variableName));
     372            m_stringBuilder.append(m_entryPointScaffolding->pack(takeLastValue(), variableName));
    334373            m_stringBuilder.append(makeString("return ", variableName, ";\n"));
    335374        } else
    336             m_stringBuilder.append(makeString("return ", m_stack.takeLast(), ";\n"));
     375            m_stringBuilder.append(makeString("return ", takeLastValue(), ";\n"));
    337376    } else
    338377        m_stringBuilder.append("return;\n");
     
    343382    checkErrorAndVisit(switchStatement.value());
    344383
    345     m_stringBuilder.append(makeString("switch (", m_stack.takeLast(), ") {"));
     384    m_stringBuilder.append(makeString("switch (", takeLastValue(), ") {"));
    346385    for (auto& switchCase : switchStatement.switchCases())
    347386        checkErrorAndVisit(switchCase);
     
    376415    auto mangledTypeName = m_typeNamer.mangledNameForType(integerLiteral.resolvedType());
    377416    m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = static_cast<", mangledTypeName, ">(", integerLiteral.value(), ");\n"));
    378     m_stack.append(variableName);
     417    appendRightValue(integerLiteral, variableName);
    379418}
    380419
     
    384423    auto mangledTypeName = m_typeNamer.mangledNameForType(unsignedIntegerLiteral.resolvedType());
    385424    m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = static_cast<", mangledTypeName, ">(", unsignedIntegerLiteral.value(), ");\n"));
    386     m_stack.append(variableName);
     425    appendRightValue(unsignedIntegerLiteral, variableName);
    387426}
    388427
     
    392431    auto mangledTypeName = m_typeNamer.mangledNameForType(floatLiteral.resolvedType());
    393432    m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = static_cast<", mangledTypeName, ">(", floatLiteral.value(), ");\n"));
    394     m_stack.append(variableName);
     433    appendRightValue(floatLiteral, variableName);
    395434}
    396435
     
    408447        m_stringBuilder.append("nullptr");
    409448    m_stringBuilder.append(";\n");
    410     m_stack.append(variableName);
     449    appendRightValue(nullLiteral, variableName);
    411450}
    412451
     
    416455    auto mangledTypeName = m_typeNamer.mangledNameForType(booleanLiteral.resolvedType());
    417456    m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = static_cast<", mangledTypeName, ">(", booleanLiteral.value() ? "true" : "false", ");\n"));
    418     m_stack.append(variableName);
     457    appendRightValue(booleanLiteral, variableName);
    419458}
    420459
     
    426465    auto mangledTypeName = m_typeNamer.mangledNameForType(enumerationMemberLiteral.resolvedType());
    427466    m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = ", mangledTypeName, '.', m_typeNamer.mangledNameForEnumerationMember(*enumerationMemberLiteral.enumerationMember()), ";\n"));
    428     m_stack.append(variableName);
     467    appendRightValue(enumerationMemberLiteral, variableName);
    429468}
    430469
     
    434473}
    435474
    436 void FunctionDefinitionWriter::visit(AST::DotExpression&)
     475void FunctionDefinitionWriter::visit(AST::DotExpression& dotExpression)
    437476{
    438477    // This should be lowered already.
    439478    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195788 Replace this with ASSERT_NOT_REACHED().
    440479    notImplemented();
    441     m_stack.append("dummy");
     480    appendRightValue(dotExpression, "dummy");
    442481}
    443482
    444483void FunctionDefinitionWriter::visit(AST::GlobalVariableReference& globalVariableReference)
    445484{
    446     auto variableName = generateNextVariableName();
     485    auto valueName = generateNextVariableName();
     486    auto pointerName = generateNextVariableName();
    447487    auto mangledTypeName = m_typeNamer.mangledNameForType(globalVariableReference.resolvedType());
    448488    checkErrorAndVisit(globalVariableReference.base());
    449     m_stringBuilder.append(makeString("thread ", mangledTypeName, "& ", variableName, " = ", m_stack.takeLast(), "->", m_typeNamer.mangledNameForStructureElement(globalVariableReference.structField()), ";\n"));
    450     m_stack.append(variableName);
    451 }
    452 
    453 void FunctionDefinitionWriter::visit(AST::IndexExpression&)
     489    m_stringBuilder.append(makeString("thread ", mangledTypeName, "* ", pointerName, " = &", takeLastValue(), "->", m_typeNamer.mangledNameForStructureElement(globalVariableReference.structField()), ";\n"));
     490    m_stringBuilder.append(makeString(mangledTypeName, ' ', valueName, " = ", "*", pointerName, ";\n"));
     491    appendLeftValue(globalVariableReference, valueName, pointerName);
     492}
     493
     494void FunctionDefinitionWriter::visit(AST::IndexExpression& indexExpression)
    454495{
    455496    // This should be lowered already.
    456497    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195788 Replace this with ASSERT_NOT_REACHED().
    457498    notImplemented();
    458     m_stack.append("dummy");
    459 }
    460 
    461 void FunctionDefinitionWriter::visit(AST::PropertyAccessExpression&)
     499    appendRightValue(indexExpression, "dummy");
     500}
     501
     502void FunctionDefinitionWriter::visit(AST::PropertyAccessExpression& propertyAccessExpression)
    462503{
    463504    // This should be lowered already.
    464505    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195788 Replace this with ASSERT_NOT_REACHED().
    465506    notImplemented();
    466     m_stack.append("dummy");
     507    appendRightValue(propertyAccessExpression, "dummy");
    467508}
    468509
     
    476517    if (variableDeclaration.initializer()) {
    477518        checkErrorAndVisit(*variableDeclaration.initializer());
    478         m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(*variableDeclaration.type()), ' ', variableName, " = ", m_stack.takeLast(), ";\n"));
     519        m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(*variableDeclaration.type()), ' ', variableName, " = ", takeLastValue(), ";\n"));
    479520    } else
    480521        m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(*variableDeclaration.type()), ' ', variableName, ";\n"));
     
    484525{
    485526    checkErrorAndVisit(assignmentExpression.left());
    486     auto leftName = m_stack.takeLast();
     527    auto pointerName = takeLastLeftValue();
    487528    checkErrorAndVisit(assignmentExpression.right());
    488     auto rightName = m_stack.takeLast();
    489     m_stringBuilder.append(makeString(leftName, " = ", rightName, ";\n"));
    490     m_stack.append(rightName);
     529    auto rightName = takeLastValue();
     530    m_stringBuilder.append(makeString("if (", pointerName, ") *", pointerName, " = ", rightName, ";\n"));
     531    appendRightValue(assignmentExpression, rightName);
    491532}
    492533
     
    496537    for (auto& argument : callExpression.arguments()) {
    497538        checkErrorAndVisit(argument);
    498         argumentNames.append(m_stack.takeLast());
     539        argumentNames.append(takeLastValue());
    499540    }
    500541    ASSERT(callExpression.function());
     
    509550    }
    510551    m_stringBuilder.append(");\n");
    511     m_stack.append(variableName);
     552    appendRightValue(callExpression, variableName);
    512553}
    513554
     
    517558    for (auto& expression : commaExpression.list()) {
    518559        checkErrorAndVisit(expression);
    519         result = m_stack.takeLast();
    520     }
    521     m_stack.append(result);
     560        result = takeLastValue();
     561    }
     562    appendRightValue(commaExpression, result);
    522563}
    523564
     
    525566{
    526567    checkErrorAndVisit(dereferenceExpression.pointer());
    527     auto right = m_stack.takeLast();
    528     auto variableName = generateNextVariableName();
    529     m_stringBuilder.append(makeString(AST::toString(*dereferenceExpression.typeAnnotation().leftAddressSpace()), ' ', m_typeNamer.mangledNameForType(dereferenceExpression.resolvedType()), "& ", variableName, " = *", right, ";\n"));
    530     m_stack.append(variableName);
     568    auto right = takeLastValue();
     569    auto variableName = generateNextVariableName();
     570    auto pointerName = generateNextVariableName();
     571    m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(dereferenceExpression.pointer().resolvedType()), ' ', pointerName, " = ", right, ";\n"));
     572    m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(dereferenceExpression.resolvedType()), ' ', variableName, ";\n"));
     573    m_stringBuilder.append(makeString("if (", pointerName, ") ", variableName, " = *", right, ";\n"));
     574    m_stringBuilder.append(makeString("else ", memsetZeroFunctionName, '(', variableName, ");\n"));
     575    appendLeftValue(dereferenceExpression, variableName, pointerName);
    531576}
    532577
     
    534579{
    535580    checkErrorAndVisit(logicalExpression.left());
    536     auto left = m_stack.takeLast();
     581    auto left = takeLastValue();
    537582    checkErrorAndVisit(logicalExpression.right());
    538     auto right = m_stack.takeLast();
     583    auto right = takeLastValue();
    539584    auto variableName = generateNextVariableName();
    540585    m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(logicalExpression.resolvedType()), ' ', variableName, " = ", left));
     
    549594    }
    550595    m_stringBuilder.append(makeString(right, ";\n"));
    551     m_stack.append(variableName);
     596    appendRightValue(logicalExpression, variableName);
    552597}
    553598
     
    555600{
    556601    checkErrorAndVisit(logicalNotExpression.operand());
    557     auto operand = m_stack.takeLast();
     602    auto operand = takeLastValue();
    558603    auto variableName = generateNextVariableName();
    559604    m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(logicalNotExpression.resolvedType()), ' ', variableName, " = !", operand, ";\n"));
    560     m_stack.append(variableName);
     605    appendRightValue(logicalNotExpression, variableName);
    561606}
    562607
     
    564609{
    565610    checkErrorAndVisit(makeArrayReferenceExpression.leftValue());
    566     auto lValue = m_stack.takeLast();
     611    // FIXME: This needs to be made to work. It probably should be using the last leftValue too.
     612    // https://bugs.webkit.org/show_bug.cgi?id=198838
     613    auto lValue = takeLastValue();
    567614    auto variableName = generateNextVariableName();
    568615    auto mangledTypeName = m_typeNamer.mangledNameForType(makeArrayReferenceExpression.resolvedType());
     
    574621    } else
    575622        m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = { &", lValue, ", 1 };\n"));
    576     m_stack.append(variableName);
     623    appendRightValue(makeArrayReferenceExpression, variableName);
    577624}
    578625
     
    580627{
    581628    checkErrorAndVisit(makePointerExpression.leftValue());
    582     auto lValue = m_stack.takeLast();
    583     auto variableName = generateNextVariableName();
    584     m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(makePointerExpression.resolvedType()), ' ', variableName, " = &", lValue, ";\n"));
    585     m_stack.append(variableName);
     629    auto pointer = takeLastLeftValue();
     630    auto variableName = generateNextVariableName();
     631    m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(makePointerExpression.resolvedType()), ' ', variableName, " = ", pointer, ";\n"));
     632    appendRightValue(makePointerExpression, variableName);
    586633}
    587634
     
    595642{
    596643    checkErrorAndVisit(ternaryExpression.predicate());
    597     auto check = m_stack.takeLast();
     644    auto check = takeLastValue();
    598645
    599646    auto variableName = generateNextVariableName();
     
    602649    m_stringBuilder.append(makeString("if (", check, ") {\n"));
    603650    checkErrorAndVisit(ternaryExpression.bodyExpression());
    604     m_stringBuilder.append(makeString(variableName, " = ", m_stack.takeLast(), ";\n"));
     651    m_stringBuilder.append(makeString(variableName, " = ", takeLastValue(), ";\n"));
    605652    m_stringBuilder.append("} else {\n");
    606653    checkErrorAndVisit(ternaryExpression.elseExpression());
    607     m_stringBuilder.append(makeString(variableName, " = ", m_stack.takeLast(), ";\n"));
     654    m_stringBuilder.append(makeString(variableName, " = ", takeLastValue(), ";\n"));
    608655    m_stringBuilder.append("}\n");
    609     m_stack.append(variableName);
     656    appendRightValue(ternaryExpression, variableName);
    610657}
    611658
     
    615662    auto iterator = m_variableMapping.find(variableReference.variable());
    616663    ASSERT(iterator != m_variableMapping.end());
    617     m_stack.append(iterator->value);
     664    auto pointerName = generateNextVariableName();
     665    m_stringBuilder.append(makeString("thread ", m_typeNamer.mangledNameForType(variableReference.resolvedType()), "* ", pointerName, " = &", iterator->value, ";\n"));
     666    appendLeftValue(variableReference, iterator->value, pointerName);
    618667}
    619668
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp

    r246428 r246438  
    8282}
    8383
    84 String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclaration, String& outputFunctionName, Intrinsics& intrinsics, TypeNamer& typeNamer)
     84String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclaration, String& outputFunctionName, Intrinsics& intrinsics, TypeNamer& typeNamer, const char* memsetZeroFunctionName)
    8585{
    8686    StringBuilder stringBuilder;
     
    9090            stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, "() {\n"));
    9191            stringBuilder.append(makeString("    ", metalReturnName, " x;\n"));
    92             stringBuilder.append("    thread char* ptr = static_cast<thread char*>(static_cast<thread void*>(&x));\n");
    93             stringBuilder.append(makeString("    for (size_t i = 0; i < sizeof(", metalReturnName, "); ++i) ptr[i] = 0;\n"));
     92            stringBuilder.append(makeString("    ", memsetZeroFunctionName, "(x);\n"));
    9493            stringBuilder.append("    return x;\n");
    9594            stringBuilder.append("}\n");
     
    215214    }
    216215
    217     if (nativeFunctionDeclaration.name() == "operator[]") {
    218         ASSERT(nativeFunctionDeclaration.parameters().size() == 2);
    219         auto metalParameter1Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type());
    220         auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type());
    221         auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
    222         stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameter1Name, " m, ", metalParameter2Name, " i) {\n"));
    223         stringBuilder.append(makeString("    return m[i];\n"));
    224         stringBuilder.append("}\n");
    225         return stringBuilder.toString();
    226     }
    227 
    228216    if (nativeFunctionDeclaration.name() == "operator&[]") {
    229217        ASSERT(nativeFunctionDeclaration.parameters().size() == 2);
     
    231219        auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type());
    232220        auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
    233         auto fieldName = nativeFunctionDeclaration.name().substring("operator&[]."_str.length());
    234221        stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameter1Name, " v, ", metalParameter2Name, " n) {\n"));
    235         stringBuilder.append(makeString("    return &(v.pointer[n]);\n"));
    236         stringBuilder.append("}\n");
    237         return stringBuilder.toString();
    238     }
    239 
    240     if (nativeFunctionDeclaration.name() == "operator[]=") {
    241         ASSERT(nativeFunctionDeclaration.parameters().size() == 3);
    242         auto metalParameter1Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type());
    243         auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type());
    244         auto metalParameter3Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[2]->type());
    245         auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
    246         stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameter1Name, " m, ", metalParameter2Name, " i, ", metalParameter3Name, " v) {\n"));
    247         stringBuilder.append(makeString("    m[i] = v;\n"));
    248         stringBuilder.append(makeString("    return m;\n"));
     222        stringBuilder.append("    if (n < v.length) return &(v.pointer[n]);\n");
     223        stringBuilder.append("    return nullptr;\n");
    249224        stringBuilder.append("}\n");
    250225        return stringBuilder.toString();
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.h

    r243924 r246438  
    4646class TypeNamer;
    4747
    48 String writeNativeFunction(AST::NativeFunctionDeclaration&, String& outputFunctionName, Intrinsics&, TypeNamer&);
     48String writeNativeFunction(AST::NativeFunctionDeclaration&, String& outputFunctionName, Intrinsics&, TypeNamer&, const char* memsetZeroFunctionName);
    4949
    5050}
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp

    r246428 r246438  
    394394        stringBuilder.append(makeString("struct ", arrayReferenceType.mangledName(), "{ \n"));
    395395        stringBuilder.append(makeString("    ", toString(arrayReferenceType.addressSpace()), " ", arrayReferenceType.parent()->mangledName(), "* pointer;\n"));
    396         stringBuilder.append("    uint length;\n");
     396        stringBuilder.append("    uint32_t length;\n");
    397397        stringBuilder.append("};\n");
    398398    } else {
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPreserveVariableLifetimes.cpp

    r245945 r246438  
    111111        auto rhs = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variable));
    112112        rhs->setType(variable.type()->clone());
    113         rhs->setTypeAnnotation(AST::RightValue());
     113        rhs->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread });
    114114
    115115        auto assignment = makeUniqueRef<AST::AssignmentExpression>(variable.origin(), WTFMove(lhs), WTFMove(rhs));
     
    137137            auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(functionDefinition.origin(), WTFMove(structVariableReference));
    138138            makePointerExpression->setType(m_pointerToStructType->clone());
    139             makePointerExpression->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread });
     139            makePointerExpression->setTypeAnnotation(AST::RightValue());
    140140
    141141            auto pointerDeclaration = makeUniqueRef<AST::VariableDeclaration>(functionDefinition.origin(), AST::Qualifiers(),
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp

    r246428 r246438  
    686686        }
    687687
    688         return {{ WTFMove(expressions), readModifyWriteExpression.newVariableReference() }};
     688        auto variableReference = readModifyWriteExpression.newVariableReference();
     689        variableReference->setType(readModifyWriteExpression.leftValue().resolvedType().clone());
     690        variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right?
     691
     692        return {{ WTFMove(expressions),  WTFMove(variableReference) }};
    689693    });
    690694
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt

    r246427 r246438  
    440440native bool operator<(uint, uint);
    441441native bool operator<(float, float);
     442native bool operator==(float, float);
     443native bool operator==(int, int);
     444native bool operator==(thread int*, thread int*);
    442445native float operator*(float, float);
    443446
  • trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm

    r246427 r246438  
    9393        computeLibrary = adoptNS([device.platformDevice() newLibraryWithSource:whlslCompileResult->metalSource options:nil error:&error]);
    9494        END_BLOCK_OBJC_EXCEPTIONS;
    95 
     95#ifndef NDEBUG
     96        if (!computeLibrary)
     97            NSLog(@"%@", error);
     98#endif
    9699        ASSERT(computeLibrary);
    97100        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195771 Once we zero-fill variables, there should be no warnings, so we should be able to ASSERT(!error) here.
  • trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm

    r246427 r246438  
    417417        END_BLOCK_OBJC_EXCEPTIONS;
    418418
     419#ifndef NDEBUG
     420        if (!vertexLibrary)
     421            NSLog(@"%@", error);
     422#endif
    419423        ASSERT(vertexLibrary);
    420424        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195771 Once we zero-fill variables, there should be no warnings, so we should be able to ASSERT(!error) here.
Note: See TracChangeset for help on using the changeset viewer.