Fixed memory leak associated with TLS.

We used to allocate thread-local memory on each compile.
If the compile did not happen on the same thread as ShInitialize,
we leaked the thread-local memory.

It turns out that there is no need to allocate any thread-local
memory. This patch cleans up all the unnecessary junk around TLS.

BUG=chromium:181691

Change-Id: I4b67ab23dc856d93424ae51ebf8aaf8966b732e4
Reviewed-on: https://swiftshader-review.googlesource.com/1361
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/compiler/Common.h b/src/OpenGL/compiler/Common.h
index 27a5598..1dc5eeb 100644
--- a/src/OpenGL/compiler/Common.h
+++ b/src/OpenGL/compiler/Common.h
@@ -36,14 +36,14 @@
 //
 // Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
 //
-#define POOL_ALLOCATOR_NEW_DELETE(A)                                  \
-    void* operator new(size_t s) { return (A).allocate(s); }          \
-    void* operator new(size_t, void *_Where) { return (_Where);	}     \
-    void operator delete(void*) { }                                   \
-    void operator delete(void *, void *) { }                          \
-    void* operator new[](size_t s) { return (A).allocate(s); }        \
-    void* operator new[](size_t, void *_Where) { return (_Where);	} \
-    void operator delete[](void*) { }                                 \
+#define POOL_ALLOCATOR_NEW_DELETE()                                                  \
+    void* operator new(size_t s) { return GetGlobalPoolAllocator()->allocate(s); }   \
+    void* operator new(size_t, void *_Where) { return (_Where); }                    \
+    void operator delete(void*) { }                                                  \
+    void operator delete(void *, void *) { }                                         \
+    void* operator new[](size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \
+    void* operator new[](size_t, void *_Where) { return (_Where); }                  \
+    void operator delete[](void*) { }                                                \
     void operator delete[](void *, void *) { }
 
 //
@@ -54,7 +54,7 @@
 typedef std::basic_ostringstream<char, std::char_traits<char>, TStringAllocator> TStringStream;
 inline TString* NewPoolTString(const char* s)
 {
-	void* memory = GlobalPoolAllocator.allocate(sizeof(TString));
+	void* memory = GetGlobalPoolAllocator()->allocate(sizeof(TString));
 	return new(memory) TString(s);
 }
 
diff --git a/src/OpenGL/compiler/Compiler.cpp b/src/OpenGL/compiler/Compiler.cpp
index 6945869..28455cf 100644
--- a/src/OpenGL/compiler/Compiler.cpp
+++ b/src/OpenGL/compiler/Compiler.cpp
@@ -92,7 +92,7 @@
     TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
                                shaderType, shaderSpec, compileOptions, true,
                                sourcePath, infoSink);
-    GlobalParseContext = &parseContext;
+    SetGlobalParseContext(&parseContext);
 
     // We preserve symbols at the built-in level from compile-to-compile.
     // Start pushing the user-defined symbols at global level.
diff --git a/src/OpenGL/compiler/ConstantUnion.h b/src/OpenGL/compiler/ConstantUnion.h
index 6b04310..397bb75 100644
--- a/src/OpenGL/compiler/ConstantUnion.h
+++ b/src/OpenGL/compiler/ConstantUnion.h
@@ -11,6 +11,7 @@
 
 class ConstantUnion {
 public:
+	POOL_ALLOCATOR_NEW_DELETE();
     ConstantUnion()
     {
         iConst = 0;
diff --git a/src/OpenGL/compiler/InitializeDll.cpp b/src/OpenGL/compiler/InitializeDll.cpp
index 8763cfe..6c7f27f 100644
--- a/src/OpenGL/compiler/InitializeDll.cpp
+++ b/src/OpenGL/compiler/InitializeDll.cpp
@@ -10,25 +10,8 @@
 #include "compiler/InitializeParseContext.h"
 #include "compiler/osinclude.h"
 
-OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
-
 bool InitProcess()
 {
-    if (ThreadInitializeIndex != OS_INVALID_TLS_INDEX) {
-        //
-        // Function is re-entrant.
-        //
-        return true;
-    }
-
-    ThreadInitializeIndex = OS_AllocTLSIndex();
-
-    if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
-        assert(0 && "InitProcess(): Failed to allocate TLS area for init flag");
-        return false;
-    }
-
-
     if (!InitializePoolIndex()) {
         assert(0 && "InitProcess(): Failed to initalize global pool");
         return false;
@@ -39,77 +22,11 @@
         return false;
     }
 
-    return InitThread();
-}
-
-bool DetachProcess()
-{
-    bool success = true;
-
-    if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
-        return true;
-
-    success = DetachThread();
-
-    if (!FreeParseContextIndex())
-        success = false;
-
-    FreePoolIndex();
-
-    OS_FreeTLSIndex(ThreadInitializeIndex);
-    ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
-
-    return success;
-}
-
-bool InitThread()
-{
-    //
-    // This function is re-entrant
-    //
-    if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
-        assert(0 && "InitThread(): Process hasn't been initalised.");
-        return false;
-    }
-
-    if (OS_GetTLSValue(ThreadInitializeIndex) != 0)
-        return true;
-
-    InitializeGlobalPools();
-
-    if (!InitializeGlobalParseContext())
-        return false;
-
-    if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
-        assert(0 && "InitThread(): Unable to set init flag.");
-        return false;
-    }
-
     return true;
 }
 
-bool DetachThread()
+void DetachProcess()
 {
-    bool success = true;
-
-    if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
-        return true;
-
-    //
-    // Function is re-entrant and this thread may not have been initalised.
-    //
-    if (OS_GetTLSValue(ThreadInitializeIndex) != 0) {
-        if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)0)) {
-            assert(0 && "DetachThread(): Unable to clear init flag.");
-            success = false;
-        }
-
-        if (!FreeParseContext())
-            success = false;
-
-        FreeGlobalPools();
-    }
-
-    return success;
+    FreeParseContextIndex();
+    FreePoolIndex();
 }
-
diff --git a/src/OpenGL/compiler/InitializeDll.h b/src/OpenGL/compiler/InitializeDll.h
index 857238e..43070cc 100644
--- a/src/OpenGL/compiler/InitializeDll.h
+++ b/src/OpenGL/compiler/InitializeDll.h
@@ -7,10 +7,7 @@
 #define __INITIALIZEDLL_H
 
 bool InitProcess();
-bool DetachProcess();
-
-bool InitThread();
-bool DetachThread();
+void DetachProcess();
 
 #endif // __INITIALIZEDLL_H
 
diff --git a/src/OpenGL/compiler/InitializeGlobals.h b/src/OpenGL/compiler/InitializeGlobals.h
index 842a452..0715941 100644
--- a/src/OpenGL/compiler/InitializeGlobals.h
+++ b/src/OpenGL/compiler/InitializeGlobals.h
@@ -7,8 +7,6 @@
 #ifndef __INITIALIZE_GLOBALS_INCLUDED_
 #define __INITIALIZE_GLOBALS_INCLUDED_
 
-void InitializeGlobalPools();
-void FreeGlobalPools();
 bool InitializePoolIndex();
 void FreePoolIndex();
 
diff --git a/src/OpenGL/compiler/InitializeParseContext.cpp b/src/OpenGL/compiler/InitializeParseContext.cpp
index 1f40cf5..dfab027 100644
--- a/src/OpenGL/compiler/InitializeParseContext.cpp
+++ b/src/OpenGL/compiler/InitializeParseContext.cpp
@@ -12,85 +12,29 @@
 
 bool InitializeParseContextIndex()
 {
-    if (GlobalParseContextIndex != OS_INVALID_TLS_INDEX) {
-        assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
-        return false;
-    }
+    assert(GlobalParseContextIndex == OS_INVALID_TLS_INDEX);
 
-    //
-    // Allocate a TLS index.
-    //
     GlobalParseContextIndex = OS_AllocTLSIndex();
-    
-    if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
-        assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
-        return false;
-    }
-
-    return true;
+    return GlobalParseContextIndex != OS_INVALID_TLS_INDEX;
 }
 
-bool FreeParseContextIndex()
+void FreeParseContextIndex()
 {
-    OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
+    assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
 
-    if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
-        assert(0 && "FreeParseContextIndex(): Parse Context index not initalized");
-        return false;
-    }
-
+    OS_FreeTLSIndex(GlobalParseContextIndex);
     GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
-
-    return OS_FreeTLSIndex(tlsiIndex);
 }
 
-bool InitializeGlobalParseContext()
+void SetGlobalParseContext(TParseContext* context)
 {
-    if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
-        assert(0 && "InitializeGlobalParseContext(): Parse Context index not initalized");
-        return false;
-    }
-
-    TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
-    if (lpParseContext != 0) {
-        assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
-        return false;
-    }
-
-    TThreadParseContext *lpThreadData = new TThreadParseContext();
-    if (lpThreadData == 0) {
-        assert(0 && "InitializeGlobalParseContext(): Unable to create thread parse context");
-        return false;
-    }
-
-    lpThreadData->lpGlobalParseContext = 0;
-    OS_SetTLSValue(GlobalParseContextIndex, lpThreadData);
-
-    return true;
+    assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
+    OS_SetTLSValue(GlobalParseContextIndex, context);
 }
 
