Bug 697333 - Update ANGLE to r809 - no review
authorBenoit Jacob <bjacob@mozilla.com>
Wed, 02 Nov 2011 00:56:35 -0400
changeset 80905 93625e3af8bca0b25c58959e33fd3f6dac3889fa
parent 80904 26d38dea2c7c68c5316397b002ae014da9e06bb0
child 80906 1630a68499bc158946f7211be9cb7fda8e257b9e
push id434
push userclegnitto@mozilla.com
push dateWed, 21 Dec 2011 12:10:54 +0000
treeherdermozilla-beta@bddb6ed8dd47 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs697333, 676071, 694495
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 697333 - Update ANGLE to r809 - no review This is just syncing us with the upstream, http://code.google.com/p/angleproject/ This gets us two important fixes, for bug 676071 and bug 694495.
gfx/angle/Makefile.in
gfx/angle/README.mozilla
gfx/angle/angle-intrinsic-msvc2005.patch
gfx/angle/angle-limit-identifiers-to-250-chars.patch
gfx/angle/angle-renaming-debug.patch
gfx/angle/src/build_angle.gyp
gfx/angle/src/common/version.h
gfx/angle/src/compiler/Compiler.cpp
gfx/angle/src/compiler/MapLongVariableNames.cpp
gfx/angle/src/compiler/MapLongVariableNames.h
gfx/angle/src/compiler/ParseHelper.cpp
gfx/angle/src/compiler/ParseHelper.h
gfx/angle/src/compiler/ShaderLang.cpp
gfx/angle/src/compiler/SymbolTable.cpp
gfx/angle/src/compiler/Types.h
gfx/angle/src/compiler/glslang.y
gfx/angle/src/compiler/glslang_tab.cpp
gfx/angle/src/compiler/preprocessor/length_limits.h
gfx/angle/src/compiler/preprocessor/scanner.h
gfx/angle/src/libGLESv2/Context.cpp
gfx/angle/src/libGLESv2/Context.h
gfx/angle/src/libGLESv2/Program.cpp
gfx/angle/src/libGLESv2/Program.h
gfx/angle/src/libGLESv2/libGLESv2.cpp
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in
@@ -121,17 +121,17 @@ CSRCS   = \
         cpp.c \
         cppstruct.c \
         memory.c \
         scanner.c \
         symbols.c \
         tokens.c \
 	$(NULL)
 
-DEFINES += -DANGLE_USE_NSPR -DANGLE_BUILD
+DEFINES += -DANGLE_USE_NSPR -DANGLE_BUILD -DCOMPILER_IMPLEMENTATION
 
 #these defines are from ANGLE's build_angle.gyp
 DEFINES += -DANGLE_DISABLE_TRACE
 DEFINES += -DANGLE_COMPILE_OPTIMIZATION_LEVEL=D3DCOMPILE_OPTIMIZATION_LEVEL0
 
 EXTRA_DSO_LDOPTS = $(MOZALLOC_LIB)
 
 ifdef MOZ_ANGLE
--- a/gfx/angle/README.mozilla
+++ b/gfx/angle/README.mozilla
@@ -1,11 +1,11 @@
 This is the ANGLE project, from http://code.google.com/p/angleproject/
 
-Current revision: r802
+Current revision: r809
 
 == Applied local patches ==
 
 In this order:
   angle-renaming-debug.patch - rename debug.h to compilerdebug.h to avoid conflict in our makefiles
   angle-intrinsic-msvc2005.patch - work around a MSVC 2005 compile error
   angle-limit-identifiers-to-250-chars.patch - see bug 675625
   angle-use-xmalloc.patch - see bug 680840. Can drop this patch whenever the new preprocessor lands.
--- a/gfx/angle/angle-intrinsic-msvc2005.patch
+++ b/gfx/angle/angle-intrinsic-msvc2005.patch
@@ -1,45 +1,10 @@
 # HG changeset patch
-# Parent cf38970fcf3b4bee12f09b3747b7b7711bc77ad8
-diff --git a/gfx/angle/angle-renaming-debug.patch b/gfx/angle/angle-renaming-debug.patch
---- a/gfx/angle/angle-renaming-debug.patch
-+++ b/gfx/angle/angle-renaming-debug.patch
-@@ -1,11 +1,10 @@
- # HG changeset patch
--# Parent 96359f46b01fdb37e791f564495e8b2755a05233
--
-+# Parent 70640278da97b0ca49e21c4bb52766b8af7db4db
- diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
- --- a/gfx/angle/Makefile.in
- +++ b/gfx/angle/Makefile.in
- @@ -73,17 +73,17 @@ CPPSRCS = \
-          parseConst.cpp \
-          ParseHelper.cpp \
-          PoolAlloc.cpp \
-          QualifierAlive.cpp \
-@@ -129,17 +128,17 @@ diff --git a/gfx/angle/src/compiler/comp
-  
-  #include <assert.h>
-  
-  #ifdef _DEBUG
-  #define TRACE_ENABLED  // define to enable debug message tracing
- diff --git a/gfx/angle/src/compiler/osinclude.h b/gfx/angle/src/compiler/osinclude.h
- --- a/gfx/angle/src/compiler/osinclude.h
- +++ b/gfx/angle/src/compiler/osinclude.h
--@@ -32,17 +32,17 @@
-+@@ -30,17 +30,17 @@
-  #include <windows.h>
-  #elif defined(ANGLE_OS_POSIX)
-  #include <pthread.h>
-  #include <semaphore.h>
-  #include <errno.h>
-  #endif  // ANGLE_USE_NSPR
-  
-  
+# Parent b5604c321da4e3b5d6b0a940d18022a827061579
 diff --git a/gfx/angle/src/libGLESv2/Texture.cpp b/gfx/angle/src/libGLESv2/Texture.cpp
 --- a/gfx/angle/src/libGLESv2/Texture.cpp
 +++ b/gfx/angle/src/libGLESv2/Texture.cpp
 @@ -8,16 +8,22 @@
  // Texture2D and TextureCubeMap. Implements GL texture objects and related
  // functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
  
  #include "libGLESv2/Texture.h"
--- a/gfx/angle/angle-limit-identifiers-to-250-chars.patch
+++ b/gfx/angle/angle-limit-identifiers-to-250-chars.patch
@@ -1,26 +1,42 @@
 # HG changeset patch
-# Parent f9415c10c3ebd27856500cca7a0ee0f28a16f53c
-diff --git a/gfx/angle/src/compiler/preprocessor/scanner.h b/gfx/angle/src/compiler/preprocessor/scanner.h
---- a/gfx/angle/src/compiler/preprocessor/scanner.h
-+++ b/gfx/angle/src/compiler/preprocessor/scanner.h
-@@ -44,17 +44,19 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILI
- //
- // scanner.h
- //
+# Parent e8b87ef36a1dae3bbd7abb13c4bb0a0bb8f5b58c
+diff --git a/gfx/angle/README.mozilla b/gfx/angle/README.mozilla
+--- a/gfx/angle/README.mozilla
++++ b/gfx/angle/README.mozilla
+@@ -2,16 +2,17 @@ This is the ANGLE project, from http://c
+ 
+ Current revision: r802
+ 
+ == Applied local patches ==
+ 
+ In this order:
+   angle-renaming-debug.patch - rename debug.h to compilerdebug.h to avoid conflict in our makefiles
+   angle-intrinsic-msvc2005.patch - work around a MSVC 2005 compile error
++  angle-limit-identifiers-to-250-chars.patch - see bug 675625
  
- #if !defined(__SCANNER_H)
- #define __SCANNER_H 1
+ In addition to these patches, the Makefile.in files are ours, they're not present in upsteam ANGLE.
+ 
+ == How to update this ANGLE copy ==
+ 
+ 1. Unapply patches
+ 2. Apply diff with new ANGLE version
+ 3. Reapply patches.
+diff --git a/gfx/angle/src/compiler/preprocessor/length_limits.h b/gfx/angle/src/compiler/preprocessor/length_limits.h
+--- a/gfx/angle/src/compiler/preprocessor/length_limits.h
++++ b/gfx/angle/src/compiler/preprocessor/length_limits.h
+@@ -10,12 +10,14 @@
+ 
+ #if !defined(__LENGTH_LIMITS_H)
+ #define __LENGTH_LIMITS_H 1
+ 
+ // These constants are factored out from the rest of the headers to
+ // make it easier to reference them from the compiler sources.
  
  // These lengths do not include the NULL terminator.
 -#define MAX_SYMBOL_NAME_LEN 256
 +// see bug 675625: NVIDIA driver crash with lengths >= 253
 +// this is only an interim fix, the real fix is name mapping, see ANGLE bug 144 / r619
 +#define MAX_SYMBOL_NAME_LEN 250
  #define MAX_STRING_LEN 511
  
- #include "compiler/preprocessor/parser.h"
- 
- // Not really atom table stuff but needed first...
- 
- typedef struct SourceLoc_Rec {
-     unsigned short file, line;
+ #endif // !(defined(__LENGTH_LIMITS_H)
--- a/gfx/angle/angle-renaming-debug.patch
+++ b/gfx/angle/angle-renaming-debug.patch
@@ -1,10 +1,10 @@
 # HG changeset patch
-# Parent 70640278da97b0ca49e21c4bb52766b8af7db4db
+# Parent 0239f15c7212413b5cffe66aee9ae5a4feb28f16
 diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
 --- a/gfx/angle/Makefile.in
 +++ b/gfx/angle/Makefile.in
 @@ -73,17 +73,17 @@ CPPSRCS = \
          parseConst.cpp \
          ParseHelper.cpp \
          PoolAlloc.cpp \
          QualifierAlive.cpp \
--- a/gfx/angle/src/build_angle.gyp
+++ b/gfx/angle/src/build_angle.gyp
@@ -12,16 +12,19 @@
   'targets': [
     {
       'target_name': 'translator_common',
       'type': 'static_library',
       'include_dirs': [
         '.',
         '../include',
       ],
+      'defines': [
+        'COMPILER_IMPLEMENTATION',
+      ],
       'sources': [
         'compiler/BaseTypes.h',
         'compiler/BuiltInFunctionEmulator.cpp',
         'compiler/BuiltInFunctionEmulator.h',
         'compiler/Common.h',
         'compiler/Compiler.cpp',
         'compiler/ConstantUnion.h',
         'compiler/debug.cpp',
@@ -55,33 +58,33 @@
         'compiler/ParseHelper.cpp',
         'compiler/ParseHelper.h',
         'compiler/PoolAlloc.cpp',
         'compiler/PoolAlloc.h',
         'compiler/QualifierAlive.cpp',
         'compiler/QualifierAlive.h',
         'compiler/RemoveTree.cpp',
         'compiler/RemoveTree.h',
-        'compiler/ShaderLang.cpp',
         'compiler/ShHandle.h',
         'compiler/SymbolTable.cpp',
         'compiler/SymbolTable.h',
         'compiler/Types.h',
         'compiler/util.cpp',
         'compiler/util.h',
         'compiler/ValidateLimitations.cpp',
         'compiler/ValidateLimitations.h',
         'compiler/VariableInfo.cpp',
         'compiler/VariableInfo.h',
         'compiler/preprocessor/atom.c',
         'compiler/preprocessor/atom.h',
         'compiler/preprocessor/compile.h',
         'compiler/preprocessor/cpp.c',
         'compiler/preprocessor/cpp.h',
         'compiler/preprocessor/cppstruct.c',
+        'compiler/preprocessor/length_limits.h',
         'compiler/preprocessor/memory.c',
         'compiler/preprocessor/memory.h',
         'compiler/preprocessor/parser.h',
         'compiler/preprocessor/preprocess.h',
         'compiler/preprocessor/scanner.c',
         'compiler/preprocessor/scanner.h',
         'compiler/preprocessor/slglobals.h',
         'compiler/preprocessor/symbols.c',
@@ -94,47 +97,55 @@
           'sources': ['compiler/ossource_win.cpp'],
         }, { # else: posix
           'sources': ['compiler/ossource_posix.cpp'],
         }],
       ],
     },
     {
       'target_name': 'translator_glsl',
-      'type': 'static_library',
+      'type': '<(component)',
       'dependencies': ['translator_common'],
       'include_dirs': [
         '.',
         '../include',
       ],
+      'defines': [
+        'COMPILER_IMPLEMENTATION',
+      ],
       'sources': [
         'compiler/CodeGenGLSL.cpp',
         'compiler/OutputESSL.cpp',
         'compiler/OutputESSL.h',        
         'compiler/OutputGLSLBase.cpp',
         'compiler/OutputGLSLBase.h',
         'compiler/OutputGLSL.cpp',
         'compiler/OutputGLSL.h',
+        'compiler/ShaderLang.cpp',
         'compiler/TranslatorESSL.cpp',
         'compiler/TranslatorESSL.h',
         'compiler/TranslatorGLSL.cpp',
         'compiler/TranslatorGLSL.h',
         'compiler/VersionGLSL.cpp',
         'compiler/VersionGLSL.h',
       ],
     },
     {
       'target_name': 'translator_hlsl',
-      'type': 'static_library',
+      'type': '<(component)',
       'dependencies': ['translator_common'],
       'include_dirs': [
         '.',
         '../include',
       ],
+      'defines': [
+        'COMPILER_IMPLEMENTATION',
+      ],
       'sources': [
+        'compiler/ShaderLang.cpp',
         'compiler/CodeGenHLSL.cpp',
         'compiler/OutputHLSL.cpp',
         'compiler/OutputHLSL.h',
         'compiler/TranslatorHLSL.cpp',
         'compiler/TranslatorHLSL.h',
         'compiler/UnfoldSelect.cpp',
         'compiler/UnfoldSelect.h',
         'compiler/SearchSymbol.cpp',
--- a/gfx/angle/src/common/version.h
+++ b/gfx/angle/src/common/version.h
@@ -1,10 +1,10 @@
 #define MAJOR_VERSION 0
 #define MINOR_VERSION 0
 #define BUILD_VERSION 0
-#define BUILD_REVISION 802
+#define BUILD_REVISION 809
 
 #define STRINGIFY(x) #x
 #define MACRO_STRINGIFY(x) STRINGIFY(x)
 
 #define REVISION_STRING MACRO_STRINGIFY(BUILD_REVISION)
 #define VERSION_STRING MACRO_STRINGIFY(MAJOR_VERSION) "." MACRO_STRINGIFY(MINOR_VERSION) "." MACRO_STRINGIFY(BUILD_VERSION) "." MACRO_STRINGIFY(BUILD_REVISION)
--- a/gfx/angle/src/compiler/Compiler.cpp
+++ b/gfx/angle/src/compiler/Compiler.cpp
@@ -1,10 +1,10 @@
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #include "compiler/BuiltInFunctionEmulator.h"
 #include "compiler/DetectRecursion.h"
 #include "compiler/ForLoopUnroll.h"
 #include "compiler/Initialize.h"
@@ -247,17 +247,17 @@ void TCompiler::collectAttribsUniforms(T
 void TCompiler::mapLongVariableNames(TIntermNode* root)
 {
     MapLongVariableNames map(varyingLongNameMap);
     root->traverse(&map);
 }
 
 int TCompiler::getMappedNameMaxLength() const
 {
-    return MAX_IDENTIFIER_NAME_SIZE + 1;
+    return MAX_SHORTENED_IDENTIFIER_SIZE + 1;
 }
 
 const TExtensionBehavior& TCompiler::getExtensionBehavior() const
 {
     return extensionBehavior;
 }
 
 const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
--- a/gfx/angle/src/compiler/MapLongVariableNames.cpp
+++ b/gfx/angle/src/compiler/MapLongVariableNames.cpp
@@ -5,38 +5,38 @@
 //
 
 #include "compiler/MapLongVariableNames.h"
 
 namespace {
 
 TString mapLongName(int id, const TString& name, bool isVarying)
 {
-    ASSERT(name.size() > MAX_IDENTIFIER_NAME_SIZE);
+    ASSERT(name.size() > MAX_SHORTENED_IDENTIFIER_SIZE);
     TStringStream stream;
     stream << "webgl_";
     if (isVarying)
         stream << "v";
     stream << id << "_";
-    stream << name.substr(0, MAX_IDENTIFIER_NAME_SIZE - stream.str().size());
+    stream << name.substr(0, MAX_SHORTENED_IDENTIFIER_SIZE - stream.str().size());
     return stream.str();
 }
 
 }  // anonymous namespace
 
 MapLongVariableNames::MapLongVariableNames(
     std::map<std::string, std::string>& varyingLongNameMap)
     : mVaryingLongNameMap(varyingLongNameMap)
 {
 }
 
 void MapLongVariableNames::visitSymbol(TIntermSymbol* symbol)
 {
     ASSERT(symbol != NULL);
-    if (symbol->getSymbol().size() > MAX_IDENTIFIER_NAME_SIZE) {
+    if (symbol->getSymbol().size() > MAX_SHORTENED_IDENTIFIER_SIZE) {
         switch (symbol->getQualifier()) {
           case EvqVaryingIn:
           case EvqVaryingOut:
           case EvqInvariantVaryingIn:
           case EvqInvariantVaryingOut:
             symbol->setSymbol(
                 mapVaryingLongName(symbol->getSymbol()));
             break;
--- a/gfx/angle/src/compiler/MapLongVariableNames.h
+++ b/gfx/angle/src/compiler/MapLongVariableNames.h
@@ -8,20 +8,20 @@
 #define COMPILER_MAP_LONG_VARIABLE_NAMES_H_
 
 #include "GLSLANG/ShaderLang.h"
 
 #include "compiler/intermediate.h"
 #include "compiler/VariableInfo.h"
 
 // This size does not include '\0' in the end.
-#define MAX_IDENTIFIER_NAME_SIZE 32
+#define MAX_SHORTENED_IDENTIFIER_SIZE 32
 
 // Traverses intermediate tree to map attributes and uniforms names that are
-// longer than MAX_IDENTIFIER_NAME_SIZE to MAX_IDENTIFIER_NAME_SIZE.
+// longer than MAX_SHORTENED_IDENTIFIER_SIZE to MAX_SHORTENED_IDENTIFIER_SIZE.
 class MapLongVariableNames : public TIntermTraverser {
 public:
     MapLongVariableNames(std::map<std::string, std::string>& varyingLongNameMap);
 
     virtual void visitSymbol(TIntermSymbol*);
     virtual bool visitLoop(Visit, TIntermLoop*);
 
 private:
--- a/gfx/angle/src/compiler/ParseHelper.cpp
+++ b/gfx/angle/src/compiler/ParseHelper.cpp
@@ -1420,16 +1420,63 @@ TIntermTyped* TParseContext::addConstStr
         recover();
 
         return 0;
     }
 
     return typedNode;
 }
 
+bool TParseContext::enterStructDeclaration(int line, const TString& identifier)
+{
+    ++structNestingLevel;
+
+    // Embedded structure definitions are not supported per GLSL ES spec.
+    // They aren't allowed in GLSL either, but we need to detect this here
+    // so we don't rely on the GLSL compiler to catch it.
+    if (structNestingLevel > 1) {
+        error(line, "", "Embedded struct definitions are not allowed", "");
+        return true;
+    }
+
+    return false;
+}
+
+void TParseContext::exitStructDeclaration()
+{
+    --structNestingLevel;
+}
+
+namespace {
+
+const int kWebGLMaxStructNesting = 4;
+
+}  // namespace
+
+bool TParseContext::structNestingErrorCheck(TSourceLoc line, const TType& fieldType)
+{
+    if (shaderSpec != SH_WEBGL_SPEC) {
+        return false;
+    }
+
+    if (fieldType.getBasicType() != EbtStruct) {
+        return false;
+    }
+
+    // We're already inside a structure definition at this point, so add
+    // one to the field's struct nesting.
+    if (1 + fieldType.getDeepestStructNesting() >= kWebGLMaxStructNesting) {
+        error(line, "", "", "Reference of struct type %s exceeds maximum struct nesting of %d",
+              fieldType.getTypeName().c_str(), kWebGLMaxStructNesting);
+        return true;
+    }
+
+    return false;
+}
+
 //
 // Parse an array of strings using yyparse.
 //
 // Returns 0 for success.
 //
 int PaParseStrings(int count, const char* const string[], const int length[],
                    TParseContext* context) {
     if ((count == 0) || (string == NULL))
--- a/gfx/angle/src/compiler/ParseHelper.h
+++ b/gfx/angle/src/compiler/ParseHelper.h
@@ -26,31 +26,48 @@ struct TPragma {
 };
 
 //
 // The following are extra variables needed during parsing, grouped together so
 // they can be passed to the parser without needing a global.
 //
 struct TParseContext {
     TParseContext(TSymbolTable& symt, TExtensionBehavior& ext, TIntermediate& interm, ShShaderType type, ShShaderSpec spec, int options, bool checksPrecErrors, const char* sourcePath, TInfoSink& is) :
-            intermediate(interm), symbolTable(symt), extensionBehavior(ext), infoSink(is), shaderType(type), shaderSpec(spec), compileOptions(options), checksPrecisionErrors(checksPrecErrors), sourcePath(sourcePath), treeRoot(0),
-            numErrors(0), lexAfterType(false), loopNestingLevel(0),
-            inTypeParen(false), contextPragma(true, false), scanner(NULL) {  }
+            intermediate(interm),
+            symbolTable(symt),
+            extensionBehavior(ext),
+            infoSink(is),
+            shaderType(type),
+            shaderSpec(spec),
+            compileOptions(options),
+            sourcePath(sourcePath),
+            treeRoot(0),
+            numErrors(0),
+            lexAfterType(false),
+            loopNestingLevel(0),
+            structNestingLevel(0),
+            inTypeParen(false),
+            currentFunctionType(NULL),
+            functionReturnsValue(false),
+            checksPrecisionErrors(checksPrecErrors),
+            contextPragma(true, false),
+            scanner(NULL) {  }
     TIntermediate& intermediate; // to hold and build a parse tree
     TSymbolTable& symbolTable;   // symbol table that goes with the language currently being parsed
     TExtensionBehavior& extensionBehavior;  // mapping between supported extensions and current behavior.
     TInfoSink& infoSink;
     ShShaderType shaderType;              // vertex or fragment language (future: pack or unpack)
     ShShaderSpec shaderSpec;              // The language specification compiler conforms to - GLES2 or WebGL.
     int compileOptions;
     const char* sourcePath;      // Path of source file or NULL.
     TIntermNode* treeRoot;       // root of parse tree being created
     int numErrors;
     bool lexAfterType;           // true if we've recognized a type, so can only be looking for an identifier
     int loopNestingLevel;        // 0 if outside all loops
+    int structNestingLevel;      // incremented while parsing a struct declaration
     bool inTypeParen;            // true if in parentheses, looking only for an identifier
     const TType* currentFunctionType;  // the return type of the function that's currently being parsed
     bool functionReturnsValue;   // true if a non-void function has a return
     bool checksPrecisionErrors;  // true if an error will be generated when a variable is declared without precision, explicit or implicit.
     struct TPragma contextPragma;
     TString HashErrMsg;
     bool AfterEOF;
     void* scanner;
@@ -100,16 +117,24 @@ struct TParseContext {
     TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, TSourceLoc);
     TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type);
     TIntermTyped* constructStruct(TIntermNode*, TType*, int, TSourceLoc, bool subset);
     TIntermTyped* constructBuiltIn(const TType*, TOperator, TIntermNode*, TSourceLoc, bool subset);
     TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc);
     TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc);
     TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line);
     TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc);
+
+    // Performs an error check for embedded struct declarations.
+    // Returns true if an error was raised due to the declaration of
+    // this struct.
+    bool enterStructDeclaration(TSourceLoc line, const TString& identifier);
+    void exitStructDeclaration();
+
+    bool structNestingErrorCheck(TSourceLoc line, const TType& fieldType);
 };
 
 int PaParseStrings(int count, const char* const string[], const int length[],
                    TParseContext* context);
 
 typedef TParseContext* TParseContextPointer;
 extern TParseContextPointer& GetGlobalParseContext();
 #define GlobalParseContext GetGlobalParseContext()
--- a/gfx/angle/src/compiler/ShaderLang.cpp
+++ b/gfx/angle/src/compiler/ShaderLang.cpp
@@ -1,39 +1,45 @@
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2011 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.
 //
 
 //
 // Implement the top-level of interface to the compiler,
 // as defined in ShaderLang.h
 //
 
 #include "GLSLANG/ShaderLang.h"
 
 #include "compiler/InitializeDll.h"
+#include "compiler/preprocessor/length_limits.h"
 #include "compiler/ShHandle.h"
 
 //
 // This is the platform independent interface between an OGL driver
 // and the shading language compiler.
 //
 
-static int getVariableMaxLength(const TVariableInfoList& varList)
+static bool checkActiveUniformAndAttribMaxLengths(const ShHandle handle,
+                                                  int expectedValue)
 {
-    TString::size_type maxLen = 0;
-    for (TVariableInfoList::const_iterator i = varList.begin();
-         i != varList.end(); ++i)
-    {
-        maxLen = std::max(maxLen, i->name.size());
-    }
-    // Add 1 to include null-termination character.
-    return static_cast<int>(maxLen) + 1;
+    int activeUniformLimit = 0;
+    ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
+    int activeAttribLimit = 0;
+    ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
+    return (expectedValue == activeUniformLimit && expectedValue == activeAttribLimit);
+}
+
+static bool checkMappedNameMaxLength(const ShHandle handle, int expectedValue)
+{
+    int mappedNameMaxLength = 0;
+    ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength);
+    return (expectedValue == mappedNameMaxLength);
 }
 
 static void getVariableInfo(ShShaderInfo varType,
                             const ShHandle handle,
                             int index,
                             int* length,
                             int* size,
                             ShDataType* type,
@@ -54,19 +60,30 @@ static void getVariableInfo(ShShaderInfo
         compiler->getAttribs() : compiler->getUniforms();
     if (index < 0 || index >= static_cast<int>(varList.size()))
         return;
 
     const TVariableInfo& varInfo = varList[index];
     if (length) *length = varInfo.name.size();
     *size = varInfo.size;
     *type = varInfo.type;
-    strcpy(name, varInfo.name.c_str());
-    if (mappedName)
-        strcpy(mappedName, varInfo.mappedName.c_str());
+
+    // This size must match that queried by
+    // SH_ACTIVE_UNIFORM_MAX_LENGTH and SH_ACTIVE_ATTRIBUTE_MAX_LENGTH
+    // in ShGetInfo, below.
+    int activeUniformAndAttribLength = 1 + MAX_SYMBOL_NAME_LEN;
+    ASSERT(checkActiveUniformAndAttribMaxLengths(handle, activeUniformAndAttribLength));
+    strncpy(name, varInfo.name.c_str(), activeUniformAndAttribLength);
+    if (mappedName) {
+        // This size must match that queried by
+        // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
+        int maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN;
+        ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
+        strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength);
+    }
 }
 
 //
 // Driver must call this first, once, before doing any other
 // compiler operations.
 //
 int ShInitialize()
 {
@@ -186,26 +203,28 @@ void ShGetInfo(const ShHandle handle, Sh
         break;
     case SH_OBJECT_CODE_LENGTH:
         *params = compiler->getInfoSink().obj.size() + 1;
         break;
     case SH_ACTIVE_UNIFORMS:
         *params = compiler->getUniforms().size();
         break;
     case SH_ACTIVE_UNIFORM_MAX_LENGTH:
-        *params = getVariableMaxLength(compiler->getUniforms());
+        *params = 1 +  MAX_SYMBOL_NAME_LEN;
         break;
     case SH_ACTIVE_ATTRIBUTES:
         *params = compiler->getAttribs().size();
         break;
     case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
-        *params = getVariableMaxLength(compiler->getAttribs());
+        *params = 1 + MAX_SYMBOL_NAME_LEN;
         break;
     case SH_MAPPED_NAME_MAX_LENGTH:
-        *params = compiler->getMappedNameMaxLength();
+        // Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to
+        // handle array and struct dereferences.
+        *params = 1 + MAX_SYMBOL_NAME_LEN;
         break;
     default: UNREACHABLE();
     }
 }
 
 //
 // Return any compiler log of messages for the application.
 //
--- a/gfx/angle/src/compiler/SymbolTable.cpp
+++ b/gfx/angle/src/compiler/SymbolTable.cpp
@@ -8,16 +8,18 @@
 // Symbol table for parsing.  Most functionaliy and main ideas
 // are documented in the header file.
 //
 
 #include "compiler/SymbolTable.h"
 
 #include <stdio.h>
 
+#include <algorithm>
+
 //
 // TType helper function needs a place to live.
 //
 
 //
 // Recursively generate mangled names.
 //
 void TType::buildMangledName(TString& mangledName)
@@ -66,16 +68,30 @@ int TType::getStructSize() const
 
     if (structureSize == 0)
         for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
             structureSize += ((*tl).type)->getObjectSize();
 
     return structureSize;
 }
 
