Minor refactoring of TSymbolTable.
Used pointers for precision-stack entries as well to avoid unnecessarily re-allocating PrecisionStackLevel whenever the vector needs to resize.
Added a scoped class to properly restore symbol-table level after each compile.
R=kbr@chromium.org
Review URL: https://codereview.appspot.com/12583047
diff --git a/src/compiler/Compiler.cpp b/src/compiler/Compiler.cpp
index 1f5eb16..37b5ab2 100644
--- a/src/compiler/Compiler.cpp
+++ b/src/compiler/Compiler.cpp
@@ -30,19 +30,32 @@
namespace {
class TScopedPoolAllocator {
public:
- TScopedPoolAllocator(TPoolAllocator* allocator, bool pushPop)
- : mAllocator(allocator), mPushPopAllocator(pushPop) {
- if (mPushPopAllocator) mAllocator->push();
+ TScopedPoolAllocator(TPoolAllocator* allocator) : mAllocator(allocator) {
+ mAllocator->push();
SetGlobalPoolAllocator(mAllocator);
}
~TScopedPoolAllocator() {
SetGlobalPoolAllocator(NULL);
- if (mPushPopAllocator) mAllocator->pop();
+ mAllocator->pop();
}
private:
TPoolAllocator* mAllocator;
- bool mPushPopAllocator;
+};
+
+class TScopedSymbolTableLevel {
+public:
+ TScopedSymbolTableLevel(TSymbolTable* table) : mTable(table) {
+ ASSERT(mTable->atBuiltInLevel());
+ mTable->push();
+ }
+ ~TScopedSymbolTableLevel() {
+ while (!mTable->atBuiltInLevel())
+ mTable->pop();
+ }
+
+private:
+ TSymbolTable* mTable;
};
} // namespace
@@ -83,7 +96,8 @@
resources.MaxFragmentUniformVectors;
maxExpressionComplexity = resources.MaxExpressionComplexity;
maxCallStackDepth = resources.MaxCallStackDepth;
- TScopedPoolAllocator scopedAlloc(&allocator, false);
+
+ SetGlobalPoolAllocator(&allocator);
// Generate built-in symbol table.
if (!InitBuiltInSymbolTable(resources))
@@ -103,7 +117,7 @@
size_t numStrings,
int compileOptions)
{
- TScopedPoolAllocator scopedAlloc(&allocator, true);
+ TScopedPoolAllocator scopedAlloc(&allocator);
clearResults();
if (numStrings == 0)
@@ -131,11 +145,7 @@
// We preserve symbols at the built-in level from compile-to-compile.
// Start pushing the user-defined symbols at global level.
- symbolTable.push();
- if (!symbolTable.atGlobalLevel()) {
- infoSink.info.prefix(EPrefixInternalError);
- infoSink.info << "Wrong symbol table level";
- }
+ TScopedSymbolTableLevel scopedSymbolLevel(&symbolTable);
// Parse shader.
bool success =
@@ -206,10 +216,6 @@
// Cleanup memory.
intermediate.remove(parseContext.treeRoot);
- // Ensure symbol table is returned to the built-in level,
- // throwing away all but the built-ins.
- while (!symbolTable.atBuiltInLevel())
- symbolTable.pop();
return success;
}
diff --git a/src/compiler/SymbolTable.cpp b/src/compiler/SymbolTable.cpp
index f9daad4..1132386 100644
--- a/src/compiler/SymbolTable.cpp
+++ b/src/compiler/SymbolTable.cpp
@@ -246,3 +246,9 @@
return 0;
}
+
+TSymbolTable::~TSymbolTable()
+{
+ while (table.size() > 0)
+ pop();
+}
diff --git a/src/compiler/SymbolTable.h b/src/compiler/SymbolTable.h
index 7fa2c9c..d4849d2 100644
--- a/src/compiler/SymbolTable.h
+++ b/src/compiler/SymbolTable.h
@@ -42,7 +42,7 @@
class TSymbol {
public:
POOL_ALLOCATOR_NEW_DELETE();
- TSymbol(const TString *n) : name(n) { }
+ TSymbol(const TString* n) : uniqueId(0), name(n) { }
virtual ~TSymbol() { /* don't delete name, it's from the pool */ }
const TString& getName() const { return *name; }
@@ -57,8 +57,8 @@
private:
DISALLOW_COPY_AND_ASSIGN(TSymbol);
+ int uniqueId; // For real comparing during code generation
const TString *name;
- unsigned int uniqueId; // For real comparing during code generation
TString extension;
};
@@ -194,7 +194,6 @@
typedef const tLevel::value_type tLevelPair;
typedef std::pair<tLevel::iterator, bool> tInsertResult;
- POOL_ALLOCATOR_NEW_DELETE();
TSymbolTableLevel() { }
~TSymbolTableLevel();
@@ -205,8 +204,7 @@
//
// returning true means symbol was added to the table
//
- tInsertResult result;
- result = level.insert(tLevelPair(name, &symbol));
+ tInsertResult result = level.insert(tLevelPair(name, &symbol));
return result.second;
}
@@ -253,11 +251,7 @@
//
}
- ~TSymbolTable()
- {
- while (table.size() > 0)
- pop();
- }
+ ~TSymbolTable();
//
// When the symbol table is initialized with the built-ins, there should
@@ -270,13 +264,15 @@
void push()
{
table.push_back(new TSymbolTableLevel);
- precisionStack.push_back( PrecisionStackLevel() );
+ precisionStack.push_back(new PrecisionStackLevel);
}
void pop()
- {
- delete table[currentLevel()];
- table.pop_back();
+ {
+ delete table.back();
+ table.pop_back();
+
+ delete precisionStack.back();
precisionStack.pop_back();
}
@@ -333,8 +329,9 @@
void relateToExtension(ESymbolLevel level, const char* name, const TString& ext) {
table[level]->relateToExtension(name, ext);
}
+ void dump(TInfoSink &infoSink) const;
- bool setDefaultPrecision( const TPublicType& type, TPrecision prec ){
+ bool setDefaultPrecision(const TPublicType& type, TPrecision prec) {
if (IsSampler(type.type))
return true; // Skip sampler types for the time being
if (type.type != EbtFloat && type.type != EbtInt)
@@ -342,7 +339,7 @@
if (type.isAggregate())
return false; // Not allowed to set for aggregate types
int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1;
- precisionStack[indexOfLastElement][type.type] = prec; // Uses map operator [], overwrites the current value
+ (*precisionStack[indexOfLastElement])[type.type] = prec; // Uses map operator [], overwrites the current value
return true;
}
@@ -350,16 +347,19 @@
TPrecision getDefaultPrecision( TBasicType type){
// unsigned integers use the same precision as signed
- if (type == EbtUInt) type = EbtInt;
+ if (type == EbtUInt)
+ type = EbtInt;
- if( type != EbtFloat && type != EbtInt ) return EbpUndefined;
+ if (type != EbtFloat && type != EbtInt)
+ return EbpUndefined;
+
int level = static_cast<int>(precisionStack.size()) - 1;
- assert( level >= 0); // Just to be safe. Should not happen.
+ assert(level >= 0); // Just to be safe. Should not happen.
PrecisionStackLevel::iterator it;
TPrecision prec = EbpUndefined; // If we dont find anything we return this. Should we error check this?
- while( level >= 0 ){
- it = precisionStack[level].find( type );
- if( it != precisionStack[level].end() ){
+ while (level >= 0) {
+ it = precisionStack[level]->find(type);
+ if (it != precisionStack[level]->end()) {
prec = (*it).second;
break;
}
@@ -368,12 +368,12 @@
return prec;
}
-protected:
+private:
ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); }
std::vector<TSymbolTableLevel*> table;
- typedef std::map< TBasicType, TPrecision > PrecisionStackLevel;
- std::vector< PrecisionStackLevel > precisionStack;
+ typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
+ std::vector< PrecisionStackLevel*> precisionStack;
};
#endif // _SYMBOL_TABLE_INCLUDED_