-bool FreeParseContext()
+TParseContext* GetGlobalParseContext()
 {
-    if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
-        assert(0 && "FreeParseContext(): Parse Context index not initalized");
-        return false;
-    }
-
-    TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
-    if (lpParseContext)
-        delete lpParseContext;
-
-    return true;
-}
-
-TParseContextPointer& GetGlobalParseContext()
-{
-    //
-    // Minimal error checking for speed
-    //
-
-    TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
-
-    return lpParseContext->lpGlobalParseContext;
+    assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
+    return static_cast<TParseContext*>(OS_GetTLSValue(GlobalParseContextIndex));
 }
 
diff --git a/src/OpenGL/compiler/InitializeParseContext.h b/src/OpenGL/compiler/InitializeParseContext.h
index 354bfe1..4729d3c 100644
--- a/src/OpenGL/compiler/InitializeParseContext.h
+++ b/src/OpenGL/compiler/InitializeParseContext.h
@@ -8,19 +8,10 @@
 #define __INITIALIZE_PARSE_CONTEXT_INCLUDED_
 
 bool InitializeParseContextIndex();
-bool FreeParseContextIndex();
-
-bool InitializeGlobalParseContext();
-bool FreeParseContext();
+void FreeParseContextIndex();
 
 struct TParseContext;
-typedef TParseContext* TParseContextPointer;
-extern TParseContextPointer& GetGlobalParseContext();
-#define GlobalParseContext GetGlobalParseContext()
-
-typedef struct TThreadParseContextRec
-{
-    TParseContext *lpGlobalParseContext;
-} TThreadParseContext;
+extern void SetGlobalParseContext(TParseContext* context);
+extern TParseContext* GetGlobalParseContext();
 
 #endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_
diff --git a/src/OpenGL/compiler/PoolAlloc.cpp b/src/OpenGL/compiler/PoolAlloc.cpp
index 9cdbeaa..6ec3c40 100644
--- a/src/OpenGL/compiler/PoolAlloc.cpp
+++ b/src/OpenGL/compiler/PoolAlloc.cpp
@@ -16,55 +16,32 @@
 
 OS_TLSIndex PoolIndex = OS_INVALID_TLS_INDEX;
 
-void InitializeGlobalPools()
-{
-    TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));    
-    if (globalPools)
-        return;
-
-    TThreadGlobalPools* threadData = new TThreadGlobalPools();
-    threadData->globalPoolAllocator = 0;
-
-    OS_SetTLSValue(PoolIndex, threadData);
-}
-
-void FreeGlobalPools()
-{
-    // Release the allocated memory for this thread.
-    TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));    
-    if (!globalPools)
-        return;
- 
-    delete globalPools;
-}
-
 bool InitializePoolIndex()
 {
-    // Allocate a TLS index.
-    if ((PoolIndex = OS_AllocTLSIndex()) == OS_INVALID_TLS_INDEX)
-        return false;
+    assert(PoolIndex == OS_INVALID_TLS_INDEX);
 
-    return true;
+    PoolIndex = OS_AllocTLSIndex();
+    return PoolIndex != OS_INVALID_TLS_INDEX;
 }
 
 void FreePoolIndex()
 {
-    // Release the TLS index.
+    assert(PoolIndex != OS_INVALID_TLS_INDEX);
+
     OS_FreeTLSIndex(PoolIndex);
+    PoolIndex = OS_INVALID_TLS_INDEX;
 }
 
-TPoolAllocator& GetGlobalPoolAllocator()
+TPoolAllocator* GetGlobalPoolAllocator()
 {
-    TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
-
-    return *threadData->globalPoolAllocator;
+    assert(PoolIndex != OS_INVALID_TLS_INDEX);
+    return static_cast<TPoolAllocator*>(OS_GetTLSValue(PoolIndex));
 }
 
 void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator)
 {
-    TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
-
-    threadData->globalPoolAllocator = poolAllocator;
+    assert(PoolIndex != OS_INVALID_TLS_INDEX);
+    OS_SetTLSValue(PoolIndex, poolAllocator);
 }
 
 //
diff --git a/src/OpenGL/compiler/PoolAlloc.h b/src/OpenGL/compiler/PoolAlloc.h
index c33dfd9..b032c47 100644
--- a/src/OpenGL/compiler/PoolAlloc.h
+++ b/src/OpenGL/compiler/PoolAlloc.h
@@ -219,14 +219,8 @@
 // different times.  But a simple use is to have a global pop
 // with everyone using the same global allocator.
 //
-extern TPoolAllocator& GetGlobalPoolAllocator();
+extern TPoolAllocator* GetGlobalPoolAllocator();
 extern void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator);
-#define GlobalPoolAllocator GetGlobalPoolAllocator()
-
-struct TThreadGlobalPools
-{
-    TPoolAllocator* globalPoolAllocator;
-};
 
 //
 // This STL compatible allocator is intended to be used as the allocator
@@ -253,7 +247,7 @@
     pointer address(reference x) const { return &x; }
     const_pointer address(const_reference x) const { return &x; }
 
-    pool_allocator() : allocator(&GlobalPoolAllocator) { }
+    pool_allocator() : allocator(GetGlobalPoolAllocator()) { }
     pool_allocator(TPoolAllocator& a) : allocator(&a) { }
     pool_allocator(const pool_allocator<T>& p) : allocator(p.allocator) { }
 
diff --git a/src/OpenGL/compiler/ShaderLang.cpp b/src/OpenGL/compiler/ShaderLang.cpp
index 368c068..cd4e9ad 100644
--- a/src/OpenGL/compiler/ShaderLang.cpp
+++ b/src/OpenGL/compiler/ShaderLang.cpp
@@ -23,10 +23,7 @@
 //
 int ShInitialize()
 {
-    if (!InitProcess())
-        return 0;
-
-    return 1;
+    return InitProcess() ? 1 : 0;
 }
 
 //
@@ -34,9 +31,7 @@
 //
 int ShFinalize()
 {
-    if (!DetachProcess())
-        return 0;
-
+    DetachProcess();
     return 1;
 }
 
@@ -69,9 +64,6 @@
 ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
                              const ShBuiltInResources* resources)
 {
-    if (!InitThread())
-        return 0;
-
     TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec));
     TCompiler* compiler = base->getAsCompiler();
     if (compiler == 0)
@@ -110,9 +102,6 @@
     const int numStrings,
     int compileOptions)
 {
-    if (!InitThread())
-        return 0;
-
     if (handle == 0)
         return 0;
 
diff --git a/src/OpenGL/compiler/SymbolTable.h b/src/OpenGL/compiler/SymbolTable.h
index 6d4355d..739b7ad 100644
--- a/src/OpenGL/compiler/SymbolTable.h
+++ b/src/OpenGL/compiler/SymbolTable.h
@@ -40,9 +40,10 @@
 //
 class TSymbol {    
 public:
-    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
+    POOL_ALLOCATOR_NEW_DELETE();
     TSymbol(const TString *n) :  name(n) { }
     virtual ~TSymbol() { /* don't delete name, it's from the pool */ }
+
     const TString& getName() const { return *name; }
     virtual const TString& getMangledName() const { return getName(); }
     virtual bool isFunction() const { return false; }
@@ -179,7 +180,7 @@
     typedef const tLevel::value_type tLevelPair;
     typedef std::pair<tLevel::iterator, bool> tInsertResult;
 
-    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
+    POOL_ALLOCATOR_NEW_DELETE();
     TSymbolTableLevel() { }
     ~TSymbolTableLevel();
 
diff --git a/src/OpenGL/compiler/Types.h b/src/OpenGL/compiler/Types.h
index ff280d6..8b6f07c 100644
--- a/src/OpenGL/compiler/Types.h
+++ b/src/OpenGL/compiler/Types.h
@@ -1,314 +1,314 @@
-//

-// Copyright (c) 2002-2013 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.

-//

-

-#ifndef _TYPES_INCLUDED

-#define _TYPES_INCLUDED

-

-#include "compiler/BaseTypes.h"

-#include "compiler/Common.h"

-#include "compiler/debug.h"

-

-#include <algorithm>

-

-class TType;

-struct TPublicType;

-

-//

-// Need to have association of line numbers to types in a list for building structs.

-//

-struct TTypeLine {

-    TType* type;

-    int line;

-};

-typedef TVector<TTypeLine> TTypeList;

-

-inline TTypeList* NewPoolTTypeList()

-{

-    void* memory = GlobalPoolAllocator.allocate(sizeof(TTypeList));

-    return new(memory) TTypeList;

-}

-

-//

-// Base class for things that have a type.

-//

-class TType

-{

-public:

-    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)

-    TType() {}

-    TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :

-            type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0),

-            maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)

-    {

-    }

-    explicit TType(const TPublicType &p);

-    TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) :

-            type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),

-            maxArraySize(0), arrayInformationType(0), structure(userDef), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0)

-    {

-        typeName = NewPoolTString(n.c_str());

-    }

-

-    TBasicType getBasicType() const { return type; }

-    void setBasicType(TBasicType t) { type = t; }

-

-    TPrecision getPrecision() const { return precision; }

-    void setPrecision(TPrecision p) { precision = p; }

-

-    TQualifier getQualifier() const { return qualifier; }

-    void setQualifier(TQualifier q) { qualifier = q; }

-

-    // One-dimensional size of single instance type

-    int getNominalSize() const { return size; }