+void TType::computeDeepestStructNesting()
+{
+    if (!getStruct()) {
+        return;
+    }
+
+    int maxNesting = 0;
+    for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); ++tl) {
+        maxNesting = std::max(maxNesting, ((*tl).type)->getDeepestStructNesting());
+    }
+
+    deepestStructNesting = 1 + maxNesting;
+}
+
 //
 // Dump functions.
 //
 
 void TVariable::dump(TInfoSink& infoSink) const
 {
     infoSink.debug << getName().c_str() << ": " << type.getQualifierString() << " " << type.getPrecisionString() << " " << type.getBasicString();
     if (type.isArray()) {
--- a/gfx/angle/src/compiler/Types.h
+++ b/gfx/angle/src/compiler/Types.h
@@ -80,31 +80,32 @@ typedef TMap<TTypeList*, TTypeList*>::it
 // 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), fieldName(0), mangled(0), typeName(0)
+            maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
     {
     }
     explicit TType(const TPublicType &p) :
             type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize),
-            maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), fieldName(0), mangled(0), typeName(0)
+            maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
     {
         if (p.userDef) {
             structure = p.userDef->getStruct();
             typeName = NewPoolTString(p.userDef->getTypeName().c_str());
+            computeDeepestStructNesting();
         }
     }
     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), fieldName(0), mangled(0)
+            maxArraySize(0), arrayInformationType(0), structure(userDef), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0)
     {
         typeName = NewPoolTString(n.c_str());
     }
 
     void copyType(const TType& copyOf, TStructureMap& remapper)
     {
         type = copyOf.type;
         precision = copyOf.precision;
@@ -139,16 +140,17 @@ public:
             typeName = NewPoolTString(copyOf.typeName->c_str());
 
         mangled = 0;
         if (copyOf.mangled)
             mangled = NewPoolTString(copyOf.mangled->c_str());
 
         structureSize = copyOf.structureSize;
         maxArraySize = copyOf.maxArraySize;
+        deepestStructNesting = copyOf.deepestStructNesting;
         assert(copyOf.arrayInformationType == 0);
         arrayInformationType = 0; // arrayInformationType should not be set for builtIn symbol table level
     }
 
     TType* clone(TStructureMap& remapper)
     {
         TType *newType = new TType();
         newType->copyType(*this, remapper);
@@ -197,17 +199,17 @@ public:
     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; }
 
     TTypeList* getStruct() const { return structure; }
-    void setStruct(TTypeList* s) { structure = s; }
+    void setStruct(TTypeList* s) { structure = s; computeDeepestStructNesting(); }
 
     const TString& getTypeName() const
     {
         assert(typeName);
         return *typeName;
     }
     void setTypeName(const TString& n)
     {
@@ -263,31 +265,47 @@ public:
         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; }
+
 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
 };
 
 #endif // _TYPES_INCLUDED_
--- a/gfx/angle/src/compiler/glslang.y
+++ b/gfx/angle/src/compiler/glslang.y
@@ -1637,33 +1637,35 @@ type_specifier_nonarray
         TType& structure = static_cast<TVariable*>($1.symbol)->getType();
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtStruct, qual, $1.line);
         $$.userDef = &structure;
     }
     ;
 
 struct_specifier
-    : STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE {
+    : STRUCT IDENTIFIER LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
         if (context->reservedErrorCheck($2.line, *$2.string))
             context->recover();
 
-        TType* structure = new TType($4, *$2.string);
+        TType* structure = new TType($5, *$2.string);
         TVariable* userTypeDef = new TVariable($2.string, *structure, true);
         if (! context->symbolTable.insert(*userTypeDef)) {
             context->error($2.line, "redefinition", $2.string->c_str(), "struct");
             context->recover();
         }
         $$.setBasic(EbtStruct, EvqTemporary, $1.line);
         $$.userDef = structure;
+        context->exitStructDeclaration();
     }
-    | STRUCT LEFT_BRACE struct_declaration_list RIGHT_BRACE {
-        TType* structure = new TType($3, TString(""));
+    | STRUCT LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
+        TType* structure = new TType($4, TString(""));
         $$.setBasic(EbtStruct, EvqTemporary, $1.line);
         $$.userDef = structure;
+        context->exitStructDeclaration();
     }
     ;
 
 struct_declaration_list
     : struct_declaration {
         $$ = $1;
     }
     | struct_declaration_list struct_declaration {
@@ -1703,16 +1705,20 @@ struct_declaration
                     context->recover();
             }
             if ($1.array)
                 type->setArraySize($1.arraySize);
             if ($1.userDef) {
                 type->setStruct($1.userDef->getStruct());
                 type->setTypeName($1.userDef->getTypeName());
             }
+
+            if (context->structNestingErrorCheck($1.line, *type)) {
+                context->recover();
+            }
         }
     }
     ;
 
 struct_declarator_list
     : struct_declarator {
         $$ = NewPoolTTypeList();
         $$->push_back($1);
--- a/gfx/angle/src/compiler/glslang_tab.cpp
+++ b/gfx/angle/src/compiler/glslang_tab.cpp
@@ -322,17 +322,17 @@ typedef union YYSTYPE
             TQualifier qualifier;
             TFunction* function;
             TParameter param;
             TTypeLine typeLine;
             TTypeList* typeList;
         };
     } interm;
 }
-/* Line 187 of yacc.c.  */
+/* Line 193 of yacc.c.  */
 
 	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
 #endif
 
 
@@ -412,17 +412,17 @@ typedef short int yytype_int16;
 # else
 #  define YYSIZE_T unsigned int
 # endif
 #endif
 
 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
 
 #ifndef YY_
-# if YYENABLE_NLS
+# if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
 #   define YY_(msgid) dgettext ("bison-runtime", msgid)
 #  endif
 # endif
 # ifndef YY_
 #  define YY_(msgid) msgid
 # endif
@@ -577,26 +577,26 @@ union yyalloc
       }									\
     while (YYID (0))
 
 #endif
 
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  70
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   1381
+#define YYLAST   1327
 
 /* YYNTOKENS -- Number of terminals.  */
 #define YYNTOKENS  95
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  78
+#define YYNNTS  80
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  194
+#define YYNRULES  196
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  297
+#define YYNSTATES  299
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
 #define YYMAXUTOK   349
 
 #define YYTRANSLATE(YYX)						\
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
@@ -653,29 +653,29 @@ static const yytype_uint16 yyprhs[] =
      140,   142,   144,   146,   148,   152,   154,   158,   160,   164,
      166,   172,   174,   178,   180,   182,   184,   186,   188,   190,
      194,   196,   199,   202,   207,   210,   212,   214,   217,   221,
      225,   228,   234,   238,   241,   245,   248,   249,   251,   253,
      255,   257,   259,   263,   269,   276,   282,   284,   287,   292,
      298,   303,   306,   308,   311,   313,   315,   317,   320,   322,
      324,   327,   329,   331,   333,   335,   340,   342,   344,   346,
      348,   350,   352,   354,   356,   358,   360,   362,   364,   366,
