1 : //
2 : // Copyright (c) 2002-2012 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/MapLongVariableNames.h"
8 : #include "spooky.h"
9 :
10 : namespace {
11 :
12 0 : TString mapLongName(int id, const TString& name, bool isGlobal)
13 : {
14 0 : ASSERT(name.size() > MAX_SHORTENED_IDENTIFIER_SIZE);
15 0 : TStringStream stream;
16 0 : uint64 hash = SpookyHash::Hash64(name.data(), name.length(), 0);
17 0 : stream << "webgl_"
18 0 : << name.substr(0, 9)
19 0 : << "_"
20 0 : << std::hex
21 0 : << hash;
22 0 : ASSERT(stream.str().length() == MAX_SHORTENED_IDENTIFIER_SIZE);
23 0 : return stream.str();
24 : }
25 :
26 : LongNameMap* gLongNameMapInstance = NULL;
27 :
28 : } // anonymous namespace
29 :
30 0 : LongNameMap::LongNameMap()
31 0 : : refCount(0)
32 : {
33 0 : }
34 :
35 0 : LongNameMap::~LongNameMap()
36 : {
37 0 : }
38 :
39 : // static
40 0 : LongNameMap* LongNameMap::GetInstance()
41 : {
42 0 : if (gLongNameMapInstance == NULL)
43 0 : gLongNameMapInstance = new LongNameMap;
44 0 : gLongNameMapInstance->refCount++;
45 0 : return gLongNameMapInstance;
46 : }
47 :
48 0 : void LongNameMap::Release()
49 : {
50 0 : ASSERT(gLongNameMapInstance == this);
51 0 : ASSERT(refCount > 0);
52 0 : refCount--;
53 0 : if (refCount == 0) {
54 0 : delete gLongNameMapInstance;
55 0 : gLongNameMapInstance = NULL;
56 : }
57 0 : }
58 :
59 0 : const char* LongNameMap::Find(const char* originalName) const
60 : {
61 : std::map<std::string, std::string>::const_iterator it = mLongNameMap.find(
62 0 : originalName);
63 0 : if (it != mLongNameMap.end())
64 0 : return (*it).second.c_str();
65 0 : return NULL;
66 : }
67 :
68 0 : void LongNameMap::Insert(const char* originalName, const char* mappedName)
69 : {
70 : mLongNameMap.insert(std::map<std::string, std::string>::value_type(
71 0 : originalName, mappedName));
72 0 : }
73 :
74 0 : int LongNameMap::Size() const
75 : {
76 0 : return mLongNameMap.size();
77 : }
78 :
79 0 : MapLongVariableNames::MapLongVariableNames(LongNameMap* globalMap)
80 : {
81 0 : ASSERT(globalMap);
82 0 : mGlobalMap = globalMap;
83 0 : }
84 :
85 0 : void MapLongVariableNames::visitSymbol(TIntermSymbol* symbol)
86 : {
87 0 : ASSERT(symbol != NULL);
88 0 : if (symbol->getSymbol().size() > MAX_SHORTENED_IDENTIFIER_SIZE) {
89 0 : switch (symbol->getQualifier()) {
90 : case EvqVaryingIn:
91 : case EvqVaryingOut:
92 : case EvqInvariantVaryingIn:
93 : case EvqInvariantVaryingOut:
94 : case EvqUniform:
95 : symbol->setSymbol(
96 0 : mapGlobalLongName(symbol->getSymbol()));
97 0 : break;
98 : default:
99 : symbol->setSymbol(
100 0 : mapLongName(symbol->getId(), symbol->getSymbol(), false));
101 0 : break;
102 : };
103 : }
104 0 : }
105 :
106 0 : bool MapLongVariableNames::visitLoop(Visit, TIntermLoop* node)
107 : {
108 0 : if (node->getInit())
109 0 : node->getInit()->traverse(this);
110 0 : return true;
111 : }
112 :
113 0 : TString MapLongVariableNames::mapGlobalLongName(const TString& name)
114 : {
115 0 : ASSERT(mGlobalMap);
116 0 : const char* mappedName = mGlobalMap->Find(name.c_str());
117 0 : if (mappedName != NULL)
118 0 : return mappedName;
119 0 : int id = mGlobalMap->Size();
120 0 : TString rt = mapLongName(id, name, true);
121 0 : mGlobalMap->Insert(name.c_str(), rt.c_str());
122 0 : return rt;
123 : }
|