-    void setNominalSize(int s) { size = s; }

-    // Full size of single instance of type

-	int getObjectSize() const

-	{

-		if(isArray())

-		{

-			return getElementSize() * std::max(getArraySize(), getMaxArraySize());

-		}

-		else

-		{

-			return getElementSize();

-		}

-	}

-

-	int getElementSize() const

-	{

-		if(getBasicType() == EbtStruct)

-		{

-			return getStructSize();

-		}

-		else if(matrix)

-		{

-			return size * size;

-		}

-		else   // Vector or scalar

-		{

-			return size;

-		}

-	}

-

-	int elementRegisterCount() const

-	{

-		TTypeList *structure = getStruct();

-

-		if(structure)

-		{

-			int registerCount = 0;

-

-			for(size_t i = 0; i < structure->size(); i++)

-			{

-				registerCount += (*structure)[i].type->totalRegisterCount();

-			}

-

-			return registerCount;

-		}

-		else if(isMatrix())

-		{

-			return getNominalSize();

-		}

-		else

-		{

-			return 1;

-		}

-	}

-

-	int totalRegisterCount() const

-	{

-		if(array)

-		{

-			return arraySize * elementRegisterCount();

-		}

-		else

-		{

-			return elementRegisterCount();

-		}

-	}

-

-    bool isMatrix() const { return matrix ? true : false; }

-    void setMatrix(bool m) { matrix = m; }

-

-    bool isArray() const  { return array ? true : false; }

-    int getArraySize() const { return arraySize; }

-    void setArraySize(int s) { array = true; arraySize = s; }

-    int getMaxArraySize () const { return maxArraySize; }

-    void setMaxArraySize (int s) { maxArraySize = s; }

-    void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }

-    void setArrayInformationType(TType* t) { arrayInformationType = t; }

-    TType* getArrayInformationType() const { return arrayInformationType; }

-

-    bool isVector() const { return size > 1 && !matrix; }

-    bool isScalar() const { return size == 1 && !matrix && !structure; }

-	bool isRegister() const { return !matrix && !structure && !array; }   // Fits in a 4-element register

-	bool isStruct() const { return structure != 0; }

-

-    TTypeList* getStruct() const { return structure; }

-    void setStruct(TTypeList* s) { structure = s; computeDeepestStructNesting(); }

-

-    const TString& getTypeName() const

-    {

-        assert(typeName);

-        return *typeName;

-    }

-    void setTypeName(const TString& n)

-    {

-        typeName = NewPoolTString(n.c_str());

-    }

-

-    bool isField() const { return fieldName != 0; }

-    const TString& getFieldName() const

-    {

-        assert(fieldName);

-        return *fieldName;

-    }

-    void setFieldName(const TString& n)

-    {

-        fieldName = NewPoolTString(n.c_str());

-    }

-

-    TString& getMangledName() {

-        if (!mangled) {

-            mangled = NewPoolTString("");

-            buildMangledName(*mangled);

-            *mangled += ';' ;

-        }

-

-        return *mangled;

-    }

-

-    bool sameElementType(const TType& right) const {

-        return      type == right.type   &&

-                    size == right.size   &&

-                  matrix == right.matrix &&

-               structure == right.structure;

-    }

-    bool operator==(const TType& right) const {

-        return      type == right.type   &&

-                    size == right.size   &&

-                  matrix == right.matrix &&

-                   array == right.array  && (!array || arraySize == right.arraySize) &&

-               structure == right.structure;

-        // don't check the qualifier, it's not ever what's being sought after

-    }

-    bool operator!=(const TType& right) const {

-        return !operator==(right);

-    }

-    bool operator<(const TType& right) const {

-        if (type != right.type) return type < right.type;

-        if (size != right.size) return size < right.size;

-        if (matrix != right.matrix) return matrix < right.matrix;

-        if (array != right.array) return array < right.array;

-        if (arraySize != right.arraySize) return arraySize < right.arraySize;

-        if (structure != right.structure) return structure < right.structure;

-

-        return false;

-    }

-

-    const char* getBasicString() const { return ::getBasicString(type); }

-    const char* getPrecisionString() const { return ::getPrecisionString(precision); }

-    const char* getQualifierString() const { return ::getQualifierString(qualifier); }

-    TString getCompleteString() const;

-

-    // If this type is a struct, returns the deepest struct nesting of

-    // any field in the struct. For example:

-    //   struct nesting1 {

-    //     vec4 position;

-    //   };

-    //   struct nesting2 {

-    //     nesting1 field1;

-    //     vec4 field2;

-    //   };

-    // For type "nesting2", this method would return 2 -- the number

-    // of structures through which indirection must occur to reach the

-    // deepest field (nesting2.field1.position).

-    int getDeepestStructNesting() const { return deepestStructNesting; }

-

-    bool isStructureContainingArrays() const;

-

-protected:

-    void buildMangledName(TString&);

-    int getStructSize() const;

-    void computeDeepestStructNesting();

-

-    TBasicType type      : 6;

-    TPrecision precision;

-    TQualifier qualifier : 7;

-    int size             : 8; // size of vector or matrix, not size of array

-    unsigned int matrix  : 1;

-    unsigned int array   : 1;

-    int arraySize;

-    int maxArraySize;

-    TType* arrayInformationType;

-

-    TTypeList* structure;      // 0 unless this is a struct

-    mutable int structureSize;

-    int deepestStructNesting;

-

-    TString *fieldName;         // for structure field names

-    TString *mangled;

-    TString *typeName;          // for structure field type name

-};

-

-//

-// This is a workaround for a problem with the yacc stack,  It can't have

-// types that it thinks have non-trivial constructors.  It should

-// just be used while recognizing the grammar, not anything else.  Pointers

-// could be used, but also trying to avoid lots of memory management overhead.

-//

-// Not as bad as it looks, there is no actual assumption that the fields

-// match up or are name the same or anything like that.

-//

-struct TPublicType

-{

-    TBasicType type;

-    TQualifier qualifier;

-    TPrecision precision;

-    int size;          // size of vector or matrix, not size of array

-    bool matrix;

-    bool array;

-    int arraySize;

-    TType* userDef;

-    int line;

-

-    void setBasic(TBasicType bt, TQualifier q, int ln = 0)

-    {

-        type = bt;

-        qualifier = q;

-        precision = EbpUndefined;

-        size = 1;

-        matrix = false;

-        array = false;

-        arraySize = 0;

-        userDef = 0;

-        line = ln;

-    }

-

-    void setAggregate(int s, bool m = false)

-    {

-        size = s;

-        matrix = m;

-    }

-

-    void setArray(bool a, int s = 0)

-    {

-        array = a;

-        arraySize = s;

-    }

-

-    bool isStructureContainingArrays() const

-    {

-        if (!userDef)

-        {

-            return false;

-        }

-

-        return userDef->isStructureContainingArrays();

-    }

-};

-

-#endif // _TYPES_INCLUDED_

