| // | |
| // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // | |
| #include "compiler/MapLongVariableNames.h" | |
| namespace { | |
| TString mapLongName(size_t id, const TString& name, bool isGlobal) | |
| { | |
| ASSERT(name.size() > MAX_SHORTENED_IDENTIFIER_SIZE); | |
| TStringStream stream; | |
| stream << "webgl_"; | |
| if (isGlobal) | |
| stream << "g"; | |
| stream << id; | |
| if (name[0] != '_') | |
| stream << "_"; | |
| stream << name.substr(0, MAX_SHORTENED_IDENTIFIER_SIZE - stream.str().size()); | |
| return stream.str(); | |
| } | |
| LongNameMap* gLongNameMapInstance = NULL; | |
| } // anonymous namespace | |
| LongNameMap::LongNameMap() | |
| : refCount(0) | |
| { | |
| } | |
| LongNameMap::~LongNameMap() | |
| { | |
| } | |
| // static | |
| LongNameMap* LongNameMap::GetInstance() | |
| { | |
| if (gLongNameMapInstance == NULL) | |
| gLongNameMapInstance = new LongNameMap; | |
| gLongNameMapInstance->refCount++; | |
| return gLongNameMapInstance; | |
| } | |
| void LongNameMap::Release() | |
| { | |
| ASSERT(gLongNameMapInstance == this); | |
| ASSERT(refCount > 0); | |
| refCount--; | |
| if (refCount == 0) { | |
| delete gLongNameMapInstance; | |
| gLongNameMapInstance = NULL; | |
| } | |
| } | |
| const char* LongNameMap::Find(const char* originalName) const | |
| { | |
| std::map<std::string, std::string>::const_iterator it = mLongNameMap.find( | |
| originalName); | |
| if (it != mLongNameMap.end()) | |
| return (*it).second.c_str(); | |
| return NULL; | |
| } | |
| void LongNameMap::Insert(const char* originalName, const char* mappedName) | |
| { | |
| mLongNameMap.insert(std::map<std::string, std::string>::value_type( | |
| originalName, mappedName)); | |
| } | |
| size_t LongNameMap::Size() const | |
| { | |
| return mLongNameMap.size(); | |
| } | |
| MapLongVariableNames::MapLongVariableNames(LongNameMap* globalMap) | |
| { | |
| ASSERT(globalMap); | |
| mGlobalMap = globalMap; | |
| } | |
| void MapLongVariableNames::visitSymbol(TIntermSymbol* symbol) | |
| { | |
| ASSERT(symbol != NULL); | |
| if (symbol->getSymbol().size() > MAX_SHORTENED_IDENTIFIER_SIZE) { | |
| switch (symbol->getQualifier()) { | |
| case EvqVaryingIn: | |
| case EvqVaryingOut: | |
| case EvqInvariantVaryingIn: | |
| case EvqInvariantVaryingOut: | |
| case EvqUniform: | |
| symbol->setSymbol( | |
| mapGlobalLongName(symbol->getSymbol())); | |
| break; | |
| default: | |
| symbol->setSymbol( | |
| mapLongName(symbol->getId(), symbol->getSymbol(), false)); | |
| break; | |
| }; | |
| } | |
| } | |
| bool MapLongVariableNames::visitLoop(Visit, TIntermLoop* node) | |
| { | |
| if (node->getInit()) | |
| node->getInit()->traverse(this); | |
| return true; | |
| } | |
| TString MapLongVariableNames::mapGlobalLongName(const TString& name) | |
| { | |
| ASSERT(mGlobalMap); | |
| const char* mappedName = mGlobalMap->Find(name.c_str()); | |
| if (mappedName != NULL) | |
| return mappedName; | |
| size_t id = mGlobalMap->Size(); | |
| TString rt = mapLongName(id, name, true); | |
| mGlobalMap->Insert(name.c_str(), rt.c_str()); | |
| return rt; | |
| } |