merge mozilla-inbound to mozilla-central a=merge
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Fri, 25 Nov 2016 15:36:56 +0100
changeset 324295 b982373cb0e953976fd45f342910d1d1ea123fbb
parent 324243 d4cc716d86d0bac2e75c77ea69f349f9f6c001a4 (current diff)
parent 324294 629069be312e79f7b50005adf6c68bf446f5064e (diff)
child 324296 ee388da4aeb6b686a04c16d11ca8606ee2b3e8e0
child 324300 c4d075822fbfd1a2e07b93bdb70edd3596d02139
child 324316 40fd20c7aed22abc0a700dee63682fc1a41f0c6b
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersmerge
milestone53.0a1
merge mozilla-inbound to mozilla-central a=merge
browser/base/content/browser.js
devtools/client/responsive.html/browser/tunnel.js
devtools/client/webconsole/test/head.js
gfx/angle/src/compiler/preprocessor/pp_utils.h
gfx/angle/src/libANGLE/renderer/Format.cpp
gfx/angle/src/libANGLE/renderer/Format_autogen.cpp
netwerk/base/rust-url-capi/src/string_utils.rs
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -825,24 +825,23 @@ function _loadURIWithFlags(browser, uri,
     uri = "about:blank";
   }
   let flags = params.flags || 0;
   let referrer = params.referrerURI;
   let referrerPolicy = ('referrerPolicy' in params ? params.referrerPolicy :
                         Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT);
   let postData = params.postData;
 
-  let wasRemote = browser.isRemoteBrowser;
-
-  let process = browser.isRemoteBrowser ? Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT
-                                        : Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
-  let mustChangeProcess = gMultiProcessBrowser &&
-                          !E10SUtils.canLoadURIInProcess(uri, process);
-  if ((!wasRemote && !mustChangeProcess) ||
-      (wasRemote && mustChangeProcess)) {
+  let currentRemoteType = browser.remoteType;
+  let requiredRemoteType =
+    E10SUtils.getRemoteTypeForURI(uri, gMultiProcessBrowser, currentRemoteType);
+  let mustChangeProcess = requiredRemoteType != currentRemoteType;
+
+  // !requiredRemoteType means we're loading in the parent/this process.
+  if (!requiredRemoteType) {
     browser.inLoadURI = true;
   }
   try {
     if (!mustChangeProcess) {
       if (params.userContextId) {
         browser.webNavigation.setOriginAttributesBeforeLoading({ userContextId: params.userContextId });
       }
 
@@ -883,18 +882,17 @@ function _loadURIWithFlags(browser, uri,
       }
 
       browser.webNavigation.loadURIWithOptions(uri, flags, referrer, referrerPolicy,
                                                postData, null, null);
     } else {
       throw e;
     }
   } finally {
-    if ((!wasRemote && !mustChangeProcess) ||
-        (wasRemote && mustChangeProcess)) {
+    if (!requiredRemoteType) {
       browser.inLoadURI = false;
     }
   }
 }
 
 // Starts a new load in the browser first switching the browser to the correct
 // process
 function LoadInOtherProcess(browser, loadOptions, historyIndex = -1) {
@@ -1140,32 +1138,22 @@ var gBrowserInit = {
 
         // We must set usercontextid before updateBrowserRemoteness()
         // so that the newly created remote tab child has correct usercontextid
         if (tabToOpen.hasAttribute("usercontextid")) {
           let usercontextid = tabToOpen.getAttribute("usercontextid");
           gBrowser.selectedBrowser.setAttribute("usercontextid", usercontextid);
         }
 
-        // If the browser that we're swapping in was remote, then we'd better
-        // be able to support remote browsers, and then make our selectedTab
-        // remote.
         try {
-          if (tabToOpen.linkedBrowser.isRemoteBrowser) {
-            if (!gMultiProcessBrowser) {
-              throw new Error("Cannot drag a remote browser into a window " +
-                              "without the remote tabs load context.");
-            }
-            gBrowser.updateBrowserRemoteness(gBrowser.selectedBrowser, true);
-          } else if (gBrowser.selectedBrowser.isRemoteBrowser) {
-            // If the browser is remote, then it's implied that
-            // gMultiProcessBrowser is true. We need to flip the remoteness
-            // of this tab to false in order for the tab drag to work.
-            gBrowser.updateBrowserRemoteness(gBrowser.selectedBrowser, false);
-          }
+          // Make sure selectedBrowser has the same remote settings as the one
+          // we are swapping in.
+          gBrowser.updateBrowserRemoteness(gBrowser.selectedBrowser,
+                                           tabToOpen.linkedBrowser.isRemoteBrowser,
+                                           tabToOpen.linkedBrowser.remoteType);
           gBrowser.swapBrowsersAndCloseOther(gBrowser.selectedTab, tabToOpen);
         } catch (e) {
           Cu.reportError(e);
         }
       }
       // window.arguments[2]: referrer (nsIURI | string)
       //                 [3]: postData (nsIInputStream)
       //                 [4]: allowThirdPartyFixup (bool)
@@ -2266,34 +2254,32 @@ function BrowserViewSourceOfDocument(aAr
   } else {
     args = aArgsOrDocument;
   }
 
   let viewInternal = () => {
     let inTab = Services.prefs.getBoolPref("view_source.tab");
     if (inTab) {
       let tabBrowser = gBrowser;
-      let forceNotRemote = false;
+      let preferredRemoteType;
       if (!tabBrowser) {
         if (!args.browser) {
           throw new Error("BrowserViewSourceOfDocument should be passed the " +
                           "subject browser if called from a window without " +
                           "gBrowser defined.");
         }
-        forceNotRemote = !args.browser.isRemoteBrowser;
+        preferredRemoteType = args.browser.remoteType;
       } else {
         // Some internal URLs (such as specific chrome: and about: URLs that are
         // not yet remote ready) cannot be loaded in a remote browser.  View
         // source in tab expects the new view source browser's remoteness to match
         // that of the original URL, so disable remoteness if necessary for this
         // URL.
-        let contentProcess = Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT
-        forceNotRemote =
-          gMultiProcessBrowser &&
-          !E10SUtils.canLoadURIInProcess(args.URL, contentProcess)
+        preferredRemoteType =
+          E10SUtils.getRemoteTypeForURI(args.URL, gMultiProcessBrowser);
       }
 
       // In the case of popups, we need to find a non-popup browser window.
       if (!tabBrowser || !window.toolbar.visible) {
         // This returns only non-popup browser windows by default.
         let browserWindow = RecentWindow.getMostRecentBrowserWindow();
         tabBrowser = browserWindow.gBrowser;
       }
@@ -2301,17 +2287,17 @@ function BrowserViewSourceOfDocument(aAr
       // `viewSourceInBrowser` will load the source content from the page
       // descriptor for the tab (when possible) or fallback to the network if
       // that fails.  Either way, the view source module will manage the tab's
       // location, so use "about:blank" here to avoid unnecessary redundant
       // requests.
       let tab = tabBrowser.loadOneTab("about:blank", {
         relatedToCurrent: true,
         inBackground: false,
-        forceNotRemote,
+        preferredRemoteType,
         relatedBrowser: args.browser
       });
       args.viewSourceBrowser = tabBrowser.getBrowserForTab(tab);
       top.gViewSourceUtils.viewSourceInBrowser(args);
     } else {
       top.gViewSourceUtils.viewSource(args);
     }
   }
@@ -3260,21 +3246,21 @@ function getPEMString(cert)
 var PrintPreviewListener = {
   _printPreviewTab: null,
   _tabBeforePrintPreview: null,
   _simplifyPageTab: null,
 
   getPrintPreviewBrowser: function() {
     if (!this._printPreviewTab) {
       let browser = gBrowser.selectedTab.linkedBrowser;
-      let forceNotRemote = gMultiProcessBrowser && !browser.isRemoteBrowser;
+      let preferredRemoteType = browser.remoteType;
       this._tabBeforePrintPreview = gBrowser.selectedTab;
       this._printPreviewTab = gBrowser.loadOneTab("about:blank",
                                                   { inBackground: false,
-                                                    forceNotRemote,
+                                                    preferredRemoteType,
                                                     relatedBrowser: browser });
       gBrowser.selectedTab = this._printPreviewTab;
     }
     return gBrowser.getBrowserForTab(this._printPreviewTab);
   },
   createSimplifiedBrowser: function() {
     this._simplifyPageTab = gBrowser.loadOneTab("about:blank",
                                                 { inBackground: true });
@@ -4218,26 +4204,26 @@ var XULBrowserWindow = {
     var securityUI = gBrowser.securityUI;
     this.onSecurityChange(null, null, securityUI.state, true);
   },
 
   setJSStatus: function() {
     // unsupported
   },
 
-  forceInitialBrowserRemote: function() {
+  forceInitialBrowserRemote: function(aRemoteType) {
     let initBrowser =
       document.getAnonymousElementByAttribute(gBrowser, "anonid", "initialBrowser");
-    return initBrowser.frameLoader.tabParent;
+    gBrowser.updateBrowserRemoteness(initBrowser, true, aRemoteType, null);
   },
 
   forceInitialBrowserNonRemote: function(aOpener) {
     let initBrowser =
       document.getAnonymousElementByAttribute(gBrowser, "anonid", "initialBrowser");
-    gBrowser.updateBrowserRemoteness(initBrowser, false, aOpener);
+    gBrowser.updateBrowserRemoteness(initBrowser, false, E10SUtils.NOT_REMOTE, aOpener);
   },
 
   setDefaultStatus: function(status) {
     this.defaultStatus = status;
     this.updateStatusField();
   },
 
   setOverLink: function(url, anchorElt) {
@@ -5020,17 +5006,18 @@ nsBrowserAccess.prototype = {
 
     var isExternal = !!(aFlags & Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
 
     var userContextId = aParams.openerOriginAttributes &&
                         ("userContextId" in aParams.openerOriginAttributes)
                           ? aParams.openerOriginAttributes.userContextId
                           : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID
 
-    let browser = this._openURIInNewTab(aURI, aParams.referrer,
+    let referrer = aParams.referrer ? makeURI(aParams.referrer) : null;
+    let browser = this._openURIInNewTab(aURI, referrer,
                                         aParams.referrerPolicy,
                                         aParams.isPrivate,
                                         isExternal, false,
                                         userContextId);
     if (browser)
       return browser.QueryInterface(Ci.nsIFrameLoaderOwner);
 
     return null;
--- a/browser/base/content/tab-content.js
+++ b/browser/base/content/tab-content.js
@@ -617,16 +617,20 @@ var WebBrowserChrome = {
     if (!E10SUtils.shouldLoadURI(aDocShell, aURI, aReferrer)) {
       E10SUtils.redirectLoad(aDocShell, aURI, aReferrer);
       return false;
     }
 
     return true;
   },
 
+  shouldLoadURIInThisProcess: function(aURI) {
+    return E10SUtils.shouldLoadURIInThisProcess(aURI);
+  },
+
   // Try to reload the currently active or currently loading page in a new process.
   reloadInFreshProcess: function(aDocShell, aURI, aReferrer) {
     E10SUtils.redirectLoad(aDocShell, aURI, aReferrer, true);
     return true;
   }
 };
 
 if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1509,16 +1509,17 @@
         <body>
           <![CDATA[
             var aReferrerPolicy;
             var aFromExternal;
             var aRelatedToCurrent;
             var aAllowMixedContent;
             var aSkipAnimation;
             var aForceNotRemote;
+            var aPreferredRemoteType;
             var aNoReferrer;
             var aUserContextId;
             var aRelatedBrowser;
             var aOriginPrincipal;
             var aOpener;
             if (arguments.length == 2 &&
                 typeof arguments[1] == "object" &&
                 !(arguments[1] instanceof Ci.nsIURI)) {
@@ -1529,16 +1530,17 @@
               aPostData             = params.postData;
               aLoadInBackground     = params.inBackground;
               aAllowThirdPartyFixup = params.allowThirdPartyFixup;
               aFromExternal         = params.fromExternal;
               aRelatedToCurrent     = params.relatedToCurrent;
               aAllowMixedContent    = params.allowMixedContent;
               aSkipAnimation        = params.skipAnimation;
               aForceNotRemote       = params.forceNotRemote;
+              aPreferredRemoteType  = params.preferredRemoteType;
               aNoReferrer           = params.noReferrer;
               aUserContextId        = params.userContextId;
               aRelatedBrowser       = params.relatedBrowser;
               aOriginPrincipal      = params.originPrincipal;
               aOpener               = params.opener;
             }
 
             var bgLoad = (aLoadInBackground != null) ? aLoadInBackground :
@@ -1551,16 +1553,17 @@
                                   postData: aPostData,
                                   ownerTab: owner,
                                   allowThirdPartyFixup: aAllowThirdPartyFixup,
                                   fromExternal: aFromExternal,
                                   relatedToCurrent: aRelatedToCurrent,
                                   skipAnimation: aSkipAnimation,
                                   allowMixedContent: aAllowMixedContent,
                                   forceNotRemote: aForceNotRemote,
+                                  preferredRemoteType: aPreferredRemoteType,
                                   noReferrer: aNoReferrer,
                                   userContextId: aUserContextId,
                                   originPrincipal: aOriginPrincipal,
                                   relatedBrowser: aRelatedBrowser,
                                   opener: aOpener });
             if (!bgLoad)
               this.selectedTab = tab;
 
@@ -1668,36 +1671,48 @@
               this.selectedBrowser.focus();
           }
         ]]></body>
       </method>
 
       <method name="updateBrowserRemoteness">
         <parameter name="aBrowser"/>
         <parameter name="aShouldBeRemote"/>
+        <parameter name="aNewRemoteType"/>
         <parameter name="aOpener"/>
         <parameter name="aFreshProcess"/>
         <body>
           <![CDATA[
+            if (!gMultiProcessBrowser && aShouldBeRemote) {
+              throw new Error("Cannot switch to remote browser in a window " +
+                              "without the remote tabs load context.");
+            }
+
             let isRemote = aBrowser.getAttribute("remote") == "true";
 
+            // If going remote and no aNewRemoteType then use default.
+            if (aShouldBeRemote && !aNewRemoteType) {
+              aNewRemoteType = E10SUtils.DEFAULT_REMOTE_TYPE;
+            }
+
             // If we are passed an opener, we must be making the browser non-remote, and
             // if the browser is _currently_ non-remote, we need the openers to match,
             // because it is already too late to change it.
             if (aOpener) {
               if (aShouldBeRemote) {
-                throw new Exception("Cannot set an opener on a browser which should be remote!");
+                throw new Error("Cannot set an opener on a browser which should be remote!");
               }
               if (!isRemote && aBrowser.contentWindow.opener != aOpener) {
-                throw new Exception("Cannot change opener on an already non-remote browser!");
+                throw new Error("Cannot change opener on an already non-remote browser!");
               }
             }
 
             // Abort if we're not going to change anything
-            if (isRemote == aShouldBeRemote && !aFreshProcess) {
+            if (isRemote == aShouldBeRemote && !aFreshProcess &&
+                (!isRemote || aBrowser.getAttribute("remoteType") == aNewRemoteType)) {
               return false;
             }
 
             let tab = this.getTabForBrowser(aBrowser);
             let evt = document.createEvent("Events");
             evt.initEvent("BeforeTabRemotenessChange", true, false);
             tab.dispatchEvent(evt);
 
@@ -1724,17 +1739,23 @@
             // Make sure to restore the original droppedLinkHandler and
             // relatedBrowser.
             let droppedLinkHandler = aBrowser.droppedLinkHandler;
             let relatedBrowser = aBrowser.relatedBrowser;
 
             // Change the "remote" attribute.
             let parent = aBrowser.parentNode;
             parent.removeChild(aBrowser);
-            aBrowser.setAttribute("remote", aShouldBeRemote ? "true" : "false");
+            if (aShouldBeRemote) {
+              aBrowser.setAttribute("remote", "true");
+              aBrowser.setAttribute("remoteType", aNewRemoteType);
+            } else {
+              aBrowser.setAttribute("remote", "false");
+              aBrowser.removeAttribute("remoteType");
+            }
 
             // NB: This works with the hack in the browser constructor that
             // turns this normal property into a field.
             aBrowser.relatedBrowser = relatedBrowser;
 
             // Set the opener window on the browser, such that when the frame
             // loader is created the opener is set correctly.
             aBrowser.presetOpenerWindow(aOpener);
@@ -1808,47 +1829,38 @@
             evt.initEvent("TabRemotenessChange", true, false);
             tab.dispatchEvent(evt);
 
             return true;
           ]]>
         </body>
       </method>
 
-      <method name="switchBrowserIntoFreshProcess">
-        <parameter name="aBrowser"/>
-        <body>
-          <![CDATA[
-            if (!gMultiProcessBrowser) {
-              return this.updateBrowserRemoteness(aBrowser, false);
-            }
-
-            return this.updateBrowserRemoteness(aBrowser,
-                                                /* aShouldBeRemote */ true,
-                                                /* aOpener */ null,
-                                                /* aFreshProcess */ true);
-          ]]>
-        </body>
-      </method>
-
       <method name="updateBrowserRemotenessByURL">
         <parameter name="aBrowser"/>
         <parameter name="aURL"/>
+        <parameter name="aFreshProcess"/>
         <body>
           <![CDATA[
             if (!gMultiProcessBrowser)
               return this.updateBrowserRemoteness(aBrowser, false);
 
-            let process = aBrowser.isRemoteBrowser ? Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT
-                                                   : Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
-
-            // If this URL can't load in the browser's current process then flip
-            // it to the other process
-            if (!E10SUtils.canLoadURIInProcess(aURL, process))
-              return this.updateBrowserRemoteness(aBrowser, !aBrowser.isRemoteBrowser);
+            // If this URL can't load in the current browser then flip it to the
+            // correct type.
+            let currentRemoteType = aBrowser.remoteType;
+            let requiredRemoteType =
+              E10SUtils.getRemoteTypeForURI(aURL, gMultiProcessBrowser,
+                                            currentRemoteType);
+            if (currentRemoteType != requiredRemoteType || aFreshProcess) {
+              return this.updateBrowserRemoteness(aBrowser,
+                                                  !!requiredRemoteType,
+                                                  requiredRemoteType,
+                                                  /* aOpener */ null,
+                                                  aFreshProcess);
+            }
 
             return false;
           ]]>
         </body>
       </method>
 
       <field name="_preloadedBrowser">null</field>
       <method name="_getPreloadedBrowser">
@@ -1895,25 +1907,26 @@
         <body>
           <![CDATA[
             // Do nothing if we have a preloaded browser already
             // or preloading of newtab pages is disabled.
             if (this._preloadedBrowser || !this._isPreloadingEnabled()) {
               return;
             }
 
-            let remote = gMultiProcessBrowser &&
-                         E10SUtils.canLoadURIInProcess(BROWSER_NEW_TAB_URL, Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT);
-            let browser = this._createBrowser({isPreloadBrowser: true, remote: remote});
+            let remoteType =
+              E10SUtils.getRemoteTypeForURI(BROWSER_NEW_TAB_URL,
+                                            gMultiProcessBrowser);
+            let browser = this._createBrowser({isPreloadBrowser: true, remoteType});
             this._preloadedBrowser = browser;
 
             let notificationbox = this.getNotificationBox(browser);
             this.mPanelContainer.appendChild(notificationbox);
 
-            if (remote) {
+            if (remoteType != E10SUtils.NOT_REMOTE) {
               // For remote browsers, we need to make sure that the webProgress is
               // instantiated, otherwise the parent won't get informed about the state
               // of the preloaded browser until it gets attached to a tab.
               browser.webProgress;
             }
 
             browser.loadURI(BROWSER_NEW_TAB_URL);
             browser.docShellIsActive = false;
@@ -1921,38 +1934,45 @@
         </body>
       </method>
 
       <method name="_createBrowser">
         <parameter name="aParams"/>
         <body>
           <![CDATA[
             // Supported parameters:
-            // userContextId, remote, isPreloadBrowser, uriIsAboutBlank, permanentKey
+            // userContextId, remote, remoteType, isPreloadBrowser,
+            // uriIsAboutBlank, permanentKey
 
             const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
             let b = document.createElementNS(NS_XUL, "browser");
             b.permanentKey = aParams.permanentKey || {};
             b.setAttribute("type", "content-targetable");
             b.setAttribute("message", "true");
             b.setAttribute("messagemanagergroup", "browsers");
             b.setAttribute("contextmenu", this.getAttribute("contentcontextmenu"));
             b.setAttribute("tooltip", this.getAttribute("contenttooltip"));
 
             if (aParams.userContextId) {
               b.setAttribute("usercontextid", aParams.userContextId);
             }
 
-            if (aParams.remote) {
+            // remote parameter used by some addons, use default in this case.
+            if (aParams.remote && !aParams.remoteType) {
+              aParams.remoteType = E10SUtils.DEFAULT_REMOTE_TYPE;
+            }
+
+            if (aParams.remoteType) {
+              b.setAttribute("remoteType", aParams.remoteType);
               b.setAttribute("remote", "true");
             }
 
             if (aParams.opener) {
-              if (aParams.remote) {
+              if (aParams.remoteType) {
                 throw new Exception("Cannot set opener window on a remote browser!");
               }
               b.QueryInterface(Ci.nsIFrameLoaderOwner).presetOpenerWindow(aParams.opener);
             }
 
             if (window.gShowPageResizers && window.windowState == window.STATE_NORMAL) {
               b.setAttribute("showresizer", "true");
             }
@@ -2015,25 +2035,24 @@
         <parameter name="aTab"/>
         <parameter name="aURI"/>
         <parameter name="aParams"/>
         <body>
           <![CDATA[
             "use strict";
 
             // Supported parameters:
-            // forceNotRemote, userContextId
+            // forceNotRemote, preferredRemoteType, userContextId
 
             let uriIsAboutBlank = !aURI || aURI == "about:blank";
 
-            // The new browser should be remote if this is an e10s window and
-            // the uri to load can be loaded remotely.
-            let remote = gMultiProcessBrowser &&
-                         !aParams.forceNotRemote &&
-                         E10SUtils.canLoadURIInProcess(aURI, Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT);
+            let remoteType =
+              aParams.forceNotRemote ? E10SUtils.NOT_REMOTE
+              : E10SUtils.getRemoteTypeForURI(aURI, gMultiProcessBrowser,
+                                              aParams.preferredRemoteType);
 
             let browser;
             let usingPreloadedContent = false;
 
             // If we open a new tab with the newtab URL in the default
             // userContext, check if there is a preloaded browser ready.
             // Private windows are not included because both the label and the
             // icon for the tab would be set incorrectly (see bug 1195981).
@@ -2045,17 +2064,17 @@
                 usingPreloadedContent = true;
                 aTab.permanentKey = browser.permanentKey;
               }
             }
 
             if (!browser) {
               // No preloaded browser found, create one.
               browser = this._createBrowser({permanentKey: aTab.permanentKey,
-                                             remote: remote,
+                                             remoteType,
                                              uriIsAboutBlank: uriIsAboutBlank,
                                              userContextId: aParams.userContextId,
                                              relatedBrowser: aParams.relatedBrowser,
                                              opener: aParams.opener});
             }
 
             let notificationbox = this.getNotificationBox(browser);
             let uniqueId = this._generateUniquePanelID();
@@ -2090,17 +2109,17 @@
             // activeness in the tab switcher.
             browser.docShellIsActive = false;
 
             // When addTab() is called with an URL that is not "about:blank" we
             // set the "nodefaultsrc" attribute that prevents a frameLoader
             // from being created as soon as the linked <browser> is inserted
             // into the DOM. We thus have to register the new outerWindowID
             // for non-remote browsers after we have called browser.loadURI().
-            if (!remote) {
+            if (remoteType == E10SUtils.NOT_REMOTE) {
               this._outerWindowIDBrowserMap.set(browser.outerWindowID, browser);
             }
 
             var evt = new CustomEvent("TabBrowserInserted", { bubbles: true, detail: {} });
             aTab.dispatchEvent(evt);
 
             return { usingPreloadedContent: usingPreloadedContent };
           ]]>
@@ -2120,16 +2139,17 @@
 
             const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
             var aReferrerPolicy;
             var aFromExternal;
             var aRelatedToCurrent;
             var aSkipAnimation;
             var aAllowMixedContent;
             var aForceNotRemote;
+            var aPreferredRemoteType;
             var aNoReferrer;
             var aUserContextId;
             var aEventDetail;
             var aRelatedBrowser;
             var aOriginPrincipal;
             var aDisallowInheritPrincipal;
             var aOpener;
             if (arguments.length == 2 &&
@@ -2142,16 +2162,17 @@
               aPostData                 = params.postData;
               aOwner                    = params.ownerTab;
               aAllowThirdPartyFixup     = params.allowThirdPartyFixup;
               aFromExternal             = params.fromExternal;
               aRelatedToCurrent         = params.relatedToCurrent;
               aSkipAnimation            = params.skipAnimation;
               aAllowMixedContent        = params.allowMixedContent;
               aForceNotRemote           = params.forceNotRemote;
+              aPreferredRemoteType      = params.preferredRemoteType;
               aNoReferrer               = params.noReferrer;
               aUserContextId            = params.userContextId;
               aEventDetail              = params.eventDetail;
               aRelatedBrowser           = params.relatedBrowser;
               aOriginPrincipal          = params.originPrincipal;
               aDisallowInheritPrincipal = params.disallowInheritPrincipal;
               aOpener                   = params.opener;
             }
@@ -2215,16 +2236,17 @@
             // browser to immediately be linked.  In future incarnations of this
             // bug this will be removed so we can leave the tab in its "lazy"
             // state to be exploited for startup optimization.  Note that for
             // now this must occur before "TabOpen" event is fired, as that will
             // trigger SessionStore.jsm to run code that expects the existence
             // of tab.linkedBrowser.
             let browserParams = {
               forceNotRemote: aForceNotRemote,
+              preferredRemoteType: aPreferredRemoteType,
               userContextId:  aUserContextId,
               relatedBrowser: aRelatedBrowser,
               opener: aOpener,
             };
             let { usingPreloadedContent } = this._linkBrowserToTab(t, aURI, browserParams);
             let b = t.linkedBrowser;
 
             // Dispatch a new tab notification.  We do this once we're
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -3538,23 +3538,18 @@ var SessionStoreInternal = {
     }
 
     // We have to mark this tab as restoring first, otherwise
     // the "pending" attribute will be applied to the linked
     // browser, which removes it from the display list. We cannot
     // flip the remoteness of any browser that is not being displayed.
     this.markTabAsRestoring(aTab);
 
-    let isRemotenessUpdate = false;
-    if (aReloadInFreshProcess) {
-      isRemotenessUpdate = tabbrowser.switchBrowserIntoFreshProcess(browser);
-    } else {
-      isRemotenessUpdate = tabbrowser.updateBrowserRemotenessByURL(browser, uri);
-    }
-
+    let isRemotenessUpdate =
+      tabbrowser.updateBrowserRemotenessByURL(browser, uri, aReloadInFreshProcess);
     if (isRemotenessUpdate) {
       // We updated the remoteness, so we need to send the history down again.
       //
       // Start a new epoch to discard all frame script messages relating to a
       // previous epoch. All async messages that are still on their way to chrome
       // will be ignored and don't override any tab data set when restoring.
       let epoch = this.startNextEpoch(browser);
 
--- a/browser/components/sessionstore/test/browser_grouped_session_store.js
+++ b/browser/components/sessionstore/test/browser_grouped_session_store.js
@@ -21,28 +21,37 @@ add_task(function* () {
     is(history.entries.length, length, "Lengths match");
     for (let i = 0; i < length; ++i) {
       is(history.entries[i].url, URIs[i], "URI at index " + i + " matches");
     }
     is(history.index, index, "Index matches");
     yield ContentTask.spawn(browser, [index, length], function* ([index, length]) {
       let webNav = content.window.QueryInterface(Ci.nsIInterfaceRequestor)
             .getInterface(Ci.nsIWebNavigation);
+      is(webNav.sessionHistory.globalIndexOffset + webNav.sessionHistory.index,
+         index - 1, "In content index matches");
       is(webNav.canGoForward, index < length, "canGoForward is correct");
       is(webNav.canGoBack, index > 1, "canGoBack is correct");
     });
   }
 
-  // Wait for a process change and then fulfil the promise.
+  // Wait for a process change, followed by a locationchange event, and then
+  // fulfil the promise.
   function awaitProcessChange(browser) {
     return new Promise(resolve => {
+      let locChangeListener = {
+        onLocationChange: () => {
+          gBrowser.removeProgressListener(locChangeListener);
+          resolve();
+        },
+      };
+
       browser.addEventListener("BrowserChangedProcess", function bcp(e) {
         browser.removeEventListener("BrowserChangedProcess", bcp);
-        ok(true, "The browser changed process!");
-        resolve();
+        gBrowser.addProgressListener(locChangeListener);
       });
     });
   }
 
   // Order of events:
   // Load [0], load [1], prerender [2], load [2], load [3]
   // Back [2], Back [1], Forward [2], Back [0], Forward [3]
   // Prerender [4], Back [0], Forward [2], Load [3'], Back [0].
--- a/browser/locales/en-US/chrome/browser/preferences/search.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/search.dtd
@@ -8,19 +8,16 @@
 
 <!ENTITY provideSearchSuggestions.label        "Provide search suggestions">
 <!ENTITY provideSearchSuggestions.accesskey    "s">
 
 <!ENTITY showURLBarSuggestions.label           "Show search suggestions in location bar results">
 <!ENTITY showURLBarSuggestions.accesskey       "l">
 <!ENTITY urlBarSuggestionsPermanentPB.label    "Search suggestions will not be shown in location bar results because you have configured &brandShortName; to never remember history.">
 
-<!ENTITY redirectWindowsSearch.label "Use this search engine for searches from Windows">
-<!ENTITY redirectWindowsSearch.accesskey "W">
-
 <!ENTITY oneClickSearchEngines.label           "One-click search engines">
 
 <!ENTITY chooseWhichOneToDisplay.label         "The search bar lets you search alternate engines directly. Choose which ones to display.">
 
 <!ENTITY engineNameColumn.label                "Search Engine">
 <!ENTITY engineKeywordColumn.label             "Keyword">
 
 <!ENTITY restoreDefaultSearchEngines.label     "Restore Default Search Engines">
--- a/browser/modules/E10SUtils.jsm
+++ b/browser/modules/E10SUtils.jsm
@@ -23,87 +23,143 @@ function getAboutModule(aURL) {
   }
   catch (e) {
     // Either the about module isn't defined or it is broken. In either case
     // ignore it.
     return null;
   }
 }
 
+const NOT_REMOTE = null;
+
+// These must match any similar ones in ContentParent.h.
+const WEB_REMOTE_TYPE = "web";
+const FILE_REMOTE_TYPE = "file";
+const DEFAULT_REMOTE_TYPE = WEB_REMOTE_TYPE;
+
+function validatedWebRemoteType(aPreferredRemoteType) {
+  return aPreferredRemoteType && aPreferredRemoteType.startsWith(WEB_REMOTE_TYPE)
+         ? aPreferredRemoteType : WEB_REMOTE_TYPE;
+}
+
 this.E10SUtils = {
+  DEFAULT_REMOTE_TYPE,
+  NOT_REMOTE,
+  WEB_REMOTE_TYPE,
+  FILE_REMOTE_TYPE,
+
   canLoadURIInProcess: function(aURL, aProcess) {
+    let remoteType = aProcess == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT
+                     ? DEFAULT_REMOTE_TYPE : NOT_REMOTE;
+    return remoteType == this.getRemoteTypeForURI(aURL, true, remoteType);
+  },
+
+  getRemoteTypeForURI: function(aURL, aMultiProcess,
+                                aPreferredRemoteType = DEFAULT_REMOTE_TYPE) {
+    if (!aMultiProcess) {
+      return NOT_REMOTE;
+    }
+
     // loadURI in browser.xml treats null as about:blank
-    if (!aURL)
+    if (!aURL) {
       aURL = "about:blank";
+    }
 
     // Javascript urls can load in any process, they apply to the current document
-    if (aURL.startsWith("javascript:"))
-      return true;
+    if (aURL.startsWith("javascript:")) {
+      return aPreferredRemoteType;
+    }
 
-    let processIsRemote = aProcess == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT;
+    // We need data: URIs to load in any remote process, because some of our
+    // tests rely on this.
+    if (aURL.startsWith("data:")) {
+      return aPreferredRemoteType == NOT_REMOTE ? DEFAULT_REMOTE_TYPE
+                                                : aPreferredRemoteType;
+    }
 
-    let canLoadRemote = true;
-    let mustLoadRemote = true;
+    if (aURL.startsWith("file:")) {
+      return Services.prefs.getBoolPref("browser.tabs.remote.separateFileUriProcess")
+             ? FILE_REMOTE_TYPE : DEFAULT_REMOTE_TYPE;
+    }
 
     if (aURL.startsWith("about:")) {
+      // We need to special case about:blank because it needs to load in any.
+      if (aURL == "about:blank") {
+        return aPreferredRemoteType;
+      }
+
       let url = Services.io.newURI(aURL, null, null);
       let module = getAboutModule(url);
       // If the module doesn't exist then an error page will be loading, that
-      // should be ok to load in either process
-      if (module) {
-        let flags = module.getURIFlags(url);
-        canLoadRemote = !!(flags & Ci.nsIAboutModule.URI_CAN_LOAD_IN_CHILD);
-        mustLoadRemote = !!(flags & Ci.nsIAboutModule.URI_MUST_LOAD_IN_CHILD);
+      // should be ok to load in any process
+      if (!module) {
+        return aPreferredRemoteType;
       }
+
+      let flags = module.getURIFlags(url);
+      if (flags & Ci.nsIAboutModule.URI_MUST_LOAD_IN_CHILD) {
+        return DEFAULT_REMOTE_TYPE;
+      }
+
+      if (flags & Ci.nsIAboutModule.URI_CAN_LOAD_IN_CHILD &&
+          aPreferredRemoteType != NOT_REMOTE) {
+        return DEFAULT_REMOTE_TYPE;
+      }
+
+      return NOT_REMOTE;
     }
 
     if (aURL.startsWith("chrome:")) {
       let url;
       try {
         // This can fail for invalid Chrome URIs, in which case we will end up
         // not loading anything anyway.
         url = Services.io.newURI(aURL, null, null);
       } catch (ex) {
-        canLoadRemote = true;
-        mustLoadRemote = false;
+        return aPreferredRemoteType;
       }
 
-      if (url) {
-        let chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"].
-                        getService(Ci.nsIXULChromeRegistry);
-        canLoadRemote = chromeReg.canLoadURLRemotely(url);
-        mustLoadRemote = chromeReg.mustLoadURLRemotely(url);
+      let chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"].
+                      getService(Ci.nsIXULChromeRegistry);
+      if (chromeReg.mustLoadURLRemotely(url)) {
+        return DEFAULT_REMOTE_TYPE;
       }
+
+      if (chromeReg.canLoadURLRemotely(url) &&
+          aPreferredRemoteType != NOT_REMOTE) {
+        return DEFAULT_REMOTE_TYPE;
+      }
+
+      return NOT_REMOTE;
     }
 
     if (aURL.startsWith("moz-extension:")) {
-      canLoadRemote = useRemoteWebExtensions;
-      mustLoadRemote = useRemoteWebExtensions;
+      return useRemoteWebExtensions ? WEB_REMOTE_TYPE : NOT_REMOTE;
     }
 
     if (aURL.startsWith("view-source:")) {
-      return this.canLoadURIInProcess(aURL.substr("view-source:".length), aProcess);
+      return this.getRemoteTypeForURI(aURL.substr("view-source:".length),
+                                      aMultiProcess, aPreferredRemoteType);
     }
 
-    if (mustLoadRemote)
-      return processIsRemote;
+    return validatedWebRemoteType(aPreferredRemoteType);
+  },
 
-    if (!canLoadRemote && processIsRemote)
-      return false;
-
-    return true;
+  shouldLoadURIInThisProcess: function(aURI) {
+    let remoteType = Services.appinfo.remoteType;
+    return remoteType == this.getRemoteTypeForURI(aURI.spec, true, remoteType);
   },
 
   shouldLoadURI: function(aDocShell, aURI, aReferrer) {
     // Inner frames should always load in the current process
     if (aDocShell.QueryInterface(Ci.nsIDocShellTreeItem).sameTypeParent)
       return true;
 
     // If the URI can be loaded in the current process then continue
-    return this.canLoadURIInProcess(aURI.spec, Services.appinfo.processType);
+    return this.shouldLoadURIInThisProcess(aURI);
   },
 
   redirectLoad: function(aDocShell, aURI, aReferrer, aFreshProcess) {
     // Retarget the load to the correct process
     let messageManager = aDocShell.QueryInterface(Ci.nsIInterfaceRequestor)
                                   .getInterface(Ci.nsIContentFrameMessageManager);
     let sessionHistory = aDocShell.getInterface(Ci.nsIWebNavigation).sessionHistory;
 
--- a/devtools/client/inspector/rules/test/browser_rules_edit-property-increments.js
+++ b/devtools/client/inspector/rules/test/browser_rules_edit-property-increments.js
@@ -2,16 +2,19 @@
 /* Any copyright is dedicated to the Public Domain.
  http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 // Test that increasing/decreasing values in rule view using
 // arrow keys works correctly.
 
+// Bug 1275446 - This test happen to hit the default timeout on linux32
+requestLongerTimeout(2);
+
 const TEST_URI = `
   <style>
     #test {
       margin-top: 0px;
       padding-top: 0px;
       color: #000000;
       background-color: #000000;
       background: none;
--- a/devtools/client/inspector/test/browser_inspector_search-05.js
+++ b/devtools/client/inspector/test/browser_inspector_search-05.js
@@ -1,16 +1,18 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
 // Testing that when search results contain suggestions for nodes in other
 // frames, selecting these suggestions actually selects the right nodes.
 
+requestLongerTimeout(2);
+
 const IFRAME_SRC = "doc_inspector_search.html";
 const NESTED_IFRAME_SRC = `
   <button id="b1">Nested button</button>
   <iframe id="iframe-4" src="${URL_ROOT + IFRAME_SRC}"></iframe>
 `;
 const TEST_URL = `
   <iframe id="iframe-1" src="${URL_ROOT + IFRAME_SRC}"></iframe>
   <iframe id="iframe-2" src="${URL_ROOT + IFRAME_SRC}"></iframe>
--- a/devtools/client/responsive.html/browser/swap.js
+++ b/devtools/client/responsive.html/browser/swap.js
@@ -134,17 +134,18 @@ function swapToInnerBrowser({ tab, conta
       //    `gBrowser._swapBrowserDocShells`.
       dispatchDevToolsBrowserSwap(innerBrowser, contentBrowser);
       gBrowser._swapBrowserDocShells(contentTab, innerBrowser);
       innerBrowser = null;
 
       // 5. Force the original browser tab to be remote since web content is
       //    loaded in the child process, and we're about to swap the content
       //    into this tab.
-      gBrowser.updateBrowserRemoteness(tab.linkedBrowser, true);
+      gBrowser.updateBrowserRemoteness(tab.linkedBrowser, true,
+                                       contentBrowser.remoteType);
 
       // 6. Swap the content into the original browser tab and close the
       //    temporary tab used to hold the content via
       //    `swapBrowsersAndCloseOther`.
       dispatchDevToolsBrowserSwap(contentBrowser, tab.linkedBrowser);
       gBrowser.swapBrowsersAndCloseOther(tab, contentTab);
       gBrowser = null;
 
@@ -207,16 +208,25 @@ function addXULBrowserDecorations(browse
     Object.defineProperty(browser, "isRemoteBrowser", {
       get() {
         return this.getAttribute("remote") == "true";
       },
       configurable: true,
       enumerable: true,
     });
   }
+  if (browser.remoteType == undefined) {
+    Object.defineProperty(browser, "remoteType", {
+      get() {
+        return this.getAttribute("remoteType");
+      },
+      configurable: true,
+      enumerable: true,
+    });
+  }
   if (browser.messageManager == undefined) {
     Object.defineProperty(browser, "messageManager", {
       get() {
         return this.frameLoader.messageManager;
       },
       configurable: true,
       enumerable: true,
     });
--- a/devtools/client/responsive.html/browser/tunnel.js
+++ b/devtools/client/responsive.html/browser/tunnel.js
@@ -138,16 +138,17 @@ function tunnelToInnerBrowser(outer, inn
       mmTunnel = new MessageManagerTunnel(outer, inner);
 
       // We are tunneling to an inner browser with a specific remoteness, so it is simpler
       // for the logic of the browser UI to assume this tab has taken on that remoteness,
       // even though it's not true.  Since the actions the browser UI performs are sent
       // down to the inner browser by this tunnel, the tab's remoteness effectively is the
       // remoteness of the inner browser.
       outer.setAttribute("remote", "true");
+      outer.setAttribute("remoteType", inner.remoteType);
 
       // Clear out any cached state that references the current non-remote XBL binding,
       // such as form fill controllers.  Otherwise they will remain in place and leak the
       // outer docshell.
       outer.destroy();
       // The XBL binding for remote browsers uses the message manager for many actions in
       // the UI and that works well here, since it gives us one main thing we need to
       // route to the inner browser (the messages), instead of having to tweak many
@@ -264,16 +265,17 @@ function tunnelToInnerBrowser(outer, inn
       outer.webProgress.removeProgressListener(filteredProgressListener);
 
       // Reset the XBL binding back to the default.
       outer.destroy();
       outer.style.MozBinding = "";
 
       // Reset @remote since this is now back to a regular, non-remote browser
       outer.setAttribute("remote", "false");
+      outer.removeAttribute("remoteType");
 
       // Delete browser window properties exposed on content's owner global
       delete inner.ownerGlobal.PopupNotifications;
       delete inner.ownerGlobal.whereToOpenLink;
 
       // Remove mozbrowser event handlers
       inner.removeEventListener("mozbrowseropenwindow", this);
 
--- a/devtools/client/responsive.html/components/browser.js
+++ b/devtools/client/responsive.html/components/browser.js
@@ -122,27 +122,28 @@ module.exports = createClass({
       {
         ref: "browserContainer",
         className: "browser-container",
 
         /**
          * React uses a whitelist for attributes, so we need some way to set
          * attributes it does not know about, such as @mozbrowser.  If this were
          * the only issue, we could use componentDidMount or ref: node => {} to
-         * set the atttibutes. In the case of @remote, the attribute must be set
-         * before the element is added to the DOM to have any effect, which we
-         * are able to do with this approach.
+         * set the atttibutes. In the case of @remote and @remoteType, the
+         * attribute must be set before the element is added to the DOM to have
+         * any effect, which we are able to do with this approach.
          *
          * @noisolation and @allowfullscreen are needed so that these frames
          * have the same access to browser features as regular browser tabs.
          * The `swapFrameLoaders` platform API we use compares such features
          * before allowing the swap to proceed.
          */
         dangerouslySetInnerHTML: {
-          __html: `<iframe class="browser" mozbrowser="true" remote="true"
+          __html: `<iframe class="browser" mozbrowser="true"
+                           remote="true" remoteType="web"
                            noisolation="true" allowfullscreen="true"
                            src="${location}" width="100%" height="100%">
                    </iframe>`
         }
       }
     );
   },
 
--- a/devtools/client/themes/markup.css
+++ b/devtools/client/themes/markup.css
@@ -134,29 +134,36 @@ ul.children + .tag-line::before {
 .tag-line {
   min-height: 1.4em;
   line-height: 1.4em;
   position: relative;
   cursor: default;
   padding-left: 2px;
 }
 
-.tag-line[selected] + .children {
+.tag-line[selected] + .children,
+.tag-line[selected] ~ .tag-line {
   background-image: linear-gradient(to top, var(--markup-outline), var(--markup-outline));
+  background-position-x: -6px;
   background-repeat: no-repeat;
-  /* Shorten the outline height by 4px to account for the 2px top padding and
-   * allow for a 2px bottom padding */
-  background-size: 1.5px calc(100% - 4px);
-  /* Align the outline to under the expander arrow and provide 2px top
-   * padding */
-  background-position: -6px 2px;
+  background-size: 1.5px 100%;
   border-left: 6px solid transparent;
   margin-left: -6px;
 }
 
+.tag-line[selected] + .children {
+  background-position-y: 2px;
+}
+
+.tag-line[selected] ~ .tag-line {
+  background-position-y: -2px;
+  /* Unset transition-property to prevent the markup outline from horizontal shifting */
+  transition-property: none;
+}
+
 .html-editor-container {
   position: relative;
   min-height: 200px;
 }
 
 /* This extra element placed in each tag is positioned absolutely to cover the
  * whole tag line and is used for background styling (when a selection is made
  * or when the tag is flashing) */
--- a/devtools/client/webconsole/test/browser_webconsole_bug_595223_file_uri.js
+++ b/devtools/client/webconsole/test/browser_webconsole_bug_595223_file_uri.js
@@ -2,32 +2,33 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 const PREF = "devtools.webconsole.persistlog";
 const TEST_FILE = "test-network.html";
-const TEST_URI = "data:text/html;charset=utf8,<p>test file URI";
 
 var hud;
 
 add_task(function* () {
   Services.prefs.setBoolPref(PREF, true);
 
   let jar = getJar(getRootDirectory(gTestPath));
   let dir = jar ?
             extractJarToTmp(jar) :
             getChromeDir(getResolvedURI(gTestPath));
 
   dir.append(TEST_FILE);
   let uri = Services.io.newFileURI(dir);
 
-  let { browser } = yield loadTab(TEST_URI);
+  // We need a file remote type to make sure we don't switch processes when we
+  // load the file:// URI.
+  let { browser } = yield loadTab("about:blank", E10SUtils.FILE_REMOTE_TYPE);
 
   hud = yield openConsole();
   hud.jsterm.clearOutput();
 
   let loaded = loadBrowser(browser);
   BrowserTestUtils.loadURI(gBrowser.selectedBrowser, uri.spec);
   yield loaded;
 
--- a/devtools/client/webconsole/test/head.js
+++ b/devtools/client/webconsole/test/head.js
@@ -41,20 +41,20 @@ const WEBCONSOLE_STRINGS_URI = "devtools
 var WCUL10n = new WebConsoleUtils.L10n(WEBCONSOLE_STRINGS_URI);
 
 const DOCS_GA_PARAMS = "?utm_source=mozilla" +
                        "&utm_medium=firefox-console-errors" +
                        "&utm_campaign=default";
 
 flags.testing = true;
 
-function loadTab(url) {
+function loadTab(url, preferredRemoteType) {
   let deferred = promise.defer();
 
-  let tab = gBrowser.selectedTab = gBrowser.addTab(url);
+  let tab = gBrowser.selectedTab = gBrowser.addTab(url, { preferredRemoteType });
   let browser = gBrowser.getBrowserForTab(tab);
 
   browser.addEventListener("load", function onLoad() {
     browser.removeEventListener("load", onLoad, true);
     deferred.resolve({tab: tab, browser: browser});
   }, true);
 
   return deferred.promise;
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -1642,19 +1642,19 @@ Navigator::GetVRDisplays(ErrorResult& aR
   win->NotifyVREventListenerAdded();
 
   nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
   RefPtr<Promise> p = Promise::Create(go, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
-  // We pass ourself to RefreshVRDisplays, so NotifyVRDisplaysUpdated will
+  // We pass mWindow's id to RefreshVRDisplays, so NotifyVRDisplaysUpdated will
   // be called asynchronously, resolving the promises in mVRGetDisplaysPromises.
-  if (!VRDisplay::RefreshVRDisplays(this)) {
+  if (!VRDisplay::RefreshVRDisplays(win->WindowID())) {
     p->MaybeReject(NS_ERROR_FAILURE);
     return p.forget();
   }
 
   mVRGetDisplaysPromises.AppendElement(p);
   return p.forget();
 }
 
--- a/dom/base/nsFrameLoader.h
+++ b/dom/base/nsFrameLoader.h
@@ -42,22 +42,23 @@ namespace mozilla {
 class DocShellOriginAttributes;
 
 namespace dom {
 class ContentParent;
 class PBrowserParent;
 class Promise;
 class TabParent;
 class MutableTabContext;
-} // namespace dom
 
 namespace ipc {
 class StructuredCloneData;
 } // namespace ipc
 
+} // namespace dom
+
 namespace layout {
 class RenderFrameParent;
 } // namespace layout
 } // namespace mozilla
 
 #if defined(MOZ_WIDGET_GTK)
 typedef struct _GtkWidget GtkWidget;
 #endif
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -2210,16 +2210,17 @@ GK_ATOM(serif, "serif")
 GK_ATOM(sans_serif, "sans-serif")
 GK_ATOM(cursive, "cursive")
 GK_ATOM(fantasy, "fantasy")
 GK_ATOM(monospace, "monospace")
 
 // IPC stuff
 GK_ATOM(Remote, "remote")
 GK_ATOM(RemoteId, "_remote_id")
+GK_ATOM(RemoteType, "remoteType")
 GK_ATOM(DisplayPort, "_displayport")
 GK_ATOM(DisplayPortMargins, "_displayportmargins")
 GK_ATOM(DisplayPortBase, "_displayportbase")
 GK_ATOM(AsyncScrollLayerCreationFailed, "_asyncscrolllayercreationfailed")
 GK_ATOM(forcemessagemanager, "forcemessagemanager")
 
 // Names for system metrics
 GK_ATOM(color_picker_available, "color-picker-available")
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -1362,33 +1362,47 @@ bool CanvasRenderingContext2D::SwitchRen
 
   // Return the old target to the buffer provider.
   // We need to do this before calling EnsureTarget.
   ReturnTarget();
   mTarget = nullptr;
   mBufferProvider = nullptr;
   mResetLayer = true;
 
-  // Borrowing the snapshot must be done after ReturnTarget.
-  RefPtr<SourceSurface> snapshot = oldBufferProvider->BorrowSnapshot();
-
   // Recreate mTarget using the new rendering mode
   RenderingMode attemptedMode = EnsureTarget(nullptr, aRenderingMode);
+
   if (!IsTargetValid()) {
-    oldBufferProvider->ReturnSnapshot(snapshot.forget());
     return false;
   }
 
+  if (oldBufferProvider && mTarget) {
+    CopyBufferProvider(*oldBufferProvider, *mTarget, IntRect(0, 0, mWidth, mHeight));
+  }
+
   // We succeeded, so update mRenderingMode to reflect reality
   mRenderingMode = attemptedMode;
 
-  // Restore the content from the old DrawTarget
-  // Clips and transform were already restored in EnsureTarget.
-  mTarget->CopySurface(snapshot, IntRect(0, 0, mWidth, mHeight), IntPoint());
-  oldBufferProvider->ReturnSnapshot(snapshot.forget());
+  return true;
+}
+
+bool
+CanvasRenderingContext2D::CopyBufferProvider(PersistentBufferProvider& aOld,
+                                             DrawTarget& aTarget,
+                                             IntRect aCopyRect)
+{
+  // Borrowing the snapshot must be done after ReturnTarget.
+  RefPtr<SourceSurface> snapshot = aOld.BorrowSnapshot();
+
+  if (!snapshot) {
+    return false;
+  }
+
+  aTarget.CopySurface(snapshot, aCopyRect, IntPoint());
+  aOld.ReturnSnapshot(snapshot.forget());
   return true;
 }
 
 void CanvasRenderingContext2D::Demote()
 {
   if (SwitchRenderingMode(RenderingMode::SoftwareBackendMode)) {
     RemoveDemotableContext(this);
   }
@@ -1433,22 +1447,25 @@ CanvasRenderingContext2D::AddDemotableCo
 void
 CanvasRenderingContext2D::RemoveDemotableContext(CanvasRenderingContext2D* aContext)
 {
   std::vector<CanvasRenderingContext2D*>::iterator iter = std::find(DemotableContexts().begin(), DemotableContexts().end(), aContext);
   if (iter != DemotableContexts().end())
     DemotableContexts().erase(iter);
 }
 
+#define MIN_SKIA_GL_DIMENSION 16
+
 bool
 CanvasRenderingContext2D::CheckSizeForSkiaGL(IntSize aSize) {
   MOZ_ASSERT(NS_IsMainThread());
 
   int minsize = Preferences::GetInt("gfx.canvas.min-size-for-skia-gl", 128);
-  if (aSize.width < minsize || aSize.height < minsize) {
+  if (aSize.width < MIN_SKIA_GL_DIMENSION || aSize.height < MIN_SKIA_GL_DIMENSION ||
+      (aSize.width * aSize.height < minsize * minsize)) {
     return false;
   }
 
   // Maximum pref allows 3 different options:
   //  0   means unlimited size
   //  > 0 means use value as an absolute threshold
   //  < 0 means use the number of screen pixels as a threshold
   int maxsize = Preferences::GetInt("gfx.canvas.max-size-for-skia-gl", 0);
@@ -1622,35 +1639,52 @@ CanvasRenderingContext2D::EnsureTarget(c
       !TrySkiaGLTarget(newTarget, newProvider)) {
     // Fall back to software.
     mode = RenderingMode::SoftwareBackendMode;
   }
 
   if (mode == RenderingMode::SoftwareBackendMode &&
       !TrySharedTarget(newTarget, newProvider) &&
       !TryBasicTarget(newTarget, newProvider)) {
+
+    gfxCriticalError(
+      CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(GetSize()))
+    ) << "Failed borrow shared and basic targets.";
+
     SetErrorState();
     return mode;
   }
 
+
   MOZ_ASSERT(newTarget);
   MOZ_ASSERT(newProvider);
 
+  bool needsClear = !canDiscardContent;
+  if (newTarget->GetBackendType() == gfx::BackendType::SKIA) {
+    // Skia expects the unused X channel to contains 0xFF even for opaque operations
+    // so we can't skip clearing in that case, even if we are going to cover the
+    // entire canvas in the next drawing operation.
+    newTarget->ClearRect(canvasRect);
+    needsClear = false;
+  }
+
+  // Try to copy data from the previous buffer provider if there is one.
+  if (!canDiscardContent && mBufferProvider && CopyBufferProvider(*mBufferProvider, *newTarget, persistedRect)) {
+    needsClear = false;
+  }
+
+  if (needsClear) {
+    newTarget->ClearRect(canvasRect);
+  }
+
   mTarget = newTarget.forget();
   mBufferProvider = newProvider.forget();
 
   RegisterAllocation();
 
-  // Skia expects the unused X channel to contains 0 even for opaque operations
-  // so we can't skip clearing in that case, even if we are going to cover the
-  // entire canvas in the next drawing operation.
-  if (!canDiscardContent || mTarget->GetBackendType() == gfx::BackendType::SKIA) {
-    mTarget->ClearRect(canvasRect);
-  }
-
   RestoreClipsAndTransformToTarget();
 
   // Force a full layer transaction since we didn't have a layer before
   // and now we might need one.
   if (mCanvasElement) {
     mCanvasElement->InvalidateCanvas();
   }
   // Calling Redraw() tells our invalidation machinery that the entire
@@ -1779,16 +1813,22 @@ CanvasRenderingContext2D::TrySharedTarge
 {
   aOutDT = nullptr;
   aOutProvider = nullptr;
 
   if (!mCanvasElement || !mCanvasElement->OwnerDoc()) {
     return false;
   }
 
+  if (mBufferProvider && mBufferProvider->GetType() == LayersBackend::LAYERS_CLIENT) {
+    // we are already using a shared buffer provider, we are allocating a new one
+    // because the current one failed so let's just fall back to the basic provider.
+    return false;
+  }
+
   RefPtr<LayerManager> layerManager = LayerManagerFromCanvasElement(mCanvasElement);
 
   if (!layerManager) {
     return false;
   }
 
   aOutProvider = layerManager->CreatePersistentBufferProvider(GetSize(), GetSurfaceFormat());
 
@@ -5933,17 +5973,17 @@ CanvasRenderingContext2D::GetCanvasLayer
     // be accessible.
     EnsureTarget();
   }
 
   // Don't call EnsureTarget() ... if there isn't already a surface, then
   // we have nothing to paint and there is no need to create a surface just
   // to paint nothing. Also, EnsureTarget() can cause creation of a persistent
   // layer manager which must NOT happen during a paint.
-  if ((!mBufferProvider && !mTarget) || !IsTargetValid()) {
+  if (!mBufferProvider && !IsTargetValid()) {
     // No DidTransactionCallback will be received, so mark the context clean
     // now so future invalidations will be dispatched.
     MarkContextClean();
     return nullptr;
   }
 
   if (!mResetLayer && aOldLayer) {
     CanvasRenderingContext2DUserData* userData =
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -547,16 +547,20 @@ protected:
                              uint32_t aWidth, uint32_t aHeight,
                              JSObject** aRetval);
 
   nsresult PutImageData_explicit(int32_t aX, int32_t aY, uint32_t aW, uint32_t aH,
                                  dom::Uint8ClampedArray* aArray,
                                  bool aHasDirtyRect, int32_t aDirtyX, int32_t aDirtyY,
                                  int32_t aDirtyWidth, int32_t aDirtyHeight);
 
+  bool CopyBufferProvider(layers::PersistentBufferProvider& aOld,
+                          gfx::DrawTarget& aTarget,
+                          gfx::IntRect aCopyRect);
+
   /**
    * Internal method to complete initialisation, expects mTarget to have been set
    */
   nsresult Initialize(int32_t aWidth, int32_t aHeight);
 
   nsresult InitializeWithTarget(mozilla::gfx::DrawTarget* aSurface,
                                 int32_t aWidth, int32_t aHeight);
 
@@ -677,17 +681,17 @@ protected:
    * rendering.
    */
   void ReturnTarget(bool aForceReset = false);
 
   /**
    * Check if the target is valid after calling EnsureTarget.
    */
   bool IsTargetValid() const {
-    return (sErrorTarget == nullptr || mTarget != sErrorTarget) && (mBufferProvider != nullptr || mTarget);
+    return mTarget && mTarget != sErrorTarget;
   }
 
   /**
     * Returns the surface format this canvas should be allocated using. Takes
     * into account mOpaque, platform requirements, etc.
     */
   mozilla::gfx::SurfaceFormat GetSurfaceFormat() const;
 
--- a/dom/canvas/WebGLContextGL.cpp
+++ b/dom/canvas/WebGLContextGL.cpp
@@ -1182,108 +1182,22 @@ WebGLContext::PixelStorei(GLenum pname, 
 
     default:
         break;
     }
 
     ErrorInvalidEnumInfo("pixelStorei: parameter", pname);
 }
 
-static bool
-IsNeedsANGLEWorkAround(const webgl::FormatInfo* format)
-{
-    switch (format->effectiveFormat) {
-    case webgl::EffectiveFormat::RGB16F:
-    case webgl::EffectiveFormat::RGBA16F:
-        return true;
-
-    default:
-        return false;
-    }
-}
-
 bool
 WebGLContext::DoReadPixelsAndConvert(const webgl::FormatInfo* srcFormat, GLint x, GLint y,
                                      GLsizei width, GLsizei height, GLenum format,
                                      GLenum destType, void* dest, uint32_t destSize,
                                      uint32_t rowStride)
 {
-    if (gl->WorkAroundDriverBugs() &&
-        gl->IsANGLE() &&
-        gl->Version() < 300 && // ANGLE ES2 doesn't support HALF_FLOAT reads properly.
-        IsNeedsANGLEWorkAround(srcFormat))
-    {
-        MOZ_RELEASE_ASSERT(!IsWebGL2()); // No SKIP_PIXELS, etc.
-        MOZ_ASSERT(!mBoundPixelPackBuffer); // Let's be real clear.
-
-        // You'd think ANGLE would want HALF_FLOAT_OES, but it rejects that.
-        const GLenum readType = LOCAL_GL_HALF_FLOAT;
-
-        const char funcName[] = "readPixels";
-        const auto readBytesPerPixel = webgl::BytesPerPixel({format, readType});
-        const auto destBytesPerPixel = webgl::BytesPerPixel({format, destType});
-
-        uint32_t readStride;
-        uint32_t readByteCount;
-        uint32_t destStride;
-        uint32_t destByteCount;
-        if (!ValidatePackSize(funcName, width, height, readBytesPerPixel, &readStride,
-                              &readByteCount) ||
-            !ValidatePackSize(funcName, width, height, destBytesPerPixel, &destStride,
-                              &destByteCount))
-        {
-            ErrorOutOfMemory("readPixels: Overflow calculating sizes for conversion.");
-            return false;
-        }
-
-        UniqueBuffer readBuffer = malloc(readByteCount);
-        if (!readBuffer) {
-            ErrorOutOfMemory("readPixels: Failed to alloc temp buffer for conversion.");
-            return false;
-        }
-
-        gl::GLContext::LocalErrorScope errorScope(*gl);
-
-        gl->fReadPixels(x, y, width, height, format, readType, readBuffer.get());
-
-        const GLenum error = errorScope.GetError();
-        if (error == LOCAL_GL_OUT_OF_MEMORY) {
-            ErrorOutOfMemory("readPixels: Driver ran out of memory.");
-            return false;
-        }
-
-        if (error) {
-            MOZ_RELEASE_ASSERT(false, "GFX: Unexpected driver error.");
-            return false;
-        }
-
-        size_t channelsPerRow = std::min(readStride / sizeof(uint16_t),
-                                         destStride / sizeof(float));
-
-        const uint8_t* srcRow = (uint8_t*)readBuffer.get();
-        uint8_t* dstRow = (uint8_t*)dest;
-
-        for (size_t j = 0; j < (size_t)height; j++) {
-            auto src = (const uint16_t*)srcRow;
-            auto dst = (float*)dstRow;
-
-            const auto srcEnd = src + channelsPerRow;
-            while (src != srcEnd) {
-                *dst = unpackFromFloat16(*src);
-                ++src;
-                ++dst;
-            }
-
-            srcRow += readStride;
-            dstRow += destStride;
-        }
-
-        return true;
-    }
-
     // On at least Win+NV, we'll get PBO errors if we don't have at least
     // `rowStride * height` bytes available to read into.
     const auto naiveBytesNeeded = CheckedUint32(rowStride) * height;
     const bool isDangerCloseToEdge = (!naiveBytesNeeded.isValid() ||
                                       naiveBytesNeeded.value() > destSize);
     const bool useParanoidHandling = (gl->WorkAroundDriverBugs() &&
                                       isDangerCloseToEdge &&
                                       mBoundPixelPackBuffer);
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -650,16 +650,53 @@ ContentChild::ProvideWindow(mozIDOMWindo
                             mozIDOMWindowProxy** aReturn)
 {
   return ProvideWindowCommon(nullptr, aParent, false, aChromeFlags,
                              aCalledFromJS, aPositionSpecified,
                              aSizeSpecified, aURI, aName, aFeatures,
                              aForceNoOpener, aWindowIsNew, aReturn);
 }
 
+static nsresult
+GetWindowParamsFromParent(mozIDOMWindowProxy* aParent,
+                          nsACString& aBaseURIString, float* aFullZoom,
+                          DocShellOriginAttributes& aOriginAttributes)
+{
+  *aFullZoom = 1.0f;
+  auto* opener = nsPIDOMWindowOuter::From(aParent);
+  if (!opener) {
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsIDocument> doc = opener->GetDoc();
+  nsCOMPtr<nsIURI> baseURI = doc->GetDocBaseURI();
+  if (!baseURI) {
+    NS_ERROR("nsIDocument didn't return a base URI");
+    return NS_ERROR_FAILURE;
+  }
+
+  baseURI->GetSpec(aBaseURIString);
+
+  RefPtr<nsDocShell> openerDocShell =
+    static_cast<nsDocShell*>(opener->GetDocShell());
+  if (!openerDocShell) {
+    return NS_OK;
+  }
+
+  aOriginAttributes = openerDocShell->GetOriginAttributes();
+
+  nsCOMPtr<nsIContentViewer> cv;
+  nsresult rv = openerDocShell->GetContentViewer(getter_AddRefs(cv));
+  if (NS_SUCCEEDED(rv) && cv) {
+    cv->GetFullZoom(aFullZoom);
+  }
+
+  return NS_OK;
+}
+
 nsresult
 ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
                                   mozIDOMWindowProxy* aParent,
                                   bool aIframeMoz,
                                   uint32_t aChromeFlags,
                                   bool aCalledFromJS,
                                   bool aPositionSpecified,
                                   bool aSizeSpecified,
@@ -669,18 +706,53 @@ ContentChild::ProvideWindowCommon(TabChi
                                   bool aForceNoOpener,
                                   bool* aWindowIsNew,
                                   mozIDOMWindowProxy** aReturn)
 {
   *aReturn = nullptr;
 
   nsAutoPtr<IPCTabContext> ipcContext;
   TabId openerTabId = TabId(0);
-
+  nsAutoCString features(aFeatures);
+
+  nsresult rv;
   if (aTabOpener) {
+    // Check to see if the target URI can be loaded in this process.
+    // If not create and load it in an unrelated tab/window.
+    nsCOMPtr<nsIWebBrowserChrome3> browserChrome3;
+    rv = aTabOpener->GetWebBrowserChrome(getter_AddRefs(browserChrome3));
+    if (NS_SUCCEEDED(rv) && browserChrome3) {
+      bool shouldLoad;
+      rv = browserChrome3->ShouldLoadURIInThisProcess(aURI, &shouldLoad);
+      if (NS_SUCCEEDED(rv) && !shouldLoad) {
+        nsAutoCString baseURIString;
+        float fullZoom;
+        DocShellOriginAttributes originAttributes;
+        rv = GetWindowParamsFromParent(aParent, baseURIString, &fullZoom,
+                                       originAttributes);
+        if (NS_WARN_IF(NS_FAILED(rv))) {
+          return rv;
+        }
+
+        URIParams uriToLoad;
+        SerializeURI(aURI, uriToLoad);
+        Unused << SendCreateWindowInDifferentProcess(aTabOpener, aChromeFlags,
+                                                     aCalledFromJS,
+                                                     aPositionSpecified,
+                                                     aSizeSpecified,
+                                                     uriToLoad, features,
+                                                     baseURIString,
+                                                     originAttributes, fullZoom);
+
+        // We return NS_ERROR_ABORT, so that the caller knows that we've abandoned
+        // the window open as far as it is concerned.
+        return NS_ERROR_ABORT;
+      }
+    }
+
     PopupIPCTabContext context;
     openerTabId = aTabOpener->GetTabId();
     context.opener() = openerTabId;
     context.isMozBrowserElement() = aTabOpener->IsMozBrowserElement();
     ipcContext = new IPCTabContext(context);
   } else {
     // It's possible to not have a TabChild opener in the case
     // of ServiceWorker::OpenWindow.
@@ -709,17 +781,16 @@ ContentChild::ProvideWindowCommon(TabChi
 
   Unused << SendPBrowserConstructor(
     // We release this ref in DeallocPBrowserChild
     RefPtr<TabChild>(newChild).forget().take(),
     tabId, *ipcContext, aChromeFlags,
     GetID(), IsForBrowser());
 
   nsString name(aName);
-  nsAutoCString features(aFeatures);
   nsTArray<FrameScriptInfo> frameScripts;
   nsCString urlToLoad;
 
   PRenderFrameChild* renderFrame = newChild->SendPRenderFrameConstructor();
   TextureFactoryIdentifier textureFactoryIdentifier;
   uint64_t layersId = 0;
 
   if (aIframeMoz) {
@@ -735,50 +806,30 @@ ContentChild::ProvideWindowCommon(TabChi
     }
 
     newChild->SendBrowserFrameOpenWindow(aTabOpener, renderFrame, NS_ConvertUTF8toUTF16(url),
                                          name, NS_ConvertUTF8toUTF16(features),
                                          aWindowIsNew, &textureFactoryIdentifier,
                                          &layersId);
   } else {
     nsAutoCString baseURIString;
-    if (aTabOpener) {
-      auto* opener = nsPIDOMWindowOuter::From(aParent);
-      nsCOMPtr<nsIDocument> doc = opener->GetDoc();
-      nsCOMPtr<nsIURI> baseURI = doc->GetDocBaseURI();
-      if (!baseURI) {
-        NS_ERROR("nsIDocument didn't return a base URI");
-        return NS_ERROR_FAILURE;
-      }
-
-      baseURI->GetSpec(baseURIString);
+    float fullZoom;
+    DocShellOriginAttributes originAttributes;
+    rv = GetWindowParamsFromParent(aParent, baseURIString, &fullZoom,
+                                   originAttributes);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
     }
 
-    auto* opener = nsPIDOMWindowOuter::From(aParent);
-    nsIDocShell* openerShell;
-    RefPtr<nsDocShell> openerDocShell;
-    float fullZoom = 1.0f;
-    if (opener && (openerShell = opener->GetDocShell())) {
-      openerDocShell = static_cast<nsDocShell*>(openerShell);
-      nsCOMPtr<nsIContentViewer> cv;
-      openerDocShell->GetContentViewer(getter_AddRefs(cv));
-      if (cv) {
-        cv->GetFullZoom(&fullZoom);
-      }
-    }
-
-    nsresult rv;
     if (!SendCreateWindow(aTabOpener, newChild, renderFrame,
                           aChromeFlags, aCalledFromJS, aPositionSpecified,
                           aSizeSpecified,
                           features,
                           baseURIString,
-                          openerDocShell
-                            ? openerDocShell->GetOriginAttributes()
-                            : DocShellOriginAttributes(),
+                          originAttributes,
                           fullZoom,
                           &rv,
                           aWindowIsNew,
                           &frameScripts,
                           &urlToLoad,
                           &textureFactoryIdentifier,
                           &layersId)) {
       PRenderFrameChild::Send__delete__(renderFrame);
@@ -2374,16 +2425,31 @@ ContentChild::RecvAppInfo(const nsCStrin
   mAppInfo.UAName.Assign(UAName);
   mAppInfo.ID.Assign(ID);
   mAppInfo.vendor.Assign(vendor);
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
+ContentChild::RecvRemoteType(const nsString& aRemoteType)
+{
+  MOZ_ASSERT(DOMStringIsNull(mRemoteType));
+
+  mRemoteType.Assign(aRemoteType);
+  return IPC_OK();
+}
+
+const nsAString&
+ContentChild::GetRemoteType() const
+{
+  return mRemoteType;
+}
+
+mozilla::ipc::IPCResult
 ContentChild::RecvInitServiceWorkers(const ServiceWorkerConfiguration& aConfig)
 {
   RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
   MOZ_ASSERT(swm);
   swm->LoadRegistrations(aConfig.serviceWorkerRegistrations());
   return IPC_OK();
 }
 
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -420,16 +420,20 @@ public:
 
   virtual mozilla::ipc::IPCResult RecvGarbageCollect() override;
   virtual mozilla::ipc::IPCResult RecvCycleCollect() override;
 
   virtual mozilla::ipc::IPCResult RecvAppInfo(const nsCString& version, const nsCString& buildID,
                                               const nsCString& name, const nsCString& UAName,
                                               const nsCString& ID, const nsCString& vendor) override;
 
+  virtual mozilla::ipc::IPCResult RecvRemoteType(const nsString& aRemoteType) override;
+
+  const nsAString& GetRemoteType() const;
+
   virtual mozilla::ipc::IPCResult
   RecvInitServiceWorkers(const ServiceWorkerConfiguration& aConfig) override;
 
   virtual mozilla::ipc::IPCResult
   RecvInitBlobURLs(nsTArray<BlobURLRegistrationData>&& aRegistations) override;
 
   virtual mozilla::ipc::IPCResult RecvLastPrivateDocShellDestroyed() override;
 
@@ -674,16 +678,17 @@ private:
    * generated by the chrome process.
    */
   uint32_t mMsaaID;
 #endif
 
   AppInfo mAppInfo;
 
   bool mIsForBrowser;
+  nsString mRemoteType = NullString();
   bool mCanOverrideProcessName;
   bool mIsAlive;
   nsString mProcessName;
 
   static ContentChild* sSingleton;
 
   nsCOMPtr<nsIDomainPolicy> mPolicy;
   nsCOMPtr<nsITimer> mForceKillTimer;
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -102,16 +102,17 @@
 #include "nsCDefaultURIFixup.h"
 #include "nsCExternalHandlerService.h"
 #include "nsCOMPtr.h"
 #include "nsChromeRegistryChrome.h"
 #include "nsConsoleMessage.h"
 #include "nsConsoleService.h"
 #include "nsContentUtils.h"
 #include "nsDebugImpl.h"
+#include "nsFrameLoader.h"
 #include "nsFrameMessageManager.h"
 #include "nsHashPropertyBag.h"
 #include "nsIAlertsService.h"
 #include "nsIClipboard.h"
 #include "nsContentPermissionHelper.h"
 #include "nsICycleCollectorListener.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIDocument.h"
@@ -492,18 +493,17 @@ ContentParentsMemoryReporter::CollectRep
     aHandleReport->Callback(/* process */ EmptyCString(), path,
                             KIND_OTHER, UNITS_COUNT,
                             numQueuedMessages, desc, aData);
   }
 
   return NS_OK;
 }
 
-nsTArray<ContentParent*>* ContentParent::sBrowserContentParents;
-nsTArray<ContentParent*>* ContentParent::sLargeAllocationContentParents;
+nsClassHashtable<nsStringHashKey, nsTArray<ContentParent*>>* ContentParent::sBrowserContentParents;
 nsTArray<ContentParent*>* ContentParent::sPrivateContent;
 StaticAutoPtr<LinkedList<ContentParent> > ContentParent::sContentParents;
 #if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX)
 UniquePtr<SandboxBrokerPolicyFactory> ContentParent::sSandboxBrokerPolicyFactory;
 #endif
 
 // This is true when subprocess launching is enabled.  This is the
 // case between StartUp() and ShutDown() or JoinAllSubprocesses().
@@ -637,39 +637,38 @@ ContentParent::JoinAllSubprocesses()
       lock.Wait();
     }
   }
 
   sCanLaunchSubprocesses = false;
 }
 
 /*static*/ already_AddRefed<ContentParent>
-ContentParent::GetNewOrUsedBrowserProcess(bool aForBrowserElement,
+ContentParent::GetNewOrUsedBrowserProcess(const nsAString& aRemoteType,
                                           ProcessPriority aPriority,
                                           ContentParent* aOpener,
                                           bool aLargeAllocationProcess)
 {
-  nsTArray<ContentParent*>* contentParents;
-  int32_t maxContentParents;
+  if (!sBrowserContentParents) {
+    sBrowserContentParents =
+      new nsClassHashtable<nsStringHashKey, nsTArray<ContentParent*>>;
+  }
 
   // Decide which pool of content parents we are going to be pulling from based
-  // on the aLargeAllocationProcess flag.
-  if (aLargeAllocationProcess) {
-    if (!sLargeAllocationContentParents) {
-      sLargeAllocationContentParents = new nsTArray<ContentParent*>();
-    }
-    contentParents = sLargeAllocationContentParents;
-
-    maxContentParents = Preferences::GetInt("dom.ipc.dedicatedProcessCount", 2);
-  } else {
-    if (!sBrowserContentParents) {
-      sBrowserContentParents = new nsTArray<ContentParent*>();
-    }
-    contentParents = sBrowserContentParents;
-
+  // on the aRemoteType and aLargeAllocationProcess flag.
+  nsAutoString contentProcessType(aLargeAllocationProcess
+                                  ? NS_LITERAL_STRING(LARGE_ALLOCATION_REMOTE_TYPE)
+                                  : aRemoteType);
+  nsTArray<ContentParent*>* contentParents =
+    sBrowserContentParents->LookupOrAdd(contentProcessType);
+
+  int32_t maxContentParents;
+  nsAutoCString processCountPref("dom.ipc.processCount.");
+  processCountPref.Append(NS_ConvertUTF16toUTF8(contentProcessType));
+  if (NS_FAILED(Preferences::GetInt(processCountPref.get(), &maxContentParents))) {
     maxContentParents = Preferences::GetInt("dom.ipc.processCount", 1);
   }
 
   if (maxContentParents < 1) {
     maxContentParents = 1;
   }
 
   if (contentParents->Length() >= uint32_t(maxContentParents)) {
@@ -682,27 +681,24 @@ ContentParent::GetNewOrUsedBrowserProces
       NS_ASSERTION(p->IsAlive(), "Non-alive contentparent in sBrowserContentParents?");
       if (p->mOpener == aOpener) {
         return p.forget();
       }
       currIdx = (currIdx + 1) % maxSelectable;
     } while (currIdx != startIdx);
   }
 
-  RefPtr<ContentParent> p = new ContentParent(aOpener,
-                                              aForBrowserElement);
+  RefPtr<ContentParent> p = new ContentParent(aOpener, contentProcessType);
 
   if (!p->LaunchSubprocess(aPriority)) {
     return nullptr;
   }
 
   p->Init();
 
-  p->mLargeAllocationProcess = aLargeAllocationProcess;
-
   contentParents->AppendElement(p);
   return p.forget();
 }
 
 /*static*/ ProcessPriority
 ContentParent::GetInitialProcessPriority(Element* aFrameElement)
 {
   // Frames with mozapptype == critical which are expecting a system message
@@ -765,17 +761,17 @@ ContentParent::RecvCreateChildProcess(co
   MaybeInvalidTabContext tc(aContext);
   if (!tc.IsValid()) {
     NS_ERROR(nsPrintfCString("Received an invalid TabContext from "
                              "the child process. (%s)",
                              tc.GetInvalidReason()).get());
     return IPC_FAIL_NO_REASON(this);
   }
 
-  cp = GetNewOrUsedBrowserProcess(/* isBrowserElement = */ true,
+  cp = GetNewOrUsedBrowserProcess(NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE),
                                   aPriority, this);
 
   if (!cp) {
     *aCpId = 0;
     *aIsForBrowser = false;
     return IPC_OK();
   }
 
@@ -958,19 +954,25 @@ ContentParent::CreateBrowser(const TabCo
   if (isInContentProcess) {
     MOZ_ASSERT(aContext.IsMozBrowserElement());
     constructorSender = CreateContentBridgeParent(aContext, initialPriority,
                                                   openerTabId, &tabId);
   } else {
     if (aOpenerContentParent) {
       constructorSender = aOpenerContentParent;
     } else {
+      nsAutoString remoteType;
+      if (!aFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::RemoteType,
+                                  remoteType)) {
+        remoteType.AssignLiteral(DEFAULT_REMOTE_TYPE);
+      }
+
       constructorSender =
-        GetNewOrUsedBrowserProcess(aContext.IsMozBrowserElement(),
-                                   initialPriority, nullptr, aFreshProcess);
+        GetNewOrUsedBrowserProcess(remoteType, initialPriority, nullptr,
+                                   aFreshProcess);
       if (!constructorSender) {
         return nullptr;
       }
     }
     tabId = AllocateTabId(openerTabId,
                           aContext.AsIPCTabContext(),
                           constructorSender->ChildID());
   }
@@ -1088,16 +1090,18 @@ ContentParent::Init()
   }
   Preferences::AddStrongObserver(this, "");
   if (obs) {
     nsAutoString cpId;
     cpId.AppendInt(static_cast<uint64_t>(this->ChildID()));
     obs->NotifyObservers(static_cast<nsIObserver*>(this), "ipc:content-created", cpId.get());
   }
 
+  Unused << SendRemoteType(mRemoteType);
+
 #ifdef ACCESSIBILITY
   // If accessibility is running in chrome process then start it in content
   // process.
   if (nsIPresShell::IsAccessibilityActive()) {
 #if defined(XP_WIN)
     if (IsVistaOrLater()) {
       Unused <<
         SendActivateA11y(a11y::AccessibleWrap::GetContentProcessIdFor(ChildID()));
@@ -1276,28 +1280,27 @@ ContentParent::ShutDownMessageManager()
   mMessageManager->Disconnect();
   mMessageManager = nullptr;
 }
 
 void
 ContentParent::MarkAsDead()
 {
   if (sBrowserContentParents) {
-    sBrowserContentParents->RemoveElement(this);
-    if (!sBrowserContentParents->Length()) {
-      delete sBrowserContentParents;
-      sBrowserContentParents = nullptr;
-    }
-  }
-
-  if (sLargeAllocationContentParents) {
-    sLargeAllocationContentParents->RemoveElement(this);
-    if (!sLargeAllocationContentParents->Length()) {
-      delete sLargeAllocationContentParents;
-      sLargeAllocationContentParents = nullptr;
+    nsTArray<ContentParent*>* contentParents =
+      sBrowserContentParents->Get(mRemoteType);
+    if (contentParents) {
+      contentParents->RemoveElement(this);
+      if (contentParents->IsEmpty()) {
+        sBrowserContentParents->Remove(mRemoteType);
+        if (sBrowserContentParents->IsEmpty()) {
+          delete sBrowserContentParents;
+          sBrowserContentParents = nullptr;
+        }
+      }
     }
   }
 
   if (sPrivateContent) {
     sPrivateContent->RemoveElement(this);
     if (!sPrivateContent->Length()) {
       delete sPrivateContent;
       sPrivateContent = nullptr;
@@ -1595,16 +1598,48 @@ ContentParent::ActorDestroy(ActorDestroy
 
   mBlobURLs.Clear();
 
 #if defined(XP_WIN32) && defined(ACCESSIBILITY)
   a11y::AccessibleWrap::ReleaseContentProcessIdFor(ChildID());
 #endif
 }
 
+bool
+ContentParent::ShouldKeepProcessAlive() const
+{
+  if (!sBrowserContentParents) {
+    return false;
+  }
+
+  // If we have already been marked as dead, don't prevent shutdown.
+  if (!IsAlive()) {
+    return false;
+  }
+
+  // Only keep processes for the default remote type alive.
+  if (!mRemoteType.EqualsLiteral(DEFAULT_REMOTE_TYPE)) {
+    return false;
+  }
+
+  auto contentParents = sBrowserContentParents->Get(mRemoteType);
+  if (!contentParents) {
+    return false;
+  }
+
+  // We might want to keep alive some content processes for testing, because of
+  // performance reasons.
+  // We don't want to alter behavior if the pref is not set, so default to 0.
+  int32_t processesToKeepAlive =
+    Preferences::GetInt("dom.ipc.keepProcessesAlive", 0);
+  int32_t numberOfAliveProcesses = contentParents->Length();
+
+  return numberOfAliveProcesses <= processesToKeepAlive;
+}
+
 void
 ContentParent::NotifyTabDestroying(const TabId& aTabId,
                                    const ContentParentId& aCpId)
 {
   if (XRE_IsParentProcess()) {
     // There can be more than one PBrowser for a given app process
     // because of popup windows.  PBrowsers can also destroy
     // concurrently.  When all the PBrowsers are destroying, kick off
@@ -1616,19 +1651,17 @@ ContentParent::NotifyTabDestroying(const
         return;
     }
     ++cp->mNumDestroyingTabs;
     nsTArray<TabId> tabIds = cpm->GetTabParentsByProcessId(aCpId);
     if (static_cast<size_t>(cp->mNumDestroyingTabs) != tabIds.Length()) {
         return;
     }
 
-    uint32_t numberOfParents = sBrowserContentParents ? sBrowserContentParents->Length() : 0;
-    int32_t processesToKeepAlive = Preferences::GetInt("dom.ipc.keepProcessesAlive", 0);
-    if (!cp->mLargeAllocationProcess && static_cast<int32_t>(numberOfParents) <= processesToKeepAlive) {
+    if (cp->ShouldKeepProcessAlive()) {
       return;
     }
 
     // We're dying now, so prevent this content process from being
     // recycled during its shutdown procedure.
     cp->MarkAsDead();
     cp->StartForceKillTimer();
   } else {
@@ -1671,24 +1704,17 @@ ContentParent::NotifyTabDestroyed(const 
   }
 
   // There can be more than one PBrowser for a given app process
   // because of popup windows.  When the last one closes, shut
   // us down.
   ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
   nsTArray<TabId> tabIds = cpm->GetTabParentsByProcessId(this->ChildID());
 
-  // We might want to keep alive some content processes for testing, because of performance
-  // reasons, but we don't want to alter behavior if the pref is not set.
-  uint32_t numberOfParents = sBrowserContentParents ? sBrowserContentParents->Length() : 0;
-  int32_t processesToKeepAlive = Preferences::GetInt("dom.ipc.keepProcessesAlive", 0);
-  bool shouldKeepAliveAny = !mLargeAllocationProcess && processesToKeepAlive > 0;
-  bool shouldKeepAliveThis = shouldKeepAliveAny && static_cast<int32_t>(numberOfParents) <= processesToKeepAlive;
-
-  if (tabIds.Length() == 1 && !shouldKeepAliveThis) {
+  if (tabIds.Length() == 1 && !ShouldKeepProcessAlive()) {
     // In the case of normal shutdown, send a shutdown message to child to
     // allow it to perform shutdown tasks.
     MessageLoop::current()->PostTask(NewRunnableMethod
                                      <ShutDownMethod>(this,
                                                       &ContentParent::ShutDownProcess,
                                                       SEND_SHUTDOWN_MESSAGE));
   }
 }
@@ -1762,21 +1788,21 @@ ContentParent::LaunchSubprocess(ProcessP
 
   // Set a reply timeout for CPOWs.
   SetReplyTimeoutMs(Preferences::GetInt("dom.ipc.cpow.timeout", 0));
 
   return true;
 }
 
 ContentParent::ContentParent(ContentParent* aOpener,
-                             bool aIsForBrowser)
+                             const nsAString& aRemoteType)
   : nsIContentParent()
   , mOpener(aOpener)
-  , mIsForBrowser(aIsForBrowser)
-  , mLargeAllocationProcess(false)
+  , mRemoteType(aRemoteType)
+  , mIsForBrowser(!mRemoteType.IsEmpty())
 {
   InitializeMembers();  // Perform common initialization.
 
   // Insert ourselves into the global linked list of ContentParent objects.
   if (!sContentParents) {
     sContentParents = new LinkedList<ContentParent>();
   }
   sContentParents->insertBack(this);
@@ -1788,34 +1814,35 @@ ContentParent::ContentParent(ContentPare
 #if defined(XP_WIN) && !defined(MOZ_B2G)
   // Request Windows message deferral behavior on our side of the PContent
   // channel. Generally only applies to the situation where we get caught in
   // a deadlock with the plugin process when sending CPOWs.
   GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_DEFERRED_MESSAGE_PROTECTION);
 #endif
 
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-  ChildPrivileges privs = base::PRIVILEGES_DEFAULT;
+  ChildPrivileges privs = mRemoteType.EqualsLiteral(FILE_REMOTE_TYPE)
+                          ? base::PRIVILEGES_FILEREAD
+                          : base::PRIVILEGES_DEFAULT;
   mSubprocess = new GeckoChildProcessHost(GeckoProcessType_Content, privs);
 }
 
 ContentParent::~ContentParent()
 {
   if (mForceKillTimer) {
     mForceKillTimer->Cancel();
   }
 
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   // We should be removed from all these lists in ActorDestroy.
   MOZ_ASSERT(!sPrivateContent || !sPrivateContent->Contains(this));
-  MOZ_ASSERT((!sBrowserContentParents ||
-              !sBrowserContentParents->Contains(this)) &&
-             (!sLargeAllocationContentParents ||
-              !sLargeAllocationContentParents->Contains(this)));
+  MOZ_ASSERT(!sBrowserContentParents ||
+             !sBrowserContentParents->Contains(mRemoteType) ||
+             !sBrowserContentParents->Get(mRemoteType)->Contains(this));
 }
 
 void
 ContentParent::InitInternal(ProcessPriority aInitialPriority,
                             bool aSetupOffMainThreadCompositing,
                             bool aSendRegisteredChrome)
 {
   if (aSendRegisteredChrome) {
@@ -4140,16 +4167,140 @@ ContentParent::AllocPWebBrowserPersistDo
 bool
 ContentParent::DeallocPWebBrowserPersistDocumentParent(PWebBrowserPersistDocumentParent* aActor)
 {
   delete aActor;
   return true;
 }
 
 mozilla::ipc::IPCResult
+ContentParent::CommonCreateWindow(PBrowserParent* aThisTab,
+                                  bool aSetOpener,
+                                  const uint32_t& aChromeFlags,
+                                  const bool& aCalledFromJS,
+                                  const bool& aPositionSpecified,
+                                  const bool& aSizeSpecified,
+                                  nsIURI* aURIToLoad,
+                                  const nsCString& aFeatures,
+                                  const nsCString& aBaseURI,
+                                  const DocShellOriginAttributes& aOpenerOriginAttributes,
+                                  const float& aFullZoom,
+                                  nsresult& aResult,
+                                  nsCOMPtr<nsITabParent>& aNewTabParent,
+                                  bool* aWindowIsNew)
+
+{
+  // The content process should never be in charge of computing whether or
+  // not a window should be private or remote - the parent will do that.
+  const uint32_t badFlags = nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW |
+                            nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW |
+                            nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME |
+                            nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
+  if (!!(aChromeFlags & badFlags)) {
+    return IPC_FAIL(this, "Forbidden aChromeFlags passed");
+  }
+
+  TabParent* thisTabParent = TabParent::GetFrom(aThisTab);
+  nsCOMPtr<nsIContent> frame;
+  if (thisTabParent) {
+    frame = do_QueryInterface(thisTabParent->GetOwnerElement());
+
+    if (NS_WARN_IF(thisTabParent->IsMozBrowser())) {
+      return IPC_FAIL(this, "aThisTab is not a MozBrowser");
+    }
+  }
+
+  nsCOMPtr<nsPIDOMWindowOuter> outerWin;
+  if (frame) {
+    outerWin = frame->OwnerDoc()->GetWindow();
+
+    // If our chrome window is in the process of closing, don't try to open a
+    // new tab in it.
+    if (outerWin && outerWin->Closed()) {
+      outerWin = nullptr;
+    }
+  }
+
+  nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
+  if (thisTabParent) {
+    browserDOMWin = thisTabParent->GetBrowserDOMWindow();
+  }
+
+  // If we haven't found a chrome window to open in, just use the most recently
+  // opened one.
+  if (!outerWin) {
+    outerWin = nsContentUtils::GetMostRecentNonPBWindow();
+    if (NS_WARN_IF(!outerWin)) {
+      aResult = NS_ERROR_FAILURE;
+      return IPC_OK();
+    }
+
+    nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(outerWin);
+    if (rootChromeWin) {
+      rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
+    }
+  }
+
+  int32_t openLocation = nsWindowWatcher::GetWindowOpenLocation(
+    outerWin, aChromeFlags, aCalledFromJS, aPositionSpecified, aSizeSpecified);
+
+  MOZ_ASSERT(openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB ||
+             openLocation == nsIBrowserDOMWindow::OPEN_NEWWINDOW);
+
+  if (openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB) {
+    if (NS_WARN_IF(!browserDOMWin)) {
+      aResult = NS_ERROR_ABORT;
+      return IPC_OK();
+    }
+
+    bool isPrivate = false;
+    if (thisTabParent) {
+      nsCOMPtr<nsILoadContext> loadContext = thisTabParent->GetLoadContext();
+      loadContext->GetUsePrivateBrowsing(&isPrivate);
+    }
+
+    nsCOMPtr<nsIOpenURIInFrameParams> params =
+      new nsOpenURIInFrameParams(aOpenerOriginAttributes);
+    params->SetReferrer(NS_ConvertUTF8toUTF16(aBaseURI));
+    params->SetIsPrivate(isPrivate);
+
+    nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
+    aResult = browserDOMWin->OpenURIInFrame(aURIToLoad, params, openLocation,
+                                            nsIBrowserDOMWindow::OPEN_NEW,
+                                            getter_AddRefs(frameLoaderOwner));
+    if (NS_SUCCEEDED(aResult) && frameLoaderOwner) {
+      RefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
+      if (frameLoader) {
+        frameLoader->GetTabParent(getter_AddRefs(aNewTabParent));
+      }
+    } else {
+      *aWindowIsNew = false;
+    }
+
+    return IPC_OK();
+  }
+
+  nsCOMPtr<nsPIWindowWatcher> pwwatch =
+    do_GetService(NS_WINDOWWATCHER_CONTRACTID, &aResult);
+  if (NS_WARN_IF(NS_FAILED(aResult))) {
+    return IPC_OK();
+  }
+
+  if (aSetOpener && thisTabParent) {
+    aResult = pwwatch->OpenWindowWithTabParent(thisTabParent, aFeatures,
+                                               aCalledFromJS, aFullZoom,
+                                               getter_AddRefs(aNewTabParent));
+  } else {
+    aResult = pwwatch->OpenWindowWithoutParent(getter_AddRefs(aNewTabParent));
+  }
+
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
 ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
                                 PBrowserParent* aNewTab,
                                 PRenderFrameParent* aRenderFrame,
                                 const uint32_t& aChromeFlags,
                                 const bool& aCalledFromJS,
                                 const bool& aPositionSpecified,
                                 const bool& aSizeSpecified,
                                 const nsCString& aFeatures,
@@ -4162,151 +4313,41 @@ ContentParent::RecvCreateWindow(PBrowser
                                 nsCString* aURLToLoad,
                                 TextureFactoryIdentifier* aTextureFactoryIdentifier,
                                 uint64_t* aLayersId)
 {
   // We always expect to open a new window here. If we don't, it's an error.
   *aWindowIsNew = true;
   *aResult = NS_OK;
 
-  // The content process should never be in charge of computing whether or
-  // not a window should be private or remote - the parent will do that.
-  const uint32_t badFlags =
-        nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW
-      | nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW
-      | nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME
-      | nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
-  if (!!(aChromeFlags & badFlags)) {
-      return IPC_FAIL_NO_REASON(this);
-  }
-
-  TabParent* thisTabParent = nullptr;
-  if (aThisTab) {
-    thisTabParent = TabParent::GetFrom(aThisTab);
-  }
-
-  if (NS_WARN_IF(thisTabParent && thisTabParent->IsMozBrowser())) {
-    return IPC_FAIL_NO_REASON(this);
-  }
-
   TabParent* newTab = TabParent::GetFrom(aNewTab);
   MOZ_ASSERT(newTab);
 
   auto destroyNewTabOnError = MakeScopeExit([&] {
     if (!*aWindowIsNew || NS_FAILED(*aResult)) {
       if (newTab) {
         newTab->Destroy();
       }
     }
   });
 
   // Content has requested that we open this new content window, so
   // we must have an opener.
   newTab->SetHasContentOpener(true);
 
-  nsCOMPtr<nsIContent> frame;
-  if (thisTabParent) {
-    frame = do_QueryInterface(thisTabParent->GetOwnerElement());
-  }
-
-  nsCOMPtr<nsPIDOMWindowOuter> parent;
-  if (frame) {
-    parent = frame->OwnerDoc()->GetWindow();
-
-    // If our chrome window is in the process of closing, don't try to open a
-    // new tab in it.
-    if (parent && parent->Closed()) {
-      parent = nullptr;
-    }
-  }
-
-  nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
-  if (thisTabParent) {
-    browserDOMWin = thisTabParent->GetBrowserDOMWindow();
-  }
-
-  // If we haven't found a chrome window to open in, just use the most recently
-  // opened one.
-  if (!parent) {
-    parent = nsContentUtils::GetMostRecentNonPBWindow();
-    if (NS_WARN_IF(!parent)) {
-      *aResult = NS_ERROR_FAILURE;
-      return IPC_OK();
-    }
-
-    nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(parent);
-    if (rootChromeWin) {
-      rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
-    }
-  }
-
-  int32_t openLocation =
-    nsWindowWatcher::GetWindowOpenLocation(parent, aChromeFlags, aCalledFromJS,
-                                           aPositionSpecified, aSizeSpecified);
-
-  MOZ_ASSERT(openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB ||
-             openLocation == nsIBrowserDOMWindow::OPEN_NEWWINDOW);
-
-  // Opening new tabs is the easy case...
-  if (openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB) {
-    if (NS_WARN_IF(!browserDOMWin)) {
-      *aResult = NS_ERROR_ABORT;
-      return IPC_OK();
-    }
-
-    bool isPrivate = false;
-    if (thisTabParent) {
-      nsCOMPtr<nsILoadContext> loadContext = thisTabParent->GetLoadContext();
-      loadContext->GetUsePrivateBrowsing(&isPrivate);
-    }
-
-    nsCOMPtr<nsIOpenURIInFrameParams> params =
-      new nsOpenURIInFrameParams(aOpenerOriginAttributes);
-    params->SetReferrer(NS_ConvertUTF8toUTF16(aBaseURI));
-    params->SetIsPrivate(isPrivate);
-
-    TabParent::AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad);
-
-    nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
-    browserDOMWin->OpenURIInFrame(nullptr, params,
-                                  openLocation,
-                                  nsIBrowserDOMWindow::OPEN_NEW,
-                                  getter_AddRefs(frameLoaderOwner));
-    if (!frameLoaderOwner) {
-      *aWindowIsNew = false;
-    }
-
-    newTab->SwapFrameScriptsFrom(*aFrameScripts);
-
-    RenderFrameParent* rfp = static_cast<RenderFrameParent*>(aRenderFrame);
-    if (!newTab->SetRenderFrame(rfp) ||
-        !newTab->GetRenderFrameInfo(aTextureFactoryIdentifier, aLayersId)) {
-      *aResult = NS_ERROR_FAILURE;
-    }
-
-    return IPC_OK();
-  }
-
   TabParent::AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad);
 
-  nsCOMPtr<nsPIWindowWatcher> pwwatch =
-    do_GetService(NS_WINDOWWATCHER_CONTRACTID, aResult);
-
-  if (NS_WARN_IF(NS_FAILED(*aResult))) {
-    return IPC_OK();
-  }
-
   nsCOMPtr<nsITabParent> newRemoteTab;
-  if (!thisTabParent) {
-    // Because we weren't passed an opener tab, the content process has asked us
-    // to open a new window that is unrelated to a pre-existing tab.
-    *aResult = pwwatch->OpenWindowWithoutParent(getter_AddRefs(newRemoteTab));
-  } else {
-    *aResult = pwwatch->OpenWindowWithTabParent(thisTabParent, aFeatures, aCalledFromJS,
-                                                aFullZoom, getter_AddRefs(newRemoteTab));
+  mozilla::ipc::IPCResult ipcResult =
+    CommonCreateWindow(aThisTab, /* aSetOpener = */ true, aChromeFlags,
+                       aCalledFromJS, aPositionSpecified, aSizeSpecified,
+                       nullptr, aFeatures, aBaseURI, aOpenerOriginAttributes,
+                       aFullZoom, *aResult, newRemoteTab, aWindowIsNew);
+  if (!ipcResult) {
+    return ipcResult;
   }
 
   if (NS_WARN_IF(NS_FAILED(*aResult))) {
     return IPC_OK();
   }
 
   MOZ_ASSERT(TabParent::GetFrom(newRemoteTab) == newTab);
 
@@ -4317,16 +4358,49 @@ ContentParent::RecvCreateWindow(PBrowser
       !newTab->GetRenderFrameInfo(aTextureFactoryIdentifier, aLayersId)) {
     *aResult = NS_ERROR_FAILURE;
   }
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
+ContentParent::RecvCreateWindowInDifferentProcess(
+  PBrowserParent* aThisTab,
+  const uint32_t& aChromeFlags,
+  const bool& aCalledFromJS,
+  const bool& aPositionSpecified,
+  const bool& aSizeSpecified,
+  const URIParams& aURIToLoad,
+  const nsCString& aFeatures,
+  const nsCString& aBaseURI,
+  const DocShellOriginAttributes& aOpenerOriginAttributes,
+  const float& aFullZoom)
+{
+  nsCOMPtr<nsITabParent> newRemoteTab;
+  bool windowIsNew;
+  nsCOMPtr<nsIURI> uriToLoad = DeserializeURI(aURIToLoad);
+  nsresult rv;
+  mozilla::ipc::IPCResult ipcResult =
+    CommonCreateWindow(aThisTab, /* aSetOpener = */ false, aChromeFlags,
+                       aCalledFromJS, aPositionSpecified, aSizeSpecified,
+                       uriToLoad, aFeatures, aBaseURI, aOpenerOriginAttributes,
+                       aFullZoom, rv, newRemoteTab, &windowIsNew);
+  if (!ipcResult) {
+    return ipcResult;
+  }
+
+  if (NS_FAILED(rv)) {
+    NS_WARNING("Call to CommonCreateWindow failed.");
+  }
+
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
 ContentParent::RecvProfile(const nsCString& aProfile)
 {
 #ifdef MOZ_ENABLE_PROFILER_SPS
   if (NS_WARN_IF(!mGatherer)) {
     return IPC_OK();
   }
   mProfile = aProfile;
   mGatherer->GatheredOOPProfile();
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -27,19 +27,29 @@
 #include "nsIDOMGeoPositionCallback.h"
 #include "nsIDOMGeoPositionErrorCallback.h"
 #include "nsRefPtrHashtable.h"
 #include "PermissionMessageUtils.h"
 #include "DriverCrashGuard.h"
 
 #define CHILD_PROCESS_SHUTDOWN_MESSAGE NS_LITERAL_STRING("child-process-shutdown")
 
+#define NO_REMOTE_TYPE ""
+
+// These must match the similar ones in E10SUtils.jsm.
+#define DEFAULT_REMOTE_TYPE "web"
+#define FILE_REMOTE_TYPE "file"
+
+// This must start with the DEFAULT_REMOTE_TYPE above.
+#define LARGE_ALLOCATION_REMOTE_TYPE "webLargeAllocation"
+
 class nsConsoleService;
 class nsICycleCollectorLogSink;
 class nsIDumpGCAndCCLogsCallback;
+class nsITabParent;
 class nsITimer;
 class ParentIdleListener;
 class nsIWidget;
 
 namespace mozilla {
 class PRemoteSpellcheckEngineParent;
 #ifdef MOZ_ENABLE_PROFILER_SPS
 class ProfileGatherer;
@@ -124,17 +134,17 @@ public:
 
   /**
    * Get or create a content process for:
    * 1. browser iframe
    * 2. remote xul <browser>
    * 3. normal iframe
    */
   static already_AddRefed<ContentParent>
-  GetNewOrUsedBrowserProcess(bool aForBrowserElement = false,
+  GetNewOrUsedBrowserProcess(const nsAString& aRemoteType = NS_LITERAL_STRING(NO_REMOTE_TYPE),
                              hal::ProcessPriority aPriority =
                              hal::ProcessPriority::PROCESS_PRIORITY_FOREGROUND,
                              ContentParent* aOpener = nullptr,
                              bool aLargeAllocationProcess = false);
 
   /**
    * Get or create a content process for the given TabContext.  aFrameElement
    * should be the frame/iframe element with which this process will
@@ -474,33 +484,46 @@ public:
 
   virtual bool
   DeallocPContentPermissionRequestParent(PContentPermissionRequestParent* actor) override;
 
   virtual bool HandleWindowsMessages(const Message& aMsg) const override;
 
   void ForkNewProcess(bool aBlocking);
 
-  virtual mozilla::ipc::IPCResult RecvCreateWindow(PBrowserParent* aThisTabParent,
-                                                   PBrowserParent* aOpener,
-                                                   layout::PRenderFrameParent* aRenderFrame,
-                                                   const uint32_t& aChromeFlags,
-                                                   const bool& aCalledFromJS,
-                                                   const bool& aPositionSpecified,
-                                                   const bool& aSizeSpecified,
-                                                   const nsCString& aFeatures,
-                                                   const nsCString& aBaseURI,
-                                                   const DocShellOriginAttributes& aOpenerOriginAttributes,
-                                                   const float& aFullZoom,
-                                                   nsresult* aResult,
-                                                   bool* aWindowIsNew,
-                                                   InfallibleTArray<FrameScriptInfo>* aFrameScripts,
-                                                   nsCString* aURLToLoad,
-                                                   layers::TextureFactoryIdentifier* aTextureFactoryIdentifier,
-                                                   uint64_t* aLayersId) override;
+  virtual mozilla::ipc::IPCResult
+  RecvCreateWindow(PBrowserParent* aThisTabParent,
+                   PBrowserParent* aNewTab,
+                   layout::PRenderFrameParent* aRenderFrame,
+                   const uint32_t& aChromeFlags,
+                   const bool& aCalledFromJS,
+                   const bool& aPositionSpecified,
+                   const bool& aSizeSpecified,
+                   const nsCString& aFeatures,
+                   const nsCString& aBaseURI,
+                   const DocShellOriginAttributes& aOpenerOriginAttributes,
+                   const float& aFullZoom,
+                   nsresult* aResult,
+                   bool* aWindowIsNew,
+                   InfallibleTArray<FrameScriptInfo>* aFrameScripts,
+                   nsCString* aURLToLoad,
+                   layers::TextureFactoryIdentifier* aTextureFactoryIdentifier,
+                   uint64_t* aLayersId) override;
+
+  virtual mozilla::ipc::IPCResult RecvCreateWindowInDifferentProcess(
+    PBrowserParent* aThisTab,
+    const uint32_t& aChromeFlags,
+    const bool& aCalledFromJS,
+    const bool& aPositionSpecified,
+    const bool& aSizeSpecified,
+    const URIParams& aURIToLoad,
+    const nsCString& aFeatures,
+    const nsCString& aBaseURI,
+    const DocShellOriginAttributes& aOpenerOriginAttributes,
+    const float& aFullZoom) override;
 
   static bool AllocateLayerTreeId(TabParent* aTabParent, uint64_t* aId);
 
   static void
   BroadcastBlobURLRegistration(const nsACString& aURI,
                                BlobImpl* aBlobImpl,
                                nsIPrincipal* aPrincipal,
                                ContentParent* aIgnoreThisCP = nullptr);
@@ -548,18 +571,17 @@ protected:
   virtual void ActorDestroy(ActorDestroyReason why) override;
 
   bool ShouldContinueFromReplyTimeout() override;
 
   void OnVarChanged(const GfxVarUpdate& aVar) override;
   void OnCompositorUnexpectedShutdown() override;
 
 private:
-  static nsTArray<ContentParent*>* sBrowserContentParents;
-  static nsTArray<ContentParent*>* sLargeAllocationContentParents;
+  static nsClassHashtable<nsStringHashKey, nsTArray<ContentParent*>>* sBrowserContentParents;
   static nsTArray<ContentParent*>* sPrivateContent;
   static StaticAutoPtr<LinkedList<ContentParent> > sContentParents;
 
   static void JoinProcessesIOThread(const nsTArray<ContentParent*>* aProcesses,
                                     Monitor* aMonitor, bool* aDone);
 
   static hal::ProcessPriority GetInitialProcessPriority(Element* aFrameElement);
 
@@ -574,20 +596,36 @@ private:
       PBrowserParent* actor,
       const TabId& aTabId,
       const IPCTabContext& context,
       const uint32_t& chromeFlags,
       const ContentParentId& aCpId,
       const bool& aIsForBrowser) override;
   using PContentParent::SendPTestShellConstructor;
 
+  mozilla::ipc::IPCResult
+  CommonCreateWindow(PBrowserParent* aThisTab,
+                     bool aSetOpener,
+                     const uint32_t& aChromeFlags,
+                     const bool& aCalledFromJS,
+                     const bool& aPositionSpecified,
+                     const bool& aSizeSpecified,
+                     nsIURI* aURIToLoad,
+                     const nsCString& aFeatures,
+                     const nsCString& aBaseURI,
+                     const DocShellOriginAttributes& aOpenerOriginAttributes,
+                     const float& aFullZoom,
+                     nsresult& aResult,
+                     nsCOMPtr<nsITabParent>& aNewTabParent,
+                     bool* aWindowIsNew);
+
   FORWARD_SHMEM_ALLOCATOR_TO(PContentParent)
 
   ContentParent(ContentParent* aOpener,
-                bool aIsForBrowser);
+                const nsAString& aRemoteType);
 
   // The common initialization for the constructors.
   void InitializeMembers();
 
   // Launch the subprocess and associated initialization.
   // Returns false if the process fails to start.
   bool LaunchSubprocess(hal::ProcessPriority aInitialPriority = hal::PROCESS_PRIORITY_FOREGROUND);
 
@@ -607,16 +645,22 @@ private:
 
   // Set the child process's priority and then check whether the child is
   // still alive.  Returns true if the process is still alive, and false
   // otherwise.  If you pass a FOREGROUND* priority here, it's (hopefully)
   // unlikely that the process will be killed after this point.
   bool SetPriorityAndCheckIsAlive(hal::ProcessPriority aPriority);
 
   /**
+   * Decide whether the process should be kept alive even when it would normally
+   * be shut down, for example when all its tabs are closed.
+   */
+  bool ShouldKeepProcessAlive() const;
+
+  /**
    * Mark this ContentParent as dead for the purposes of Get*().
    * This method is idempotent.
    */
   void MarkAsDead();
 
   /**
    * How we will shut down this ContentParent and its subprocess.
    */
@@ -1048,16 +1092,18 @@ private:
 
   // If you add strong pointers to cycle collected objects here, be sure to
   // release these objects in ShutDownProcess.  See the comment there for more
   // details.
 
   GeckoChildProcessHost* mSubprocess;
   ContentParent* mOpener;
 
+  nsString mRemoteType;
+
   ContentParentId mChildID;
   int32_t mGeolocationWatchID;
 
   nsCString mKillHardAnnotation;
 
   // After we initiate shutdown, we also start a timer to ensure
   // that even content processes that are 100% blocked (say from
   // SIGSTOP), are still killed eventually.  This task enforces that
@@ -1116,17 +1162,16 @@ private:
   RefPtr<embedding::PrintingParent> mPrintingParent;
 #endif
 
   // This hashtable is used to run GetFilesHelper objects in the parent process.
   // GetFilesHelper can be aborted by receiving RecvDeleteGetFilesRequest.
   nsRefPtrHashtable<nsIDHashKey, GetFilesHelper> mGetFilesPendingRequests;
 
   nsTArray<nsCString> mBlobURLs;
-  bool mLargeAllocationProcess;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 class ParentIdleListener : public nsIObserver
 {
   friend class mozilla::dom::ContentParent;
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -511,16 +511,21 @@ child:
      * Shutdown accessibility engine in content process (if not in use).
      */
     async ShutdownA11y();
 
     async AppInfo(nsCString version, nsCString buildID, nsCString name, nsCString UAName,
                   nsCString ID, nsCString vendor);
 
     /**
+     * Send the remote type associated with the content process.
+     */
+    async RemoteType(nsString aRemoteType);
+
+    /**
      * Send ServiceWorkerRegistrationData to child process.
      */
     async InitServiceWorkers(ServiceWorkerConfiguration aConfig);
 
     /**
      * Send BlobURLRegistrationData to child process.
      */
     async InitBlobURLs(BlobURLRegistrationData[] registrations);
@@ -1069,16 +1074,28 @@ parent:
                       float aFullZoom)
       returns (nsresult rv,
                bool windowOpened,
                FrameScriptInfo[] frameScripts,
                nsCString urlToLoad,
                TextureFactoryIdentifier textureFactoryIdentifier,
                uint64_t layersId);
 
+    async CreateWindowInDifferentProcess(
+      PBrowser aThisTab,
+      uint32_t aChromeFlags,
+      bool aCalledFromJS,
+      bool aPositionSpecified,
+      bool aSizeSpecified,
+      URIParams aURIToLoad,
+      nsCString aFeatures,
+      nsCString aBaseURI,
+      DocShellOriginAttributes aOpenerOriginAttributes,
+      float aFullZoom);
+
     sync GetDeviceStorageLocation(nsString type)
         returns (nsString path);
 
     sync GetDeviceStorageLocations()
 	returns (DeviceStorageLocationInfo info);
 
     sync GetAndroidSystemInfo()
         returns (AndroidSystemInfo info);
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -215,17 +215,17 @@ TabChildBase::GetPresShell() const
 }
 
 void
 TabChildBase::DispatchMessageManagerMessage(const nsAString& aMessageName,
                                             const nsAString& aJSONData)
 {
     AutoSafeJSContext cx;
     JS::Rooted<JS::Value> json(cx, JS::NullValue());
-    StructuredCloneData data;
+    dom::ipc::StructuredCloneData data;
     if (JS_ParseJSON(cx,
                       static_cast<const char16_t*>(aJSONData.BeginReading()),
                       aJSONData.Length(),
                       &json)) {
         ErrorResult rv;
         data.Write(cx, json, rv);
         if (NS_WARN_IF(rv.Failed())) {
             rv.SuppressException();
--- a/dom/media/MediaDevices.cpp
+++ b/dom/media/MediaDevices.cpp
@@ -132,16 +132,24 @@ public:
     return NS_OK;
   }
 
 private:
   virtual ~GumRejecter() {}
   RefPtr<Promise> mPromise;
 };
 
+MediaDevices::~MediaDevices()
+{
+  MediaManager* mediamanager = MediaManager::GetIfExists();
+  if (mediamanager) {
+    mediamanager->RemoveDeviceChangeCallback(this);
+  }
+}
+
 NS_IMPL_ISUPPORTS(MediaDevices::GumResolver, nsIDOMGetUserMediaSuccessCallback)
 NS_IMPL_ISUPPORTS(MediaDevices::EnumDevResolver, nsIGetUserMediaDevicesSuccessCallback)
 NS_IMPL_ISUPPORTS(MediaDevices::GumRejecter, nsIDOMGetUserMediaErrorCallback)
 
 already_AddRefed<Promise>
 MediaDevices::GetUserMedia(const MediaStreamConstraints& aConstraints,
                            ErrorResult &aRv)
 {
--- a/dom/media/MediaDevices.h
+++ b/dom/media/MediaDevices.h
@@ -61,17 +61,17 @@ public:
                                 const dom::Nullable<bool>& aWantsUntrusted,
                                 ErrorResult& aRv) override;
 
 private:
   class GumResolver;
   class EnumDevResolver;
   class GumRejecter;
 
-  virtual ~MediaDevices() {}
+  virtual ~MediaDevices();
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(MediaDevices,
                               MOZILLA_DOM_MEDIADEVICES_IMPLEMENTATION_IID)
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -2691,25 +2691,26 @@ MediaManager::OnNavigation(uint64_t aWin
   }
 
   RemoveMediaDevicesCallback(aWindowID);
 }
 
 void
 MediaManager::RemoveMediaDevicesCallback(uint64_t aWindowID)
 {
+  MutexAutoLock lock(mCallbackMutex);
   for (DeviceChangeCallback* observer : mDeviceChangeCallbackList)
   {
     dom::MediaDevices* mediadevices = static_cast<dom::MediaDevices *>(observer);
     MOZ_ASSERT(mediadevices);
     if (mediadevices) {
       nsPIDOMWindowInner* window = mediadevices->GetOwner();
       MOZ_ASSERT(window);
       if (window && window->WindowID() == aWindowID) {
-        DeviceChangeCallback::RemoveDeviceChangeCallback(observer);
+        DeviceChangeCallback::RemoveDeviceChangeCallbackLocked(observer);
         return;
       }
     }
   }
 }
 
 StreamListeners*
 MediaManager::AddWindowID(uint64_t aWindowId)
--- a/dom/media/systemservices/DeviceChangeCallback.h
+++ b/dom/media/systemservices/DeviceChangeCallback.h
@@ -27,29 +27,33 @@ public:
     if (mDeviceChangeCallbackList.IndexOf(aCallback) == mDeviceChangeCallbackList.NoIndex)
       mDeviceChangeCallbackList.AppendElement(aCallback);
     return 0;
   }
 
   virtual int RemoveDeviceChangeCallback(DeviceChangeCallback* aCallback)
   {
     MutexAutoLock lock(mCallbackMutex);
+    return RemoveDeviceChangeCallbackLocked(aCallback);
+  }
+
+  virtual int RemoveDeviceChangeCallbackLocked(DeviceChangeCallback* aCallback)
+  {
+    mCallbackMutex.AssertCurrentThreadOwns();
     if (mDeviceChangeCallbackList.IndexOf(aCallback) != mDeviceChangeCallbackList.NoIndex)
       mDeviceChangeCallbackList.RemoveElement(aCallback);
     return 0;
   }
 
   DeviceChangeCallback() : mCallbackMutex("mozilla::media::DeviceChangeCallback::mCallbackMutex")
   {
-    mDeviceChangeCallbackList.Clear();
   }
 
   virtual ~DeviceChangeCallback()
   {
-    mDeviceChangeCallbackList.Clear();
   }
 
 protected:
   nsTArray<DeviceChangeCallback*> mDeviceChangeCallbackList;
   Mutex mCallbackMutex;
 };
 
 } // namespace mozilla
--- a/dom/vr/VRDisplay.cpp
+++ b/dom/vr/VRDisplay.cpp
@@ -72,20 +72,20 @@ VRDisplayCapabilities::CanPresent() cons
 
 uint32_t
 VRDisplayCapabilities::MaxLayers() const
 {
   return CanPresent() ? 1 : 0;
 }
 
 /*static*/ bool
-VRDisplay::RefreshVRDisplays(dom::Navigator* aNavigator)
+VRDisplay::RefreshVRDisplays(uint64_t aWindowId)
 {
   gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
-  return vm && vm->RefreshVRDisplaysWithCallback(aNavigator);
+  return vm && vm->RefreshVRDisplaysWithCallback(aWindowId);
 }
 
 /*static*/ void
 VRDisplay::UpdateVRDisplays(nsTArray<RefPtr<VRDisplay>>& aDisplays, nsPIDOMWindowInner* aWindow)
 {
   nsTArray<RefPtr<VRDisplay>> displays;
 
   gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
--- a/dom/vr/VRDisplay.h
+++ b/dom/vr/VRDisplay.h
@@ -277,17 +277,17 @@ public:
   bool IsConnected() const;
 
   VRDisplayCapabilities* Capabilities();
   VRStageParameters* GetStageParameters();
 
   uint32_t DisplayId() const { return mDisplayId; }
   void GetDisplayName(nsAString& aDisplayName) const { aDisplayName = mDisplayName; }
 
-  static bool RefreshVRDisplays(dom::Navigator* aNavigator);
+  static bool RefreshVRDisplays(uint64_t aWindowId);
   static void UpdateVRDisplays(nsTArray<RefPtr<VRDisplay> >& aDisplays,
                                nsPIDOMWindowInner* aWindow);
 
   gfx::VRDisplayClient *GetClient() {
     return mClient;
   }
 
   virtual already_AddRefed<VREyeParameters> GetEyeParameters(VREye aEye);
--- a/embedding/browser/nsIWebBrowserChrome3.idl
+++ b/embedding/browser/nsIWebBrowserChrome3.idl
@@ -43,16 +43,18 @@ interface nsIWebBrowserChrome3 : nsIWebB
    *        The URI being loaded.
    * @param aReferrer
    *        The referrer of the load.
    */
   bool shouldLoadURI(in nsIDocShell    aDocShell,
                      in nsIURI         aURI,
                      in nsIURI         aReferrer);
 
+  bool shouldLoadURIInThisProcess(in nsIURI aURI);
+
   /**
    * Attempts to load the currently loaded page into a fresh process to increase
    * available memory.
    *
    * @param aDocShell
    *        The docshell performing the load.
    */
   bool reloadInFreshProcess(in nsIDocShell aDocShell,
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -259,25 +259,16 @@ Factory::CheckSurfaceSize(const IntSize 
   }
 
   // reject images with sides bigger than limit
   if (extentLimit && (sz.width > extentLimit || sz.height > extentLimit)) {
     gfxDebug() << "Surface size too large (exceeds extent limit)!";
     return false;
   }
 
-#if defined(XP_MACOSX)
-  // CoreGraphics is limited to images < 32K in *height*,
-  // so clamp all surfaces on the Mac to that height
-  if (sz.height > SHRT_MAX) {
-    gfxDebug() << "Surface size too large (exceeds CoreGraphics limit)!";
-    return false;
-  }
-#endif
-
   // assuming 4 bytes per pixel, make sure the allocation size
   // doesn't overflow a int32_t either
   CheckedInt<int32_t> stride = GetAlignedStride<16>(sz.width, 4);
   if (!stride.isValid() || stride.value() == 0) {
     gfxDebug() << "Surface size too large (stride overflows int32_t)!";
     return false;
   }
 
--- a/gfx/angle/BUILD.gn
+++ b/gfx/angle/BUILD.gn
@@ -1,17 +1,18 @@
 # Copyright 2014-2015 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 # import the use_x11 variable
 import("//build/config/dcheck_always_on.gni")
 import("//build/config/linux/pkg_config.gni")
 import("//build/config/ui.gni")
-import("//third_party/angle/build/angle_common.gni")
+import("//testing/libfuzzer/fuzzer_test.gni")
+import("//third_party/angle/gni/angle.gni")
 import("//ui/ozone/ozone.gni")
 
 if (ozone_platform_gbm) {
   pkg_config("libdrm") {
     packages = [ "libdrm" ]
   }
 }
 
@@ -49,16 +50,17 @@ config("internal_config") {
 }
 
 config("extra_warnings") {
   # Enable more default warnings on Windows.
   if (is_win) {
     cflags = [
       "/we4244",  # Conversion: possible loss of data.
       "/we4456",  # Variable shadowing.
+      "/we4458",  # declaration hides class member.
     ]
   }
 }
 
 if (is_win) {
   copy("copy_compiler_dll") {
     sources = [
       "$windows_sdk_path/Redist/D3D/$target_cpu/d3dcompiler_47.dll",
@@ -66,32 +68,16 @@ if (is_win) {
     outputs = [
       "$root_out_dir/d3dcompiler_47.dll",
     ]
   }
 }
 
 angle_undefine_configs = [ "//build/config/compiler:default_include_dirs" ]
 
-component("translator") {
-  sources = [
-    "src/compiler/translator/ShaderLang.cpp",
-    "src/compiler/translator/ShaderVars.cpp",
-  ]
-
-  defines = [ "ANGLE_TRANSLATOR_IMPLEMENTATION" ]
-
-  configs -= angle_undefine_configs
-  configs += [ ":internal_config" ]
-
-  public_deps = [
-    ":translator_lib",
-  ]
-}
-
 # Holds the shared includes so we only need to list them once.
 source_set("includes") {
   sources = [
     "include/EGL/egl.h",
     "include/EGL/eglext.h",
     "include/EGL/eglplatform.h",
     "include/GLES2/gl2.h",
     "include/GLES2/gl2ext.h",
@@ -105,20 +91,24 @@ source_set("includes") {
   ]
 }
 
 static_library("preprocessor") {
   sources = rebase_path(compiler_gypi.angle_preprocessor_sources, ".", "src")
 
   configs -= angle_undefine_configs
   configs += [ ":internal_config" ]
+
+  public_deps = [
+    ":angle_common",
+  ]
 }
 
-config("translator_static_config") {
-  defines = [ "ANGLE_TRANSLATOR_STATIC" ]
+config("translator_disable_pool_alloc") {
+  defines = [ "ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC" ]
 }
 
 config("debug_annotations_config") {
   if (is_debug) {
     defines = [ "ANGLE_ENABLE_DEBUG_ANNOTATIONS" ]
   }
 }
 
@@ -167,43 +157,43 @@ static_library("angle_image_util") {
 
   public_configs = [ ":angle_image_util_config" ]
 
   public_deps = [
     ":angle_common",
   ]
 }
 
-static_library("translator_lib") {
-  sources = rebase_path(compiler_gypi.angle_translator_lib_sources, ".", "src")
+static_library("translator") {
+  sources = rebase_path(compiler_gypi.angle_translator_sources, ".", "src")
   defines = []
 
-  if (angle_enable_essl) {
+  if (angle_enable_essl || use_libfuzzer) {
     sources +=
-        rebase_path(compiler_gypi.angle_translator_lib_essl_sources, ".", "src")
+        rebase_path(compiler_gypi.angle_translator_essl_sources, ".", "src")
     defines += [ "ANGLE_ENABLE_ESSL" ]
   }
 
-  if (angle_enable_glsl) {
+  if (angle_enable_glsl || use_libfuzzer) {
     sources +=
-        rebase_path(compiler_gypi.angle_translator_lib_glsl_sources, ".", "src")
+        rebase_path(compiler_gypi.angle_translator_glsl_sources, ".", "src")
     defines += [ "ANGLE_ENABLE_GLSL" ]
   }
 
-  if (angle_enable_hlsl) {
+  if (angle_enable_hlsl || use_libfuzzer) {
     sources +=
-        rebase_path(compiler_gypi.angle_translator_lib_hlsl_sources, ".", "src")
+        rebase_path(compiler_gypi.angle_translator_hlsl_sources, ".", "src")
     defines += [ "ANGLE_ENABLE_HLSL" ]
   }
   configs -= angle_undefine_configs
-  configs += [
-    ":internal_config",
-    ":translator_static_config",
-  ]
+  configs += [ ":internal_config" ]
   public_configs = [ ":external_config" ]
+  if (use_libfuzzer) {
+    all_dependent_configs = [ ":translator_disable_pool_alloc" ]
+  }
 
   deps = [
     ":includes",
     ":preprocessor",
   ]
 
   public_deps = [
     ":angle_common",
@@ -211,32 +201,28 @@ static_library("translator_lib") {
 
   if (is_win) {
     # Necessary to suppress some system header xtree warnigns in Release.
     # For some reason this warning doesn't get triggered in Chromium
     cflags = [ "/wd4718" ]
   }
 }
 
-static_library("translator_static") {
+source_set("translator_fuzzer") {
   sources = [
-    "src/compiler/translator/ShaderLang.cpp",
-    "src/compiler/translator/ShaderVars.cpp",
+    "src/compiler/fuzz/translator_fuzzer.cpp",
   ]
 
-  if (angle_enable_hlsl) {
-    defines = [ "ANGLE_ENABLE_HLSL" ]
-  }
+  include_dirs = [
+    "include",
+    "src",
+  ]
 
-  configs -= angle_undefine_configs
-  configs += [ ":internal_config" ]
-  public_configs = [ ":translator_static_config" ]
-
-  public_deps = [
-    ":translator_lib",
+  deps = [
+    ":translator",
   ]
 }
 
 config("commit_id_config") {
   include_dirs = [ "$root_gen_dir/angle" ]
 }
 
 commit_id_output_file = "$root_gen_dir/angle/id/commit.h"
@@ -280,19 +266,23 @@ config("libANGLE_config") {
     defines += [ "ANGLE_ENABLE_OPENGL" ]
     if (use_x11) {
       defines += [ "ANGLE_USE_X11" ]
     }
   }
   if (angle_enable_vulkan) {
     defines += [ "ANGLE_ENABLE_VULKAN" ]
   }
+  if (angle_enable_null) {
+    defines += [ "ANGLE_ENABLE_NULL" ]
+  }
   defines += [
     "GL_GLEXT_PROTOTYPES",
     "EGL_EGLEXT_PROTOTYPES",
+    "LIBANGLE_IMPLEMENTATION",
   ]
 
   if (is_win) {
     defines += [
       "GL_APICALL=",
       "EGLAPI=",
     ]
   } else {
@@ -306,25 +296,25 @@ config("libANGLE_config") {
   }
 }
 
 static_library("libANGLE") {
   sources = rebase_path(gles_gypi.libangle_sources, ".", "src")
 
   include_dirs = []
   libs = []
-  defines = [ "LIBANGLE_IMPLEMENTATION" ]
+  defines = []
   public_deps = [
     ":angle_common",
   ]
   deps = [
     ":angle_image_util",
     ":commit_id",
     ":includes",
-    ":translator_static",
+    ":translator",
   ]
 
   # Shared D3D sources.
   if (angle_enable_d3d9 || angle_enable_d3d11) {
     sources += rebase_path(gles_gypi.libangle_d3d_shared_sources, ".", "src")
 
     defines += [ "ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ " + "\"d3dcompiler_47.dll\", \"d3dcompiler_46.dll\", \"d3dcompiler_43.dll\" }" ]
   }
@@ -384,16 +374,20 @@ static_library("libANGLE") {
       sources += rebase_path(gles_gypi.libangle_gl_ozone_sources, ".", "src")
     }
   }
 
   if (angle_enable_vulkan) {
     sources += rebase_path(gles_gypi.libangle_vulkan_sources, ".", "src")
   }
 
+  if (angle_enable_null) {
+    sources += rebase_path(gles_gypi.libangle_null_sources, ".", "src")
+  }
+
   if (is_debug) {
     defines += [ "ANGLE_GENERATE_SHADER_DEBUG_INFO" ]
   }
 
   configs -= angle_undefine_configs
 
   configs += [
     ":commit_id_config",
--- a/gfx/angle/CONTRIBUTORS
+++ b/gfx/angle/CONTRIBUTORS
@@ -59,22 +59,28 @@ The Qt Company Ltd.
 Imagination Technologies Ltd.
  Gregoire Payen de La Garanderie
 
 Intel Corporation
  Jin Yang
  Andy Chen
  Josh Triplett
  Sudarsana Nagineni
+ Jiajia Qin
+ Jiawei Shao
+ Jie Chen
+ Qiankun Miao
+ Bryan Bernhart
 
 Klarälvdalens Datakonsult AB
  Milian Wolff
 
 Mozilla Corp.
  Ehsan Akhgari
+ Edwin Flores
  Jeff Gilbert
  Mike Hommey
  Benoit Jacob
  Makoto Kato
  Vladimir Vukicevic
 
 Turbulenz
  Michael Braithwaite
--- a/gfx/angle/DEPS
+++ b/gfx/angle/DEPS
@@ -1,39 +1,37 @@
 vars = {
   'chromium_git': 'https://chromium.googlesource.com',
 }
 
 deps = {
-  "third_party/gyp":
-      Var('chromium_git') + "/external/gyp@81c2e5ff92af29bab61c982808076ddce3d200a2",
+  'third_party/gyp':
+      Var('chromium_git') + '/external/gyp' + '@' + '81c2e5ff92af29bab61c982808076ddce3d200a2',
 
-  # TODO(kbr): figure out how to better stay in sync with Chromium's
-  # versions of googletest and googlemock.
-  "src/tests/third_party/googletest":
-      Var('chromium_git') + "/external/googletest.git@9855a87157778d39b95eccfb201a9dc90f6d61c6",
+  'testing/gtest':
+    Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + '6f8a66431cb592dad629028a50b3dd418a408c87',
 
-  "src/tests/third_party/googlemock":
-      Var('chromium_git') + "/external/googlemock.git@b2cb211e49d872101d991201362d7b97d7d69910",
+  'testing/gmock':
+    Var('chromium_git') + '/external/googlemock.git' + '@' + '0421b6f358139f02e102c9c332ce19a33faf75be', # from svn revision 566
 
   # Cherry is a dEQP management GUI written in Go. We use it for viewing test results.
-  "third_party/cherry":
-      "https://android.googlesource.com/platform/external/cherry@d2e26b4d864ec2a6757e7f1174e464949ca5bf73",
+  'third_party/cherry':
+      'https://android.googlesource.com/platform/external/cherry' + '@' + 'd2e26b4d864ec2a6757e7f1174e464949ca5bf73',
 
-  "third_party/deqp/src":
-      "https://android.googlesource.com/platform/external/deqp@f4f3d8079e7a37d7675ab93583e6438d0bca0e58",
+  'third_party/deqp/src':
+      'https://android.googlesource.com/platform/external/deqp' + '@' + 'f4f3d8079e7a37d7675ab93583e6438d0bca0e58',
 
-  "third_party/libpng":
-      "https://android.googlesource.com/platform/external/libpng@094e181e79a3d6c23fd005679025058b7df1ad6c",
+  'third_party/libpng':
+      'https://android.googlesource.com/platform/external/libpng' + '@' + '094e181e79a3d6c23fd005679025058b7df1ad6c',
 
-  "third_party/zlib":
-      Var('chromium_git') + "/chromium/src/third_party/zlib@afd8c4593c010c045902f6c0501718f1823064a3",
+  'third_party/zlib':
+      Var('chromium_git') + '/chromium/src/third_party/zlib' + '@' + 'afd8c4593c010c045902f6c0501718f1823064a3',
 
-  "buildtools":
-      Var('chromium_git') + '/chromium/buildtools.git@06e80a0e17319868d4a9b13f9bb6a248dc8d8b20',
+  'buildtools':
+      Var('chromium_git') + '/chromium/buildtools.git' + '@' + '39b1db2ab4aa4b2ccaa263c29bdf63e7c1ee28aa',
 }
 
 hooks = [
   # Pull clang-format binaries using checked-in hashes.
   {
     'name': 'clang_format_win',
     'pattern': '.',
     'action': [ 'download_from_google_storage',
@@ -97,12 +95,17 @@ hooks = [
                 '--platform=linux*',
                 '--no_auth',
                 '--bucket', 'chromium-gn',
                 '-s', 'buildtools/linux64/gn.sha1',
     ],
   },
   {
     # A change to a .gyp, .gypi, or to GYP itself should run the generator.
-    "pattern": ".",
-    "action": ["python", "build/gyp_angle"],
+    'pattern': '.',
+    'action': ['python', 'gyp/gyp_angle'],
   },
 ]
+
+recursedeps = [
+  # buildtools provides clang_format.
+  'buildtools',
+]
--- a/gfx/angle/include/EGL/eglext.h
+++ b/gfx/angle/include/EGL/eglext.h
@@ -467,16 +467,21 @@ EGLAPI EGLint EGLAPIENTRY eglDupNativeFe
 #define EGL_D3D11_DEVICE_ANGLE            0x33A1
 #endif /* EGL_ANGLE_device_d3d */
 
 #ifndef EGL_ANGLE_keyed_mutex
 #define EGL_ANGLE_keyed_mutex 1
 #define EGL_DXGI_KEYED_MUTEX_ANGLE        0x33A2
 #endif /* EGL_ANGLE_keyed_mutex */
 
+#ifndef EGL_ANGLE_d3d_texture_client_buffer
+#define EGL_ANGLE_d3d_texture_client_buffer 1
+#define EGL_D3D_TEXTURE_ANGLE             0x33A3
+#endif /* EGL_ANGLE_d3d_texture_client_buffer */
+
 #ifndef EGL_ANGLE_query_surface_pointer
 #define EGL_ANGLE_query_surface_pointer 1
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
 #ifdef EGL_EGLEXT_PROTOTYPES
 EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
 #endif
 #endif /* EGL_ANGLE_query_surface_pointer */
 
@@ -521,16 +526,21 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySu
 #endif /* EGL_ANGLE_platform_angle_d3d */
 
 #ifndef EGL_ANGLE_platform_angle_opengl
 #define EGL_ANGLE_platform_angle_opengl 1
 #define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D
 #define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E
 #endif /* EGL_ANGLE_platform_angle_opengl */
 
+#ifndef EGL_ANGLE_platform_angle_null
+#define EGL_ANGLE_platform_angle_null 1
+#define EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE 0x33AE
+#endif /* EGL_ANGLE_platform_angle_null */
+
 #ifndef EGL_ANGLE_window_fixed_size
 #define EGL_ANGLE_window_fixed_size 1
 #define EGL_FIXED_SIZE_ANGLE              0x3201
 #endif /* EGL_ANGLE_window_fixed_size */
 
 #ifndef EGL_ANGLE_x11_visual
 #define EGL_ANGLE_x11_visual
 #define EGL_X11_VISUAL_ID_ANGLE 0x33A3
@@ -553,25 +563,35 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySu
 #define EGL_ANGLE_experimental_present_path
 #define EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE 0x33A4
 #define EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE 0x33A9
 #define EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE 0x33AA
 #endif /* EGL_ANGLE_experimental_present_path */
 
 #ifndef EGL_ANGLE_stream_producer_d3d_texture_nv12
 #define EGL_ANGLE_stream_producer_d3d_texture_nv12
-#define EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE 0x3AAB
+#define EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE 0x33AB
 typedef EGLBoolean(EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
 typedef EGLBoolean(EGLAPIENTRYP PFNEGLSTREAMPOSTD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
 #ifdef EGL_EGLEXT_PROTOTYPES
 EGLAPI EGLBoolean EGLAPIENTRY eglCreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
 EGLAPI EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
 #endif
 #endif /* EGL_ANGLE_stream_producer_d3d_texture_nv12 */
 
+#ifndef EGL_ANGLE_create_context_webgl_compatibility
+#define EGL_ANGLE_create_context_webgl_compatibility 1
+#define EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE 0x3AAC
+#endif /* EGL_ANGLE_create_context_webgl_compatibility */
+
+#ifndef EGL_CHROMIUM_create_context_bind_generates_resource
+#define EGL_CHROMIUM_create_context_bind_generates_resource 1
+#define EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM 0x3AAD
+#endif /* EGL_CHROMIUM_create_context_bind_generates_resource */
+
 #ifndef EGL_ARM_pixmap_multisample_discard
 #define EGL_ARM_pixmap_multisample_discard 1
 #define EGL_DISCARD_SAMPLES_ARM           0x3286
 #endif /* EGL_ARM_pixmap_multisample_discard */
 
 #ifndef EGL_EXT_buffer_age
 #define EGL_EXT_buffer_age 1
 #define EGL_BUFFER_AGE_EXT                0x313D
--- a/gfx/angle/include/GLES2/gl2ext.h
+++ b/gfx/angle/include/GLES2/gl2ext.h
@@ -816,25 +816,38 @@ GL_APICALL void GL_APIENTRY glGetPerfMon
 #define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6
 #define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA
 typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
 #ifdef GL_GLEXT_PROTOTYPES
 GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
 #endif
 #endif /* GL_ANGLE_framebuffer_blit */
 
+#ifndef GL_ANGLE_webgl_compatibility
+#define GL_ANGLE_webgl_compatibility 1
+typedef GLboolean(GL_APIENTRYP PFNGLENABLEEXTENSIONANGLEPROC) (const GLchar *name);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLboolean GL_APIENTRY glEnableExtensionANGLE (const GLchar *name);
+#endif
+#endif /* GL_ANGLE_webgl_compatibility */
+
 #ifndef GL_CHROMIUM_framebuffer_mixed_samples
 #define GL_CHROMIUM_frambuffer_mixed_samples 1
 #define GL_COVERAGE_MODULATION_CHROMIUM 0x9332
 typedef void (GL_APIENTRYP PFNGLCOVERAGEMODULATIONCHROMIUMPROC) (GLenum components);
 #ifdef GL_GLEXT_PROTOTYPES
 GL_APICALL void GL_APIENTRY glCoverageModulationCHROMIUM(GLenum components);
 #endif
 #endif /* GL_CHROMIUM_framebuffer_mixed_samples */
 
+#ifndef GL_CHROMIUM_bind_generates_resource
+#define GL_CHROMIUM_bind_generates_resource 1
+#define GL_BIND_GENERATES_RESOURCE_CHROMIUM 0x9244
+#endif /* GL_CHROMIUM_bind_generates_resource */
+
 // needed by NV_path_rendering (and thus CHROMIUM_path_rendering)
 // but CHROMIUM_path_rendering only needs MatrixLoadfEXT, MatrixLoadIdentityEXT
 #ifndef GL_EXT_direct_state_access
 #define GL_EXT_direct_state_access 1
 typedef void(GL_APIENTRYP PFNGLMATRIXLOADFEXTPROC)(GLenum matrixMode, const GLfloat *m);
 typedef void(GL_APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC)(GLenum matrixMode);
 #ifdef GL_GLEXT_PROTOTYPES
 GL_APICALL void GL_APIENTRY glMatrixLoadfEXT(GLenum matrixMode, const GLfloat *m);
@@ -1298,16 +1311,24 @@ GL_APICALL void GL_APIENTRY glCopySubTex
                                                      GLsizei width,
                                                      GLsizei height,
                                                      GLboolean unpackFlipY,
                                                      GLboolean unpackPremultiplyAlpha,
                                                      GLboolean unpackUnmultiplyAlpha);
 #endif
 #endif /* GL_CHROMIUM_copy_texture */
 
+#ifndef GL_CHROMIUM_compressed_copy_texture
+#define GL_CHROMIUM_compressed_copy_texture 1
+typedef void(GL_APIENTRYP PFNGLCOMPRESSEDCOPYTEXTURECHROMIUMPROC)(GLuint sourceId, GLuint destId);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCompressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId);
+#endif
+#endif /* GL_CHROMIUM_compressed_copy_texture */
+
 #ifndef GL_CHROMIUM_sync_query
 #define GL_CHROMIUM_sync_query 1
 #define GL_COMMANDS_COMPLETED_CHROMIUM    0x84F7
 #endif  /* GL_CHROMIUM_sync_query */
 
 #ifndef GL_DMP_program_binary
 #define GL_DMP_program_binary 1
 #define GL_SMAPHS30_PROGRAM_BINARY_DMP    0x9251
@@ -3229,13 +3250,139 @@ GL_APICALL void GL_APIENTRY glEndTilingQ
 #define GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE                       0x9695
 #define GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE                      0x9696
 #define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE   0x9697
 #define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE  0x9698
 #define GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE                  0x9699
 #define GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE           0x969A
 #endif /* GL_ANGLE_lossy_etc_decode */
 
+#ifndef GL_ANGLE_robust_client_memory
+#define GL_ANGLE_robust_client_memory 1
+typedef void (GL_APIENTRYP PFNGLGETBOOLEANVROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *data);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETFLOATVROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *data);
+typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVROBUSTANGLE) (GLenum target, GLenum attachment, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETINTEGERVROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMIVROBUSTANGLE) (GLuint program, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSHADERIVROBUSTANGLE) (GLuint shader, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERFVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMFVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMIVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBFVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, void **pointer);
+typedef void (GL_APIENTRYP PFNGLREADPIXELSROBUSTANGLE) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLsizei *length, void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DROBUSTANGLE) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, const GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DROBUSTANGLE) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DROBUSTANGLE) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DROBUSTANGLE) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLGETQUERYIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVROBUSTANGLE) (GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, void **params);
+typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VROBUSTANGLE) (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint *data);
+typedef void (GL_APIENTRYP PFNGETINTERNALFORMATIVROBUSTANGLE) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIIVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIUIVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMUIVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVROBUSTANGLE) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETINTEGER64VROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data);
+typedef void (GL_APIENTRYP PFNGLGETINTEGER64I_VROBUSTANGLE) (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint64 *data);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERI64VROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLfloat *param);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERFVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMINTERFACEIVROBUSTANGLE) (GLuint program, GLenum programInterface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETBOOLEANI_VROBUSTANGLE) (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLboolean *data);
+typedef void (GL_APIENTRYP PFNGLGETMULTISAMPLEFVROBUSTANGLE) (GLenum pname, GLuint index, GLsizei bufSize, GLsizei *length, GLfloat *val);
+typedef void (GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERIVROBUSTANGLE) (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERFVROBUSTANGLE) (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETPOINTERVROBUSTANGLEROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, void **params);
+typedef void (GL_APIENTRYP PFNGLREADNPIXELSROBUSTANGLE) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLsizei *length, void *data);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMUIVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIUIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, const GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIUIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIUIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLuint *param);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTIVROBUSTANGLE)(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTI64VROBUSTANGLE)(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUI64VROBUSTANGLE)(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint64 *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetBooleanvRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *data);
+GL_APICALL void GL_APIENTRY glGetBufferParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetFloatvRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *data);
+GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameterivRobustANGLE (GLenum target, GLenum attachment, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetIntegervRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data);
+GL_APICALL void GL_APIENTRY glGetProgramivRobustANGLE (GLuint program, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetRenderbufferParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetShaderivRobustANGLE (GLuint shader, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterfvRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetUniformfvRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetUniformivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribfvRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribivRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribPointervRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, void **pointer);
+GL_APICALL void GL_APIENTRY glReadPixelsRobustANGLE (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLsizei *length, void *pixels);
+GL_APICALL void GL_APIENTRY glTexImage2DRobustANGLE (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
+GL_APICALL void GL_APIENTRY glTexParameterfvRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLfloat *params);
+GL_APICALL void GL_APIENTRY glTexParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params);
+GL_APICALL void GL_APIENTRY glTexSubImage2DRobustANGLE (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
+GL_APICALL void GL_APIENTRY glTexImage3DRobustANGLE (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
+GL_APICALL void GL_APIENTRY glTexSubImage3DRobustANGLE (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
+GL_APICALL void GL_APIENTRY glGetQueryivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjectuivRobustANGLE (GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
+GL_APICALL void GL_APIENTRY glGetBufferPointervRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, void **params);
+GL_APICALL void GL_APIENTRY glGetIntegeri_vRobustANGLE (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint *data);
+GL_APICALL void GL_APIENTRY glGetInternalformativRobustANGLE (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribIivRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribIuivRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
+GL_APICALL void GL_APIENTRY glGetUniformuivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params);
+GL_APICALL void GL_APIENTRY glGetActiveUniformBlockivRobustANGLE (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetInteger64vRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data);
+GL_APICALL void GL_APIENTRY glGetInteger64i_vRobustANGLE (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint64 *data);
+GL_APICALL void GL_APIENTRY glGetBufferParameteri64vRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params);
+GL_APICALL void GL_APIENTRY glSamplerParameterivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param);
+GL_APICALL void GL_APIENTRY glSamplerParameterfvRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLfloat *param);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterfvRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetFramebufferParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetProgramInterfaceivRobustANGLE (GLuint program, GLenum programInterface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetBooleani_vRobustANGLE (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLboolean *data);
+GL_APICALL void GL_APIENTRY glGetMultisamplefvRobustANGLE (GLenum pname, GLuint index, GLsizei bufSize, GLsizei *length, GLfloat *val);
+GL_APICALL void GL_APIENTRY glGetTexLevelParameterivRobustANGLE (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetTexLevelParameterfvRobustANGLE (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetPointervRobustANGLERobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, void **params);
+GL_APICALL void GL_APIENTRY glReadnPixelsRobustANGLE (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLsizei *length, void *data);
+GL_APICALL void GL_APIENTRY glGetnUniformfvRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetnUniformivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetnUniformuivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params);
+GL_APICALL void GL_APIENTRY glTexParameterIivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params);
+GL_APICALL void GL_APIENTRY glTexParameterIuivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLuint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterIivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterIuivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
+GL_APICALL void GL_APIENTRY glSamplerParameterIivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param);
+GL_APICALL void GL_APIENTRY glSamplerParameterIuivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLuint *param);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterIivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterIuivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjectivRobustANGLE(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjecti64vRobustANGLE(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjectui64vRobustANGLE(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint64 *params);
+#endif
+#endif /* GL_ANGLE_robust_client_memory */
+
 #ifdef __cplusplus
 }
 #endif
 
 #endif
--- a/gfx/angle/include/GLSLANG/ShaderLang.h
+++ b/gfx/angle/include/GLSLANG/ShaderLang.h
@@ -1,33 +1,16 @@
 //
 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 #ifndef GLSLANG_SHADERLANG_H_
 #define GLSLANG_SHADERLANG_H_
 
-#if defined(COMPONENT_BUILD) && !defined(ANGLE_TRANSLATOR_STATIC)
-#if defined(_WIN32) || defined(_WIN64)
-
-#if defined(ANGLE_TRANSLATOR_IMPLEMENTATION)
-#define COMPILER_EXPORT __declspec(dllexport)
-#else
-#define COMPILER_EXPORT __declspec(dllimport)
-#endif  // defined(ANGLE_TRANSLATOR_IMPLEMENTATION)
-
-#else  // defined(_WIN32) || defined(_WIN64)
-#define COMPILER_EXPORT __attribute__((visibility("default")))
-#endif
-
-#else  // defined(COMPONENT_BUILD) && !defined(ANGLE_TRANSLATOR_STATIC)
-#define COMPILER_EXPORT
-#endif
-
 #include <stddef.h>
 
 #include "KHR/khrplatform.h"
 
 #include <array>
 #include <map>
 #include <string>
 #include <vector>
@@ -44,31 +27,31 @@ typedef unsigned int GLenum;
 }
 
 // Must be included after GLenum proxy typedef
 // Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h
 #include "ShaderVars.h"
 
 // Version number for shader translation API.
 // It is incremented every time the API changes.
-#define ANGLE_SH_VERSION 161
+#define ANGLE_SH_VERSION 167
 
-typedef enum {
+enum ShShaderSpec
+{
     SH_GLES2_SPEC,
     SH_WEBGL_SPEC,
 
     SH_GLES3_SPEC,
     SH_WEBGL2_SPEC,
 
     SH_GLES3_1_SPEC,
     SH_WEBGL3_SPEC,
+};
 
-} ShShaderSpec;
-
-typedef enum
+enum ShShaderOutput
 {
     // ESSL output only supported in some configurations.
     SH_ESSL_OUTPUT = 0x8B45,
 
     // GLSL output only supported in some configurations.
     SH_GLSL_COMPATIBILITY_OUTPUT = 0x8B46,
     // Note: GL introduced core profiles in 1.5.
     SH_GLSL_130_OUTPUT      = 0x8B47,
@@ -77,30 +60,25 @@ typedef enum
     SH_GLSL_330_CORE_OUTPUT = 0x8B82,
     SH_GLSL_400_CORE_OUTPUT = 0x8B83,
     SH_GLSL_410_CORE_OUTPUT = 0x8B84,
     SH_GLSL_420_CORE_OUTPUT = 0x8B85,
     SH_GLSL_430_CORE_OUTPUT = 0x8B86,
     SH_GLSL_440_CORE_OUTPUT = 0x8B87,
     SH_GLSL_450_CORE_OUTPUT = 0x8B88,
 
-    // HLSL output only supported in some configurations.
-    // Deprecated:
-    SH_HLSL_OUTPUT   = 0x8B48,
-    SH_HLSL9_OUTPUT  = 0x8B48,
-    SH_HLSL11_OUTPUT = 0x8B49,
-
     // Prefer using these to specify HLSL output type:
     SH_HLSL_3_0_OUTPUT       = 0x8B48,  // D3D 9
     SH_HLSL_4_1_OUTPUT       = 0x8B49,  // D3D 11
     SH_HLSL_4_0_FL9_3_OUTPUT = 0x8B4A   // D3D 11 feature level 9_3
-} ShShaderOutput;
+};
 
 // Compile options.
-typedef uint64_t ShCompileOptions;
+
+using ShCompileOptions = uint64_t;
 
 const ShCompileOptions SH_VALIDATE                           = 0;
 const ShCompileOptions SH_VALIDATE_LOOP_INDEXING             = UINT64_C(1) << 0;
 const ShCompileOptions SH_INTERMEDIATE_TREE                  = UINT64_C(1) << 1;
 const ShCompileOptions SH_OBJECT_CODE                        = UINT64_C(1) << 2;
 const ShCompileOptions SH_VARIABLES                          = UINT64_C(1) << 3;
 const ShCompileOptions SH_LINE_DIRECTIVES                    = UINT64_C(1) << 4;
 const ShCompileOptions SH_SOURCE_PATH                        = UINT64_C(1) << 5;
@@ -194,46 +172,69 @@ const ShCompileOptions SH_HLSL_GET_DIMEN
 // This flag works around an issue in translating GLSL function texelFetchOffset on
 // INTEL drivers. It works by translating texelFetchOffset into texelFetch.
 const ShCompileOptions SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH = UINT64_C(1) << 24;
 
 // This flag works around condition bug of for and while loops in Intel Mac OSX drivers.
 // Condition calculation is not correct. Rewrite it from "CONDITION" to "CONDITION && true".
 const ShCompileOptions SH_ADD_AND_TRUE_TO_LOOP_CONDITION = UINT64_C(1) << 25;
 
-// Defines alternate strategies for implementing array index clamping.
-typedef enum {
-  // Use the clamp intrinsic for array index clamping.
-  SH_CLAMP_WITH_CLAMP_INTRINSIC = 1,
+// This flag works around a bug in evaluating unary minus operator on integer on some INTEL
+// drivers. It works by translating -(int) into ~(int) + 1.
+const ShCompileOptions SH_REWRITE_INTEGER_UNARY_MINUS_OPERATOR = UINT64_C(1) << 26;
+
+// This flag works around a bug in evaluating isnan() on some INTEL D3D and Mac OSX drivers.
+// It works by using an expression to emulate this function.
+const ShCompileOptions SH_EMULATE_ISNAN_FLOAT_FUNCTION = UINT64_C(1) << 27;
 
-  // Use a user-defined function for array index clamping.
-  SH_CLAMP_WITH_USER_DEFINED_INT_CLAMP_FUNCTION
-} ShArrayIndexClampingStrategy;
+// This flag will use all uniforms of unused std140 and shared uniform blocks at the
+// beginning of the vertex/fragment shader's main(). It is intended as a workaround for Mac
+// drivers with shader version 4.10. In those drivers, they will treat unused
+// std140 and shared uniform blocks' members as inactive. However, WebGL2.0 based on
+// OpenGL ES3.0.4 requires all members of a named uniform block declared with a shared or std140
+// layout qualifier to be considered active. The uniform block itself is also considered active.
+const ShCompileOptions SH_USE_UNUSED_STANDARD_SHARED_BLOCKS = UINT64_C(1) << 28;
 
-//
-// Driver must call this first, once, before doing any other
-// compiler operations.
-// If the function succeeds, the return value is true, else false.
-//
-COMPILER_EXPORT bool ShInitialize();
-//
-// Driver should call this at shutdown.
-// If the function succeeds, the return value is true, else false.
-//
-COMPILER_EXPORT bool ShFinalize();
+// This flag will keep invariant declaration for input in fragment shader for GLSL >=4.20 on AMD.
+// From GLSL >= 4.20, it's optional to add invariant for fragment input, but GPU vendors have
+// different implementations about this. Some drivers forbid invariant in fragment for GLSL>= 4.20,
+// e.g. Linux Mesa, some drivers treat that as optional, e.g. NVIDIA, some drivers require invariant
+// must match between vertex and fragment shader, e.g. AMD. The behavior on AMD is obviously wrong.
+// Remove invariant for input in fragment shader to workaround the restriction on Intel Mesa.
+// But don't remove on AMD Linux to avoid triggering the bug on AMD.
+const ShCompileOptions SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT = UINT64_C(1) << 29;
+
+// Due to spec difference between GLSL 4.1 or lower and ESSL3, some platforms (for example, Mac OSX
+// core profile) require a variable's "invariant"/"centroid" qualifiers to match between vertex and
+// fragment shader. A simple solution to allow such shaders to link is to omit the two qualifiers.
+// Note that the two flags only take effect on ESSL3 input shaders translated to GLSL 4.1 or lower.
+// TODO(zmo): This is not a good long-term solution. Simply dropping these qualifiers may break some
+// developers' content. A more complex workaround of dynamically generating, compiling, and
+// re-linking shaders that use these qualifiers should be implemented.
+const ShCompileOptions SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3 = UINT64_C(1) << 30;
+
+// Defines alternate strategies for implementing array index clamping.
+enum ShArrayIndexClampingStrategy
+{
+    // Use the clamp intrinsic for array index clamping.
+    SH_CLAMP_WITH_CLAMP_INTRINSIC = 1,
+
+    // Use a user-defined function for array index clamping.
+    SH_CLAMP_WITH_USER_DEFINED_INT_CLAMP_FUNCTION
+};
 
 // The 64 bits hash function. The first parameter is the input string; the
 // second parameter is the string length.
-typedef khronos_uint64_t (*ShHashFunction64)(const char*, size_t);
+using ShHashFunction64 = khronos_uint64_t (*)(const char *, size_t);
 
 //
 // Implementation dependent built-in resources (constants and extensions).
 // The names for these resources has been obtained by stripping gl_/GL_.
 //
-typedef struct
+struct ShBuiltInResources
 {
     // Constants.
     int MaxVertexAttribs;
     int MaxVertexUniformVectors;
     int MaxVaryingVectors;
     int MaxVertexTextureImageUnits;
     int MaxCombinedTextureImageUnits;
     int MaxTextureImageUnits;
@@ -355,62 +356,72 @@ typedef struct
     // maximum number of atomic counter buffers in a fragment shader
     int MaxFragmentAtomicCounterBuffers;
 
     // maximum number of atomic counter buffers in a program
     int MaxCombinedAtomicCounterBuffers;
 
     // maximum number of buffer object storage in machine units
     int MaxAtomicCounterBufferSize;
-
-} ShBuiltInResources;
-
-//
-// Initialize built-in resources with minimum expected values.
-// Parameters:
-// resources: The object to initialize. Will be comparable with memcmp.
-//
-COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources *resources);
+};
 
 //
 // ShHandle held by but opaque to the driver.  It is allocated,
 // managed, and de-allocated by the compiler. Its contents
 // are defined by and used by the compiler.
 //
 // If handle creation fails, 0 will be returned.
 //
-typedef void *ShHandle;
+using ShHandle = void *;
+
+//
+// Driver must call this first, once, before doing any other
+// compiler operations.
+// If the function succeeds, the return value is true, else false.
+//
+bool ShInitialize();
+//
+// Driver should call this at shutdown.
+// If the function succeeds, the return value is true, else false.
+//
+bool ShFinalize();
+
+//
+// Initialize built-in resources with minimum expected values.
+// Parameters:
+// resources: The object to initialize. Will be comparable with memcmp.
+//
+void ShInitBuiltInResources(ShBuiltInResources *resources);
 
 //
 // Returns the a concatenated list of the items in ShBuiltInResources as a
 // null-terminated string.
 // This function must be updated whenever ShBuiltInResources is changed.
 // Parameters:
 // handle: Specifies the handle of the compiler to be used.
-COMPILER_EXPORT const std::string &ShGetBuiltInResourcesString(const ShHandle handle);
+const std::string &ShGetBuiltInResourcesString(const ShHandle handle);
 
 //
 // Driver calls these to create and destroy compiler objects.
 //
 // Returns the handle of constructed compiler, null if the requested compiler is
 // not supported.
 // Parameters:
 // type: Specifies the type of shader - GL_FRAGMENT_SHADER or GL_VERTEX_SHADER.
 // spec: Specifies the language spec the compiler must conform to -
 //       SH_GLES2_SPEC or SH_WEBGL_SPEC.
 // output: Specifies the output code type - for example SH_ESSL_OUTPUT, SH_GLSL_OUTPUT,
 //         SH_HLSL_3_0_OUTPUT or SH_HLSL_4_1_OUTPUT. Note: Each output type may only
 //         be supported in some configurations.
 // resources: Specifies the built-in resources.
-COMPILER_EXPORT ShHandle ShConstructCompiler(
-    sh::GLenum type,
-    ShShaderSpec spec,
-    ShShaderOutput output,
-    const ShBuiltInResources *resources);
-COMPILER_EXPORT void ShDestruct(ShHandle handle);
+ShHandle ShConstructCompiler(sh::GLenum type,
+                             ShShaderSpec spec,
+                             ShShaderOutput output,
+                             const ShBuiltInResources *resources);
+void ShDestruct(ShHandle handle);
 
 //
 // Compiles the given shader source.
 // If the function succeeds, the return value is true, else false.
 // Parameters:
 // handle: Specifies the handle of compiler to be used.
 // shaderStrings: Specifies an array of pointers to null-terminated strings
 //                containing the shader source code.
@@ -420,95 +431,227 @@ COMPILER_EXPORT void ShDestruct(ShHandle
 //              specified during compiler construction.
 // SH_VALIDATE_LOOP_INDEXING: Validates loop and indexing in the shader to
 //                            ensure that they do not exceed the minimum
 //                            functionality mandated in GLSL 1.0 spec,
 //                            Appendix A, Section 4 and 5.
 //                            There is no need to specify this parameter when
 //                            compiling for WebGL - it is implied.
 // SH_INTERMEDIATE_TREE: Writes intermediate tree to info log.
-//                       Can be queried by calling ShGetInfoLog().
+//                       Can be queried by calling sh::GetInfoLog().
 // SH_OBJECT_CODE: Translates intermediate tree to glsl or hlsl shader.
-//                 Can be queried by calling ShGetObjectCode().
+//                 Can be queried by calling sh::GetObjectCode().
 // SH_VARIABLES: Extracts attributes, uniforms, and varyings.
 //               Can be queried by calling ShGetVariableInfo().
 //
-COMPILER_EXPORT bool ShCompile(const ShHandle handle,
-                               const char *const shaderStrings[],
-                               size_t numStrings,
-                               ShCompileOptions compileOptions);
+bool ShCompile(const ShHandle handle,
+               const char *const shaderStrings[],
+               size_t numStrings,
+               ShCompileOptions compileOptions);
 
 // Clears the results from the previous compilation.
-COMPILER_EXPORT void ShClearResults(const ShHandle handle);
+void ShClearResults(const ShHandle handle);
 
 // Return the version of the shader language.
-COMPILER_EXPORT int ShGetShaderVersion(const ShHandle handle);
+int ShGetShaderVersion(const ShHandle handle);
 
 // Return the currently set language output type.
-COMPILER_EXPORT ShShaderOutput ShGetShaderOutputType(
-    const ShHandle handle);
+ShShaderOutput ShGetShaderOutputType(const ShHandle handle);
 
 // Returns null-terminated information log for a compiled shader.
 // Parameters:
 // handle: Specifies the compiler
-COMPILER_EXPORT const std::string &ShGetInfoLog(const ShHandle handle);
+const std::string &ShGetInfoLog(const ShHandle handle);
 
 // Returns null-terminated object code for a compiled shader.
 // Parameters:
 // handle: Specifies the compiler
-COMPILER_EXPORT const std::string &ShGetObjectCode(const ShHandle handle);
+const std::string &ShGetObjectCode(const ShHandle handle);
 
 // Returns a (original_name, hash) map containing all the user defined
 // names in the shader, including variable names, function names, struct
 // names, and struct field names.
 // Parameters:
 // handle: Specifies the compiler
-COMPILER_EXPORT const std::map<std::string, std::string> *ShGetNameHashingMap(
-    const ShHandle handle);
+const std::map<std::string, std::string> *ShGetNameHashingMap(const ShHandle handle);
 
 // Shader variable inspection.
 // Returns a pointer to a list of variables of the designated type.
 // (See ShaderVars.h for type definitions, included above)
 // Returns NULL on failure.
 // Parameters:
 // handle: Specifies the compiler
-COMPILER_EXPORT const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle);
-COMPILER_EXPORT const std::vector<sh::Varying> *ShGetVaryings(const ShHandle handle);
-COMPILER_EXPORT const std::vector<sh::Attribute> *ShGetAttributes(const ShHandle handle);
-COMPILER_EXPORT const std::vector<sh::OutputVariable> *ShGetOutputVariables(const ShHandle handle);
-COMPILER_EXPORT const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handle);
-COMPILER_EXPORT sh::WorkGroupSize ShGetComputeShaderLocalGroupSize(const ShHandle handle);
-
-typedef struct
-{
-    sh::GLenum type;
-    int size;
-} ShVariableInfo;
+const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle);
+const std::vector<sh::Varying> *ShGetVaryings(const ShHandle handle);
+const std::vector<sh::Attribute> *ShGetAttributes(const ShHandle handle);
+const std::vector<sh::OutputVariable> *ShGetOutputVariables(const ShHandle handle);
+const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handle);
+sh::WorkGroupSize ShGetComputeShaderLocalGroupSize(const ShHandle handle);
 
 // Returns true if the passed in variables pack in maxVectors following
 // the packing rules from the GLSL 1.017 spec, Appendix A, section 7.
 // Returns false otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
 // flag above.
 // Parameters:
 // maxVectors: the available rows of registers.
 // variables: an array of variables.
-COMPILER_EXPORT bool ShCheckVariablesWithinPackingLimits(
-    int maxVectors,
-    const std::vector<sh::ShaderVariable> &variables);
+bool ShCheckVariablesWithinPackingLimits(int maxVectors,
+                                         const std::vector<sh::ShaderVariable> &variables);
 
 // Gives the compiler-assigned register for an interface block.
 // The method writes the value to the output variable "indexOut".
 // Returns true if it found a valid interface block, false otherwise.
 // Parameters:
 // handle: Specifies the compiler
 // interfaceBlockName: Specifies the interface block
 // indexOut: output variable that stores the assigned register
-COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle,
-                                                 const std::string &interfaceBlockName,
-                                                 unsigned int *indexOut);
+bool ShGetInterfaceBlockRegister(const ShHandle handle,
+                                 const std::string &interfaceBlockName,
+                                 unsigned int *indexOut);
 
 // Gives a map from uniform names to compiler-assigned registers in the default
 // interface block. Note that the map contains also registers of samplers that
 // have been extracted from structs.
-COMPILER_EXPORT const std::map<std::string, unsigned int> *ShGetUniformRegisterMap(
-    const ShHandle handle);
+const std::map<std::string, unsigned int> *ShGetUniformRegisterMap(const ShHandle handle);
+
+// Temporary duplicate of the scoped APIs, to be removed when we roll ANGLE and fix Chromium.
+// TODO(jmadill): Consolidate with these APIs once we roll ANGLE.
+
+namespace sh
+{
+
+//
+// Driver must call this first, once, before doing any other compiler operations.
+// If the function succeeds, the return value is true, else false.
+//
+bool Initialize();
+//
+// Driver should call this at shutdown.
+// If the function succeeds, the return value is true, else false.
+//
+bool Finalize();
+
+//
+// Initialize built-in resources with minimum expected values.
+// Parameters:
+// resources: The object to initialize. Will be comparable with memcmp.
+//
+void InitBuiltInResources(ShBuiltInResources *resources);
+
+//
+// Returns the a concatenated list of the items in ShBuiltInResources as a null-terminated string.
+// This function must be updated whenever ShBuiltInResources is changed.
+// Parameters:
+// handle: Specifies the handle of the compiler to be used.
+const std::string &GetBuiltInResourcesString(const ShHandle handle);
+
+//
+// Driver calls these to create and destroy compiler objects.
+//
+// Returns the handle of constructed compiler, null if the requested compiler is not supported.
+// Parameters:
+// type: Specifies the type of shader - GL_FRAGMENT_SHADER or GL_VERTEX_SHADER.
+// spec: Specifies the language spec the compiler must conform to - SH_GLES2_SPEC or SH_WEBGL_SPEC.
+// output: Specifies the output code type - for example SH_ESSL_OUTPUT, SH_GLSL_OUTPUT,
+//         SH_HLSL_3_0_OUTPUT or SH_HLSL_4_1_OUTPUT. Note: Each output type may only
+//         be supported in some configurations.
+// resources: Specifies the built-in resources.
+ShHandle ConstructCompiler(sh::GLenum type,
+                           ShShaderSpec spec,
+                           ShShaderOutput output,
+                           const ShBuiltInResources *resources);
+void Destruct(ShHandle handle);
+
+//
+// Compiles the given shader source.
+// If the function succeeds, the return value is true, else false.
+// Parameters:
+// handle: Specifies the handle of compiler to be used.
+// shaderStrings: Specifies an array of pointers to null-terminated strings containing the shader
+// source code.
+// numStrings: Specifies the number of elements in shaderStrings array.
+// compileOptions: A mask containing the following parameters:
+// SH_VALIDATE: Validates shader to ensure that it conforms to the spec
+//              specified during compiler construction.
+// SH_VALIDATE_LOOP_INDEXING: Validates loop and indexing in the shader to
+//                            ensure that they do not exceed the minimum
+//                            functionality mandated in GLSL 1.0 spec,
+//                            Appendix A, Section 4 and 5.
+//                            There is no need to specify this parameter when
+//                            compiling for WebGL - it is implied.
+// SH_INTERMEDIATE_TREE: Writes intermediate tree to info log.
+//                       Can be queried by calling sh::GetInfoLog().
+// SH_OBJECT_CODE: Translates intermediate tree to glsl or hlsl shader.
+//                 Can be queried by calling sh::GetObjectCode().
+// SH_VARIABLES: Extracts attributes, uniforms, and varyings.
+//               Can be queried by calling ShGetVariableInfo().
+//
+bool Compile(const ShHandle handle,
+             const char *const shaderStrings[],
+             size_t numStrings,
+             ShCompileOptions compileOptions);
+
+// Clears the results from the previous compilation.
+void ClearResults(const ShHandle handle);
+
+// Return the version of the shader language.
+int GetShaderVersion(const ShHandle handle);
+
+// Return the currently set language output type.
+ShShaderOutput GetShaderOutputType(const ShHandle handle);
+
+// Returns null-terminated information log for a compiled shader.
+// Parameters:
+// handle: Specifies the compiler
+const std::string &GetInfoLog(const ShHandle handle);
+
+// Returns null-terminated object code for a compiled shader.
+// Parameters:
+// handle: Specifies the compiler
+const std::string &GetObjectCode(const ShHandle handle);
+
+// Returns a (original_name, hash) map containing all the user defined names in the shader,
+// including variable names, function names, struct names, and struct field names.
+// Parameters:
+// handle: Specifies the compiler
+const std::map<std::string, std::string> *GetNameHashingMap(const ShHandle handle);
+
+// Shader variable inspection.
+// Returns a pointer to a list of variables of the designated type.
+// (See ShaderVars.h for type definitions, included above)
+// Returns NULL on failure.
+// Parameters:
+// handle: Specifies the compiler
+const std::vector<sh::Uniform> *GetUniforms(const ShHandle handle);
+const std::vector<sh::Varying> *GetVaryings(const ShHandle handle);
+const std::vector<sh::Attribute> *GetAttributes(const ShHandle handle);
+const std::vector<sh::OutputVariable> *GetOutputVariables(const ShHandle handle);
+const std::vector<sh::InterfaceBlock> *GetInterfaceBlocks(const ShHandle handle);
+sh::WorkGroupSize GetComputeShaderLocalGroupSize(const ShHandle handle);
+
+// Returns true if the passed in variables pack in maxVectors followingthe packing rules from the
+// GLSL 1.017 spec, Appendix A, section 7.
+// Returns false otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
+// flag above.
+// Parameters:
+// maxVectors: the available rows of registers.
+// variables: an array of variables.
+bool CheckVariablesWithinPackingLimits(int maxVectors,
+                                       const std::vector<sh::ShaderVariable> &variables);
+
+// Gives the compiler-assigned register for an interface block.
+// The method writes the value to the output variable "indexOut".
+// Returns true if it found a valid interface block, false otherwise.
+// Parameters:
+// handle: Specifies the compiler
+// interfaceBlockName: Specifies the interface block
+// indexOut: output variable that stores the assigned register
+bool GetInterfaceBlockRegister(const ShHandle handle,
+                               const std::string &interfaceBlockName,
+                               unsigned int *indexOut);
+
+// Gives a map from uniform names to compiler-assigned registers in the default interface block.
+// Note that the map contains also registers of samplers that have been extracted from structs.
+const std::map<std::string, unsigned int> *GetUniformRegisterMap(const ShHandle handle);
+
+}  // namespace sh
 
 #endif // GLSLANG_SHADERLANG_H_
--- a/gfx/angle/include/GLSLANG/ShaderVars.h
+++ b/gfx/angle/include/GLSLANG/ShaderVars.h
@@ -24,31 +24,31 @@ namespace sh
 enum InterpolationType
 {
     INTERPOLATION_SMOOTH,
     INTERPOLATION_CENTROID,
     INTERPOLATION_FLAT
 };
 
 // Validate link & SSO consistency of interpolation qualifiers
-COMPILER_EXPORT bool InterpolationTypesMatch(InterpolationType a, InterpolationType b);
+bool InterpolationTypesMatch(InterpolationType a, InterpolationType b);
 
 // Uniform block layout qualifier, see section 4.3.8.3 of the ESSL 3.00.4 spec
 enum BlockLayoutType
 {
     BLOCKLAYOUT_STANDARD,
     BLOCKLAYOUT_PACKED,
     BLOCKLAYOUT_SHARED
 };
 
 // Base class for all variables defined in shaders, including Varyings, Uniforms, etc
 // Note: we must override the copy constructor and assignment operator so we can
 // work around excessive GCC binary bloating:
 // See https://code.google.com/p/angleproject/issues/detail?id=697
-struct COMPILER_EXPORT ShaderVariable
+struct ShaderVariable
 {
     ShaderVariable();
     ShaderVariable(GLenum typeIn, unsigned int arraySizeIn);
     ~ShaderVariable();
     ShaderVariable(const ShaderVariable &other);
     ShaderVariable &operator=(const ShaderVariable &other);
 
     bool isArray() const { return arraySize > 0; }
@@ -87,17 +87,17 @@ struct COMPILER_EXPORT ShaderVariable
 
     bool operator==(const ShaderVariable &other) const;
     bool operator!=(const ShaderVariable &other) const
     {
         return !operator==(other);
     }
 };
 
-struct COMPILER_EXPORT Uniform : public ShaderVariable
+struct Uniform : public ShaderVariable
 {
     Uniform();
     ~Uniform();
     Uniform(const Uniform &other);
     Uniform &operator=(const Uniform &other);
     bool operator==(const Uniform &other) const;
     bool operator!=(const Uniform &other) const
     {
@@ -108,49 +108,49 @@ struct COMPILER_EXPORT Uniform : public 
     // assuming one from vertex shader and the other from fragment shader.
     // See GLSL ES Spec 3.00.3, sec 4.3.5.
     bool isSameUniformAtLinkTime(const Uniform &other) const;
 };
 
 // An interface variable is a variable which passes data between the GL data structures and the
 // shader execution: either vertex shader inputs or fragment shader outputs. These variables can
 // have integer locations to pass back to the GL API.
-struct COMPILER_EXPORT InterfaceVariable : public ShaderVariable
+struct InterfaceVariable : public ShaderVariable
 {
     InterfaceVariable();
     ~InterfaceVariable();
     InterfaceVariable(const InterfaceVariable &other);
     InterfaceVariable &operator=(const InterfaceVariable &other);
     bool operator==(const InterfaceVariable &other) const;
     bool operator!=(const InterfaceVariable &other) const { return !operator==(other); }
 
     int location;
 };
 
-struct COMPILER_EXPORT Attribute : public InterfaceVariable
+struct Attribute : public InterfaceVariable
 {
     Attribute();
     ~Attribute();
     Attribute(const Attribute &other);
     Attribute &operator=(const Attribute &other);
     bool operator==(const Attribute &other) const;
     bool operator!=(const Attribute &other) const { return !operator==(other); }
 };
 
-struct COMPILER_EXPORT OutputVariable : public InterfaceVariable
+struct OutputVariable : public InterfaceVariable
 {
     OutputVariable();
     ~OutputVariable();
     OutputVariable(const OutputVariable &other);
     OutputVariable &operator=(const OutputVariable &other);
     bool operator==(const OutputVariable &other) const;
     bool operator!=(const OutputVariable &other) const { return !operator==(other); }
 };
 
-struct COMPILER_EXPORT InterfaceBlockField : public ShaderVariable
+struct InterfaceBlockField : public ShaderVariable
 {
     InterfaceBlockField();
     ~InterfaceBlockField();
     InterfaceBlockField(const InterfaceBlockField &other);
     InterfaceBlockField &operator=(const InterfaceBlockField &other);
     bool operator==(const InterfaceBlockField &other) const;
     bool operator!=(const InterfaceBlockField &other) const
     {
@@ -162,17 +162,17 @@ struct COMPILER_EXPORT InterfaceBlockFie
     // fragment shader.
     // See GLSL ES Spec 3.00.3, sec 4.3.7.
     bool isSameInterfaceBlockFieldAtLinkTime(
         const InterfaceBlockField &other) const;
 
     bool isRowMajorLayout;
 };
 
-struct COMPILER_EXPORT Varying : public ShaderVariable
+struct Varying : public ShaderVariable
 {
     Varying();
     ~Varying();
     Varying(const Varying &otherg);
     Varying &operator=(const Varying &other);
     bool operator==(const Varying &other) const;
     bool operator!=(const Varying &other) const
     {
@@ -188,17 +188,17 @@ struct COMPILER_EXPORT Varying : public 
 
     // Deprecated version of isSameVaryingAtLinkTime, which assumes ESSL1.
     bool isSameVaryingAtLinkTime(const Varying &other) const;
 
     InterpolationType interpolation;
     bool isInvariant;
 };
 
-struct COMPILER_EXPORT InterfaceBlock
+struct InterfaceBlock
 {
     InterfaceBlock();
     ~InterfaceBlock();
     InterfaceBlock(const InterfaceBlock &other);
     InterfaceBlock &operator=(const InterfaceBlock &other);
 
     // Fields from blocks with non-empty instance names are prefixed with the block name.
     std::string fieldPrefix() const;
@@ -211,17 +211,17 @@ struct COMPILER_EXPORT InterfaceBlock
     std::string instanceName;
     unsigned int arraySize;
     BlockLayoutType layout;
     bool isRowMajorLayout;
     bool staticUse;
     std::vector<InterfaceBlockField> fields;
 };
 
-struct COMPILER_EXPORT WorkGroupSize
+struct WorkGroupSize
 {
     void fill(int fillValue);
     void setLocalSize(int localSizeX, int localSizeY, int localSizeZ);
 
     int &operator[](size_t index);
     int operator[](size_t index) const;
     size_t size() const;
 
--- a/gfx/angle/moz.build
+++ b/gfx/angle/moz.build
@@ -69,56 +69,59 @@ UNIFIED_SOURCES += [
     'src/compiler/translator/OutputHLSL.cpp',
     'src/compiler/translator/ParseContext.cpp',
     'src/compiler/translator/PoolAlloc.cpp',
     'src/compiler/translator/PruneEmptyDeclarations.cpp',
     'src/compiler/translator/QualifierTypes.cpp',
     'src/compiler/translator/RecordConstantPrecision.cpp',
     'src/compiler/translator/RegenerateStructNames.cpp',
     'src/compiler/translator/RemoveDynamicIndexing.cpp',
+    'src/compiler/translator/RemoveInvariantDeclaration.cpp',
     'src/compiler/translator/RemovePow.cpp',
     'src/compiler/translator/RemoveSwitchFallThrough.cpp',
     'src/compiler/translator/RewriteDoWhile.cpp',
     'src/compiler/translator/RewriteElseBlocks.cpp',
-    'src/compiler/translator/RewriteTexelFetchOffset.cpp',
+    'src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp',
     'src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp',
     'src/compiler/translator/SearchSymbol.cpp',
     'src/compiler/translator/SeparateArrayInitialization.cpp',
     'src/compiler/translator/SeparateDeclarations.cpp',
     'src/compiler/translator/SeparateExpressionsReturningArrays.cpp',
-    'src/compiler/translator/ShaderLang.cpp',
     'src/compiler/translator/ShaderVars.cpp',
     'src/compiler/translator/SimplifyLoopConditions.cpp',
     'src/compiler/translator/SplitSequenceOperator.cpp',
     'src/compiler/translator/StructureHLSL.cpp',
     'src/compiler/translator/SymbolTable.cpp',
     'src/compiler/translator/TextureFunctionHLSL.cpp',
     'src/compiler/translator/TranslatorESSL.cpp',
     'src/compiler/translator/TranslatorGLSL.cpp',
     'src/compiler/translator/TranslatorHLSL.cpp',
     'src/compiler/translator/Types.cpp',
     'src/compiler/translator/UnfoldShortCircuitAST.cpp',
     'src/compiler/translator/UnfoldShortCircuitToIf.cpp',
     'src/compiler/translator/UniformHLSL.cpp',
+    'src/compiler/translator/UseInterfaceBlockFields.cpp',
     'src/compiler/translator/util.cpp',
     'src/compiler/translator/UtilsHLSL.cpp',
     'src/compiler/translator/ValidateGlobalInitializer.cpp',
     'src/compiler/translator/ValidateLimitations.cpp',
     'src/compiler/translator/ValidateMaxParameters.cpp',
     'src/compiler/translator/ValidateOutputs.cpp',
     'src/compiler/translator/ValidateSwitch.cpp',
     'src/compiler/translator/VariableInfo.cpp',
     'src/compiler/translator/VariablePacker.cpp',
     'src/compiler/translator/VersionGLSL.cpp',
     'src/third_party/compiler/ArrayBoundsClamper.cpp',
 ]
 SOURCES += [
     'src/compiler/translator/EmulateGLFragColorBroadcast.cpp',
     'src/compiler/translator/glslang_lex.cpp',
     'src/compiler/translator/glslang_tab.cpp',
+    'src/compiler/translator/RewriteTexelFetchOffset.cpp',
+    'src/compiler/translator/ShaderLang.cpp',
 ]
 
 
 if CONFIG['GNU_CXX']:
     CXXFLAGS += [
         '-Wno-attributes',
         '-Wno-shadow',
         '-Wno-sign-compare',
--- a/gfx/angle/src/angle.gyp
+++ b/gfx/angle/src/angle.gyp
@@ -40,30 +40,31 @@
             {
                 'angle_enable_gl%': 1,
             }],
             ['use_ozone==1',
             {
                 'angle_enable_gl%': 1,
             }],
         ],
+        'angle_enable_null%': 1, # Available on all platforms
     },
     'includes':
     [
         'compiler.gypi',
         'libGLESv2.gypi',
         'libEGL.gypi'
     ],
 
     'targets':
     [
         {
             'target_name': 'angle_common',
             'type': 'static_library',
-            'includes': [ '../build/common_defines.gypi', ],
+            'includes': [ '../gyp/common_defines.gypi', ],
             'sources':
             [
                 '<@(libangle_common_sources)',
             ],
             'include_dirs':
             [
                 '.',
                 '../include',
@@ -140,17 +141,17 @@
                     },
                 }],
             ],
         },
 
         {
             'target_name': 'angle_image_util',
             'type': 'static_library',
-            'includes': [ '../build/common_defines.gypi', ],
+            'includes': [ '../gyp/common_defines.gypi', ],
             'sources':
             [
                 '<@(libangle_image_util_sources)',
             ],
             'include_dirs':
             [
                 '.',
                 '../include',
@@ -167,17 +168,17 @@
                     '<(angle_path)/src',
                 ],
             },
         },
 
         {
             'target_name': 'copy_scripts',
             'type': 'none',
-            'includes': [ '../build/common_defines.gypi', ],
+            'includes': [ '../gyp/common_defines.gypi', ],
             'hard_dependency': 1,
             'copies':
             [
                 {
                     'destination': '<(angle_gen_path)',
                     'files': [ 'copy_compiler_dll.bat', '<(angle_id_script_base)' ],
                 },
             ],
@@ -194,17 +195,17 @@
     [
         ['angle_use_commit_id!=0',
         {
             'targets':
             [
                 {
                     'target_name': 'commit_id',
                     'type': 'none',
-                    'includes': [ '../build/common_defines.gypi', ],
+                    'includes': [ '../gyp/common_defines.gypi', ],
                     'dependencies': [ 'copy_scripts', ],
                     'hard_dependency': 1,
                     'actions':
                     [
                         {
                             'action_name': 'Generate ANGLE Commit ID Header',
                             'message': 'Generating ANGLE Commit ID',
                             # reference the git index as an input, so we rebuild on changes to the index
@@ -236,17 +237,17 @@
         },
         { # angle_use_commit_id==0
             'targets':
             [
                 {
                     'target_name': 'commit_id',
                     'type': 'none',
                     'hard_dependency': 1,
-                    'includes': [ '../build/common_defines.gypi', ],
+                    'includes': [ '../gyp/common_defines.gypi', ],
                     'copies':
                     [
                         {
                             'destination': '<(angle_gen_path)/id',
                             'files': [ '<(angle_id_header_base)' ]
                         }
                     ],
                     'all_dependent_settings':
@@ -269,17 +270,17 @@
         ['OS=="win"',
         {
             'targets':
             [
                 {
                     'target_name': 'copy_compiler_dll',
                     'type': 'none',
                     'dependencies': [ 'copy_scripts', ],
-                    'includes': [ '../build/common_defines.gypi', ],
+                    'includes': [ '../gyp/common_defines.gypi', ],
                     'conditions':
                     [
                         ['angle_build_winrt==0',
                         {
                             'actions':
                             [
                                 {
                                     'action_name': 'copy_dll',
--- a/gfx/angle/src/commit.h
+++ b/gfx/angle/src/commit.h
@@ -1,3 +1,3 @@
-#define ANGLE_COMMIT_HASH "8b3e8b4d1b09"
+#define ANGLE_COMMIT_HASH "2a250c8a0e15"
 #define ANGLE_COMMIT_HASH_SIZE 12
-#define ANGLE_COMMIT_DATE "2016-10-24 15:38:47 +0800"
+#define ANGLE_COMMIT_DATE "2016-11-23 17:58:16 +0800"
--- a/gfx/angle/src/common/BitSetIterator.h
+++ b/gfx/angle/src/common/BitSetIterator.h
@@ -99,17 +99,16 @@ typename BitSetIterator<N>::Iterator &Bi
 
 inline unsigned long ScanForward(unsigned long bits)
 {
     ASSERT(bits != 0);
 #if defined(ANGLE_PLATFORM_WINDOWS)
     unsigned long firstBitIndex = 0ul;
     unsigned char ret = _BitScanForward(&firstBitIndex, bits);
     ASSERT(ret != 0);
-    UNUSED_ASSERTION_VARIABLE(ret);
     return firstBitIndex;
 #elif defined(ANGLE_PLATFORM_POSIX)
     return static_cast<unsigned long>(__builtin_ctzl(bits));
 #else
 #error Please implement bit-scan-forward for your platform!
 #endif
 }
 
--- a/gfx/angle/src/common/angleutils.h
+++ b/gfx/angle/src/common/angleutils.h
@@ -151,16 +151,24 @@ inline std::string Str(int i)
     return strstr.str();
 }
 
 size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& buffer);
 
 std::string FormatString(const char *fmt, va_list vararg);
 std::string FormatString(const char *fmt, ...);
 
+template <typename T>
+std::string ToString(const T &value)
+{
+    std::ostringstream o;
+    o << value;
+    return o.str();
+}
+
 // snprintf is not defined with MSVC prior to to msvc14
 #if defined(_MSC_VER) && _MSC_VER < 1900
 #define snprintf _snprintf
 #endif
 
 #define GL_BGR565_ANGLEX 0x6ABB
 #define GL_BGRA4_ANGLEX 0x6ABC
 #define GL_BGR5_A1_ANGLEX 0x6ABD
--- a/gfx/angle/src/common/debug.cpp
+++ b/gfx/angle/src/common/debug.cpp
@@ -166,9 +166,14 @@ ScopedPerfEventHelper::ScopedPerfEventHe
 ScopedPerfEventHelper::~ScopedPerfEventHelper()
 {
     if (DebugAnnotationsActive())
     {
         g_debugAnnotator->endEvent();
     }
 }
 
+std::ostream &DummyStream()
+{
+    return std::cout;
 }
+
+}  // namespace gl
--- a/gfx/angle/src/common/debug.h
+++ b/gfx/angle/src/common/debug.h
@@ -52,17 +52,30 @@ class DebugAnnotator : angle::NonCopyabl
     virtual void setMarker(const wchar_t *markerName) = 0;
     virtual bool getStatus() = 0;
 };
 
 void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator);
 void UninitializeDebugAnnotations();
 bool DebugAnnotationsActive();
 
-}
+// This class is used to explicitly ignore values in the conditional logging macros. This avoids
+// compiler warnings like "value computed is not used" and "statement has no effect".
+class LogMessageVoidify
+{
+  public:
+    LogMessageVoidify() {}
+    // This has to be an operator with a precedence lower than << but higher than ?:
+    void operator&(std::ostream &) {}
+};
+
+// This can be any ostream, it is unused, but needs to be a valid reference.
+std::ostream &DummyStream();
+
+}  // namespace gl
 
 #if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
 #define ANGLE_TRACE_ENABLED
 #endif
 
 #define ANGLE_EMPTY_STATEMENT for (;;) break
 #if !defined(NDEBUG) || defined(ANGLE_ENABLE_RELEASE_ASSERTS)
 #define ANGLE_ENABLE_ASSERTS
@@ -99,66 +112,63 @@ bool DebugAnnotationsActive();
 #else
 #define EVENT(message, ...) (void(0))
 #endif
 
 #if defined(ANGLE_TRACE_ENABLED)
 #undef ANGLE_TRACE_ENABLED
 #endif
 
+#if defined(COMPILER_GCC) || defined(__clang__)
+#define ANGLE_CRASH() __builtin_trap()
+#else
+#define ANGLE_CRASH() ((void)(*(volatile char *)0 = 0))
+#endif
+
 #if !defined(NDEBUG)
 #define ANGLE_ASSERT_IMPL(expression) assert(expression)
 #else
 // TODO(jmadill): Detect if debugger is attached and break.
-#define ANGLE_ASSERT_IMPL(expression) abort()
+#define ANGLE_ASSERT_IMPL(expression) ANGLE_CRASH()
 #endif  // !defined(NDEBUG)
 
+// Helper macro which avoids evaluating the arguments to a stream if the condition doesn't hold.
+// Condition is evaluated once and only once.
+#define ANGLE_LAZY_STREAM(stream, condition) \
+    !(condition) ? static_cast<void>(0) : ::gl::LogMessageVoidify() & (stream)
+
+#if defined(NDEBUG) && !defined(ANGLE_ENABLE_ASSERTS)
+#define ANGLE_ASSERTS_ON 0
+#else
+#define ANGLE_ASSERTS_ON 1
+#endif
+
 // A macro asserting a condition and outputting failures to the debug log
-#if defined(ANGLE_ENABLE_ASSERTS)
-#define ASSERT(expression)                                                                 \
-    {                                                                                      \
-        if (!(expression))                                                                 \
-        {                                                                                  \
-            ERR("\t! Assert failed in %s(%d): %s\n", __FUNCTION__, __LINE__, #expression); \
-            ANGLE_ASSERT_IMPL(expression);                                                 \
-        }                                                                                  \
-    }                                                                                      \
-    ANGLE_EMPTY_STATEMENT
-#define UNUSED_ASSERTION_VARIABLE(variable)
+#if ANGLE_ASSERTS_ON
+#define ASSERT(expression)                                                                        \
+    (expression ? static_cast<void>(0)                                                            \
+                : (ERR("\t! Assert failed in %s(%d): %s\n", __FUNCTION__, __LINE__, #expression), \
+                   ANGLE_ASSERT_IMPL(expression)))
 #else
-#define ASSERT(expression) (void(0))
-#define UNUSED_ASSERTION_VARIABLE(variable) ((void)variable)
-#endif
+#define ASSERT(condition)                                                           \
+    ANGLE_LAZY_STREAM(::gl::DummyStream(), ANGLE_ASSERTS_ON ? !(condition) : false) \
+        << "Check failed: " #condition ". "
+#endif  // ANGLE_ASSERTS_ON
 
 #define UNUSED_VARIABLE(variable) ((void)variable)
 
 // A macro to indicate unimplemented functionality
-
-#if defined (ANGLE_TEST_CONFIG)
+#ifndef NOASSERT_UNIMPLEMENTED
 #define NOASSERT_UNIMPLEMENTED 1
 #endif
 
-// Define NOASSERT_UNIMPLEMENTED to non zero to skip the assert fail in the unimplemented checks
-// This will allow us to test with some automated test suites (eg dEQP) without crashing
-#ifndef NOASSERT_UNIMPLEMENTED
-#define NOASSERT_UNIMPLEMENTED 0
-#endif
-
-#if !defined(NDEBUG)
-#define UNIMPLEMENTED() { \
-    FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \
-    assert(NOASSERT_UNIMPLEMENTED); \
-    } ANGLE_EMPTY_STATEMENT
-#else
-    #define UNIMPLEMENTED() FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__)
-#endif
+#define UNIMPLEMENTED()                                             \
+    {                                                               \
+        ERR("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \
+        ASSERT(NOASSERT_UNIMPLEMENTED);                             \
+    }                                                               \
+    ANGLE_EMPTY_STATEMENT
 
 // A macro for code which is not expected to be reached under valid assumptions
-#if !defined(NDEBUG)
-#define UNREACHABLE() { \
-    ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__); \
-    assert(false); \
-    } ANGLE_EMPTY_STATEMENT
-#else
-    #define UNREACHABLE() ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__)
-#endif
+#define UNREACHABLE() \
+    (ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__), ASSERT(false))
 
 #endif   // COMMON_DEBUG_H_
--- a/gfx/angle/src/common/mathutil.cpp
+++ b/gfx/angle/src/common/mathutil.cpp
@@ -9,36 +9,42 @@
 #include "common/mathutil.h"
 
 #include <algorithm>
 #include <math.h>
 
 namespace gl
 {
 
+namespace
+{
+
 struct RGB9E5Data
 {
     unsigned int R : 9;
     unsigned int G : 9;
     unsigned int B : 9;
     unsigned int E : 5;
 };
 
 // B is the exponent bias (15)
-static const int g_sharedexp_bias = 15;
+constexpr int g_sharedexp_bias = 15;
 
 // N is the number of mantissa bits per component (9)
-static const int g_sharedexp_mantissabits = 9;
+constexpr int g_sharedexp_mantissabits = 9;
 
 // Emax is the maximum allowed biased exponent value (31)
-static const int g_sharedexp_maxexponent = 31;
+constexpr int g_sharedexp_maxexponent = 31;
 
-static const float g_sharedexp_max = ((pow(2.0f, g_sharedexp_mantissabits) - 1) /
-                                       pow(2.0f, g_sharedexp_mantissabits)) *
-                                     pow(2.0f, g_sharedexp_maxexponent - g_sharedexp_bias);
+constexpr float g_sharedexp_max =
+    ((static_cast<float>(1 << g_sharedexp_mantissabits) - 1) /
+     static_cast<float>(1 << g_sharedexp_mantissabits)) *
+    static_cast<float>(1 << (g_sharedexp_maxexponent - g_sharedexp_bias));
+
+}  // anonymous namespace
 
 unsigned int convertRGBFloatsTo999E5(float red, float green, float blue)
 {
     const float red_c = std::max<float>(0, std::min(g_sharedexp_max, red));
     const float green_c = std::max<float>(0, std::min(g_sharedexp_max, green));
     const float blue_c = std::max<float>(0, std::min(g_sharedexp_max, blue));
 
     const float max_c = std::max<float>(std::max<float>(red_c, green_c), blue_c);
--- a/gfx/angle/src/common/mathutil.h
+++ b/gfx/angle/src/common/mathutil.h
@@ -39,16 +39,25 @@ struct Vector4
     Vector4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {}
 
     float x;
     float y;
     float z;
     float w;
 };
 
+struct Vector2
+{
+    Vector2() {}
+    Vector2(float x, float y) : x(x), y(y) {}
+
+    float x;
+    float y;
+};
+
 inline bool isPow2(int x)
 {
     return (x & (x - 1)) == 0 && (x != 0);
 }
 
 inline int log2(int x)
 {
     int r = 0;
@@ -751,16 +760,50 @@ struct iSquareRoot<N, N>
 }  // namespace priv
 
 template <unsigned int N>
 constexpr unsigned int iSquareRoot()
 {
     return priv::iSquareRoot<N, 1>::value;
 }
 
+// Sum, difference and multiplication operations for signed ints that wrap on 32-bit overflow.
+//
+// Unsigned types are defined to do arithmetic modulo 2^n in C++. For signed types, overflow
+// behavior is undefined.
+
+template <typename T>
+inline T WrappingSum(T lhs, T rhs)
+{
+    uint32_t lhsUnsigned = static_cast<uint32_t>(lhs);
+    uint32_t rhsUnsigned = static_cast<uint32_t>(rhs);
+    return static_cast<T>(lhsUnsigned + rhsUnsigned);
+}
+
+template <typename T>
+inline T WrappingDiff(T lhs, T rhs)
+{
+    uint32_t lhsUnsigned = static_cast<uint32_t>(lhs);
+    uint32_t rhsUnsigned = static_cast<uint32_t>(rhs);
+    return static_cast<T>(lhsUnsigned - rhsUnsigned);
+}
+
+inline int32_t WrappingMul(int32_t lhs, int32_t rhs)
+{
+    int64_t lhsWide = static_cast<int64_t>(lhs);
+    int64_t rhsWide = static_cast<int64_t>(rhs);
+    // The multiplication is guaranteed not to overflow.
+    int64_t resultWide = lhsWide * rhsWide;
+    // Implement the desired wrapping behavior by masking out the high-order 32 bits.
+    resultWide = resultWide & 0xffffffffll;
+    // Casting to a narrower signed type is fine since the casted value is representable in the
+    // narrower type.
+    return static_cast<int32_t>(resultWide);
+}
+
 }  // namespace gl
 
 namespace rx
 {
 
 template <typename T>
 T roundUp(const T value, const T alignment)
 {
--- a/gfx/angle/src/common/third_party/numerics/base/logging.h
+++ b/gfx/angle/src/common/third_party/numerics/base/logging.h
@@ -11,12 +11,12 @@
 #include "common/debug.h"
 
 #ifndef CHECK
 #define CHECK(X) ASSERT(X)
 #endif
 
 // Unfortunately ANGLE relies on ASSERT being an empty statement, which these libs don't respect.
 #ifndef NOTREACHED
-#define NOTREACHED() 0
+#define NOTREACHED() UNREACHABLE()
 #endif
 
-#endif  // BASE_LOGGING_H_
\ No newline at end of file
+#endif  // BASE_LOGGING_H_
--- a/gfx/angle/src/common/third_party/numerics/base/numerics/safe_conversions_impl.h
+++ b/gfx/angle/src/common/third_party/numerics/base/numerics/safe_conversions_impl.h
@@ -87,17 +87,17 @@ template <typename Dst, typename Src>
 struct StaticDstRangeRelationToSrcRange<Dst,
                                         Src,
                                         INTEGER_REPRESENTATION_UNSIGNED,
                                         INTEGER_REPRESENTATION_SIGNED>
 {
     static const NumericRangeRepresentation value = NUMERIC_RANGE_NOT_CONTAINED;
 };
 
-enum RangeConstraint
+enum RangeConstraint : unsigned char
 {
     RANGE_VALID     = 0x0,  // Value can be represented by the destination type.
     RANGE_UNDERFLOW = 0x1,  // Value would overflow.
     RANGE_OVERFLOW  = 0x2,  // Value would underflow.
     RANGE_INVALID   = RANGE_UNDERFLOW | RANGE_OVERFLOW  // Invalid (i.e. NaN).
 };
 
 // Helper function for coercing an int back to a RangeContraint.
--- a/gfx/angle/src/common/utilities.cpp
+++ b/gfx/angle/src/common/utilities.cpp
@@ -242,17 +242,29 @@ int VariableRowCount(GLenum type)
       case GL_INT_SAMPLER_2D_ARRAY:
       case GL_UNSIGNED_INT_SAMPLER_2D:
       case GL_UNSIGNED_INT_SAMPLER_3D:
       case GL_UNSIGNED_INT_SAMPLER_CUBE:
       case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
       case GL_SAMPLER_2D_SHADOW:
       case GL_SAMPLER_CUBE_SHADOW:
       case GL_SAMPLER_2D_ARRAY_SHADOW:
-        return 1;
+      case GL_IMAGE_2D:
+      case GL_INT_IMAGE_2D:
+      case GL_UNSIGNED_INT_IMAGE_2D:
+      case GL_IMAGE_2D_ARRAY:
+      case GL_INT_IMAGE_2D_ARRAY:
+      case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
+      case GL_IMAGE_3D:
+      case GL_INT_IMAGE_3D:
+      case GL_UNSIGNED_INT_IMAGE_3D:
+      case GL_IMAGE_CUBE:
+      case GL_INT_IMAGE_CUBE:
+      case GL_UNSIGNED_INT_IMAGE_CUBE:
+          return 1;
       case GL_FLOAT_MAT2:
       case GL_FLOAT_MAT3x2:
       case GL_FLOAT_MAT4x2:
         return 2;
       case GL_FLOAT_MAT3:
       case GL_FLOAT_MAT2x3:
       case GL_FLOAT_MAT4x3:
         return 3;
@@ -639,16 +651,39 @@ std::string ParseUniformName(const std::
         {
             *outSubscript = GL_INVALID_INDEX;
         }
     }
 
     return name.substr(0, open);
 }
 
+template <>
+GLuint ConvertToGLuint(GLfloat param)
+{
+    return uiround<GLuint>(param);
+}
+
+template <>
+GLint ConvertToGLint(GLfloat param)
+{
+    return iround<GLint>(param);
+}
+
+template <>
+GLint ConvertFromGLfloat(GLfloat param)
+{
+    return iround<GLint>(param);
+}
+template <>
+GLuint ConvertFromGLfloat(GLfloat param)
+{
+    return uiround<GLuint>(param);
+}
+
 unsigned int ParseAndStripArrayIndex(std::string *name)
 {
     unsigned int subscript = GL_INVALID_INDEX;
 
     // Strip any trailing array operator and retrieve the subscript
     size_t open  = name->find_last_of('[');
     size_t close = name->find_last_of(']');
     if (open != std::string::npos && close == name->length() - 1)
--- a/gfx/angle/src/common/utilities.h
+++ b/gfx/angle/src/common/utilities.h
@@ -63,16 +63,86 @@ GLuint GetPrimitiveRestartIndex(GLenum i
 bool IsTriangleMode(GLenum drawMode);
 
 // [OpenGL ES 3.0.2] Section 2.3.1 page 14
 // Data Conversion For State-Setting Commands
 // Floating-point values are rounded to the nearest integer, instead of truncated, as done by static_cast.
 template <typename outT> outT iround(GLfloat value) { return static_cast<outT>(value > 0.0f ? floor(value + 0.5f) : ceil(value - 0.5f)); }
 template <typename outT> outT uiround(GLfloat value) { return static_cast<outT>(value + 0.5f); }
 
+// Helper for converting arbitrary GL types to other GL types used in queries and state setting
+template <typename ParamType>
+GLuint ConvertToGLuint(ParamType param)
+{
+    return static_cast<GLuint>(param);
+}
+template <>
+GLuint ConvertToGLuint(GLfloat param);
+
+template <typename ParamType>
+GLint ConvertToGLint(ParamType param)
+{
+    return static_cast<GLint>(param);
+}
+template <>
+GLint ConvertToGLint(GLfloat param);
+
+// Same conversion as uint
+template <typename ParamType>
+GLenum ConvertToGLenum(ParamType param)
+{
+    return static_cast<GLenum>(ConvertToGLuint(param));
+}
+
+template <typename ParamType>
+GLfloat ConvertToGLfloat(ParamType param)
+{
+    return static_cast<GLfloat>(param);
+}
+
+template <typename ParamType>
+ParamType ConvertFromGLfloat(GLfloat param)
+{
+    return static_cast<ParamType>(param);
+}
+template <>
+GLint ConvertFromGLfloat(GLfloat param);
+template <>
+GLuint ConvertFromGLfloat(GLfloat param);
+
+template <typename ParamType>
+ParamType ConvertFromGLenum(GLenum param)
+{
+    return static_cast<ParamType>(param);
+}
+
+template <typename ParamType>
+ParamType ConvertFromGLuint(GLuint param)
+{
+    return static_cast<ParamType>(param);
+}
+
+template <typename ParamType>
+ParamType ConvertFromGLint(GLint param)
+{
+    return static_cast<ParamType>(param);
+}
+
+template <typename ParamType>
+ParamType ConvertFromGLboolean(GLboolean param)
+{
+    return static_cast<ParamType>(param ? GL_TRUE : GL_FALSE);
+}
+
+template <typename ParamType>
+ParamType ConvertFromGLint64(GLint64 param)
+{
+    return clampCast<ParamType>(param);
+}
+
 unsigned int ParseAndStripArrayIndex(std::string *name);
 
 }  // namespace gl
 
 namespace egl
 {
 static const EGLenum FirstCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR;
 static const EGLenum LastCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR;
--- a/gfx/angle/src/compiler.gypi
+++ b/gfx/angle/src/compiler.gypi
@@ -1,17 +1,17 @@
 # Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 {
     'variables':
     {
         # These file lists are shared with the GN build.
-        'angle_translator_lib_sources':
+        'angle_translator_sources':
         [
             '../include/EGL/egl.h',
             '../include/EGL/eglext.h',
             '../include/EGL/eglplatform.h',
             '../include/GLES2/gl2.h',
             '../include/GLES2/gl2ext.h',
             '../include/GLES2/gl2platform.h',
             '../include/GLES3/gl3.h',
@@ -87,32 +87,40 @@
             'compiler/translator/PruneEmptyDeclarations.cpp',
             'compiler/translator/PruneEmptyDeclarations.h',
             'compiler/translator/QualifierTypes.h',
             'compiler/translator/QualifierTypes.cpp',
             'compiler/translator/RecordConstantPrecision.cpp',
             'compiler/translator/RecordConstantPrecision.h',
             'compiler/translator/RegenerateStructNames.cpp',
             'compiler/translator/RegenerateStructNames.h',
+            'compiler/translator/RemoveInvariantDeclaration.cpp',
+            'compiler/translator/RemoveInvariantDeclaration.h',
             'compiler/translator/RemovePow.cpp',
             'compiler/translator/RemovePow.h',
             'compiler/translator/RewriteDoWhile.cpp',
             'compiler/translator/RewriteDoWhile.h',
             'compiler/translator/RewriteTexelFetchOffset.cpp',
             'compiler/translator/RewriteTexelFetchOffset.h',
+            'compiler/translator/RewriteUnaryMinusOperatorInt.cpp',
+            'compiler/translator/RewriteUnaryMinusOperatorInt.h',
             'compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp',
             'compiler/translator/ScalarizeVecAndMatConstructorArgs.h',
             'compiler/translator/SearchSymbol.cpp',
             'compiler/translator/SearchSymbol.h',
+            'compiler/translator/ShaderLang.cpp',
+            'compiler/translator/ShaderVars.cpp',
             'compiler/translator/SymbolTable.cpp',
             'compiler/translator/SymbolTable.h',
             'compiler/translator/Types.cpp',
             'compiler/translator/Types.h',
             'compiler/translator/UnfoldShortCircuitAST.cpp',
             'compiler/translator/UnfoldShortCircuitAST.h',
+            'compiler/translator/UseInterfaceBlockFields.cpp',
+            'compiler/translator/UseInterfaceBlockFields.h',
             'compiler/translator/ValidateGlobalInitializer.cpp',
             'compiler/translator/ValidateGlobalInitializer.h',
             'compiler/translator/ValidateLimitations.cpp',
             'compiler/translator/ValidateLimitations.h',
             'compiler/translator/ValidateMaxParameters.h',
             'compiler/translator/ValidateMaxParameters.cpp',
             'compiler/translator/ValidateOutputs.cpp',
             'compiler/translator/ValidateOutputs.h',
@@ -132,39 +140,39 @@
             'compiler/translator/glslang_tab.h',
             'compiler/translator/intermOut.cpp',
             'compiler/translator/length_limits.h',
             'compiler/translator/util.cpp',
             'compiler/translator/util.h',
             'third_party/compiler/ArrayBoundsClamper.cpp',
             'third_party/compiler/ArrayBoundsClamper.h',
         ],
-        'angle_translator_lib_essl_sources':
+        'angle_translator_essl_sources':
         [
             'compiler/translator/OutputESSL.cpp',
             'compiler/translator/OutputESSL.h',
             'compiler/translator/TranslatorESSL.cpp',
             'compiler/translator/TranslatorESSL.h',
         ],
-        'angle_translator_lib_glsl_sources':
+        'angle_translator_glsl_sources':
         [
             'compiler/translator/BuiltInFunctionEmulatorGLSL.cpp',
             'compiler/translator/BuiltInFunctionEmulatorGLSL.h',
             'compiler/translator/ExtensionGLSL.cpp',
             'compiler/translator/ExtensionGLSL.h',
             'compiler/translator/OutputGLSL.cpp',
             'compiler/translator/OutputGLSL.h',
             'compiler/translator/OutputGLSLBase.cpp',
             'compiler/translator/OutputGLSLBase.h',
             'compiler/translator/TranslatorGLSL.cpp',
             'compiler/translator/TranslatorGLSL.h',
             'compiler/translator/VersionGLSL.cpp',
             'compiler/translator/VersionGLSL.h',
         ],
-        'angle_translator_lib_hlsl_sources':
+        'angle_translator_hlsl_sources':
         [
             'compiler/translator/AddDefaultReturnStatements.cpp',
             'compiler/translator/AddDefaultReturnStatements.h',
             'compiler/translator/ArrayReturnValueToOutParameter.cpp',
             'compiler/translator/ArrayReturnValueToOutParameter.h',
             'compiler/translator/ASTMetadataHLSL.cpp',
             'compiler/translator/ASTMetadataHLSL.h',
             'compiler/translator/blocklayoutHLSL.cpp',
@@ -227,48 +235,42 @@
             'compiler/preprocessor/Preprocessor.h',
             'compiler/preprocessor/SourceLocation.h',
             'compiler/preprocessor/Token.cpp',
             'compiler/preprocessor/Token.h',
             'compiler/preprocessor/Tokenizer.cpp',
             'compiler/preprocessor/Tokenizer.h',
             'compiler/preprocessor/Tokenizer.l',
             'compiler/preprocessor/numeric_lex.h',
-            'compiler/preprocessor/pp_utils.h',
         ],
     },
     # Everything below this is duplicated in the GN build. If you change
     # anything also change angle/BUILD.gn
     'targets':
     [
         {
             'target_name': 'preprocessor',
             'type': 'static_library',
-            'includes': [ '../build/common_defines.gypi', ],
+            'dependencies': [ 'angle_common' ],
+            'includes': [ '../gyp/common_defines.gypi', ],
             'sources': [ '<@(angle_preprocessor_sources)', ],
         },
         {
-            'target_name': 'translator_lib',
+            'target_name': 'translator',
             'type': 'static_library',
             'dependencies': [ 'preprocessor', 'angle_common' ],
-            'includes': [ '../build/common_defines.gypi', ],
+            'includes': [ '../gyp/common_defines.gypi', ],
             'include_dirs':
             [
                 '.',
                 '../include',
             ],
-            'defines':
-            [
-                # define the static translator to indicate exported
-                # classes are (in fact) locally defined
-                'ANGLE_TRANSLATOR_STATIC',
-            ],
             'sources':
             [
-                '<@(angle_translator_lib_sources)',
+                '<@(angle_translator_sources)',
             ],
             'msvs_settings':
             {
               'VCLibrarianTool':
               {
                 'AdditionalOptions': ['/ignore:4221']
               },
             },
@@ -284,17 +286,17 @@
                     {
                         'defines':
                         [
                             'ANGLE_ENABLE_ESSL',
                         ],
                     },
                     'sources':
                     [
-                        '<@(angle_translator_lib_essl_sources)',
+                        '<@(angle_translator_essl_sources)',
                     ],
                 }],
                 ['angle_enable_glsl==1',
                 {
                     'defines':
                     [
                         'ANGLE_ENABLE_GLSL',
                     ],
@@ -302,17 +304,17 @@
                     {
                         'defines':
                         [
                             'ANGLE_ENABLE_GLSL',
                         ],
                     },
                     'sources':
                     [
-                        '<@(angle_translator_lib_glsl_sources)',
+                        '<@(angle_translator_glsl_sources)',
                     ],
                 }],
                 ['angle_enable_hlsl==1',
                 {
                     'defines':
                     [
                         'ANGLE_ENABLE_HLSL',
                     ],
@@ -320,64 +322,15 @@
                     {
                         'defines':
                         [
                             'ANGLE_ENABLE_HLSL',
                         ],
                     },
                     'sources':
                     [
-                        '<@(angle_translator_lib_hlsl_sources)',
+                        '<@(angle_translator_hlsl_sources)',
                     ],
                 }],
             ],
         },
-
-        {
-            'target_name': 'translator',
-            'type': '<(component)',
-            'dependencies': [ 'translator_lib', 'angle_common' ],
-            'includes': [ '../build/common_defines.gypi', ],
-            'include_dirs':
-            [
-                '.',
-                '../include',
-            ],
-            'defines':
-            [
-                'ANGLE_TRANSLATOR_IMPLEMENTATION',
-            ],
-            'sources':
-            [
-                'compiler/translator/ShaderLang.cpp',
-                'compiler/translator/ShaderVars.cpp'
-            ],
-        },
-
-        {
-            'target_name': 'translator_static',
-            'type': 'static_library',
-            'dependencies': [ 'translator_lib' ],
-            'includes': [ '../build/common_defines.gypi', ],
-            'include_dirs':
-            [
-                '.',
-                '../include',
-            ],
-            'defines':
-            [
-                'ANGLE_TRANSLATOR_STATIC',
-            ],
-            'direct_dependent_settings':
-            {
-                'defines':
-                [
-                    'ANGLE_TRANSLATOR_STATIC',
-                ],
-            },
-            'sources':
-            [
-                'compiler/translator/ShaderLang.cpp',
-                'compiler/translator/ShaderVars.cpp'
-            ],
-        },
     ],
 }
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/fuzz/translator_fuzzer.cpp
@@ -0,0 +1,161 @@
+//
+// Copyright (c) 2016 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.
+//
+
+// translator_fuzzer.cpp: A libfuzzer fuzzer for the shader translator.
+
+#include <stddef.h>
+#include <stdint.h>
+#include <unordered_map>
+#include <iostream>
+
+#include "compiler/translator/Compiler.h"
+#include "angle_gl.h"
+
+using namespace sh;
+
+struct TranslatorCacheKey
+{
+    bool operator==(const TranslatorCacheKey &other) const
+    {
+        return type == other.type && spec == other.spec && output == other.output;
+    }
+
+    uint32_t type   = 0;
+    uint32_t spec   = 0;
+    uint32_t output = 0;
+};
+
+namespace std
+{
+
+template <>
+struct hash<TranslatorCacheKey>
+{
+    std::size_t operator()(const TranslatorCacheKey &k) const
+    {
+        return (hash<uint32_t>()(k.type) << 1) ^ (hash<uint32_t>()(k.spec) >> 1) ^
+               hash<uint32_t>()(k.output);
+    }
+};
+}  // namespace std
+
+static std::unordered_map<TranslatorCacheKey, TCompiler *> translators;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+    // Reserve some size for future compile options
+    const size_t kHeaderSize = 128;
+
+    if (size <= kHeaderSize)
+    {
+        return 0;
+    }
+
+    // Make sure the rest of data will be a valid C string so that we don't have to copy it.
+    if (data[size - 1] != 0)
+    {
+        return 0;
+    }
+
+    uint32_t type    = *reinterpret_cast<const uint32_t *>(data);
+    uint32_t spec    = *reinterpret_cast<const uint32_t *>(data + 4);
+    uint32_t output  = *reinterpret_cast<const uint32_t *>(data + 8);
+    uint64_t options = *reinterpret_cast<const uint64_t *>(data + 12);
+
+    if (type != GL_FRAGMENT_SHADER && type != GL_VERTEX_SHADER)
+    {
+        return 0;
+    }
+
+    if (spec != SH_GLES2_SPEC && type != SH_WEBGL_SPEC && spec != SH_GLES3_SPEC &&
+        spec != SH_WEBGL2_SPEC)
+    {
+        return 0;
+    }
+
+    std::vector<uint32_t> validOutputs;
+    validOutputs.push_back(SH_ESSL_OUTPUT);
+    validOutputs.push_back(SH_GLSL_COMPATIBILITY_OUTPUT);
+    validOutputs.push_back(SH_GLSL_130_OUTPUT);
+    validOutputs.push_back(SH_GLSL_140_OUTPUT);
+    validOutputs.push_back(SH_GLSL_150_CORE_OUTPUT);
+    validOutputs.push_back(SH_GLSL_330_CORE_OUTPUT);
+    validOutputs.push_back(SH_GLSL_400_CORE_OUTPUT);
+    validOutputs.push_back(SH_GLSL_410_CORE_OUTPUT);
+    validOutputs.push_back(SH_GLSL_420_CORE_OUTPUT);
+    validOutputs.push_back(SH_GLSL_430_CORE_OUTPUT);
+    validOutputs.push_back(SH_GLSL_440_CORE_OUTPUT);
+    validOutputs.push_back(SH_GLSL_450_CORE_OUTPUT);
+    validOutputs.push_back(SH_HLSL_3_0_OUTPUT);
+    validOutputs.push_back(SH_HLSL_4_1_OUTPUT);
+    validOutputs.push_back(SH_HLSL_4_0_FL9_3_OUTPUT);
+    bool found = false;
+    for (auto valid : validOutputs)
+    {
+        found = found || (valid == output);
+    }
+    if (!found)
+    {
+        return 0;
+    }
+
+    size -= kHeaderSize;
+    data += kHeaderSize;
+
+    if (!ShInitialize())
+    {
+        return 0;
+    }
+
+    TranslatorCacheKey key;
+    key.type   = type;
+    key.spec   = spec;
+    key.output = output;
+
+    if (translators.find(key) == translators.end())
+    {
+        TCompiler *translator = ConstructCompiler(type, static_cast<ShShaderSpec>(spec),
+                                                  static_cast<ShShaderOutput>(output));
+
+        if (!translator)
+        {
+            return 0;
+        }
+
+        ShBuiltInResources resources;
+        ShInitBuiltInResources(&resources);
+
+        // Enable all the extensions to have more coverage
+        resources.OES_standard_derivatives        = 1;
+        resources.OES_EGL_image_external          = 1;
+        resources.OES_EGL_image_external_essl3    = 1;
+        resources.NV_EGL_stream_consumer_external = 1;
+        resources.ARB_texture_rectangle           = 1;
+        resources.EXT_blend_func_extended         = 1;
+        resources.EXT_draw_buffers                = 1;
+        resources.EXT_frag_depth                  = 1;
+        resources.EXT_shader_texture_lod          = 1;
+        resources.WEBGL_debug_shader_precision    = 1;
+        resources.EXT_shader_framebuffer_fetch    = 1;
+        resources.NV_shader_framebuffer_fetch     = 1;
+        resources.ARM_shader_framebuffer_fetch    = 1;
+
+        if (!translator->Init(resources))
+        {
+            DeleteCompiler(translator);
+            return 0;
+        }
+
+        translators[key] = translator;
+    }
+
+    TCompiler *translator = translators[key];
+
+    const char *shaderStrings[] = {reinterpret_cast<const char *>(data)};
+    translator->compile(shaderStrings, 1, options);
+
+    return 0;
+}
--- a/gfx/angle/src/compiler/preprocessor/64bit-tokenizer-safety.patch
+++ b/gfx/angle/src/compiler/preprocessor/64bit-tokenizer-safety.patch
@@ -1,31 +1,79 @@
+diff --git a/src/compiler/preprocessor/Tokenizer.cpp b/src/compiler/preprocessor/Tokenizer.cpp
+index 0d7ad58..5ef0e5e 100644
 --- a/src/compiler/preprocessor/Tokenizer.cpp
 +++ b/src/compiler/preprocessor/Tokenizer.cpp
-@@ -56,6 +56,7 @@ typedef int16_t flex_int16_t;
- typedef uint16_t flex_uint16_t;
- typedef int32_t flex_int32_t;
- typedef uint32_t flex_uint32_t;
-+typedef uint64_t flex_uint64_t;
- #else
- typedef signed char flex_int8_t;
- typedef short int flex_int16_t;
-@@ -179,6 +180,11 @@ typedef void* yyscan_t;
- typedef struct yy_buffer_state *YY_BUFFER_STATE;
- #endif
-
-+#ifndef YY_TYPEDEF_YY_SIZE_T
-+#define YY_TYPEDEF_YY_SIZE_T
-+typedef size_t yy_size_t;
-+#endif
-+
- #define EOB_ACT_CONTINUE_SCAN 0
- #define EOB_ACT_END_OF_FILE 1
- #define EOB_ACT_LAST_MATCH 2
-@@ -353,7 +354,7 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+@@ -1703,7 +1703,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
+ 	else
+ 		{
+ 			int num_to_read =
+-			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
++			static_cast<int>(YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1);
+ 
+ 		while ( num_to_read <= 0 )
+ 			{ /* Not enough room in the buffer - grow it. */
+@@ -1737,8 +1737,8 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
+ 
+ 			yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+ 
+-			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+-						number_to_move - 1;
++			num_to_read = static_cast<int>(YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
++						number_to_move - 1);
+ 
+ 			}
+ 
+@@ -1746,8 +1746,10 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
+ 			num_to_read = YY_READ_BUF_SIZE;
+ 
+ 		/* Read in more data. */
++		yy_size_t ret = 0;
+ 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+-			yyg->yy_n_chars, num_to_read );
++			ret, num_to_read );
++		yyg->yy_n_chars = static_cast<int>(ret);
+ 
+ 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ 		}
+@@ -1773,13 +1775,13 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
+ 
+ 	if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ 		/* Extend the array by 50%, plus the number we really need. */
+-		int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
++		yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ 		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) pprealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+ 		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ 			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ 	}
+ 
+-	yyg->yy_n_chars += number_to_move;
++	yyg->yy_n_chars += static_cast<int>(number_to_move);
+ 	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ 	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+ 
+@@ -2171,7 +2173,7 @@ void pppop_buffer_state (yyscan_t yyscanner)
   */
- #define YY_DO_BEFORE_ACTION \
- 	yyg->yytext_ptr = yy_bp; \
--	yyleng = (size_t) (yy_cp - yy_bp); \
-+	yyleng = (yy_size_t) (yy_cp - yy_bp); \
- 	yyg->yy_hold_char = *yy_cp; \
- 	*yy_cp = '\0'; \
- 	yyg->yy_c_buf_p = yy_cp;
+ static void ppensure_buffer_stack (yyscan_t yyscanner)
+ {
+-	int num_to_alloc;
++	yy_size_t num_to_alloc;
+     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ 
+ 	if (!yyg->yy_buffer_stack) {
+@@ -2238,7 +2240,7 @@ YY_BUFFER_STATE pp_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscann
+ 	if ( ! b )
+ 		YY_FATAL_ERROR( "out of dynamic memory in pp_scan_buffer()" );
+ 
+-	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
++	b->yy_buf_size = static_cast<int>(size - 2);	/* "- 2" to take care of EOB's */
+ 	b->yy_buf_pos = b->yy_ch_buf = base;
+ 	b->yy_is_our_buffer = 0;
+ 	b->yy_input_file = NULL;
+@@ -2293,7 +2295,7 @@ YY_BUFFER_STATE pp_scan_bytes  (yyconst char * yybytes, int  _yybytes_len , yysc
+ 	if ( ! buf )
+ 		YY_FATAL_ERROR( "out of dynamic memory in pp_scan_bytes()" );
+ 
+-	for ( i = 0; i < _yybytes_len; ++i )
++	for ( i = 0; i < static_cast<yy_size_t>(_yybytes_len); ++i )
+ 		buf[i] = yybytes[i];
+ 
+ 	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
--- a/gfx/angle/src/compiler/preprocessor/DiagnosticsBase.cpp
+++ b/gfx/angle/src/compiler/preprocessor/DiagnosticsBase.cpp
@@ -1,17 +1,17 @@
 //
 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
-#include "DiagnosticsBase.h"
+#include "compiler/preprocessor/DiagnosticsBase.h"
 
-#include <cassert>
+#include "common/debug.h"
 
 namespace pp
 {
 
 Diagnostics::~Diagnostics()
 {
 }
 
@@ -26,17 +26,17 @@ void Diagnostics::report(ID id,
 Diagnostics::Severity Diagnostics::severity(ID id)
 {
     if ((id > PP_ERROR_BEGIN) && (id < PP_ERROR_END))
         return PP_ERROR;
 
     if ((id > PP_WARNING_BEGIN) && (id < PP_WARNING_END))
         return PP_WARNING;
 
-    assert(false);
+    UNREACHABLE();
     return PP_ERROR;
 }
 
 std::string Diagnostics::message(ID id)
 {
     switch (id)
     {
       // Errors begin.
@@ -69,16 +69,18 @@ std::string Diagnostics::message(ID id)
       case PP_MACRO_REDEFINED:
         return "macro redefined";
       case PP_MACRO_PREDEFINED_REDEFINED:
         return "predefined macro redefined";
       case PP_MACRO_PREDEFINED_UNDEFINED:
         return "predefined macro undefined";
       case PP_MACRO_UNTERMINATED_INVOCATION:
         return "unterminated macro invocation";
+      case PP_MACRO_UNDEFINED_WHILE_INVOKED:
+          return "macro undefined while being invoked";
       case PP_MACRO_TOO_FEW_ARGS:
         return "Not enough arguments for macro";
       case PP_MACRO_TOO_MANY_ARGS:
         return "Too many arguments for macro";
       case PP_MACRO_DUPLICATE_PARAMETER_NAMES:
         return "duplicate macro parameter name";
       case PP_CONDITIONAL_ENDIF_WITHOUT_IF:
         return "unexpected #endif found without a matching #if";
@@ -126,14 +128,14 @@ std::string Diagnostics::message(ID id)
       case PP_UNRECOGNIZED_PRAGMA:
         return "unrecognized pragma";
       case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1:
         return "extension directive should occur before any non-preprocessor tokens";
       case PP_WARNING_MACRO_NAME_RESERVED:
         return "macro name with a double underscore is reserved - unintented behavior is possible";
       // Warnings end.
       default:
-        assert(false);
-        return "";
+          UNREACHABLE();
+          return "";
     }
 }
 
 }  // namespace pp
--- a/gfx/angle/src/compiler/preprocessor/DiagnosticsBase.h
+++ b/gfx/angle/src/compiler/preprocessor/DiagnosticsBase.h
@@ -39,16 +39,17 @@ class Diagnostics
         PP_EOF_IN_COMMENT,
         PP_UNEXPECTED_TOKEN,
         PP_DIRECTIVE_INVALID_NAME,
         PP_MACRO_NAME_RESERVED,
         PP_MACRO_REDEFINED,
         PP_MACRO_PREDEFINED_REDEFINED,
         PP_MACRO_PREDEFINED_UNDEFINED,
         PP_MACRO_UNTERMINATED_INVOCATION,
+        PP_MACRO_UNDEFINED_WHILE_INVOKED,
         PP_MACRO_TOO_FEW_ARGS,
         PP_MACRO_TOO_MANY_ARGS,
         PP_MACRO_DUPLICATE_PARAMETER_NAMES,
         PP_CONDITIONAL_ENDIF_WITHOUT_IF,
         PP_CONDITIONAL_ELSE_WITHOUT_IF,
         PP_CONDITIONAL_ELSE_AFTER_ELSE,
         PP_CONDITIONAL_ELIF_WITHOUT_IF,
         PP_CONDITIONAL_ELIF_AFTER_ELSE,
--- a/gfx/angle/src/compiler/preprocessor/DirectiveHandlerBase.cpp
+++ b/gfx/angle/src/compiler/preprocessor/DirectiveHandlerBase.cpp
@@ -1,15 +1,15 @@
 //
 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
-#include "DirectiveHandlerBase.h"
+#include "compiler/preprocessor/DirectiveHandlerBase.h"
 
 namespace pp
 {
 
 DirectiveHandler::~DirectiveHandler()
 {
 }
 
--- a/gfx/angle/src/compiler/preprocessor/DirectiveParser.cpp
+++ b/gfx/angle/src/compiler/preprocessor/DirectiveParser.cpp
@@ -1,27 +1,27 @@
 //
 // Copyright (c) 2011-2013 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
-#include "DirectiveParser.h"
+#include "compiler/preprocessor/DirectiveParser.h"
 
 #include <algorithm>
-#include <cassert>
 #include <cstdlib>
 #include <sstream>
 
-#include "DiagnosticsBase.h"
-#include "DirectiveHandlerBase.h"
-#include "ExpressionParser.h"
-#include "MacroExpander.h"
-#include "Token.h"
-#include "Tokenizer.h"
+#include "common/debug.h"
+#include "compiler/preprocessor/DiagnosticsBase.h"
+#include "compiler/preprocessor/DirectiveHandlerBase.h"
+#include "compiler/preprocessor/ExpressionParser.h"
+#include "compiler/preprocessor/MacroExpander.h"
+#include "compiler/preprocessor/Token.h"
+#include "compiler/preprocessor/Tokenizer.h"
 
 namespace {
 enum DirectiveType
 {
     DIRECTIVE_NONE,
     DIRECTIVE_DEFINE,
     DIRECTIVE_UNDEF,
     DIRECTIVE_IF,
@@ -243,17 +243,17 @@ void DirectiveParser::lex(Token *token)
     }
     while (skipping() || (token->type == '\n'));
 
     mPastFirstStatement = true;
 }
 
 void DirectiveParser::parseDirective(Token *token)
 {
-    assert(token->type == Token::PP_HASH);
+    ASSERT(token->type == Token::PP_HASH);
 
     mTokenizer->lex(token);
     if (isEOD(token))
     {
         // Empty Directive.
         return;
     }
 
@@ -309,31 +309,31 @@ void DirectiveParser::parseDirective(Tok
         break;
       case DIRECTIVE_VERSION:
         parseVersion(token);
         break;
       case DIRECTIVE_LINE:
         parseLine(token);
         break;
       default:
-        assert(false);
-        break;
+          UNREACHABLE();
+          break;
     }
 
     skipUntilEOD(mTokenizer, token);
     if (token->type == Token::LAST)
     {
         mDiagnostics->report(Diagnostics::PP_EOF_IN_DIRECTIVE,
                              token->location, token->text);
     }
 }
 
 void DirectiveParser::parseDefine(Token *token)
 {
-    assert(getDirective(token) == DIRECTIVE_DEFINE);
+    ASSERT(getDirective(token) == DIRECTIVE_DEFINE);
 
     mTokenizer->lex(token);
     if (token->type != Token::IDENTIFIER)
     {
         mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
                              token->location, token->text);
         return;
     }
@@ -423,33 +423,40 @@ void DirectiveParser::parseDefine(Token 
                              macro.name);
         return;
     }
     mMacroSet->insert(std::make_pair(macro.name, macro));
 }
 
 void DirectiveParser::parseUndef(Token *token)
 {
-    assert(getDirective(token) == DIRECTIVE_UNDEF);
+    ASSERT(getDirective(token) == DIRECTIVE_UNDEF);
 
     mTokenizer->lex(token);
     if (token->type != Token::IDENTIFIER)
     {
         mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
                              token->location, token->text);
         return;
     }
 
     MacroSet::iterator iter = mMacroSet->find(token->text);
     if (iter != mMacroSet->end())
     {
         if (iter->second.predefined)
         {
             mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED,
                                  token->location, token->text);
+            return;
+        }
+        else if (iter->second.expansionCount > 0)
+        {
+            mDiagnostics->report(Diagnostics::PP_MACRO_UNDEFINED_WHILE_INVOKED, token->location,
+                                 token->text);
+            return;
         }
         else
         {
             mMacroSet->erase(iter);
         }
     }
 
     mTokenizer->lex(token);
@@ -458,35 +465,35 @@ void DirectiveParser::parseUndef(Token *
         mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
                              token->location, token->text);
         skipUntilEOD(mTokenizer, token);
     }
 }
 
 void DirectiveParser::parseIf(Token *token)
 {
-    assert(getDirective(token) == DIRECTIVE_IF);
+    ASSERT(getDirective(token) == DIRECTIVE_IF);
     parseConditionalIf(token);
 }
 
 void DirectiveParser::parseIfdef(Token *token)
 {
-    assert(getDirective(token) == DIRECTIVE_IFDEF);
+    ASSERT(getDirective(token) == DIRECTIVE_IFDEF);
     parseConditionalIf(token);
 }
 
 void DirectiveParser::parseIfndef(Token *token)
 {
-    assert(getDirective(token) == DIRECTIVE_IFNDEF);
+    ASSERT(getDirective(token) == DIRECTIVE_IFNDEF);
     parseConditionalIf(token);
 }
 
 void DirectiveParser::parseElse(Token *token)
 {
-    assert(getDirective(token) == DIRECTIVE_ELSE);
+    ASSERT(getDirective(token) == DIRECTIVE_ELSE);
 
     if (mConditionalStack.empty())
     {
         mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_WITHOUT_IF,
                              token->location, token->text);
         skipUntilEOD(mTokenizer, token);
         return;
     }
@@ -517,17 +524,17 @@ void DirectiveParser::parseElse(Token *t
         mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN,
                              token->location, token->text);
         skipUntilEOD(mTokenizer, token);
     }
 }
 
 void DirectiveParser::parseElif(Token *token)
 {
-    assert(getDirective(token) == DIRECTIVE_ELIF);
+    ASSERT(getDirective(token) == DIRECTIVE_ELIF);
 
     if (mConditionalStack.empty())
     {
         mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_WITHOUT_IF,
                              token->location, token->text);
         skipUntilEOD(mTokenizer, token);
         return;
     }
@@ -557,17 +564,17 @@ void DirectiveParser::parseElif(Token *t
 
     int expression = parseExpressionIf(token);
     block.skipGroup = expression == 0;
     block.foundValidGroup = expression != 0;
 }
 
 void DirectiveParser::parseEndif(Token *token)
 {
-    assert(getDirective(token) == DIRECTIVE_ENDIF);
+    ASSERT(getDirective(token) == DIRECTIVE_ENDIF);
 
     if (mConditionalStack.empty())
     {
         mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ENDIF_WITHOUT_IF,
                              token->location, token->text);
         skipUntilEOD(mTokenizer, token);
         return;
     }
@@ -581,32 +588,32 @@ void DirectiveParser::parseEndif(Token *
         mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN,
                              token->location, token->text);
         skipUntilEOD(mTokenizer, token);
     }
 }
 
 void DirectiveParser::parseError(Token *token)
 {
-    assert(getDirective(token) == DIRECTIVE_ERROR);
+    ASSERT(getDirective(token) == DIRECTIVE_ERROR);
 
     std::ostringstream stream;
     mTokenizer->lex(token);
     while ((token->type != '\n') && (token->type != Token::LAST))
     {
         stream << *token;
         mTokenizer->lex(token);
     }
     mDirectiveHandler->handleError(token->location, stream.str());
 }
 
 // Parses pragma of form: #pragma name[(value)].
 void DirectiveParser::parsePragma(Token *token)
 {
-    assert(getDirective(token) == DIRECTIVE_PRAGMA);
+    ASSERT(getDirective(token) == DIRECTIVE_PRAGMA);
 
     enum State
     {
         PRAGMA_NAME,
         LEFT_PAREN,
         PRAGMA_VALUE,
         RIGHT_PAREN
     };
@@ -657,17 +664,17 @@ void DirectiveParser::parsePragma(Token 
     else if (state > PRAGMA_NAME)  // Do not notify for empty pragma.
     {
         mDirectiveHandler->handlePragma(token->location, name, value, stdgl);
     }
 }
 
 void DirectiveParser::parseExtension(Token *token)
 {
-    assert(getDirective(token) == DIRECTIVE_EXTENSION);
+    ASSERT(getDirective(token) == DIRECTIVE_EXTENSION);
 
     enum State
     {
         EXT_NAME,
         COLON,
         EXT_BEHAVIOR
     };
 
@@ -738,17 +745,17 @@ void DirectiveParser::parseExtension(Tok
         }
     }
     if (valid)
         mDirectiveHandler->handleExtension(token->location, name, behavior);
 }
 
 void DirectiveParser::parseVersion(Token *token)
 {
-    assert(getDirective(token) == DIRECTIVE_VERSION);
+    ASSERT(getDirective(token) == DIRECTIVE_VERSION);
 
     if (mPastFirstStatement)
     {
         mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT,
                              token->location, token->text);
         skipUntilEOD(mTokenizer, token);
         return;
     }
@@ -825,17 +832,17 @@ void DirectiveParser::parseVersion(Token
         mDirectiveHandler->handleVersion(token->location, version);
         mShaderVersion = version;
         PredefineMacro(mMacroSet, "__VERSION__", version);
     }
 }
 
 void DirectiveParser::parseLine(Token *token)
 {
-    assert(getDirective(token) == DIRECTIVE_LINE);
+    ASSERT(getDirective(token) == DIRECTIVE_LINE);
 
     bool valid = true;
     bool parsedFileNumber = false;
     int line = 0, file = 0;
 
     MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics);
 
     // Lex the first token after "#line" so we can check it for EOD.
@@ -926,29 +933,28 @@ void DirectiveParser::parseConditionalIf
             break;
           case DIRECTIVE_IFDEF:
             expression = parseExpressionIfdef(token);
             break;
           case DIRECTIVE_IFNDEF:
             expression = parseExpressionIfdef(token) == 0 ? 1 : 0;
             break;
           default:
-            assert(false);
-            break;
+              UNREACHABLE();
+              break;
         }
         block.skipGroup = expression == 0;
         block.foundValidGroup = expression != 0;
     }
     mConditionalStack.push_back(block);
 }
 
 int DirectiveParser::parseExpressionIf(Token *token)
 {
-    assert((getDirective(token) == DIRECTIVE_IF) ||
-           (getDirective(token) == DIRECTIVE_ELIF));
+    ASSERT((getDirective(token) == DIRECTIVE_IF) || (getDirective(token) == DIRECTIVE_ELIF));
 
     DefinedParser definedParser(mTokenizer, mMacroSet, mDiagnostics);
     MacroExpander macroExpander(&definedParser, mMacroSet, mDiagnostics);
     ExpressionParser expressionParser(&macroExpander, mDiagnostics);
 
     int expression = 0;
     ExpressionParser::ErrorSettings errorSettings;
     errorSettings.integerLiteralsMustFit32BitSignedRange = false;
@@ -965,18 +971,17 @@ int DirectiveParser::parseExpressionIf(T
         skipUntilEOD(mTokenizer, token);
     }
 
     return expression;
 }
 
 int DirectiveParser::parseExpressionIfdef(Token *token)
 {
-    assert((getDirective(token) == DIRECTIVE_IFDEF) ||
-           (getDirective(token) == DIRECTIVE_IFNDEF));
+    ASSERT((getDirective(token) == DIRECTIVE_IFDEF) || (getDirective(token) == DIRECTIVE_IFNDEF));
 
     mTokenizer->lex(token);
     if (token->type != Token::IDENTIFIER)
     {
         mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
                              token->location, token->text);
         skipUntilEOD(mTokenizer, token);
         return 0;
--- a/gfx/angle/src/compiler/preprocessor/DirectiveParser.h
+++ b/gfx/angle/src/compiler/preprocessor/DirectiveParser.h
@@ -2,20 +2,19 @@
 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #ifndef COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
 #define COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
 
-#include "Lexer.h"
-#include "Macro.h"
-#include "pp_utils.h"
-#include "SourceLocation.h"
+#include "compiler/preprocessor/Lexer.h"
+#include "compiler/preprocessor/Macro.h"
+#include "compiler/preprocessor/SourceLocation.h"
 
 namespace pp
 {
 
 class Diagnostics;
 class DirectiveHandler;
 class Tokenizer;
 
@@ -25,17 +24,16 @@ class DirectiveParser : public Lexer
     DirectiveParser(Tokenizer *tokenizer,
                     MacroSet *macroSet,
                     Diagnostics *diagnostics,
                     DirectiveHandler *directiveHandler);
 
     void lex(Token *token) override;
 
   private:
-    PP_DISALLOW_COPY_AND_ASSIGN(DirectiveParser);
 
     void parseDirective(Token *token);
     void parseDefine(Token *token);
     void parseUndef(Token *token);
     void parseIf(Token *token);
     void parseIfdef(Token *token);
     void parseIfndef(Token *token);
     void parseElse(Token *token);
--- a/gfx/angle/src/compiler/preprocessor/ExpressionParser.cpp
+++ b/gfx/angle/src/compiler/preprocessor/ExpressionParser.cpp
@@ -94,27 +94,25 @@
 #if defined(_MSC_VER)
 #include <malloc.h>
 #else
 #include <stdlib.h>
 #endif
 
 #include <cassert>
 #include <sstream>
+#include <stdint.h>
 
 #include "DiagnosticsBase.h"
 #include "Lexer.h"
 #include "Token.h"
+#include "common/mathutil.h"
 
-#if defined(_MSC_VER)
-typedef __int64 YYSTYPE;
-#else
-#include <stdint.h>
-typedef intmax_t YYSTYPE;
-#endif  // _MSC_VER
+typedef int32_t YYSTYPE;
+typedef uint32_t UNSIGNED_TYPE;
 
 #define YYENABLE_NLS 0
 #define YYLTYPE_IS_TRIVIAL 1
 #define YYSTYPE_IS_TRIVIAL 1
 #define YYSTYPE_IS_DECLARED 1
 
 namespace {
 struct Context
@@ -493,19 +491,22 @@ static const yytype_uint8 yytranslate[] 
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
        5,     6,    10,    11,    14,    15,    16,    17,    23
 };
 
 #if YYDEBUG
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
-static const yytype_uint16 yyrline[] = {0,   110, 110, 117, 118, 129, 129, 150, 150, 171,
-                                        174, 177, 180, 183, 186, 189, 192, 195, 198, 218,
-                                        238, 241, 244, 264, 284, 287, 290, 293, 296, 299};
+static const yytype_uint16 yyrline[] =
+{
+       0,   108,   108,   115,   116,   127,   127,   148,   148,   169,
+     172,   175,   178,   181,   184,   187,   190,   193,   196,   221,
+     246,   249,   252,   278,   305,   308,   311,   314,   326,   329
+};
 #endif
 
 #if YYDEBUG || YYERROR_VERBOSE || 0
 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
 {
   "$end", "error", "$undefined", "TOK_CONST_INT", "TOK_IDENTIFIER",
@@ -1487,73 +1488,85 @@ yyreduce:
         (yyval) = (yyvsp[-2]) < (yyvsp[0]);
     }
 
     break;
 
   case 18:
 
     {
-        if ((yyvsp[0]) < 0)
+        if ((yyvsp[0]) < 0 || (yyvsp[0]) > 31)
         {
             if (!context->isIgnoringErrors())
             {
                 std::ostringstream stream;
                 stream << (yyvsp[-2]) << " >> " << (yyvsp[0]);
                 std::string text = stream.str();
                 context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
-                                             context->token->location, text.c_str());
+                                             context->token->location,
+                                             text.c_str());
                 *(context->valid) = false;
             }
             (yyval) = static_cast<YYSTYPE>(0);
         }
+        else if ((yyvsp[-2]) < 0)
+        {
+            // Logical shift right.
+            (yyval) = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>((yyvsp[-2])) >> (yyvsp[0]));
+        }
         else
         {
             (yyval) = (yyvsp[-2]) >> (yyvsp[0]);
         }
     }
 
     break;
 
   case 19:
 
     {
-        if ((yyvsp[0]) < 0)
+        if ((yyvsp[0]) < 0 || (yyvsp[0]) > 31)
         {
             if (!context->isIgnoringErrors())
             {
                 std::ostringstream stream;
                 stream << (yyvsp[-2]) << " << " << (yyvsp[0]);
                 std::string text = stream.str();
                 context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
-                                             context->token->location, text.c_str());
+                                             context->token->location,
+                                             text.c_str());
                 *(context->valid) = false;
             }
             (yyval) = static_cast<YYSTYPE>(0);
         }
+        else if ((yyvsp[-2]) < 0)
+        {
+            // Logical shift left.
+            (yyval) = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>((yyvsp[-2])) << (yyvsp[0]));
+        }
         else
         {
             (yyval) = (yyvsp[-2]) << (yyvsp[0]);
         }
     }
 
     break;
 
   case 20:
 
     {
-        (yyval) = (yyvsp[-2]) - (yyvsp[0]);
+        (yyval) = gl::WrappingDiff<YYSTYPE>((yyvsp[-2]), (yyvsp[0]));
     }
 
     break;
 
   case 21:
 
     {
-        (yyval) = (yyvsp[-2]) + (yyvsp[0]);
+        (yyval) = gl::WrappingSum<YYSTYPE>((yyvsp[-2]), (yyvsp[0]));
     }
 
     break;
 
   case 22:
 
     {
         if ((yyvsp[0]) == 0)
@@ -1565,16 +1578,22 @@ yyreduce:
                 std::string text = stream.str();
                 context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
                                              context->token->location,
                                              text.c_str());
                 *(context->valid) = false;
             }
             (yyval) = static_cast<YYSTYPE>(0);
         }
+        else if (((yyvsp[-2]) == std::numeric_limits<YYSTYPE>::min()) && ((yyvsp[0]) == -1))
+        {
+            // Check for the special case where the minimum representable number is
+            // divided by -1. If left alone this has undefined results.
+            (yyval) = 0;
+        }
         else
         {
             (yyval) = (yyvsp[-2]) % (yyvsp[0]);
         }
     }
 
     break;
 
@@ -1590,28 +1609,35 @@ yyreduce:
                 std::string text = stream.str();
                 context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
                                             context->token->location,
                                             text.c_str());
                 *(context->valid) = false;
             }
             (yyval) = static_cast<YYSTYPE>(0);
         }
+        else if (((yyvsp[-2]) == std::numeric_limits<YYSTYPE>::min()) && ((yyvsp[0]) == -1))
+        {
+            // Check for the special case where the minimum representable number is
+            // divided by -1. If left alone this leads to integer overflow in C++, which
+            // has undefined results.
+            (yyval) = std::numeric_limits<YYSTYPE>::max();
+        }
         else
         {
             (yyval) = (yyvsp[-2]) / (yyvsp[0]);
         }
     }
 
     break;
 
   case 24:
 
     {
-        (yyval) = (yyvsp[-2]) * (yyvsp[0]);
+        (yyval) = gl::WrappingMul((yyvsp[-2]), (yyvsp[0]));
     }
 
     break;
 
   case 25:
 
     {
         (yyval) = ! (yyvsp[0]);
@@ -1625,17 +1651,26 @@ yyreduce:
         (yyval) = ~ (yyvsp[0]);
     }
 
     break;
 
   case 27:
 
     {
-        (yyval) = - (yyvsp[0]);
+        // Check for negation of minimum representable integer to prevent undefined signed int
+        // overflow.
+        if ((yyvsp[0]) == std::numeric_limits<YYSTYPE>::min())
+        {
+            (yyval) = std::numeric_limits<YYSTYPE>::min();
+        }
+        else
+        {
+            (yyval) = -(yyvsp[0]);
+        }
     }
 
     break;
 
   case 28:
 
     {
         (yyval) = + (yyvsp[0]);
--- a/gfx/angle/src/compiler/preprocessor/ExpressionParser.h
+++ b/gfx/angle/src/compiler/preprocessor/ExpressionParser.h
@@ -2,26 +2,26 @@
 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #ifndef COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
 #define COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
 
-#include "DiagnosticsBase.h"
-#include "pp_utils.h"
+#include "common/angleutils.h"
+#include "compiler/preprocessor/DiagnosticsBase.h"
 
 namespace pp
 {
 
 class Lexer;
 struct Token;
 
-class ExpressionParser
+class ExpressionParser : angle::NonCopyable
 {
   public:
     struct ErrorSettings
     {
         Diagnostics::ID unexpectedIdentifier;
         bool integerLiteralsMustFit32BitSignedRange;
     };
 
@@ -29,17 +29,15 @@ class ExpressionParser
 
     bool parse(Token *token,
                int *result,
                bool parsePresetToken,
                const ErrorSettings &errorSettings,
                bool *valid);
 
   private:
-    PP_DISALLOW_COPY_AND_ASSIGN(ExpressionParser);
-
     Lexer *mLexer;
     Diagnostics *mDiagnostics;
 };
 
 }  // namespace pp
 
 #endif  // COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
--- a/gfx/angle/src/compiler/preprocessor/ExpressionParser.y
+++ b/gfx/angle/src/compiler/preprocessor/ExpressionParser.y
@@ -36,27 +36,25 @@ WHICH GENERATES THE GLSL ES preprocessor
 #if defined(_MSC_VER)
 #include <malloc.h>
 #else
 #include <stdlib.h>
 #endif
 
 #include <cassert>
 #include <sstream>
+#include <stdint.h>
 
 #include "DiagnosticsBase.h"
 #include "Lexer.h"
 #include "Token.h"
+#include "common/mathutil.h"
 
-#if defined(_MSC_VER)
-typedef __int64 YYSTYPE;
-#else
-#include <stdint.h>
-typedef intmax_t YYSTYPE;
-#endif  // _MSC_VER
+typedef int32_t YYSTYPE;
+typedef uint32_t UNSIGNED_TYPE;
 
 #define YYENABLE_NLS 0
 #define YYLTYPE_IS_TRIVIAL 1
 #define YYSTYPE_IS_TRIVIAL 1
 #define YYSTYPE_IS_DECLARED 1
 
 namespace {
 struct Context
@@ -191,76 +189,92 @@ expression
     }
     | expression '>' expression {
         $$ = $1 > $3;
     }
     | expression '<' expression {
         $$ = $1 < $3;
     }
     | expression TOK_OP_RIGHT expression {
-        if ($3 < 0)
+        if ($3 < 0 || $3 > 31)
         {
             if (!context->isIgnoringErrors())
             {
                 std::ostringstream stream;
                 stream << $1 << " >> " << $3;
                 std::string text = stream.str();
                 context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
                                              context->token->location,
                                              text.c_str());
                 *(context->valid) = false;
             }
             $$ = static_cast<YYSTYPE>(0);
         }
+        else if ($1 < 0)
+        {
+            // Logical shift right.
+            $$ = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>($1) >> $3);
+        }
         else
         {
             $$ = $1 >> $3;
         }
     }
     | expression TOK_OP_LEFT expression {
-        if ($3 < 0)
+        if ($3 < 0 || $3 > 31)
         {
             if (!context->isIgnoringErrors())
             {
                 std::ostringstream stream;
                 stream << $1 << " << " << $3;
                 std::string text = stream.str();
                 context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
                                              context->token->location,
                                              text.c_str());
                 *(context->valid) = false;
             }
             $$ = static_cast<YYSTYPE>(0);
         }
+        else if ($1 < 0)
+        {
+            // Logical shift left.
+            $$ = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>($1) << $3);
+        }
         else
         {
             $$ = $1 << $3;
         }
     }
     | expression '-' expression {
-        $$ = $1 - $3;
+        $$ = gl::WrappingDiff<YYSTYPE>($1, $3);
     }
     | expression '+' expression {
-        $$ = $1 + $3;
+        $$ = gl::WrappingSum<YYSTYPE>($1, $3);
     }
     | expression '%' expression {
         if ($3 == 0)
         {
             if (!context->isIgnoringErrors())
             {
                 std::ostringstream stream;
                 stream << $1 << " % " << $3;
                 std::string text = stream.str();
                 context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
                                              context->token->location,
                                              text.c_str());
                 *(context->valid) = false;
             }
             $$ = static_cast<YYSTYPE>(0);
         }
+        else if (($1 == std::numeric_limits<YYSTYPE>::min()) && ($3 == -1))
+        {
+            // Check for the special case where the minimum representable number is
+            // divided by -1. If left alone this has undefined results.
+            $$ = 0;
+        }
         else
         {
             $$ = $1 % $3;
         }
     }
     | expression '/' expression {
         if ($3 == 0)
         {
@@ -271,32 +285,48 @@ expression
                 std::string text = stream.str();
                 context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
                                             context->token->location,
                                             text.c_str());
                 *(context->valid) = false;
             }
             $$ = static_cast<YYSTYPE>(0);
         }
+        else if (($1 == std::numeric_limits<YYSTYPE>::min()) && ($3 == -1))
+        {
+            // Check for the special case where the minimum representable number is
+            // divided by -1. If left alone this leads to integer overflow in C++, which
+            // has undefined results.
+            $$ = std::numeric_limits<YYSTYPE>::max();
+        }
         else
         {
             $$ = $1 / $3;
         }
     }
     | expression '*' expression {
-        $$ = $1 * $3;
+        $$ = gl::WrappingMul($1, $3);
     }
     | '!' expression %prec TOK_UNARY {
         $$ = ! $2;
     }
     | '~' expression %prec TOK_UNARY {
         $$ = ~ $2;
     }
     | '-' expression %prec TOK_UNARY {
-        $$ = - $2;
+        // Check for negation of minimum representable integer to prevent undefined signed int
+        // overflow.
+        if ($2 == std::numeric_limits<YYSTYPE>::min())
+        {
+            $$ = std::numeric_limits<YYSTYPE>::min();
+        }
+        else
+        {
+            $$ = -$2;
+        }
     }
     | '+' expression %prec TOK_UNARY {
         $$ = + $2;
     }
     | '(' expression ')' {
         $$ = $2;
     }
 ;
--- a/gfx/angle/src/compiler/preprocessor/Input.cpp
+++ b/gfx/angle/src/compiler/preprocessor/Input.cpp
@@ -1,20 +1,21 @@
 //
 // 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.
 //
 
-#include "Input.h"
+#include "compiler/preprocessor/Input.h"
 
 #include <algorithm>
-#include <cassert>
 #include <cstring>
 
+#include "common/debug.h"
+
 namespace pp
 {
 
 Input::Input() : mCount(0), mString(0)
 {
 }
 
 Input::Input(size_t count, const char *const string[], const int length[]) :
@@ -27,17 +28,17 @@ Input::Input(size_t count, const char *c
         int len = length ? length[i] : -1;
         mLength.push_back(len < 0 ? std::strlen(mString[i]) : len);
     }
 }
 
 const char *Input::skipChar()
 {
     // This function should only be called when there is a character to skip.
-    assert(mReadLoc.cIndex < mLength[mReadLoc.sIndex]);
+    ASSERT(mReadLoc.cIndex < mLength[mReadLoc.sIndex]);
     ++mReadLoc.cIndex;
     if (mReadLoc.cIndex == mLength[mReadLoc.sIndex])
     {
         ++mReadLoc.sIndex;
         mReadLoc.cIndex = 0;
     }
     if (mReadLoc.sIndex >= mCount)
     {
--- a/gfx/angle/src/compiler/preprocessor/Input.h
+++ b/gfx/angle/src/compiler/preprocessor/Input.h
@@ -2,17 +2,17 @@
 // 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.
 //
 
 #ifndef COMPILER_PREPROCESSOR_INPUT_H_
 #define COMPILER_PREPROCESSOR_INPUT_H_
 
-#include <stddef.h>
+#include <cstddef>
 #include <vector>
 
 namespace pp
 {
 
 // Holds and reads input for Lexer.
 class Input
 {
--- a/gfx/angle/src/compiler/preprocessor/Lexer.cpp
+++ b/gfx/angle/src/compiler/preprocessor/Lexer.cpp
@@ -1,15 +1,15 @@
 //
 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
-#include "Lexer.h"
+#include "compiler/preprocessor/Lexer.h"
 
 namespace pp
 {
 
 Lexer::~Lexer()
 {
 }
 
--- a/gfx/angle/src/compiler/preprocessor/Lexer.h
+++ b/gfx/angle/src/compiler/preprocessor/Lexer.h
@@ -2,22 +2,24 @@
 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #ifndef COMPILER_PREPROCESSOR_LEXER_H_
 #define COMPILER_PREPROCESSOR_LEXER_H_
 
+#include "common/angleutils.h"
+
 namespace pp
 {
 
 struct Token;
 
-class Lexer
+class Lexer : angle::NonCopyable
 {
   public:
     virtual ~Lexer();
 
     virtual void lex(Token *token) = 0;
 };
 
 }  // namespace pp
--- a/gfx/angle/src/compiler/preprocessor/Macro.cpp
+++ b/gfx/angle/src/compiler/preprocessor/Macro.cpp
@@ -1,39 +1,35 @@
 //
 // 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.
 //
 
-#include "Macro.h"
+#include "compiler/preprocessor/Macro.h"
 
-#include <sstream>
-
-#include "Token.h"
+#include "common/angleutils.h"
+#include "compiler/preprocessor/Token.h"
 
 namespace pp
 {
 
 bool Macro::equals(const Macro &other) const
 {
     return (type == other.type) &&
            (name == other.name) &&
            (parameters == other.parameters) &&
            (replacements == other.replacements);
 }
 
 void PredefineMacro(MacroSet *macroSet, const char *name, int value)
 {
-    std::ostringstream stream;
-    stream << value;
-
     Token token;
     token.type = Token::CONST_INT;
-    token.text = stream.str();
+    token.text = ToString(value);
 
     Macro macro;
     macro.predefined = true;
     macro.type       = Macro::kTypeObj;
     macro.name = name;
     macro.replacements.push_back(token);
 
     (*macroSet)[name] = macro;
--- a/gfx/angle/src/compiler/preprocessor/Macro.h
+++ b/gfx/angle/src/compiler/preprocessor/Macro.h
@@ -21,26 +21,22 @@ struct Macro
     enum Type
     {
         kTypeObj,
         kTypeFunc
     };
     typedef std::vector<std::string> Parameters;
     typedef std::vector<Token> Replacements;
 
-    Macro()
-        : predefined(false),
-          disabled(false),
-          type(kTypeObj)
-    {
-    }
+    Macro() : predefined(false), disabled(false), expansionCount(0), type(kTypeObj) {}
     bool equals(const Macro &other) const;
 
     bool predefined;
     mutable bool disabled;
+    mutable int expansionCount;
 
     Type type;
     std::string name;
     Parameters parameters;
     Replacements replacements;
 };
 
 typedef std::map<std::string, Macro> MacroSet;
--- a/gfx/angle/src/compiler/preprocessor/MacroExpander.cpp
+++ b/gfx/angle/src/compiler/preprocessor/MacroExpander.cpp
@@ -1,25 +1,30 @@
 //
 // 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.
 //
 
-#include "MacroExpander.h"
+#include "compiler/preprocessor/MacroExpander.h"
 
 #include <algorithm>
-#include <sstream>
 
-#include "DiagnosticsBase.h"
-#include "Token.h"
+#include "common/debug.h"
+#include "compiler/preprocessor/DiagnosticsBase.h"
+#include "compiler/preprocessor/Token.h"
 
 namespace pp
 {
 
+namespace
+{
+
+const size_t kMaxContextTokens = 10000;
+
 class TokenLexer : public Lexer
 {
  public:
     typedef std::vector<Token> TokenVector;
 
     TokenLexer(TokenVector *tokens)
     {
         tokens->swap(mTokens);
@@ -35,32 +40,32 @@ class TokenLexer : public Lexer
         }
         else
         {
             *token = *mIter++;
         }
     }
 
  private:
-    PP_DISALLOW_COPY_AND_ASSIGN(TokenLexer);
-
     TokenVector mTokens;
     TokenVector::const_iterator mIter;
 };
 
+}  // anonymous namespace
+
 MacroExpander::MacroExpander(Lexer *lexer, MacroSet *macroSet, Diagnostics *diagnostics)
-    : mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics)
+    : mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics), mTotalTokensInContexts(0)
 {
 }
 
 MacroExpander::~MacroExpander()
 {
-    for (std::size_t i = 0; i < mContextStack.size(); ++i)
+    for (MacroContext *context : mContextStack)
     {
-        delete mContextStack[i];
+        delete context;
     }
 }
 
 void MacroExpander::lex(Token *token)
 {
     while (true)
     {
         getToken(token);
@@ -77,20 +82,25 @@ void MacroExpander::lex(Token *token)
 
         const Macro& macro = iter->second;
         if (macro.disabled)
         {
             // If a particular token is not expanded, it is never expanded.
             token->setExpansionDisabled(true);
             break;
         }
+
+        // Bump the expansion count before peeking if the next token is a '('
+        // otherwise there could be a #undef of the macro before the next token.
+        macro.expansionCount++;
         if ((macro.type == Macro::kTypeFunc) && !isNextTokenLeftParen())
         {
             // If the token immediately after the macro name is not a '(',
             // this macro should not be expanded.
+            macro.expansionCount--;
             break;
         }
 
         pushMacro(macro, *token);
     }
 }
 
 void MacroExpander::getToken(Token *token)
@@ -109,31 +119,32 @@ void MacroExpander::getToken(Token *toke
     }
 
     if (!mContextStack.empty())
     {
         *token = mContextStack.back()->get();
     }
     else
     {
+        ASSERT(mTotalTokensInContexts == 0);
         mLexer->lex(token);
     }
 }
 
 void MacroExpander::ungetToken(const Token &token)
 {
     if (!mContextStack.empty())
     {
         MacroContext *context = mContextStack.back();
         context->unget();
-        assert(context->replacements[context->index] == token);
+        ASSERT(context->replacements[context->index] == token);
     }
     else
     {
-        assert(!mReserveToken.get());
+        ASSERT(!mReserveToken.get());
         mReserveToken.reset(new Token(token));
     }
 }
 
 bool MacroExpander::isNextTokenLeftParen()
 {
     Token token;
     getToken(&token);
@@ -141,45 +152,49 @@ bool MacroExpander::isNextTokenLeftParen
     bool lparen = token.type == '(';
     ungetToken(token);
 
     return lparen;
 }
 
 bool MacroExpander::pushMacro(const Macro &macro, const Token &identifier)
 {
-    assert(!macro.disabled);
-    assert(!identifier.expansionDisabled());
-    assert(identifier.type == Token::IDENTIFIER);
-    assert(identifier.text == macro.name);
+    ASSERT(!macro.disabled);
+    ASSERT(!identifier.expansionDisabled());
+    ASSERT(identifier.type == Token::IDENTIFIER);
+    ASSERT(identifier.text == macro.name);
 
     std::vector<Token> replacements;
     if (!expandMacro(macro, identifier, &replacements))
         return false;
 
     // Macro is disabled for expansion until it is popped off the stack.
     macro.disabled = true;
 
     MacroContext *context = new MacroContext;
     context->macro = &macro;
     context->replacements.swap(replacements);
     mContextStack.push_back(context);
+    mTotalTokensInContexts += context->replacements.size();
     return true;
 }
 
 void MacroExpander::popMacro()
 {
-    assert(!mContextStack.empty());
+    ASSERT(!mContextStack.empty());
 
     MacroContext *context = mContextStack.back();
     mContextStack.pop_back();
 
-    assert(context->empty());
-    assert(context->macro->disabled);
+    ASSERT(context->empty());
+    ASSERT(context->macro->disabled);
+    ASSERT(context->macro->expansionCount > 0);
     context->macro->disabled = false;
+    context->macro->expansionCount--;
+    mTotalTokensInContexts -= context->replacements.size();
     delete context;
 }
 
 bool MacroExpander::expandMacro(const Macro &macro,
                                 const Token &identifier,
                                 std::vector<Token> *replacements)
 {
     replacements->clear();
@@ -194,35 +209,31 @@ bool MacroExpander::expandMacro(const Ma
         replacements->assign(macro.replacements.begin(),
                              macro.replacements.end());
 
         if (macro.predefined)
         {
             const char kLine[] = "__LINE__";
             const char kFile[] = "__FILE__";
 
-            assert(replacements->size() == 1);
+            ASSERT(replacements->size() == 1);
             Token& repl = replacements->front();
             if (macro.name == kLine)
             {
-                std::ostringstream stream;
-                stream << identifier.location.line;
-                repl.text = stream.str();
+                repl.text = ToString(identifier.location.line);
             }
             else if (macro.name == kFile)
             {
-                std::ostringstream stream;
-                stream << identifier.location.file;
-                repl.text = stream.str();
+                repl.text = ToString(identifier.location.file);
             }
         }
     }
     else
     {
-        assert(macro.type == Macro::kTypeFunc);
+        ASSERT(macro.type == Macro::kTypeFunc);
         std::vector<MacroArg> args;
         args.reserve(macro.parameters.size());
         if (!collectMacroArgs(macro, identifier, &args, &replacementLocation))
             return false;
 
         replaceMacroParams(macro, args, replacements);
     }
 
@@ -243,20 +254,22 @@ bool MacroExpander::expandMacro(const Ma
 
 bool MacroExpander::collectMacroArgs(const Macro &macro,
                                      const Token &identifier,
                                      std::vector<MacroArg> *args,
                                      SourceLocation *closingParenthesisLocation)
 {
     Token token;
     getToken(&token);
-    assert(token.type == '(');
+    ASSERT(token.type == '(');
 
     args->push_back(MacroArg());
-    for (int openParens = 1; openParens != 0; )
+
+    int openParens = 1;
+    while (openParens != 0)
     {
         getToken(&token);
 
         if (token.type == Token::LAST)
         {
             mDiagnostics->report(Diagnostics::PP_MACRO_UNTERMINATED_INVOCATION,
                                  identifier.location, identifier.text);
             // Do not lose EOF token.
@@ -312,39 +325,53 @@ bool MacroExpander::collectMacroArgs(con
             Diagnostics::PP_MACRO_TOO_MANY_ARGS;
         mDiagnostics->report(id, identifier.location, identifier.text);
         return false;
     }
 
     // Pre-expand each argument before substitution.
     // This step expands each argument individually before they are
     // inserted into the macro body.
-    for (std::size_t i = 0; i < args->size(); ++i)
+    size_t numTokens = 0;
+    for (auto &arg : *args)
     {
-        MacroArg &arg = args->at(i);
         TokenLexer lexer(&arg);
         MacroExpander expander(&lexer, mMacroSet, mDiagnostics);
 
         arg.clear();
         expander.lex(&token);
         while (token.type != Token::LAST)
         {
             arg.push_back(token);
             expander.lex(&token);
+            numTokens++;
+            if (numTokens + mTotalTokensInContexts > kMaxContextTokens)
+            {
+                mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token.location, token.text);
+                return false;
+            }
         }
     }
     return true;
 }
 
 void MacroExpander::replaceMacroParams(const Macro &macro,
                                        const std::vector<MacroArg> &args,
                                        std::vector<Token> *replacements)
 {
     for (std::size_t i = 0; i < macro.replacements.size(); ++i)
     {
+        if (!replacements->empty() &&
+            replacements->size() + mTotalTokensInContexts > kMaxContextTokens)
+        {
+            const Token &token = replacements->back();
+            mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token.location, token.text);
+            return;
+        }
+
         const Token &repl = macro.replacements[i];
         if (repl.type != Token::IDENTIFIER)
         {
             replacements->push_back(repl);
             continue;
         }
 
         // TODO(alokp): Optimize this.
@@ -367,10 +394,30 @@ void MacroExpander::replaceMacroParams(c
         std::size_t iRepl = replacements->size();
         replacements->insert(replacements->end(), arg.begin(), arg.end());
         // The replacement token inherits padding properties from
         // macro replacement token.
         replacements->at(iRepl).setHasLeadingSpace(repl.hasLeadingSpace());
     }
 }
 
+MacroExpander::MacroContext::MacroContext() : macro(0), index(0)
+{
+}
+
+bool MacroExpander::MacroContext::empty() const
+{
+    return index == replacements.size();
+}
+
+const Token &MacroExpander::MacroContext::get()
+{
+    return replacements[index++];
+}
+
+void MacroExpander::MacroContext::unget()
+{
+    ASSERT(index > 0);
+    --index;
+}
+
 }  // namespace pp
 
--- a/gfx/angle/src/compiler/preprocessor/MacroExpander.h
+++ b/gfx/angle/src/compiler/preprocessor/MacroExpander.h
@@ -2,41 +2,37 @@
 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #ifndef COMPILER_PREPROCESSOR_MACROEXPANDER_H_
 #define COMPILER_PREPROCESSOR_MACROEXPANDER_H_
 
-#include <cassert>
 #include <memory>
 #include <vector>
 
-#include "Lexer.h"
-#include "Macro.h"
-#include "pp_utils.h"
+#include "compiler/preprocessor/Lexer.h"
+#include "compiler/preprocessor/Macro.h"
 
 namespace pp
 {
 
 class Diagnostics;
 struct SourceLocation;
 
 class MacroExpander : public Lexer
 {
   public:
     MacroExpander(Lexer *lexer, MacroSet *macroSet, Diagnostics *diagnostics);
     ~MacroExpander() override;
 
     void lex(Token *token) override;
 
   private:
-    PP_DISALLOW_COPY_AND_ASSIGN(MacroExpander);
-
     void getToken(Token *token);
     void ungetToken(const Token &token);
     bool isNextTokenLeftParen();
 
     bool pushMacro(const Macro &macro, const Token &identifier);
     void popMacro();
 
     bool expandMacro(const Macro &macro,
@@ -49,43 +45,30 @@ class MacroExpander : public Lexer
                           std::vector<MacroArg> *args,
                           SourceLocation *closingParenthesisLocation);
     void replaceMacroParams(const Macro &macro,
                             const std::vector<MacroArg> &args,
                             std::vector<Token> *replacements);
 
     struct MacroContext
     {
+        MacroContext();
+        bool empty() const;
+        const Token &get();
+        void unget();
+
         const Macro *macro;
         std::size_t index;
         std::vector<Token> replacements;
-
-        MacroContext()
-            : macro(0),
-              index(0)
-        {
-        }
-        bool empty() const
-        {
-            return index == replacements.size();
-        }
-        const Token &get()
-        {
-            return replacements[index++];
-        }
-        void unget()
-        {
-            assert(index > 0);
-            --index;
-        }
     };
 
     Lexer *mLexer;
     MacroSet *mMacroSet;
     Diagnostics *mDiagnostics;
 
     std::unique_ptr<Token> mReserveToken;
     std::vector<MacroContext *> mContextStack;
+    size_t mTotalTokensInContexts;
 };
 
 }  // namespace pp
 
 #endif  // COMPILER_PREPROCESSOR_MACROEXPANDER_H_
--- a/gfx/angle/src/compiler/preprocessor/Preprocessor.cpp
+++ b/gfx/angle/src/compiler/preprocessor/Preprocessor.cpp
@@ -1,24 +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.
 //
 
-#include "Preprocessor.h"
-
-#include <cassert>
+#include "compiler/preprocessor/Preprocessor.h"
 
-#include "DiagnosticsBase.h"
-#include "DirectiveParser.h"
-#include "Macro.h"
-#include "MacroExpander.h"
-#include "Token.h"
-#include "Tokenizer.h"
+#include "common/debug.h"
+#include "compiler/preprocessor/DiagnosticsBase.h"
+#include "compiler/preprocessor/DirectiveParser.h"
+#include "compiler/preprocessor/Macro.h"
+#include "compiler/preprocessor/MacroExpander.h"
+#include "compiler/preprocessor/Token.h"
+#include "compiler/preprocessor/Tokenizer.h"
 
 namespace pp
 {
 
 struct PreprocessorImpl
 {
     Diagnostics *diagnostics;
     MacroSet macroSet;
@@ -73,18 +72,18 @@ void Preprocessor::lex(Token *token)
     {
         mImpl->macroExpander.lex(token);
         switch (token->type)
         {
           // We should not be returning internal preprocessing tokens.
           // Convert preprocessing tokens to compiler tokens or report
           // diagnostics.
           case Token::PP_HASH:
-            assert(false);
-            break;
+              UNREACHABLE();
+              break;
           case Token::PP_NUMBER:
             mImpl->diagnostics->report(Diagnostics::PP_INVALID_NUMBER,
                                        token->location, token->text);
             break;
           case Token::PP_OTHER:
             mImpl->diagnostics->report(Diagnostics::PP_INVALID_CHARACTER,
                                        token->location, token->text);
             break;
--- a/gfx/angle/src/compiler/preprocessor/Preprocessor.h
+++ b/gfx/angle/src/compiler/preprocessor/Preprocessor.h
@@ -2,29 +2,29 @@
 // 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.
 //
 
 #ifndef COMPILER_PREPROCESSOR_PREPROCESSOR_H_
 #define COMPILER_PREPROCESSOR_PREPROCESSOR_H_
 
-#include <stddef.h>
+#include <cstddef>
 
-#include "pp_utils.h"
+#include "common/angleutils.h"
 
 namespace pp
 {
 
 class Diagnostics;
 class DirectiveHandler;
 struct PreprocessorImpl;
 struct Token;
 
-class Preprocessor
+class Preprocessor : angle::NonCopyable
 {
   public:
     Preprocessor(Diagnostics *diagnostics, DirectiveHandler *directiveHandler);
     ~Preprocessor();
 
     // count: specifies the number of elements in the string and length arrays.
     // string: specifies an array of pointers to strings.
     // length: specifies an array of string lengths.
@@ -39,16 +39,14 @@ class Preprocessor
     void predefineMacro(const char *name, int value);
 
     void lex(Token *token);
 
     // Set maximum preprocessor token size
     void setMaxTokenSize(size_t maxTokenSize);
 
   private:
-    PP_DISALLOW_COPY_AND_ASSIGN(Preprocessor);
-
     PreprocessorImpl *mImpl;
 };
 
 }  // namespace pp
 
 #endif  // COMPILER_PREPROCESSOR_PREPROCESSOR_H_
--- a/gfx/angle/src/compiler/preprocessor/Token.cpp
+++ b/gfx/angle/src/compiler/preprocessor/Token.cpp
@@ -1,19 +1,18 @@
 //
 // 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.
 //
 
-#include "Token.h"
+#include "compiler/preprocessor/Token.h"
 
-#include <cassert>
-
-#include "numeric_lex.h"
+#include "common/debug.h"
+#include "compiler/preprocessor/numeric_lex.h"
 
 namespace pp
 {
 
 void Token::reset()
 {
     type = 0;
     flags = 0;
@@ -50,29 +49,29 @@ void Token::setExpansionDisabled(bool di
     if (disable)
         flags |= EXPANSION_DISABLED;
     else
         flags &= ~EXPANSION_DISABLED;
 }
 
 bool Token::iValue(int *value) const
 {
-    assert(type == CONST_INT);
+    ASSERT(type == CONST_INT);
     return numeric_lex_int(text, value);
 }
 
 bool Token::uValue(unsigned int *value) const
 {
-    assert(type == CONST_INT);
+    ASSERT(type == CONST_INT);
     return numeric_lex_int(text, value);
 }
 
 bool Token::fValue(float *value) const
 {
-    assert(type == CONST_FLOAT);
+    ASSERT(type == CONST_FLOAT);
     return numeric_lex_float(text, value);
 }
 
 std::ostream &operator<<(std::ostream &out, const Token &token)
 {
     if (token.hasLeadingSpace())
         out << " ";
 
--- a/gfx/angle/src/compiler/preprocessor/Token.h
+++ b/gfx/angle/src/compiler/preprocessor/Token.h
@@ -5,17 +5,17 @@
 //
 
 #ifndef COMPILER_PREPROCESSOR_TOKEN_H_
 #define COMPILER_PREPROCESSOR_TOKEN_H_
 
 #include <ostream>
 #include <string>
 
-#include "SourceLocation.h"
+#include "compiler/preprocessor/SourceLocation.h"
 
 namespace pp
 {
 
 struct Token
 {
     enum Type
     {
@@ -108,13 +108,13 @@ inline bool operator==(const Token &lhs,
     return lhs.equals(rhs);
 }
 
 inline bool operator!=(const Token &lhs, const Token &rhs)
 {
     return !lhs.equals(rhs);
 }
 
-extern std::ostream &operator<<(std::ostream &out, const Token &token);
+std::ostream &operator<<(std::ostream &out, const Token &token);
 
 }  // namepsace pp
 
 #endif  // COMPILER_PREPROCESSOR_TOKEN_H_
--- a/gfx/angle/src/compiler/preprocessor/Tokenizer.cpp
+++ b/gfx/angle/src/compiler/preprocessor/Tokenizer.cpp
@@ -4,30 +4,106 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 // This file is auto-generated by generate_parser.sh. DO NOT EDIT!
 
 
 
-#line 13 "./Tokenizer.cpp"
-
 #define  YY_INT_ALIGNED short int
 
 /* A lexical scanner generated by flex */
 
+
+
+
+
+
+
+
+
+
+
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 39
+#define YY_FLEX_MINOR_VERSION 6
+#define YY_FLEX_SUBMINOR_VERSION 1
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+        
+        
+    
+    
+
+
+    
+    
+
+
+
+    
+    
+
+
+
+    
+    
+    
+
+
+
+
+
+
 /* First, we deal with  platform-specific or compiler-specific issues. */
 
 /* begin standard C headers. */
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
 #include <stdlib.h>
 
@@ -51,17 +127,16 @@
 
 #include <inttypes.h>
 typedef int8_t flex_int8_t;
 typedef uint8_t flex_uint8_t;
 typedef int16_t flex_int16_t;
 typedef uint16_t flex_uint16_t;
 typedef int32_t flex_int32_t;
 typedef uint32_t flex_uint32_t;
-typedef uint64_t flex_uint64_t;
 #else
 typedef signed char flex_int8_t;
 typedef short int flex_int16_t;
 typedef int flex_int32_t;
 typedef unsigned char flex_uint8_t; 
 typedef unsigned short int flex_uint16_t;
 typedef unsigned int flex_uint32_t;
 
@@ -93,150 +168,213 @@ typedef unsigned int flex_uint32_t;
 #ifndef UINT32_MAX
 #define UINT32_MAX             (4294967295U)
 #endif
 
 #endif /* ! C99 */
 
 #endif /* ! FLEXINT_H */
 
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else	/* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif	/* defined (__STDC__) */
-#endif	/* ! __cplusplus */
-
-#ifdef YY_USE_CONST
+
+
+/* TODO: this is always defined, so inline it */
 #define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
 #else
-#define yyconst
+#define yynoreturn
 #endif
 
+
+    
+
+
+
 /* Returned upon end-of-file. */
 #define YY_NULL 0
 
+
+
 /* Promotes a possibly negative, possibly signed char to an unsigned
  * integer for use as an array index.  If the signed char is negative,
  * we want to instead treat it as an 8-bit unsigned char, hence the
  * double cast.
  */
 #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
 
+
+
+
+
 /* An opaque pointer. */
 #ifndef YY_TYPEDEF_YY_SCANNER_T
 #define YY_TYPEDEF_YY_SCANNER_T
 typedef void* yyscan_t;
 #endif
 
+
+
+
+
+
+
+
+
+    
+    
+
+
+
+
+
+
+
+
 /* For convenience, these vars (plus the bison vars far below)
    are macros in the reentrant scanner. */
 #define yyin yyg->yyin_r
 #define yyout yyg->yyout_r
 #define yyextra yyg->yyextra_r
 #define yyleng yyg->yyleng_r
 #define yytext yyg->yytext_r
 #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
 #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
 #define yy_flex_debug yyg->yy_flex_debug_r
 
+
+
+
+
+
+
+
+
+    
+    
+    
+    
+
+
+
 /* Enter a start condition.  This macro really ought to take a parameter,
  * but we do it the disgusting crufty way forced on us by the ()-less
  * definition of BEGIN.
  */
 #define BEGIN yyg->yy_start = 1 + 2 *
 
+
+
 /* Translate the current start state into a value that can be later handed
  * to BEGIN to return to the state.  The YYSTATE alias is for lex
  * compatibility.
  */
 #define YY_START ((yyg->yy_start - 1) / 2)
 #define YYSTATE YY_START
 
+
+
 /* Action number for EOF rule of a given start state. */
 #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
 
+
+
 /* Special action meaning "start processing a new file". */
 #define YY_NEW_FILE pprestart(yyin ,yyscanner )
 
+
+
 #define YY_END_OF_BUFFER_CHAR 0
 
+
 /* Size of default input buffer. */
 #ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
 #define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
 #endif
 
+
 /* The state buf must be large enough to hold one state per character in the main buffer.
  */
 #define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
 
+
+
 #ifndef YY_TYPEDEF_YY_BUFFER_STATE
 #define YY_TYPEDEF_YY_BUFFER_STATE
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
 #endif
 
 #ifndef YY_TYPEDEF_YY_SIZE_T
 #define YY_TYPEDEF_YY_SIZE_T
 typedef size_t yy_size_t;
 #endif
 
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
+
+
 
 #define EOB_ACT_CONTINUE_SCAN 0
 #define EOB_ACT_END_OF_FILE 1
 #define EOB_ACT_LAST_MATCH 2
 
+
+
+    
     #define YY_LESS_LINENO(n)
     #define YY_LINENO_REWIND_TO(ptr)
     
+
+
+
 /* Return all but the first "n" matched characters back to the input stream. */
 #define yyless(n) \
 	do \
 		{ \
 		/* Undo effects of setting up yytext. */ \
         int yyless_macro_arg = (n); \
         YY_LESS_LINENO(yyless_macro_arg);\
 		*yy_cp = yyg->yy_hold_char; \
 		YY_RESTORE_YY_MORE_OFFSET \
 		yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
 		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
 		} \
 	while ( 0 )
 
+
+
 #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
 
+
 #ifndef YY_STRUCT_YY_BUFFER_STATE
 #define YY_STRUCT_YY_BUFFER_STATE
 struct yy_buffer_state
 	{
 	FILE *yy_input_file;
 
+
+
 	char *yy_ch_buf;		/* input buffer */
 	char *yy_buf_pos;		/* current position in input buffer */
 
 	/* Size of input buffer in bytes, not including room for EOB
 	 * characters.
 	 */
-	yy_size_t yy_buf_size;
+	int yy_buf_size;
 
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
 	 */
-	yy_size_t yy_n_chars;
+	int yy_n_chars;
 
 	/* Whether we "own" the buffer - i.e., we know we created it,
 	 * and can realloc() it to grow it, and should free() it to
 	 * delete it.
 	 */
 	int yy_is_our_buffer;
 
 	/* Whether this is an "interactive" input source; if so, and
@@ -250,16 +388,17 @@ struct yy_buffer_state
 	 * If so, '^' rules will be active on the next match, otherwise
 	 * not.
 	 */
 	int yy_at_bol;
 
     int yy_bs_lineno; /**< The line count. */
     int yy_bs_column; /**< The column count. */
     
+
 	/* Whether to try to fill the input buffer when we reach the
 	 * end of it.
 	 */
 	int yy_fill_buffer;
 
 	int yy_buffer_status;
 
 #define YY_BUFFER_NEW 0
@@ -274,103 +413,140 @@ struct yy_buffer_state
 	 * (via pprestart()), so that the user can continue scanning by
 	 * just pointing yyin at a new input file.
 	 */
 #define YY_BUFFER_EOF_PENDING 2
 
 	};
 #endif /* !YY_STRUCT_YY_BUFFER_STATE */
 
+
+
+
+
 /* We provide macros for accessing buffer states in case in the
  * future we want to put the buffer states in a more general
  * "scanner state".
  *
  * Returns the top of the stack, or NULL.
  */
 #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
                           ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
                           : NULL)
 
+
+
 /* Same as previous macro, but useful when we know that the buffer stack is not
  * NULL or when we need an lvalue. For internal use only.
  */
 #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
 
+
+
+
+
+
 void pprestart (FILE *input_file ,yyscan_t yyscanner );
 void pp_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
 YY_BUFFER_STATE pp_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
 void pp_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
 void pp_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
 void pppush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
 void pppop_buffer_state (yyscan_t yyscanner );
 
+
 static void ppensure_buffer_stack (yyscan_t yyscanner );
 static void pp_load_buffer_state (yyscan_t yyscanner );
 static void pp_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
 
+
+
 #define YY_FLUSH_BUFFER pp_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
 
+
 YY_BUFFER_STATE pp_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
 YY_BUFFER_STATE pp_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE pp_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );
+YY_BUFFER_STATE pp_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
 
 void *ppalloc (yy_size_t ,yyscan_t yyscanner );
 void *pprealloc (void *,yy_size_t ,yyscan_t yyscanner );
 void ppfree (void * ,yyscan_t yyscanner );
 
+
 #define yy_new_buffer pp_create_buffer
 
+
+
 #define yy_set_interactive(is_interactive) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){ \
         ppensure_buffer_stack (yyscanner); \
 		YY_CURRENT_BUFFER_LVALUE =    \
             pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
 	}
 
+
+
 #define yy_set_bol(at_bol) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){\
         ppensure_buffer_stack (yyscanner); \
 		YY_CURRENT_BUFFER_LVALUE =    \
             pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
 	}
 
+
+
 #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
 
+
 /* Begin user sect3 */
 
-#define ppwrap(yyscanner) 1
+#define ppwrap(yyscanner) (/*CONSTCOND*/1)
 #define YY_SKIP_YYWRAP
 
 typedef unsigned char YY_CHAR;
 
+
+
+
 typedef int yy_state_type;
 
 #define yytext_ptr yytext_r
 
+
+
+
+
+
 static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
 static yy_state_type yy_try_NUL_trans (yy_state_type current_state  ,yyscan_t yyscanner);
 static int yy_get_next_buffer (yyscan_t yyscanner );
-static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+static void yynoreturn yy_fatal_error (yyconst char* msg ,yyscan_t yyscanner );
+
+
+
 
 /* Done after the current pattern has been matched and before the
  * corresponding action - sets up yytext.
  */
 #define YY_DO_BEFORE_ACTION \
 	yyg->yytext_ptr = yy_bp; \
-	yyleng = (yy_size_t) (yy_cp - yy_bp); \
+	yyleng = (int) (yy_cp - yy_bp); \
 	yyg->yy_hold_char = *yy_cp; \
 	*yy_cp = '\0'; \
 	yyg->yy_c_buf_p = yy_cp;
 
+
+
 #define YY_NUM_RULES 38
 #define YY_END_OF_BUFFER 39
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
 	{
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
@@ -385,17 +561,17 @@ static yyconst flex_int16_t yy_accept[98
        11,   11,    9,   11,    9,    9,   14,   16,   18,   17,
        15,    8,   36,   36,   31,   21,   32,   22,    3,    5,
         6,   11,   10,   11,   10,    1,   10,   11,   10,    0,
        10,    9,    9,    9,   28,   29,    0,   10,   10,   10,
        10,    9,   10,   10,    9,   10,    0
 
     } ;
 
-static yyconst flex_int32_t yy_ec[256] =
+static yyconst YY_CHAR yy_ec[256] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
         2,    2,    4,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    2,    5,    1,    6,    1,    7,    8,    1,    9,
         9,   10,   11,    9,   12,   13,   14,   15,   16,   16,
        16,   16,   16,   16,   16,   17,   17,    9,    9,   18,
        19,   20,    9,    1,   21,   21,   21,   21,   22,   23,
@@ -417,24 +593,24 @@ static yyconst flex_int32_t yy_ec[256] =
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[30] =
+static yyconst YY_CHAR yy_meta[30] =
     {   0,
         1,    1,    2,    2,    1,    1,    1,    1,    1,    3,
         1,    1,    4,    1,    5,    5,    5,    1,    1,    1,
         5,    5,    5,    5,    5,    5,    1,    1,    1
     } ;
 
-static yyconst flex_int16_t yy_base[103] =
+static yyconst flex_uint16_t yy_base[103] =
     {   0,
         0,    0,   27,   29,  137,  194,  133,  194,  117,  100,
       194,   98,   26,  194,   94,   24,   28,   33,   32,   39,
        51,   39,   80,   50,    0,   68,   25,   54,    0,  194,
        88,   71,   80,  194,  194,  194,  194,  194,  194,  194,
       194,  194,  194,   71,  194,    0,  194,   85,   55,   64,
        99,  111,   53,  105,    0,   50,   55,  194,  194,  194,
        40,    0,  194,   38,  194,  194,  194,  194,    0,  194,
@@ -456,17 +632,17 @@ static yyconst flex_int16_t yy_def[103] 
        97,   99,   97,   97,   97,   97,   97,   97,  100,   97,
        97,   44,   44,   72,   72,  101,   48,   51,   51,   97,
        52,   51,  102,   51,   97,   97,   97,   74,   78,   97,
        51,   51,   97,   97,   51,   97,    0,   97,   97,   97,
 
        97,   97
     } ;
 
-static yyconst flex_int16_t yy_nxt[224] =
+static yyconst flex_uint16_t yy_nxt[224] =
     {   0,
         6,    7,    8,    9,   10,   11,   12,   13,   14,   15,
        16,   17,   18,   19,   20,   21,   21,   22,   23,   24,
        25,   25,   25,   25,   25,   25,   26,   27,   28,   30,
        31,   30,   31,   37,   40,   62,   32,   95,   32,   42,
        63,   45,   41,   65,   38,   46,   43,   44,   44,   44,
        47,   48,   66,   49,   49,   50,   57,   58,   86,   51,
        52,   51,   51,   53,   54,   55,   55,   55,   60,   61,
@@ -539,20 +715,20 @@ http://msdn.microsoft.com/en-us/library/
 
 IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh.
 */
 
 #if defined(_MSC_VER)
 #pragma warning(disable: 4005)
 #endif
 
-#include "Tokenizer.h"
-
-#include "DiagnosticsBase.h"
-#include "Token.h"
+#include "compiler/preprocessor/Tokenizer.h"
+
+#include "compiler/preprocessor/DiagnosticsBase.h"
+#include "compiler/preprocessor/Token.h"
 
 #if defined(__GNUC__)
 // Triggered by the auto-generated yy_fatal_error function.
 #pragma GCC diagnostic ignored "-Wmissing-noreturn"
 #elif defined(_MSC_VER)
 #pragma warning(disable: 4244)
 #endif
 
@@ -591,124 +767,205 @@ typedef pp::SourceLocation YYLTYPE;
         yylloc->file = yyfileno;                                    \
         yylloc->line = yylineno;                                    \
         scanLoc->cIndex += yyleng;                                  \
     } while(0);
 
 #define YY_INPUT(buf, result, maxSize) \
     result = yyextra->input.read(buf, maxSize, &yylineno);
 
+
+
+
+
 #define INITIAL 0
 #define COMMENT 1
 
+
+
+
+
+
 #define YY_EXTRA_TYPE pp::Tokenizer::Context*
 
+
+
+
 /* Holds the entire state of the reentrant scanner. */
 struct yyguts_t
     {
 
     /* User-defined. Not touched by flex. */
     YY_EXTRA_TYPE yyextra_r;
 
     /* The rest are the same as the globals declared in the non-reentrant scanner. */
     FILE *yyin_r, *yyout_r;
     size_t yy_buffer_stack_top; /**< index of top of stack. */
     size_t yy_buffer_stack_max; /**< capacity of stack. */
     YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
     char yy_hold_char;
-    yy_size_t yy_n_chars;
-    yy_size_t yyleng_r;
+    int yy_n_chars;
+    int yyleng_r;
     char *yy_c_buf_p;
     int yy_init;
     int yy_start;
     int yy_did_buffer_switch_on_eof;
     int yy_start_stack_ptr;
     int yy_start_stack_depth;
     int *yy_start_stack;
     yy_state_type yy_last_accepting_state;
     char* yy_last_accepting_cpos;
 
     int yylineno_r;
     int yy_flex_debug_r;
 
+
+
+
     char *yytext_r;
     int yy_more_flag;
     int yy_more_len;
 
+
+
     YYSTYPE * yylval_r;
 
+
+
     YYLTYPE * yylloc_r;
 
+
     }; /* end struct yyguts_t */
 
+
+
+
 static int yy_init_globals (yyscan_t yyscanner );
 
+
+
+
+    
     /* This must go here because YYSTYPE and YYLTYPE are included
      * from bison output in section 1.*/
     #    define yylval yyg->yylval_r
     
+
+    
     #    define yylloc yyg->yylloc_r
     
+
+
 int pplex_init (yyscan_t* scanner);
 
 int pplex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
 
+
+
 /* Accessor methods to globals.
    These are made visible to non-reentrant scanners for convenience. */
 
+
 int pplex_destroy (yyscan_t yyscanner );
 
+
+
 int ppget_debug (yyscan_t yyscanner );
 
+
+
 void ppset_debug (int debug_flag ,yyscan_t yyscanner );
 
+
+
 YY_EXTRA_TYPE ppget_extra (yyscan_t yyscanner );
 
+
+
 void ppset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
 
+
+
 FILE *ppget_in (yyscan_t yyscanner );
 
-void ppset_in  (FILE * in_str ,yyscan_t yyscanner );
+
+
+void ppset_in  (FILE * _in_str ,yyscan_t yyscanner );
+
+
 
 FILE *ppget_out (yyscan_t yyscanner );
 
-void ppset_out  (FILE * out_str ,yyscan_t yyscanner );
-
-yy_size_t ppget_leng (yyscan_t yyscanner );
+
+
+void ppset_out  (FILE * _out_str ,yyscan_t yyscanner );
+
+
+
+			int ppget_leng (yyscan_t yyscanner );
+
+
 
 char *ppget_text (yyscan_t yyscanner );
 
+
+
 int ppget_lineno (yyscan_t yyscanner );
 
-void ppset_lineno (int line_number ,yyscan_t yyscanner );
+
+
+void ppset_lineno (int _line_number ,yyscan_t yyscanner );
+
+
+
 
 int ppget_column  (yyscan_t yyscanner );
 
-void ppset_column (int column_no ,yyscan_t yyscanner );
+
+
+
+
+void ppset_column (int _column_no ,yyscan_t yyscanner );
+
+
+
 
 YYSTYPE * ppget_lval (yyscan_t yyscanner );
 
+
 void ppset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
 
+
+    
        YYLTYPE *ppget_lloc (yyscan_t yyscanner );
     
+
+    
         void ppset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
     
+
+
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
  */
 
 #ifndef YY_SKIP_YYWRAP
 #ifdef __cplusplus
 extern "C" int ppwrap (yyscan_t yyscanner );
 #else
 extern int ppwrap (yyscan_t yyscanner );
 #endif
 #endif
 
+
+#ifndef YY_NO_UNPUT
+    
+#endif
+
+
 #ifndef yytext_ptr
 static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
 #endif
 
 #ifdef YY_NEED_STRLEN
 static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
 #endif
 
@@ -717,29 +974,44 @@ static int yy_flex_strlen (yyconst char 
 #ifdef __cplusplus
 static int yyinput (yyscan_t yyscanner );
 #else
 static int input (yyscan_t yyscanner );
 #endif
 
 #endif
 
+
+
+
+
+
+
+
 /* Amount of stuff to slurp up with each read. */
 #ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
 #define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
 #endif
 
+
 /* Copy whatever the last rule matched to the standard output. */
 #ifndef ECHO
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
 #endif
 
+
+
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
  * is returned in "result".
  */
 #ifndef YY_INPUT
 #define YY_INPUT(buf,result,max_size) \
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
 		{ \
 		int c = '*'; \
@@ -751,100 +1023,141 @@ static int input (yyscan_t yyscanner );
 			buf[n++] = (char) c; \
 		if ( c == EOF && ferror( yyin ) ) \
 			YY_FATAL_ERROR( "input in flex scanner failed" ); \
 		result = n; \
 		} \
 	else \
 		{ \
 		errno=0; \
-		while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+		while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
 			{ \
 			if( errno != EINTR) \
 				{ \
 				YY_FATAL_ERROR( "input in flex scanner failed" ); \
 				break; \
 				} \
 			errno=0; \
 			clearerr(yyin); \
 			} \
 		}\
 \
 
 #endif
 
+
+
 /* No semi-colon after return; correct usage is to write "yyterminate();" -
  * we don't want an extra ';' after the "return" because that will cause
  * some compilers to complain about unreachable statements.
  */
 #ifndef yyterminate
 #define yyterminate() return YY_NULL
 #endif
 
+
 /* Number of entries by which start-condition stack grows. */
 #ifndef YY_START_STACK_INCR
 #define YY_START_STACK_INCR 25
 #endif
 
+
 /* Report a fatal error. */
 #ifndef YY_FATAL_ERROR
 #define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
 #endif
 
+
+
+
+
 /* end tables serialization structures and prototypes */
 
+
+
 /* Default declaration of generated scanner - a define so the user can
  * easily add parameters.
  */
 #ifndef YY_DECL
 #define YY_DECL_IS_OURS 1
 
+
+
+
+
+
+        
+    
+    
+
+
+
+    
+    
+    
+
+
 extern int pplex \
                (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
 
 #define YY_DECL int pplex \
                (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
 #endif /* !YY_DECL */
 
+
 /* Code executed at the beginning of each rule, after yytext and yyleng
  * have been set up.
  */
 #ifndef YY_USER_ACTION
 #define YY_USER_ACTION
 #endif
 
+
+
 /* Code executed at the end of each rule. */
 #ifndef YY_BREAK
-#define YY_BREAK break;
+#define YY_BREAK /*LINTED*/break;
 #endif
 
+
+
 #define YY_RULE_SETUP \
 	YY_USER_ACTION
 
+
+
 /** The main scanner function which does all the work.
  */
 YY_DECL
 {
-	register yy_state_type yy_current_state;
-	register char *yy_cp, *yy_bp;
-	register int yy_act;
+	yy_state_type yy_current_state;
+	char *yy_cp, *yy_bp;
+	int yy_act;
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
+
+
+
     yylval = yylval_param;
 
+
+
     yylloc = yylloc_param;
 
+
 	if ( !yyg->yy_init )
 		{
 		yyg->yy_init = 1;
 
 #ifdef YY_USER_INIT
 		YY_USER_INIT;
 #endif
 
+
+
 		if ( ! yyg->yy_start )
 			yyg->yy_start = 1;	/* first start state */
 
 		if ( ! yyin )
 			yyin = stdin;
 
 		if ( ! yyout )
 			yyout = stdout;
@@ -855,60 +1168,64 @@ YY_DECL
 				pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
 		}
 
 		pp_load_buffer_state(yyscanner );
 		}
 
 	{
 
+
     /* Line comment */
 
-	while ( 1 )		/* loops until end-of-file is reached */
+	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
 		yy_cp = yyg->yy_c_buf_p;
 
 		/* Support of yytext. */
 		*yy_cp = yyg->yy_hold_char;
 
 		/* yy_bp points to the position in yy_ch_buf of the start of
 		 * the current run.
 		 */
 		yy_bp = yy_cp;
 
 		yy_current_state = yyg->yy_start;
 yy_match:
 		do
 			{
-			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
+			YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
 			if ( yy_accept[yy_current_state] )
 				{
 				yyg->yy_last_accepting_state = yy_current_state;
 				yyg->yy_last_accepting_cpos = yy_cp;
 				}
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
 				if ( yy_current_state >= 98 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
-			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
 			++yy_cp;
 			}
 		while ( yy_current_state != 97 );
 		yy_cp = yyg->yy_last_accepting_cpos;
 		yy_current_state = yyg->yy_last_accepting_state;
 
 yy_find_action:
 		yy_act = yy_accept[yy_current_state];
 
 		YY_DO_BEFORE_ACTION;
 
+
+
 do_action:	/* This label is used only to access EOF actions. */
 
+
 		switch ( yy_act )
 	{ /* beginning of action switch */
 			case 0: /* must back up */
 			/* undo the effects of YY_DO_BEFORE_ACTION */
 			*yy_cp = yyg->yy_hold_char;
 			yy_cp = yyg->yy_last_accepting_cpos;
 			yy_current_state = yyg->yy_last_accepting_state;
 			goto yy_find_action;
@@ -1321,29 +1638,34 @@ ECHO;
 	default:
 		YY_FATAL_ERROR(
 			"fatal flex scanner internal error--no action found" );
 	} /* end of action switch */
 		} /* end of scanning one token */
 	} /* end of user's declarations */
 } /* end of pplex */
 
+
+
+
+
+
 /* yy_get_next_buffer - try to read in a new buffer
  *
  * Returns a code representing an action:
  *	EOB_ACT_LAST_MATCH -
  *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
  *	EOB_ACT_END_OF_FILE - end of file
  */
 static int yy_get_next_buffer (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
-	register char *source = yyg->yytext_ptr;
-	register int number_to_move, i;
+	char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+	char *source = yyg->yytext_ptr;
+	yy_size_t number_to_move, i;
 	int ret_val;
 
 	if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
 		YY_FATAL_ERROR(
 		"fatal flex scanner internal error--end of buffer missed" );
 
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
 		{ /* Don't try to fill the buffer, so this is an EOF. */
@@ -1362,75 +1684,77 @@ static int yy_get_next_buffer (yyscan_t 
 			 */
 			return EOB_ACT_LAST_MATCH;
 			}
 		}
 
 	/* Try to read more data. */
 
 	/* First move last chars to start of buffer. */
-	number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+	number_to_move = (yy_size_t) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
 
 	for ( i = 0; i < number_to_move; ++i )
 		*(dest++) = *(source++);
 
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
 		/* don't do the read, it's not guaranteed to return an EOF,
 		 * just force an EOF
 		 */
 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
 
 	else
 		{
-			yy_size_t num_to_read =
-			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+			int num_to_read =
+			static_cast<int>(YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1);
 
 		while ( num_to_read <= 0 )
 			{ /* Not enough room in the buffer - grow it. */
 
 			/* just a shorter name for the current buffer */
 			YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
 
 			int yy_c_buf_p_offset =
 				(int) (yyg->yy_c_buf_p - b->yy_ch_buf);
 
 			if ( b->yy_is_our_buffer )
 				{
-				yy_size_t new_size = b->yy_buf_size * 2;
+				int new_size = b->yy_buf_size * 2;
 
 				if ( new_size <= 0 )
 					b->yy_buf_size += b->yy_buf_size / 8;
 				else
 					b->yy_buf_size *= 2;
 
 				b->yy_ch_buf = (char *)
 					/* Include room in for 2 EOB chars. */
 					pprealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
 				}
 			else
 				/* Can't grow it, we don't own it. */
-				b->yy_ch_buf = 0;
+				b->yy_ch_buf = NULL;
 
 			if ( ! b->yy_ch_buf )
 				YY_FATAL_ERROR(
 				"fatal error - scanner input buffer overflow" );
 
 			yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
 
-			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
-						number_to_move - 1;
+			num_to_read = static_cast<int>(YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+						number_to_move - 1);
 
 			}
 
 		if ( num_to_read > YY_READ_BUF_SIZE )
 			num_to_read = YY_READ_BUF_SIZE;
 
 		/* Read in more data. */
+		yy_size_t ret = 0;
 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			yyg->yy_n_chars, num_to_read );
+			ret, num_to_read );
+		yyg->yy_n_chars = static_cast<int>(ret);
 
 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
 		}
 
 	if ( yyg->yy_n_chars == 0 )
 		{
 		if ( number_to_move == YY_MORE_ADJ )
 			{
@@ -1444,93 +1768,101 @@ static int yy_get_next_buffer (yyscan_t 
 			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
 				YY_BUFFER_EOF_PENDING;
 			}
 		}
 
 	else
 		ret_val = EOB_ACT_CONTINUE_SCAN;
 
-	if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+	if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
 		/* Extend the array by 50%, plus the number we really need. */
 		yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
 		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) pprealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
 		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
 			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
 	}
 
-	yyg->yy_n_chars += number_to_move;
+	yyg->yy_n_chars += static_cast<int>(number_to_move);
 	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
 	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
 
 	yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
 
 	return ret_val;
 }
 
+
 /* yy_get_previous_state - get the state just before the EOB char was reached */
 
+
     static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
 {
-	register yy_state_type yy_current_state;
-	register char *yy_cp;
+	yy_state_type yy_current_state;
+	char *yy_cp;
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
 	yy_current_state = yyg->yy_start;
 
 	for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
 		{
-		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
 		if ( yy_accept[yy_current_state] )
 			{
 			yyg->yy_last_accepting_state = yy_current_state;
 			yyg->yy_last_accepting_cpos = yy_cp;
 			}
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
 			if ( yy_current_state >= 98 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
-		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
 		}
 
 	return yy_current_state;
 }
 
+
 /* yy_try_NUL_trans - try to make a transition on the NUL character
  *
  * synopsis
  *	next_state = yy_try_NUL_trans( current_state );
  */
     static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state , yyscan_t yyscanner)
 {
-	register int yy_is_jam;
+	int yy_is_jam;
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
-	register char *yy_cp = yyg->yy_c_buf_p;
-
-	register YY_CHAR yy_c = 1;
+	char *yy_cp = yyg->yy_c_buf_p;
+
+	YY_CHAR yy_c = 1;
 	if ( yy_accept[yy_current_state] )
 		{
 		yyg->yy_last_accepting_state = yy_current_state;
 		yyg->yy_last_accepting_cpos = yy_cp;
 		}
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
 		if ( yy_current_state >= 98 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
-	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
 	yy_is_jam = (yy_current_state == 97);
 
 	(void)yyg;
 	return yy_is_jam ? 0 : yy_current_state;
 }
 
+
+#ifndef YY_NO_UNPUT
+
+#endif
+
 #ifndef YY_NO_INPUT
 #ifdef __cplusplus
     static int yyinput (yyscan_t yyscanner)
 #else
     static int input  (yyscan_t yyscanner)
 #endif
 
 {
@@ -1546,17 +1878,17 @@ static int yy_get_next_buffer (yyscan_t 
 		 * valid NUL; if not, then we've hit the end of the buffer.
 		 */
 		if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
 			/* This was really a NUL. */
 			*yyg->yy_c_buf_p = '\0';
 
 		else
 			{ /* need more input */
-			yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+			int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
 			++yyg->yy_c_buf_p;
 
 			switch ( yy_get_next_buffer( yyscanner ) )
 				{
 				case EOB_ACT_LAST_MATCH:
 					/* This happens because yy_g_n_b()
 					 * sees that we've accumulated a
 					 * token and flags that we need to
@@ -1570,17 +1902,17 @@ static int yy_get_next_buffer (yyscan_t 
 					/* Reset buffer status. */
 					pprestart(yyin ,yyscanner);
 
 					/*FALLTHROUGH*/
 
 				case EOB_ACT_END_OF_FILE:
 					{
 					if ( ppwrap(yyscanner ) )
-						return EOF;
+						return 0;
 
 					if ( ! yyg->yy_did_buffer_switch_on_eof )
 						YY_NEW_FILE;
 #ifdef __cplusplus
 					return yyinput(yyscanner);
 #else
 					return input(yyscanner);
 #endif
@@ -1592,16 +1924,17 @@ static int yy_get_next_buffer (yyscan_t 
 				}
 			}
 		}
 
 	c = *(unsigned char *) yyg->yy_c_buf_p;	/* cast for 8-bit char's */
 	*yyg->yy_c_buf_p = '\0';	/* preserve yytext */
 	yyg->yy_hold_char = *++yyg->yy_c_buf_p;
 
+
 	return c;
 }
 #endif	/* ifndef YY_NO_INPUT */
 
 /** Immediately switch to a different input stream.
  * @param input_file A readable stream.
  * @param yyscanner The scanner object.
  * @note This function does not reset the start condition to @c INITIAL .
@@ -1615,16 +1948,17 @@ static int yy_get_next_buffer (yyscan_t 
 		YY_CURRENT_BUFFER_LVALUE =
             pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
 	}
 
 	pp_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
 	pp_load_buffer_state(yyscanner );
 }
 
+
 /** Switch to a different input buffer.
  * @param new_buffer The new input buffer.
  * @param yyscanner The scanner object.
  */
     void pp_switch_to_buffer  (YY_BUFFER_STATE  new_buffer , yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
@@ -1651,16 +1985,17 @@ static int yy_get_next_buffer (yyscan_t 
 	/* We don't actually know whether we did this switch during
 	 * EOF (ppwrap()) processing, but the only time this flag
 	 * is looked at is after ppwrap() is called, so it's safe
 	 * to go ahead and always set it.
 	 */
 	yyg->yy_did_buffer_switch_on_eof = 1;
 }
 
+
 static void pp_load_buffer_state  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 	yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
 	yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
 	yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
 	yyg->yy_hold_char = *yyg->yy_c_buf_p;
 }
@@ -1674,32 +2009,33 @@ static void pp_load_buffer_state  (yysca
     YY_BUFFER_STATE pp_create_buffer  (FILE * file, int  size , yyscan_t yyscanner)
 {
 	YY_BUFFER_STATE b;
     
 	b = (YY_BUFFER_STATE) ppalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
 	if ( ! b )
 		YY_FATAL_ERROR( "out of dynamic memory in pp_create_buffer()" );
 
-	b->yy_buf_size = size;
+	b->yy_buf_size = (yy_size_t)size;
 
 	/* yy_ch_buf has to be 2 characters longer than the size given because
 	 * we need to put in 2 end-of-buffer characters.
 	 */
 	b->yy_ch_buf = (char *) ppalloc(b->yy_buf_size + 2 ,yyscanner );
 	if ( ! b->yy_ch_buf )
 		YY_FATAL_ERROR( "out of dynamic memory in pp_create_buffer()" );
 
 	b->yy_is_our_buffer = 1;
 
 	pp_init_buffer(b,file ,yyscanner);
 
 	return b;
 }
 
+
 /** Destroy the buffer.
  * @param b a buffer created with pp_create_buffer()
  * @param yyscanner The scanner object.
  */
     void pp_delete_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
@@ -1710,16 +2046,17 @@ static void pp_load_buffer_state  (yysca
 		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
 
 	if ( b->yy_is_our_buffer )
 		ppfree((void *) b->yy_ch_buf ,yyscanner );
 
 	ppfree((void *) b ,yyscanner );
 }
 
+
 /* Initializes or reinitializes a buffer.
  * This function is sometimes called more than once on the same buffer,
  * such as during a pprestart() or at EOF.
  */
     static void pp_init_buffer  (YY_BUFFER_STATE  b, FILE * file , yyscan_t yyscanner)
 
 {
 	int oerrno = errno;
@@ -1734,18 +2071,21 @@ static void pp_load_buffer_state  (yysca
      * called from pprestart() or through yy_get_next_buffer.
      * In that case, we don't want to reset the lineno or column.
      */
     if (b != YY_CURRENT_BUFFER){
         b->yy_bs_lineno = 1;
         b->yy_bs_column = 0;
     }
 
+
+    
         b->yy_is_interactive = 0;
     
+
 	errno = oerrno;
 }
 
 /** Discard all buffered characters. On the next scan, YY_INPUT will be called.
  * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
  * @param yyscanner The scanner object.
  */
     void pp_flush_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
@@ -1800,16 +2140,17 @@ void pppush_buffer_state (YY_BUFFER_STAT
 		yyg->yy_buffer_stack_top++;
 	YY_CURRENT_BUFFER_LVALUE = new_buffer;
 
 	/* copied from pp_switch_to_buffer. */
 	pp_load_buffer_state(yyscanner );
 	yyg->yy_did_buffer_switch_on_eof = 1;
 }
 
+
 /** Removes and deletes the top of the stack, if present.
  *  The next element becomes the new top.
  *  @param yyscanner The scanner object.
  */
 void pppop_buffer_state (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 	if (!YY_CURRENT_BUFFER)
@@ -1821,156 +2162,180 @@ void pppop_buffer_state (yyscan_t yyscan
 		--yyg->yy_buffer_stack_top;
 
 	if (YY_CURRENT_BUFFER) {
 		pp_load_buffer_state(yyscanner );
 		yyg->yy_did_buffer_switch_on_eof = 1;
 	}
 }
 
+
 /* Allocates the stack if it does not exist.
  *  Guarantees space for at least one push.
  */
 static void ppensure_buffer_stack (yyscan_t yyscanner)
 {
 	yy_size_t num_to_alloc;
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
 	if (!yyg->yy_buffer_stack) {
 
 		/* First allocation is just for 2 elements, since we don't know if this
 		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
 		 * immediate realloc on the next call.
          */
-		num_to_alloc = 1;
+      num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
 		yyg->yy_buffer_stack = (struct yy_buffer_state**)ppalloc
 								(num_to_alloc * sizeof(struct yy_buffer_state*)
 								, yyscanner);
 		if ( ! yyg->yy_buffer_stack )
 			YY_FATAL_ERROR( "out of dynamic memory in ppensure_buffer_stack()" );
 								  
+		
 		memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
 				
 		yyg->yy_buffer_stack_max = num_to_alloc;
 		yyg->yy_buffer_stack_top = 0;
 		return;
 	}
 
 	if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
 
 		/* Increase the buffer to prepare for a possible push. */
-		int grow_size = 8 /* arbitrary grow size */;
+		yy_size_t grow_size = 8 /* arbitrary grow size */;
 
 		num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
 		yyg->yy_buffer_stack = (struct yy_buffer_state**)pprealloc
 								(yyg->yy_buffer_stack,
 								num_to_alloc * sizeof(struct yy_buffer_state*)
 								, yyscanner);
 		if ( ! yyg->yy_buffer_stack )
 			YY_FATAL_ERROR( "out of dynamic memory in ppensure_buffer_stack()" );
 
 		/* zero only the new slots.*/
 		memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
 		yyg->yy_buffer_stack_max = num_to_alloc;
 	}
 }
 
+
+
+
+
 /** Setup the input buffer state to scan directly from a user-specified character buffer.
  * @param base the character buffer
  * @param size the size in bytes of the character buffer
  * @param yyscanner The scanner object.
  * @return the newly allocated buffer state object. 
  */
 YY_BUFFER_STATE pp_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscanner)
 {
 	YY_BUFFER_STATE b;
     
 	if ( size < 2 ||
 	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
 	     base[size-1] != YY_END_OF_BUFFER_CHAR )
 		/* They forgot to leave room for the EOB's. */
-		return 0;
+		return NULL;
 
 	b = (YY_BUFFER_STATE) ppalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
 	if ( ! b )
 		YY_FATAL_ERROR( "out of dynamic memory in pp_scan_buffer()" );
 
-	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_size = static_cast<int>(size - 2);	/* "- 2" to take care of EOB's */
 	b->yy_buf_pos = b->yy_ch_buf = base;
 	b->yy_is_our_buffer = 0;
-	b->yy_input_file = 0;
+	b->yy_input_file = NULL;
 	b->yy_n_chars = b->yy_buf_size;
 	b->yy_is_interactive = 0;
 	b->yy_at_bol = 1;
 	b->yy_fill_buffer = 0;
 	b->yy_buffer_status = YY_BUFFER_NEW;
 
 	pp_switch_to_buffer(b ,yyscanner );
 
 	return b;
 }
 
+
+
+
 /** Setup the input buffer state to scan a string. The next call to pplex() will
  * scan from a @e copy of @a str.
  * @param yystr a NUL-terminated string to scan
  * @param yyscanner The scanner object.
  * @return the newly allocated buffer state object.
  * @note If you want to scan bytes that may contain NUL values, then use
  *       pp_scan_bytes() instead.
  */
 YY_BUFFER_STATE pp_scan_string (yyconst char * yystr , yyscan_t yyscanner)
 {
     
-	return pp_scan_bytes(yystr,strlen(yystr) ,yyscanner);
+	return pp_scan_bytes(yystr,(int) strlen(yystr) ,yyscanner);
 }
 
+
+
+
 /** Setup the input buffer state to scan the given bytes. The next call to pplex() will
  * scan from a @e copy of @a bytes.
  * @param yybytes the byte buffer to scan
  * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
  * @param yyscanner The scanner object.
  * @return the newly allocated buffer state object.
  */
-YY_BUFFER_STATE pp_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len , yyscan_t yyscanner)
+YY_BUFFER_STATE pp_scan_bytes  (yyconst char * yybytes, int  _yybytes_len , yyscan_t yyscanner)
 {
 	YY_BUFFER_STATE b;
 	char *buf;
 	yy_size_t n;
 	yy_size_t i;
     
 	/* Get memory for full buffer, including space for trailing EOB's. */
-	n = _yybytes_len + 2;
+	n = (yy_size_t) _yybytes_len + 2;
 	buf = (char *) ppalloc(n ,yyscanner );
 	if ( ! buf )
 		YY_FATAL_ERROR( "out of dynamic memory in pp_scan_bytes()" );
 
-	for ( i = 0; i < _yybytes_len; ++i )
+	for ( i = 0; i < static_cast<yy_size_t>(_yybytes_len); ++i )
 		buf[i] = yybytes[i];
 
 	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
 
 	b = pp_scan_buffer(buf,n ,yyscanner);
 	if ( ! b )
 		YY_FATAL_ERROR( "bad buffer in pp_scan_bytes()" );
 
 	/* It's okay to grow etc. this buffer, and we should throw it
 	 * away when we're done.
 	 */
 	b->yy_is_our_buffer = 1;
 
 	return b;
 }
 
+
+
+
+
+
+
+
+
+
+
 #ifndef YY_EXIT_FAILURE
 #define YY_EXIT_FAILURE 2
 #endif
 
-static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+static void yynoreturn yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
 {
-    	(void) fprintf( stderr, "%s\n", msg );
+	struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	(void)yyg;
+	(void) fprintf( stderr, "%s\n", msg );
 	exit( YY_EXIT_FAILURE );
 }
 
 /* Redefine yyless() so it works in section 3 code. */
 
 #undef yyless
 #define yyless(n) \
 	do \
@@ -1981,186 +2346,237 @@ static void yy_fatal_error (yyconst char
 		yytext[yyleng] = yyg->yy_hold_char; \
 		yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
 		yyg->yy_hold_char = *yyg->yy_c_buf_p; \
 		*yyg->yy_c_buf_p = '\0'; \
 		yyleng = yyless_macro_arg; \
 		} \
 	while ( 0 )
 
+
+
 /* Accessor  methods (get/set functions) to struct members. */
 
+
 /** Get the user-defined data for this scanner.
  * @param yyscanner The scanner object.
  */
 YY_EXTRA_TYPE ppget_extra  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
     return yyextra;
 }
 
+
+
 /** Get the current line number.
  * @param yyscanner The scanner object.
  */
 int ppget_lineno  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
     
+    
         if (! YY_CURRENT_BUFFER)
             return 0;
     
     return yylineno;
 }
 
+
+
+
 /** Get the current column number.
  * @param yyscanner The scanner object.
  */
 int ppget_column  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
     
+    
         if (! YY_CURRENT_BUFFER)
             return 0;
     
     return yycolumn;
 }
 
+
+
+
 /** Get the input stream.
  * @param yyscanner The scanner object.
  */
 FILE *ppget_in  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
     return yyin;
 }
 
+
+
 /** Get the output stream.
  * @param yyscanner The scanner object.
  */
 FILE *ppget_out  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
     return yyout;
 }
 
+
+
 /** Get the length of the current token.
  * @param yyscanner The scanner object.
  */
-yy_size_t ppget_leng  (yyscan_t yyscanner)
+int ppget_leng  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
     return yyleng;
 }
 
+
 /** Get the current token.
  * @param yyscanner The scanner object.
  */
 
 char *ppget_text  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
     return yytext;
 }
 
+
+
 /** Set the user-defined data. This data is never touched by the scanner.
  * @param user_defined The data to be associated with this scanner.
  * @param yyscanner The scanner object.
  */
 void ppset_extra (YY_EXTRA_TYPE  user_defined , yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
     yyextra = user_defined ;
 }
 
+
+
 /** Set the current line number.
- * @param line_number
+ * @param _line_number line number
  * @param yyscanner The scanner object.
  */
-void ppset_lineno (int  line_number , yyscan_t yyscanner)
+void ppset_lineno (int  _line_number , yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
+    
         /* lineno is only valid if an input buffer exists. */
         if (! YY_CURRENT_BUFFER )
            YY_FATAL_ERROR( "ppset_lineno called with no buffer" );
     
-    yylineno = line_number;
+    yylineno = _line_number;
 }
 
+
+
+
 /** Set the current column.
- * @param line_number
+ * @param _column_no column number
  * @param yyscanner The scanner object.
  */
-void ppset_column (int  column_no , yyscan_t yyscanner)
+void ppset_column (int  _column_no , yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
+    
         /* column is only valid if an input buffer exists. */
         if (! YY_CURRENT_BUFFER )
            YY_FATAL_ERROR( "ppset_column called with no buffer" );
     
-    yycolumn = column_no;
+    yycolumn = _column_no;
 }
 
+
+
+
+
 /** Set the input stream. This does not discard the current
  * input buffer.
- * @param in_str A readable stream.
+ * @param _in_str A readable stream.
  * @param yyscanner The scanner object.
  * @see pp_switch_to_buffer
  */
-void ppset_in (FILE *  in_str , yyscan_t yyscanner)
+void ppset_in (FILE *  _in_str , yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    yyin = in_str ;
+    yyin = _in_str ;
 }
 
-void ppset_out (FILE *  out_str , yyscan_t yyscanner)
+
+
+void ppset_out (FILE *  _out_str , yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    yyout = out_str ;
+    yyout = _out_str ;
 }
 
+
+
+
 int ppget_debug  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
     return yy_flex_debug;
 }
 
-void ppset_debug (int  bdebug , yyscan_t yyscanner)
+
+
+void ppset_debug (int  _bdebug , yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    yy_flex_debug = bdebug ;
+    yy_flex_debug = _bdebug ;
 }
 
+
 /* Accessor methods for yylval and yylloc */
 
+
 YYSTYPE * ppget_lval  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
     return yylval;
 }
 
+
+
 void ppset_lval (YYSTYPE *  yylval_param , yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
     yylval = yylval_param;
 }
 
+
+
+    
 YYLTYPE *ppget_lloc  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
     return yylloc;
 }
     
+
+    
 void ppset_lloc (YYLTYPE *  yylloc_param , yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
     yylloc = yylloc_param;
 }
     
+
+
+
+
 /* User-visible API */
 
 /* pplex_init is special because it creates the scanner itself, so it is
  * the ONLY reentrant function that doesn't take the scanner as the last argument.
  * That's why we explicitly handle the declaration, instead of using our macros.
  */
 
 int pplex_init(yyscan_t* ptr_yy_globals)
@@ -2179,16 +2595,17 @@ int pplex_init(yyscan_t* ptr_yy_globals)
     }
 
     /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
     memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
 
     return yy_init_globals ( *ptr_yy_globals );
 }
 
+
 /* pplex_init_extra has the same functionality as pplex_init, but follows the
  * convention of taking the scanner as the last argument. Note however, that
  * this is a *pointer* to a scanner, as it will be allocated by this call (and
  * is the reason, too, why this function also must handle its own declaration).
  * The user defined value in the first argument will be available to ppalloc in
  * the yyextra field.
  */
 
@@ -2215,132 +2632,174 @@ int pplex_init_extra(YY_EXTRA_TYPE yy_us
     yy_init_globals. Leave at 0x00 for releases. */
     memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
     
     ppset_extra (yy_user_defined, *ptr_yy_globals);
     
     return yy_init_globals ( *ptr_yy_globals );
 }
 
+
 static int yy_init_globals (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
     /* Initialization is the same as for the non-reentrant scanner.
      * This function is called from pplex_destroy(), so don't allocate here.
      */
 
-    yyg->yy_buffer_stack = 0;
+
+    yyg->yy_buffer_stack = NULL;
     yyg->yy_buffer_stack_top = 0;
     yyg->yy_buffer_stack_max = 0;
-    yyg->yy_c_buf_p = (char *) 0;
+    yyg->yy_c_buf_p = NULL;
     yyg->yy_init = 0;
     yyg->yy_start = 0;
 
+
     yyg->yy_start_stack_ptr = 0;
     yyg->yy_start_stack_depth = 0;
     yyg->yy_start_stack =  NULL;
 
+
+
+
+
+
 /* Defined in main.c */
 #ifdef YY_STDINIT
     yyin = stdin;
     yyout = stdout;
 #else
-    yyin = (FILE *) 0;
-    yyout = (FILE *) 0;
+    yyin = NULL;
+    yyout = NULL;
 #endif
 
     /* For future reference: Set errno on error, since we are called by
      * pplex_init()
      */
     return 0;
 }
 
+
 /* pplex_destroy is for both reentrant and non-reentrant scanners. */
 int pplex_destroy  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
     /* Pop the buffer stack, destroying each element. */
 	while(YY_CURRENT_BUFFER){
 		pp_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
 		YY_CURRENT_BUFFER_LVALUE = NULL;
 		pppop_buffer_state(yyscanner);
 	}
 
 	/* Destroy the stack itself. */
 	ppfree(yyg->yy_buffer_stack ,yyscanner);
 	yyg->yy_buffer_stack = NULL;
 
+
     /* Destroy the start condition stack. */
         ppfree(yyg->yy_start_stack ,yyscanner );
         yyg->yy_start_stack = NULL;
 
+
+
+
     /* Reset the globals. This is important in a non-reentrant scanner so the next time
      * pplex() is called, initialization will occur. */
     yy_init_globals( yyscanner);
 
     /* Destroy the main struct (reentrant only). */
     ppfree ( yyscanner , yyscanner );
     yyscanner = NULL;
     return 0;
 }
 
+
+
 /*
  * Internal utility routines.
  */
 
+
+
 #ifndef yytext_ptr
 static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
 {
-	register int i;
+	struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	(void)yyg;
+
+	int i;
 	for ( i = 0; i < n; ++i )
 		s1[i] = s2[i];
 }
 #endif
 
+
+
 #ifdef YY_NEED_STRLEN
 static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
 {
-	register int n;
+	int n;
 	for ( n = 0; s[n]; ++n )
 		;
 
 	return n;
 }
 #endif
 
+
+
 void *ppalloc (yy_size_t  size , yyscan_t yyscanner)
 {
-	return (void *) malloc( size );
+	struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	(void)yyg;
+	return malloc(size);
 }
 
+
+
 void *pprealloc  (void * ptr, yy_size_t  size , yyscan_t yyscanner)
 {
+	struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	(void)yyg;
+
 	/* The cast to (char *) in the following accommodates both
 	 * implementations that use char* generic pointers, and those
 	 * that use void* generic pointers.  It works with the latter
 	 * because both ANSI C and C++ allow castless assignment from
 	 * any pointer type to void*, and deal with argument conversions
 	 * as though doing an assignment.
 	 */
-	return (void *) realloc( (char *) ptr, size );
+	return realloc(ptr, size);
 }
 
+
+
 void ppfree (void * ptr , yyscan_t yyscanner)
 {
+	struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	(void)yyg;
 	free( (char *) ptr );	/* see pprealloc() for (char *) cast */
 }
 
+
 #define YYTABLES_NAME "yytables"
 
+
+
+
+
+
+
+
+
 namespace pp {
 
-Tokenizer::Tokenizer(Diagnostics *diagnostics)
-    : mHandle(0),
-      mMaxTokenSize(256)
+Tokenizer::Tokenizer(Diagnostics *diagnostics) : mHandle(nullptr), mMaxTokenSize(256)
 {
     mContext.diagnostics = diagnostics;
 }
 
 Tokenizer::~Tokenizer()
 {
     destroyScanner();
 }
@@ -2387,26 +2846,27 @@ void Tokenizer::lex(Token *token)
     mContext.lineStart = token->type == '\n';
 
     token->setHasLeadingSpace(mContext.leadingSpace);
     mContext.leadingSpace = false;
 }
 
 bool Tokenizer::initScanner()
 {
-    if ((mHandle == NULL) && pplex_init_extra(&mContext,&mHandle))
+    if ((mHandle == nullptr) && pplex_init_extra(&mContext, &mHandle))
         return false;
 
     pprestart(0,mHandle);
     return true;
 }
 
 void Tokenizer::destroyScanner()
 {
-    if (mHandle == NULL)
+    if (mHandle == nullptr)
         return;
 
     pplex_destroy(mHandle);
-    mHandle = NULL;
+    mHandle = nullptr;
 }
 
 }  // namespace pp
 
+
--- a/gfx/angle/src/compiler/preprocessor/Tokenizer.h
+++ b/gfx/angle/src/compiler/preprocessor/Tokenizer.h
@@ -2,19 +2,19 @@
 // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #ifndef COMPILER_PREPROCESSOR_TOKENIZER_H_
 #define COMPILER_PREPROCESSOR_TOKENIZER_H_
 
-#include "Input.h"
-#include "Lexer.h"
-#include "pp_utils.h"
+#include "common/angleutils.h"
+#include "compiler/preprocessor/Input.h"
+#include "compiler/preprocessor/Lexer.h"
 
 namespace pp
 {
 
 class Diagnostics;
 
 class Tokenizer : public Lexer
 {
@@ -40,17 +40,16 @@ class Tokenizer : public Lexer
 
     void setFileNumber(int file);
     void setLineNumber(int line);
     void setMaxTokenSize(size_t maxTokenSize);
 
     void lex(Token *token) override;
 
   private:
-    PP_DISALLOW_COPY_AND_ASSIGN(Tokenizer);
     bool initScanner();
     void destroyScanner();
 
     void *mHandle;  // Scanner handle.
     Context mContext;  // Scanner extra.
     size_t mMaxTokenSize; // Maximum token size
 };
 
--- a/gfx/angle/src/compiler/preprocessor/Tokenizer.l
+++ b/gfx/angle/src/compiler/preprocessor/Tokenizer.l
@@ -22,20 +22,20 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO
 // This file is auto-generated by generate_parser.sh. DO NOT EDIT!
 }
 
 %{
 #if defined(_MSC_VER)
 #pragma warning(disable: 4005)
 #endif
 
-#include "Tokenizer.h"
+#include "compiler/preprocessor/Tokenizer.h"
 
-#include "DiagnosticsBase.h"
-#include "Token.h"
+#include "compiler/preprocessor/DiagnosticsBase.h"
+#include "compiler/preprocessor/Token.h"
 
 #if defined(__GNUC__)
 // Triggered by the auto-generated yy_fatal_error function.
 #pragma GCC diagnostic ignored "-Wmissing-noreturn"
 #elif defined(_MSC_VER)
 #pragma warning(disable: 4244)
 #endif
 
@@ -275,19 +275,17 @@ FRACTIONAL_CONSTANT  ({DIGIT}*"."{DIGIT}
     }
     yyterminate();
 }
 
 %%
 
 namespace pp {
 
-Tokenizer::Tokenizer(Diagnostics *diagnostics)
-    : mHandle(0),
-      mMaxTokenSize(256)
+Tokenizer::Tokenizer(Diagnostics *diagnostics) : mHandle(nullptr), mMaxTokenSize(256)
 {
     mContext.diagnostics = diagnostics;
 }
 
 Tokenizer::~Tokenizer()
 {
     destroyScanner();
 }
@@ -334,26 +332,26 @@ void Tokenizer::lex(Token *token)
     mContext.lineStart = token->type == '\n';
 
     token->setHasLeadingSpace(mContext.leadingSpace);
     mContext.leadingSpace = false;
 }
 
 bool Tokenizer::initScanner()
 {
-    if ((mHandle == NULL) && yylex_init_extra(&mContext, &mHandle))
+    if ((mHandle == nullptr) && yylex_init_extra(&mContext, &mHandle))
         return false;
 
     yyrestart(0, mHandle);
     return true;
 }
 
 void Tokenizer::destroyScanner()
 {
-    if (mHandle == NULL)
+    if (mHandle == nullptr)
         return;
 
     yylex_destroy(mHandle);
-    mHandle = NULL;
+    mHandle = nullptr;
 }
 
 }  // namespace pp
 
--- a/gfx/angle/src/compiler/preprocessor/numeric_lex.h
+++ b/gfx/angle/src/compiler/preprocessor/numeric_lex.h
@@ -4,16 +4,17 @@
 // found in the LICENSE file.
 //
 
 // numeric_lex.h: Functions to extract numeric values from string.
 
 #ifndef COMPILER_PREPROCESSOR_NUMERICLEX_H_
 #define COMPILER_PREPROCESSOR_NUMERICLEX_H_
 
+#include <cmath>
 #include <sstream>
 
 namespace pp {
 
 inline std::ios::fmtflags numeric_base_int(const std::string &str)
 {
     if ((str.size() >= 2) &&
         (str[0] == '0') &&
@@ -58,15 +59,15 @@ bool numeric_lex_float(const std::string
     return errno != ERANGE;
 #else
     std::istringstream stream(str);
     // Force "C" locale so that decimal character is always '.', and
     // not dependent on the current locale.
     stream.imbue(std::locale::classic());
 
     stream >> (*value);
-    return !stream.fail();
+    return !stream.fail() && std::isfinite(*value);
 #endif
 }
 
 } // namespace pp.
 
 #endif // COMPILER_PREPROCESSOR_NUMERICLEX_H_
deleted file mode 100755
--- a/gfx/angle/src/compiler/preprocessor/pp_utils.h
+++ /dev/null
@@ -1,18 +0,0 @@
-//
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// pp_utils.h: Common preprocessor utilities
-
-#ifndef COMPILER_PREPROCESSOR_PPUTILS_H_
-#define COMPILER_PREPROCESSOR_PPUTILS_H_
-
-// A macro to disallow the copy constructor and operator= functions
-// This must be used in the private: declarations for a class.
-#define PP_DISALLOW_COPY_AND_ASSIGN(TypeName) \
-  TypeName(const TypeName &);               \
-  void operator=(const TypeName &)
-
-#endif // COMPILER_PREPROCESSOR_PPUTILS_H_
--- a/gfx/angle/src/compiler/translator/64bit-lexer-safety.patch
+++ b/gfx/angle/src/compiler/translator/64bit-lexer-safety.patch
@@ -1,40 +1,122 @@
---- a/src/compiler/glslang_lex.cpp
-+++ b/src/compiler/glslang_lex.cpp
-@@ -68,6 +68,7 @@ typedef int16_t flex_int16_t;
+diff --git a/src/compiler/translator/glslang_lex.cpp b/src/compiler/translator/glslang_lex.cpp
+index 1ba63df..2a206ab 100644
+--- a/src/compiler/translator/glslang_lex.cpp
++++ b/src/compiler/translator/glslang_lex.cpp
+@@ -1,4 +1,3 @@
+-#line 17 "./glslang.l"
+ //
+ // Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style license that can be
+@@ -149,6 +148,7 @@ typedef int16_t flex_int16_t;
  typedef uint16_t flex_uint16_t;
  typedef int32_t flex_int32_t;
  typedef uint32_t flex_uint32_t;
 +typedef uint64_t flex_uint64_t;
  #else
  typedef signed char flex_int8_t;
  typedef short int flex_int16_t;
-@@ -191,6 +192,11 @@ typedef void* yyscan_t;
- typedef struct yy_buffer_state *YY_BUFFER_STATE;
- #endif
-
+@@ -335,6 +335,11 @@ typedef size_t yy_size_t;
+ 
+ 
+ 
 +#ifndef YY_TYPEDEF_YY_SIZE_T
 +#define YY_TYPEDEF_YY_SIZE_T
 +typedef size_t yy_size_t;
 +#endif
 +
  #define EOB_ACT_CONTINUE_SCAN 0
  #define EOB_ACT_END_OF_FILE 1
  #define EOB_ACT_LAST_MATCH 2
-@@ -204,7 +210,7 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE;
+@@ -351,8 +356,8 @@ typedef size_t yy_size_t;
       */
      #define  YY_LESS_LINENO(n) \
              do { \
 -                int yyl;\
+-                for ( yyl = n; yyl < yyleng; ++yyl )\
 +                yy_size_t yyl;\
-                 for ( yyl = n; yyl < yyleng; ++yyl )\
++                for ( yyl = n; yyl < static_cast<yy_site_t>(yyleng); ++yyl )\
                      if ( yytext[yyl] == '\n' )\
                          --yylineno;\
-@@ -378,7 +379,7 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
-  */
- #define YY_DO_BEFORE_ACTION \
- 	yyg->yytext_ptr = yy_bp; \
--	yyleng = (size_t) (yy_cp - yy_bp); \
-+	yyleng = (yy_size_t) (yy_cp - yy_bp); \
- 	yyg->yy_hold_char = *yy_cp; \
- 	*yy_cp = '\0'; \
- 	yyg->yy_c_buf_p = yy_cp;
+             }while(0)
+@@ -1692,7 +1697,7 @@ yy_find_action:
+ 		if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
+ 			{
+ 			yy_size_t yyl;
+-			for ( yyl = 0; yyl < yyleng; ++yyl )
++			for ( yyl = 0; yyl < static_cast<yy_size_t>(yyleng); ++yyl )
+ 				if ( yytext[yyl] == '\n' )
+ 					   
+     do{ yylineno++;
+@@ -2655,7 +2660,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
+ 	else
+ 		{
+ 			int num_to_read =
+-			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
++			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - static_cast<int>(number_to_move) - 1;
+ 
+ 		while ( num_to_read <= 0 )
+ 			{ /* Not enough room in the buffer - grow it. */
+@@ -2690,7 +2695,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
+ 			yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+ 
+ 			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+-						number_to_move - 1;
++						static_cast<int>(number_to_move) - 1;
+ 
+ 			}
+ 
+@@ -2698,8 +2703,10 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
+ 			num_to_read = YY_READ_BUF_SIZE;
+ 
+ 		/* Read in more data. */
++        size_t result = 0;
+ 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+-			yyg->yy_n_chars, num_to_read );
++            result, num_to_read );
++        yyg->yy_n_chars = static_cast<int>(result);
+ 
+ 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ 		}
+@@ -2725,13 +2732,13 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
+ 
+ 	if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ 		/* Extend the array by 50%, plus the number we really need. */
+-		int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
++		int new_size = yyg->yy_n_chars + static_cast<int>(number_to_move) + (yyg->yy_n_chars >> 1);
+ 		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+ 		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ 			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ 	}
+ 
+-	yyg->yy_n_chars += number_to_move;
++	yyg->yy_n_chars += static_cast<int>(number_to_move);
+ 	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ 	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+ 
+@@ -3158,7 +3165,7 @@ static void yyensure_buffer_stack (yyscan_t yyscanner)
+ 		/* Increase the buffer to prepare for a possible push. */
+ 		yy_size_t grow_size = 8 /* arbitrary grow size */;
+ 
+-		num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
++		num_to_alloc = static_cast<int>(yyg->yy_buffer_stack_max + grow_size);
+ 		yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc
+ 								(yyg->yy_buffer_stack,
+ 								num_to_alloc * sizeof(struct yy_buffer_state*)
+@@ -3196,7 +3203,7 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscann
+ 	if ( ! b )
+ 		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+ 
+-	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
++	b->yy_buf_size = static_cast<int>(size) - 2;	/* "- 2" to take care of EOB's */
+ 	b->yy_buf_pos = b->yy_ch_buf = base;
+ 	b->yy_is_our_buffer = 0;
+ 	b->yy_input_file = NULL;
+@@ -3251,7 +3258,7 @@ YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len , yysc
+ 	if ( ! buf )
+ 		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+ 
+-	for ( i = 0; i < _yybytes_len; ++i )
++	for ( i = 0; i < static_cast<yy_size_t>(_yybytes_len); ++i )
+ 		buf[i] = yybytes[i];
+ 
+ 	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
--- a/gfx/angle/src/compiler/translator/ASTMetadataHLSL.cpp
+++ b/gfx/angle/src/compiler/translator/ASTMetadataHLSL.cpp
@@ -6,16 +6,19 @@
 
 // Analysis of the AST needed for HLSL generation
 
 #include "compiler/translator/ASTMetadataHLSL.h"
 
 #include "compiler/translator/CallDAG.h"
 #include "compiler/translator/SymbolTable.h"
 
+namespace sh
+{
+
 namespace
 {
 
 // Class used to traverse the AST of a function definition, checking if the
 // function uses a gradient, and writing the set of control flow using gradients.
 // It assumes that the analysis has already been made for the function's
 // callees.
 class PullGradient : public TIntermTraverser
@@ -26,17 +29,17 @@ class PullGradient : public TIntermTrave
           mMetadataList(metadataList),
           mMetadata(&(*metadataList)[index]),
           mIndex(index),
           mDag(dag)
     {
         ASSERT(index < metadataList->size());
     }
 
-    void traverse(TIntermAggregate *node)
+    void traverse(TIntermFunctionDefinition *node)
     {
         node->traverse(this);
         ASSERT(mParents.empty());
     }
 
     // Called when a gradient operation or a call to a function using a gradient is found.
     void onGradient()
     {
@@ -67,19 +70,19 @@ class PullGradient : public TIntermTrave
     }
 
     bool visitLoop(Visit visit, TIntermLoop *loop) override
     {
         visitControlFlow(visit, loop);
         return true;
     }
 
-    bool visitSelection(Visit visit, TIntermSelection *selection) override
+    bool visitIfElse(Visit visit, TIntermIfElse *ifElse) override
     {
-        visitControlFlow(visit, selection);
+        visitControlFlow(visit, ifElse);
         return true;
     }
 
     bool visitUnary(Visit visit, TIntermUnary *node) override
     {
         if (visit == PreVisit)
         {
             switch (node->getOp())
@@ -98,27 +101,27 @@ class PullGradient : public TIntermTrave
     bool visitAggregate(Visit visit, TIntermAggregate *node) override
     {
         if (visit == PreVisit)
         {
             if (node->getOp() == EOpFunctionCall)
             {
                 if (node->isUserDefined())
                 {
-                    size_t calleeIndex = mDag.findIndex(node);
+                    size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo());
                     ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
-                    UNUSED_ASSERTION_VARIABLE(mIndex);
 
                     if ((*mMetadataList)[calleeIndex].mUsesGradient) {
                         onGradient();
                     }
                 }
                 else
                 {
-                    TString name = TFunction::unmangleName(node->getName());
+                    TString name =
+                        TFunction::unmangleName(node->getFunctionSymbolInfo()->getName());
 
                     if (name == "texture2D" ||
                         name == "texture2DProj" ||
                         name == "textureCube")
                     {
                         onGradient();
                     }
                 }
@@ -152,17 +155,17 @@ class PullComputeDiscontinuousAndGradien
         : TIntermTraverser(true, false, true),
           mMetadataList(metadataList),
           mMetadata(&(*metadataList)[index]),
           mIndex(index),
           mDag(dag)
     {
     }
 
-    void traverse(TIntermAggregate *node)
+    void traverse(TIntermFunctionDefinition *node)
     {
         node->traverse(this);
         ASSERT(mLoopsAndSwitches.empty());
         ASSERT(mIfs.empty());
     }
 
     // Called when traversing a gradient loop or a call to a function with a
     // gradient loop in its call graph.
@@ -191,17 +194,17 @@ class PullComputeDiscontinuousAndGradien
         {
             ASSERT(mLoopsAndSwitches.back() == loop);
             mLoopsAndSwitches.pop_back();
         }
 
         return true;
     }
 
-    bool visitSelection(Visit visit, TIntermSelection *node) override
+    bool visitIfElse(Visit visit, TIntermIfElse *node) override
     {
         if (visit == PreVisit)
         {
             mIfs.push_back(node);
         }
         else if (visit == PostVisit)
         {
             ASSERT(mIfs.back() == node);
@@ -270,19 +273,18 @@ class PullComputeDiscontinuousAndGradien
     }
 
     bool visitAggregate(Visit visit, TIntermAggregate *node) override
     {
         if (visit == PreVisit && node->getOp() == EOpFunctionCall)
         {
             if (node->isUserDefined())
             {
-                size_t calleeIndex = mDag.findIndex(node);
+                size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo());
                 ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
-                UNUSED_ASSERTION_VARIABLE(mIndex);
 
                 if ((*mMetadataList)[calleeIndex].mHasGradientLoopInCallGraph)
                 {
                     onGradientLoop();
                 }
             }
         }
 
@@ -305,34 +307,34 @@ class PullComputeDiscontinuousAndGradien
 
   private:
     MetadataList *mMetadataList;
     ASTMetadataHLSL *mMetadata;
     size_t mIndex;
     const CallDAG &mDag;
 
     std::vector<TIntermNode*> mLoopsAndSwitches;
-    std::vector<TIntermSelection*> mIfs;
+    std::vector<TIntermIfElse *> mIfs;
 };
 
 // Tags all the functions called in a discontinuous loop
 class PushDiscontinuousLoops : public TIntermTraverser
 {
   public:
     PushDiscontinuousLoops(MetadataList *metadataList, size_t index, const CallDAG &dag)
         : TIntermTraverser(true, true, true),
           mMetadataList(metadataList),
           mMetadata(&(*metadataList)[index]),
           mIndex(index),
           mDag(dag),
           mNestedDiscont(mMetadata->mCalledInDiscontinuousLoop ? 1 : 0)
     {
     }
 
-    void traverse(TIntermAggregate *node)
+    void traverse(TIntermFunctionDefinition *node)
     {
         node->traverse(this);
         ASSERT(mNestedDiscont == (mMetadata->mCalledInDiscontinuousLoop ? 1 : 0));
     }
 
     bool visitLoop(Visit visit, TIntermLoop *loop) override
     {
         bool isDiscontinuous = mMetadata->mDiscontinuousLoops.count(loop) > 0;
@@ -351,19 +353,18 @@ class PushDiscontinuousLoops : public TI
 
     bool visitAggregate(Visit visit, TIntermAggregate *node) override
     {
         switch (node->getOp())
         {
           case EOpFunctionCall:
             if (visit == PreVisit && node->isUserDefined() && mNestedDiscont > 0)
             {
-                size_t calleeIndex = mDag.findIndex(node);
+                size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo());
                 ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
-                UNUSED_ASSERTION_VARIABLE(mIndex);
 
                 (*mMetadataList)[calleeIndex].mCalledInDiscontinuousLoop = true;
             }
             break;
           default:
             break;
         }
         return true;
@@ -380,17 +381,17 @@ class PushDiscontinuousLoops : public TI
 
 }
 
 bool ASTMetadataHLSL::hasGradientInCallGraph(TIntermLoop *node)
 {
     return mControlFlowsContainingGradient.count(node) > 0;
 }
 
-bool ASTMetadataHLSL::hasGradientLoop(TIntermSelection *node)
+bool ASTMetadataHLSL::hasGradientLoop(TIntermIfElse *node)
 {
     return mIfsContainingGradientLoop.count(node) > 0;
 }
 
 MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag)
 {
     MetadataList metadataList(callDag.size());
 
@@ -444,8 +445,10 @@ MetadataList CreateASTMetadataHLSL(TInte
     // loops.
     for (auto &metadata : metadataList)
     {
         metadata.mNeedsLod0 = metadata.mCalledInDiscontinuousLoop && metadata.mUsesGradient;
     }
 
     return metadataList;
 }
+
+}  // namespace sh
--- a/gfx/angle/src/compiler/translator/ASTMetadataHLSL.h
+++ b/gfx/angle/src/compiler/translator/ASTMetadataHLSL.h
@@ -7,52 +7,57 @@
 // Defines analyses of the AST needed for HLSL generation
 
 #ifndef COMPILER_TRANSLATOR_ASTMETADATAHLSL_H_
 #define COMPILER_TRANSLATOR_ASTMETADATAHLSL_H_
 
 #include <set>
 #include <vector>
 
+namespace sh
+{
+
 class CallDAG;
 class TIntermNode;
-class TIntermSelection;
+class TIntermIfElse;
 class TIntermLoop;
 
 struct ASTMetadataHLSL
 {
     ASTMetadataHLSL()
         : mUsesGradient(false),
           mCalledInDiscontinuousLoop(false),
           mHasGradientLoopInCallGraph(false),
           mNeedsLod0(false)
     {
     }
 
     // Here "something uses a gradient" means here that it either contains a
     // gradient operation, or a call to a function that uses a gradient.
     bool hasGradientInCallGraph(TIntermLoop *node);
-    bool hasGradientLoop(TIntermSelection *node);
+    bool hasGradientLoop(TIntermIfElse *node);
 
     // Does the function use a gradient.
     bool mUsesGradient;
 
     // Even if usesGradient is true, some control flow might not use a gradient
     // so we store the set of all gradient-using control flows.
     std::set<TIntermNode*> mControlFlowsContainingGradient;
 
     // Remember information about the discontinuous loops and which functions
     // are called in such loops.
     bool mCalledInDiscontinuousLoop;
     bool mHasGradientLoopInCallGraph;
     std::set<TIntermLoop*> mDiscontinuousLoops;
-    std::set<TIntermSelection *> mIfsContainingGradientLoop;
+    std::set<TIntermIfElse *> mIfsContainingGradientLoop;
 
     // Will we need to generate a Lod0 version of the function.
     bool mNeedsLod0;
 };
 
 typedef std::vector<ASTMetadataHLSL> MetadataList;
 
 // Return the AST analysis result, in the order defined by the call DAG
 MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag);
 
+}  // namespace sh
+
 #endif // COMPILER_TRANSLATOR_ASTMETADATAHLSL_H_
--- a/gfx/angle/src/compiler/translator/AddDefaultReturnStatements.cpp
+++ b/gfx/angle/src/compiler/translator/AddDefaultReturnStatements.cpp
@@ -26,49 +26,44 @@ class AddDefaultReturnStatementsTraverse
         AddDefaultReturnStatementsTraverser separateInit;
         root->traverse(&separateInit);
         separateInit.updateTree();
     }
 
   private:
     AddDefaultReturnStatementsTraverser() : TIntermTraverser(true, false, false) {}
 
-    static bool IsFunctionWithoutReturnStatement(TIntermAggregate *node, TType *returnType)
+    static bool IsFunctionWithoutReturnStatement(TIntermFunctionDefinition *node, TType *returnType)
     {
         *returnType = node->getType();
-        if (node->getOp() != EOpFunction || node->getType().getBasicType() == EbtVoid)
+        if (node->getType().getBasicType() == EbtVoid)
         {
             return false;
         }
 
-        TIntermAggregate *lastNode = node->getSequence()->back()->getAsAggregate();
-        if (lastNode == nullptr)
-        {
-            return true;
-        }
-
-        TIntermBranch *returnNode = lastNode->getSequence()->front()->getAsBranchNode();
+        TIntermBlock *bodyNode    = node->getBody();
+        TIntermBranch *returnNode = bodyNode->getSequence()->back()->getAsBranchNode();
         if (returnNode != nullptr && returnNode->getFlowOp() == EOpReturn)
         {
             return false;
         }
 
         return true;
     }
 
-    bool visitAggregate(Visit, TIntermAggregate *node) override
+    bool visitFunctionDefinition(Visit, TIntermFunctionDefinition *node) override
     {
         TType returnType;
         if (IsFunctionWithoutReturnStatement(node, &returnType))
         {
             TIntermBranch *branch =
                 new TIntermBranch(EOpReturn, TIntermTyped::CreateZero(returnType));
 
-            TIntermAggregate *lastNode = node->getSequence()->back()->getAsAggregate();
-            lastNode->getSequence()->push_back(branch);
+            TIntermBlock *bodyNode = node->getBody();
+            bodyNode->getSequence()->push_back(branch);
 
             return false;
         }
 
         return true;
     }
 };
 }  // anonymous namespace
--- a/gfx/angle/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
+++ b/gfx/angle/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
@@ -5,16 +5,19 @@
 //
 // The ArrayReturnValueToOutParameter function changes return values of an array type to out parameters in
 // function definitions, prototypes, and call sites.
 
 #include "compiler/translator/ArrayReturnValueToOutParameter.h"
 
 #include "compiler/translator/IntermNode.h"
 
+namespace sh
+{
+
 namespace
 {
 
 void CopyAggregateChildren(TIntermAggregate *from, TIntermAggregate *to)
 {
     const TIntermSequence *fromSequence = from->getSequence();
     for (size_t ii = 0; ii < fromSequence->size(); ++ii)
     {
@@ -36,18 +39,17 @@ TIntermSymbol *CreateReturnValueOutSymbo
     return CreateReturnValueSymbol(outType);
 }
 
 TIntermAggregate *CreateReplacementCall(TIntermAggregate *originalCall, TIntermTyped *returnValueTarget)
 {
     TIntermAggregate *replacementCall = new TIntermAggregate(EOpFunctionCall);
     replacementCall->setType(TType(EbtVoid));
     replacementCall->setUserDefined();
-    replacementCall->setNameObj(originalCall->getNameObj());
-    replacementCall->setFunctionId(originalCall->getFunctionId());
+    *replacementCall->getFunctionSymbolInfo() = *originalCall->getFunctionSymbolInfo();
     replacementCall->setLine(originalCall->getLine());
     TIntermSequence *replacementParameters = replacementCall->getSequence();
     TIntermSequence *originalParameters = originalCall->getSequence();
     for (auto &param : *originalParameters)
     {
         replacementParameters->push_back(param);
     }
     replacementParameters->push_back(returnValueTarget);
@@ -56,16 +58,17 @@ TIntermAggregate *CreateReplacementCall(
 
 class ArrayReturnValueToOutParameterTraverser : private TIntermTraverser
 {
   public:
     static void apply(TIntermNode *root, unsigned int *temporaryIndex);
   private:
     ArrayReturnValueToOutParameterTraverser();
 
+    bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
     bool visitAggregate(Visit visit, TIntermAggregate *node) override;
     bool visitBranch(Visit visit, TIntermBranch *node) override;
     bool visitBinary(Visit visit, TIntermBinary *node) override;
 
     bool mInFunctionWithArrayReturnValue;
 };
 
 void ArrayReturnValueToOutParameterTraverser::apply(TIntermNode *root, unsigned int *temporaryIndex)
@@ -77,91 +80,96 @@ void ArrayReturnValueToOutParameterTrave
 }
 
 ArrayReturnValueToOutParameterTraverser::ArrayReturnValueToOutParameterTraverser()
     : TIntermTraverser(true, false, true),
       mInFunctionWithArrayReturnValue(false)
 {
 }
 
+bool ArrayReturnValueToOutParameterTraverser::visitFunctionDefinition(
+    Visit visit,
+    TIntermFunctionDefinition *node)
+{
+    if (node->isArray() && visit == PreVisit)
+    {
+        // Replace the parameters child node of the function definition with another node
+        // that has the out parameter added.
+        // Also set the function to return void.
+
+        TIntermAggregate *params = node->getFunctionParameters();
+        ASSERT(params != nullptr && params->getOp() == EOpParameters);
+
+        TIntermAggregate *replacementParams = new TIntermAggregate;
+        replacementParams->setOp(EOpParameters);
+        CopyAggregateChildren(params, replacementParams);
+        replacementParams->getSequence()->push_back(CreateReturnValueOutSymbol(node->getType()));
+        replacementParams->setLine(params->getLine());
+
+        queueReplacementWithParent(node, params, replacementParams, OriginalNode::IS_DROPPED);
+
+        node->setType(TType(EbtVoid));
+
+        mInFunctionWithArrayReturnValue = true;
+    }
+    if (visit == PostVisit)
+    {
+        // This isn't conditional on node->isArray() since the type has already been changed on
+        // PreVisit.
+        mInFunctionWithArrayReturnValue = false;
+    }
+    return true;
+}
+
 bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
 {
     if (visit == PreVisit)
     {
         if (node->isArray())
         {
-            if (node->getOp() == EOpFunction)
-            {
-                // Replace the parameters child node of the function definition with another node
-                // that has the out parameter added.
-                // Also set the function to return void.
-
-                TIntermAggregate *params = node->getSequence()->front()->getAsAggregate();
-                ASSERT(params != nullptr && params->getOp() == EOpParameters);
-
-                TIntermAggregate *replacementParams = new TIntermAggregate;
-                replacementParams->setOp(EOpParameters);
-                CopyAggregateChildren(params, replacementParams);
-                replacementParams->getSequence()->push_back(CreateReturnValueOutSymbol(node->getType()));
-                replacementParams->setLine(params->getLine());
-
-                queueReplacementWithParent(node, params, replacementParams,
-                                           OriginalNode::IS_DROPPED);
-
-                node->setType(TType(EbtVoid));
-
-                mInFunctionWithArrayReturnValue = true;
-            }
-            else if (node->getOp() == EOpPrototype)
+            if (node->getOp() == EOpPrototype)
             {
                 // Replace the whole prototype node with another node that has the out parameter added.
                 TIntermAggregate *replacement = new TIntermAggregate;
                 replacement->setOp(EOpPrototype);
                 CopyAggregateChildren(node, replacement);
                 replacement->getSequence()->push_back(CreateReturnValueOutSymbol(node->getType()));
                 replacement->setUserDefined();
-                replacement->setNameObj(node->getNameObj());
-                replacement->setFunctionId(node->getFunctionId());
+                *replacement->getFunctionSymbolInfo() = *node->getFunctionSymbolInfo();
                 replacement->setLine(node->getLine());
                 replacement->setType(TType(EbtVoid));
 
                 queueReplacement(node, replacement, OriginalNode::IS_DROPPED);
             }
             else if (node->getOp() == EOpFunctionCall)
             {
                 // Handle call sites where the returned array is not assigned.
                 // Examples where f() is a function returning an array:
                 // 1. f();
                 // 2. another_array == f();
                 // 3. another_function(f());
                 // 4. return f();
                 // Cases 2 to 4 are already converted to simpler cases by SeparateExpressionsReturningArrays, so we
                 // only need to worry about the case where a function call returning an array forms an expression by
                 // itself.
-                TIntermAggregate *parentAgg = getParentNode()->getAsAggregate();
-                if (parentAgg != nullptr && parentAgg->getOp() == EOpSequence)
+                TIntermBlock *parentBlock = getParentNode()->getAsBlock();
+                if (parentBlock)
                 {
                     nextTemporaryIndex();
                     TIntermSequence replacements;
                     replacements.push_back(createTempDeclaration(node->getType()));
                     TIntermSymbol *returnSymbol = createTempSymbol(node->getType());
                     replacements.push_back(CreateReplacementCall(node, returnSymbol));
-                    mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parentAgg, node, replacements));
+                    mMultiReplacements.push_back(
+                        NodeReplaceWithMultipleEntry(parentBlock, node, replacements));
                 }
                 return false;
             }
         }
     }
-    else if (visit == PostVisit)
-    {
-        if (node->getOp() == EOpFunction)
-        {
-            mInFunctionWithArrayReturnValue = false;
-        }
-    }
     return true;
 }
 
 bool ArrayReturnValueToOutParameterTraverser::visitBranch(Visit visit, TIntermBranch *node)
 {
     if (mInFunctionWithArrayReturnValue && node->getFlowOp() == EOpReturn)
     {
         // Instead of returning a value, assign to the out parameter and then return.
@@ -174,17 +182,18 @@ bool ArrayReturnValueToOutParameterTrave
             new TIntermBinary(EOpAssign, returnValueSymbol, expression);
         replacementAssignment->setLine(expression->getLine());
         replacements.push_back(replacementAssignment);
 
         TIntermBranch *replacementBranch = new TIntermBranch(EOpReturn, nullptr);
         replacementBranch->setLine(node->getLine());
         replacements.push_back(replacementBranch);
 
-        mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(getParentNode()->getAsAggregate(), node, replacements));
+        mMultiReplacements.push_back(
+            NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(), node, replacements));
     }
     return false;
 }
 
 bool ArrayReturnValueToOutParameterTraverser::visitBinary(Visit visit, TIntermBinary *node)
 {
     if (node->getOp() == EOpAssign && node->getLeft()->isArray())
     {
@@ -199,8 +208,10 @@ bool ArrayReturnValueToOutParameterTrave
 }
 
 } // namespace
 
 void ArrayReturnValueToOutParameter(TIntermNode *root, unsigned int *temporaryIndex)
 {
     ArrayReturnValueToOutParameterTraverser::apply(root, temporaryIndex);
 }
+
+}  // namespace sh
--- a/gfx/angle/src/compiler/translator/ArrayReturnValueToOutParameter.h
+++ b/gfx/angle/src/compiler/translator/ArrayReturnValueToOutParameter.h
@@ -4,13 +4,16 @@
 // found in the LICENSE file.
 //
 // The ArrayReturnValueToOutParameter function changes return values of an array type to out parameters in
 // function definitions, prototypes and call sites.
 
 #ifndef COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
 #define COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
 
+namespace sh
+{
 class TIntermNode;
 
 void ArrayReturnValueToOutParameter(TIntermNode *root, unsigned int *temporaryIndex);
+}  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
--- a/gfx/angle/src/compiler/translator/BaseTypes.h
+++ b/gfx/angle/src/compiler/translator/BaseTypes.h
@@ -8,16 +8,19 @@
 #define COMPILER_TRANSLATOR_BASETYPES_H_
 
 #include <algorithm>
 #include <array>
 
 #include "common/debug.h"
 #include "GLSLANG/ShaderLang.h"
 
+namespace sh
+{
+
 //
 // Precision qualifiers
 //
 enum TPrecision
 {
     // These need to be kept sorted
     EbpUndefined,
     EbpLow,
@@ -27,20 +30,20 @@ enum TPrecision
     // end of list
     EbpLast
 };
 
 inline const char* getPrecisionString(TPrecision p)
 {
     switch(p)
     {
-    case EbpHigh:		return "highp";		break;
-    case EbpMedium:		return "mediump";	break;
-    case EbpLow:		return "lowp";		break;
-    default:			return "mediump";   break;   // Safest fallback
+        case EbpHigh:   return "highp";
+        case EbpMedium: return "mediump";
+        case EbpLow:    return "lowp";
+        default:        return "mediump";  // Safest fallback
     }
 }
 
 //
 // Basic type.  Arrays, vectors, etc., are orthogonal to this.
 //
 enum TBasicType
 {
@@ -71,36 +74,131 @@ enum TBasicType
     EbtISampler2DArray,
     EbtUSampler2D,
     EbtUSampler3D,
     EbtUSamplerCube,
     EbtUSampler2DArray,
     EbtSampler2DShadow,
     EbtSamplerCubeShadow,
     EbtSampler2DArrayShadow,
-    EbtGuardSamplerEnd,    // non type: see implementation of IsSampler()
-    EbtGSampler2D,         // non type: represents sampler2D, isampler2D, and usampler2D
-    EbtGSampler3D,         // non type: represents sampler3D, isampler3D, and usampler3D
-    EbtGSamplerCube,       // non type: represents samplerCube, isamplerCube, and usamplerCube
-    EbtGSampler2DArray,    // non type: represents sampler2DArray, isampler2DArray, and usampler2DArray
+    EbtGuardSamplerEnd,  // non type: see implementation of IsSampler()
+    EbtGSampler2D,       // non type: represents sampler2D, isampler2D, and usampler2D
+    EbtGSampler3D,       // non type: represents sampler3D, isampler3D, and usampler3D
+    EbtGSamplerCube,     // non type: represents samplerCube, isamplerCube, and usamplerCube
+    EbtGSampler2DArray,  // non type: represents sampler2DArray, isampler2DArray, and
+                         // usampler2DArray
+
+    // images
+    EbtGuardImageBegin,
+    EbtImage2D,
+    EbtIImage2D,
+    EbtUImage2D,
+    EbtImage3D,
+    EbtIImage3D,
+    EbtUImage3D,
+    EbtImage2DArray,
+    EbtIImage2DArray,
+    EbtUImage2DArray,
+    EbtImageCube,
+    EbtIImageCube,
+    EbtUImageCube,
+    EbtGuardImageEnd,
+
+    EbtGuardGImageBegin,
+    EbtGImage2D,       // non type: represents image2D, uimage2D, iimage2D
+    EbtGImage3D,       // non type: represents image3D, uimage3D, iimage3D
+    EbtGImage2DArray,  // non type: represents image2DArray, uimage2DArray, iimage2DArray
+    EbtGImageCube,     // non type: represents imageCube, uimageCube, iimageCube
+    EbtGuardGImageEnd,
+
     EbtStruct,
     EbtInterfaceBlock,
-    EbtAddress,            // should be deprecated??
+    EbtAddress,  // should be deprecated??
 
     // end of list
     EbtLast
 };
 
+inline TBasicType convertGImageToFloatImage(TBasicType type)
+{
+    switch (type)
+    {
+        case EbtGImage2D:
+            return EbtImage2D;
+        case EbtGImage3D:
+            return EbtImage3D;
+        case EbtGImage2DArray:
+            return EbtImage2DArray;
+        case EbtGImageCube:
+            return EbtImageCube;
+        default:
+            UNREACHABLE();
+    }
+    return EbtLast;
+}
+
+inline TBasicType convertGImageToIntImage(TBasicType type)
+{
+    switch (type)
+    {
+        case EbtGImage2D:
+            return EbtIImage2D;
+        case EbtGImage3D:
+            return EbtIImage3D;
+        case EbtGImage2DArray:
+            return EbtIImage2DArray;
+        case EbtGImageCube:
+            return EbtIImageCube;
+        default:
+            UNREACHABLE();
+    }
+    return EbtLast;
+}
+
+inline TBasicType convertGImageToUnsignedImage(TBasicType type)
+{
+    switch (type)
+    {
+        case EbtGImage2D:
+            return EbtUImage2D;
+        case EbtGImage3D:
+            return EbtUImage3D;
+        case EbtGImage2DArray:
+            return EbtUImage2DArray;
+        case EbtGImageCube:
+            return EbtUImageCube;
+        default:
+            UNREACHABLE();
+    }
+    return EbtLast;
+}
+
 const char* getBasicString(TBasicType t);
 
 inline bool IsSampler(TBasicType type)
 {
     return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
 }
 
+inline bool IsImage(TBasicType type)
+{
+    return type > EbtGuardImageBegin && type < EbtGuardImageEnd;
+}
+
+inline bool IsGImage(TBasicType type)
+{
+    return type > EbtGuardGImageBegin && type < EbtGuardGImageEnd;
+}
+
+inline bool IsOpaqueType(TBasicType type)
+{
+    // TODO (mradev): add atomic types as opaque.
+    return IsSampler(type) || IsImage(type);
+}
+
 inline bool IsIntegerSampler(TBasicType type)
 {
     switch (type)
     {
       case EbtISampler2D:
       case EbtISampler3D:
       case EbtISamplerCube:
       case EbtISampler2DArray:
@@ -121,16 +219,66 @@ inline bool IsIntegerSampler(TBasicType 
         return false;
       default:
         assert(!IsSampler(type));
     }
 
     return false;
 }
 
+inline bool IsFloatImage(TBasicType type)
+{
+    switch (type)
+    {
+        case EbtImage2D:
+        case EbtImage3D:
+        case EbtImage2DArray:
+        case EbtImageCube:
+            return true;
+        default:
+            break;
+    }
+
+    return false;
+}
+
+inline bool IsIntegerImage(TBasicType type)
+{
+
+    switch (type)
+    {
+        case EbtIImage2D:
+        case EbtIImage3D:
+        case EbtIImage2DArray:
+        case EbtIImageCube:
+            return true;
+        default:
+            break;
+    }
+
+    return false;
+}
+
+inline bool IsUnsignedImage(TBasicType type)
+{
+
+    switch (type)
+    {
+        case EbtUImage2D:
+        case EbtUImage3D:
+        case EbtUImage2DArray:
+        case EbtUImageCube:
+            return true;
+        default:
+            break;
+    }
+
+    return false;
+}
+
 inline bool IsSampler2D(TBasicType type)
 {
     switch (type)
     {
       case EbtSampler2D:
       case EbtISampler2D:
       case EbtUSampler2D:
       case EbtSampler2DArray:
@@ -278,17 +426,17 @@ inline bool IsShadowSampler(TBasicType t
 
 inline bool IsInteger(TBasicType type)
 {
     return type == EbtInt || type == EbtUInt;
 }
 
 inline bool SupportsPrecision(TBasicType type)
 {
-    return type == EbtFloat || type == EbtInt || type == EbtUInt || IsSampler(type);
+    return type == EbtFloat || type == EbtInt || type == EbtUInt || IsOpaqueType(type);
 }
 
 //
 // Qualifiers and built-ins.  These are mainly used to see what can be read
 // or written, and by the machine dependent translator to know which registers
 // to allocate variables in.  Since built-ins tend to go to different registers
 // than varying or uniform, it makes sense they are peers, not sub-classes.
 //
@@ -355,25 +503,50 @@ enum TQualifier
     EvqComputeIn,
     EvqNumWorkGroups,
     EvqWorkGroupSize,
     EvqWorkGroupID,
     EvqLocalInvocationID,
     EvqGlobalInvocationID,
     EvqLocalInvocationIndex,
 
+    // GLSL ES 3.1 memory qualifiers
+    EvqReadOnly,
+    EvqWriteOnly,
+    EvqCoherent,
+    EvqRestrict,
+    EvqVolatile,
+
     // end of list
     EvqLast
 };
 
 inline bool IsQualifierUnspecified(TQualifier qualifier)
 {
     return (qualifier == EvqTemporary || qualifier == EvqGlobal);
 }
 
+enum TLayoutImageInternalFormat
+{
+    EiifUnspecified,
+    EiifRGBA32F,
+    EiifRGBA16F,
+    EiifR32F,
+    EiifRGBA32UI,
+    EiifRGBA16UI,
+    EiifRGBA8UI,
+    EiifR32UI,
+    EiifRGBA32I,
+    EiifRGBA16I,
+    EiifRGBA8I,
+    EiifR32I,
+    EiifRGBA8,
+    EiifRGBA8_SNORM
+};
+
 enum TLayoutMatrixPacking
 {
     EmpUnspecified,
     EmpRowMajor,
     EmpColumnMajor
 };
 
 enum TLayoutBlockStorage
@@ -389,52 +562,89 @@ struct TLayoutQualifier
     int location;
     unsigned int locationsSpecified;
     TLayoutMatrixPacking matrixPacking;
     TLayoutBlockStorage blockStorage;
 
     // Compute shader layout qualifiers.
     sh::WorkGroupSize localSize;
 
+    // Image format layout qualifier
+    TLayoutImageInternalFormat imageInternalFormat;
+
     static TLayoutQualifier create()
     {
         TLayoutQualifier layoutQualifier;
 
         layoutQualifier.location = -1;
         layoutQualifier.locationsSpecified = 0;
         layoutQualifier.matrixPacking = EmpUnspecified;
         layoutQualifier.blockStorage = EbsUnspecified;
 
         layoutQualifier.localSize.fill(-1);
 
+        layoutQualifier.imageInternalFormat = EiifUnspecified;
         return layoutQualifier;
     }
 
     bool isEmpty() const
     {
         return location == -1 && matrixPacking == EmpUnspecified &&
-               blockStorage == EbsUnspecified && !localSize.isAnyValueSet();
+               blockStorage == EbsUnspecified && !localSize.isAnyValueSet() &&
+               imageInternalFormat == EiifUnspecified;
     }
 
     bool isCombinationValid() const
     {
         bool workSizeSpecified = localSize.isAnyValueSet();
         bool otherLayoutQualifiersSpecified =
-            (location != -1 || matrixPacking != EmpUnspecified || blockStorage != EbsUnspecified);
+            (location != -1 || matrixPacking != EmpUnspecified || blockStorage != EbsUnspecified ||
+             imageInternalFormat != EiifUnspecified);
 
         // we can have either the work group size specified, or the other layout qualifiers
         return !(workSizeSpecified && otherLayoutQualifiersSpecified);
     }
 
     bool isLocalSizeEqual(const sh::WorkGroupSize &localSizeIn) const
     {
         return localSize.isWorkGroupSizeMatching(localSizeIn);
     }
 };
 
+struct TMemoryQualifier
+{
+    // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
+    // An image can be qualified as both readonly and writeonly. It still can be can be used with
+    // imageSize().
+    bool readonly;
+    bool writeonly;
+    bool coherent;
+
+    // restrict and volatile are reserved keywords in C/C++
+    bool restrictQualifier;
+    bool volatileQualifier;
+    static TMemoryQualifier create()
+    {
+        TMemoryQualifier memoryQualifier;
+
+        memoryQualifier.readonly          = false;
+        memoryQualifier.writeonly         = false;
+        memoryQualifier.coherent          = false;
+        memoryQualifier.restrictQualifier = false;
+        memoryQualifier.volatileQualifier = false;
+
+        return memoryQualifier;
+    }
+
+    bool isEmpty()
+    {
+        return !readonly && !writeonly && !coherent && !restrictQualifier && !volatileQualifier;
+    }
+};
+
 inline const char *getWorkGroupSizeString(size_t dimension)
 {
     switch (dimension)
     {
         case 0u:
             return "local_size_x";
         case 1u:
             return "local_size_y";
@@ -495,16 +705,18 @@ inline const char* getQualifierString(TQ
     case EvqSmooth:                 return "smooth";
     case EvqComputeIn:              return "in";
     case EvqNumWorkGroups:          return "NumWorkGroups";
     case EvqWorkGroupSize:          return "WorkGroupSize";
     case EvqWorkGroupID:            return "WorkGroupID";
     case EvqLocalInvocationID:      return "LocalInvocationID";
     case EvqGlobalInvocationID:     return "GlobalInvocationID";
     case EvqLocalInvocationIndex:   return "LocalInvocationIndex";
+    case EvqReadOnly:               return "readonly";
+    case EvqWriteOnly:              return "writeonly";
     default: UNREACHABLE();         return "unknown qualifier";
     }
     // clang-format on
 }
 
 inline const char* getMatrixPackingString(TLayoutMatrixPacking mpq)
 {
     switch (mpq)
@@ -523,23 +735,47 @@ inline const char* getBlockStorageString
     case EbsUnspecified:    return "bs_unspecified";
     case EbsShared:         return "shared";
     case EbsPacked:         return "packed";
     case EbsStd140:         return "std140";
     default: UNREACHABLE(); return "unknown block storage";
     }
 }
 
-inline const char* getInterpolationString(TQualifier q)
+inline const char *getImageInternalFormatString(TLayoutImageInternalFormat iifq)
 {
-    switch(q)
+    switch (iifq)
     {
-    case EvqSmoothOut:      return "smooth";   break;
-    case EvqCentroidOut:    return "smooth centroid"; break;
-    case EvqFlatOut:        return "flat";     break;
-    case EvqSmoothIn:       return "smooth";   break;
-    case EvqCentroidIn:     return "smooth centroid"; break;
-    case EvqFlatIn:         return "flat";     break;
-    default: UNREACHABLE(); return "unknown interpolation";
+        case EiifRGBA32F:
+            return "rgba32f";
+        case EiifRGBA16F:
+            return "rgba16f";
+        case EiifR32F:
+            return "r32f";
+        case EiifRGBA32UI:
+            retur