blob: df448d87df882bcdba8f151d17fe1b9bddafe117 [file] [log] [blame]
Olli Etuahocccf2b02017-07-05 14:50:54 +03001//
2// Copyright (c) 2017 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/HashNames.h"
8
Olli Etuaho855d9642017-05-17 14:05:06 +03009#include "compiler/translator/IntermNode.h"
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +020010#include "compiler/translator/Symbol.h"
Olli Etuaho855d9642017-05-17 14:05:06 +030011
Olli Etuahocccf2b02017-07-05 14:50:54 +030012namespace sh
13{
14
Olli Etuaho855d9642017-05-17 14:05:06 +030015namespace
16{
17
18// GLSL ES 3.00.6 section 3.9: the maximum length of an identifier is 1024 characters.
19static const unsigned int kESSLMaxIdentifierLength = 1024u;
20
21static const char *kHashedNamePrefix = "webgl_";
22
23// Can't prefix with just _ because then we might introduce a double underscore, which is not safe
24// in GLSL (ESSL 3.00.6 section 3.8: All identifiers containing a double underscore are reserved for
25// use by the underlying implementation). u is short for user-defined.
26static const char *kUnhashedNamePrefix = "_u";
27static const unsigned int kUnhashedNamePrefixLength = 2u;
28
Olli Etuahocccf2b02017-07-05 14:50:54 +030029TString HashName(const TString &name, ShHashFunction64 hashFunction)
30{
Olli Etuaho855d9642017-05-17 14:05:06 +030031 ASSERT(!name.empty());
32 ASSERT(hashFunction);
Olli Etuahocccf2b02017-07-05 14:50:54 +030033 khronos_uint64_t number = (*hashFunction)(name.c_str(), name.length());
34 TStringStream stream;
Olli Etuaho855d9642017-05-17 14:05:06 +030035 stream << kHashedNamePrefix << std::hex << number;
Olli Etuahocccf2b02017-07-05 14:50:54 +030036 TString hashedName = stream.str();
37 return hashedName;
38}
39
Olli Etuaho855d9642017-05-17 14:05:06 +030040} // anonymous namespace
41
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +020042TString HashName(const TString &name, ShHashFunction64 hashFunction, NameMap *nameMap)
Olli Etuaho855d9642017-05-17 14:05:06 +030043{
Olli Etuaho855d9642017-05-17 14:05:06 +030044 if (hashFunction == nullptr)
45 {
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +020046 if (name.length() + kUnhashedNamePrefixLength > kESSLMaxIdentifierLength)
Olli Etuaho855d9642017-05-17 14:05:06 +030047 {
48 // If the identifier length is already close to the limit, we can't prefix it. This is
49 // not a problem since there are no builtins or ANGLE's internal variables that would
50 // have as long names and could conflict.
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +020051 return name;
Olli Etuaho855d9642017-05-17 14:05:06 +030052 }
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +020053 return kUnhashedNamePrefix + name;
Olli Etuaho855d9642017-05-17 14:05:06 +030054 }
55 if (nameMap)
56 {
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +020057 NameMap::const_iterator it = nameMap->find(name.c_str());
Olli Etuaho855d9642017-05-17 14:05:06 +030058 if (it != nameMap->end())
59 return it->second.c_str();
60 }
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +020061 TString hashedName = HashName(name, hashFunction);
Olli Etuaho855d9642017-05-17 14:05:06 +030062 if (nameMap)
63 {
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +020064 (*nameMap)[name.c_str()] = hashedName.c_str();
Olli Etuaho855d9642017-05-17 14:05:06 +030065 }
66 return hashedName;
67}
68
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +020069TString HashName(const TSymbol *symbol, ShHashFunction64 hashFunction, NameMap *nameMap)
70{
71 if (symbol->symbolType() == SymbolType::Empty)
72 {
73 return TString();
74 }
75 if (symbol->symbolType() == SymbolType::AngleInternal ||
76 symbol->symbolType() == SymbolType::BuiltIn)
77 {
78 return symbol->name();
79 }
80 return HashName(symbol->name(), hashFunction, nameMap);
81}
82
Olli Etuahocccf2b02017-07-05 14:50:54 +030083} // namespace sh