+//
+// Copyright (c) 2002-2013 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.
+//
+
+#ifndef _TYPES_INCLUDED
+#define _TYPES_INCLUDED
+
+#include "compiler/BaseTypes.h"
+#include "compiler/Common.h"
+#include "compiler/debug.h"
+
+#include <algorithm>
+
+class TType;
+struct TPublicType;
+
+//
+// Need to have association of line numbers to types in a list for building structs.
+//
+struct TTypeLine {
+    TType* type;
+    int line;
+};
+typedef TVector<TTypeLine> TTypeList;
+
+inline TTypeList* NewPoolTTypeList()
+{
+    void* memory = GetGlobalPoolAllocator()->allocate(sizeof(TTypeList));
+    return new(memory) TTypeList;
+}
+
+//
+// Base class for things that have a type.
+//
+class TType
+{
+public:
+    POOL_ALLOCATOR_NEW_DELETE();
+    TType() {}
+    TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
+            type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0),
+            maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
+    {
+    }
+    explicit TType(const TPublicType &p);
+    TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) :
+            type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),
+            maxArraySize(0), arrayInformationType(0), structure(userDef), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0)
+    {
+        typeName = NewPoolTString(n.c_str());
+    }
+
+    TBasicType getBasicType() const { return type; }
+    void setBasicType(TBasicType t) { type = t; }
+
+    TPrecision getPrecision() const { return precision; }
+    void setPrecision(TPrecision p) { precision = p; }
+
+    TQualifier getQualifier() const { return qualifier; }
+    void setQualifier(TQualifier q) { qualifier = q; }
+
+    // One-dimensional size of single instance type
+    int getNominalSize() const { return size; }
+    void setNominalSize(int s) { size = s; }
+    // Full size of single instance of type
+	int getObjectSize() const
+	{
+		if(isArray())
+		{
+			return getElementSize() * std::max(getArraySize(), getMaxArraySize());
+		}
+		else
+		{
+			return getElementSize();
+		}
+	}
+
+	int getElementSize() const
+	{
+		if(getBasicType() == EbtStruct)
+		{
+			return getStructSize();
+		}
+		else if(matrix)
+		{
+			return size * size;
+		}
+		else   // Vector or scalar
+		{
+			return size;
+		}
+	}
+
+	int elementRegisterCount() const
+	{
+		TTypeList *structure = getStruct();
+
+		if(structure)
+		{
+			int registerCount = 0;
+
+			for(size_t i = 0; i < structure->size(); i++)
+			{
+				registerCount += (*structure)[i].type->totalRegisterCount();
+			}
+
+			return registerCount;
+		}
+		else if(isMatrix())
+		{
+			return getNominalSize();
+		}
+		else
+		{
+			return 1;
+		}
+	}
+
+	int totalRegisterCount() const
+	{
+		if(array)
+		{
+			return arraySize * elementRegisterCount();
+		}
+		else
+		{
+			return elementRegisterCount();
+		}
+	}
+
+    bool isMatrix() const { return matrix ? true : false; }
+    void setMatrix(bool m) { matrix = m; }
+
+    bool isArray() const  { return array ? true : false; }
+    int getArraySize() const { return arraySize; }
+    void setArraySize(int s) { array = true; arraySize = s; }
+    int getMaxArraySize () const { return maxArraySize; }
+    void setMaxArraySize (int s) { maxArraySize = s; }
+    void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }
+    void setArrayInformationType(TType* t) { arrayInformationType = t; }
+    TType* getArrayInformationType() const { return arrayInformationType; }
+
+    bool isVector() const { return size > 1 && !matrix; }
+    bool isScalar() const { return size == 1 && !matrix && !structure; }
+	bool isRegister() const { return !matrix && !structure && !array; }   // Fits in a 4-element register
+	bool isStruct() const { return structure != 0; }
+
+    TTypeList* getStruct() const { return structure; }
+    void setStruct(TTypeList* s) { structure = s; computeDeepestStructNesting(); }
+
+    const TString& getTypeName() const
+    {
+        assert(typeName);
+        return *typeName;
+    }
+    void setTypeName(const TString& n)
+    {
+        typeName = NewPoolTString(n.c_str());
+    }
+
+    bool isField() const { return fieldName != 0; }
+    const TString& getFieldName() const
+    {
+        assert(fieldName);
+        return *fieldName;
+    }
+    void setFieldName(const TString& n)
+    {
+        fieldName = NewPoolTString(n.c_str());
+    }
+
+    TString& getMangledName() {
+        if (!mangled) {
+            mangled = NewPoolTString("");
+            buildMangledName(*mangled);
+            *mangled += ';' ;
+        }
+
+        return *mangled;
+    }
+
+    bool sameElementType(const TType& right) const {
+        return      type == right.type   &&
+                    size == right.size   &&
+                  matrix == right.matrix &&
+               structure == right.structure;
+    }
+    bool operator==(const TType& right) const {
+        return      type == right.type   &&
+                    size == right.size   &&
+                  matrix == right.matrix &&
+                   array == right.array  && (!array || arraySize == right.arraySize) &&
+               structure == right.structure;
+        // don't check the qualifier, it's not ever what's being sought after
+    }
+    bool operator!=(const TType& right) const {
+        return !operator==(right);
+    }
+    bool operator<(const TType& right) const {
+        if (type != right.type) return type < right.type;
+        if (size != right.size) return size < right.size;
+        if (matrix != right.matrix) return matrix < right.matrix;
+        if (array != right.array) return array < right.array;
+        if (arraySize != right.arraySize) return arraySize < right.arraySize;
+        if (structure != right.structure) return structure < right.structure;
+
+        return false;
+    }
+
+    const char* getBasicString() const { return ::getBasicString(type); }
+    const char* getPrecisionString() const { return ::getPrecisionString(precision); }
+    const char* getQualifierString() const { return ::getQualifierString(qualifier); }
+    TString getCompleteString() const;
+
+    // If this type is a struct, returns the deepest struct nesting of
+    // any field in the struct. For example:
+    //   struct nesting1 {
+    //     vec4 position;
+    //   };
+    //   struct nesting2 {
+    //     nesting1 field1;
+    //     vec4 field2;
+    //   };
+    // For type "nesting2", this method would return 2 -- the number
+    // of structures through which indirection must occur to reach the
+    // deepest field (nesting2.field1.position).
+    int getDeepestStructNesting() const { return deepestStructNesting; }
+
+    bool isStructureContainingArrays() const;
+
+protected:
+    void buildMangledName(TString&);
+    int getStructSize() const;
+    void computeDeepestStructNesting();
+
+    TBasicType type      : 6;
+    TPrecision precision;
+    TQualifier qualifier : 7;
+    int size             : 8; // size of vector or matrix, not size of array
+    unsigned int matrix  : 1;
+    unsigned int array   : 1;
+    int arraySize;
+    int maxArraySize;
+    TType* arrayInformationType;
+
+    TTypeList* structure;      // 0 unless this is a struct
+    mutable int structureSize;
+    int deepestStructNesting;
+
+    TString *fieldName;         // for structure field names
+    TString *mangled;
+    TString *typeName;          // for structure field type name
+};
+
+//
+// This is a workaround for a problem with the yacc stack,  It can't have
+// types that it thinks have non-trivial constructors.  It should
+// just be used while recognizing the grammar, not anything else.  Pointers
+// could be used, but also trying to avoid lots of memory management overhead.
+//
+// Not as bad as it looks, there is no actual assumption that the fields
+// match up or are name the same or anything like that.
+//
+struct TPublicType
+{
+    TBasicType type;
+    TQualifier qualifier;
+    TPrecision precision;
+    int size;          // size of vector or matrix, not size of array
+    bool matrix;
+    bool array;
+    int arraySize;
+    TType* userDef;
+    int line;
+
+    void setBasic(TBasicType bt, TQualifier q, int ln = 0)
+    {
+        type = bt;
+        qualifier = q;
+        precision = EbpUndefined;
+        size = 1;
+        matrix = false;
+        array = false;
+        arraySize = 0;
+        userDef = 0;
+        line = ln;
+    }
+
+    void setAggregate(int s, bool m = false)
+    {
+        size = s;
+        matrix = m;
+    }
+
+    void setArray(bool a, int s = 0)
+    {
+        array = a;
+        arraySize = s;
+    }
+
+    bool isStructureContainingArrays() const
+    {
+        if (!userDef)
+        {
+            return false;
+        }
+
+        return userDef->isStructureContainingArrays();
+    }
+};
+
+#endif // _TYPES_INCLUDED_
diff --git a/src/OpenGL/compiler/ValidateLimitations.cpp b/src/OpenGL/compiler/ValidateLimitations.cpp
index 5838d0f..9219cd1 100644
--- a/src/OpenGL/compiler/ValidateLimitations.cpp
+++ b/src/OpenGL/compiler/ValidateLimitations.cpp
@@ -435,7 +435,7 @@
         return true;
 
     bool valid = true;
-    TSymbolTable& symbolTable = GlobalParseContext->symbolTable;
+    TSymbolTable& symbolTable = GetGlobalParseContext()->symbolTable;
     TSymbol* symbol = symbolTable.find(node->getName());
     ASSERT(symbol && symbol->isFunction());
     TFunction* function = static_cast<TFunction*>(symbol);