-     368,   370,   372,   374,   376,   378,   380,   382,   388,   393,
-     395,   398,   402,   404,   408,   410,   415,   417,   419,   421,
-     423,   425,   427,   429,   431,   433,   436,   437,   438,   444,
-     446,   448,   451,   455,   457,   460,   462,   465,   471,   475,
-     477,   479,   484,   485,   492,   493,   502,   503,   511,   513,
-     515,   517,   518,   521,   525,   528,   531,   534,   538,   541,
-     543,   546,   548,   550,   551
+     368,   370,   372,   374,   376,   378,   380,   382,   383,   390,
+     391,   397,   399,   402,   406,   408,   412,   414,   419,   421,
+     423,   425,   427,   429,   431,   433,   435,   437,   440,   441,
+     442,   448,   450,   452,   455,   459,   461,   464,   466,   469,
+     475,   479,   481,   483,   488,   489,   496,   497,   506,   507,
+     515,   517,   519,   521,   522,   525,   529,   532,   535,   538,
+     542,   545,   547,   550,   552,   554,   555
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 static const yytype_int16 yyrhs[] =
 {
-     169,     0,    -1,    44,    -1,    96,    -1,    47,    -1,    46,
+     171,     0,    -1,    44,    -1,    96,    -1,    47,    -1,    46,
       -1,    48,    -1,    71,   123,    72,    -1,    97,    -1,    98,
       73,    99,    74,    -1,   100,    -1,    98,    77,    49,    -1,
       98,    52,    -1,    98,    53,    -1,   123,    -1,   101,    -1,
      102,    -1,    98,    77,   102,    -1,   104,    72,    -1,   103,
       72,    -1,   105,    39,    -1,   105,    -1,   105,   121,    -1,
      104,    78,   121,    -1,   106,    71,    -1,   141,    -1,    44,
       -1,    49,    -1,    98,    -1,    52,   107,    -1,    53,   107,
       -1,   108,   107,    -1,    85,    -1,    83,    -1,    82,    -1,
@@ -693,44 +693,44 @@ static const yytype_int16 yyrhs[] =
       81,    -1,     7,   139,   140,    81,    -1,   127,    72,    -1,
      129,    -1,   128,    -1,   129,   131,    -1,   128,    78,   131,
       -1,   136,    44,    71,    -1,   138,    44,    -1,   138,    44,
       73,   124,    74,    -1,   137,   132,   130,    -1,   132,   130,
       -1,   137,   132,   133,    -1,   132,   133,    -1,    -1,    33,
       -1,    34,    -1,    35,    -1,   138,    -1,   135,    -1,   134,
       78,    44,    -1,   134,    78,    44,    73,    74,    -1,   134,
       78,    44,    73,   124,    74,    -1,   134,    78,    44,    80,
-     147,    -1,   136,    -1,   136,    44,    -1,   136,    44,    73,
+     149,    -1,   136,    -1,   136,    44,    -1,   136,    44,    73,
       74,    -1,   136,    44,    73,   124,    74,    -1,   136,    44,
-      80,   147,    -1,     3,    44,    -1,   138,    -1,   137,   138,
+      80,   149,    -1,     3,    44,    -1,   138,    -1,   137,   138,
       -1,     9,    -1,     8,    -1,    37,    -1,     3,    37,    -1,
       36,    -1,   140,    -1,   139,   140,    -1,     4,    -1,     5,
       -1,     6,    -1,   141,    -1,   141,    73,   124,    74,    -1,
       39,    -1,    11,    -1,    12,    -1,    10,    -1,    27,    -1,
       28,    -1,    29,    -1,    21,    -1,    22,    -1,    23,    -1,
       24,    -1,    25,    -1,    26,    -1,    30,    -1,    31,    -1,
       32,    -1,    41,    -1,    42,    -1,    43,    -1,   142,    -1,
-      45,    -1,    38,    44,    75,   143,    76,    -1,    38,    75,
-     143,    76,    -1,   144,    -1,   143,   144,    -1,   138,   145,
-      81,    -1,   146,    -1,   145,    78,   146,    -1,    44,    -1,
-      44,    73,   124,    74,    -1,   121,    -1,   125,    -1,   151,
-      -1,   150,    -1,   148,    -1,   157,    -1,   158,    -1,   161,
-      -1,   168,    -1,    75,    76,    -1,    -1,    -1,    75,   152,
-     156,   153,    76,    -1,   155,    -1,   150,    -1,    75,    76,
-      -1,    75,   156,    76,    -1,   149,    -1,   156,   149,    -1,
-      81,    -1,   123,    81,    -1,    18,    71,   123,    72,   159,
-      -1,   149,    16,   149,    -1,   149,    -1,   123,    -1,   136,
-      44,    80,   147,    -1,    -1,    40,    71,   162,   160,    72,
-     154,    -1,    -1,    15,   163,   149,    40,    71,   123,    72,
-      81,    -1,    -1,    17,    71,   164,   165,   167,    72,   154,
-      -1,   157,    -1,   148,    -1,   160,    -1,    -1,   166,    81,
-      -1,   166,    81,   123,    -1,    14,    81,    -1,    13,    81,
-      -1,    20,    81,    -1,    20,   123,    81,    -1,    19,    81,
-      -1,   170,    -1,   169,   170,    -1,   171,    -1,   125,    -1,
-      -1,   126,   172,   155,    -1
+      45,    -1,    -1,    38,    44,    75,   143,   145,    76,    -1,
+      -1,    38,    75,   144,   145,    76,    -1,   146,    -1,   145,
+     146,    -1,   138,   147,    81,    -1,   148,    -1,   147,    78,
+     148,    -1,    44,    -1,    44,    73,   124,    74,    -1,   121,
+      -1,   125,    -1,   153,    -1,   152,    -1,   150,    -1,   159,
+      -1,   160,    -1,   163,    -1,   170,    -1,    75,    76,    -1,
+      -1,    -1,    75,   154,   158,   155,    76,    -1,   157,    -1,
+     152,    -1,    75,    76,    -1,    75,   158,    76,    -1,   151,
+      -1,   158,   151,    -1,    81,    -1,   123,    81,    -1,    18,
+      71,   123,    72,   161,    -1,   151,    16,   151,    -1,   151,
+      -1,   123,    -1,   136,    44,    80,   149,    -1,    -1,    40,
+      71,   164,   162,    72,   156,    -1,    -1,    15,   165,   151,
+      40,    71,   123,    72,    81,    -1,    -1,    17,    71,   166,
+     167,   169,    72,   156,    -1,   159,    -1,   150,    -1,   162,
+      -1,    -1,   168,    81,    -1,   168,    81,   123,    -1,    14,
+      81,    -1,    13,    81,    -1,    20,    81,    -1,    20,   123,
+      81,    -1,    19,    81,    -1,   172,    -1,   171,   172,    -1,
+     173,    -1,   125,    -1,    -1,   126,   174,   157,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
        0,   153,   153,   188,   191,   204,   209,   214,   220,   223,
      296,   299,   408,   418,   431,   439,   538,   541,   549,   553,
      560,   564,   571,   577,   586,   594,   649,   656,   666,   669,
@@ -739,23 +739,23 @@ static const yytype_uint16 yyrline[] =
      831,   835,   839,   843,   844,   857,   858,   871,   872,   885,
      886,   903,   904,   917,   918,   919,   920,   921,   925,   928,
      939,   947,   972,   977,   984,  1020,  1023,  1030,  1038,  1059,
     1078,  1089,  1118,  1123,  1133,  1138,  1148,  1151,  1154,  1157,
     1163,  1170,  1173,  1189,  1207,  1231,  1254,  1258,  1276,  1284,
     1316,  1336,  1412,  1421,  1444,  1447,  1453,  1461,  1469,  1477,
     1487,  1494,  1497,  1500,  1506,  1509,  1524,  1528,  1532,  1536,
     1545,  1550,  1555,  1560,  1565,  1570,  1575,  1580,  1585,  1590,
-    1596,  1602,  1608,  1613,  1618,  1627,  1632,  1645,  1658,  1666,
-    1669,  1684,  1716,  1720,  1726,  1734,  1750,  1754,  1758,  1759,
-    1765,  1766,  1767,  1768,  1769,  1773,  1774,  1774,  1774,  1784,
-    1785,  1790,  1793,  1803,  1806,  1812,  1813,  1817,  1825,  1829,
-    1839,  1844,  1861,  1861,  1866,  1866,  1873,  1873,  1881,  1884,
-    1890,  1893,  1899,  1903,  1910,  1917,  1924,  1931,  1942,  1951,
-    1955,  1962,  1965,  1971,  1971
+    1596,  1602,  1608,  1613,  1618,  1627,  1632,  1645,  1645,  1659,
+    1659,  1668,  1671,  1686,  1722,  1726,  1732,  1740,  1756,  1760,
+    1764,  1765,  1771,  1772,  1773,  1774,  1775,  1779,  1780,  1780,
+    1780,  1790,  1791,  1796,  1799,  1809,  1812,  1818,  1819,  1823,
+    1831,  1835,  1845,  1850,  1867,  1867,  1872,  1872,  1879,  1879,
+    1887,  1890,  1896,  1899,  1905,  1909,  1916,  1923,  1930,  1937,
+    1948,  1957,  1961,  1968,  1971,  1977,  1977
 };
 #endif
 
 #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
 {
@@ -789,26 +789,26 @@ static const char *const yytname[] =
   "assignment_expression", "assignment_operator", "expression",
   "constant_expression", "declaration", "function_prototype",
   "function_declarator", "function_header_with_parameters",
   "function_header", "parameter_declarator", "parameter_declaration",
   "parameter_qualifier", "parameter_type_specifier",
   "init_declarator_list", "single_declaration", "fully_specified_type",
   "type_qualifier", "type_specifier", "precision_qualifier",
   "type_specifier_no_prec", "type_specifier_nonarray", "struct_specifier",
-  "struct_declaration_list", "struct_declaration",
+  "@1", "@2", "struct_declaration_list", "struct_declaration",
   "struct_declarator_list", "struct_declarator", "initializer",
   "declaration_statement", "statement", "simple_statement",
-  "compound_statement", "@1", "@2", "statement_no_new_scope",
+  "compound_statement", "@3", "@4", "statement_no_new_scope",
   "compound_statement_no_new_scope", "statement_list",
   "expression_statement", "selection_statement",
-  "selection_rest_statement", "condition", "iteration_statement", "@3",
-  "@4", "@5", "for_init_statement", "conditionopt", "for_rest_statement",
+  "selection_rest_statement", "condition", "iteration_statement", "@5",
+  "@6", "@7", "for_init_statement", "conditionopt", "for_rest_statement",
   "jump_statement", "translation_unit", "external_declaration",
-  "function_definition", "@6", 0
+  "function_definition", "@8", 0
 };
 #endif
 
 # ifdef YYPRINT
 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
    token YYLEX-NUM.  */
 static const yytype_uint16 yytoknum[] =
 {
@@ -836,23 +836,23 @@ static const yytype_uint8 yyr1[] =
      114,   115,   116,   117,   117,   118,   118,   119,   119,   120,
      120,   121,   121,   122,   122,   122,   122,   122,   123,   123,
      124,   125,   125,   125,   126,   127,   127,   128,   128,   129,
      130,   130,   131,   131,   131,   131,   132,   132,   132,   132,
      133,   134,   134,   134,   134,   134,   135,   135,   135,   135,
      135,   135,   136,   136,   137,   137,   137,   137,   137,   138,
      138,   139,   139,   139,   140,   140,   141,   141,   141,   141,
      141,   141,   141,   141,   141,   141,   141,   141,   141,   141,
-     141,   141,   141,   141,   141,   141,   141,   142,   142,   143,
-     143,   144,   145,   145,   146,   146,   147,   148,   149,   149,
-     150,   150,   150,   150,   150,   151,   152,   153,   151,   154,
-     154,   155,   155,   156,   156,   157,   157,   158,   159,   159,
-     160,   160,   162,   161,   163,   161,   164,   161,   165,   165,
-     166,   166,   167,   167,   168,   168,   168,   168,   168,   169,
-     169,   170,   170,   172,   171
+     141,   141,   141,   141,   141,   141,   141,   143,   142,   144,
+     142,   145,   145,   146,   147,   147,   148,   148,   149,   150,
+     151,   151,   152,   152,   152,   152,   152,   153,   154,   155,
+     153,   156,   156,   157,   157,   158,   158,   159,   159,   160,
+     161,   161,   162,   162,   164,   163,   165,   163,   166,   163,
+     167,   167,   168,   168,   169,   169,   170,   170,   170,   170,
+     170,   171,   171,   172,   172,   174,   173
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 static const yytype_uint8 yyr2[] =
 {
        0,     2,     1,     1,     1,     1,     1,     3,     1,     4,
        1,     3,     2,     2,     1,     1,     1,     3,     2,     2,
        2,     1,     2,     3,     2,     1,     1,     1,     1,     2,
@@ -861,450 +861,438 @@ static const yytype_uint8 yyr2[] =
        1,     1,     1,     1,     3,     1,     3,     1,     3,     1,
        5,     1,     3,     1,     1,     1,     1,     1,     1,     3,
        1,     2,     2,     4,     2,     1,     1,     2,     3,     3,
        2,     5,     3,     2,     3,     2,     0,     1,     1,     1,
        1,     1,     3,     5,     6,     5,     1,     2,     4,     5,
        4,     2,     1,     2,     1,     1,     1,     2,     1,     1,
        2,     1,     1,     1,     1,     4,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     1,     1,     1,     5,     4,     1,
-       2,     3,     1,     3,     1,     4,     1,     1,     1,     1,
-       1,     1,     1,     1,     1,     2,     0,     0,     5,     1,
-       1,     2,     3,     1,     2,     1,     2,     5,     3,     1,
-       1,     4,     0,     6,     0,     8,     0,     7,     1,     1,
-       1,     0,     2,     3,     2,     2,     2,     3,     2,     1,
-       2,     1,     1,     0,     3
+       1,     1,     1,     1,     1,     1,     1,     0,     6,     0,
+       5,     1,     2,     3,     1,     3,     1,     4,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     2,     0,     0,
+       5,     1,     1,     2,     3,     1,     2,     1,     2,     5,
+       3,     1,     1,     4,     0,     6,     0,     8,     0,     7,
+       1,     1,     1,     0,     2,     3,     2,     2,     2,     3,
+       2,     1,     2,     1,     1,     0,     3
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
    STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
        0,     0,   111,   112,   113,     0,   105,   104,   119,   117,
      118,   123,   124,   125,   126,   127,   128,   120,   121,   122,
      129,   130,   131,   108,   106,     0,   116,   132,   133,   134,
-     136,   192,   193,     0,    76,    86,     0,    91,    96,     0,
-     102,     0,   109,   114,   135,     0,   189,   191,   107,   101,
-       0,     0,     0,    71,     0,    74,    86,     0,    87,    88,
+     136,   194,   195,     0,    76,    86,     0,    91,    96,     0,
+     102,     0,   109,   114,   135,     0,   191,   193,   107,   101,
+       0,     0,   139,    71,     0,    74,    86,     0,    87,    88,
       89,    77,     0,    86,     0,    72,    97,   103,   110,     0,
-       1,   190,     0,     0,     0,     0,   139,     0,   194,    78,
-      83,    85,    90,     0,    92,    79,     0,     0,     2,     5,
-       4,     6,    27,     0,     0,     0,    34,    33,    32,     3,
-       8,    28,    10,    15,    16,     0,     0,    21,     0,    35,
-       0,    38,    41,    42,    47,    50,    51,    52,    53,    55,
-      57,    59,    70,     0,    25,    73,     0,   144,     0,   142,
-     138,   140,     0,     0,   174,     0,     0,     0,     0,     0,
-     156,   161,   165,    35,    61,    68,     0,   147,     0,   114,
-     150,   163,   149,   148,     0,   151,   152,   153,   154,    80,
-      82,    84,     0,     0,    98,     0,   146,   100,    29,    30,
-       0,    12,    13,     0,     0,    19,    18,     0,    20,    22,
-      24,    31,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,   115,   137,     0,     0,
-     141,   185,   184,     0,   176,     0,   188,   186,     0,   172,
-     155,     0,    64,    65,    66,    67,    63,     0,     0,   166,
-     162,   164,     0,    93,     0,    95,    99,     7,     0,    14,
-      26,    11,    17,    23,    36,    37,    40,    39,    45,    46,
-      43,    44,    48,    49,    54,    56,    58,     0,     0,   143,
-       0,     0,     0,   187,     0,   157,    62,    69,     0,    94,
-       9,     0,   145,     0,   179,   178,   181,     0,   170,     0,
-       0,     0,    81,    60,     0,   180,     0,     0,   169,   167,
-       0,     0,   158,     0,   182,     0,     0,     0,   160,   173,
-     159,     0,   183,   177,   168,   171,   175
+       1,   192,     0,   137,     0,     0,   196,    78,    83,    85,
+      90,     0,    92,    79,     0,     0,     2,     5,     4,     6,
+      27,     0,     0,     0,    34,    33,    32,     3,     8,    28,
+      10,    15,    16,     0,     0,    21,     0,    35,     0,    38,
+      41,    42,    47,    50,    51,    52,    53,    55,    57,    59,
+      70,     0,    25,    73,     0,     0,     0,   141,     0,     0,
+     176,     0,     0,     0,     0,     0,   158,   163,   167,    35,
+      61,    68,     0,   149,     0,   114,   152,   165,   151,   150,
+       0,   153,   154,   155,   156,    80,    82,    84,     0,     0,
+      98,     0,   148,   100,    29,    30,     0,    12,    13,     0,
+       0,    19,    18,     0,    20,    22,    24,    31,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   115,     0,   146,     0,   144,   140,   142,   187,
+     186,     0,   178,     0,   190,   188,     0,   174,   157,     0,
+      64,    65,    66,    67,    63,     0,     0,   168,   164,   166,
+       0,    93,     0,    95,    99,     7,     0,    14,    26,    11,
+      17,    23,    36,    37,    40,    39,    45,    46,    43,    44,
+      48,    49,    54,    56,    58,     0,   138,     0,     0,   143,
+       0,     0,     0,   189,     0,   159,    62,    69,     0,    94,
+       9,     0,     0,   145,     0,   181,   180,   183,     0,   172,
+       0,     0,     0,    81,    60,   147,     0,   182,     0,     0,
+     171,   169,     0,     0,   160,     0,   184,     0,     0,     0,
+     162,   175,   161,     0,   185,   179,   170,   173,   177
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,    99,   100,   101,   228,   102,   103,   104,   105,   106,
-     107,   108,   143,   110,   111,   112,   113,   114,   115,   116,
-     117,   118,   119,   120,   121,   144,   145,   217,   146,   123,
-     147,   148,    33,    34,    35,    80,    61,    62,    81,    36,
-      37,    38,    39,    40,    41,    42,   124,    44,    75,    76,
-     128,   129,   167,   150,   151,   152,   153,   211,   271,   289,
-     290,   154,   155,   156,   279,   270,   157,   254,   203,   251,
-     266,   276,   277,   158,    45,    46,    47,    54
+      -1,    97,    98,    99,   226,   100,   101,   102,   103,   104,
+     105,   106,   139,   108,   109,   110,   111,   112,   113,   114,
+     115,   116,   117,   118,   119,   140,   141,   215,   142,   121,
+     143,   144,    33,    34,    35,    78,    61,    62,    79,    36,
+      37,    38,    39,    40,    41,    42,   122,    44,   124,    74,
+     126,   127,   195,   196,   163,   146,   147,   148,   149,   209,
+     272,   291,   292,   150,   151,   152,   281,   271,   153,   254,
+     201,   251,   267,   278,   279,   154,    45,    46,    47,    54
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -251
+#define YYPACT_NINF -242
 static const yytype_int16 yypact[] =
 {
-    1233,   -19,  -251,  -251,  -251,   130,  -251,  -251,  -251,  -251,
-    -251,  -251,  -251,  -251,  -251,  -251,  -251,  -251,  -251,  -251,
-    -251,  -251,  -251,  -251,  -251,   -24,  -251,  -251,  -251,  -251,
-    -251,  -251,   -62,    -6,    17,    34,   -20,  -251,    36,  1275,
-    -251,  1336,  -251,    32,  -251,  1190,  -251,  -251,  -251,  -251,
-    1336,    44,  1275,  -251,    47,  -251,    51,    78,  -251,  -251,
-    -251,  -251,  1275,   109,    81,  -251,   -50,  -251,  -251,   959,
-    -251,  -251,    56,  1275,   102,  1092,  -251,   284,  -251,  -251,
-    -251,  -251,   111,  1275,   -44,  -251,   764,   959,    87,  -251,
-    -251,  -251,  -251,   959,   959,   959,  -251,  -251,  -251,  -251,
-    -251,    37,  -251,  -251,  -251,    89,    22,  1024,    88,  -251,
-     959,   -54,    -9,  -251,   -43,    92,  -251,  -251,  -251,   105,
-     104,   -45,  -251,    91,  -251,  -251,  1134,    93,    15,  -251,
-    -251,  -251,    86,    90,  -251,    97,    98,    94,   829,    99,
-     101,  -251,  -251,     2,  -251,  -251,    31,  -251,   -62,    74,
-    -251,  -251,  -251,  -251,   367,  -251,  -251,  -251,  -251,   100,
-    -251,  -251,   894,   959,  -251,   107,  -251,  -251,  -251,  -251,
-      25,  -251,  -251,   959,  1300,  -251,  -251,   959,   103,  -251,
-    -251,  -251,   959,   959,   959,   959,   959,   959,   959,   959,
-     959,   959,   959,   959,   959,   959,  -251,  -251,   959,   102,
-    -251,  -251,  -251,   450,  -251,   959,  -251,  -251,    40,  -251,
-    -251,   450,  -251,  -251,  -251,  -251,  -251,   959,   959,  -251,
-    -251,  -251,   959,  -251,   108,  -251,  -251,  -251,   110,   113,
-    -251,   112,  -251,  -251,  -251,  -251,   -54,   -54,  -251,  -251,
-    -251,  -251,   -43,   -43,  -251,   105,   104,    72,   114,  -251,
-     138,   616,    26,  -251,   699,   450,  -251,  -251,   115,  -251,
-    -251,   959,  -251,   116,  -251,  -251,   699,   450,   113,   135,
-     121,   118,  -251,  -251,   959,  -251,   117,   123,   169,  -251,
-     106,   533,  -251,    35,   959,   533,   450,   959,  -251,  -251,
-    -251,   119,   113,  -251,  -251,  -251,  -251
+    1179,    -6,  -242,  -242,  -242,   151,  -242,  -242,  -242,  -242,
+    -242,  -242,  -242,  -242,  -242,  -242,  -242,  -242,  -242,  -242,
+    -242,  -242,  -242,  -242,  -242,   -39,  -242,  -242,  -242,  -242,
+    -242,  -242,   -69,   -37,   -32,    21,   -61,  -242,    26,  1221,
+    -242,  1282,  -242,   -58,  -242,   207,  -242,  -242,  -242,  -242,
+    1282,    22,  -242,  -242,    33,  -242,    70,    88,  -242,  -242,
+    -242,  -242,  1221,   125,    42,  -242,    -8,  -242,  -242,   961,
+    -242,  -242,    72,  -242,  1221,   286,  -242,  -242,  -242,  -242,
+     117,  1221,   -57,  -242,   766,   961,    94,  -242,  -242,  -242,
+    -242,   961,   961,   961,  -242,  -242,  -242,  -242,  -242,    14,
+    -242,  -242,  -242,    99,   -35,  1026,   101,  -242,   961,   -27,
+      46,  -242,   -21,    56,  -242,  -242,  -242,   115,   119,   -45,
+    -242,   103,  -242,  -242,  1221,   136,  1094,  -242,   102,   104,
+    -242,   111,   116,   105,   831,   118,   112,  -242,  -242,    39,
+    -242,  -242,    17,  -242,   -69,    93,  -242,  -242,  -242,  -242,
+     369,  -242,  -242,  -242,  -242,   122,  -242,  -242,   896,   961,
+    -242,   123,  -242,  -242,  -242,  -242,    10,  -242,  -242,   961,
+    1246,  -242,  -242,   961,   120,  -242,  -242,  -242,   961,   961,
+     961,   961,   961,   961,   961,   961,   961,   961,   961,   961,
+     961,   961,  -242,  1136,   126,    49,  -242,  -242,  -242,  -242,
+    -242,   452,  -242,   961,  -242,  -242,    71,  -242,  -242,   452,
+    -242,  -242,  -242,  -242,  -242,   961,   961,  -242,  -242,  -242,
+     961,  -242,   124,  -242,  -242,  -242,   128,   114,  -242,   129,
+    -242,  -242,  -242,  -242,   -27,   -27,  -242,  -242,  -242,  -242,
+     -21,   -21,  -242,   115,   119,    89,  -242,   961,   136,  -242,
+     150,   618,    11,  -242,   701,   452,  -242,  -242,   130,  -242,
+    -242,   961,   131,  -242,   137,  -242,  -242,   701,   452,   114,
+     152,   148,   145,  -242,  -242,  -242,   961,  -242,   141,   153,
+     208,  -242,   143,   535,  -242,    38,   961,   535,   452,   961,
+    -242,  -242,  -242,   146,   114,  -242,  -242,  -242,  -242
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -251,  -251,  -251,  -251,  -251,  -251,  -251,    23,  -251,  -251,
-    -251,  -251,    30,  -251,   -32,  -251,   -58,   -34,  -251,  -251,
-    -251,     4,     6,     7,  -251,   -60,   -85,  -251,   -94,   -81,
-       8,    10,  -251,  -251,  -251,   122,   148,   143,   124,  -251,
-    -251,  -238,   -22,   -35,   203,   -26,     0,  -251,   136,   -69,
-    -251,    11,  -160,   -25,  -147,  -250,  -251,  -251,  -251,   -56,
-     171,    16,   -21,  -251,  -251,   -33,  -251,  -251,  -251,  -251,
-    -251,  -251,  -251,  -251,  -251,   186,  -251,  -251
+    -242,  -242,  -242,  -242,  -242,  -242,  -242,    77,  -242,  -242,
+    -242,  -242,   -44,  -242,   -63,  -242,   -62,   -17,  -242,  -242,
+    -242,    52,    37,    51,  -242,   -66,   -83,  -242,   -92,   -73,
+       7,     8,  -242,  -242,  -242,   161,   197,   193,   176,  -242,
+    -242,  -241,   -29,   -30,   253,   -22,     0,  -242,  -242,  -242,
+     135,  -122,  -242,    12,  -138,    13,  -140,  -203,  -242,  -242,
+    -242,   -26,   209,    53,    15,  -242,  -242,    -2,  -242,  -242,
+    -242,  -242,  -242,  -242,  -242,  -242,  -242,   224,  -242,  -242
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
    number is the opposite.  If zero, do what YYDEFACT says.
    If YYTABLE_NINF, syntax error.  */
 #define YYTABLE_NINF -117
 static const yytype_int16 yytable[] =
 {
-      43,   170,   166,   225,    67,   165,   131,   221,    31,   122,
-      32,   186,   187,    63,   194,    68,   269,    74,    48,    53,
-      51,    85,   179,    86,    72,    49,   122,    82,   269,   162,
-      87,   288,   182,   183,    63,   288,   163,    57,    74,    43,
-      74,    43,     6,     7,   208,    43,   188,   189,    82,   195,
-      43,    52,    43,    31,    57,    32,   250,   131,    64,     6,
-       7,    65,    43,   212,   213,   214,    55,    58,    59,    60,
-      23,    24,   215,    43,   184,    43,   185,   149,   166,   229,
-      66,   224,   216,    43,    58,    59,    60,    23,    24,   171,
-     172,    74,   233,   199,   176,    56,   200,   227,   267,   109,
-     177,   247,   122,   218,   218,    69,   -75,   291,   221,   218,
-     173,   252,   219,   218,   174,    48,   109,   248,   218,    73,
-     278,   253,    77,   168,   169,    84,    43,   295,   238,   239,
-     240,   241,   256,   257,     2,     3,     4,   125,   122,   294,
-     181,   258,    58,    59,    60,   -25,   127,    69,   190,   191,
-     218,   261,   236,   237,   149,   159,   242,   243,   -26,   180,
-     268,   175,   122,   192,   193,   196,   198,   201,   204,   205,
-     209,   202,   268,   222,  -116,   206,   273,   210,   263,   280,
-     283,   226,   259,   -27,   260,   286,   287,   274,   262,   272,
-     292,   218,   109,   281,   282,   285,   244,   232,   284,   245,
-     296,   246,   166,   149,    79,   160,    83,   161,    50,   126,
-     249,   149,   234,   235,   109,   109,   109,   109,   109,   109,
-     109,   109,   109,   109,   109,    78,   264,   255,   109,   293,
-     265,    71,     0,   275,     0,     0,     0,     0,     0,     0,
+      43,   166,   162,   120,   198,    51,    63,    31,    32,    67,
+     219,   161,    53,   270,   190,    69,   158,    64,   120,    68,
+      65,   223,   175,   159,    57,   107,   270,    63,    72,     6,
+       7,    48,    80,   182,   183,    55,    52,   172,    49,    43,
+     107,    43,   206,   173,   125,    43,    56,   164,   165,   191,
+      43,    80,    31,    32,    58,    59,    60,    23,    24,   178,
+     179,   250,    43,    83,   177,    84,   167,   168,   184,   185,
+      66,   198,    85,    57,    43,   145,   162,   227,     6,     7,
+     290,    43,   225,   268,   290,   222,    82,   169,   216,   216,
+     231,   170,   120,   -75,   125,   216,   125,    73,   217,   245,
+     210,   211,   212,    58,    59,    60,    23,    24,    75,   213,
+     293,   252,   186,   187,   107,   219,   216,   234,   235,   214,
+     236,   237,   238,   239,    43,    48,    43,   248,   280,   180,
+     249,   181,   256,   257,   232,   233,   107,   107,   107,   107,
+     107,   107,   107,   107,   107,   107,   107,   258,   296,   216,
+     145,   297,   253,   123,   120,     2,     3,     4,    58,    59,
+      60,   155,   269,   125,   -25,   -26,    69,   216,   261,   240,
+     241,   171,   176,   188,   262,   269,   107,   192,   274,   189,
+     194,   120,   202,   199,   285,   200,   204,   203,   208,   207,
+     264,  -116,   216,    43,   294,   220,   282,   224,   259,   247,
+     -27,   145,   260,   107,   273,   275,   162,    70,   276,   145,
+       1,     2,     3,     4,     5,     6,     7,     8,     9,    10,
+     283,   284,   286,   289,   288,   287,   243,   298,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+     242,   244,   156,    23,    24,    25,    26,   230,    27,    28,
+      29,   145,    30,    77,   145,   145,    81,   157,    50,   193,
+     263,   295,   255,    76,   265,   277,   266,   145,   145,    71,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,   145,     0,     0,     0,   145,   145,     1,
+       2,     3,     4,     5,     6,     7,     8,     9,    10,   128,
+     129,   130,     0,   131,   132,   133,   134,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
+       0,     0,    23,    24,    25,    26,   135,    27,    28,    29,
+      86,    30,    87,    88,    89,    90,     0,     0,    91,    92,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    93,     0,     0,
+       0,   136,   137,     0,     0,     0,     0,   138,    94,    95,
+       0,    96,     1,     2,     3,     4,     5,     6,     7,     8,
+       9,    10,   128,   129,   130,     0,   131,   132,   133,   134,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,     0,     0,     0,    23,    24,    25,    26,   135,
+      27,    28,    29,    86,    30,    87,    88,    89,    90,     0,
+       0,    91,    92,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      93,     0,     0,     0,   136,   218,     0,     0,     0,     0,
+     138,    94,    95,     0,    96,     1,     2,     3,     4,     5,
+       6,     7,     8,     9,    10,   128,   129,   130,     0,   131,
+     132,   133,   134,    11,    12,    13,    14,    15,    16,    17,
+      18,    19,    20,    21,    22,     0,     0,     0,    23,    24,
+      25,    26,   135,    27,    28,    29,    86,    30,    87,    88,
+      89,    90,     0,     0,    91,    92,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,   149,   109,     0,   149,   149,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,   149,   149,     0,     0,
+       0,     0,     0,    93,     0,     0,     0,   136,     0,     0,
+       0,     0,     0,   138,    94,    95,     0,    96,     1,     2,
+       3,     4,     5,     6,     7,     8,     9,    10,   128,   129,
+     130,     0,   131,   132,   133,   134,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,     0,     0,
+       0,    23,    24,    25,    26,   135,    27,    28,    29,    86,
+      30,    87,    88,    89,    90,     0,     0,    91,    92,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    93,     0,     0,     0,
+      75,     0,     0,     0,     0,     0,   138,    94,    95,     0,
+      96,     1,     2,     3,     4,     5,     6,     7,     8,     9,
+      10,     0,     0,     0,     0,     0,     0,     0,     0,    11,
+      12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+      22,     0,     0,     0,    23,    24,    25,    26,     0,    27,
+      28,    29,    86,    30,    87,    88,    89,    90,     0,     0,
+      91,    92,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    93,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,   138,
+      94,    95,     0,    96,    57,     2,     3,     4,     0,     6,
+       7,     8,     9,    10,     0,     0,     0,     0,     0,     0,
+       0,     0,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,     0,     0,     0,    23,    24,    25,
+      26,     0,    27,    28,    29,    86,    30,    87,    88,    89,
+      90,     0,     0,    91,    92,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,   149,     0,     0,     0,   149,   149,     1,     2,     3,
-       4,     5,     6,     7,     8,     9,    10,   132,   133,   134,
-       0,   135,   136,   137,   138,    11,    12,    13,    14,    15,
+       0,     0,    93,     0,     0,     0,     8,     9,    10,     0,
+       0,     0,     0,    94,    95,     0,    96,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
+       0,     0,     0,     0,    25,    26,     0,    27,    28,    29,
+      86,    30,    87,    88,    89,    90,     0,     0,    91,    92,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    93,     0,     0,
+     160,     8,     9,    10,     0,     0,     0,     0,    94,    95,
+       0,    96,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,     0,     0,     0,     0,     0,    25,
+      26,     0,    27,    28,    29,    86,    30,    87,    88,    89,
+      90,     0,     0,    91,    92,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    93,     0,     0,     0,     8,     9,    10,     0,
+       0,     0,   205,    94,    95,     0,    96,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
+       0,     0,     0,     0,    25,    26,     0,    27,    28,    29,
+      86,    30,    87,    88,    89,    90,     0,     0,    91,    92,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    93,     0,     0,
+     221,     8,     9,    10,     0,     0,     0,     0,    94,    95,
+       0,    96,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,     0,     0,     0,     0,     0,    25,
+      26,     0,    27,    28,    29,    86,    30,    87,    88,    89,
+      90,     0,     0,    91,    92,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    93,     0,     0,     0,     8,     9,    10,     0,
+       0,     0,     0,    94,    95,     0,    96,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
+       0,     0,     0,     0,    25,   174,     0,    27,    28,    29,
+      86,    30,    87,    88,    89,    90,     0,     0,    91,    92,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    93,     2,     3,
+       4,     0,     0,     0,     8,     9,    10,     0,    94,    95,
+       0,    96,     0,     0,     0,    11,    12,    13,    14,    15,
       16,    17,    18,    19,    20,    21,    22,     0,     0,     0,
-      23,    24,    25,    26,   139,    27,    28,    29,    88,    30,
-      89,    90,    91,    92,     0,     0,    93,    94,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    95,     0,     0,     0,   140,
-     141,     0,     0,     0,     0,   142,    96,    97,     0,    98,
-       1,     2,     3,     4,     5,     6,     7,     8,     9,    10,
-     132,   133,   134,     0,   135,   136,   137,   138,    11,    12,
-      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-       0,     0,     0,    23,    24,    25,    26,   139,    27,    28,
-      29,    88,    30,    89,    90,    91,    92,     0,     0,    93,
-      94,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    95,     0,
-       0,     0,   140,   220,     0,     0,     0,     0,   142,    96,
-      97,     0,    98,     1,     2,     3,     4,     5,     6,     7,
-       8,     9,    10,   132,   133,   134,     0,   135,   136,   137,
-     138,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,     0,     0,     0,    23,    24,    25,    26,
-     139,    27,    28,    29,    88,    30,    89,    90,    91,    92,
-       0,     0,    93,    94,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    95,     0,     0,     0,   140,     0,     0,     0,     0,
-       0,   142,    96,    97,     0,    98,     1,     2,     3,     4,
-       5,     6,     7,     8,     9,    10,   132,   133,   134,     0,
-     135,   136,   137,   138,    11,    12,    13,    14,    15,    16,
-      17,    18,    19,    20,    21,    22,     0,     0,     0,    23,
-      24,    25,    26,   139,    27,    28,    29,    88,    30,    89,
-      90,    91,    92,     0,     0,    93,    94,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    95,     0,     0,     0,    77,     0,
-       0,     0,     0,     0,   142,    96,    97,     0,    98,     1,
-       2,     3,     4,     5,     6,     7,     8,     9,    10,     0,
+       0,     0,    25,    26,     0,    27,    28,    29,     0,    30,
+       2,     3,     4,     0,     0,     0,     8,     9,    10,     0,
        0,     0,     0,     0,     0,     0,     0,    11,    12,    13,
       14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
-       0,     0,    23,    24,    25,    26,     0,    27,    28,    29,
-      88,    30,    89,    90,    91,    92,     0,     0,    93,    94,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,    95,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,   142,    96,    97,
-       0,    98,    57,     2,     3,     4,     0,     6,     7,     8,
+     197,     0,     0,     0,    25,    26,     0,    27,    28,    29,
+       0,    30,     1,     2,     3,     4,     5,     6,     7,     8,
        9,    10,     0,     0,     0,     0,     0,     0,     0,     0,
       11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
-      21,    22,     0,     0,     0,    23,    24,    25,    26,     0,
-      27,    28,    29,    88,    30,    89,    90,    91,    92,     0,
-       0,    93,    94,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-      95,     0,     0,     0,     8,     9,    10,     0,     0,     0,
-       0,    96,    97,     0,    98,    11,    12,    13,    14,    15,
-      16,    17,    18,    19,    20,    21,    22,     0,     0,     0,
-       0,     0,    25,    26,     0,    27,    28,    29,    88,    30,
-      89,    90,    91,    92,     0,     0,    93,    94,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    95,     0,     0,   164,     8,
-       9,    10,     0,     0,     0,     0,    96,    97,     0,    98,
-      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
-      21,    22,     0,     0,     0,     0,     0,    25,    26,     0,
-      27,    28,    29,    88,    30,    89,    90,    91,    92,     0,
-       0,    93,    94,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-      95,     0,     0,     0,     8,     9,    10,     0,     0,     0,
-     207,    96,    97,     0,    98,    11,    12,    13,    14,    15,
-      16,    17,    18,    19,    20,    21,    22,     0,     0,     0,
-       0,     0,    25,    26,     0,    27,    28,    29,    88,    30,
-      89,    90,    91,    92,     0,     0,    93,    94,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    95,     0,     0,   223,     8,
-       9,    10,     0,     0,     0,     0,    96,    97,     0,    98,
-      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
-      21,    22,     0,     0,     0,     0,     0,    25,    26,     0,
-      27,    28,    29,    88,    30,    89,    90,    91,    92,     0,
-       0,    93,    94,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-      95,     0,     0,     0,     8,     9,    10,     0,     0,     0,
-       0,    96,    97,     0,    98,    11,    12,    13,    14,    15,
-      16,    17,    18,    19,    20,    21,    22,     0,     0,     0,
-       0,     0,    25,   178,     0,    27,    28,    29,    88,    30,
-      89,    90,    91,    92,     0,     0,    93,    94,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    95,     2,     3,     4,     0,
-       0,     0,     8,     9,    10,     0,    96,    97,     0,    98,
+      21,    22,   246,     0,     0,    23,    24,    25,    26,     0,
+      27,    28,    29,     0,    30,     2,     3,     4,     0,     0,
+       0,     8,     9,    10,     0,     0,     0,     0,     0,     0,
+       0,     0,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,     0,     0,     8,     9,    10,    25,
+      26,     0,    27,    28,    29,     0,    30,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
+       0,     0,     0,     0,    25,    26,     0,    27,    28,    29,
+     228,    30,     8,     9,    10,   229,     0,     0,     0,     0,
        0,     0,     0,    11,    12,    13,    14,    15,    16,    17,
       18,    19,    20,    21,    22,     0,     0,     0,     0,     0,
-      25,    26,     0,    27,    28,    29,     0,    30,     2,     3,
-       4,     0,     0,     0,     8,     9,    10,     0,     0,     0,
-       0,     0,     0,     0,     0,    11,    12,    13,    14,    15,
-      16,    17,    18,    19,    20,    21,    22,     0,   130,     0,
-       0,     0,    25,    26,     0,    27,    28,    29,     0,    30,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-      70,     0,     0,     1,     2,     3,     4,     5,     6,     7,
-       8,     9,    10,     0,     0,     0,     0,     0,     0,     0,
-     197,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,     0,     0,     0,    23,    24,    25,    26,
-       0,    27,    28,    29,     0,    30,     1,     2,     3,     4,
-       5,     6,     7,     8,     9,    10,     0,     0,     0,     0,
-       0,     0,     0,     0,    11,    12,    13,    14,    15,    16,
-      17,    18,    19,    20,    21,    22,     0,     0,     0,    23,
-      24,    25,    26,     0,    27,    28,    29,     0,    30,     2,
-       3,     4,     0,     0,     0,     8,     9,    10,     0,     0,
-       0,     0,     0,     0,     0,     0,    11,    12,    13,    14,
-      15,    16,    17,    18,    19,    20,    21,    22,     0,     0,
-       8,     9,    10,    25,    26,     0,    27,    28,    29,     0,
-      30,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,     0,     0,     0,     0,     0,    25,    26,
-       0,    27,    28,    29,   230,    30,     8,     9,    10,   231,
-       0,     0,     0,     0,     0,     0,     0,    11,    12,    13,
-      14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
-       0,     0,     0,     0,    25,    26,     0,    27,    28,    29,
-       0,    30
+      25,    26,     0,    27,    28,    29,     0,    30
 };
 
 static const yytype_int16 yycheck[] =
 {
-       0,    95,    87,   163,    39,    86,    75,   154,     0,    69,
-       0,    54,    55,    35,    59,    41,   254,    52,    37,    81,
-      44,    71,   107,    73,    50,    44,    86,    62,   266,    73,
-      80,   281,    86,    87,    56,   285,    80,     3,    73,    39,
-      75,    41,     8,     9,   138,    45,    89,    90,    83,    94,
-      50,    75,    52,    45,     3,    45,   203,   126,    78,     8,
-       9,    81,    62,    61,    62,    63,    72,    33,    34,    35,
-      36,    37,    70,    73,    83,    75,    85,    77,   163,   173,
-      44,   162,    80,    83,    33,    34,    35,    36,    37,    52,
-      53,   126,   177,    78,    72,    78,    81,    72,    72,    69,
-      78,   195,   162,    78,    78,    73,    72,    72,   255,    78,
-      73,   205,    81,    78,    77,    37,    86,   198,    78,    75,
-     267,    81,    75,    93,    94,    44,   126,   287,   186,   187,
-     188,   189,   217,   218,     4,     5,     6,    81,   198,   286,
-     110,   222,    33,    34,    35,    71,    44,    73,    56,    57,
-      78,    79,   184,   185,   154,    44,   190,   191,    71,    71,
-     254,    72,   222,    58,    60,    74,    73,    81,    71,    71,
-      71,    81,   266,    73,    71,    81,   261,    76,    40,    44,
-     274,    74,    74,    71,    74,    16,    80,    71,    74,    74,
-     284,    78,   162,    72,    76,    72,   192,   174,    81,   193,
-      81,   194,   287,   203,    56,    83,    63,    83,     5,    73,
-     199,   211,   182,   183,   184,   185,   186,   187,   188,   189,
-     190,   191,   192,   193,   194,    54,   251,   211,   198,   285,
-     251,    45,    -1,   266,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,   251,   222,    -1,   254,   255,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,   266,   267,    -1,    -1,
+       0,    93,    85,    69,   126,    44,    35,     0,     0,    39,
+     150,    84,    81,   254,    59,    73,    73,    78,    84,    41,
+      81,   159,   105,    80,     3,    69,   267,    56,    50,     8,
+       9,    37,    62,    54,    55,    72,    75,    72,    44,    39,
+      84,    41,   134,    78,    74,    45,    78,    91,    92,    94,
+      50,    81,    45,    45,    33,    34,    35,    36,    37,    86,
+      87,   201,    62,    71,   108,    73,    52,    53,    89,    90,
+      44,   193,    80,     3,    74,    75,   159,   169,     8,     9,
+     283,    81,    72,    72,   287,   158,    44,    73,    78,    78,
+     173,    77,   158,    72,   124,    78,   126,    75,    81,   191,
+      61,    62,    63,    33,    34,    35,    36,    37,    75,    70,
+      72,   203,    56,    57,   158,   255,    78,   180,   181,    80,
+     182,   183,   184,   185,   124,    37,   126,    78,   268,    83,
+      81,    85,   215,   216,   178,   179,   180,   181,   182,   183,
+     184,   185,   186,   187,   188,   189,   190,   220,   288,    78,
+     150,   289,    81,    81,   220,     4,     5,     6,    33,    34,
+      35,    44,   254,   193,    71,    71,    73,    78,    79,   186,
+     187,    72,    71,    58,   247,   267,   220,    74,   261,    60,
+      44,   247,    71,    81,   276,    81,    81,    71,    76,    71,
+      40,    71,    78,   193,   286,    73,    44,    74,    74,    73,
+      71,   201,    74,   247,    74,    74,   289,     0,    71,   209,
+       3,     4,     5,     6,     7,     8,     9,    10,    11,    12,
+      72,    76,    81,    80,    16,    72,   189,    81,    21,    22,
+      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
+     188,   190,    81,    36,    37,    38,    39,   170,    41,    42,
+      43,   251,    45,    56,   254,   255,    63,    81,     5,   124,
+     248,   287,   209,    54,   251,   267,   251,   267,   268,    45,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,   281,    -1,    -1,    -1,   285,   286,     3,     4,     5,
-       6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
-      -1,    17,    18,    19,    20,    21,    22,    23,    24,    25,
-      26,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
-      36,    37,    38,    39,    40,    41,    42,    43,    44,    45,
-      46,    47,    48,    49,    -1,    -1,    52,    53,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    71,    -1,    -1,    -1,    75,
-      76,    -1,    -1,    -1,    -1,    81,    82,    83,    -1,    85,
-       3,     4,     5,     6,     7,     8,     9,    10,    11,    12,
-      13,    14,    15,    -1,    17,    18,    19,    20,    21,    22,
-      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
-      -1,    -1,    -1,    36,    37,    38,    39,    40,    41,    42,
-      43,    44,    45,    46,    47,    48,    49,    -1,    -1,    52,
-      53,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    71,    -1,
-      -1,    -1,    75,    76,    -1,    -1,    -1,    -1,    81,    82,
-      83,    -1,    85,     3,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    -1,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    -1,    -1,    -1,    36,    37,    38,    39,
-      40,    41,    42,    43,    44,    45,    46,    47,    48,    49,
-      -1,    -1,    52,    53,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    71,    -1,    -1,    -1,    75,    -1,    -1,    -1,    -1,
-      -1,    81,    82,    83,    -1,    85,     3,     4,     5,     6,
-       7,     8,     9,    10,    11,    12,    13,    14,    15,    -1,
-      17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
-      27,    28,    29,    30,    31,    32,    -1,    -1,    -1,    36,
-      37,    38,    39,    40,    41,    42,    43,    44,    45,    46,
-      47,    48,    49,    -1,    -1,    52,    53,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    71,    -1,    -1,    -1,    75,    -1,
-      -1,    -1,    -1,    -1,    81,    82,    83,    -1,    85,     3,
-       4,     5,     6,     7,     8,     9,    10,    11,    12,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    21,    22,    23,
+      -1,    -1,    -1,   283,    -1,    -1,    -1,   287,   288,     3,
+       4,     5,     6,     7,     8,     9,    10,    11,    12,    13,
+      14,    15,    -1,    17,    18,    19,    20,    21,    22,    23,
       24,    25,    26,    27,    28,    29,    30,    31,    32,    -1,
-      -1,    -1,    36,    37,    38,    39,    -1,    41,    42,    43,
+      -1,    -1,    36,    37,    38,    39,    40,    41,    42,    43,
       44,    45,    46,    47,    48,    49,    -1,    -1,    52,    53,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    71,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    81,    82,    83,
-      -1,    85,     3,     4,     5,     6,    -1,     8,     9,    10,
-      11,    12,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    75,    76,    -1,    -1,    -1,    -1,    81,    82,    83,
+      -1,    85,     3,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    -1,    17,    18,    19,    20,
       21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
-      31,    32,    -1,    -1,    -1,    36,    37,    38,    39,    -1,
-      41,    42,    43,    44,    45,    46,    47,    48,    49,    -1,
-      -1,    52,    53,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      71,    -1,    -1,    -1,    10,    11,    12,    -1,    -1,    -1,
-      -1,    82,    83,    -1,    85,    21,    22,    23,    24,    25,
-      26,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
-      -1,    -1,    38,    39,    -1,    41,    42,    43,    44,    45,
-      46,    47,    48,    49,    -1,    -1,    52,    53,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    71,    -1,    -1,    74,    10,
-      11,    12,    -1,    -1,    -1,    -1,    82,    83,    -1,    85,
-      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
-      31,    32,    -1,    -1,    -1,    -1,    -1,    38,    39,    -1,
-      41,    42,    43,    44,    45,    46,    47,    48,    49,    -1,
-      -1,    52,    53,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      71,    -1,    -1,    -1,    10,    11,    12,    -1,    -1,    -1,
-      81,    82,    83,    -1,    85,    21,    22,    23,    24,    25,
-      26,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
-      -1,    -1,    38,    39,    -1,    41,    42,    43,    44,    45,
-      46,    47,    48,    49,    -1,    -1,    52,    53,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    71,    -1,    -1,    74,    10,
-      11,    12,    -1,    -1,    -1,    -1,    82,    83,    -1,    85,
-      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
-      31,    32,    -1,    -1,    -1,    -1,    -1,    38,    39,    -1,
+      31,    32,    -1,    -1,    -1,    36,    37,    38,    39,    40,
       41,    42,    43,    44,    45,    46,    47,    48,    49,    -1,
       -1,    52,    53,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      71,    -1,    -1,    -1,    10,    11,    12,    -1,    -1,    -1,
-      -1,    82,    83,    -1,    85,    21,    22,    23,    24,    25,
+      71,    -1,    -1,    -1,    75,    76,    -1,    -1,    -1,    -1,
+      81,    82,    83,    -1,    85,     3,     4,     5,     6,     7,
+       8,     9,    10,    11,    12,    13,    14,    15,    -1,    17,
+      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
+      28,    29,    30,    31,    32,    -1,    -1,    -1,    36,    37,
+      38,    39,    40,    41,    42,    43,    44,    45,    46,    47,
+      48,    49,    -1,    -1,    52,    53,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    71,    -1,    -1,    -1,    75,    -1,    -1,
+      -1,    -1,    -1,    81,    82,    83,    -1,    85,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    -1,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    -1,    -1,
+      -1,    36,    37,    38,    39,    40,    41,    42,    43,    44,
+      45,    46,    47,    48,    49,    -1,    -1,    52,    53,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    71,    -1,    -1,    -1,
+      75,    -1,    -1,    -1,    -1,    -1,    81,    82,    83,    -1,
+      85,     3,     4,     5,     6,     7,     8,     9,    10,    11,
+      12,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    21,
+      22,    23,    24,    25,    26,    27,    28,    29,    30,    31,
+      32,    -1,    -1,    -1,    36,    37,    38,    39,    -1,    41,
+      42,    43,    44,    45,    46,    47,    48,    49,    -1,    -1,
+      52,    53,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    71,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    81,
+      82,    83,    -1,    85,     3,     4,     5,     6,    -1,     8,
+       9,    10,    11,    12,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    21,    22,    23,    24,    25,    26,    27,    28,
+      29,    30,    31,    32,    -1,    -1,    -1,    36,    37,    38,
+      39,    -1,    41,    42,    43,    44,    45,    46,    47,    48,
+      49,    -1,    -1,    52,    53,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    71,    -1,    -1,    -1,    10,    11,    12,    -1,
+      -1,    -1,    -1,    82,    83,    -1,    85,    21,    22,    23,
+      24,    25,    26,    27,    28,    29,    30,    31,    32,    -1,
+      -1,    -1,    -1,    -1,    38,    39,    -1,    41,    42,    43,
+      44,    45,    46,    47,    48,    49,    -1,    -1,    52,    53,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    71,    -1,    -1,
+      74,    10,    11,    12,    -1,    -1,    -1,    -1,    82,    83,
+      -1,    85,    21,    22,    23,    24,    25,    26,    27,    28,
+      29,    30,    31,    32,    -1,    -1,    -1,    -1,    -1,    38,
+      39,    -1,    41,    42,    43,    44,    45,    46,    47,    48,
+      49,    -1,    -1,    52,    53,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    71,    -1,    -1,    -1,    10,    11,    12,    -1,
+      -1,    -1,    81,    82,    83,    -1,    85,    21,    22,    23,
+      24,    25,    26,    27,    28,    29,    30,    31,    32,    -1,
+      -1,    -1,    -1,    -1,    38,    39,    -1,    41,    42,    43,
+      44,    45,    46,    47,    48,    49,    -1,    -1,    52,    53,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    71,    -1,    -1,
+      74,    10,    11,    12,    -1,    -1,    -1,    -1,    82,    83,
+      -1,    85,    21,    22,    23,    24,    25,    26,    27,    28,
+      29,    30,    31,    32,    -1,    -1,    -1,    -1,    -1,    38,
+      39,    -1,    41,    42,    43,    44,    45,    46,    47,    48,
+      49,    -1,    -1,    52,    53,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    71,    -1,    -1,    -1,    10,    11,    12,    -1,
+      -1,    -1,    -1,    82,    83,    -1,    85,    21,    22,    23,
+      24,    25,    26,    27,    28,    29,    30,    31,    32,    -1,
+      -1,    -1,    -1,    -1,    38,    39,    -1,    41,    42,    43,
+      44,    45,    46,    47,    48,    49,    -1,    -1,    52,    53,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    71,     4,     5,
+       6,    -1,    -1,    -1,    10,    11,    12,    -1,    82,    83,
+      -1,    85,    -1,    -1,    -1,    21,    22,    23,    24,    25,
       26,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
-      -1,    -1,    38,    39,    -1,    41,    42,    43,    44,    45,
-      46,    47,    48,    49,    -1,    -1,    52,    53,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    71,     4,     5,     6,    -1,
-      -1,    -1,    10,    11,    12,    -1,    82,    83,    -1,    85,
+      -1,    -1,    38,    39,    -1,    41,    42,    43,    -1,    45,
+       4,     5,     6,    -1,    -1,    -1,    10,    11,    12,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    21,    22,    23,
+      24,    25,    26,    27,    28,    29,    30,    31,    32,    -1,
+      76,    -1,    -1,    -1,    38,    39,    -1,    41,    42,    43,
+      -1,    45,     3,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
+      31,    32,    76,    -1,    -1,    36,    37,    38,    39,    -1,
+      41,    42,    43,    -1,    45,     4,     5,     6,    -1,    -1,
+      -1,    10,    11,    12,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    21,    22,    23,    24,    25,    26,    27,    28,
+      29,    30,    31,    32,    -1,    -1,    10,    11,    12,    38,
+      39,    -1,    41,    42,    43,    -1,    45,    21,    22,    23,
+      24,    25,    26,    27,    28,    29,    30,    31,    32,    -1,
+      -1,    -1,    -1,    -1,    38,    39,    -1,    41,    42,    43,
+      44,    45,    10,    11,    12,    49,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    21,    22,    23,    24,    25,    26,    27,
       28,    29,    30,    31,    32,    -1,    -1,    -1,    -1,    -1,
-      38,    39,    -1,    41,    42,    43,    -1,    45,     4,     5,
-       6,    -1,    -1,    -1,    10,    11,    12,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    21,    22,    23,    24,    25,
-      26,    27,    28,    29,    30,    31,    32,    -1,    76,    -1,
-      -1,    -1,    38,    39,    -1,    41,    42,    43,    -1,    45,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-       0,    -1,    -1,     3,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      76,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    -1,    -1,    -1,    36,    37,    38,    39,
-      -1,    41,    42,    43,    -1,    45,     3,     4,     5,     6,
-       7,     8,     9,    10,    11,    12,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    21,    22,    23,    24,    25,    26,
-      27,    28,    29,    30,    31,    32,    -1,    -1,    -1,    36,
-      37,    38,    39,    -1,    41,    42,    43,    -1,    45,     4,
-       5,     6,    -1,    -1,    -1,    10,    11,    12,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    21,    22,    23,    24,
-      25,    26,    27,    28,    29,    30,    31,    32,    -1,    -1,
-      10,    11,    12,    38,    39,    -1,    41,    42,    43,    -1,
-      45,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    -1,    -1,    -1,    -1,    -1,    38,    39,
-      -1,    41,    42,    43,    44,    45,    10,    11,    12,    49,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    21,    22,    23,
-      24,    25,    26,    27,    28,    29,    30,    31,    32,    -1,
-      -1,    -1,    -1,    -1,    38,    39,    -1,    41,    42,    43,
-      -1,    45
+      38,    39,    -1,    41,    42,    43,    -1,    45
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
        0,     3,     4,     5,     6,     7,     8,     9,    10,    11,
       12,    21,    22,    23,    24,    25,    26,    27,    28,    29,
       30,    31,    32,    36,    37,    38,    39,    41,    42,    43,
       45,   125,   126,   127,   128,   129,   134,   135,   136,   137,
-     138,   139,   140,   141,   142,   169,   170,   171,    37,    44,
-     139,    44,    75,    81,   172,    72,    78,     3,    33,    34,
+     138,   139,   140,   141,   142,   171,   172,   173,    37,    44,
+     139,    44,    75,    81,   174,    72,    78,     3,    33,    34,
       35,   131,   132,   137,    78,    81,    44,   138,   140,    73,
-       0,   170,   140,    75,   138,   143,   144,    75,   155,   131,
-     130,   133,   138,   132,    44,    71,    73,    80,    44,    46,
-      47,    48,    49,    52,    53,    71,    82,    83,    85,    96,
-      97,    98,   100,   101,   102,   103,   104,   105,   106,   107,
-     108,   109,   110,   111,   112,   113,   114,   115,   116,   117,
-     118,   119,   120,   124,   141,    81,   143,    44,   145,   146,
-      76,   144,    13,    14,    15,    17,    18,    19,    20,    40,
-      75,    76,    81,   107,   120,   121,   123,   125,   126,   141,
-     148,   149,   150,   151,   156,   157,   158,   161,   168,    44,
-     130,   133,    73,    80,    74,   124,   121,   147,   107,   107,
-     123,    52,    53,    73,    77,    72,    72,    78,    39,   121,
-      71,   107,    86,    87,    83,    85,    54,    55,    89,    90,
-      56,    57,    58,    60,    59,    94,    74,    76,    73,    78,
-      81,    81,    81,   163,    71,    71,    81,    81,   123,    71,
-      76,   152,    61,    62,    63,    70,    80,   122,    78,    81,
-      76,   149,    73,    74,   124,   147,    74,    72,    99,   123,
-      44,    49,   102,   121,   107,   107,   109,   109,   111,   111,
-     111,   111,   112,   112,   116,   117,   118,   123,   124,   146,
-     149,   164,   123,    81,   162,   156,   121,   121,   124,    74,
-      74,    79,    74,    40,   148,   157,   165,    72,   123,   136,
-     160,   153,    74,   121,    71,   160,   166,   167,   149,   159,
-      44,    72,    76,   123,    81,    72,    16,    80,   150,   154,
-     155,    72,   123,   154,   149,   147,    81
+       0,   172,   140,    75,   144,    75,   157,   131,   130,   133,
+     138,   132,    44,    71,    73,    80,    44,    46,    47,    48,
+      49,    52,    53,    71,    82,    83,    85,    96,    97,    98,
+     100,   101,   102,   103,   104,   105,   106,   107,   108,   109,
+     110,   111,   112,   113,   114,   115,   116,   117,   118,   119,
+     120,   124,   141,    81,   143,   138,   145,   146,    13,    14,
+      15,    17,    18,    19,    20,    40,    75,    76,    81,   107,
+     120,   121,   123,   125,   126,   141,   150,   151,   152,   153,
+     158,   159,   160,   163,   170,    44,   130,   133,    73,    80,
+      74,   124,   121,   149,   107,   107,   123,    52,    53,    73,
+      77,    72,    72,    78,    39,   121,    71,   107,    86,    87,
+      83,    85,    54,    55,    89,    90,    56,    57,    58,    60,
+      59,    94,    74,   145,    44,   147,   148,    76,   146,    81,
+      81,   165,    71,    71,    81,    81,   123,    71,    76,   154,
+      61,    62,    63,    70,    80,   122,    78,    81,    76,   151,
+      73,    74,   124,   149,    74,    72,    99,   123,    44,    49,
+     102,   121,   107,   107,   109,   109,   111,   111,   111,   111,
+     112,   112,   116,   117,   118,   123,    76,    73,    78,    81,
+     151,   166,   123,    81,   164,   158,   121,   121,   124,    74,
+      74,    79,   124,   148,    40,   150,   159,   167,    72,   123,
+     136,   162,   155,    74,   121,    74,    71,   162,   168,   169,
+     151,   161,    44,    72,    76,   123,    81,    72,    16,    80,
+     152,   156,   157,    72,   123,   156,   151,   149,    81
 };
 
 #define yyerrok		(yyerrstatus = 0)
 #define yyclearin	(yychar = YYEMPTY)
 #define YYEMPTY		(-2)
 #define YYEOF		0
 
 #define YYACCEPT	goto yyacceptlab
@@ -1368,17 +1356,17 @@ while (YYID (0))
 #endif
 
 
 /* YY_LOCATION_PRINT -- Print the location on the stream.
    This macro was not mandated originally: define only if we know
    we won't break user code: when these are the locations we know.  */
 
 #ifndef YY_LOCATION_PRINT
-# if YYLTYPE_IS_TRIVIAL
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
 #  define YY_LOCATION_PRINT(File, Loc)			\
      fprintf (File, "%d.%d-%d.%d",			\
 	      (Loc).first_line, (Loc).first_column,	\
 	      (Loc).last_line,  (Loc).last_column)
 # else
 #  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
 # endif
 #endif
@@ -3920,64 +3908,76 @@ yyreduce:
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         (yyval.interm.type).setBasic(EbtStruct, qual, (yyvsp[(1) - (1)].lex).line);
         (yyval.interm.type).userDef = &structure;
     ;}
     break;
 
   case 137:
 
-    {
-        if (context->reservedErrorCheck((yyvsp[(2) - (5)].lex).line, *(yyvsp[(2) - (5)].lex).string))
-            context->recover();
-
-        TType* structure = new TType((yyvsp[(4) - (5)].interm.typeList), *(yyvsp[(2) - (5)].lex).string);
-        TVariable* userTypeDef = new TVariable((yyvsp[(2) - (5)].lex).string, *structure, true);
-        if (! context->symbolTable.insert(*userTypeDef)) {
-            context->error((yyvsp[(2) - (5)].lex).line, "redefinition", (yyvsp[(2) - (5)].lex).string->c_str(), "struct");
-            context->recover();
-        }
-        (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yyvsp[(1) - (5)].lex).line);
-        (yyval.interm.type).userDef = structure;
-    ;}
+    { if (context->enterStructDeclaration((yyvsp[(2) - (3)].lex).line, *(yyvsp[(2) - (3)].lex).string)) context->recover(); ;}
     break;
 
   case 138:
 
     {
-        TType* structure = new TType((yyvsp[(3) - (4)].interm.typeList), TString(""));
-        (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yyvsp[(1) - (4)].lex).line);
+        if (context->reservedErrorCheck((yyvsp[(2) - (6)].lex).line, *(yyvsp[(2) - (6)].lex).string))
+            context->recover();
+
+        TType* structure = new TType((yyvsp[(5) - (6)].interm.typeList), *(yyvsp[(2) - (6)].lex).string);
+        TVariable* userTypeDef = new TVariable((yyvsp[(2) - (6)].lex).string, *structure, true);
+        if (! context->symbolTable.insert(*userTypeDef)) {
+            context->error((yyvsp[(2) - (6)].lex).line, "redefinition", (yyvsp[(2) - (6)].lex).string->c_str(), "struct");
+            context->recover();
+        }
+        (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yyvsp[(1) - (6)].lex).line);
         (yyval.interm.type).userDef = structure;
