tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

RegenerateStructNames.cpp (3805B)


      1 //
      2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 #include "compiler/translator/tree_ops/gl/RegenerateStructNames.h"
      8 
      9 #include "common/debug.h"
     10 #include "compiler/translator/Compiler.h"
     11 #include "compiler/translator/ImmutableStringBuilder.h"
     12 #include "compiler/translator/SymbolTable.h"
     13 #include "compiler/translator/tree_util/IntermTraverse.h"
     14 
     15 #include <set>
     16 
     17 namespace sh
     18 {
     19 
     20 namespace
     21 {
     22 constexpr const ImmutableString kPrefix("_webgl_struct_");
     23 }  // anonymous namespace
     24 
     25 class RegenerateStructNamesTraverser : public TIntermTraverser
     26 {
     27  public:
     28    RegenerateStructNamesTraverser(TSymbolTable *symbolTable)
     29        : TIntermTraverser(true, false, false, symbolTable), mScopeDepth(0)
     30    {}
     31 
     32  protected:
     33    void visitSymbol(TIntermSymbol *) override;
     34    bool visitBlock(Visit, TIntermBlock *block) override;
     35 
     36  private:
     37    // Indicating the depth of the current scope.
     38    // The global scope is 1.
     39    int mScopeDepth;
     40 
     41    // If a struct is declared globally, push its ID in this set.
     42    std::set<int> mDeclaredGlobalStructs;
     43 };
     44 
     45 void RegenerateStructNamesTraverser::visitSymbol(TIntermSymbol *symbol)
     46 {
     47    ASSERT(symbol);
     48    const TType &type          = symbol->getType();
     49    const TStructure *userType = type.getStruct();
     50    if (!userType)
     51        return;
     52 
     53    if (userType->symbolType() == SymbolType::BuiltIn ||
     54        userType->symbolType() == SymbolType::Empty)
     55    {
     56        // Built-in struct or nameless struct, do not touch it.
     57        return;
     58    }
     59 
     60    int uniqueId = userType->uniqueId().get();
     61 
     62    ASSERT(mScopeDepth > 0);
     63    if (mScopeDepth == 1)
     64    {
     65        // If a struct is defined at global scope, we don't map its name.
     66        // This is because at global level, the struct might be used to
     67        // declare a uniform, so the same name needs to stay the same for
     68        // vertex/fragment shaders. However, our mapping uses internal ID,
     69        // which will be different for the same struct in vertex/fragment
     70        // shaders.
     71        // This is OK because names for any structs defined in other scopes
     72        // will begin with "_webgl", which is reserved. So there will be
     73        // no conflicts among unmapped struct names from global scope and
     74        // mapped struct names from other scopes.
     75        // However, we need to keep track of these global structs, so if a
     76        // variable is used in a local scope, we don't try to modify the
     77        // struct name through that variable.
     78        mDeclaredGlobalStructs.insert(uniqueId);
     79        return;
     80    }
     81    if (mDeclaredGlobalStructs.count(uniqueId) > 0)
     82        return;
     83    // Map {name} to _webgl_struct_{uniqueId}_{name}.
     84    if (userType->name().beginsWith(kPrefix))
     85    {
     86        // The name has already been regenerated.
     87        return;
     88    }
     89    ImmutableStringBuilder tmp(kPrefix.length() + sizeof(uniqueId) * 2u + 1u +
     90                               userType->name().length());
     91    tmp << kPrefix;
     92    tmp.appendHex(uniqueId);
     93    tmp << '_' << userType->name();
     94 
     95    // TODO(oetuaho): Add another mechanism to change symbol names so that the const_cast is not
     96    // needed.
     97    const_cast<TStructure *>(userType)->setName(tmp);
     98 }
     99 
    100 bool RegenerateStructNamesTraverser::visitBlock(Visit, TIntermBlock *block)
    101 {
    102    ++mScopeDepth;
    103    TIntermSequence &sequence = *(block->getSequence());
    104    for (TIntermNode *node : sequence)
    105    {
    106        node->traverse(this);
    107    }
    108    --mScopeDepth;
    109    return false;
    110 }
    111 
    112 bool RegenerateStructNames(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable)
    113 {
    114    RegenerateStructNamesTraverser traverser(symbolTable);
    115    root->traverse(&traverser);
    116    return compiler->validateAST(root);
    117 }
    118 
    119 }  // namespace sh