diff --git a/src/OpenGL/compiler/intermediate.h b/src/OpenGL/compiler/intermediate.h
index fe7c363..18b889f 100644
--- a/src/OpenGL/compiler/intermediate.h
+++ b/src/OpenGL/compiler/intermediate.h
@@ -196,7 +196,7 @@
 //
 class TIntermNode {
 public:
-    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
+    POOL_ALLOCATOR_NEW_DELETE();
 
     TIntermNode() : line(0) {}
 
@@ -510,8 +510,7 @@
 class TIntermTraverser
 {
 public:
-    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
-
+    POOL_ALLOCATOR_NEW_DELETE();
     TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) : 
             preVisit(preVisit),
             inVisit(inVisit),
diff --git a/src/OpenGL/compiler/localintermediate.h b/src/OpenGL/compiler/localintermediate.h
index 253548d..805744f 100644
--- a/src/OpenGL/compiler/localintermediate.h
+++ b/src/OpenGL/compiler/localintermediate.h
@@ -21,7 +21,7 @@
 class TInfoSink;
 class TIntermediate {
 public:
-    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
+    POOL_ALLOCATOR_NEW_DELETE();
 
     TIntermediate(TInfoSink& i) : infoSink(i) { }
     TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc);
diff --git a/src/OpenGL/libGLESv2/Shader.cpp b/src/OpenGL/libGLESv2/Shader.cpp
index d88e561..a66a6b6 100644
--- a/src/OpenGL/libGLESv2/Shader.cpp
+++ b/src/OpenGL/libGLESv2/Shader.cpp
@@ -24,6 +24,8 @@
 
 namespace es2
 {
+bool Shader::compilerInitialized = false;
+
 Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
 {
     mSource = NULL;
@@ -154,7 +156,11 @@
 
 TranslatorASM *Shader::createCompiler(ShShaderType type)
 {
-	ShInitialize();
+	if(!compilerInitialized)
+	{
+		ShInitialize();
+		compilerInitialized = true;
+	}
 
 	TranslatorASM *assembler = new TranslatorASM(this, type, SH_GLES2_SPEC);
 
@@ -233,6 +239,7 @@
 void Shader::releaseCompiler()
 {
     ShFinalize();
+	compilerInitialized = false;
 }
 
 GLenum Shader::parseType(const std::string &type)
diff --git a/src/OpenGL/libGLESv2/Shader.h b/src/OpenGL/libGLESv2/Shader.h
index adf1c96..009d0dd 100644
--- a/src/OpenGL/libGLESv2/Shader.h
+++ b/src/OpenGL/libGLESv2/Shader.h
@@ -97,6 +97,7 @@
     static void releaseCompiler();

 

 protected:

+	static bool compilerInitialized;

 	TranslatorASM *createCompiler(ShShaderType type);

 	void clear();

 

diff --git a/src/Radiance/compiler/Common.h b/src/Radiance/compiler/Common.h
index 27a5598..1dc5eeb 100644
--- a/src/Radiance/compiler/Common.h
+++ b/src/Radiance/compiler/Common.h
@@ -36,14 +36,14 @@
 //
 // Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
 //
-#define POOL_ALLOCATOR_NEW_DELETE(A)                                  \
-    void* operator new(size_t s) { return (A).allocate(s); }          \
-    void* operator new(size_t, void *_Where) { return (_Where);	}     \
-    void operator delete(void*) { }                                   \
-    void operator delete(void *, void *) { }                          \
-    void* operator new[](size_t s) { return (A).allocate(s); }        \
-    void* operator new[](size_t, void *_Where) { return (_Where);	} \
-    void operator delete[](void*) { }                                 \
+#define POOL_ALLOCATOR_NEW_DELETE()                                                  \
+    void* operator new(size_t s) { return GetGlobalPoolAllocator()->allocate(s); }   \
+    void* operator new(size_t, void *_Where) { return (_Where); }                    \
+    void operator delete(void*) { }                                                  \
+    void operator delete(void *, void *) { }                                         \
+    void* operator new[](size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \
+    void* operator new[](size_t, void *_Where) { return (_Where); }                  \
+    void operator delete[](void*) { }                                                \
     void operator delete[](void *, void *) { }
 
 //
@@ -54,7 +54,7 @@
 typedef std::basic_ostringstream<char, std::char_traits<char>, TStringAllocator> TStringStream;
 inline TString* NewPoolTString(const char* s)
 {
-	void* memory = GlobalPoolAllocator.allocate(sizeof(TString));
+	void* memory = GetGlobalPoolAllocator()->allocate(sizeof(TString));
 	return new(memory) TString(s);
 }
 
diff --git a/src/Radiance/compiler/Compiler.cpp b/src/Radiance/compiler/Compiler.cpp
index 6945869..28455cf 100644
--- a/src/Radiance/compiler/Compiler.cpp
+++ b/src/Radiance/compiler/Compiler.cpp
@@ -92,7 +92,7 @@
     TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
                                shaderType, shaderSpec, compileOptions, true,
                                sourcePath, infoSink);
-    GlobalParseContext = &parseContext;
+    SetGlobalParseContext(&parseContext);
 
     // We preserve symbols at the built-in level from compile-to-compile.
     // Start pushing the user-defined symbols at global level.
diff --git a/src/Radiance/compiler/ConstantUnion.h b/src/Radiance/compiler/ConstantUnion.h
index 6b04310..397bb75 100644
--- a/src/Radiance/compiler/ConstantUnion.h
+++ b/src/Radiance/compiler/ConstantUnion.h
@@ -11,6 +11,7 @@
 
 class ConstantUnion {
 public:
+	POOL_ALLOCATOR_NEW_DELETE();
     ConstantUnion()
     {
         iConst = 0;
diff --git a/src/Radiance/compiler/InitializeDll.cpp b/src/Radiance/compiler/InitializeDll.cpp
index 8763cfe..6c7f27f 100644
--- a/src/Radiance/compiler/InitializeDll.cpp
+++ b/src/Radiance/compiler/InitializeDll.cpp
@@ -10,25 +10,8 @@
 #include "compiler/InitializeParseContext.h"
 #include "compiler/osinclude.h"
 
-OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
-
 bool InitProcess()
 {
-    if (ThreadInitializeIndex != OS_INVALID_TLS_INDEX) {
-        //
-        // Function is re-entrant.
-        //
-        return true;
-    }
-
-    ThreadInitializeIndex = OS_AllocTLSIndex();
-
-    if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
-        assert(0 && "InitProcess(): Failed to allocate TLS area for init flag");
-        return false;
-    }
-
-
     if (!InitializePoolIndex()) {
         assert(0 && "InitProcess(): Failed to initalize global pool");
         return false;
@@ -39,77 +22,11 @@
         return false;
     }
 
-    return InitThread();
-}
-
-bool DetachProcess()
-{
-    bool success = true;
-
-    if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
-        return true;
-
-    success = DetachThread();
-
-    if (!FreeParseContextIndex())
-        success = false;
-
-    FreePoolIndex();
-
-    OS_FreeTLSIndex(ThreadInitializeIndex);
-    ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
-
-    return success;
-}
-
-bool InitThread()
-{
-    //
-    // This function is re-entrant
-    //
-    if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
-        assert(0 && "InitThread(): Process hasn't been initalised.");
-        return false;
-    }
-
-    if (OS_GetTLSValue(ThreadInitializeIndex) != 0)
-        return true;
-
-    InitializeGlobalPools();
-
-    if (!InitializeGlobalParseContext())
-        return false;
-
-    if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
-        assert(0 && "InitThread(): Unable to set init flag.");
-        return false;
-    }
-
     return true;
 }
 
-bool DetachThread()
+void DetachProcess()
 {
-    bool success = true;
-
-    if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
-        return true;
-
-    //
-    // Function is re-entrant and this thread may not have been initalised.
-    //
-    if (OS_GetTLSValue(ThreadInitializeIndex) != 0) {
-        if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)0)) {
-            assert(0 && "DetachThread(): Unable to clear init flag.");
-            success = false;
-        }
-
-        if (!FreeParseContext())
-            success = false;
-
-        FreeGlobalPools();
-    }
-
-    return success;
+    FreeParseContextIndex();
+    FreePoolIndex();
 }
-
diff --git a/src/Radiance/compiler/InitializeDll.h b/src/Radiance/compiler/InitializeDll.h
index 857238e..43070cc 100644
--- a/src/Radiance/compiler/InitializeDll.h
+++ b/src/Radiance/compiler/InitializeDll.h
@@ -7,10 +7,7 @@
 #define __INITIALIZEDLL_H
 
 bool InitProcess();
-bool DetachProcess();
-
-bool InitThread();
-bool DetachThread();
+void DetachProcess();
 
 #endif // __INITIALIZEDLL_H
 
diff --git a/src/Radiance/compiler/InitializeGlobals.h b/src/Radiance/compiler/InitializeGlobals.h
index 842a452..0715941 100644
--- a/src/Radiance/compiler/InitializeGlobals.h
+++ b/src/Radiance/compiler/InitializeGlobals.h
@@ -7,8 +7,6 @@
 #ifndef __INITIALIZE_GLOBALS_INCLUDED_
 #define __INITIALIZE_GLOBALS_INCLUDED_
 
-void InitializeGlobalPools();
-void FreeGlobalPools();
 bool InitializePoolIndex();
 void FreePoolIndex();
 
diff --git a/src/Radiance/compiler/InitializeParseContext.cpp b/src/Radiance/compiler/InitializeParseContext.cpp
index 1f40cf5..dfab027 100644
--- a/src/Radiance/compiler/InitializeParseContext.cpp
+++ b/src/Radiance/compiler/InitializeParseContext.cpp
@@ -12,85 +12,29 @@
 
 bool InitializeParseContextIndex()
 {
-    if (GlobalParseContextIndex != OS_INVALID_TLS_INDEX) {
-        assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
-        return false;
-    }
+    assert(GlobalParseContextIndex == OS_INVALID_TLS_INDEX);
 
-    //
-    // Allocate a TLS index.
-    //
     GlobalParseContextIndex = OS_AllocTLSIndex();
-    
-    if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
-        assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
-        return false;
-    }
-
-    return true;
+    return GlobalParseContextIndex != OS_INVALID_TLS_INDEX;
 }
 
-bool FreeParseContextIndex()
+void FreeParseContextIndex()
 {
-    OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
+    assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
 
-    if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
-        assert(0 && "FreeParseContextIndex(): Parse Context index not initalized");
-        return false;
-    }
-
+    OS_FreeTLSIndex(GlobalParseContextIndex);
     GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
-
-    return OS_FreeTLSIndex(tlsiIndex);
 }
 
-bool InitializeGlobalParseContext()
+void SetGlobalParseContext(TParseContext* context)
 {
-    if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
-        assert(0 && "InitializeGlobalParseContext(): Parse Context index not initalized");
-        return false;
-    }
-
-    TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
-    if (lpParseContext != 0) {
-        assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
-        return false;
-    }
-
-    TThreadParseContext *lpThreadData = new TThreadParseContext();
-    if (lpThreadData == 0) {
-        assert(0 && "InitializeGlobalParseContext(): Unable to create thread parse context");
-        return false;
-    }
-
-    lpThreadData->lpGlobalParseContext = 0;
-    OS_SetTLSValue(GlobalParseContextIndex, lpThreadData);
-
-    return true;
+    assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
+    OS_SetTLSValue(GlobalParseContextIndex, context);
 }
 
