blob: 6d0ddaf2428d84bedf469afd96a3319aabfcf5e1 [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{
Olli Etuahofbb1c792018-01-19 16:26:59 +020019constexpr const ImmutableString kHashedNamePrefix("webgl_");
Olli Etuaho855d9642017-05-17 14:05:06 +030020
21// Can't prefix with just _ because then we might introduce a double underscore, which is not safe
22// in GLSL (ESSL 3.00.6 section 3.8: All identifiers containing a double underscore are reserved for
23// use by the underlying implementation). u is short for user-defined.
Olli Etuahofbb1c792018-01-19 16:26:59 +020024constexpr const ImmutableString kUnhashedNamePrefix("_u");
Olli Etuaho855d9642017-05-17 14:05:06 +030025
Olli Etuahofbb1c792018-01-19 16:26:59 +020026ImmutableString HashName(const ImmutableString &name, ShHashFunction64 hashFunction)
Olli Etuahocccf2b02017-07-05 14:50:54 +030027{
Olli Etuaho855d9642017-05-17 14:05:06 +030028 ASSERT(!name.empty());
29 ASSERT(hashFunction);
Olli Etuahofbb1c792018-01-19 16:26:59 +020030 khronos_uint64_t number = (*hashFunction)(name.data(), name.length());
31
32 // Build the hashed name in place.
33 static const unsigned int kHexStrMaxLength = sizeof(number) * 2;
34 static const size_t kHashedNameMaxLength = kHashedNamePrefix.length() + kHexStrMaxLength;
35
36 ImmutableStringBuilder hashedName(kHashedNameMaxLength);
37 hashedName << kHashedNamePrefix;
38
39 hashedName.appendHex(number);
40
Olli Etuahocccf2b02017-07-05 14:50:54 +030041 return hashedName;
42}
43
Olli Etuaho855d9642017-05-17 14:05:06 +030044} // anonymous namespace
45
Olli Etuahofbb1c792018-01-19 16:26:59 +020046ImmutableString HashName(const ImmutableString &name,
47 ShHashFunction64 hashFunction,
48 NameMap *nameMap)
Olli Etuaho855d9642017-05-17 14:05:06 +030049{
Olli Etuaho855d9642017-05-17 14:05:06 +030050 if (hashFunction == nullptr)
51 {
Olli Etuahofbb1c792018-01-19 16:26:59 +020052 if (name.length() + kUnhashedNamePrefix.length() > kESSLMaxIdentifierLength)
Olli Etuaho855d9642017-05-17 14:05:06 +030053 {
54 // If the identifier length is already close to the limit, we can't prefix it. This is
55 // not a problem since there are no builtins or ANGLE's internal variables that would
56 // have as long names and could conflict.
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +020057 return name;
Olli Etuaho855d9642017-05-17 14:05:06 +030058 }
Olli Etuahofbb1c792018-01-19 16:26:59 +020059 ImmutableStringBuilder prefixedName(kUnhashedNamePrefix.length() + name.length());
60 prefixedName << kUnhashedNamePrefix << name;
61 return prefixedName;
Olli Etuaho855d9642017-05-17 14:05:06 +030062 }
63 if (nameMap)
64 {
Olli Etuahofbb1c792018-01-19 16:26:59 +020065 NameMap::const_iterator it = nameMap->find(name.data());
Olli Etuaho855d9642017-05-17 14:05:06 +030066 if (it != nameMap->end())
Olli Etuahofbb1c792018-01-19 16:26:59 +020067 {
68 // TODO(oetuaho): Would be nice if we didn't need to allocate a string here.
69 return ImmutableString(it->second);
70 }
Olli Etuaho855d9642017-05-17 14:05:06 +030071 }
Olli Etuahofbb1c792018-01-19 16:26:59 +020072 ImmutableString hashedName = HashName(name, hashFunction);
Olli Etuaho855d9642017-05-17 14:05:06 +030073 if (nameMap)
74 {
Olli Etuahofbb1c792018-01-19 16:26:59 +020075 (*nameMap)[name.data()] = hashedName.data();
Olli Etuaho855d9642017-05-17 14:05:06 +030076 }
77 return hashedName;
78}
79
Olli Etuahofbb1c792018-01-19 16:26:59 +020080ImmutableString HashName(const TSymbol *symbol, ShHashFunction64 hashFunction, NameMap *nameMap)
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +020081{
82 if (symbol->symbolType() == SymbolType::Empty)
83 {
Olli Etuahofbb1c792018-01-19 16:26:59 +020084 return ImmutableString("");
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +020085 }
86 if (symbol->symbolType() == SymbolType::AngleInternal ||
87 symbol->symbolType() == SymbolType::BuiltIn)
88 {
89 return symbol->name();
90 }
91 return HashName(symbol->name(), hashFunction, nameMap);
92}
93
Olli Etuahocccf2b02017-07-05 14:50:54 +030094} // namespace sh