+        context->exitStructDeclaration();
     ;}
     break;
 
   case 139:
 
+    { if (context->enterStructDeclaration((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string)) context->recover(); ;}
+    break;
+
+  case 140:
+
+    {
+        TType* structure = new TType((yyvsp[(4) - (5)].interm.typeList), TString(""));
+        (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yyvsp[(1) - (5)].lex).line);
+        (yyval.interm.type).userDef = structure;
+        context->exitStructDeclaration();
+    ;}
+    break;
+
+  case 141:
+
     {
         (yyval.interm.typeList) = (yyvsp[(1) - (1)].interm.typeList);
     ;}
     break;
 
-  case 140:
+  case 142:
 
     {
         (yyval.interm.typeList) = (yyvsp[(1) - (2)].interm.typeList);
         for (unsigned int i = 0; i < (yyvsp[(2) - (2)].interm.typeList)->size(); ++i) {
             for (unsigned int j = 0; j < (yyval.interm.typeList)->size(); ++j) {
                 if ((*(yyval.interm.typeList))[j].type->getFieldName() == (*(yyvsp[(2) - (2)].interm.typeList))[i].type->getFieldName()) {
                     context->error((*(yyvsp[(2) - (2)].interm.typeList))[i].line, "duplicate field name in structure:", "struct", (*(yyvsp[(2) - (2)].interm.typeList))[i].type->getFieldName().c_str());
                     context->recover();
                 }
             }
             (yyval.interm.typeList)->push_back((*(yyvsp[(2) - (2)].interm.typeList))[i]);
         }
     ;}
     break;
 
-  case 141:
+  case 143:
 
     {
         (yyval.interm.typeList) = (yyvsp[(2) - (3)].interm.typeList);
 
         if (context->voidErrorCheck((yyvsp[(1) - (3)].interm.type).line, (*(yyvsp[(2) - (3)].interm.typeList))[0].type->getFieldName(), (yyvsp[(1) - (3)].interm.type))) {
             context->recover();
         }
         for (unsigned int i = 0; i < (yyval.interm.typeList)->size(); ++i) {
@@ -3996,87 +3996,81 @@ yyreduce:
                     context->recover();
             }
             if ((yyvsp[(1) - (3)].interm.type).array)
                 type->setArraySize((yyvsp[(1) - (3)].interm.type).arraySize);
             if ((yyvsp[(1) - (3)].interm.type).userDef) {
                 type->setStruct((yyvsp[(1) - (3)].interm.type).userDef->getStruct());
                 type->setTypeName((yyvsp[(1) - (3)].interm.type).userDef->getTypeName());
             }
+
+            if (context->structNestingErrorCheck((yyvsp[(1) - (3)].interm.type).line, *type)) {
+                context->recover();
+            }
         }
     ;}
     break;
 
-  case 142:
+  case 144:
 
     {
         (yyval.interm.typeList) = NewPoolTTypeList();
         (yyval.interm.typeList)->push_back((yyvsp[(1) - (1)].interm.typeLine));
     ;}
     break;
 
-  case 143:
+  case 145:
 
     {
         (yyval.interm.typeList)->push_back((yyvsp[(3) - (3)].interm.typeLine));
     ;}
     break;
 
-  case 144:
+  case 146:
 
     {
         if (context->reservedErrorCheck((yyvsp[(1) - (1)].lex).line, *(yyvsp[(1) - (1)].lex).string))
             context->recover();
 
         (yyval.interm.typeLine).type = new TType(EbtVoid, EbpUndefined);
         (yyval.interm.typeLine).line = (yyvsp[(1) - (1)].lex).line;
         (yyval.interm.typeLine).type->setFieldName(*(yyvsp[(1) - (1)].lex).string);
     ;}
     break;
 
-  case 145:
+  case 147:
 
     {
         if (context->reservedErrorCheck((yyvsp[(1) - (4)].lex).line, *(yyvsp[(1) - (4)].lex).string))
             context->recover();
 
         (yyval.interm.typeLine).type = new TType(EbtVoid, EbpUndefined);
         (yyval.interm.typeLine).line = (yyvsp[(1) - (4)].lex).line;
         (yyval.interm.typeLine).type->setFieldName(*(yyvsp[(1) - (4)].lex).string);
 
         int size;
         if (context->arraySizeErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(3) - (4)].interm.intermTypedNode), size))
             context->recover();
         (yyval.interm.typeLine).type->setArraySize(size);
     ;}
     break;
 
-  case 146:
+  case 148:
 
     { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
     break;
 
-  case 147:
-
-    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
-    break;
-
-  case 148:
-
-    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermAggregate); ;}
-    break;
-
   case 149:
 
     { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
     break;
 
   case 150:
 
-    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermAggregate); ;}
     break;
 
   case 151:
 
     { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
     break;
 
   case 152:
@@ -4091,127 +4085,137 @@ yyreduce:
 
   case 154:
 
     { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
     break;
 
   case 155:
 
-    { (yyval.interm.intermAggregate) = 0; ;}
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
     break;
 
   case 156:
 
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+    break;
+
+  case 157:
+
+    { (yyval.interm.intermAggregate) = 0; ;}
+    break;
+
+  case 158:
+
     { context->symbolTable.push(); ;}
     break;
 
-  case 157:
+  case 159:
 
     { context->symbolTable.pop(); ;}
     break;
 
-  case 158:
+  case 160:
 
     {
         if ((yyvsp[(3) - (5)].interm.intermAggregate) != 0) {
             (yyvsp[(3) - (5)].interm.intermAggregate)->setOp(EOpSequence);
             (yyvsp[(3) - (5)].interm.intermAggregate)->setEndLine((yyvsp[(5) - (5)].lex).line);
         }
         (yyval.interm.intermAggregate) = (yyvsp[(3) - (5)].interm.intermAggregate);
     ;}
     break;
 
-  case 159:
+  case 161:
 
     { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
     break;
 
-  case 160:
+  case 162:
 
     { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
     break;
 
-  case 161:
+  case 163:
 
     {
         (yyval.interm.intermNode) = 0;
     ;}
     break;
 
-  case 162:
+  case 164:
 
     {
         if ((yyvsp[(2) - (3)].interm.intermAggregate)) {
             (yyvsp[(2) - (3)].interm.intermAggregate)->setOp(EOpSequence);
             (yyvsp[(2) - (3)].interm.intermAggregate)->setEndLine((yyvsp[(3) - (3)].lex).line);
         }
         (yyval.interm.intermNode) = (yyvsp[(2) - (3)].interm.intermAggregate);
     ;}
     break;
 
-  case 163:
+  case 165:
 
     {
         (yyval.interm.intermAggregate) = context->intermediate.makeAggregate((yyvsp[(1) - (1)].interm.intermNode), 0);
     ;}
     break;
 
-  case 164:
+  case 166:
 
     {
         (yyval.interm.intermAggregate) = context->intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermAggregate), (yyvsp[(2) - (2)].interm.intermNode), 0);
     ;}
     break;
 
-  case 165:
+  case 167:
 
     { (yyval.interm.intermNode) = 0; ;}
     break;
 
-  case 166:
+  case 168:
 
     { (yyval.interm.intermNode) = static_cast<TIntermNode*>((yyvsp[(1) - (2)].interm.intermTypedNode)); ;}
     break;
 
-  case 167:
+  case 169:
 
     {
         if (context->boolErrorCheck((yyvsp[(1) - (5)].lex).line, (yyvsp[(3) - (5)].interm.intermTypedNode)))
             context->recover();
         (yyval.interm.intermNode) = context->intermediate.addSelection((yyvsp[(3) - (5)].interm.intermTypedNode), (yyvsp[(5) - (5)].interm.nodePair), (yyvsp[(1) - (5)].lex).line);
     ;}
     break;
 
-  case 168:
+  case 170:
 
     {
         (yyval.interm.nodePair).node1 = (yyvsp[(1) - (3)].interm.intermNode);
         (yyval.interm.nodePair).node2 = (yyvsp[(3) - (3)].interm.intermNode);
     ;}
     break;
 
-  case 169:
+  case 171:
 
     {
         (yyval.interm.nodePair).node1 = (yyvsp[(1) - (1)].interm.intermNode);
         (yyval.interm.nodePair).node2 = 0;
     ;}
     break;
 
-  case 170:
+  case 172:
 
     {
         (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
         if (context->boolErrorCheck((yyvsp[(1) - (1)].interm.intermTypedNode)->getLine(), (yyvsp[(1) - (1)].interm.intermTypedNode)))
             context->recover();
     ;}
     break;
 
-  case 171:
+  case 173:
 
     {
         TIntermNode* intermNode;
         if (context->structQualifierErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
             context->recover();
         if (context->boolErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
             context->recover();
 
@@ -4219,193 +4223,193 @@ yyreduce:
             (yyval.interm.intermTypedNode) = (yyvsp[(4) - (4)].interm.intermTypedNode);
         else {
             context->recover();
             (yyval.interm.intermTypedNode) = 0;
         }
     ;}
     break;
 
-  case 172:
+  case 174:
 
     { context->symbolTable.push(); ++context->loopNestingLevel; ;}
     break;
 
-  case 173:
+  case 175:
 
     {
         context->symbolTable.pop();
         (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopWhile, 0, (yyvsp[(4) - (6)].interm.intermTypedNode), 0, (yyvsp[(6) - (6)].interm.intermNode), (yyvsp[(1) - (6)].lex).line);
         --context->loopNestingLevel;
     ;}
     break;
 
-  case 174:
+  case 176:
 
     { ++context->loopNestingLevel; ;}
     break;
 
-  case 175:
+  case 177:
 
     {
         if (context->boolErrorCheck((yyvsp[(8) - (8)].lex).line, (yyvsp[(6) - (8)].interm.intermTypedNode)))
             context->recover();
 
         (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopDoWhile, 0, (yyvsp[(6) - (8)].interm.intermTypedNode), 0, (yyvsp[(3) - (8)].interm.intermNode), (yyvsp[(4) - (8)].lex).line);
         --context->loopNestingLevel;
     ;}
     break;
 
-  case 176:
+  case 178:
 
     { context->symbolTable.push(); ++context->loopNestingLevel; ;}
     break;
 
-  case 177:
+  case 179:
 
     {
         context->symbolTable.pop();
         (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopFor, (yyvsp[(4) - (7)].interm.intermNode), reinterpret_cast<TIntermTyped*>((yyvsp[(5) - (7)].interm.nodePair).node1), reinterpret_cast<TIntermTyped*>((yyvsp[(5) - (7)].interm.nodePair).node2), (yyvsp[(7) - (7)].interm.intermNode), (yyvsp[(1) - (7)].lex).line);
         --context->loopNestingLevel;
     ;}
     break;
 
-  case 178:
+  case 180:
 
     {
         (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
     ;}
     break;
 
-  case 179:
-
-    {
-        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
-    ;}
-    break;
-
-  case 180:
-
-    {
-        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
-    ;}
-    break;
-
   case 181:
 
     {
-        (yyval.interm.intermTypedNode) = 0;
+        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
     ;}
     break;
 
   case 182:
 
     {
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+    ;}
+    break;
+
+  case 183:
+
+    {
+        (yyval.interm.intermTypedNode) = 0;
+    ;}
+    break;
+
+  case 184:
+
+    {
         (yyval.interm.nodePair).node1 = (yyvsp[(1) - (2)].interm.intermTypedNode);
         (yyval.interm.nodePair).node2 = 0;
     ;}
     break;
 
-  case 183:
+  case 185:
 
     {
         (yyval.interm.nodePair).node1 = (yyvsp[(1) - (3)].interm.intermTypedNode);
         (yyval.interm.nodePair).node2 = (yyvsp[(3) - (3)].interm.intermTypedNode);
     ;}
     break;
 
-  case 184:
+  case 186:
 
     {
         if (context->loopNestingLevel <= 0) {
             context->error((yyvsp[(1) - (2)].lex).line, "continue statement only allowed in loops", "", "");
             context->recover();
         }
         (yyval.interm.intermNode) = context->intermediate.addBranch(EOpContinue, (yyvsp[(1) - (2)].lex).line);
     ;}
     break;
 
-  case 185:
+  case 187:
 
     {
         if (context->loopNestingLevel <= 0) {
             context->error((yyvsp[(1) - (2)].lex).line, "break statement only allowed in loops", "", "");
             context->recover();
         }
         (yyval.interm.intermNode) = context->intermediate.addBranch(EOpBreak, (yyvsp[(1) - (2)].lex).line);
     ;}
     break;
 
-  case 186:
+  case 188:
 
     {
         (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(1) - (2)].lex).line);
         if (context->currentFunctionType->getBasicType() != EbtVoid) {
             context->error((yyvsp[(1) - (2)].lex).line, "non-void function must return a value", "return", "");
             context->recover();
         }
     ;}
     break;
 
-  case 187:
+  case 189:
 
     {
         (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(2) - (3)].interm.intermTypedNode), (yyvsp[(1) - (3)].lex).line);
         context->functionReturnsValue = true;
         if (context->currentFunctionType->getBasicType() == EbtVoid) {
             context->error((yyvsp[(1) - (3)].lex).line, "void function cannot return a value", "return", "");
             context->recover();
         } else if (*(context->currentFunctionType) != (yyvsp[(2) - (3)].interm.intermTypedNode)->getType()) {
             context->error((yyvsp[(1) - (3)].lex).line, "function return is not matching type:", "return", "");
             context->recover();
         }
     ;}
     break;
 
-  case 188:
+  case 190:
 
     {
         FRAG_ONLY("discard", (yyvsp[(1) - (2)].lex).line);
         (yyval.interm.intermNode) = context->intermediate.addBranch(EOpKill, (yyvsp[(1) - (2)].lex).line);
     ;}
     break;
 
-  case 189:
-
-    {
-        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
-        context->treeRoot = (yyval.interm.intermNode);
-    ;}
-    break;
-
-  case 190:
-
-    {
-        (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermNode), (yyvsp[(2) - (2)].interm.intermNode), 0);
-        context->treeRoot = (yyval.interm.intermNode);
-    ;}
-    break;
-
   case 191:
 
     {
         (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+        context->treeRoot = (yyval.interm.intermNode);
     ;}
     break;
 
   case 192:
 
     {
-        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+        (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermNode), (yyvsp[(2) - (2)].interm.intermNode), 0);
+        context->treeRoot = (yyval.interm.intermNode);
     ;}
     break;
 
   case 193:
 
     {
+        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+    ;}
+    break;
+
+  case 194:
+
+    {
+        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+    ;}
+    break;
+
+  case 195:
+
+    {
         TFunction* function = (yyvsp[(1) - (1)].interm).function;
         TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName()));
         //
         // Note:  'prevDec' could be 'function' if this is the first time we've seen function
         // as it would have just been put in the symbol table.  Otherwise, we're looking up
         // an earlier occurance.
         //
         if (prevDec->isDefined()) {
@@ -4478,17 +4482,17 @@ yyreduce:
             }
         }
         context->intermediate.setAggregateOperator(paramNodes, EOpParameters, (yyvsp[(1) - (1)].interm).line);
         (yyvsp[(1) - (1)].interm).intermAggregate = paramNodes;
         context->loopNestingLevel = 0;
     ;}
     break;
 
-  case 194:
+  case 196:
 
     {
         //?? Check that all paths return a value if return type != void ?
         //   May be best done as post process phase on intermediate code
         if (context->currentFunctionType->getBasicType() != EbtVoid && ! context->functionReturnsValue) {
             context->error((yyvsp[(1) - (3)].interm).line, "function does not return a value:", "", (yyvsp[(1) - (3)].interm).function->getName().c_str());
             context->recover();
         }
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/preprocessor/length_limits.h
@@ -0,0 +1,23 @@
+//
+// Copyright (c) 2011 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.
+//
+
+//
+// length_limits.h
+//
+
+#if !defined(__LENGTH_LIMITS_H)
+#define __LENGTH_LIMITS_H 1
+
+// These constants are factored out from the rest of the headers to
+// make it easier to reference them from the compiler sources.
+
+// These lengths do not include the NULL terminator.
+// see bug 675625: NVIDIA driver crash with lengths >= 253
+// this is only an interim fix, the real fix is name mapping, see ANGLE bug 144 / r619
+#define MAX_SYMBOL_NAME_LEN 250
+#define MAX_STRING_LEN 511
+
+#endif // !(defined(__LENGTH_LIMITS_H)
--- a/gfx/angle/src/compiler/preprocessor/scanner.h
+++ b/gfx/angle/src/compiler/preprocessor/scanner.h
@@ -43,22 +43,17 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILI
 \****************************************************************************/
 //
 // scanner.h
 //
 
 #if !defined(__SCANNER_H)
 #define __SCANNER_H 1
 
-// These lengths do not include the NULL terminator.
-// see bug 675625: NVIDIA driver crash with lengths >= 253
-// this is only an interim fix, the real fix is name mapping, see ANGLE bug 144 / r619
-#define MAX_SYMBOL_NAME_LEN 250
-#define MAX_STRING_LEN 511
-
+#include "compiler/preprocessor/length_limits.h"
 #include "compiler/preprocessor/parser.h"
 
 // Not really atom table stuff but needed first...
 
 typedef struct SourceLoc_Rec {
     unsigned short file, line;
 } SourceLoc;
 
--- a/gfx/angle/src/libGLESv2/Context.cpp
+++ b/gfx/angle/src/libGLESv2/Context.cpp
@@ -35,16 +35,19 @@ namespace
 {
     enum { CLOSING_INDEX_BUFFER_SIZE = 4096 };
 }
 
 namespace gl
 {
 Context::Context(const egl::Config *config, const gl::Context *shareContext) : mConfig(config)
 {
+    mDisplay = NULL;
+    mDevice = NULL;
+
     mFenceHandleAllocator.setBaseHandle(0);
 
     setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 
     mState.depthClearValue = 1.0f;
     mState.stencilClearValue = 0;
 
     mState.cullFace = false;
@@ -229,29 +232,30 @@ Context::~Context()
         mMaskedClearSavedState->Release();
     }
 
     mResourceManager->release();
 }
 
 void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
 {
-    IDirect3DDevice9 *device = display->getDevice();
+    mDisplay = display;
+    mDevice = mDisplay->getDevice();
 
     if (!mHasBeenCurrent)
     {
-        mDeviceCaps = display->getDeviceCaps();
-
-        mVertexDataManager = new VertexDataManager(this, device);
-        mIndexDataManager = new IndexDataManager(this, device);
+        mDeviceCaps = mDisplay->getDeviceCaps();
+
+        mVertexDataManager = new VertexDataManager(this, mDevice);
+        mIndexDataManager = new IndexDataManager(this, mDevice);
         mBlit = new Blit(this);
 
         mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0);
-        mSupportsVertexTexture = display->getVertexTextureSupport();
-        mSupportsNonPower2Texture = display->getNonPower2TextureSupport();
+        mSupportsVertexTexture = mDisplay->getVertexTextureSupport();
+        mSupportsNonPower2Texture = mDisplay->getNonPower2TextureSupport();
 
         mMaxTextureDimension = std::min(std::min((int)mDeviceCaps.MaxTextureWidth, (int)mDeviceCaps.MaxTextureHeight),
                                         (int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE);
         mMaxCubeTextureDimension = std::min(mMaxTextureDimension, (int)gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
         mMaxRenderbufferDimension = mMaxTextureDimension;
         mMaxTextureLevel = log2(mMaxTextureDimension) + 1;
         TRACE("MaxTextureDimension=%d, MaxCubeTextureDimension=%d, MaxRenderbufferDimension=%d, MaxTextureLevel=%d",
               mMaxTextureDimension, mMaxCubeTextureDimension, mMaxRenderbufferDimension, mMaxTextureLevel);
@@ -263,38 +267,38 @@ void Context::makeCurrent(egl::Display *
             D3DFMT_R5G6B5,
             D3DFMT_D24S8
         };
 
         int max = 0;
         for (int i = 0; i < sizeof(renderBufferFormats) / sizeof(D3DFORMAT); ++i)
         {
             bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1];
-            display->getMultiSampleSupport(renderBufferFormats[i], multisampleArray);
+            mDisplay->getMultiSampleSupport(renderBufferFormats[i], multisampleArray);
             mMultiSampleSupport[renderBufferFormats[i]] = multisampleArray;
 
             for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j)
             {
                 if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max)
                 {
                     max = j;
                 }
             }
         }
 
         mMaxSupportedSamples = max;
 
-        mSupportsEventQueries = display->getEventQuerySupport();
-        mSupportsDXT1Textures = display->getDXT1TextureSupport();
-        mSupportsDXT3Textures = display->getDXT3TextureSupport();
-        mSupportsDXT5Textures = display->getDXT5TextureSupport();
-        mSupportsFloatTextures = display->getFloatTextureSupport(&mSupportsFloatLinearFilter, &mSupportsFloatRenderableTextures);
-        mSupportsHalfFloatTextures = display->getHalfFloatTextureSupport(&mSupportsHalfFloatLinearFilter, &mSupportsHalfFloatRenderableTextures);
-        mSupportsLuminanceTextures = display->getLuminanceTextureSupport();
-        mSupportsLuminanceAlphaTextures = display->getLuminanceAlphaTextureSupport();
+        mSupportsEventQueries = mDisplay->getEventQuerySupport();
+        mSupportsDXT1Textures = mDisplay->getDXT1TextureSupport();
+        mSupportsDXT3Textures = mDisplay->getDXT3TextureSupport();
+        mSupportsDXT5Textures = mDisplay->getDXT5TextureSupport();
+        mSupportsFloatTextures = mDisplay->getFloatTextureSupport(&mSupportsFloatLinearFilter, &mSupportsFloatRenderableTextures);
+        mSupportsHalfFloatTextures = mDisplay->getHalfFloatTextureSupport(&mSupportsHalfFloatLinearFilter, &mSupportsHalfFloatRenderableTextures);
+        mSupportsLuminanceTextures = mDisplay->getLuminanceTextureSupport();
+        mSupportsLuminanceAlphaTextures = mDisplay->getLuminanceAlphaTextureSupport();
 
         mSupports32bitIndices = mDeviceCaps.MaxVertexIndex >= (1 << 16);
 
         mNumCompressedTextureFormats = 0;
         if (supportsDXT1Textures())
         {
             mNumCompressedTextureFormats += 2;
         }
@@ -1615,18 +1619,16 @@ bool Context::getQueryParameterInfo(GLen
 
     return true;
 }
 
 // Applies the render target surface, depth stencil surface, viewport rectangle and
 // scissor rectangle to the Direct3D 9 device
 bool Context::applyRenderTarget(bool ignoreViewport)
 {
-    IDirect3DDevice9 *device = getDevice();
-
     Framebuffer *framebufferObject = getDrawFramebuffer();
 
     if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
     {
         return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
     }
 
     IDirect3DSurface9 *renderTarget = NULL;
@@ -1637,17 +1639,17 @@ bool Context::applyRenderTarget(bool ign
     if (renderTargetSerial != mAppliedRenderTargetSerial)
     {
         renderTarget = framebufferObject->getRenderTarget();
 
         if (!renderTarget)
         {
             return false;   // Context must be lost
         }
-        device->SetRenderTarget(0, renderTarget);
+        mDevice->SetRenderTarget(0, renderTarget);
         mAppliedRenderTargetSerial = renderTargetSerial;
         mScissorStateDirty = true; // Scissor area must be clamped to render target's size-- this is different for different render targets.
         renderTargetChanged = true;
     }
 
     unsigned int depthbufferSerial = 0;
     unsigned int stencilbufferSerial = 0;
     if (framebufferObject->getDepthbufferType() != GL_NONE)
@@ -1672,17 +1674,17 @@ bool Context::applyRenderTarget(bool ign
         
         stencilbufferSerial = framebufferObject->getStencilbuffer()->getSerial();
     }
 
     if (depthbufferSerial != mAppliedDepthbufferSerial ||
         stencilbufferSerial != mAppliedStencilbufferSerial ||
         !mDepthStencilInitialized)
     {
-        device->SetDepthStencilSurface(depthStencil);
+        mDevice->SetDepthStencilSurface(depthStencil);
         mAppliedDepthbufferSerial = depthbufferSerial;
         mAppliedStencilbufferSerial = stencilbufferSerial;
         mDepthStencilInitialized = true;
     }
 
     if (!mRenderTargetDescInitialized || renderTargetChanged)
     {
         if (!renderTarget)
@@ -1725,37 +1727,37 @@ bool Context::applyRenderTarget(bool ign
 
     if (viewport.Width <= 0 || viewport.Height <= 0)
     {
         return false;   // Nothing to render
     }
 
     if (!mViewportInitialized || memcmp(&viewport, &mSetViewport, sizeof mSetViewport) != 0)
     {
-        device->SetViewport(&viewport);
+        mDevice->SetViewport(&viewport);
         mSetViewport = viewport;
         mViewportInitialized = true;
         mDxUniformsDirty = true;
     }
 
     if (mScissorStateDirty)
     {
         if (mState.scissorTest)
         {
             RECT rect = transformPixelRect(mState.scissorX, mState.scissorY, mState.scissorWidth, mState.scissorHeight, mRenderTargetDesc.Height);
             rect.left = clamp(rect.left, 0L, static_cast<LONG>(mRenderTargetDesc.Width));
             rect.top = clamp(rect.top, 0L, static_cast<LONG>(mRenderTargetDesc.Height));
             rect.right = clamp(rect.right, 0L, static_cast<LONG>(mRenderTargetDesc.Width));
             rect.bottom = clamp(rect.bottom, 0L, static_cast<LONG>(mRenderTargetDesc.Height));
-            device->SetScissorRect(&rect);
-            device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
+            mDevice->SetScissorRect(&rect);
+            mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
         }
         else
         {
-            device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
+            mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
         }
 
         mScissorStateDirty = false;
     }
 
     if (mState.currentProgram && mDxUniformsDirty)
     {
         Program *programObject = getCurrentProgram();
@@ -1781,127 +1783,125 @@ bool Context::applyRenderTarget(bool ign
     }
 
     return true;
 }
 
 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
 void Context::applyState(GLenum drawMode)
 {
-    IDirect3DDevice9 *device = getDevice();
     Program *programObject = getCurrentProgram();
 
     Framebuffer *framebufferObject = getDrawFramebuffer();
 
     GLenum adjustedFrontFace = adjustWinding(mState.frontFace);
 
     GLint frontCCW = programObject->getDxFrontCCWLocation();
     GLint ccw = (adjustedFrontFace == GL_CCW);
     programObject->setUniform1iv(frontCCW, 1, &ccw);
 
     GLint pointsOrLines = programObject->getDxPointsOrLinesLocation();
     GLint alwaysFront = !isTriangleMode(drawMode);
     programObject->setUniform1iv(pointsOrLines, 1, &alwaysFront);
 
-    egl::Display *display = getDisplay();
-    D3DADAPTER_IDENTIFIER9 *identifier = display->getAdapterIdentifier();
+    D3DADAPTER_IDENTIFIER9 *identifier = mDisplay->getAdapterIdentifier();
     bool zeroColorMaskAllowed = identifier->VendorId != 0x1002;
     // Apparently some ATI cards have a bug where a draw with a zero color
     // write mask can cause later draws to have incorrect results. Instead,
     // set a nonzero color write mask but modify the blend state so that no
     // drawing is done.
     // http://code.google.com/p/angleproject/issues/detail?id=169
 
     if (mCullStateDirty || mFrontFaceDirty)
     {
         if (mState.cullFace)
         {
-            device->SetRenderState(D3DRS_CULLMODE, es2dx::ConvertCullMode(mState.cullMode, adjustedFrontFace));
+            mDevice->SetRenderState(D3DRS_CULLMODE, es2dx::ConvertCullMode(mState.cullMode, adjustedFrontFace));
         }
         else
         {
-            device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+            mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
         }
 
         mCullStateDirty = false;
     }
 
     if (mDepthStateDirty)
     {
         if (mState.depthTest)
         {
-            device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
-            device->SetRenderState(D3DRS_ZFUNC, es2dx::ConvertComparison(mState.depthFunc));
+            mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
+            mDevice->SetRenderState(D3DRS_ZFUNC, es2dx::ConvertComparison(mState.depthFunc));
         }
         else
         {
-            device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
+            mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
         }
 
         mDepthStateDirty = false;
     }
 
     if (!zeroColorMaskAllowed && (mMaskStateDirty || mBlendStateDirty))
     {
         mBlendStateDirty = true;
         mMaskStateDirty = true;
     }
 
     if (mBlendStateDirty)
     {
         if (mState.blend)
         {
-            device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+            mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
 
             if (mState.sourceBlendRGB != GL_CONSTANT_ALPHA && mState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &&
                 mState.destBlendRGB != GL_CONSTANT_ALPHA && mState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
             {
-                device->SetRenderState(D3DRS_BLENDFACTOR, es2dx::ConvertColor(mState.blendColor));
+                mDevice->SetRenderState(D3DRS_BLENDFACTOR, es2dx::ConvertColor(mState.blendColor));
             }
             else
             {
-                device->SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_RGBA(unorm<8>(mState.blendColor.alpha),
+                mDevice->SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_RGBA(unorm<8>(mState.blendColor.alpha),
                                                                         unorm<8>(mState.blendColor.alpha),
                                                                         unorm<8>(mState.blendColor.alpha),
                                                                         unorm<8>(mState.blendColor.alpha)));
             }
 
-            device->SetRenderState(D3DRS_SRCBLEND, es2dx::ConvertBlendFunc(mState.sourceBlendRGB));
-            device->SetRenderState(D3DRS_DESTBLEND, es2dx::ConvertBlendFunc(mState.destBlendRGB));
-            device->SetRenderState(D3DRS_BLENDOP, es2dx::ConvertBlendOp(mState.blendEquationRGB));
+            mDevice->SetRenderState(D3DRS_SRCBLEND, es2dx::ConvertBlendFunc(mState.sourceBlendRGB));
+            mDevice->SetRenderState(D3DRS_DESTBLEND, es2dx::ConvertBlendFunc(mState.destBlendRGB));
+            mDevice->SetRenderState(D3DRS_BLENDOP, es2dx::ConvertBlendOp(mState.blendEquationRGB));
 
             if (mState.sourceBlendRGB != mState.sourceBlendAlpha || 
                 mState.destBlendRGB != mState.destBlendAlpha || 
                 mState.blendEquationRGB != mState.blendEquationAlpha)
             {
-                device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
-
-                device->SetRenderState(D3DRS_SRCBLENDALPHA, es2dx::ConvertBlendFunc(mState.sourceBlendAlpha));
-                device->SetRenderState(D3DRS_DESTBLENDALPHA, es2dx::ConvertBlendFunc(mState.destBlendAlpha));
-                device->SetRenderState(D3DRS_BLENDOPALPHA, es2dx::ConvertBlendOp(mState.blendEquationAlpha));
+                mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
+
+                mDevice->SetRenderState(D3DRS_SRCBLENDALPHA, es2dx::ConvertBlendFunc(mState.sourceBlendAlpha));
+                mDevice->SetRenderState(D3DRS_DESTBLENDALPHA, es2dx::ConvertBlendFunc(mState.destBlendAlpha));
+                mDevice->SetRenderState(D3DRS_BLENDOPALPHA, es2dx::ConvertBlendOp(mState.blendEquationAlpha));
             }
             else
             {
-                device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
+                mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
             }
         }
         else
         {
-            device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+            mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
         }
 
         mBlendStateDirty = false;
     }
 
     if (mStencilStateDirty || mFrontFaceDirty)
     {
         if (mState.stencilTest && framebufferObject->hasStencil())
         {
-            device->SetRenderState(D3DRS_STENCILENABLE, TRUE);
-            device->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE);
+            mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
+            mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE);
 
             // FIXME: Unsupported by D3D9
             const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF;
             const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK;
             const D3DRENDERSTATETYPE D3DRS_CCW_STENCILWRITEMASK = D3DRS_STENCILWRITEMASK;
             if (mState.stencilWritemask != mState.stencilBackWritemask || 
                 mState.stencilRef != mState.stencilBackRef || 
                 mState.stencilMask != mState.stencilBackMask)
@@ -1909,105 +1909,105 @@ void Context::applyState(GLenum drawMode
                 ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL.");
                 return error(GL_INVALID_OPERATION);
             }
 
             // get the maximum size of the stencil ref
             gl::DepthStencilbuffer *stencilbuffer = framebufferObject->getStencilbuffer();
             GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
 
-            device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilWritemask);
-            device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, 
+            mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilWritemask);
+            mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, 
                                    es2dx::ConvertComparison(mState.stencilFunc));
 
-            device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
-            device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilMask);
-
-            device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, 
+            mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
+            mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilMask);
+
+            mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, 
                                    es2dx::ConvertStencilOp(mState.stencilFail));
-            device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, 
+            mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, 
                                    es2dx::ConvertStencilOp(mState.stencilPassDepthFail));
-            device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, 
+            mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, 
                                    es2dx::ConvertStencilOp(mState.stencilPassDepthPass));
 
-            device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilBackWritemask);
-            device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, 
+            mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilBackWritemask);
+            mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, 
                                    es2dx::ConvertComparison(mState.stencilBackFunc));
 
-            device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
-            device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilBackMask);
-
-            device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, 
+            mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
+            mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilBackMask);
+
+            mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, 
                                    es2dx::ConvertStencilOp(mState.stencilBackFail));
-            device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, 
+            mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, 
                                    es2dx::ConvertStencilOp(mState.stencilBackPassDepthFail));
-            device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, 
+            mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, 
                                    es2dx::ConvertStencilOp(mState.stencilBackPassDepthPass));
         }
         else
         {
-            device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
+            mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
         }
 
         mStencilStateDirty = false;
         mFrontFaceDirty = false;
     }
 
     if (mMaskStateDirty)
     {
         int colorMask = es2dx::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, 
                                                 mState.colorMaskBlue, mState.colorMaskAlpha);
         if (colorMask == 0 && !zeroColorMaskAllowed)
         {
             // Enable green channel, but set blending so nothing will be drawn.
-            device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN);
-            device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
-
-            device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
-            device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
-            device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
+            mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN);
+            mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+
+            mDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
+            mDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
+            mDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
         }
         else
         {
-            device->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask);
+            mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask);
         }
-        device->SetRenderState(D3DRS_ZWRITEENABLE, mState.depthMask ? TRUE : FALSE);
+        mDevice->SetRenderState(D3DRS_ZWRITEENABLE, mState.depthMask ? TRUE : FALSE);
 
         mMaskStateDirty = false;
     }
 
     if (mPolygonOffsetStateDirty)
     {
         if (mState.polygonOffsetFill)
         {
             gl::DepthStencilbuffer *depthbuffer = framebufferObject->getDepthbuffer();
             if (depthbuffer)
             {
-                device->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *((DWORD*)&mState.polygonOffsetFactor));
+                mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *((DWORD*)&mState.polygonOffsetFactor));
                 float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
-                device->SetRenderState(D3DRS_DEPTHBIAS, *((DWORD*)&depthBias));
+                mDevice->SetRenderState(D3DRS_DEPTHBIAS, *((DWORD*)&depthBias));
             }
         }
         else
         {
-            device->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0);
-            device->SetRenderState(D3DRS_DEPTHBIAS, 0);
+            mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0);
+            mDevice->SetRenderState(D3DRS_DEPTHBIAS, 0);
         }
 
         mPolygonOffsetStateDirty = false;
     }
 
     if (mSampleStateDirty)
     {
         if (mState.sampleAlphaToCoverage)
         {
             FIXME("Sample alpha to coverage is unimplemented.");
         }
 
-        device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
+        mDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
         if (mState.sampleCoverage)
         {
             unsigned int mask = 0;
             if (mState.sampleCoverageValue != 0)
             {
                 float threshold = 0.5f;
 
                 for (int i = 0; i < framebufferObject->getSamples(); ++i)
@@ -2022,77 +2022,75 @@ void Context::applyState(GLenum drawMode
                 }
             }
             
             if (mState.sampleCoverageInvert)
             {
                 mask = ~mask;
             }
 
-            device->SetRenderState(D3DRS_MULTISAMPLEMASK, mask);
+            mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, mask);
         }
         else
         {
-            device->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
+            mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
         }
 
         mSampleStateDirty = false;
     }
 
     if (mDitherStateDirty)
     {
-        device->SetRenderState(D3DRS_DITHERENABLE, mState.dither ? TRUE : FALSE);
+        mDevice->SetRenderState(D3DRS_DITHERENABLE, mState.dither ? TRUE : FALSE);
 
         mDitherStateDirty = false;
     }
 }
 
 GLenum Context::applyVertexBuffer(GLint first, GLsizei count)
 {
     TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
 
     GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);
     if (err != GL_NO_ERROR)
     {
         return err;
     }
 
-    return mVertexDeclarationCache.applyDeclaration(attributes, getCurrentProgram());
+    return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, getCurrentProgram());
 }
 
 // Applies the indices and element array bindings to the Direct3D 9 device
 GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
 {
-    IDirect3DDevice9 *device = getDevice();
     GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer.get(), indices, indexInfo);
 
     if (err == GL_NO_ERROR)
     {
         if (indexInfo->serial != mAppliedIBSerial)
         {
-            device->SetIndices(indexInfo->indexBuffer);
+            mDevice->SetIndices(indexInfo->indexBuffer);
             mAppliedIBSerial = indexInfo->serial;
         }
     }
 
     return err;
 }
 
 // Applies the shaders and shader constants to the Direct3D 9 device
 void Context::applyShaders()
 {
-    IDirect3DDevice9 *device = getDevice();
     Program *programObject = getCurrentProgram();
     if (programObject->getSerial() != mAppliedProgramSerial)
     {
         IDirect3DVertexShader9 *vertexShader = programObject->getVertexShader();
         IDirect3DPixelShader9 *pixelShader = programObject->getPixelShader();
 
-        device->SetPixelShader(pixelShader);
-        device->SetVertexShader(vertexShader);
+        mDevice->SetPixelShader(pixelShader);
+        mDevice->SetVertexShader(vertexShader);
         programObject->dirtyAllUniforms();
         mAppliedProgramSerial = programObject->getSerial();
     }
 
     programObject->applyUniforms();
 }
 
 // Applies the textures and sampler states to the Direct3D 9 device
@@ -2106,17 +2104,16 @@ void Context::applyTextures()
     }
 }
 
 // For each Direct3D 9 sampler of either the pixel or vertex stage,
 // looks up the corresponding OpenGL texture image unit and texture type,
 // and sets the texture and its addressing/filtering state (or NULL when inactive).
 void Context::applyTextures(SamplerType type)
 {
-    IDirect3DDevice9 *device = getDevice();
     Program *programObject = getCurrentProgram();
 
     int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF;   // Range of Direct3D 9 samplers of given sampler type
     unsigned int *appliedTextureSerial = (type == SAMPLER_PIXEL) ? mAppliedTextureSerialPS : mAppliedTextureSerialVS;
     int d3dSamplerOffset = (type == SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0;
     int samplerRange = programObject->getUsedSamplerRange(type);
 
     for (int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
@@ -2138,55 +2135,55 @@ void Context::applyTextures(SamplerType 
                 {
                     if (appliedTextureSerial[samplerIndex] != texture->getSerial() || texture->isDirtyParameter())
                     {
                         GLenum wrapS = texture->getWrapS();
                         GLenum wrapT = texture->getWrapT();
                         GLenum minFilter = texture->getMinFilter();
                         GLenum magFilter = texture->getMagFilter();
 
-                        device->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, es2dx::ConvertTextureWrap(wrapS));
-                        device->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, es2dx::ConvertTextureWrap(wrapT));
-
-                        device->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, es2dx::ConvertMagFilter(magFilter));
+                        mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, es2dx::ConvertTextureWrap(wrapS));
+                        mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, es2dx::ConvertTextureWrap(wrapT));
+
+                        mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, es2dx::ConvertMagFilter(magFilter));
                         D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter;
                         es2dx::ConvertMinFilter(minFilter, &d3dMinFilter, &d3dMipFilter);
-                        device->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter);
-                        device->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
+                        mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter);
+                        mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
                     }
 
                     if (appliedTextureSerial[samplerIndex] != texture->getSerial() || texture->isDirtyImage())
                     {
-                        device->SetTexture(d3dSampler, d3dTexture);
+                        mDevice->SetTexture(d3dSampler, d3dTexture);
                     }
                 }
                 else
                 {
-                    device->SetTexture(d3dSampler, getIncompleteTexture(textureType)->getTexture());
+                    mDevice->SetTexture(d3dSampler, getIncompleteTexture(textureType)->getTexture());
                 }
 
                 appliedTextureSerial[samplerIndex] = texture->getSerial();
                 texture->resetDirty();
             }
         }
         else
         {
             if (appliedTextureSerial[samplerIndex] != 0)
             {
-                device->SetTexture(d3dSampler, NULL);
+                mDevice->SetTexture(d3dSampler, NULL);
                 appliedTextureSerial[samplerIndex] = 0;
             }
         }
     }
 
     for (int samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
     {
         if (appliedTextureSerial[samplerIndex] != 0)
         {
-            device->SetTexture(samplerIndex + d3dSamplerOffset, NULL);
+            mDevice->SetTexture(samplerIndex + d3dSamplerOffset, NULL);
             appliedTextureSerial[samplerIndex] = 0;
         }
     }
 }
 
 void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
 {
     Framebuffer *framebuffer = getReadFramebuffer();
@@ -2203,37 +2200,35 @@ void Context::readPixels(GLint x, GLint 
 
     IDirect3DSurface9 *renderTarget = framebuffer->getRenderTarget();
 
     if (!renderTarget)
     {
         return;   // Context must be lost, return silently
     }
 
-    IDirect3DDevice9 *device = getDevice();
-
     D3DSURFACE_DESC desc;
     renderTarget->GetDesc(&desc);
 
     IDirect3DSurface9 *systemSurface;
-    HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &systemSurface, NULL);
+    HRESULT result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &systemSurface, NULL);
 
     if (FAILED(result))
     {
         ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
         return error(GL_OUT_OF_MEMORY);
     }
 
     if (desc.MultiSampleType != D3DMULTISAMPLE_NONE)
     {
         UNIMPLEMENTED();   // FIXME: Requires resolve using StretchRect into non-multisampled render target
         return error(GL_OUT_OF_MEMORY);
     }
 
-    result = device->GetRenderTargetData(renderTarget, systemSurface);
+    result = mDevice->GetRenderTargetData(renderTarget, systemSurface);
 
     if (FAILED(result))
     {
         systemSurface->Release();
 
         switch (result)
         {
           // It turns out that D3D will sometimes produce more error
@@ -2452,18 +2447,16 @@ void Context::clear(GLbitfield mask)
 {
     Framebuffer *framebufferObject = getDrawFramebuffer();
 
     if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
     {
         return error(GL_INVALID_FRAMEBUFFER_OPERATION);
     }
 
-    egl::Display *display = getDisplay();
-    IDirect3DDevice9 *device = getDevice();
     DWORD flags = 0;
 
     if (mask & GL_COLOR_BUFFER_BIT)
     {
         mask &= ~GL_COLOR_BUFFER_BIT;
 
         if (framebufferObject->getColorbufferType() != GL_NONE)
         {
@@ -2545,98 +2538,98 @@ void Context::clear(GLbitfield mask)
     if (needMaskedColorClear || needMaskedStencilClear)
     {
         // State which is altered in all paths from this point to the clear call is saved.
         // State which is altered in only some paths will be flagged dirty in the case that
         //  that path is taken.
         HRESULT hr;
         if (mMaskedClearSavedState == NULL)
         {
-            hr = device->BeginStateBlock();
+            hr = mDevice->BeginStateBlock();
             ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
 
-            device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
-            device->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
-            device->SetRenderState(D3DRS_ZENABLE, FALSE);
-            device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
-            device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
-            device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
-            device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
-            device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
-            device->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
-            device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
-            device->SetPixelShader(NULL);
-            device->SetVertexShader(NULL);
-            device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
-            device->SetStreamSource(0, NULL, 0, 0);
-            device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
-            device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
-            device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
-            device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
-            device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
-            device->SetRenderState(D3DRS_TEXTUREFACTOR, color);
-            device->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
-
-            hr = device->EndStateBlock(&mMaskedClearSavedState);
+            mDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
+            mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
+            mDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
+            mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+            mDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+            mDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
+            mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+            mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
+            mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
+            mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
+            mDevice->SetPixelShader(NULL);
+            mDevice->SetVertexShader(NULL);
+            mDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
+            mDevice->SetStreamSource(0, NULL, 0, 0);
+            mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
+            mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+            mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
+            mDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+            mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
+            mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color);
+            mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
+
+            hr = mDevice->EndStateBlock(&mMaskedClearSavedState);
             ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
         }
 
         ASSERT(mMaskedClearSavedState != NULL);
 
         if (mMaskedClearSavedState != NULL)
         {
             hr = mMaskedClearSavedState->Capture();
             ASSERT(SUCCEEDED(hr));
         }
 
-        device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
-        device->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
-        device->SetRenderState(D3DRS_ZENABLE, FALSE);
-        device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
-        device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
-        device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
-        device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
-        device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
+        mDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
+        mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
+        mDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
+        mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+        mDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+        mDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
+        mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+        mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
 
         if (flags & D3DCLEAR_TARGET)
         {
-            device->SetRenderState(D3DRS_COLORWRITEENABLE, es2dx::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
+            mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, es2dx::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
         }
         else
         {
-            device->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
+            mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
         }
 
         if (stencilUnmasked != 0x0 && (flags & D3DCLEAR_STENCIL))
         {
-            device->SetRenderState(D3DRS_STENCILENABLE, TRUE);
-            device->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE);
-            device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
-            device->SetRenderState(D3DRS_STENCILREF, stencil);
-            device->SetRenderState(D3DRS_STENCILWRITEMASK, mState.stencilWritemask);
-            device->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_REPLACE);
-            device->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_REPLACE);
-            device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
+            mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
+            mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE);
+            mDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
+            mDevice->SetRenderState(D3DRS_STENCILREF, stencil);
+            mDevice->SetRenderState(D3DRS_STENCILWRITEMASK, mState.stencilWritemask);
+            mDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_REPLACE);
+            mDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_REPLACE);
+            mDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
             mStencilStateDirty = true;
         }
         else
         {
-            device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
+            mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
         }
 
-        device->SetPixelShader(NULL);
-        device->SetVertexShader(NULL);
-        device->SetFVF(D3DFVF_XYZRHW);
-        device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
-        device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
-        device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
-        device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
-        device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
-        device->SetRenderState(D3DRS_TEXTUREFACTOR, color);
-        device->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
+        mDevice->SetPixelShader(NULL);
+        mDevice->SetVertexShader(NULL);
+        mDevice->SetFVF(D3DFVF_XYZRHW);
+        mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
+        mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+        mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
+        mDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+        mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
+        mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color);
+        mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
 
         float quad[4][4];   // A quadrilateral covering the target, aligned to match the edges
         quad[0][0] = -0.5f;
         quad[0][1] = desc.Height - 0.5f;
         quad[0][2] = 0.0f;
         quad[0][3] = 1.0f;
 
         quad[1][0] = desc.Width - 0.5f;
@@ -2649,46 +2642,44 @@ void Context::clear(GLbitfield mask)
         quad[2][2] = 0.0f;
         quad[2][3] = 1.0f;
 
         quad[3][0] = desc.Width - 0.5f;
         quad[3][1] = -0.5f;
         quad[3][2] = 0.0f;
         quad[3][3] = 1.0f;
 
-        display->startScene();
-        device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float[4]));
+        mDisplay->startScene();
+        mDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float[4]));
 
         if (flags & D3DCLEAR_ZBUFFER)
         {
-            device->SetRenderState(D3DRS_ZENABLE, TRUE);
-            device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
-            device->Clear(0, NULL, D3DCLEAR_ZBUFFER, color, depth, stencil);
+            mDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
+            mDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
+            mDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, color, depth, stencil);
         }
 
         if (mMaskedClearSavedState != NULL)
         {
             mMaskedClearSavedState->Apply();
         }
     }
     else if (flags)
     {
-        device->Clear(0, NULL, flags, color, depth, stencil);
+        mDevice->Clear(0, NULL, flags, color, depth, stencil);
     }
 }
 
 void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
 {
     if (!mState.currentProgram)
     {
         return error(GL_INVALID_OPERATION);
     }
 
-    egl::Display *display = getDisplay();
-    IDirect3DDevice9 *device = getDevice();
     D3DPRIMITIVETYPE primitiveType;
     int primitiveCount;
 
     if(!es2dx::ConvertPrimitiveType(mode, count, &primitiveType, &primitiveCount))
         return error(GL_INVALID_ENUM);
 
     if (primitiveCount <= 0)
     {
@@ -2713,19 +2704,19 @@ void Context::drawArrays(GLenum mode, GL
 
     if (!getCurrentProgram()->validateSamplers(false))
     {
         return error(GL_INVALID_OPERATION);
     }
 
     if (!cullSkipsDraw(mode))
     {
-        display->startScene();
+        mDisplay->startScene();
         
-        device->DrawPrimitive(primitiveType, 0, primitiveCount);
+        mDevice->DrawPrimitive(primitiveType, 0, primitiveCount);
 
         if (mode == GL_LINE_LOOP)   // Draw the last segment separately
         {
             drawClosingLine(first, first + count - 1);
         }
     }
 }
 
@@ -2736,18 +2727,16 @@ void Context::drawElements(GLenum mode, 
         return error(GL_INVALID_OPERATION);
     }
 
     if (!indices && !mState.elementArrayBuffer)
     {
         return error(GL_INVALID_OPERATION);
     }
 
-    egl::Display *display = getDisplay();
-    IDirect3DDevice9 *device = getDevice();
     D3DPRIMITIVETYPE primitiveType;
     int primitiveCount;
 
     if(!es2dx::ConvertPrimitiveType(mode, count, &primitiveType, &primitiveCount))
         return error(GL_INVALID_ENUM);
 
     if (primitiveCount <= 0)
     {
@@ -2780,113 +2769,34 @@ void Context::drawElements(GLenum mode, 
 
     if (!getCurrentProgram()->validateSamplers(false))
     {
         return error(GL_INVALID_OPERATION);
     }
 
     if (!cullSkipsDraw(mode))
     {
-        display->startScene();
-
-        device->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, primitiveCount);
+        mDisplay->startScene();
+
+        mDevice->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, primitiveCount);
 
         if (mode == GL_LINE_LOOP)   // Draw the last segment separately
         {
             drawClosingLine(count, type, indices);
         }
     }
 }
 
-void Context::finish()
+// Implements glFlush when block is false, glFinish when block is true
+void Context::sync(bool block)
 {
-    egl::Display *display = getDisplay();
-    IDirect3DDevice9 *device = getDevice();
-    IDirect3DQuery9 *occlusionQuery = NULL;
-    HRESULT result;
-
-    result = device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery);
-    if (FAILED(result))
-    {
-        ERR("CreateQuery failed hr=%x\n", result);
-        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
-        {
-            return error(GL_OUT_OF_MEMORY);
-        }
-        ASSERT(false);
-        return;
-    }
-
-    IDirect3DStateBlock9 *savedState = NULL;
-    result = device->CreateStateBlock(D3DSBT_ALL, &savedState);
-    if (FAILED(result))
-    {
-        ERR("CreateStateBlock failed hr=%x\n", result);
-        occlusionQuery->Release();
-
-        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
-        {
-            return error(GL_OUT_OF_MEMORY);
-        }
-        ASSERT(false);
-        return;
-    }
-
-    result = occlusionQuery->Issue(D3DISSUE_BEGIN);
-    if (FAILED(result))
-    {
-        ERR("occlusionQuery->Issue(BEGIN) failed hr=%x\n", result);
-        occlusionQuery->Release();
-        savedState->Release();
-        ASSERT(false);
-        return;
-    }
-
-    // Render something outside the render target
-    device->SetPixelShader(NULL);
-    device->SetVertexShader(NULL);
-    device->SetFVF(D3DFVF_XYZRHW);
-    float data[4] = {-1.0f, -1.0f, -1.0f, 1.0f};
-    display->startScene();
-    device->DrawPrimitiveUP(D3DPT_POINTLIST, 1, data, sizeof(data));
-
-    result = occlusionQuery->Issue(D3DISSUE_END);
-    if (FAILED(result))
-    {
-        ERR("occlusionQuery->Issue(END) failed hr=%x\n", result);
-        occlusionQuery->Release();
-        savedState->Apply();
-        savedState->Release();
-        ASSERT(false);
-        return;
-    }
-
-    while ((result = occlusionQuery->GetData(NULL, 0, D3DGETDATA_FLUSH)) == S_FALSE)
-    {
-        // Keep polling, but allow other threads to do something useful first
-        Sleep(0);
-    }
-
-    occlusionQuery->Release();
-    savedState->Apply();
-    savedState->Release();
-
-    if (result == D3DERR_DEVICELOST)
-    {
-        error(GL_OUT_OF_MEMORY);
-    }
-}
-
-void Context::flush()
-{
-    IDirect3DDevice9 *device = getDevice();
     IDirect3DQuery9 *eventQuery = NULL;
     HRESULT result;
 
-    result = device->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery);
+    result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery);
     if (FAILED(result))
     {
         ERR("CreateQuery failed hr=%x\n", result);
         if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
         {
             return error(GL_OUT_OF_MEMORY);
         }
         ASSERT(false);
@@ -2897,39 +2807,49 @@ void Context::flush()
     if (FAILED(result))
     {
         ERR("eventQuery->Issue(END) failed hr=%x\n", result);
         ASSERT(false);
         eventQuery->Release();
         return;
     }
 
-    result = eventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
+    do
+    {
+        result = eventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
+
+        if(block && result == S_FALSE)
+        {
+            // Keep polling, but allow other threads to do something useful first
+            Sleep(0);
+        }
+    }
+    while(block && result == S_FALSE);
+
     eventQuery->Release();
 
     if (result == D3DERR_DEVICELOST)
     {
         error(GL_OUT_OF_MEMORY);
     }
 }
 
 void Context::drawClosingLine(unsigned int first, unsigned int last)
 {
-    IDirect3DDevice9 *device = getDevice();
     IDirect3DIndexBuffer9 *indexBuffer = NULL;
     bool succeeded = false;
     UINT offset;
 
     if (supports32bitIndices())
     {
         const int spaceNeeded = 2 * sizeof(unsigned int);
 
         if (!mClosingIB)
         {
-            mClosingIB = new StreamingIndexBuffer(device, CLOSING_INDEX_BUFFER_SIZE, D3DFMT_INDEX32);
+            mClosingIB = new StreamingIndexBuffer(mDevice, CLOSING_INDEX_BUFFER_SIZE, D3DFMT_INDEX32);
         }
 
         mClosingIB->reserveSpace(spaceNeeded, GL_UNSIGNED_INT);
 
         unsigned int *data = static_cast<unsigned int*>(mClosingIB->map(spaceNeeded, &offset));
         if (data)
         {
             data[0] = last;
@@ -2940,17 +2860,17 @@ void Context::drawClosingLine(unsigned i
         }
     }
     else
     {
         const int spaceNeeded = 2 * sizeof(unsigned short);
 
         if (!mClosingIB)
         {
-            mClosingIB = new StreamingIndexBuffer(device, CLOSING_INDEX_BUFFER_SIZE, D3DFMT_INDEX16);
+            mClosingIB = new StreamingIndexBuffer(mDevice, CLOSING_INDEX_BUFFER_SIZE, D3DFMT_INDEX16);
         }
 
         mClosingIB->reserveSpace(spaceNeeded, GL_UNSIGNED_SHORT);
 
         unsigned short *data = static_cast<unsigned short*>(mClosingIB->map(spaceNeeded, &offset));
         if (data)
         {
             data[0] = last;
@@ -2958,20 +2878,20 @@ void Context::drawClosingLine(unsigned i
             mClosingIB->unmap();
             offset /= 2;
             succeeded = true;
         }
     }
     
     if (succeeded)
     {
-        device->SetIndices(mClosingIB->getBuffer());
+        mDevice->SetIndices(mClosingIB->getBuffer());
         mAppliedIBSerial = mClosingIB->getSerial();
 
-        device->DrawIndexedPrimitive(D3DPT_LINELIST, 0, 0, last, offset, 1);
+        mDevice->DrawIndexedPrimitive(D3DPT_LINELIST, 0, 0, last, offset, 1);
     }
     else
     {
         ERR("Could not create an index buffer for closing a line loop.");
         error(GL_OUT_OF_MEMORY);
     }
 }
 
@@ -3488,35 +3408,32 @@ void Context::initExtensionString()
 
 const char *Context::getExtensionString() const
 {
     return mExtensionString.c_str();
 }
 
 void Context::initRendererString()
 {
-    egl::Display *display = getDisplay();
-    D3DADAPTER_IDENTIFIER9 *identifier = display->getAdapterIdentifier();
+    D3DADAPTER_IDENTIFIER9 *identifier = mDisplay->getAdapterIdentifier();
 
     mRendererString = "ANGLE (";
     mRendererString += identifier->Description;
     mRendererString += ")";
 }
 
 const char *Context::getRendererString() const
 {
     return mRendererString.c_str();
 }
 
 void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 
                               GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                               GLbitfield mask)
 {
-    IDirect3DDevice9 *device = getDevice();
-
     Framebuffer *readFramebuffer = getReadFramebuffer();
     Framebuffer *drawFramebuffer = getDrawFramebuffer();
 
     if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE ||
         !drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
     {
         return error(GL_INVALID_FRAMEBUFFER_OPERATION);
     }
@@ -3747,34 +3664,33 @@ void Context::blitFramebuffer(GLint srcX
             (readDSBuffer && readDSBuffer->getSamples() != 0))
         {
             return error(GL_INVALID_OPERATION);
         }
     }
 
     if (blitRenderTarget || blitDepthStencil)
     {
-        egl::Display *display = getDisplay();
-        display->endScene();
+        mDisplay->endScene();
 
         if (blitRenderTarget)
         {
-            HRESULT result = device->StretchRect(readFramebuffer->getRenderTarget(), &sourceTrimmedRect, 
+            HRESULT result = mDevice->StretchRect(readFramebuffer->getRenderTarget(), &sourceTrimmedRect, 
                                                  drawFramebuffer->getRenderTarget(), &destTrimmedRect, D3DTEXF_NONE);
 
             if (FAILED(result))
             {
                 ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result);
                 return;
             }
         }
 
         if (blitDepthStencil)
         {
-            HRESULT result = device->StretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, D3DTEXF_NONE);
+            HRESULT result = mDevice->StretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, D3DTEXF_NONE);
 
             if (FAILED(result))
             {
                 ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result);
                 return;
             }
         }
     }
@@ -3795,20 +3711,18 @@ VertexDeclarationCache::~VertexDeclarati
     {
         if (mVertexDeclCache[i].vertexDeclaration)
         {
             mVertexDeclCache[i].vertexDeclaration->Release();
         }
     }
 }
 
-GLenum VertexDeclarationCache::applyDeclaration(TranslatedAttribute attributes[], Program *program)
+GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], Program *program)
 {
-    IDirect3DDevice9 *device = getDevice();
-
     D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS + 1];
     D3DVERTEXELEMENT9 *element = &elements[0];
 
     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
     {
         if (attributes[i].active)
         {
             if (mAppliedVBs[i].serial != attributes[i].serial ||
--- a/gfx/angle/src/libGLESv2/Context.h
+++ b/gfx/angle/src/libGLESv2/Context.h
@@ -223,17 +223,17 @@ struct State
 
 // Helper class to construct and cache vertex declarations
 class VertexDeclarationCache
 {
   public:
     VertexDeclarationCache();
     ~VertexDeclarationCache();
 
-    GLenum applyDeclaration(TranslatedAttribute attributes[], Program *program);
+    GLenum applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], Program *program);
 
     void markStateDirty();
 
   private:
     UINT mMaxLru;
 
     enum { NUM_VERTEX_DECL_CACHE_ENTRIES = 16 };
 
@@ -416,18 +416,17 @@ class Context
     bool getBooleanv(GLenum pname, GLboolean *params);
 
     bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
 
     void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels);
     void clear(GLbitfield mask);
     void drawArrays(GLenum mode, GLint first, GLsizei count);
     void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
-    void finish();
-    void flush();
+    void sync(bool block);   // flush/finish
 
 	// Draw the last segment of a line loop
     void drawClosingLine(unsigned int first, unsigned int last);
     void drawClosingLine(GLsizei count, GLenum type, const void *indices);
 
     void recordInvalidEnum();
     void recordInvalidValue();
     void recordInvalidOperation();
@@ -492,16 +491,18 @@ class Context
 
     bool cullSkipsDraw(GLenum drawMode);
     bool isTriangleMode(GLenum drawMode);
 
     void initExtensionString();
     void initRendererString();
 
     const egl::Config *const mConfig;
+    egl::Display *mDisplay;
+    IDirect3DDevice9 *mDevice;
 
     State mState;
 
     BindingPointer<Texture2D> mTexture2DZero;
     BindingPointer<TextureCubeMap> mTextureCubeMapZero;
 
     typedef stdext::hash_map<GLuint, Framebuffer*> FramebufferMap;
     FramebufferMap mFramebufferMap;
--- a/gfx/angle/src/libGLESv2/Program.cpp
+++ b/gfx/angle/src/libGLESv2/Program.cpp
@@ -54,16 +54,17 @@ bool Uniform::isArray()
 
 UniformLocation::UniformLocation(const std::string &_name, unsigned int element, unsigned int index) 
     : name(Program::undecorateUniform(_name)), element(element), index(index)
 {
 }
 
 Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle), mSerial(issueSerial())
 {
+    mDevice = getDevice();
     mFragmentShader = NULL;
     mVertexShader = NULL;
 
     mPixelExecutable = NULL;
     mVertexExecutable = NULL;
     mConstantTablePS = NULL;
     mConstantTableVS = NULL;
 
@@ -1670,19 +1671,18 @@ void Program::link()
     const char *vertexProfile = context->supportsShaderModel3() ? "vs_3_0" : "vs_2_0";
     const char *pixelProfile = context->supportsShaderModel3() ? "ps_3_0" : "ps_2_0";
 
     ID3D10Blob *vertexBinary = compileToBinary(mVertexHLSL.c_str(), vertexProfile, &mConstantTableVS);
     ID3D10Blob *pixelBinary = compileToBinary(mPixelHLSL.c_str(), pixelProfile, &mConstantTablePS);
 
     if (vertexBinary && pixelBinary)
     {
-        IDirect3DDevice9 *device = getDevice();
-        HRESULT vertexResult = device->CreateVertexShader((DWORD*)vertexBinary->GetBufferPointer(), &mVertexExecutable);
-        HRESULT pixelResult = device->CreatePixelShader((DWORD*)pixelBinary->GetBufferPointer(), &mPixelExecutable);
+        HRESULT vertexResult = mDevice->CreateVertexShader((DWORD*)vertexBinary->GetBufferPointer(), &mVertexExecutable);
+        HRESULT pixelResult = mDevice->CreatePixelShader((DWORD*)pixelBinary->GetBufferPointer(), &mPixelExecutable);
 
         if (vertexResult == D3DERR_OUTOFVIDEOMEMORY || vertexResult == E_OUTOFMEMORY || pixelResult == D3DERR_OUTOFVIDEOMEMORY || pixelResult == E_OUTOFMEMORY)
         {
             return error(GL_OUT_OF_MEMORY);
         }
 
         ASSERT(SUCCEEDED(vertexResult) && SUCCEEDED(pixelResult));
 
@@ -2046,18 +2046,16 @@ std::string Program::undecorateUniform(c
         return _name.substr(3);
     }
     
     return _name;
 }
 
 void Program::applyUniformnbv(Uniform *targetUniform, GLsizei count, int width, const GLboolean *v)
 {
-    IDirect3DDevice9 *device = getDevice();
-
     float *vector = NULL;
     BOOL *boolVector = NULL;
 
     if (targetUniform->ps.registerCount && targetUniform->ps.registerSet == D3DXRS_FLOAT4 ||
         targetUniform->vs.registerCount && targetUniform->vs.registerSet == D3DXRS_FLOAT4)
     {
         vector = new float[4 * count];
 
@@ -2086,70 +2084,66 @@ void Program::applyUniformnbv(Uniform *t
             boolVector[i] = v[i] != GL_FALSE;
         }
     }
 
     if (targetUniform->ps.registerCount)
     {
         if (targetUniform->ps.registerSet == D3DXRS_FLOAT4)
         {
-            device->SetPixelShaderConstantF(targetUniform->ps.registerIndex, vector, targetUniform->ps.registerCount);
+            mDevice->SetPixelShaderConstantF(targetUniform->ps.registerIndex, vector, targetUniform->ps.registerCount);
         }
         else if (targetUniform->ps.registerSet == D3DXRS_BOOL)
         {
-            device->SetPixelShaderConstantB(targetUniform->ps.registerIndex, boolVector, targetUniform->ps.registerCount);
+            mDevice->SetPixelShaderConstantB(targetUniform->ps.registerIndex, boolVector, targetUniform->ps.registerCount);
         }
         else UNREACHABLE();
     }
 
     if (targetUniform->vs.registerCount)
     {
         if (targetUniform->vs.registerSet == D3DXRS_FLOAT4)
         {
-            device->SetVertexShaderConstantF(targetUniform->vs.registerIndex, vector, targetUniform->vs.registerCount);
+            mDevice->SetVertexShaderConstantF(targetUniform->vs.registerIndex, vector, targetUniform->vs.registerCount);
         }
         else if (targetUniform->vs.registerSet == D3DXRS_BOOL)
         {
-            device->SetVertexShaderConstantB(targetUniform->vs.registerIndex, boolVector, targetUniform->vs.registerCount);
+            mDevice->SetVertexShaderConstantB(targetUniform->vs.registerIndex, boolVector, targetUniform->vs.registerCount);
         }
         else UNREACHABLE();
     }
 
     delete [] vector;
     delete [] boolVector;
 }
 
 bool Program::applyUniformnfv(Uniform *targetUniform, const GLfloat *v)
 {
-    IDirect3DDevice9 *device = getDevice();
-
     if (targetUniform->ps.registerCount)
     {
-        device->SetPixelShaderConstantF(targetUniform->ps.registerIndex, v, targetUniform->ps.registerCount);
+        mDevice->SetPixelShaderConstantF(targetUniform->ps.registerIndex, v, targetUniform->ps.registerCount);
     }
 
     if (targetUniform->vs.registerCount)
     {
-        device->SetVertexShaderConstantF(targetUniform->vs.registerIndex, v, targetUniform->vs.registerCount);
+        mDevice->SetVertexShaderConstantF(targetUniform->vs.registerIndex, v, targetUniform->vs.registerCount);
     }
 
     return true;
 }
 
 bool Program::applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint *v)
 {
     D3DXVECTOR4 *vector = new D3DXVECTOR4[count];
 
     for (int i = 0; i < count; i++)
     {
         vector[i] = D3DXVECTOR4((float)v[i], 0, 0, 0);
     }
 
-    IDirect3DDevice9 *device = getDevice();
-
     if (targetUniform->ps.registerCount)
     {
         if (targetUniform->ps.registerSet == D3DXRS_SAMPLER)
         {
             unsigned int firstIndex = targetUniform->ps.registerIndex;
 
             for (int i = 0; i < count; i++)
             {
@@ -2160,17 +2154,17 @@ bool Program::applyUniform1iv(Uniform *t
                     ASSERT(mSamplersPS[samplerIndex].active);
                     mSamplersPS[samplerIndex].logicalTextureUnit = v[i];
                 }
             }
         }
         else
         {
             ASSERT(targetUniform->ps.registerSet == D3DXRS_FLOAT4);
-            device->SetPixelShaderConstantF(targetUniform->ps.registerIndex, (const float*)vector, targetUniform->ps.registerCount);
+            mDevice->SetPixelShaderConstantF(targetUniform->ps.registerIndex, (const float*)vector, targetUniform->ps.registerCount);
         }
     }
 
     if (targetUniform->vs.registerCount)
     {
         if (targetUniform->vs.registerSet == D3DXRS_SAMPLER)
         {
             unsigned int firstIndex = targetUniform->vs.registerIndex;
@@ -2184,17 +2178,17 @@ bool Program::applyUniform1iv(Uniform *t
                     ASSERT(mSamplersVS[samplerIndex].active);
                     mSamplersVS[samplerIndex].logicalTextureUnit = v[i];
                 }
             }
         }
         else
         {
             ASSERT(targetUniform->vs.registerSet == D3DXRS_FLOAT4);
-            device->SetVertexShaderConstantF(targetUniform->vs.registerIndex, (const float *)vector, targetUniform->vs.registerCount);
+            mDevice->SetVertexShaderConstantF(targetUniform->vs.registerIndex, (const float *)vector, targetUniform->vs.registerCount);
         }
     }
 
     delete [] vector;
 
     return true;
 }
 
@@ -2249,28 +2243,26 @@ bool Program::applyUniform4iv(Uniform *t
 
     delete [] vector;
 
     return true;
 }
 
 void Program::applyUniformniv(Uniform *targetUniform, GLsizei count, const D3DXVECTOR4 *vector)
 {
-    IDirect3DDevice9 *device = getDevice();
-
     if (targetUniform->ps.registerCount)
     {
         ASSERT(targetUniform->ps.registerSet == D3DXRS_FLOAT4);
-        device->SetPixelShaderConstantF(targetUniform->ps.registerIndex, (const float *)vector, targetUniform->ps.registerCount);
+        mDevice->SetPixelShaderConstantF(targetUniform->ps.registerIndex, (const float *)vector, targetUniform->ps.registerCount);
     }
 
     if (targetUniform->vs.registerCount)
     {
         ASSERT(targetUniform->vs.registerSet == D3DXRS_FLOAT4);
-        device->SetVertexShaderConstantF(targetUniform->vs.registerIndex, (const float *)vector, targetUniform->vs.registerCount);
+        mDevice->SetVertexShaderConstantF(targetUniform->vs.registerIndex, (const float *)vector, targetUniform->vs.registerCount);
     }
 }
 
 // append a santized message to the program info log.
 // The D3D compiler includes a fake file path in some of the warning or error 
 // messages, so lets remove all occurrences of this fake file path from the log.
 void Program::appendToInfoLogSanitized(const char *message)
 {
--- a/gfx/angle/src/libGLESv2/Program.h
+++ b/gfx/angle/src/libGLESv2/Program.h
@@ -167,16 +167,17 @@ class Program
     void initializeConstantHandles(Uniform *targetUniform, Uniform::RegisterInfo *rs, ID3DXConstantTable *constantTable);
 
     void appendToInfoLogSanitized(const char *message);
     void appendToInfoLog(const char *info, ...);
     void resetInfoLog();
 
     static unsigned int issueSerial();
 
+    IDirect3DDevice9 *mDevice;
     FragmentShader *mFragmentShader;
     VertexShader *mVertexShader;
 
     std::string mPixelHLSL;
     std::string mVertexHLSL;
 
     IDirect3DPixelShader9 *mPixelExecutable;
     IDirect3DVertexShader9 *mVertexExecutable;
--- a/gfx/angle/src/libGLESv2/libGLESv2.cpp
+++ b/gfx/angle/src/libGLESv2/libGLESv2.cpp
@@ -1946,17 +1946,17 @@ void __stdcall glFinish(void)
     EVENT("()");
 
     try
     {
         gl::Context *context = gl::getContext();
 
         if (context)
         {
-            context->finish();
+            context->sync(true);
         }
     }
     catch(std::bad_alloc&)
     {
         return error(GL_OUT_OF_MEMORY);
     }
 }
 
@@ -1965,17 +1965,17 @@ void __stdcall glFlush(void)
     EVENT("()");
 
     try
     {
         gl::Context *context = gl::getContext();
 
         if (context)
         {
-            context->flush();
+            context->sync(false);
         }
     }
     catch(std::bad_alloc&)
     {
         return error(GL_OUT_OF_MEMORY);
     }
 }