-bool FreeParseContext()
+TParseContext* GetGlobalParseContext()
 {
-    if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
-        assert(0 && "FreeParseContext(): Parse Context index not initalized");
-        return false;
-    }
-
-    TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
-    if (lpParseContext)
-        delete lpParseContext;
-
-    return true;
-}
-
-TParseContextPointer& GetGlobalParseContext()
-{
-    //
-    // Minimal error checking for speed
-    //
-
-    TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
-
-    return lpParseContext->lpGlobalParseContext;
+    assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
+    return static_cast<TParseContext*>(OS_GetTLSValue(GlobalParseContextIndex));
 }
 
diff --git a/src/Radiance/compiler/InitializeParseContext.h b/src/Radiance/compiler/InitializeParseContext.h
index 354bfe1..4729d3c 100644
--- a/src/Radiance/compiler/InitializeParseContext.h
+++ b/src/Radiance/compiler/InitializeParseContext.h
@@ -8,19 +8,10 @@
 #define __INITIALIZE_PARSE_CONTEXT_INCLUDED_
 
 bool InitializeParseContextIndex();
-bool FreeParseContextIndex();
-
-bool InitializeGlobalParseContext();
-bool FreeParseContext();
+void FreeParseContextIndex();
 
 struct TParseContext;
-typedef TParseContext* TParseContextPointer;
-extern TParseContextPointer& GetGlobalParseContext();
-#define GlobalParseContext GetGlobalParseContext()
-
-typedef struct TThreadParseContextRec
-{
-    TParseContext *lpGlobalParseContext;
-} TThreadParseContext;
+extern void SetGlobalParseContext(TParseContext* context);
+extern TParseContext* GetGlobalParseContext();
 
 #endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_
diff --git a/src/Radiance/compiler/PoolAlloc.cpp b/src/Radiance/compiler/PoolAlloc.cpp
index 9cdbeaa..6ec3c40 100644
--- a/src/Radiance/compiler/PoolAlloc.cpp
+++ b/src/Radiance/compiler/PoolAlloc.cpp
@@ -16,55 +16,32 @@
 
 OS_TLSIndex PoolIndex = OS_INVALID_TLS_INDEX;
 
-void InitializeGlobalPools()
-{
-    TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));    
-    if (globalPools)
-        return;
-
-    TThreadGlobalPools* threadData = new TThreadGlobalPools();
-    threadData->globalPoolAllocator = 0;
-
-    OS_SetTLSValue(PoolIndex, threadData);
-}
-
-void FreeGlobalPools()
-{
-    // Release the allocated memory for this thread.
-    TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));    
-    if (!globalPools)
-        return;
- 
-    delete globalPools;
-}
-
 bool InitializePoolIndex()
 {
-    // Allocate a TLS index.
-    if ((PoolIndex = OS_AllocTLSIndex()) == OS_INVALID_TLS_INDEX)
-        return false;
+    assert(PoolIndex == OS_INVALID_TLS_INDEX);
 
-    return true;
+    PoolIndex = OS_AllocTLSIndex();
+    return PoolIndex != OS_INVALID_TLS_INDEX;
 }
 
 void FreePoolIndex()
 {
-    // Release the TLS index.
+    assert(PoolIndex != OS_INVALID_TLS_INDEX);
+
     OS_FreeTLSIndex(PoolIndex);
+    PoolIndex = OS_INVALID_TLS_INDEX;
 }
 
-TPoolAllocator& GetGlobalPoolAllocator()
+TPoolAllocator* GetGlobalPoolAllocator()
 {
-    TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
-
-    return *threadData->globalPoolAllocator;
+    assert(PoolIndex != OS_INVALID_TLS_INDEX);
+    return static_cast<TPoolAllocator*>(OS_GetTLSValue(PoolIndex));
 }
 
 void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator)
 {
-    TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
-
-    threadData->globalPoolAllocator = poolAllocator;
+    assert(PoolIndex != OS_INVALID_TLS_INDEX);
+    OS_SetTLSValue(PoolIndex, poolAllocator);
 }
 
 //
diff --git a/src/Radiance/compiler/PoolAlloc.h b/src/Radiance/compiler/PoolAlloc.h
index c33dfd9..b032c47 100644
--- a/src/Radiance/compiler/PoolAlloc.h
+++ b/src/Radiance/compiler/PoolAlloc.h
@@ -219,14 +219,8 @@
 // different times.  But a simple use is to have a global pop
 // with everyone using the same global allocator.
 //
-extern TPoolAllocator& GetGlobalPoolAllocator();
+extern TPoolAllocator* GetGlobalPoolAllocator();
 extern void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator);
-#define GlobalPoolAllocator GetGlobalPoolAllocator()
-
-struct TThreadGlobalPools
-{
-    TPoolAllocator* globalPoolAllocator;
-};
 
 //
 // This STL compatible allocator is intended to be used as the allocator
@@ -253,7 +247,7 @@
     pointer address(reference x) const { return &x; }
     const_pointer address(const_reference x) const { return &x; }
 
-    pool_allocator() : allocator(&GlobalPoolAllocator) { }
+    pool_allocator() : allocator(GetGlobalPoolAllocator()) { }
     pool_allocator(TPoolAllocator& a) : allocator(&a) { }
     pool_allocator(const pool_allocator<T>& p) : allocator(p.allocator) { }
 
diff --git a/src/Radiance/compiler/ShaderLang.cpp b/src/Radiance/compiler/ShaderLang.cpp
index 368c068..cd4e9ad 100644
--- a/src/Radiance/compiler/ShaderLang.cpp
+++ b/src/Radiance/compiler/ShaderLang.cpp
@@ -23,10 +23,7 @@
 //
 int ShInitialize()
 {
-    if (!InitProcess())
-        return 0;
-
-    return 1;
+    return InitProcess() ? 1 : 0;
 }
 
 //
@@ -34,9 +31,7 @@
 //
 int ShFinalize()
 {
-    if (!DetachProcess())
-        return 0;
-
+    DetachProcess();
     return 1;
 }
 
@@ -69,9 +64,6 @@
 ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
                              const ShBuiltInResources* resources)
 {
-    if (!InitThread())
-        return 0;
-
     TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec));
     TCompiler* compiler = base->getAsCompiler();
     if (compiler == 0)
@@ -110,9 +102,6 @@
     const int numStrings,
     int compileOptions)
 {
-    if (!InitThread())
-        return 0;
-
     if (handle == 0)
         return 0;
 
diff --git a/src/Radiance/compiler/SymbolTable.h b/src/Radiance/compiler/SymbolTable.h
index 6d4355d..739b7ad 100644
--- a/src/Radiance/compiler/SymbolTable.h
+++ b/src/Radiance/compiler/SymbolTable.h
@@ -40,9 +40,10 @@
 //
 class TSymbol {    
 public:
-    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
+    POOL_ALLOCATOR_NEW_DELETE();
     TSymbol(const TString *n) :  name(n) { }
     virtual ~TSymbol() { /* don't delete name, it's from the pool */ }
+
     const TString& getName() const { return *name; }
     virtual const TString& getMangledName() const { return getName(); }
     virtual bool isFunction() const { return false; }
@@ -179,7 +180,7 @@
     typedef const tLevel::value_type tLevelPair;
     typedef std::pair<tLevel::iterator, bool> tInsertResult;
 
-    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
+    POOL_ALLOCATOR_NEW_DELETE();
     TSymbolTableLevel() { }
     ~TSymbolTableLevel();
 
diff --git a/src/Radiance/compiler/Types.h b/src/Radiance/compiler/Types.h
index ff280d6..8b6f07c 100644
--- a/src/Radiance/compiler/Types.h
+++ b/src/Radiance/compiler/Types.h
@@ -1,314 +1,314 @@
-//

-// Copyright (c) 2002-2013 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.

-//

-

-#ifndef _TYPES_INCLUDED

-#define _TYPES_INCLUDED

-

-#include "compiler/BaseTypes.h"

-#include "compiler/Common.h"

-#include "compiler/debug.h"

-

-#include <algorithm>

-

-class TType;

-struct TPublicType;

-

-//

-// Need to have association of line numbers to types in a list for building structs.

-//

-struct TTypeLine {

-    TType* type;

-    int line;

-};

-typedef TVector<TTypeLine> TTypeList;

-

-inline TTypeList* NewPoolTTypeList()

-{

-    void* memory = GlobalPoolAllocator.allocate(sizeof(TTypeList));

-    return new(memory) TTypeList;

-}

-

-//

-// Base class for things that have a type.

-//

-class TType

-{

-public:

-    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)

-    TType() {}

-    TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :

-            type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0),

-            maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)

-    {

-    }

-    explicit TType(const TPublicType &p);

-    TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) :

-            type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),

-            maxArraySize(0), arrayInformationType(0), structure(userDef), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0)

-    {

-        typeName = NewPoolTString(n.c_str());

-    }

-

-    TBasicType getBasicType() const { return type; }

-    void setBasicType(TBasicType t) { type = t; }

-

-    TPrecision getPrecision() const { return precision; }

-    void setPrecision(TPrecision p) { precision = p; }

-

-    TQualifier getQualifier() const { return qualifier; }

-    void setQualifier(TQualifier q) { qualifier = q; }

-

-    // One-dimensional size of single instance type

-    int getNominalSize() const { return size; }

-    void setNominalSize(int s) { size = s; }

-    // Full size of single instance of type

-	int getObjectSize() const

-	{

-		if(isArray())

-		{

-			return getElementSize() * std::max(getArraySize(), getMaxArraySize());

-		}

-		else

-		{

-			return getElementSize();

-		}

-	}

-

-	int getElementSize() const

-	{

-		if(getBasicType() == EbtStruct)

-		{

-			return getStructSize();

-		}

-		else if(matrix)

-		{

-			return size * size;

-		}

-		else   // Vector or scalar

-		{

-			return size;

-		}

-	}

-

-	int elementRegisterCount() const

-	{

-		TTypeList *structure = getStruct();

-

-		if(structure)

-		{

-			int registerCount = 0;

-

-			for(size_t i = 0; i < structure->size(); i++)

-			{

-				registerCount += (*structure)[i].type->totalRegisterCount();

-			}

-

-			return registerCount;

-		}

-		else if(isMatrix())

-		{

-			return getNominalSize();

-		}

-		else

-		{

-			return 1;

-		}

-	}

-

-	int totalRegisterCount() const

-	{

-		if(array)

-		{

-			return arraySize * elementRegisterCount();

-		}

-		else

-		{

-			return elementRegisterCount();

-		}

-	}

-

-    bool isMatrix() const { return matrix ? true : false; }

-    void setMatrix(bool m) { matrix = m; }

-

-    bool isArray() const  { return array ? true : false; }

-    int getArraySize() const { return arraySize; }

-    void setArraySize(int s) { array = true; arraySize = s; }

-    int getMaxArraySize () const { return maxArraySize; }

-    void setMaxArraySize (int s) { maxArraySize = s; }

-    void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }

-    void setArrayInformationType(TType* t) { arrayInformationType = t; }

-    TType* getArrayInformationType() const { return arrayInformationType; }

-

-    bool isVector() const { return size > 1 && !matrix; }

-    bool isScalar() const { return size == 1 && !matrix && !structure; }

-	bool isRegister() const { return !matrix && !structure && !array; }   // Fits in a 4-element register

-	bool isStruct() const { return structure != 0; }

-

-    TTypeList* getStruct() const { return structure; }

-    void setStruct(TTypeList* s) { structure = s; computeDeepestStructNesting(); }

-

-    const TString& getTypeName() const

-    {

-        assert(typeName);

-        return *typeName;

-    }

-    void setTypeName(const TString& n)

-    {

-        typeName = NewPoolTString(n.c_str());

-    }

-

-    bool isField() const { return fieldName != 0; }

-    const TString& getFieldName() const

-    {

-        assert(fieldName);

-        return *fieldName;

-    }

-    void setFieldName(const TString& n)

-    {

-        fieldName = NewPoolTString(n.c_str());

-    }

-

-    TString& getMangledName() {

-        if (!mangled) {

-            mangled = NewPoolTString("");

-            buildMangledName(*mangled);

-            *mangled += ';' ;

-        }

-

-        return *mangled;

-    }

-

-    bool sameElementType(const TType& right) const {

-        return      type == right.type   &&

-                    size == right.size   &&

-                  matrix == right.matrix &&

-               structure == right.structure;

-    }

-    bool operator==(const TType& right) const {

-        return      type == right.type   &&

-                    size == right.size   &&

-                  matrix == right.matrix &&

-                   array == right.array  && (!array || arraySize == right.arraySize) &&

-               structure == right.structure;

-        // don't check the qualifier, it's not ever what's being sought after

-    }

-    bool operator!=(const TType& right) const {

-        return !operator==(right);

-    }

-    bool operator<(const TType& right) const {

-        if (type != right.type) return type < right.type;

-        if (size != right.size) return size < right.size;

-        if (matrix != right.matrix) return matrix < right.matrix;

-        if (array != right.array) return array < right.array;

-        if (arraySize != right.arraySize) return arraySize < right.arraySize;

-        if (structure != right.structure) return structure < right.structure;

-

-        return false;

-    }

-

-    const char* getBasicString() const { return ::getBasicString(type); }

-    const char* getPrecisionString() const { return ::getPrecisionString(precision); }

-    const char* getQualifierString() const { return ::getQualifierString(qualifier); }

-    TString getCompleteString() const;

-

-    // If this type is a struct, returns the deepest struct nesting of

-    // any field in the struct. For example:

-    //   struct nesting1 {

-    //     vec4 position;

-    //   };

-    //   struct nesting2 {

-    //     nesting1 field1;

-    //     vec4 field2;

-    //   };

-    // For type "nesting2", this method would return 2 -- the number

-    // of structures through which indirection must occur to reach the

-    // deepest field (nesting2.field1.position).

-    int getDeepestStructNesting() const { return deepestStructNesting; }

-

-    bool isStructureContainingArrays() const;

-

-protected:

-    void buildMangledName(TString&);

-    int getStructSize() const;

-    void computeDeepestStructNesting();

-

-    TBasicType type      : 6;

-    TPrecision precision;

-    TQualifier qualifier : 7;

-    int size             : 8; // size of vector or matrix, not size of array

-    unsigned int matrix  : 1;

-    unsigned int array   : 1;

-    int arraySize;

-    int maxArraySize;

-    TType* arrayInformationType;

-

-    TTypeList* structure;      // 0 unless this is a struct

-    mutable int structureSize;

-    int deepestStructNesting;

-

-    TString *fieldName;         // for structure field names

-    TString *mangled;

-    TString *typeName;          // for structure field type name

-};

-

-//

-// This is a workaround for a problem with the yacc stack,  It can't have

-// types that it thinks have non-trivial constructors.  It should

-// just be used while recognizing the grammar, not anything else.  Pointers

-// could be used, but also trying to avoid lots of memory management overhead.

-//

-// Not as bad as it looks, there is no actual assumption that the fields

-// match up or are name the same or anything like that.

-//

-struct TPublicType

-{

-    TBasicType type;

-    TQualifier qualifier;

-    TPrecision precision;

-    int size;          // size of vector or matrix, not size of array

-    bool matrix;

-    bool array;

-    int arraySize;

-    TType* userDef;

-    int line;

-

-    void setBasic(TBasicType bt, TQualifier q, int ln = 0)

-    {

-        type = bt;

-        qualifier = q;

-        precision = EbpUndefined;

-        size = 1;

-        matrix = false;

-        array = false;

-        arraySize = 0;

-        userDef = 0;

-        line = ln;

-    }

-

-    void setAggregate(int s, bool m = false)

-    {

-        size = s;

-        matrix = m;

-    }

-

-    void setArray(bool a, int s = 0)

-    {

-        array = a;

-        arraySize = s;

-    }

-

-    bool isStructureContainingArrays() const

-    {

-        if (!userDef)

-        {

-            return false;

-        }

-

-        return userDef->isStructureContainingArrays();

-    }

-};

-

-#endif // _TYPES_INCLUDED_

+//
+// Copyright (c) 2002-2013 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.
+//
+
+#ifndef _TYPES_INCLUDED
+#define _TYPES_INCLUDED
+
+#include "compiler/BaseTypes.h"
+#include "compiler/Common.h"
+#include "compiler/debug.h"
+
+#include <algorithm>
+
+class TType;
+struct TPublicType;
+
+//
+// Need to have association of line numbers to types in a list for building structs.
+//
+struct TTypeLine {
+    TType* type;
+    int line;
+};
+typedef TVector<TTypeLine> TTypeList;
+
+inline TTypeList* NewPoolTTypeList()
+{
+    void* memory = GetGlobalPoolAllocator()->allocate(sizeof(TTypeList));
+    return new(memory) TTypeList;
+}
+
+//
+// Base class for things that have a type.
+//
+class TType
+{
+public:
+    POOL_ALLOCATOR_NEW_DELETE();
+    TType() {}
+    TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
+            type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0),
+            maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
+    {
+    }
+    explicit TType(const TPublicType &p);
+    TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) :
+            type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),
+            maxArraySize(0), arrayInformationType(0), structure(userDef), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0)
+    {
+        typeName = NewPoolTString(n.c_str());
+    }
+
+    TBasicType getBasicType() const { return type; }
+    void setBasicType(TBasicType t) { type = t; }
+
+    TPrecision getPrecision() const { return precision; }
+    void setPrecision(TPrecision p) { precision = p; }
+
+    TQualifier getQualifier() const { return qualifier; }
+    void setQualifier(TQualifier q) { qualifier = q; }
+
+    // One-dimensional size of single instance type
+    int getNominalSize() const { return size; }
+    void setNominalSize(int s) { size = s; }
+    // Full size of single instance of type
+	int getObjectSize() const
+	{
+		if(isArray())
+		{
+			return getElementSize() * std::max(getArraySize(), getMaxArraySize());
+		}
+		else
+		{
+			return getElementSize();
+		}
+	}
+
+	int getElementSize() const
+	{
+		if(getBasicType() == EbtStruct)
+		{
+			return getStructSize();
+		}
+		else if(matrix)
+		{
+			return size * size;
+		}
+		else   // Vector or scalar
+		{
+			return size;
+		}
+	}
+
+	int elementRegisterCount() const
+	{
+		TTypeList *structure = getStruct();
+
+		if(structure)
+		{
+			int registerCount = 0;
+
+			for(size_t i = 0; i < structure->size(); i++)
+			{
+				registerCount += (*structure)[i].type->totalRegisterCount();
+			}
+
+			return registerCount;
+		}
+		else if(isMatrix())
+		{
+			return getNominalSize();
+		}
+		else
+		{
+			return 1;
+		}
+	}
+
+	int totalRegisterCount() const
+	{
+		if(array)
+		{
+			return arraySize * elementRegisterCount();
+		}
+		else
+		{
+			return elementRegisterCount();
+		}
+	}
+
+    bool isMatrix() const { return matrix ? true : false; }
+    void setMatrix(bool m) { matrix = m; }
+
+    bool isArray() const  { return array ? true : false; }
+    int getArraySize() const { return arraySize; }
+    void setArraySize(int s) { array = true; arraySize = s; }
+    int getMaxArraySize () const { return maxArraySize; }
+    void setMaxArraySize (int s) { maxArraySize = s; }
+    void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }
+    void setArrayInformationType(TType* t) { arrayInformationType = t; }
+    TType* getArrayInformationType() const { return arrayInformationType; }
+
+    bool isVector() const { return size > 1 && !matrix; }
+    bool isScalar() const { return size == 1 && !matrix && !structure; }
+	bool isRegister() const { return !matrix && !structure && !array; }   // Fits in a 4-element register
+	bool isStruct() const { return structure != 0; }
+
+    TTypeList* getStruct() const { return structure; }
+    void setStruct(TTypeList* s) { structure = s; computeDeepestStructNesting(); }
+
+    const TString& getTypeName() const
+    {
+        assert(typeName);
+        return *typeName;
+    }
+    void setTypeName(const TString& n)
+    {
+        typeName = NewPoolTString(n.c_str());
+    }
+
+    bool isField() const { return fieldName != 0; }
+    const TString& getFieldName() const
+    {
+        assert(fieldName);
+        return *fieldName;
+    }
+    void setFieldName(const TString& n)
+    {
+        fieldName = NewPoolTString(n.c_str());
+    }
+
+    TString& getMangledName() {
+        if (!mangled) {
+            mangled = NewPoolTString("");
+            buildMangledName(*mangled);
+            *mangled += ';' ;
+        }
+
+        return *mangled;
+    }
+
+    bool sameElementType(const TType& right) const {
+        return      type == right.type   &&
+                    size == right.size   &&
+                  matrix == right.matrix &&
+               structure == right.structure;
+    }
+    bool operator==(const TType& right) const {
+        return      type == right.type   &&
+                    size == right.size   &&
+                  matrix == right.matrix &&
+                   array == right.array  && (!array || arraySize == right.arraySize) &&
+               structure == right.structure;
+        // don't check the qualifier, it's not ever what's being sought after
+    }
+    bool operator!=(const TType& right) const {
+        return !operator==(right);
+    }
+    bool operator<(const TType& right) const {
+        if (type != right.type) return type < right.type;
+        if (size != right.size) return size < right.size;
+        if (matrix != right.matrix) return matrix < right.matrix;
+        if (array != right.array) return array < right.array;
+        if (arraySize != right.arraySize) return arraySize < right.arraySize;
+        if (structure != right.structure) return structure < right.structure;
+
+        return false;
+    }
+
+    const char* getBasicString() const { return ::getBasicString(type); }
+    const char* getPrecisionString() const { return ::getPrecisionString(precision); }
+    const char* getQualifierString() const { return ::getQualifierString(qualifier); }
+    TString getCompleteString() const;
+
+    // If this type is a struct, returns the deepest struct nesting of
+    // any field in the struct. For example:
+    //   struct nesting1 {
+    //     vec4 position;
+    //   };
+    //   struct nesting2 {
+    //     nesting1 field1;
+    //     vec4 field2;
+    //   };
+    // For type "nesting2", this method would return 2 -- the number
+    // of structures through which indirection must occur to reach the
+    // deepest field (nesting2.field1.position).
+    int getDeepestStructNesting() const { return deepestStructNesting; }
+
+    bool isStructureContainingArrays() const;
+
+protected:
+    void buildMangledName(TString&);
+    int getStructSize() const;
+    void computeDeepestStructNesting();
+
+    TBasicType type      : 6;
+    TPrecision precision;
+    TQualifier qualifier : 7;
+    int size             : 8; // size of vector or matrix, not size of array
+    unsigned int matrix  : 1;
+    unsigned int array   : 1;
+    int arraySize;
+    int maxArraySize;
+    TType* arrayInformationType;
+
+    TTypeList* structure;      // 0 unless this is a struct
+    mutable int structureSize;
+    int deepestStructNesting;
+
+    TString *fieldName;         // for structure field names
+    TString *mangled;
+    TString *typeName;          // for structure field type name
+};
+
+//
+// This is a workaround for a problem with the yacc stack,  It can't have
+// types that it thinks have non-trivial constructors.  It should
+// just be used while recognizing the grammar, not anything else.  Pointers
+// could be used, but also trying to avoid lots of memory management overhead.
+//
+// Not as bad as it looks, there is no actual assumption that the fields
+// match up or are name the same or anything like that.
+//
+struct TPublicType
+{
+    TBasicType type;
+    TQualifier qualifier;
+    TPrecision precision;
+    int size;          // size of vector or matrix, not size of array
+    bool matrix;
+    bool array;
+    int arraySize;
+    TType* userDef;
+    int line;
+
+    void setBasic(TBasicType bt, TQualifier q, int ln = 0)
+    {
+        type = bt;
+        qualifier = q;
+        precision = EbpUndefined;
+        size = 1;
+        matrix = false;
+        array = false;
+        arraySize = 0;
+        userDef = 0;
+        line = ln;
+    }
+
+    void setAggregate(int s, bool m = false)
+    {
+        size = s;
+        matrix = m;
+    }
+
+    void setArray(bool a, int s = 0)
+    {
+        array = a;
+        arraySize = s;
+    }
+
+    bool isStructureContainingArrays() const
+    {
+        if (!userDef)
+        {
+            return false;
+        }
+
+        return userDef->isStructureContainingArrays();
+    }
+};
+
+#endif // _TYPES_INCLUDED_
diff --git a/src/Radiance/compiler/ValidateLimitations.cpp b/src/Radiance/compiler/ValidateLimitations.cpp
index 5838d0f..9219cd1 100644
--- a/src/Radiance/compiler/ValidateLimitations.cpp
+++ b/src/Radiance/compiler/ValidateLimitations.cpp
@@ -435,7 +435,7 @@
         return true;
 
     bool valid = true;
-    TSymbolTable& symbolTable = GlobalParseContext->symbolTable;
+    TSymbolTable& symbolTable = GetGlobalParseContext()->symbolTable;
     TSymbol* symbol = symbolTable.find(node->getName());
     ASSERT(symbol && symbol->isFunction());
     TFunction* function = static_cast<TFunction*>(symbol);
diff --git a/src/Radiance/compiler/intermediate.h b/src/Radiance/compiler/intermediate.h
index fe7c363..18b889f 100644
--- a/src/Radiance/compiler/intermediate.h
+++ b/src/Radiance/compiler/intermediate.h
@@ -196,7 +196,7 @@
 //
 class TIntermNode {
 public:
-    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
+    POOL_ALLOCATOR_NEW_DELETE();
 
     TIntermNode() : line(0) {}
 
@@ -510,8 +510,7 @@
 class TIntermTraverser
 {
 public:
-    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
-
+    POOL_ALLOCATOR_NEW_DELETE();
     TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) : 
             preVisit(preVisit),
             inVisit(inVisit),
diff --git a/src/Radiance/compiler/localintermediate.h b/src/Radiance/compiler/localintermediate.h
index 253548d..805744f 100644
--- a/src/Radiance/compiler/localintermediate.h
+++ b/src/Radiance/compiler/localintermediate.h
@@ -21,7 +21,7 @@
 class TInfoSink;
 class TIntermediate {
 public:
-    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
+    POOL_ALLOCATOR_NEW_DELETE();
 
     TIntermediate(TInfoSink& i) : infoSink(i) { }
     TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc);
diff --git a/src/Radiance/libRAD/Shader.cpp b/src/Radiance/libRAD/Shader.cpp
index e8d2925..8908dc6 100644
--- a/src/Radiance/libRAD/Shader.cpp
+++ b/src/Radiance/libRAD/Shader.cpp
@@ -24,6 +24,8 @@
 
 namespace rad
 {
+bool Shader::compilerInitialized = false;
+
 Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
 {
     mSource = NULL;
@@ -154,7 +156,11 @@
 
 TranslatorASM *Shader::createCompiler(ShShaderType type)
 {
-	ShInitialize();
+	if(!compilerInitialized)
+	{
+		ShInitialize();
+		compilerInitialized = true;
+	}
 
 	TranslatorASM *assembler = new TranslatorASM(this, type, SH_GLES2_SPEC);
 
@@ -233,6 +239,7 @@
 void Shader::releaseCompiler()
 {
     ShFinalize();
+	compilerInitialized = false;
 }
 
 GLenum Shader::parseType(const std::string &type)
diff --git a/src/Radiance/libRAD/Shader.h b/src/Radiance/libRAD/Shader.h
index 4eb9312..409cbd7 100644
--- a/src/Radiance/libRAD/Shader.h
+++ b/src/Radiance/libRAD/Shader.h
@@ -97,6 +97,7 @@
     static void releaseCompiler();

 

 protected:

+	static bool compilerInitialized;

 	TranslatorASM *createCompiler(ShShaderType type);

 	void clear();