Commit a6829d57 by Alok Priyadarshi

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
parent a612ed8e
...@@ -29,19 +29,32 @@ bool isWebGLBasedSpec(ShShaderSpec spec) ...@@ -29,19 +29,32 @@ bool isWebGLBasedSpec(ShShaderSpec spec)
namespace { namespace {
class TScopedPoolAllocator { class TScopedPoolAllocator {
public: public:
TScopedPoolAllocator(TPoolAllocator* allocator, bool pushPop) TScopedPoolAllocator(TPoolAllocator* allocator) : mAllocator(allocator) {
: mAllocator(allocator), mPushPopAllocator(pushPop) { mAllocator->push();
if (mPushPopAllocator) mAllocator->push();
SetGlobalPoolAllocator(mAllocator); SetGlobalPoolAllocator(mAllocator);
} }
~TScopedPoolAllocator() { ~TScopedPoolAllocator() {
SetGlobalPoolAllocator(NULL); SetGlobalPoolAllocator(NULL);
if (mPushPopAllocator) mAllocator->pop(); mAllocator->pop();
} }
private: private:
TPoolAllocator* mAllocator; 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 } // namespace
...@@ -81,7 +94,8 @@ bool TCompiler::Init(const ShBuiltInResources& resources) ...@@ -81,7 +94,8 @@ bool TCompiler::Init(const ShBuiltInResources& resources)
resources.MaxFragmentUniformVectors; resources.MaxFragmentUniformVectors;
maxExpressionComplexity = resources.MaxExpressionComplexity; maxExpressionComplexity = resources.MaxExpressionComplexity;
maxCallStackDepth = resources.MaxCallStackDepth; maxCallStackDepth = resources.MaxCallStackDepth;
TScopedPoolAllocator scopedAlloc(&allocator, false);
SetGlobalPoolAllocator(&allocator);
// Generate built-in symbol table. // Generate built-in symbol table.
if (!InitBuiltInSymbolTable(resources)) if (!InitBuiltInSymbolTable(resources))
...@@ -101,7 +115,7 @@ bool TCompiler::compile(const char* const shaderStrings[], ...@@ -101,7 +115,7 @@ bool TCompiler::compile(const char* const shaderStrings[],
size_t numStrings, size_t numStrings,
int compileOptions) int compileOptions)
{ {
TScopedPoolAllocator scopedAlloc(&allocator, true); TScopedPoolAllocator scopedAlloc(&allocator);
clearResults(); clearResults();
if (numStrings == 0) if (numStrings == 0)
...@@ -129,11 +143,7 @@ bool TCompiler::compile(const char* const shaderStrings[], ...@@ -129,11 +143,7 @@ bool TCompiler::compile(const char* const shaderStrings[],
// We preserve symbols at the built-in level from compile-to-compile. // We preserve symbols at the built-in level from compile-to-compile.
// Start pushing the user-defined symbols at global level. // Start pushing the user-defined symbols at global level.
symbolTable.push(); TScopedSymbolTableLevel scopedSymbolLevel(&symbolTable);
if (!symbolTable.atGlobalLevel()) {
infoSink.info.prefix(EPrefixInternalError);
infoSink.info << "Wrong symbol table level";
}
// Parse shader. // Parse shader.
bool success = bool success =
...@@ -198,10 +208,6 @@ bool TCompiler::compile(const char* const shaderStrings[], ...@@ -198,10 +208,6 @@ bool TCompiler::compile(const char* const shaderStrings[],
// Cleanup memory. // Cleanup memory.
intermediate.remove(parseContext.treeRoot); 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; return success;
} }
......
...@@ -206,3 +206,11 @@ void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext) ...@@ -206,3 +206,11 @@ void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
symbol->relateToExtension(ext); symbol->relateToExtension(ext);
} }
} }
TSymbolTable::~TSymbolTable()
{
for (size_t i = 0; i < table.size(); ++i)
delete table[i];
for (size_t i = 0; i < precisionStack.size(); ++i)
delete precisionStack[i];
}
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
class TSymbol { class TSymbol {
public: public:
POOL_ALLOCATOR_NEW_DELETE(); 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 */ } virtual ~TSymbol() { /* don't delete name, it's from the pool */ }
const TString& getName() const { return *name; } const TString& getName() const { return *name; }
...@@ -58,8 +58,8 @@ public: ...@@ -58,8 +58,8 @@ public:
private: private:
DISALLOW_COPY_AND_ASSIGN(TSymbol); DISALLOW_COPY_AND_ASSIGN(TSymbol);
int uniqueId; // For real comparing during code generation
const TString *name; const TString *name;
unsigned int uniqueId; // For real comparing during code generation
TString extension; TString extension;
}; };
...@@ -187,7 +187,6 @@ public: ...@@ -187,7 +187,6 @@ public:
typedef const tLevel::value_type tLevelPair; typedef const tLevel::value_type tLevelPair;
typedef std::pair<tLevel::iterator, bool> tInsertResult; typedef std::pair<tLevel::iterator, bool> tInsertResult;
POOL_ALLOCATOR_NEW_DELETE();
TSymbolTableLevel() { } TSymbolTableLevel() { }
~TSymbolTableLevel(); ~TSymbolTableLevel();
...@@ -196,8 +195,7 @@ public: ...@@ -196,8 +195,7 @@ public:
// //
// returning true means symbol was added to the table // returning true means symbol was added to the table
// //
tInsertResult result; tInsertResult result = level.insert(tLevelPair(name, &symbol));
result = level.insert(tLevelPair(name, &symbol));
return result.second; return result.second;
} }
...@@ -244,13 +242,7 @@ public: ...@@ -244,13 +242,7 @@ public:
// that the symbol table has not been preloaded with built-ins. // that the symbol table has not been preloaded with built-ins.
// //
} }
~TSymbolTable();
~TSymbolTable()
{
// level 0 is always built In symbols, so we never pop that out
while (table.size() > 1)
pop();
}
// //
// When the symbol table is initialized with the built-ins, there should // When the symbol table is initialized with the built-ins, there should
...@@ -263,13 +255,15 @@ public: ...@@ -263,13 +255,15 @@ public:
void push() void push()
{ {
table.push_back(new TSymbolTableLevel); table.push_back(new TSymbolTableLevel);
precisionStack.push_back( PrecisionStackLevel() ); precisionStack.push_back(new PrecisionStackLevel);
} }
void pop() void pop()
{ {
delete table[currentLevel()]; delete table.back();
table.pop_back(); table.pop_back();
delete precisionStack.back();
precisionStack.pop_back(); precisionStack.pop_back();
} }
...@@ -324,16 +318,11 @@ public: ...@@ -324,16 +318,11 @@ public:
return symbol; return symbol;
} }
TSymbol *findBuiltIn(const TString &name) TSymbol* findBuiltIn(const TString &name)
{ {
return table[0]->find(name); return table[0]->find(name);
} }
TSymbolTableLevel* getGlobalLevel() {
assert(table.size() >= 2);
return table[1];
}
TSymbolTableLevel* getOuterLevel() { TSymbolTableLevel* getOuterLevel() {
assert(table.size() >= 2); assert(table.size() >= 2);
return table[currentLevel() - 1]; return table[currentLevel() - 1];
...@@ -345,10 +334,9 @@ public: ...@@ -345,10 +334,9 @@ public:
void relateToExtension(const char* name, const TString& ext) { void relateToExtension(const char* name, const TString& ext) {
table[0]->relateToExtension(name, ext); table[0]->relateToExtension(name, ext);
} }
int getMaxSymbolId() { return uniqueId; }
void dump(TInfoSink &infoSink) const; void dump(TInfoSink &infoSink) const;
bool setDefaultPrecision( const TPublicType& type, TPrecision prec ){ bool setDefaultPrecision(const TPublicType& type, TPrecision prec) {
if (IsSampler(type.type)) if (IsSampler(type.type))
return true; // Skip sampler types for the time being return true; // Skip sampler types for the time being
if (type.type != EbtFloat && type.type != EbtInt) if (type.type != EbtFloat && type.type != EbtInt)
...@@ -356,20 +344,22 @@ public: ...@@ -356,20 +344,22 @@ public:
if (type.size != 1 || type.matrix || type.array) if (type.size != 1 || type.matrix || type.array)
return false; // Not allowed to set for aggregate types return false; // Not allowed to set for aggregate types
int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1; 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; return true;
} }
// Searches down the precisionStack for a precision qualifier for the specified TBasicType // Searches down the precisionStack for a precision qualifier for the specified TBasicType
TPrecision getDefaultPrecision( TBasicType type){ TPrecision getDefaultPrecision(TBasicType type) {
if( type != EbtFloat && type != EbtInt ) return EbpUndefined; if (type != EbtFloat && type != EbtInt)
return EbpUndefined;
int level = static_cast<int>(precisionStack.size()) - 1; 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; PrecisionStackLevel::iterator it;
TPrecision prec = EbpUndefined; // If we dont find anything we return this. Should we error check this? TPrecision prec = EbpUndefined; // If we dont find anything we return this. Should we error check this?
while( level >= 0 ){ while (level >= 0) {
it = precisionStack[level].find( type ); it = precisionStack[level]->find(type);
if( it != precisionStack[level].end() ){ if (it != precisionStack[level]->end()) {
prec = (*it).second; prec = (*it).second;
break; break;
} }
...@@ -378,13 +368,13 @@ public: ...@@ -378,13 +368,13 @@ public:
return prec; return prec;
} }
protected: private:
int currentLevel() const { return static_cast<int>(table.size()) - 1; } int currentLevel() const { return static_cast<int>(table.size()) - 1; }
std::vector<TSymbolTableLevel*> table;
typedef std::map< TBasicType, TPrecision > PrecisionStackLevel;
std::vector< PrecisionStackLevel > precisionStack;
int uniqueId; // for unique identification in code generation int uniqueId; // for unique identification in code generation
std::vector<TSymbolTableLevel*> table;
typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
std::vector<PrecisionStackLevel*> precisionStack;
}; };
#endif // _SYMBOL_TABLE_INCLUDED_ #endif // _SYMBOL_TABLE_INCLUDED_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment