1 //
2 // Copyright 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
9 #include "compiler/translator/ImmutableString.h"
10 #include "compiler/translator/ImmutableStringBuilder.h"
11 #include "compiler/translator/IntermNode.h"
12 #include "compiler/translator/Symbol.h"
13
14 namespace sh
15 {
16
17 namespace
18 {
19 constexpr const ImmutableString kHashedNamePrefix("webgl_");
20
HashName(const ImmutableString & name,ShHashFunction64 hashFunction)21 ImmutableString HashName(const ImmutableString &name, ShHashFunction64 hashFunction)
22 {
23 ASSERT(!name.empty());
24 ASSERT(hashFunction);
25 khronos_uint64_t number = (*hashFunction)(name.data(), name.length());
26
27 // Build the hashed name in place.
28 static const unsigned int kHexStrMaxLength = sizeof(number) * 2;
29 static const size_t kHashedNameMaxLength = kHashedNamePrefix.length() + kHexStrMaxLength;
30
31 ImmutableStringBuilder hashedName(kHashedNameMaxLength);
32 hashedName << kHashedNamePrefix;
33
34 hashedName.appendHex(number);
35
36 return hashedName;
37 }
38
AddToNameMapIfNotMapped(const ImmutableString & name,const ImmutableString & hashedName,NameMap * nameMap)39 void AddToNameMapIfNotMapped(const ImmutableString &name,
40 const ImmutableString &hashedName,
41 NameMap *nameMap)
42 {
43 if (nameMap)
44 {
45 NameMap::const_iterator it = nameMap->find(name.data());
46 if (it != nameMap->end())
47 {
48 // (How bout returning?)
49 return;
50 }
51 (*nameMap)[name.data()] = hashedName.data();
52 }
53 }
54
55 } // anonymous namespace
56
HashName(const ImmutableString & name,ShHashFunction64 hashFunction,NameMap * nameMap)57 ImmutableString HashName(const ImmutableString &name,
58 ShHashFunction64 hashFunction,
59 NameMap *nameMap)
60 {
61 const ImmutableString kUnhashedNamePrefix(kUserDefinedNamePrefix);
62
63 if (hashFunction == nullptr)
64 {
65 if (name.length() + kUnhashedNamePrefix.length() > kESSLMaxIdentifierLength)
66 {
67 // If the identifier length is already close to the limit, we can't prefix it. This is
68 // not a problem since there are no builtins or ANGLE's internal variables that would
69 // have as long names and could conflict.
70 return name;
71 }
72 ImmutableStringBuilder prefixedName(kUnhashedNamePrefix.length() + name.length());
73 prefixedName << kUnhashedNamePrefix << name;
74 ImmutableString res = prefixedName;
75 AddToNameMapIfNotMapped(name, res, nameMap);
76 return res;
77 }
78
79 // Has a hash function
80 ImmutableString hashedName = HashName(name, hashFunction);
81 AddToNameMapIfNotMapped(name, hashedName, nameMap);
82 return hashedName;
83 }
84
HashName(const TSymbol * symbol,ShHashFunction64 hashFunction,NameMap * nameMap)85 ImmutableString HashName(const TSymbol *symbol, ShHashFunction64 hashFunction, NameMap *nameMap)
86 {
87 if (symbol->symbolType() == SymbolType::Empty)
88 {
89 return kEmptyImmutableString;
90 }
91 if (symbol->symbolType() == SymbolType::AngleInternal ||
92 symbol->symbolType() == SymbolType::BuiltIn)
93 {
94 return symbol->name();
95 }
96 return HashName(symbol->name(), hashFunction, nameMap);
97 }
98
99 } // namespace sh
100