blob: 6f7a419378ecc234d60fca2f3f4c8ef33777c6ee [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 Etuahofbb1c792018-01-19 16:26:59 +02009#include "compiler/translator/ImmutableString.h"
10#include "compiler/translator/ImmutableStringBuilder.h"
Olli Etuaho855d9642017-05-17 14:05:06 +030011#include "compiler/translator/IntermNode.h"
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +020012#include "compiler/translator/Symbol.h"
Olli Etuaho855d9642017-05-17 14:05:06 +030013
Olli Etuahocccf2b02017-07-05 14:50:54 +030014namespace sh
15{
16
Olli Etuaho855d9642017-05-17 14:05:06 +030017namespace
18{
19
20// GLSL ES 3.00.6 section 3.9: the maximum length of an identifier is 1024 characters.
21static const unsigned int kESSLMaxIdentifierLength = 1024u;
22
Olli Etuahofbb1c792018-01-19 16:26:59 +020023constexpr const ImmutableString kHashedNamePrefix("webgl_");
Olli Etuaho855d9642017-05-17 14:05:06 +030024
25// Can't prefix with just _ because then we might introduce a double underscore, which is not safe
26// in GLSL (ESSL 3.00.6 section 3.8: All identifiers containing a double underscore are reserved for
27// use by the underlying implementation). u is short for user-defined.
Olli Etuahofbb1c792018-01-19 16:26:59 +020028constexpr const ImmutableString kUnhashedNamePrefix("_u");
Olli Etuaho855d9642017-05-17 14:05:06 +030029
Olli Etuahofbb1c792018-01-19 16:26:59 +020030ImmutableString HashName(const ImmutableString &name, ShHashFunction64 hashFunction)
Olli Etuahocccf2b02017-07-05 14:50:54 +030031{
Olli Etuaho855d9642017-05-17 14:05:06 +030032 ASSERT(!name.empty());
33 ASSERT(hashFunction);
Olli Etuahofbb1c792018-01-19 16:26:59 +020034 khronos_uint64_t number = (*hashFunction)(name.data(), name.length());
35
36 // Build the hashed name in place.
37 static const unsigned int kHexStrMaxLength = sizeof(number) * 2;
38 static const size_t kHashedNameMaxLength = kHashedNamePrefix.length() + kHexStrMaxLength;
39
40 ImmutableStringBuilder hashedName(kHashedNameMaxLength);
41 hashedName << kHashedNamePrefix;
42
43 hashedName.appendHex(number);
44
Olli Etuahocccf2b02017-07-05 14:50:54 +030045 return hashedName;
46}
47
Olli Etuaho855d9642017-05-17 14:05:06 +030048} // anonymous namespace
49
Olli Etuahofbb1c792018-01-19 16:26:59 +020050ImmutableString HashName(const ImmutableString &name,
51 ShHashFunction64 hashFunction,
52 NameMap *nameMap)
Olli Etuaho855d9642017-05-17 14:05:06 +030053{
Olli Etuaho855d9642017-05-17 14:05:06 +030054 if (hashFunction == nullptr)
55 {
Olli Etuahofbb1c792018-01-19 16:26:59 +020056 if (name.length() + kUnhashedNamePrefix.length() > kESSLMaxIdentifierLength)
Olli Etuaho855d9642017-05-17 14:05:06 +030057 {
58 // If the identifier length is already close to the limit, we can't prefix it. This is
59 // not a problem since there are no builtins or ANGLE's internal variables that would
60 // have as long names and could conflict.
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +020061 return name;
Olli Etuaho855d9642017-05-17 14:05:06 +030062 }
Olli Etuahofbb1c792018-01-19 16:26:59 +020063 ImmutableStringBuilder prefixedName(kUnhashedNamePrefix.length() + name.length());
64 prefixedName << kUnhashedNamePrefix << name;
65 return prefixedName;
Olli Etuaho855d9642017-05-17 14:05:06 +030066 }
67 if (nameMap)
68 {
Olli Etuahofbb1c792018-01-19 16:26:59 +020069 NameMap::const_iterator it = nameMap->find(name.data());
Olli Etuaho855d9642017-05-17 14:05:06 +030070 if (it != nameMap->end())
Olli Etuahofbb1c792018-01-19 16:26:59 +020071 {
72 // TODO(oetuaho): Would be nice if we didn't need to allocate a string here.
73 return ImmutableString(it->second);
74 }
Olli Etuaho855d9642017-05-17 14:05:06 +030075 }
Olli Etuahofbb1c792018-01-19 16:26:59 +020076 ImmutableString hashedName = HashName(name, hashFunction);
Olli Etuaho855d9642017-05-17 14:05:06 +030077 if (nameMap)
78 {
Olli Etuahofbb1c792018-01-19 16:26:59 +020079 (*nameMap)[name.data()] = hashedName.data();
Olli Etuaho855d9642017-05-17 14:05:06 +030080 }
81 return hashedName;
82}
83
Olli Etuahofbb1c792018-01-19 16:26:59 +020084ImmutableString HashName(const TSymbol *symbol, ShHashFunction64 hashFunction, NameMap *nameMap)
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +020085{
86 if (symbol->symbolType() == SymbolType::Empty)
87 {
Olli Etuahofbb1c792018-01-19 16:26:59 +020088 return ImmutableString("");
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +020089 }
90 if (symbol->symbolType() == SymbolType::AngleInternal ||
91 symbol->symbolType() == SymbolType::BuiltIn)
92 {
93 return symbol->name();
94 }
95 return HashName(symbol->name(), hashFunction, nameMap);
96}
97
Olli Etuahocccf2b02017-07-05 14:50:54 +030098} // namespace sh